summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAriejan de Vroom <ariejan@ariejan.net>2012-03-01 15:09:23 +0100
committerAriejan de Vroom <ariejan@ariejan.net>2012-03-01 15:09:23 +0100
commitbfe0906f2ff7a79064c1866c0278cd0c9440b246 (patch)
tree6d5da24190f0f5315ba0516c3737074f8afab28e
parent4587ab6ff64a255577e02334fa0492b5edcb80ea (diff)
parentdf6f74817910e2e3263f214733636ba1d0da41b8 (diff)
downloadgitlab-ce-bfe0906f2ff7a79064c1866c0278cd0c9440b246.tar.gz
Merge remote-tracking branch 'upstream/master'
-rw-r--r--.gitignore5
-rw-r--r--.rbenv-version1
-rw-r--r--.travis.yml2
-rw-r--r--Gemfile27
-rw-r--r--Gemfile.lock252
-rw-r--r--Procfile.production2
-rw-r--r--VERSION2
-rw-r--r--app/assets/images/Gear-UI.PNGbin940 -> 0 bytes
-rw-r--r--app/assets/images/Home-UI.PNGbin782 -> 0 bytes
-rw-r--r--app/assets/images/Info-UI.PNGbin800 -> 801 bytes
-rw-r--r--app/assets/images/admin.PNGbin0 -> 556 bytes
-rw-r--r--app/assets/images/blueprint_add.pngbin518 -> 177 bytes
-rw-r--r--app/assets/images/blueprint_delete.pngbin469 -> 295 bytes
-rw-r--r--app/assets/images/comment_add.pngbin0 -> 1189 bytes
-rw-r--r--app/assets/images/help_commit.pngbin98025 -> 0 bytes
-rw-r--r--app/assets/images/help_merge_request.pngbin55785 -> 0 bytes
-rw-r--r--app/assets/images/home_icon.PNGbin0 -> 596 bytes
-rw-r--r--app/assets/images/logo_tr.pngbin0 -> 7896 bytes
-rw-r--r--app/assets/images/submodule.pngbin0 -> 641 bytes
-rw-r--r--app/assets/javascripts/application.js25
-rw-r--r--app/assets/javascripts/commits.js15
-rw-r--r--app/assets/javascripts/issues.js19
-rw-r--r--app/assets/javascripts/merge_requests.js39
-rw-r--r--app/assets/javascripts/note.js157
-rw-r--r--app/assets/javascripts/pager.js (renamed from app/assets/javascripts/projects.js)24
-rw-r--r--app/assets/javascripts/team.js4
-rw-r--r--app/assets/javascripts/tree.js17
-rw-r--r--app/assets/stylesheets/application.css2
-rw-r--r--app/assets/stylesheets/commits.css.scss191
-rw-r--r--app/assets/stylesheets/common.scss643
-rw-r--r--app/assets/stylesheets/dashboard.scss30
-rw-r--r--app/assets/stylesheets/highlight.black.scss (renamed from app/assets/stylesheets/highlight.black.css.scss)1
-rw-r--r--app/assets/stylesheets/highlight.scss (renamed from app/assets/stylesheets/highlight.css.scss)16
-rw-r--r--app/assets/stylesheets/issues.css.scss84
-rw-r--r--app/assets/stylesheets/login.scss44
-rw-r--r--app/assets/stylesheets/main.scss118
-rw-r--r--app/assets/stylesheets/merge_requests.css.scss10
-rw-r--r--app/assets/stylesheets/notes.css.scss52
-rw-r--r--app/assets/stylesheets/notes.scss121
-rw-r--r--app/assets/stylesheets/projects.css.scss572
-rw-r--r--app/assets/stylesheets/projects.css.scss~385
-rw-r--r--app/assets/stylesheets/ref_select.scss50
-rw-r--r--app/assets/stylesheets/style.scss802
-rw-r--r--app/assets/stylesheets/tags.css.css42
-rw-r--r--app/assets/stylesheets/top_panel.scss146
-rw-r--r--app/assets/stylesheets/tree.scss235
-rw-r--r--app/assets/stylesheets/ui_basic.scss309
-rw-r--r--app/assets/stylesheets/ui_mars.scss337
-rw-r--r--app/controllers/admin/projects_controller.rb6
-rw-r--r--app/controllers/admin/team_members_controller.rb28
-rw-r--r--app/controllers/admin/users_controller.rb20
-rw-r--r--app/controllers/application_controller.rb41
-rw-r--r--app/controllers/commits_controller.rb31
-rw-r--r--app/controllers/dashboard_controller.rb9
-rw-r--r--app/controllers/errors_controller.rb4
-rw-r--r--app/controllers/issues_controller.rb18
-rw-r--r--app/controllers/keys_controller.rb2
-rw-r--r--app/controllers/merge_requests_controller.rb33
-rw-r--r--app/controllers/notes_controller.rb31
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb13
-rw-r--r--app/controllers/projects_controller.rb17
-rw-r--r--app/controllers/protected_branches_controller.rb32
-rw-r--r--app/controllers/refs_controller.rb33
-rw-r--r--app/controllers/repositories_controller.rb26
-rw-r--r--app/controllers/snippets_controller.rb15
-rw-r--r--app/controllers/tags_controller.rb11
-rw-r--r--app/controllers/team_members_controller.rb2
-rw-r--r--app/controllers/wikis_controller.rb59
-rw-r--r--app/helpers/application_helper.rb36
-rw-r--r--app/helpers/commits_helper.rb65
-rw-r--r--app/helpers/dashboard_helper.rb2
-rw-r--r--app/helpers/issues_helper.rb22
-rw-r--r--app/helpers/merge_requests_helper.rb21
-rw-r--r--app/helpers/projects_helper.rb27
-rw-r--r--app/helpers/wikis_helper.rb5
-rw-r--r--app/mailers/notify.rb3
-rw-r--r--app/models/ability.rb34
-rw-r--r--app/models/activity_observer.rb12
-rw-r--r--app/models/commit.rb22
-rw-r--r--app/models/event.rb70
-rw-r--r--app/models/key.rb1
-rw-r--r--app/models/mailer_observer.rb31
-rw-r--r--app/models/note.rb35
-rw-r--r--app/models/project.rb109
-rw-r--r--app/models/protected_branch.rb29
-rw-r--r--app/models/repository.rb12
-rw-r--r--app/models/user.rb26
-rw-r--r--app/models/users_project.rb41
-rw-r--r--app/models/wiki.rb47
-rw-r--r--app/views/admin/projects/_form.html.haml73
-rw-r--r--app/views/admin/projects/edit.html.haml8
-rw-r--r--app/views/admin/projects/index.html.haml14
-rw-r--r--app/views/admin/projects/show.html.haml60
-rw-r--r--app/views/admin/team_members/_form.html.haml30
-rw-r--r--app/views/admin/team_members/edit.html.haml23
-rw-r--r--app/views/admin/team_members/index.html.haml28
-rw-r--r--app/views/admin/team_members/new.html.haml6
-rw-r--r--app/views/admin/team_members/show.html.haml26
-rw-r--r--app/views/admin/users/_form.html.haml55
-rw-r--r--app/views/admin/users/edit.html.haml7
-rw-r--r--app/views/admin/users/index.html.haml12
-rw-r--r--app/views/admin/users/new.html.haml7
-rw-r--r--app/views/admin/users/show.html.haml76
-rw-r--r--app/views/commits/_commit.html.haml17
-rw-r--r--app/views/commits/_commits.html.haml26
-rw-r--r--app/views/commits/_diff_head.html.haml2
-rw-r--r--app/views/commits/_diffs.html.haml (renamed from app/views/commits/_diff.html.haml)12
-rw-r--r--app/views/commits/_head.html.haml35
-rw-r--r--app/views/commits/_index.html.haml9
-rw-r--r--app/views/commits/_text_file.html.haml56
-rw-r--r--app/views/commits/compare.html.haml49
-rw-r--r--app/views/commits/index.html.haml23
-rw-r--r--app/views/commits/show.html.haml39
-rw-r--r--app/views/dashboard/_events_feed.html.haml19
-rw-r--r--app/views/dashboard/_issues_feed.html.haml36
-rw-r--r--app/views/dashboard/_menu.html.haml21
-rw-r--r--app/views/dashboard/_merge_requests_feed.html.haml34
-rw-r--r--app/views/dashboard/_projects_feed.html.haml28
-rw-r--r--app/views/dashboard/_sidebar.html.haml15
-rw-r--r--app/views/dashboard/index.html.haml69
-rw-r--r--app/views/dashboard/issues.html.haml10
-rw-r--r--app/views/dashboard/merge_requests.html.haml10
-rw-r--r--app/views/deploy_keys/_form.html.haml28
-rw-r--r--app/views/deploy_keys/_show.html.haml19
-rw-r--r--app/views/deploy_keys/index.html.haml25
-rw-r--r--app/views/deploy_keys/new.html.haml3
-rw-r--r--app/views/deploy_keys/show.html.haml17
-rw-r--r--app/views/devise/passwords/edit.html.erb16
-rw-r--r--app/views/devise/passwords/edit.html.haml12
-rw-r--r--app/views/devise/passwords/new.html.erb5
-rw-r--r--app/views/devise/sessions/new.html.erb7
-rw-r--r--app/views/devise/shared/_links.erb4
-rw-r--r--app/views/errors/access_denied.html.haml5
-rw-r--r--app/views/errors/git_not_found.html.haml9
-rw-r--r--app/views/errors/gitolite.html.haml18
-rw-r--r--app/views/errors/not_found.html.haml5
-rw-r--r--app/views/help/index.html.haml52
-rw-r--r--app/views/help/permissions.html.haml36
-rw-r--r--app/views/help/workflow.html.haml38
-rw-r--r--app/views/hooks/index.html.haml43
-rw-r--r--app/views/hooks/new.html.haml11
-rw-r--r--app/views/hooks/show.html.haml12
-rw-r--r--app/views/issues/_form.html.haml76
-rw-r--r--app/views/issues/_head.html.haml18
-rw-r--r--app/views/issues/_show.html.haml53
-rw-r--r--app/views/issues/index.html.haml77
-rw-r--r--app/views/issues/index.js.haml2
-rw-r--r--app/views/issues/show.html.haml89
-rw-r--r--app/views/issues/show.js.haml1
-rw-r--r--app/views/kaminari/_first_page.html.haml9
-rw-r--r--app/views/kaminari/_gap.html.haml8
-rw-r--r--app/views/kaminari/_last_page.html.haml9
-rw-r--r--app/views/kaminari/_next_page.html.haml9
-rw-r--r--app/views/kaminari/_page.html.haml10
-rw-r--r--app/views/kaminari/_paginator.html.haml17
-rw-r--r--app/views/kaminari/_prev_page.html.haml9
-rw-r--r--app/views/keys/_form.html.haml22
-rw-r--r--app/views/keys/_show.html.haml20
-rw-r--r--app/views/keys/index.html.haml21
-rw-r--r--app/views/keys/new.html.haml6
-rw-r--r--app/views/keys/show.html.haml13
-rw-r--r--app/views/layouts/_app_menu.html.haml6
-rw-r--r--app/views/layouts/_const_menu_links.html.haml1
-rw-r--r--app/views/layouts/_flash.html.haml7
-rw-r--r--app/views/layouts/_head.html.haml17
-rw-r--r--app/views/layouts/_head_panel.html.haml61
-rw-r--r--app/views/layouts/_project_menu.html.haml27
-rw-r--r--app/views/layouts/_project_side.html.haml19
-rw-r--r--app/views/layouts/_project_side_right.html.haml8
-rw-r--r--app/views/layouts/_projects_side.html.haml21
-rw-r--r--app/views/layouts/admin.html.haml41
-rw-r--r--app/views/layouts/application.html.haml28
-rw-r--r--app/views/layouts/devise.html.haml19
-rw-r--r--app/views/layouts/error.html.haml11
-rw-r--r--app/views/layouts/profile.html.haml48
-rw-r--r--app/views/layouts/project.html.haml38
-rw-r--r--app/views/merge_requests/_commits.html.haml30
-rw-r--r--app/views/merge_requests/_diffs.html.haml23
-rw-r--r--app/views/merge_requests/_form.html.haml63
-rw-r--r--app/views/merge_requests/_head.html.haml7
-rw-r--r--app/views/merge_requests/_how_to_merge.html.haml25
-rw-r--r--app/views/merge_requests/_merge_request.html.haml13
-rw-r--r--app/views/merge_requests/edit.html.haml3
-rw-r--r--app/views/merge_requests/index.html.haml48
-rw-r--r--app/views/merge_requests/new.html.haml2
-rw-r--r--app/views/merge_requests/show.html.haml131
-rw-r--r--app/views/notes/_create_common.js.haml9
-rw-r--r--app/views/notes/_create_line.js.haml8
-rw-r--r--app/views/notes/_form.html.haml58
-rw-r--r--app/views/notes/_load.js.haml15
-rw-r--r--app/views/notes/_notes.html.haml23
-rw-r--r--app/views/notes/_per_line_form.html.haml44
-rw-r--r--app/views/notes/_reply_button.html.haml3
-rw-r--r--app/views/notes/_show.html.haml2
-rw-r--r--app/views/notes/create.js.haml20
-rw-r--r--app/views/notes/index.js.haml (renamed from app/views/commits/show.js.haml)0
-rw-r--r--app/views/notify/note_commit_email.html.haml6
-rw-r--r--app/views/notify/note_issue_email.html.haml4
-rw-r--r--app/views/notify/note_merge_request_email.html.haml4
-rw-r--r--app/views/notify/note_wall_email.html.haml4
-rw-r--r--app/views/profile/design.html.haml40
-rw-r--r--app/views/profile/password.html.haml76
-rw-r--r--app/views/profile/show.html.haml65
-rw-r--r--app/views/projects/_feed.html.haml102
-rw-r--r--app/views/projects/_form.html.haml109
-rw-r--r--app/views/projects/_project_head.html.haml53
-rw-r--r--app/views/projects/_team.html.haml13
-rw-r--r--app/views/projects/_tile.html.haml25
-rw-r--r--app/views/projects/create.js.haml1
-rw-r--r--app/views/projects/edit.html.haml78
-rw-r--r--app/views/projects/empty.html.haml19
-rw-r--r--app/views/projects/files.html.haml21
-rw-r--r--app/views/projects/graph.html.haml8
-rw-r--r--app/views/projects/index.html.haml48
-rw-r--r--app/views/projects/index.js.haml2
-rw-r--r--app/views/projects/info.html.haml28
-rw-r--r--app/views/projects/new.html.haml27
-rw-r--r--app/views/projects/show.html.haml31
-rw-r--r--app/views/projects/team.html.haml9
-rw-r--r--app/views/projects/update.js.haml3
-rw-r--r--app/views/projects/wall.html.haml6
-rw-r--r--app/views/projects/wall.js.haml1
-rw-r--r--app/views/protected_branches/index.html.haml55
-rw-r--r--app/views/refs/_submodule_item.html.haml13
-rw-r--r--app/views/refs/_tree.html.haml28
-rw-r--r--app/views/refs/_tree_file.html.haml14
-rw-r--r--app/views/refs/_tree_item.html.haml4
-rw-r--r--app/views/refs/tree.html.haml10
-rw-r--r--app/views/repositories/_branch.html.haml20
-rw-r--r--app/views/repositories/_branches_head.html.haml12
-rw-r--r--app/views/repositories/_feed.html.haml32
-rw-r--r--app/views/repositories/_head.html.haml29
-rw-r--r--app/views/repositories/branches.html.haml15
-rw-r--r--app/views/repositories/show.html.haml10
-rw-r--r--app/views/repositories/tags.html.haml30
-rw-r--r--app/views/snippets/_form.html.haml61
-rw-r--r--app/views/snippets/_snippet.html.haml18
-rw-r--r--app/views/snippets/edit.html.haml1
-rw-r--r--app/views/snippets/index.html.haml18
-rw-r--r--app/views/snippets/new.html.haml1
-rw-r--r--app/views/snippets/show.html.haml29
-rw-r--r--app/views/tags/index.html.haml10
-rw-r--r--app/views/team_members/_form.html.haml56
-rw-r--r--app/views/team_members/_show.html.haml27
-rw-r--r--app/views/team_members/create.js.haml6
-rw-r--r--app/views/team_members/show.html.haml47
-rw-r--r--app/views/widgets/_project_member.html.haml54
-rw-r--r--app/views/widgets/_recent_projects.html.haml11
-rw-r--r--app/views/wikis/_form.html.haml24
-rw-r--r--app/views/wikis/edit.html.haml3
-rw-r--r--app/views/wikis/history.html.haml19
-rw-r--r--app/views/wikis/show.html.haml16
-rw-r--r--app/workers/post_receive.rb8
-rw-r--r--config/application.rb2
-rw-r--r--config/database.yml.example (renamed from config/database.yml)0
-rw-r--r--config/environments/development.rb7
-rw-r--r--config/gitlab.yml.example (renamed from config/gitlab.yml)0
-rw-r--r--config/initializers/carrierwave.rb1
-rw-r--r--config/initializers/devise.rb9
-rw-r--r--config/initializers/gitlabhq/30_resque_queues.rb1
-rw-r--r--config/routes.rb33
-rw-r--r--db/migrate/20120206170141_add_modularity_fields_to_project.rb7
-rw-r--r--db/migrate/20120215182305_create_protected_branches.rb10
-rw-r--r--db/migrate/20120216085842_move_to_roles_permissions.rb22
-rw-r--r--db/migrate/20120216215008_create_wikis.rb11
-rw-r--r--db/migrate/20120219130957_add_slug_to_wiki.rb6
-rw-r--r--db/migrate/20120219140810_add_wiki_enabled_to_project.rb6
-rw-r--r--db/migrate/20120219193300_add_user_to_wiki.rb6
-rw-r--r--db/migrate/20120228130210_create_events.rb14
-rw-r--r--db/migrate/20120228134252_add_action_to_event.rb5
-rw-r--r--db/schema.rb45
-rw-r--r--lib/gitlabhq/gitolite.rb62
-rwxr-xr-xlib/post-receive-hook2
-rw-r--r--lib/tasks/update_hooks.rake15
-rw-r--r--lib/utils.rb4
-rw-r--r--public/404.html16
-rw-r--r--public/422.html15
-rw-r--r--public/500.html15
-rw-r--r--public/static.css57
-rwxr-xr-xresque.sh2
-rwxr-xr-xresque_dev.sh1
-rw-r--r--spec/factories.rb14
-rw-r--r--spec/models/activity_observer_spec.rb44
-rw-r--r--spec/models/event_spec.rb32
-rw-r--r--spec/models/note_spec.rb32
-rw-r--r--spec/models/project_hooks_spec.rb121
-rw-r--r--spec/models/project_security_spec.rb10
-rw-r--r--spec/models/project_spec.rb125
-rw-r--r--spec/models/protected_branch_spec.rb16
-rw-r--r--spec/models/users_project_spec.rb1
-rw-r--r--spec/requests/admin/admin_projects_spec.rb15
-rw-r--r--spec/requests/admin/admin_users_spec.rb14
-rw-r--r--spec/requests/admin/security_spec.rb6
-rw-r--r--spec/requests/commits_spec.rb12
-rw-r--r--spec/requests/dashboard_issues_spec.rb2
-rw-r--r--spec/requests/dashboard_merge_requests_spec.rb7
-rw-r--r--spec/requests/dashboard_spec.rb3
-rw-r--r--spec/requests/issues_spec.rb14
-rw-r--r--spec/requests/keys_spec.rb6
-rw-r--r--spec/requests/merge_requests_spec.rb4
-rw-r--r--spec/requests/projects_security_spec.rb6
-rw-r--r--spec/requests/projects_spec.rb12
-rw-r--r--spec/requests/projects_wall_spec.rb2
-rw-r--r--spec/requests/repositories_spec.rb9
-rw-r--r--spec/requests/snippets_spec.rb3
-rw-r--r--spec/requests/team_members_spec.rb16
-rw-r--r--spec/requests/wikis_spec.rb35
-rw-r--r--spec/support/shared_examples.rb3
-rw-r--r--spec/workers/post_receive_spec.rb11
-rw-r--r--vendor/assets/javascripts/bootstrap-modal.js260
-rw-r--r--vendor/assets/javascripts/bootstrap-popover.js86
-rw-r--r--vendor/assets/javascripts/jquery.endless-scroll.js128
312 files changed, 6575 insertions, 4822 deletions
diff --git a/.gitignore b/.gitignore
index 74111a22c0b..c53bac48c2d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,5 +9,10 @@ coverage/*
*.swp
public/uploads/
.rvmrc
+.rbenv-version
.directory
nohup.out
+Vagrantfile
+.vagrant
+config/gitlab.yml
+config/database.yml
diff --git a/.rbenv-version b/.rbenv-version
deleted file mode 100644
index 0a95b9f5c71..00000000000
--- a/.rbenv-version
+++ /dev/null
@@ -1 +0,0 @@
-1.9.2-p290
diff --git a/.travis.yml b/.travis.yml
index 7a450b7d005..0193d00735c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,6 +4,8 @@ branches:
- 'master'
rvm: 1.9.2
before_script:
+ - "cp config/database.yml.example config/database.yml"
+ - "cp config/gitlab.yml.example config/gitlab.yml"
- "bundle exec rake db:create RAILS_ENV=test"
- "bundle exec rake db:migrate RAILS_ENV=test"
- "bundle exec rake db:seed_fu RAILS_ENV=test"
diff --git a/Gemfile b/Gemfile
index b80dca11534..5c0b660d796 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,10 +1,10 @@
source "http://rubygems.org"
-gem "rails", "3.1.1"
+gem "rails", "3.2.1"
gem "sqlite3"
-gem "rake", "0.9.2.2"
-gem "devise", "1.5.0"
+gem "rake"
+gem "devise"
gem "stamp"
gem "kaminari"
gem "haml", "3.1.4"
@@ -16,7 +16,7 @@ gem "carrierwave"
gem "six"
gem "therubyracer"
gem "faker"
-gem "seed-fu", "~> 2.1.0"
+gem "seed-fu"
gem "pygments.rb", "0.2.4"
gem "thin"
gem "git"
@@ -24,20 +24,23 @@ gem "acts_as_list"
gem "rdiscount"
gem "acts-as-taggable-on", "~> 2.1.0"
gem "drapper"
-gem "resque"
+gem "resque", "~> 1.20.0"
gem "httparty"
gem "charlock_holmes"
gem "foreman"
+gem "omniauth-ldap"
+gem 'bootstrap-sass', "1.4.4"
+gem "colored"
group :assets do
- gem "sass-rails", "~> 3.1.0"
- gem "coffee-rails", "~> 3.1.0"
- gem "uglifier"
+ gem "sass-rails", "3.2.3"
+ gem "coffee-rails", "3.2.1"
+ gem "uglifier", "1.0.3"
end
group :development do
gem "letter_opener"
- gem "rails-footnotes", "~> 3.7.5"
+ gem "rails-footnotes"
gem "annotate", :git => "https://github.com/ctran/annotate_models.git"
end
@@ -46,9 +49,7 @@ group :development, :test do
gem "capybara"
gem "autotest"
gem "autotest-rails"
- unless ENV["CI"]
- gem "ruby-debug19", :require => "ruby-debug"
- end
+ gem "pry"
gem "awesome_print"
gem "database_cleaner"
gem "launchy"
@@ -58,5 +59,5 @@ end
group :test do
gem "turn", :require => false
gem "simplecov", :require => false
- gem "shoulda", "~> 3.0.0.beta2"
+ gem "shoulda", "3.0.0"
end
diff --git a/Gemfile.lock b/Gemfile.lock
index ec171d2c84d..09457d5bce9 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,6 +1,6 @@
GIT
remote: https://github.com/ctran/annotate_models.git
- revision: fb73329243056a6d9a64878e5c543aba9b6417de
+ revision: a43c08f0eb4d69a48c6830630ebb60e35ccb2d2d
specs:
annotate (2.4.1.beta1)
@@ -25,48 +25,48 @@ GEM
remote: http://rubygems.org/
specs:
ZenTest (4.5.0)
- actionmailer (3.1.1)
- actionpack (= 3.1.1)
- mail (~> 2.3.0)
- actionpack (3.1.1)
- activemodel (= 3.1.1)
- activesupport (= 3.1.1)
+ actionmailer (3.2.1)
+ actionpack (= 3.2.1)
+ mail (~> 2.4.0)
+ actionpack (3.2.1)
+ activemodel (= 3.2.1)
+ activesupport (= 3.2.1)
builder (~> 3.0.0)
erubis (~> 2.7.0)
- i18n (~> 0.6)
- rack (~> 1.3.2)
+ journey (~> 1.0.1)
+ rack (~> 1.4.0)
rack-cache (~> 1.1)
- rack-mount (~> 0.8.2)
rack-test (~> 0.6.1)
- sprockets (~> 2.0.2)
- activemodel (3.1.1)
- activesupport (= 3.1.1)
+ sprockets (~> 2.1.2)
+ activemodel (3.2.1)
+ activesupport (= 3.2.1)
builder (~> 3.0.0)
- i18n (~> 0.6)
- activerecord (3.1.1)
- activemodel (= 3.1.1)
- activesupport (= 3.1.1)
- arel (~> 2.2.1)
+ activerecord (3.2.1)
+ activemodel (= 3.2.1)
+ activesupport (= 3.2.1)
+ arel (~> 3.0.0)
tzinfo (~> 0.3.29)
- activeresource (3.1.1)
- activemodel (= 3.1.1)
- activesupport (= 3.1.1)
- activesupport (3.1.1)
+ activeresource (3.2.1)
+ activemodel (= 3.2.1)
+ activesupport (= 3.2.1)
+ activesupport (3.2.1)
+ i18n (~> 0.6)
multi_json (~> 1.0)
acts-as-taggable-on (2.1.1)
rails
acts_as_list (0.1.4)
addressable (2.2.6)
- ansi (1.4.1)
- archive-tar-minitar (0.5.2)
- arel (2.2.1)
+ ansi (1.4.2)
+ arel (3.0.0)
autotest (4.4.6)
ZenTest (>= 4.4.1)
autotest-rails (4.1.1)
ZenTest (= 4.5)
- awesome_print (0.4.0)
+ awesome_print (1.0.2)
bcrypt-ruby (3.0.1)
blankslate (2.1.2.4)
+ bootstrap-sass (1.4.4)
+ sass-rails (~> 3.1)
builder (3.0.0)
capybara (1.1.2)
mime-types (>= 1.16)
@@ -78,19 +78,20 @@ GEM
carrierwave (0.5.8)
activesupport (~> 3.0)
charlock_holmes (0.6.8)
- childprocess (0.2.2)
+ childprocess (0.3.1)
ffi (~> 1.0.6)
- coffee-rails (3.1.1)
+ coderay (1.0.5)
+ coffee-rails (3.2.1)
coffee-script (>= 2.2.0)
- railties (~> 3.1.0)
+ railties (~> 3.2.0.beta)
coffee-script (2.2.0)
coffee-script-source
execjs
- coffee-script-source (1.1.3)
- columnize (0.3.4)
+ coffee-script-source (1.2.0)
+ colored (1.2)
crack (0.3.1)
- daemons (1.1.4)
- database_cleaner (0.7.0)
+ daemons (1.1.8)
+ database_cleaner (0.7.1)
devise (1.5.0)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.0.3)
@@ -99,13 +100,13 @@ GEM
drapper (0.8.4)
erubis (2.7.0)
eventmachine (0.12.10)
- execjs (1.2.9)
+ execjs (1.3.0)
multi_json (~> 1.0)
faker (1.0.1)
i18n (~> 0.4)
ffi (1.0.11)
- foreman (0.27.0)
- term-ansicolor (~> 1.0.5)
+ foreman (0.39.0)
+ term-ansicolor (~> 1.0.7)
thor (>= 0.13.6)
git (1.2.5)
haml (3.1.4)
@@ -115,139 +116,143 @@ GEM
haml (~> 3.0)
railties (~> 3.0)
hashery (1.4.0)
+ hashie (1.2.0)
hike (1.2.1)
httparty (0.8.1)
multi_json
multi_xml
i18n (0.6.0)
- jquery-rails (1.0.17)
- railties (~> 3.0)
+ journey (1.0.1)
+ jquery-rails (2.0.0)
+ railties (>= 3.2.0.beta, < 5.0)
thor (~> 0.14)
- json (1.6.1)
- json_pure (1.6.1)
- kaminari (0.12.4)
- rails (>= 3.0.0)
+ json (1.6.5)
+ kaminari (0.13.0)
+ actionpack (>= 3.0.0)
+ activesupport (>= 3.0.0)
+ railties (>= 3.0.0)
launchy (2.0.5)
addressable (~> 2.2.6)
letter_opener (0.0.2)
launchy
libv8 (3.3.10.4)
- linecache19 (0.5.12)
- ruby_core_source (>= 0.1.4)
- mail (2.3.0)
+ mail (2.4.1)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
+ method_source (0.7.0)
mime-types (1.17.2)
- multi_json (1.0.3)
+ multi_json (1.0.4)
multi_xml (0.4.1)
+ net-ldap (0.2.2)
nokogiri (1.5.0)
- orm_adapter (0.0.5)
+ omniauth (1.0.2)
+ hashie (~> 1.2)
+ rack
+ omniauth-ldap (1.0.2)
+ net-ldap (~> 0.2.2)
+ omniauth (~> 1.0)
+ pyu-ruby-sasl (~> 0.0.3.1)
+ rubyntlm (~> 0.1.1)
+ orm_adapter (0.0.6)
polyglot (0.3.3)
posix-spawn (0.3.6)
+ pry (0.9.8.2)
+ coderay (~> 1.0.5)
+ method_source (~> 0.7)
+ slop (>= 2.4.4, < 3)
pygments.rb (0.2.4)
rubypython (~> 0.5.3)
- rack (1.3.5)
+ pyu-ruby-sasl (0.0.3.3)
+ rack (1.4.1)
rack-cache (1.1)
rack (>= 0.4)
- rack-mount (0.8.3)
- rack (>= 1.0.0)
- rack-protection (1.1.4)
+ rack-protection (1.2.0)
rack
rack-ssl (1.3.2)
rack
rack-test (0.6.1)
rack (>= 1.0)
- rails (3.1.1)
- actionmailer (= 3.1.1)
- actionpack (= 3.1.1)
- activerecord (= 3.1.1)
- activeresource (= 3.1.1)
- activesupport (= 3.1.1)
+ rails (3.2.1)
+ actionmailer (= 3.2.1)
+ actionpack (= 3.2.1)
+ activerecord (= 3.2.1)
+ activeresource (= 3.2.1)
+ activesupport (= 3.2.1)
bundler (~> 1.0)
- railties (= 3.1.1)
+ railties (= 3.2.1)
rails-footnotes (3.7.5)
rails (>= 3.0.0)
- railties (3.1.1)
- actionpack (= 3.1.1)
- activesupport (= 3.1.1)
+ railties (3.2.1)
+ actionpack (= 3.2.1)
+ activesupport (= 3.2.1)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (~> 0.14.6)
rake (0.9.2.2)
rdiscount (1.6.8)
- rdoc (3.11)
+ rdoc (3.12)
json (~> 1.4)
redis (2.2.2)
redis-namespace (1.0.3)
redis (< 3.0.0)
- resque (1.19.0)
+ resque (1.20.0)
multi_json (~> 1.0)
redis-namespace (~> 1.0.2)
sinatra (>= 0.9.2)
vegas (~> 0.1.2)
- rspec (2.7.0)
- rspec-core (~> 2.7.0)
- rspec-expectations (~> 2.7.0)
- rspec-mocks (~> 2.7.0)
- rspec-core (2.7.1)
- rspec-expectations (2.7.0)
+ rspec (2.8.0)
+ rspec-core (~> 2.8.0)
+ rspec-expectations (~> 2.8.0)
+ rspec-mocks (~> 2.8.0)
+ rspec-core (2.8.0)
+ rspec-expectations (2.8.0)
diff-lcs (~> 1.1.2)
- rspec-mocks (2.7.0)
- rspec-rails (2.7.0)
- actionpack (~> 3.0)
- activesupport (~> 3.0)
- railties (~> 3.0)
- rspec (~> 2.7.0)
- ruby-debug-base19 (0.11.25)
- columnize (>= 0.3.1)
- linecache19 (>= 0.5.11)
- ruby_core_source (>= 0.1.4)
- ruby-debug19 (0.11.6)
- columnize (>= 0.3.1)
- linecache19 (>= 0.5.11)
- ruby-debug-base19 (>= 0.11.19)
- ruby_core_source (0.1.5)
- archive-tar-minitar (>= 0.5.2)
+ rspec-mocks (2.8.0)
+ rspec-rails (2.8.1)
+ actionpack (>= 3.0)
+ activesupport (>= 3.0)
+ railties (>= 3.0)
+ rspec (~> 2.8.0)
+ rubyntlm (0.1.1)
rubypython (0.5.3)
blankslate (>= 2.1.2.3)
ffi (~> 1.0.7)
- rubyzip (0.9.4)
- sass (3.1.10)
- sass-rails (3.1.4)
- actionpack (~> 3.1.0)
- railties (~> 3.1.0)
- sass (>= 3.1.4)
- sprockets (~> 2.0.0)
- tilt (~> 1.3.2)
- seed-fu (2.1.0)
- activerecord (~> 3.1.0)
- activesupport (~> 3.1.0)
- selenium-webdriver (2.12.2)
- childprocess (>= 0.2.1)
+ rubyzip (0.9.6.1)
+ sass (3.1.15)
+ sass-rails (3.2.3)
+ railties (~> 3.2.0.beta)
+ sass (>= 3.1.10)
+ tilt (~> 1.3)
+ seed-fu (2.2.0)
+ activerecord (~> 3.1)
+ activesupport (~> 3.1)
+ selenium-webdriver (2.19.0)
+ childprocess (>= 0.2.5)
ffi (~> 1.0.9)
- json_pure
+ multi_json (~> 1.0.4)
rubyzip
- shoulda (3.0.0.beta2)
- shoulda-context (~> 1.0.0.beta1)
- shoulda-matchers (~> 1.0.0.beta1)
+ shoulda (3.0.0)
+ shoulda-context (~> 1.0.0)
+ shoulda-matchers (~> 1.0.0)
shoulda-context (1.0.0)
shoulda-matchers (1.0.0)
simplecov (0.5.4)
multi_json (~> 1.0.3)
simplecov-html (~> 0.5.3)
simplecov-html (0.5.3)
- sinatra (1.3.1)
- rack (~> 1.3, >= 1.3.4)
- rack-protection (~> 1.1, >= 1.1.2)
+ sinatra (1.3.2)
+ rack (~> 1.3, >= 1.3.6)
+ rack-protection (~> 1.2)
tilt (~> 1.3, >= 1.3.3)
six (0.2.0)
- sprockets (2.0.3)
+ slop (2.4.4)
+ sprockets (2.1.2)
hike (~> 1.2)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
- sqlite3 (1.3.4)
+ sqlite3 (1.3.5)
stamp (0.1.6)
term-ansicolor (1.0.7)
therubyracer (0.9.9)
@@ -261,17 +266,17 @@ GEM
treetop (1.4.10)
polyglot
polyglot (>= 0.3.1)
- turn (0.8.3)
+ turn (0.9.2)
ansi
tzinfo (0.3.31)
- uglifier (1.1.0)
+ uglifier (1.0.3)
execjs (>= 0.3.0)
multi_json (>= 1.0.2)
- vegas (0.1.8)
+ vegas (0.1.11)
rack (>= 1.0.0)
warden (1.1.0)
rack (>= 1.0)
- webmock (1.7.8)
+ webmock (1.7.10)
addressable (~> 2.2, > 2.2.5)
crack (>= 0.1.7)
xpath (0.1.4)
@@ -287,12 +292,14 @@ DEPENDENCIES
autotest
autotest-rails
awesome_print
+ bootstrap-sass (= 1.4.4)
capybara
carrierwave
charlock_holmes
- coffee-rails (~> 3.1.0)
+ coffee-rails (= 3.2.1)
+ colored
database_cleaner
- devise (= 1.5.0)
+ devise
drapper
faker
foreman
@@ -306,17 +313,18 @@ DEPENDENCIES
kaminari
launchy
letter_opener
+ omniauth-ldap
+ pry
pygments.rb (= 0.2.4)
- rails (= 3.1.1)
- rails-footnotes (~> 3.7.5)
- rake (= 0.9.2.2)
+ rails (= 3.2.1)
+ rails-footnotes
+ rake
rdiscount
- resque
+ resque (~> 1.20.0)
rspec-rails
- ruby-debug19
- sass-rails (~> 3.1.0)
- seed-fu (~> 2.1.0)
- shoulda (~> 3.0.0.beta2)
+ sass-rails (= 3.2.3)
+ seed-fu
+ shoulda (= 3.0.0)
simplecov
six
sqlite3
@@ -324,5 +332,5 @@ DEPENDENCIES
therubyracer
thin
turn
- uglifier
+ uglifier (= 1.0.3)
webmock
diff --git a/Procfile.production b/Procfile.production
index 68e8556e9c0..f1126486512 100644
--- a/Procfile.production
+++ b/Procfile.production
@@ -1,2 +1,2 @@
web: bundle exec rails s -p $PORT -e production
-worker: bundle exec rake environment resque:work RAILS_ENV=production QUEUE=* VVERBOSE=1
+worker: bundle exec rake environment resque:work RAILS_ENV=production QUEUE=*
diff --git a/VERSION b/VERSION
index 7ec1d6db408..ccbccc3dc62 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.1.0
+2.2.0
diff --git a/app/assets/images/Gear-UI.PNG b/app/assets/images/Gear-UI.PNG
deleted file mode 100644
index 7720f0eb21a..00000000000
--- a/app/assets/images/Gear-UI.PNG
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/Home-UI.PNG b/app/assets/images/Home-UI.PNG
deleted file mode 100644
index f739af3c2ac..00000000000
--- a/app/assets/images/Home-UI.PNG
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/Info-UI.PNG b/app/assets/images/Info-UI.PNG
index 92795486913..7f48ed8d3f1 100644
--- a/app/assets/images/Info-UI.PNG
+++ b/app/assets/images/Info-UI.PNG
Binary files differ
diff --git a/app/assets/images/admin.PNG b/app/assets/images/admin.PNG
new file mode 100644
index 00000000000..73ff1dfb334
--- /dev/null
+++ b/app/assets/images/admin.PNG
Binary files differ
diff --git a/app/assets/images/blueprint_add.png b/app/assets/images/blueprint_add.png
index e63641d09d3..0f01128df96 100644
--- a/app/assets/images/blueprint_add.png
+++ b/app/assets/images/blueprint_add.png
Binary files differ
diff --git a/app/assets/images/blueprint_delete.png b/app/assets/images/blueprint_delete.png
index f171846bd0e..b4d360f329d 100644
--- a/app/assets/images/blueprint_delete.png
+++ b/app/assets/images/blueprint_delete.png
Binary files differ
diff --git a/app/assets/images/comment_add.png b/app/assets/images/comment_add.png
new file mode 100644
index 00000000000..010da964482
--- /dev/null
+++ b/app/assets/images/comment_add.png
Binary files differ
diff --git a/app/assets/images/help_commit.png b/app/assets/images/help_commit.png
deleted file mode 100644
index e0a49b7123a..00000000000
--- a/app/assets/images/help_commit.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/help_merge_request.png b/app/assets/images/help_merge_request.png
deleted file mode 100644
index a6b5d3dfabd..00000000000
--- a/app/assets/images/help_merge_request.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/home_icon.PNG b/app/assets/images/home_icon.PNG
new file mode 100644
index 00000000000..b1d60d59357
--- /dev/null
+++ b/app/assets/images/home_icon.PNG
Binary files differ
diff --git a/app/assets/images/logo_tr.png b/app/assets/images/logo_tr.png
new file mode 100644
index 00000000000..7a934bbb62c
--- /dev/null
+++ b/app/assets/images/logo_tr.png
Binary files differ
diff --git a/app/assets/images/submodule.png b/app/assets/images/submodule.png
new file mode 100644
index 00000000000..62a88cc619b
--- /dev/null
+++ b/app/assets/images/submodule.png
Binary files differ
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 5782f0afc75..b3142feb494 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -10,6 +10,8 @@
//= require jquery.ui.selectmenu
//= require jquery.tagify
//= require jquery.cookie
+//= require jquery.endless-scroll
+//= require bootstrap-modal
//= require modernizr
//= require chosen
//= require raphael
@@ -21,9 +23,6 @@ $(document).ready(function(){
$(this).select();
});
- $('select#branch').selectmenu({style:'popup', width:200});
- $('select#tag').selectmenu({style:'popup', width:200});
-
$(".account-box").mouseenter(showMenu);
$(".account-box").mouseleave(resetMenu);
@@ -43,6 +42,9 @@ $(document).ready(function(){
}
});
+ /**
+ * Focus search field by pressing 's' key
+ */
$(document).keypress(function(e) {
if( $(e.target).is(":input") ) return;
switch(e.which) {
@@ -50,27 +52,12 @@ $(document).ready(function(){
e.preventDefault();
}
});
-
});
function focusSearch() {
$("#search").focus();
}
-function taggifyForm(){
- var tag_field = $('#tag_field').tagify();
-
- tag_field.tagify('inputField').autocomplete({
- source: '/tags.json'
- });
-
- $('form').submit( function() {
- var tag_field = $('#tag_field')
- tag_field.val( tag_field.tagify('serialize') );
- return true;
- });
-}
-
function updatePage(data){
$.ajax({type: "GET", url: location.href, data: data, dataType: "script"});
}
@@ -82,5 +69,3 @@ function showMenu() {
function resetMenu() {
$(this).removeClass("hover");
}
-
-
diff --git a/app/assets/javascripts/commits.js b/app/assets/javascripts/commits.js
index bb06df55c6e..b31fe485896 100644
--- a/app/assets/javascripts/commits.js
+++ b/app/assets/javascripts/commits.js
@@ -2,6 +2,7 @@ var CommitsList = {
ref:null,
limit:0,
offset:0,
+ disable:false,
init:
function(ref, limit) {
@@ -36,15 +37,21 @@ var CommitsList = {
$("#commits_list").append(html);
if(count > 0) {
this.offset += count;
- this.initLoadMore();
+ } else {
+ this.disable = true;
}
},
initLoadMore:
function() {
- $(window).bind('scroll', function(){
- if($(window).scrollTop() == $(document).height() - $(window).height()){
- $(window).unbind('scroll');
+ $(document).endlessScroll({
+ bottomPixels: 400,
+ fireDelay: 1000,
+ fireOnce:true,
+ ceaseFire: function() {
+ return CommitsList.disable;
+ },
+ callback: function(i) {
CommitsList.getOld();
}
});
diff --git a/app/assets/javascripts/issues.js b/app/assets/javascripts/issues.js
index ef70a99ddf8..ded66b1c540 100644
--- a/app/assets/javascripts/issues.js
+++ b/app/assets/javascripts/issues.js
@@ -1,16 +1,18 @@
function switchToNewIssue(form){
- $("#issues-table-holder").hide("slide", { direction: "left" }, 150, function(){
- $(".project-content").append(form);
+ $(".issues_content").hide("fade", { direction: "left" }, 150, function(){
+ $(".issues_content").after(form);
$('select#issue_assignee_id').chosen();
- $("#new_issue_dialog").show("slide", { direction: "right" }, 150);
+ $("#new_issue_dialog").show("fade", { direction: "right" }, 150);
+ $('.top-tabs .add_new').hide();
});
}
function switchToEditIssue(form){
- $("#issues-table-holder").hide("slide", { direction: "left" }, 150, function(){
- $(".project-content").append(form);
+ $(".issues_content").hide("fade", { direction: "left" }, 150, function(){
+ $(".issues_content").after(form);
$('select#issue_assignee_id').chosen();
- $("#edit_issue_dialog").show("slide", { direction: "right" }, 150);
+ $("#edit_issue_dialog").show("fade", { direction: "right" }, 150);
+ $('.add_new').hide();
});
}
@@ -23,10 +25,11 @@ function switchFromEditIssue(){
}
function backToIssues(){
- $("#edit_issue_dialog, #new_issue_dialog").hide("slide", { direction: "right" }, 150, function(){
- $("#issues-table-holder").show("slide", { direction: "left" }, 150, function() {
+ $("#edit_issue_dialog, #new_issue_dialog").hide("fade", { direction: "right" }, 150, function(){
+ $(".issues_content").show("fade", { direction: "left" }, 150, function() {
$("#edit_issue_dialog").remove();
$("#new_issue_dialog").remove();
+ $('.add_new').show();
});
});
}
diff --git a/app/assets/javascripts/merge_requests.js b/app/assets/javascripts/merge_requests.js
index 0d2f535586e..1c262afc641 100644
--- a/app/assets/javascripts/merge_requests.js
+++ b/app/assets/javascripts/merge_requests.js
@@ -4,46 +4,27 @@ var MergeRequest = {
init:
function() {
- $(".merge-tabs a").live("click", function() {
- $(".merge-tabs a").removeClass("active");
- $(this).addClass("active");
+ $(".tabs a").live("click", function() {
+ $(".tabs a").parent().removeClass("active");
+ $(this).parent().addClass("active");
});
- $(".merge-tabs a.merge-notes-tab").live("click", function() {
- $(".merge-request-commits, .merge-request-diffs").hide();
+ $(".tabs a.merge-notes-tab").live("click", function(e) {
+ $(".merge-request-diffs").hide();
$(".merge-request-notes").show();
+ e.preventDefault();
});
- $(".merge-tabs a.merge-commits-tab").live("click", function() {
- if(!MergeRequest.commits_loaded) {
- MergeRequest.loadCommits();
- }
- $(".merge-request-notes, .merge-request-diffs").hide();
- $(".merge-request-commits").show();
- });
-
- $(".merge-tabs a.merge-diffs-tab").live("click", function() {
+ $(".tabs a.merge-diffs-tab").live("click", function(e) {
if(!MergeRequest.diffs_loaded) {
MergeRequest.loadDiff();
}
- $(".merge-request-notes, .merge-request-commits").hide();
+ $(".merge-request-notes").hide();
$(".merge-request-diffs").show();
+ e.preventDefault();
});
},
- loadCommits:
- function() {
- $(".dashboard-loader").show();
- $.ajax({
- type: "GET",
- url: $(".merge-commits-tab").attr("data-url"),
- complete: function(){
- MergeRequest.commits_loaded = true;
- $(".merge-request-notes, .merge-request-diffs").hide();
- $(".dashboard-loader").hide()},
- dataType: "script"});
- },
-
loadDiff:
function() {
$(".dashboard-loader").show();
@@ -52,7 +33,7 @@ var MergeRequest = {
url: $(".merge-diffs-tab").attr("data-url"),
complete: function(){
MergeRequest.diffs_loaded = true;
- $(".merge-request-notes, .merge-request-commits").hide();
+ $(".merge-request-notes").hide();
$(".dashboard-loader").hide()},
dataType: "script"});
}
diff --git a/app/assets/javascripts/note.js b/app/assets/javascripts/note.js
index c791623b91d..41759671ff8 100644
--- a/app/assets/javascripts/note.js
+++ b/app/assets/javascripts/note.js
@@ -1,49 +1,66 @@
var NoteList = {
+notes_path: null,
+target_params: null,
+target_id: 0,
+target_type: null,
first_id: 0,
last_id: 0,
-resource_name: null,
+disable:false,
init:
- function(resource_name, first_id, last_id) {
- this.resource_name = resource_name;
- this.first_id = first_id;
- this.last_id = last_id;
+ 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();
- this.initLoadMore();
- },
-getOld:
- function() {
- $('.loading').show();
- $.ajax({
- type: "GET",
- url: location.href,
- data: "first_id=" + this.first_id,
- complete: function(){ $('.loading').hide()},
- dataType: "script"});
+ $('.delete-note').live('ajax:success', function() {
+ $(this).closest('li').fadeOut(); });
+
+ $("#new_note").live("ajax:before", function(){
+ $("#submit_note").attr("disabled", "disabled");
+ })
+
+ $("#new_note").live("ajax:complete", function(){
+ $("#submit_note").removeAttr("disabled");
+ })
+
+ $("#note_note").live("click", function(){
+ $(this).css("height", "100px");
+ $('.attach_holder').show();
+ });
+
},
-append:
- function(id, html) {
- this.first_id = id;
- $("#notes-list").append(html);
- this.initLoadMore();
+
+/**
+ * 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(fid, lid, html) {
- this.first_id = fid;
- this.last_id = lid;
- $("#notes-list").html(html);
- this.initLoadMore();
+ function(html) {
+ $("#new_notes_list").html(html);
},
prepend:
function(id, html) {
if(id != this.last_id) {
- this.last_id = id;
- $("#notes-list").prepend(html);
+ $("#new_notes_list").prepend(html);
}
},
@@ -52,8 +69,8 @@ getNew:
// refersh notes list
$.ajax({
type: "GET",
- url: location.href,
- data: "last_id=" + this.last_id,
+ url: this.notes_path,
+ data: "last_id=" + this.last_id + this.target_params,
dataType: "script"});
},
@@ -62,25 +79,85 @@ refresh:
// refersh notes list
$.ajax({
type: "GET",
- url: location.href,
- data: "first_id=" + this.first_id + "&last_id=" + this.last_id,
+ url: this.notes_path,
+ data: "first_id=" + this.first_id + "&last_id=" + this.last_id + this.target_params,
dataType: "script"});
},
-initRefresh:
+
+/**
+ * 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() {
- // init timer
- var intNew = setInterval("NoteList.getNew()", 15000);
- var intRefresh = setInterval("NoteList.refresh()", 90000);
+ $('.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() {
- $(window).bind('scroll', function(){
- if($(window).scrollTop() == $(document).height() - $(window).height()){
- $(window).unbind('scroll');
+ $(document).endlessScroll({
+ bottomPixels: 400,
+ fireDelay: 1000,
+ fireOnce:true,
+ ceaseFire: function() {
+ return NoteList.disable;
+ },
+ callback: function(i) {
NoteList.getOld();
}
- });
+ });
}
}
diff --git a/app/assets/javascripts/projects.js b/app/assets/javascripts/pager.js
index 90de73a112d..d42ae1e05d1 100644
--- a/app/assets/javascripts/projects.js
+++ b/app/assets/javascripts/pager.js
@@ -1,12 +1,14 @@
-var ProjectsList = {
+var Pager = {
limit:0,
offset:0,
+ disable:false,
init:
function(limit) {
this.limit=limit;
this.offset=limit;
this.initLoadMore();
+ $('.loading').show();
},
getOld:
@@ -22,21 +24,27 @@ var ProjectsList = {
append:
function(count, html) {
- $(".tile").append(html);
+ $(".content_list").append(html);
if(count > 0) {
this.offset += count;
- this.initLoadMore();
+ } else {
+ this.disable = true;
}
},
initLoadMore:
function() {
- $(window).bind('scroll', function(){
- if($(window).scrollTop() == $(document).height() - $(window).height()){
- $(window).unbind('scroll');
+ $(document).endlessScroll({
+ bottomPixels: 400,
+ fireDelay: 1000,
+ fireOnce:true,
+ ceaseFire: function() {
+ return Pager.disable;
+ },
+ callback: function(i) {
$('.loading').show();
- ProjectsList.getOld();
+ Pager.getOld();
}
- });
+ });
}
}
diff --git a/app/assets/javascripts/team.js b/app/assets/javascripts/team.js
index e079a9e4574..f4b04354f53 100644
--- a/app/assets/javascripts/team.js
+++ b/app/assets/javascripts/team.js
@@ -1,7 +1,7 @@
function backToMembers(){
- $("#team_member_new").hide("slide", { direction: "right" }, 150, function(){
+ $("#new_team_member").hide("slide", { direction: "right" }, 150, function(){
$("#team-table").show("slide", { direction: "left" }, 150, function() {
- $("#team_member_new").remove();
+ $("#new_team_member").remove();
$(".add_new").show();
});
});
diff --git a/app/assets/javascripts/tree.js b/app/assets/javascripts/tree.js
index 2e9bcc82a2b..1c62751ad25 100644
--- a/app/assets/javascripts/tree.js
+++ b/app/assets/javascripts/tree.js
@@ -5,21 +5,24 @@
var Tree = {
init:
function() {
- (new Image).src = "ajax-loader-facebook.gif";
-
- $('#tree-slider td.tree-item-file-name a, #tree-breadcrumbs a').live("click", function() {
- history.pushState({ path: this.path }, '', this.href)
+ $('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live("click", function() {
$("#tree-content-holder").hide("slide", { direction: "left" }, 150)
})
- $("#tree-slider tr.tree-item").live('click', function(e){
+ $('.project-refs-form').live({
+ "ajax:beforeSend": function() {
+ $("#tree-content-holder").hide("slide", { direction: "left" }, 150);
+ }
+ })
+
+ $("#tree-slider .tree-item").live('click', function(e){
if(e.target.nodeName != "A") {
- link = $(this).find("td.tree-item-file-name a");
+ link = $(this).find(".tree-item-file-name a");
link.trigger("click");
}
});
- $('#tree-slider td.tree-item-file-name a, #tree-breadcrumbs a').live({
+ $('#tree-slider .tree-item-file-name a, .breadcrumb a, .project-refs-form').live({
"ajax:beforeSend": function() { $('.tree_progress').addClass("loading"); },
"ajax:complete": function() { $('.tree_progress').removeClass("loading"); }
});
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
index 5a1fb42f69d..3d809b56d11 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.css
@@ -7,5 +7,5 @@
*= require jquery-ui/jquery.tagify
*= require chosen
*= require_self
- *= require common
+ *= require main
*/
diff --git a/app/assets/stylesheets/commits.css.scss b/app/assets/stylesheets/commits.css.scss
deleted file mode 100644
index b1fa9c1827c..00000000000
--- a/app/assets/stylesheets/commits.css.scss
+++ /dev/null
@@ -1,191 +0,0 @@
-/* Commit Page */
-body.project-page.commits-page .commit-info{float: right;}
-body.project-page.commits-page .commit-info data{
- padding: 4px 10px;
- font-size: 11px;
-}
-body.project-page.commits-page .commit-info data.commit-button{
- background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.192, #fff), to(#f4f4f4));
- background-image: -webkit-linear-gradient(#fff 19.2%, #f4f4f4);
- background-image: -moz-linear-gradient(#fff 19.2%, #f4f4f4);
- background-image: -o-linear-gradient(#fff 19.2%, #f4f4f4);
- box-shadow: 0 -1px 0 white inset;
- display: block;
- border: 1px solid #eee;
- border-radius: 5px;
- margin-bottom: 2px;
- position: relative;
- padding-right: 20px;
-}
-
-body.project-page.commits-page .commit-button i{
- background: url('images.png') no-repeat -138px -27px;
- width: 6px;
- height: 9px;
- float: right;
- position: absolute;
- top: 6px;
- right: 5px;
-}
-body.project-page.commits-page .commits-date {display: block; width: 100%; margin-bottom: 20px}
-body.project-page.commits-page .commits-date .data {padding: 0}
-body.project-page.commits-page a.commit{padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
-body.project-page.commits-page .commits-date a.commit {padding: 10px; border-bottom: none; overflow: hidden; display: block;}
-body.project-page.commits-page .commits-date a.commit:last-child{border-bottom: 0}
-body.project-page.commits-page .commits-date a.commit img{float: left; margin-right: 10px;}
-body.project-page.commits-page .commits-date a.commit span.commit-title{display: block;}
-body.project-page.commits-page .commits-date a.commit span.commit-title{margin-bottom: 10px}
-body.project-page.commits-page .commits-date a.commit span.commit-author{color: #999; font-weight: normal; font-style: italic;}
-body.project-page.commits-page .commits-date a.commit span.commit-author strong{font-weight: bold; font-style: normal;}
-
-/* eo Commit Page */
-/** Commit diff view **/
-.diff_file {
- border:1px solid #CCC;
- margin-bottom:1em;
-
- .diff_file_header {
- padding:5px 5px;
- border-bottom:1px solid #CCC;
- background: #eee;
- }
- .diff_file_content {
- overflow:auto;
- overflow-y:hidden;
- background:#fff;
- color:#333;
- font-size: 12px;
- font-family: 'Courier New', 'andale mono','lucida console',monospace;
- }
- .diff_file_content_image {
- background:#eee;
- text-align:center;
- img {
- padding:100px;
- max-width:300px;
- }
- }
-}
-
-.diff_file_content{
- table {
- border:none;
- margin:0px;
- padding:0px;
- }
- .old_line, .new_line {
- margin:0px;
- padding:0px;
- border:none;
- background:#F7F7F7;
- color:#aaa;
- padding: 0px 5px;
- border-right: 1px solid #ccc;
- text-align:right;
- min-width:35px;
- max-width:35px;
- width:35px;
- a {
- float:left;
- width:35px;
- font-weight:normal;
- color:#aaa;
- &:hover {
- text-decoration:underline;
- }
- }
- }
- .line_content {
- white-space:pre;
- height:14px;
- margin:0px;
- padding:0px;
- border:none;
- &.new {
- background: #DFD;
- }
- &.old {
- background: #FDD;
- }
- }
-}
-
-pre.commit_message {
- white-space: pre-wrap;
- font-family: "Helvetica", sans-serif;
- color: #555;
- font-weight:bold;
- font-size:15px;
-}
-
-/** COMMIT BLOCK **/
-.commit-title{display: block;}
-.commit-title{margin-bottom: 10px}
-.commit-author{color: #999; font-weight: normal; font-style: italic;}
-.commit-author strong{font-weight: bold; font-style: normal;}
-
-/** bordered list **/
-ul.bordered-list {
- margin:5px 0px;
- padding:0px;
- li {
- padding: 5px 0;
- border-bottom: 1px solid #EEE;
- overflow: hidden;
- display: block;
- margin:0px;
- }
-}
-
-ul.bordered-list li:last-child { border:none }
-
-.line_holder {
- &:hover {
- td {
- background: #FFFFCF !important;
- }
- }
-}
-
-.per_line_form {
- font-family: "Helvetica", sans-serif;
- background: #2FA0BB;
-
- td {
- padding:0;
- }
-
- form {
- margin:5px;
- width: 756px;
- border: 1px solid #CCC;
- padding: 20px;
- background: white;
- }
-}
-
-
-tr.line_notes_row {
- font-family: "Helvetica", sans-serif;
- &:hover {
- background:none;
- }
- td {
- margin:0px;
- padding:0px;
- border-bottom:1px solid #DEE2E3;
-
-
- ul {
- display:block;
- list-style:none;
- margin:0px;
- padding:0px;
-
- li {
- border-top:1px solid #DEE2E3;
- padding:10px;
- }
- }
- }
-}
diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss
index 4c6544a4a55..5670f1e08e9 100644
--- a/app/assets/stylesheets/common.scss
+++ b/app/assets/stylesheets/common.scss
@@ -1,55 +1,53 @@
-$text_color:#222;
-$lite_text_color: #666;
-$link_color:#111;
-$active_link_color:#2FA0BB;
-$active_bg_color:#79C3E0;
-$active_bd_color: #2FA0BB;
-$border_color:#CCC;
-$lite_border_color:#EEE;
-$app_width:980px;
-$app_padding:20px;
-$bg_color: #FFF;
-$styled_border_color: #2FA0BB;
-
-/** MIXINS **/
-@mixin round-borders-bottom($radius) {
- border-top: 1px solid #eaeaea;
- -moz-border-radius-bottomright: $radius;
- -moz-border-radius-bottomleft: $radius;
- border-bottom-right-radius: $radius;
- border-bottom-left-radius: $radius;
- -webkit-border-bottom-left-radius: $radius;
- -webkit-border-bottom-right-radius: $radius;
-}
-
-@mixin round-borders-top($radius) {
- border-top: 1px solid #eaeaea;
- -moz-border-radius-topright: $radius;
- -moz-border-radius-topleft: $radius;
- border-top-right-radius: $radius;
- border-top-left-radius: $radius;
- -webkit-border-top-left-radius: $radius;
- -webkit-border-top-right-radius: $radius;
-}
-
-@mixin round-borders-all($radius) {
- border: 1px solid #eaeaea;
- -moz-border-radius: $radius;
- -webkit-border-radius: $radius;
- border-radius: $radius;
+a {
+ color: $link_color;
+ &:hover {
+ text-decoration:none;
+ color: $style_color;
+ }
+
+ &.btn {
+ color: $style_color;
+ }
+}
+
+.vlink {
+ color: $link_color !important;
+}
+
+.pills a:hover {
+ background-color:#ccc;
+}
+
+.pills .active a {
+ background-color: #aaa;
+}
+
+.label {
+ background-color: #474D57;
+}
+
+.tabs > li > a, .pills > li > a {
+ color:$style_color;
+}
+
+.diff_file_header a,
+.file_stats a {
+ color:$style_color;
}
/** COLORS **/
.cgray { color:gray; }
.cred { color:#D12F19; }
.cgreen { color:#44aa22; }
+.cblack { color:#111; }
+.cwhite { color:#fff !important }
/** COMMON STYLES **/
.left {
float:left;
}
.right {
- float:right;
+ float:right !important;
}
.width-50p{
width:50%;
@@ -78,38 +76,559 @@ $styled_border_color: #2FA0BB;
.no-borders {
border:none;
}
+table.no-borders {
+ border:none;
+ tr, td { border:none }
+}
.no-padding {
padding:0 !important;
}
+.underlined {
+ border-bottom: 1px solid $border_color;
+}
-/* General */
+/** LAYOUT **/
-body.collapsed {
- background-color: $bg_color;
+.container {
+ width:$min_app_width;
+ padding-top:0;
+ z-index:5;
+}
- #container{
- margin: auto;
- margin-top:51px;
- width: $app_width;
- border-top: 0;
- background-color: $bg_color;
+.container .content {
+ margin:0 $app_padding;
+}
+
+.container .sidebar {
+ width: 200px;
+ height:100%;
+ min-height:450px;
+ float:right;
+}
+
+img.avatar {
+ float:left;
+ margin-right:15px;
+ width:40px;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+img.lil_av {
+ padding-left: 5px;
+ position: relative;
+ top: 3px;
+}
+
+.media-grid {
+ h3, h2 , h4 {
+ &.media_h {
+ padding-left:10px;
+ float:left;
+ }
}
}
-a {
+.wll {
+ background-color: #FFF;
+ padding: 10px 5px;
+ min-height: 20px;
+ border-bottom: 1px solid #eee;
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05);
+ cursor:pointer;
+ &:hover {
+ background:$hover;
+ }
+ &:last-child { border:none }
+ p { padding-top:5px; margin:0; color:$style_color;}
+ .author { color: #999; }
+ p {
+ color:#222;
+ margin-bottom: 0;
+ img {
+ position:relative;
+ top:3px;
+ }
+ }
+}
+
+.visible_link,
+.author_link {
color: $link_color;
}
+.entry {
+ position: relative;
+ padding: 7px 15px;
+ margin-bottom: 18px;
+ color: #404040;
+ filter:none;
+
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
+
+ background:#F1F1F1;
+ border: 1px solid #ccc;
+
+
+ p {
+ color:$style_color;
+ margin-bottom: 0;
+ img {
+ position:relative;
+ top:3px;
+ }
+ }
+}
+
+.widget {
+ @include shade;
+ padding:20px;
+ margin-bottom:20px;
+ border: 1px solid #DDD;
+ border-radius: 5px;
+ background:#fafafa;
+
+ .link_holder {
+ background:#eee;
+ position:relative;
+ left:-20px;
+ top:20px;
+ padding:10px 20px;
+ width:100%;
+ border-top:1px solid #ccc;
+
+ a {
+ font-size:14px;
+ color:#666;
+ }
+ }
+}
+
+
+.ui-box {
+ margin-bottom: 40px;
+ @include round-borders-all(4px);
+ @include shade;
+ border-color:#ddd;
+
+ ul {
+ margin:0;
+ }
+
+ h5, .title {
+ padding: 0 10px;
+ background:#f5f5f5;
+ border-bottom: 1px solid #eee;
+ @include round-borders-top(4px);
+ border-top:none;
+
+ form {
+ padding-top:16px;
+ }
+ }
+
+ .row_title {
+ font-weight:bold;
+ color:#444;
+ &:hover {
+ text-decoration:underline;
+ }
+ }
+
+ li, .wll {
+ padding:10px;
+ &:first-child {
+ @include round-borders-top(4px);
+ border-top:none;
+ }
+
+ &:last-child {
+ @include round-borders-bottom(4px);
+ border:none;
+ }
+ }
+
+}
+
+.help li { color:#111 }
+
+.back_link {
+ text-decoration:underline;
+ font-size:14px;
+ font-weight:bold;
+ padding:10px 0;
+ padding-bottom:0;
+}
+
+.info_link {
+ margin-right:5px;
+ float:left;
+
+ img {
+ width:20px;
+ }
+}
+
+.borders {
+ border: 1px solid #ccc;
+ @include shade;
+}
+
+.download_repo_link {
+ background: url("images.png") no-repeat 0 -48px;
+ padding-left:20px;
+}
+
+.number {
+ border-radius: 4px;
+ text-shadow: none;
+ background: rgba(0,0,0,.12);
+ text-align: center;
+ padding: 2px 4px;
+ line-height:20px;
+ margin-left:2px;
+}
+
+table a code {
+ position: relative;
+ top: -2px;
+ margin-right: 3px;
+}
+
+.span12 hr{
+ margin-top: 5px;
+}
+
+.btn.padded {
+ margin-right:3px;
+}
-@import "style.scss";
-@import "projects.css.scss";
-@import "commits.css.scss";
-@import "notes.css.scss";
-@import "merge_requests.css.scss";
-@import "highlight.css.scss";
-@import "highlight.black.css.scss";
-@import "issues.css.scss";
-@import "commits.css.scss";
+.loading {
+ margin:20px auto;
+ background: url(ajax-loader-facebook.gif) no-repeat center center;
+ width:40px;
+ height:40px;
+}
+
+/** FLASH message **/
+#flash_container {
+ height:45px;
+ position:fixed;
+ z-index:10001;
+ top:0px;
+ width:100%;
+ margin-bottom:15px;
+ overflow:hidden;
+ background:white;
+ cursor:pointer;
+ border-bottom:1px solid #777;
+
+ h4 {
+ color:#444;
+ font-size:22px;
+ padding-top:5px;
+ margin:2px;
+ }
+}
+
+.git_url_wrapper {
+ margin-right:50px
+}
+.file_stats {
+ span {
+ img {
+ width:14px;
+ float:left;
+ margin-right:6px;
+ padding:2px 0;
+ }
+ }
+}
+
+.handle:hover {
+ cursor:move;
+}
+
+span.update-author {
+ display:block;
+}
+span.update-author {
+ color:#999;
+ font-weight:normal;
+ font-style:italic;
+}
+span.update-author strong {
+ font-weight:bold;
+ font-style: normal;
+}
+
+/** UPDATE ITEM **/
+span.update-author {
+ display:block;
+}
+/** END UPDATE ITEM **/
+.ajax-tab-loading {
+ padding:40px;
+ display:none;
+}
+.dashboard-loader {
+ float:left;
+ margin:10px;
+ display:none;
+}
+.user-mention {
+ color:#2FA0BB;
+ font-weight:bold;
+}
-@import "top_panel.scss";
-@import "dashboard.scss";
-@import "tree.scss";
+a.project-update.titled {
+ position:relative;
+ padding-left:35% !important;
+ .title-block {
+ padding:10px;
+ width:35%;
+ position:absolute;
+ left:0;
+ top:0;
+ }
+}
+/**
+ * Project graph
+ */
+#holder {
+ cursor: move;
+ height: 70%;
+ overflow: hidden;
+}
+
+
+
+input.git_clone_url {
+ width:475px;
+}
+
+.team_member_row {
+ img {
+ width:60px;
+ }
+}
+
+.merge-request-form-holder {
+ select {
+ width:300px;
+ }
+}
+
+/** Issues **/
+#issue_assignee_id {
+ width:300px;
+}
+
+#new_issue_dialog textarea{
+ height: 100px;
+}
+
+.project_list_url {
+ width:250px;
+ background:#fff !important;
+}
+
+.project_tile {
+ @include shade;
+ @include round-borders-all(4px);
+ margin-bottom:20px;
+ width:298px;
+ float:left;
+ margin-left:20px;
+ border: 1px solid #DDD;
+ padding-bottom:20px;
+
+ .title {
+ background:#f5f5f5;
+ padding: 5px 10px 2px 20px;
+ border-bottom: 1px solid #DDD;
+ margin-bottom: 15px;
+
+ h3 {
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+ }
+ .data {
+ margin: 0 20px;
+ }
+ .buttons {
+ margin: 0 20px;
+ }
+}
+
+/**
+ *
+ * COMMIT SHOw
+ *
+ */
+.diff_file {
+ border:1px solid #CCC;
+ margin-bottom:1em;
+
+ .diff_file_header {
+ padding:5px 5px;
+ border-bottom:1px solid #CCC;
+ background: #eee;
+ }
+ .diff_file_content {
+ overflow:auto;
+ overflow-y:hidden;
+ background:#fff;
+ color:#333;
+ font-size: 12px;
+ font-family: 'Menlo', 'Courier New', 'andale mono','lucida console',monospace;
+ }
+ .diff_file_content_image {
+ background:#eee;
+ text-align:center;
+ img {
+ padding:100px;
+ max-width:300px;
+ }
+ }
+}
+
+.diff_file_content{
+ table {
+ border:none;
+ margin:0px;
+ padding:0px;
+ tr {
+ td {
+ font-size:12px;
+ }
+ }
+ }
+ .old_line, .new_line {
+ margin:0px;
+ padding:0px;
+ border:none;
+ background:#F7F7F7;
+ color:#aaa;
+ padding: 0px 5px;
+ border-right: 1px solid #ccc;
+ text-align:right;
+ min-width:35px;
+ max-width:35px;
+ width:35px;
+ moz-user-select: none;
+ -khtml-user-select: none;
+ user-select: none;
+ a {
+ float:left;
+ width:35px;
+ font-weight:normal;
+ color:#aaa;
+ &:hover {
+ text-decoration:underline;
+ }
+ }
+ }
+ .line_content {
+ white-space:pre;
+ height:14px;
+ margin:0px;
+ padding:0px;
+ border:none;
+ &.new {
+ background: #CFD;
+ }
+ &.old {
+ background: #FDD;
+ }
+ &.matched {
+ color:#ccc;
+ background:#fafafa;
+ }
+ }
+}
+
+/** COMMIT BLOCK **/
+.commit-title{display: block;}
+.commit-title{margin-bottom: 10px}
+.commit-author, .commit-committer{display: block;color: #999; font-weight: normal; font-style: italic;}
+.commit-author strong, .commit-committer strong{font-weight: bold; font-style: normal;}
+
+/** bordered list **/
+ul.bordered-list {
+ margin:5px 0px;
+ padding:0px;
+ li {
+ padding: 5px 0;
+ border-bottom: 1px solid #EEE;
+ overflow: hidden;
+ display: block;
+ margin:0px;
+ }
+}
+
+ul.bordered-list li:last-child { border:none }
+
+.line_holder {
+ &:hover {
+ td {
+ background: #FFFFCF !important;
+ }
+ }
+}
+
+li.commit {
+ .avatar {
+ width:24px;
+ top:-3px;
+ margin-right:10px;
+ margin-left:10px;
+ }
+
+ code {
+ padding:4px;
+ }
+}
+p.time {
+ color: #999;
+ font-size: 90%;
+ margin: 30px 3px 3px 2px;
+}
+
+
+.dashboard_category {
+ margin-bottom:30px;
+
+ .dashboard_block {
+ width:700px;
+ margin:auto;
+
+ .wll {
+ border:none;
+ &:hover {
+ background:none;
+ }
+
+ h4 {
+ color:#666;
+ }
+ }
+ }
+}
+
+.event_feed {
+ ul {
+ margin-left:50px;
+ }
+}
diff --git a/app/assets/stylesheets/dashboard.scss b/app/assets/stylesheets/dashboard.scss
deleted file mode 100644
index 5e38fcc6d63..00000000000
--- a/app/assets/stylesheets/dashboard.scss
+++ /dev/null
@@ -1,30 +0,0 @@
-body.dashboard-page h2.icon span{ background-position: 9px -69px; }
-body.dashboard-page header{margin-bottom: 0}
-body.dashboard-page .news-feed{margin-left: 285px; min-height: 600px; margin-top: 20px; margin-right:2px; padding:20px;}
-body.dashboard-page .dashboard-content{ position: relative; float: left; width: 100%; height: 100%; }
-body.dashboard-page .news-feed h2{float: left;}
-
-body.dashboard-page aside{
- min-height: 820px; position: relative; top: 0; bottom: 0; right: 0; width: 260px; float: left; border-right: 1px solid $border_color; padding:20px; padding-right:0;
- h4{margin: 0; border-bottom: 1px solid #ccc; padding: 20px 20px 20px 0px; font-size: 11px; font-weight: bold; text-transform: uppercase;}
- h4 a.button-small{float: right; text-transform: none; border-radius: 4px; margin-right: 2%; margin-top: -4px; display: block;}
- .project-list {list-style: none; margin: 0; padding: 0;}
- .project-list li a {background: white; color: #{$blue_link}; display: block; border-bottom: 1px solid $lite_border_color; padding: 14px 6% 14px 0px;}
- .project-list li a span.project-name{font-size: 14px; display: block; margin-bottom: 8px}
- .project-list li a span.time{color: #666; font-weight: normal; font-size: 11px}
- .project-list li a span.arrow{float: right; background: #E3E5EA; padding: 10px; border-radius: 5px; margin-top: 2px; text-shadow: none; color: #999}
-}
-
-body.dashboard-page .news-feed .project-updates {
- margin-bottom: 20px; display: block; width: 100%;
- .data{ padding: 0}
- a.project-update {padding: 10px; overflow: hidden; display: block;}
- a.project-update:last-child{border-bottom: 0}
- a.project-update img{float: left; margin-right: 10px;}
- a.project-update span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;}
- a.project-update span.update-title{margin-bottom: 10px}
- a.project-update span.update-author{color: #999; font-weight: normal; font-style: italic;}
- a.project-update span.update-author strong{font-weight: bold; font-style: normal;}
-}
-/* eo Dashboard Page */
-
diff --git a/app/assets/stylesheets/highlight.black.css.scss b/app/assets/stylesheets/highlight.black.scss
index e094e48fad5..e63e08c8e94 100644
--- a/app/assets/stylesheets/highlight.black.css.scss
+++ b/app/assets/stylesheets/highlight.black.scss
@@ -1,5 +1,6 @@
.black .highlighttable {
background: #333;
+ td.linenos { border:none; }
pre { color: #eee }
.highlight { background: #333; border-left:1px solid #555; }
diff --git a/app/assets/stylesheets/highlight.css.scss b/app/assets/stylesheets/highlight.scss
index d65865ecdb2..0dbfc0ed964 100644
--- a/app/assets/stylesheets/highlight.css.scss
+++ b/app/assets/stylesheets/highlight.scss
@@ -10,13 +10,15 @@ table.highlighttable
margin:0px;
padding:0px;
font-size:12px;
- table-layout:fixed
+ table-layout:fixed;
+ background: #F7F7F7;
}
td.code,
td.linenos{
padding:0;
margin:0;
+ border-top:0;
vertical-align:top;
}
@@ -24,8 +26,16 @@ td.linenos{
background:none;
padding:10px 0px 0px 10px;
margin-left:0px;
+ border-left: 1px solid #DEE2E3;
+ background: white;
}
+
+.linenodiv pre,
.highlight pre{
+ margin:0;
+ padding:0;
+ background:none;
+ border:none;
}
.linenodiv pre {
@@ -48,7 +58,7 @@ td.code .highlight {
table.highlighttable pre{
padding:0;
margin:0;
- font-family: 'Courier New', 'andale mono','lucida console',monospace;
+ font-family: 'Menlo', 'Courier New', 'andale mono','lucida console',monospace;
color: #333;
text-align:left;
}
@@ -62,7 +72,7 @@ table.highlighttable pre{
padding:0;
line-height:2.0;
margin:0;
- font-family: 'Courier New', 'andale mono','lucida console',monospace;
+ font-family: 'Menlo', 'Courier New', 'andale mono','lucida console',monospace;
color: #333;
text-align:left;}
}
diff --git a/app/assets/stylesheets/issues.css.scss b/app/assets/stylesheets/issues.css.scss
deleted file mode 100644
index d2341edcf33..00000000000
--- a/app/assets/stylesheets/issues.css.scss
+++ /dev/null
@@ -1,84 +0,0 @@
-.issue-number {
- float: left;
- border-radius: 5px;
- text-shadow: none;
- background: rgba(0, 0, 0, 0.12);
- text-align: center;
- padding: 14px 8px;
- width: 40px;
- margin-right: 10px;
- color: #444;
-}
-
-.issues_filter {
- margin:10px 0;
- .left {
- margin-right:15px;
- }
-}
-
-.top_panel_issues{
- #issue_search_form {
- margin:5px 0;
- input {
- border:1px solid #D3D3D3;
- padding: 3px;
- height: 28px;
- width: 250px;
- -webkit-appearance:none;
- box-sizing: border-box;
- -moz-box-sizing: border-box;
-
- &:focus {
- border-color:#c2e1ef;
- }
- }
- }
-}
-
-/** ISSUES LIST **/
-.issue .action-links {
- display:none;
- a {
- margin-left:10px;
- }
-}
-.issue:hover .action-links { display:block; }
-.issue-show-holder {
- width:100%;
- .data p { font-size:16px }
-}
-
-#issue_assignee_id {
- width:300px;
-}
-
-.issue-form-holder .ui-box .data {
- margin: 0;
- padding: 0;
-}
-
-body.project-page .merge-request-form-holder table.no-borders tr,
-body.project-page .merge-request-form-holder table.no-borders td,
-body.project-page .issue-form-holder table.no-borders tr,
-body.project-page .issue-form-holder table.no-borders td,
-body.project-page .new_snippet table tr,
-body.project-page .new_snippet table td,
-body.project-page .edit_snippet table tr,
-body.project-page .edit_snippet table td
-{
- &:hover {
- background:none;
- }
-}
-
-
-#issues-table {
- tr {
- border-top: 1px solid $lite_border_color;
- &:first-child {
- border:none;
- }
- }
-
-}
diff --git a/app/assets/stylesheets/login.scss b/app/assets/stylesheets/login.scss
new file mode 100644
index 00000000000..3bba7062a24
--- /dev/null
+++ b/app/assets/stylesheets/login.scss
@@ -0,0 +1,44 @@
+/* Login Page */
+body.login-page{
+ padding-top: 10%;
+ background:#f1f1f1;
+}
+
+.login-box{
+ width: 304px;
+ position: relative;
+ border-radius: 5px;
+ margin: auto;
+ padding: 20px;
+ background: white;
+}
+
+.login-box .login-logo{
+ margin: 10px 0 30px 0;
+ display: block;
+}
+
+.login-box input.text{background-color: #f1f1f1; font-size: 16px; border-radius: 0; padding: 14px 10px; width: 280px}
+
+.login-box input.text.top{
+ -webkit-border-top-left-radius: 5px;
+ -webkit-border-top-right-radius: 5px;
+ -moz-border-radius-topleft: 5px;
+ -moz-border-radius-topright: 5px;
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px;
+}
+
+.login-box input.text.bottom{
+ -webkit-border-bottom-right-radius: 5px;
+ -webkit-border-bottom-left-radius: 5px;
+ -moz-border-radius-bottomright: 5px;
+ -moz-border-radius-bottomleft: 5px;
+ border-bottom-right-radius: 5px;
+ border-bottom-left-radius: 5px;
+ border-top: 0;
+ margin-bottom: 20px;
+}
+
+.login-box a.forgot{float: right; padding-top: 6px}
+
diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss
new file mode 100644
index 00000000000..5881880982a
--- /dev/null
+++ b/app/assets/stylesheets/main.scss
@@ -0,0 +1,118 @@
+@import "bootstrap";
+
+/** GITLAB colors **/
+$text_color:#222;
+$lite_text_color: #666;
+$link_color:#2A79A3;
+$active_link_color:#2FA0BB;
+$active_bg_color:#79C3E0;
+$active_bd_color: #2FA0BB;
+$border_color:#CCC;
+$lite_border_color:#EEE;
+$min_app_width:980px;
+$max_app_width:980px;
+$app_padding:20px;
+$bg_color: #FFF;
+$styled_border_color: #2FA0BB;
+$color: "#4BB8D2";
+$blue_link: "#2fa0bb";
+
+
+/** Style colors **/
+$style_color: #474D57;
+$hover: #FDF5D9;
+
+
+/** MIXINS **/
+@mixin shade {
+ -moz-box-shadow: 0 0 3px #ddd;
+ -webkit-box-shadow: 0 0 3px #ddd;
+ box-shadow: 0 0 3px #ddd;
+}
+
+
+@mixin round-borders-bottom($radius) {
+ border-top: 1px solid #eaeaea;
+ -moz-border-radius-bottomright: $radius;
+ -moz-border-radius-bottomleft: $radius;
+ border-bottom-right-radius: $radius;
+ border-bottom-left-radius: $radius;
+ -webkit-border-bottom-left-radius: $radius;
+ -webkit-border-bottom-right-radius: $radius;
+}
+
+@mixin round-borders-top($radius) {
+ border-top: 1px solid #eaeaea;
+ -moz-border-radius-topright: $radius;
+ -moz-border-radius-topleft: $radius;
+ border-top-right-radius: $radius;
+ border-top-left-radius: $radius;
+ -webkit-border-top-left-radius: $radius;
+ -webkit-border-top-right-radius: $radius;
+}
+
+@mixin round-borders-all($radius) {
+ border: 1px solid #eaeaea;
+ -moz-border-radius: $radius;
+ -webkit-border-radius: $radius;
+ border-radius: $radius;
+}
+
+/**
+ * This file represent some UI that can be changed
+ * during web app restyle or theme select.
+ *
+ * Next items should be placed there
+ * - link colors
+ * - header styles
+ * - main menu styles
+ *
+ */
+@import "ui_basic.scss";
+
+/**
+ * UI mars theme
+ */
+@import "ui_mars.scss";
+
+/**
+ * Most of application styles placed here.
+ * This file represent common UI that should not be changed between themes
+ * or project restyling like form width or user avatar class or commit title
+ *
+ * TODO: clean it
+ */
+@import "common.scss";
+
+/**
+ * This scss file redefine chozen selectbox styles for
+ * project Branch/Tag select element
+ */
+@import "ref_select.scss";
+
+/**
+ * Code (files list) styles. Browsing project files there
+ */
+@import "tree.scss";
+
+/**
+ * This file represent notes(comments) styles
+ */
+@import "notes.scss";
+
+/**
+ * Devise styles
+ */
+@import "login.scss";
+
+/**
+ * CODE HIGHTLIGHT BASE
+ *
+ */
+@import "highlight.scss";
+
+/**
+ * CODE HIGHTLIGHT DARK schema
+ *
+ */
+@import "highlight.black.scss";
diff --git a/app/assets/stylesheets/merge_requests.css.scss b/app/assets/stylesheets/merge_requests.css.scss
deleted file mode 100644
index 2b60605b255..00000000000
--- a/app/assets/stylesheets/merge_requests.css.scss
+++ /dev/null
@@ -1,10 +0,0 @@
-// Place all the styles related to the MergeRequests controller here.
-// They will automatically be included in application.css.
-// You can use Sass (SCSS) here: http://sass-lang.com/
-
-
-.merge-request-form-holder {
- select {
- width:300px;
- }
-}
diff --git a/app/assets/stylesheets/notes.css.scss b/app/assets/stylesheets/notes.css.scss
deleted file mode 100644
index 4aba53cfd5c..00000000000
--- a/app/assets/stylesheets/notes.css.scss
+++ /dev/null
@@ -1,52 +0,0 @@
-/** Notes **/
-
-#notes-list {
- display:block;
- list-style:none;
- margin:0px;
- padding:0px;
-}
-
-.issue_notes {
- .note_content {
- float:left;
- width:400px;
- }
-}
-
-/* Note textare */
-#note_note {
- height:100px;
- width:97%;
- font-size:14px;
-}
-
-#new_note {
- #note_note {
- height:25px;
- }
- .attach_holder {
- display:none;
- }
-}
-
-#notes-list .note .delete-note { display:none; }
-#notes-list .note:hover .delete-note { display:block; }
-
-body.project-page #notes-list .note {padding: 10px 0; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
-body.project-page #notes-list .note img{float: left; margin-right: 10px;}
-body.project-page #notes-list .note span.note-title{display: block;}
-body.project-page #notes-list .note span.note-title{margin-bottom: 10px}
-body.project-page #notes-list .note span.note-author{color: #999; font-weight: normal; font-style: italic;}
-body.project-page #notes-list .note span.note-author strong{font-weight: bold; font-style: normal;}
-
-
-.note .note-title { margin-left:55px; }
-
-p.notify_controls input{
- margin: 5px;
-}
-
-p.notify_controls span{
- font-weight: 700;
-}
diff --git a/app/assets/stylesheets/notes.scss b/app/assets/stylesheets/notes.scss
new file mode 100644
index 00000000000..1f05d13b868
--- /dev/null
+++ b/app/assets/stylesheets/notes.scss
@@ -0,0 +1,121 @@
+/**
+ * Notes
+ *
+ */
+#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 {
+ .note_content {
+ float:left;
+ width:400px;
+ }
+}
+
+/* Note textare */
+#note_note {
+ height:100px;
+ width:97%;
+ font-size:14px;
+}
+
+#new_note {
+ #note_note {
+ height:25px;
+ }
+ .attach_holder {
+ display:none;
+ }
+}
+
+.note .delete-note {
+ display:none;
+ float:right;
+}
+.note:hover .delete-note { display:block; }
+.note {padding: 10px 0; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
+.note img{float: left; margin-right: 10px;}
+.note span.note-title{display: block;}
+.note span.note-title{margin-bottom: 10px}
+.note span.note-author{color: #999; font-weight: normal; font-style: italic;}
+.note span.note-author strong{font-weight: bold; font-style: normal;}
+.note p { color:$style_color; }
+.note .note-author { color: $style_color;}
+
+.note .note-title { margin-left:55px; }
+
+p.notify_controls input{
+ margin: 5px;
+}
+
+p.notify_controls span{
+ font-weight: 700;
+}
+
+tr.line_notes_row {
+ border-bottom:1px solid #DDD;
+ &.reply {
+ background:#eee;
+
+ td {
+ padding:7px 10px;
+ }
+ a.line_note_reply_link {
+ @include round-borders-all(4px);
+ border-color:#aaa;
+ background: #bbb;
+ padding: 3px 20px;
+ color: white;
+ }
+ }
+ ul {
+ margin:0;
+ li {
+ padding:0;
+ border:none;
+ }
+ }
+}
+
+.line_notes_row, .per_line_form { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; }
+
+.per_line_form {
+ background:#f5f5f5;
+ form { margin: 0; }
+ td {
+ border-bottom:1px solid #ddd;
+ }
+}
+
+td .line_note_link {
+ position:absolute;
+ margin-left:-70px;
+ margin-top:-10px;
+ z-index:10;
+ background: url("comment_add.png") no-repeat left 0;
+ width:32px;
+ height:32px;
+
+ opacity: 0.0;
+ filter: alpha(opacity=0);
+
+ &:hover {
+ opacity: 1.0;
+ filter: alpha(opacity=100);
+ }
+}
+
+.diff_file_content tr.line_holder:hover > td { background: $hover !important; }
+.diff_file_content tr.line_holder:hover > td .line_note_link {
+ opacity: 1.0;
+ filter: alpha(opacity=100);
+}
diff --git a/app/assets/stylesheets/projects.css.scss b/app/assets/stylesheets/projects.css.scss
deleted file mode 100644
index c9bba0c1f69..00000000000
--- a/app/assets/stylesheets/projects.css.scss
+++ /dev/null
@@ -1,572 +0,0 @@
-body.project-page h2.icon .project-name, body.project-page h2.icon d{border: 1px solid #eee; padding: 5px 30px 5px 10px; border-radius: 5px; position: relative;}
-body.project-page h2.icon .project-name i.arrow{float: right;
- position: absolute;
- right: 10px;
- top: 13px;
- display: block;
- background: url('images.png') no-repeat -97px -29px;
- width: 4px;
- height: 5px;
-}
-
-body.project-page h2.icon span{ background-position: -78px -68px; }
-body.project-page .project-container{ position: relative; float: left; width: 100%; height: 100%; padding-bottom: 10px;}
-body.project-page .page-title{margin-bottom: 0}
-
-body.project-page .project-sidebar {
- width: 110px;
- left: 0;
- top: 0;
- height: 100%;
- bottom: 0;
- position: absolute;
- float: left;
- display: inline-block;
- background: #FFF;
- padding: $app_padding;
- padding-right:0px;
- margin: 0;
- border-right: 1px solid $border_color;
-}
-
-body.projects-page input.text.git-url { font-size: 12px; border-radius: 5px; color: #666; box-shadow: 0 1px 2px rgba(0,0,0,.2) inset; padding: 8px 0 8px 30px; margin-bottom: 20px; background: white url('images.png') no-repeat 8px -40px; width: 136px}
-body.projects-page input.text.git-url {margin:10px 0 0 }
-.git_url_wrapper { margin-right:50px }
-
-.projects_selector:hover > .project-box{ -moz-box-shadow:0px 0px 10px rgba(0, 0, 0, .1); -webkit-box-shadow:0px 0px 10px rgba(0, 0, 0, .1); box-shadow:0px 0px 10px rgba(0, 0, 0, .1); }
-
-
-/* New project Page */
-.new-project-page .container table{background: white}
-body.project-page .project-sidebar aside{width: 109px}
-body.project-page .project-sidebar aside a{
- display: block;
- position: relative;
- padding: 15px 10px;
- margin: 10px 0 0 0;
-
-
-}
-body.project-page .project-sidebar aside a span.number{float: right; border-radius: 5px; text-shadow: none; background: rgba(0,0,0,.12); text-align: center; padding: 5px 8px; position: absolute; top: 10px; right: 10px}
-body.project-page .project-sidebar aside a.current {
- color: white;
- background: $active_bg_color;
- border: 1px solid $active_bd_color;
- border-radius:5px;
-
-
- -webkit-border-top-right-radius: 0;
- -webkit-border-bottom-right-radius: 0;
- -moz-border-radius-topright: 0px;
- -moz-border-radius-bottomright: 0px;
- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
- margin-right: -1px;
-}
-body.project-page .project-content{ padding: $app_padding; display: block; margin-left: 130px; min-height: 600px}
-body.project-page .project-content h2{ margin-top: 6px}
-body.project-page .project-content .button.right{margin-left: 20px}
-body.project-page table .commit a{color: #{$blue_link}}
-body.project-page table th, body.project-page table td{ border-bottom: 1px solid #DEE2E3;}
-body.project-page .fixed{position: fixed; }
-
-
-
-
-/** File stat **/
-.file_stats {
- span {
- img {
- width:14px;
- float:left;
- margin-right: 6px;
- padding:2px 0;
- }
- }
-}
-
-.round-borders {
- @include round-borders-all(4px);
- padding: 4px 0px;
-}
-
-table.round-borders {
- float:left;
- text-align: left;
-}
-
-
-
-/** PROJECTS **/
-input.ssh_project_url {
- padding:5px;
- margin:0px;
- float:right;
- width:400px;
- text-align:center;
-}
-
-#projects-list .project {
- height:50px;
-}
-
-#tree-slider .tree-item,
-#projects-list .project,
-#snippets-table .snippet,
-#issues-table .issue{
- cursor:pointer;
-}
-
-.clear {
- clear: both;
-}
-
-
-/** Buttons **/
-.lbutton,
-.lite_button {
- display:block;
- float:left;
- margin: 0px 5px 0px 0px;
- padding:5px 10px;
-
- font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;
- border:1px solid #D3D3D3;
- background:white;
- font-size:12px !important;
- line-height:130%;
- text-decoration:none;
- font-weight:bold;
- color:#565656;
- cursor:pointer;
-
- &:hover {
- border:1px solid #C2E1EF;
- color: #0099FF;
- }
-
- &.hm {
- margin: 0px 0px;
- }
-
- &.vm {
- margin: 5px 0px;
- }
-}
-
-#user_projects_limit{
- width: 60px;
-}
-
-.handle:hover{
- cursor: move;
-}
-
-.project-refs-form {
- span {
- background: none !important;
- position:static !important;
- width:auto !important;
- height: auto !important;
- }
-}
-
-.project-refs-select {
- width:200px;
-}
-
-.filter .left { margin-right:15px; }
-
-body.project-page table .commit {
- a.tree-commit-link {
- color:#444;
- &:hover {
- text-decoration:underline;
- }
- }
-}
-
-/** NEW PROJECT **/
-.new-project-hodler {
- .icon span { background-position: -31px -70px; }
- td { border-bottom: 1px solid #DEE2E3; }
-}
-
-/** Feed entry **/
-.commit,
-.snippet,
-.message {
- .title {
- color:#666;
- a { color:#666 !important; }
- p { margin-top:0px; }
- }
- .author { color: #999 }
-}
-
-/** JQuery UI **/
-.ui-autocomplete { @include round-borders-all(5px); }
-.ui-menu-item { cursor: pointer }
-.ui-selectmenu{
- @include round-borders-all(4px);
- margin-right:10px;
- font-size:1.5em;
- height:auto;
- font-weight:bold;
- .ui-selectmenu-status {
- padding:3px 10px;
- }
-}
-
-/** Snippets **/
-.new_snippet textarea,
-.edit_snippet textarea {
- height:300px;
- padding: 8px;
- width: 95%;
-}
-.snippet .action-links {
- display:none;
- a {
- margin-left:10px;
- }
-}
-.snippet:hover .action-links { display:block; }
-
-/** ISSUES TAGS **/
-.tag {
- @include round-borders-all(4px);
- padding:2px 4px;
- border:none;
- text-shadow:none;
-
- &.inline {
- display:inline;
- }
-
- &.high, &.closed {
- background: #D12F19;
- color:white;
- }
-
- &.today, &.open {
- background: #44aa22;
- color:white;
- }
-
- &.yours {
- background: #4466cc;
- color:white;
- }
- &.normal {
- background: #2c5ca6;
- color:white;
- }
- &.notes {
- background: #2c5c66;
- color:white;
- }
- &.note {
- background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8));
- background-image: -webkit-linear-gradient(#fefefe 7.6%, #F6F7F8);
- background-image: -moz-linear-gradient(#fefefe 7.6%, #F6F7F8);
- background-image: -o-linear-gradient(#fefefe 7.6%, #F6F7F8);
- color: #777;
- border: 1px solid #DEDFE1;
- }
- &.issue {
- background: #D12F19;
- color:white;
- }
- &.commit {
- background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8));
- background-image: -webkit-linear-gradient(#fefefe 7.6%, #F6F7F8);
- background-image: -moz-linear-gradient(#fefefe 7.6%, #F6F7F8);
- background-image: -o-linear-gradient(#fefefe 7.6%, #F6F7F8);
- color: #777;
- border: 1px solid #DEDFE1;
- }
-}
-
-#holder {
- background:#FAFAFA;
- border: 1px solid #EEE;
- cursor: move;
- height: 70%;
- overflow: hidden;
-}
-
-/* Project Dashboard Page */
-html, body { height: 100%; }
-
-body.dashboard.project-page .news-feed h2{float: left;}
-body.dashboard.project-page .news-feed .project-updates {margin-bottom: 20px; display: block; width: 100%;}
-body.dashboard.project-page .news-feed .project-updates .data{ padding: 0}
-body.dashboard.project-page .news-feed .project-updates a.project-update {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
-body.dashboard.project-page .news-feed .project-updates a.project-update:last-child{border-bottom: 0}
-body.dashboard.project-page .news-feed .project-updates a.project-update img{float: left; margin-right: 10px;}
-body.dashboard.project-page .news-feed .project-updates a.project-update span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;}
-body.dashboard.project-page .news-feed .project-updates a.project-update span.update-title{margin-bottom: 10px}
-body.dashboard.project-page .news-feed .project-updates a.project-update span.update-author{color: #999; font-weight: normal; font-style: italic;}
-body.dashboard.project-page .news-feed .project-updates a.project-update span.update-author strong{font-weight: bold; font-style: normal;}
-/* eo Dashboard Page */
-
-
-/** Merge requests */
-body.project-page .merge-request-commits {margin-bottom: 20px; display: block; width: 100%;}
-body.project-page .merge-request-commits .data{ padding: 0}
-body.project-page .merge-request-commits a.commit {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
-body.project-page .merge-request-commits a.commit:last-child{border-bottom: 0}
-body.project-page .merge-request-commits a.commit img{float: left; margin-right: 10px;}
-body.project-page .merge-request-commits a.commit span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;}
-body.project-page .merge-request-commits a.commit span.update-title{margin-bottom: 10px}
-body.project-page .merge-request-commits a.commit span.update-author{color: #999; font-weight: normal; font-style: italic;}
-body.project-page .merge-request-commits a.commit span.update-author strong{font-weight: bold; font-style: normal;}
-
-
-/** Update entry **/
-.update-data { padding: 0 }
-.update-data { width:100%; }
-.update-data.ui-box .data { padding:0; }
-a.update-item {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
-a.update-item:last-child{border-bottom: 0}
-a.update-item img{float: left; margin-right: 10px;}
-a.update-item span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;}
-a.update-item span.update-title{margin-bottom: 10px}
-a.update-item span.update-author{color: #999; font-weight: normal; font-style: italic;}
-a.update-item span.update-author strong{font-weight: bold; font-style: normal;}
-
-
-body.project-page .team_member_new .span-6, .team_member_edit .span-6{ padding:10px 0; }
-
-body.projects-page input.text.git-url.project_list_url { width:165px; }
-
-
-body.project-page table.no-borders th {
- background:none;
- border-bottom:1px solid #CCC;
- color:#333;
-}
-
-body.project-page table.no-borders tr,
-body.project-page table.no-borders td{
- border:none;
-}
-
-.ajax-tab-loading {
- padding:40px;
- display:none;
-}
-
-#tree-content-holder { float:left; width:100%; }
-
-#tree-readme-holder {
- float:left;
- width:100%;
-
- .readme {
- @include round-borders-all(4px);
- padding: 4px 15px;
- background:#F7F7F7;
- }
-}
-
-
-
-/* Commit Page */
-.entity-info {float: right;}
-.entity-button{
- background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.192, #fff), to(#f4f4f4));
- background-image: -webkit-linear-gradient(#fff 19.2%, #f4f4f4);
- background-image: -moz-linear-gradient(#fff 19.2%, #f4f4f4);
- background-image: -o-linear-gradient(#fff 19.2%, #f4f4f4);
- box-shadow: 0 -1px 0 white inset;
- display: block;
- border: 1px solid #eee;
- border-radius: 5px;
- margin-bottom: 2px;
- position: relative;
- padding: 4px 10px;
- font-size: 11px;
- padding-right: 20px;
-}
-
-.entity-button i{
- background: url('images.png') no-repeat -138px -27px;
- width: 6px;
- height: 9px;
- float: right;
- position: absolute;
- top: 6px;
- right: 5px;
-}
-.box-arrow{float: right; background: #E3E5EA; padding: 10px; border-radius: 5px; margin-top: 2px; text-shadow: none; color: #999; margin: 1.5em 0;}
-
-h4.dash-tabs {
- margin: 0;
- border-bottom: 1px solid #ccc;
- padding: 10px 10px;
- font-size: 11px;
- padding-left:20px;
- font-weight: bold; text-transform: uppercase;
- background: #F7F7F7;
- margin-bottom:20px;
- height:13px;
-
-}
-
-.dash-button {
- border-right: 1px solid #ddd;
- background:none;
- padding: 10px 15px;
- float:left;
- position:relative;
- top:-10px;
- left:0px;
- height:13px;
-
- &:first-child {
- border-left: 1px solid #ddd;
- }
- &.active {
- background: #eaeaea;
- }
-}
-
-
-.dashboard-loader {
- float:right;
- margin-right:30px;
- display:none;
-}
-
-
-.merge-tabs {
- margin: 0;
- border: 1px solid #ccc;
- padding: 5px;
- font-size: 12px;
- background: #F7F7F7;
- margin-bottom:20px;
- height:26px;
-
- -moz-border-radius: 4px;
- -webkit-border-radius: 4px;
- border-radius: 4px;
-
- .tab {
- font-weight: bold;
- border-right: 1px solid #ddd;
- background:none;
- padding: 10px;
- min-width:60px;
- float:left;
- position:relative;
- top:-5px;
- left:-5px;
- height:16px;
- padding-left:34px;
-
- span {
- width: 20px;
- height: 20px;
- display: inline-block;
- position: absolute;
- left: 8px;
- top: 8px;
- }
-
- &.active {
- background: #eaeaea;
- }
- }
-}
-.merge-tabs.repository .tab span{ background: url("images.png") no-repeat -38px -77px; }
-.activities-tab span { background: url("images.png") no-repeat -161px -1px; }
-.stat-tab span,
-.team-tab span,
-.snippets-tab span { background: url("images.png") no-repeat -38px -77px; }
-.files-tab span { background: url("images.png") no-repeat -112px -23px; }
-
-.merge-notes-tab span { background: url("images.png") no-repeat -161px -1px; }
-.merge-commits-tab span { background: url("images.png") no-repeat -86px 1px; }
-.merge-diffs-tab span { background: url("images.png") no-repeat -118px 1px; }
-.merge-tabs .dashboard-loader { padding:8px; }
-
-.user-mention {
- color: #2FA0BB;
- font-weight: bold;
-}
-
-.author {
- color: #999;
-}
-
-
-.red-button{
- border-radius: 5px;
- font-size: 12px;
- font-weight: bold;
- padding: 5px 17px;
- border: 1px solid #999;
- color: #666;
- display: inline-block;
- box-shadow: 0 1px 2px rgba(0,0,0,.3);
- background: #D12F19;
- color: white;
-}
-
-.positive-button{
- border-radius: 5px;
- font-size: 12px;
- font-weight: bold;
- padding: 5px 17px;
- border: 1px solid #999;
- color: #666;
- display: inline-block;
- box-shadow: 0 1px 2px rgba(0,0,0,.3);
- background: #4A2;
- color: white;
-}
-
-
-.dark_scheme_box {
- padding:20px 0;
-
- label {
- float:left;
- box-shadow: 0 0px 5px rgba(0,0,0,.3);
-
- img {
- }
- }
-}
-
-a.project-update.titled {
- position: relative;
- padding-left: 235px !important;
-
- .title-block {
- padding: 10px;
- width: 205px;
- position: absolute;
- left: 0;
- top: 0;
- }
-}
-
-.add_new {
- float: right;
- background: #A6B807;
- color: white;
- padding: 4px 10px;
- @include round-borders-all(4px);
- font-size:11px;
- margin: 10px 0;
-}
-
-
-
-.new-project-hodler {
- padding:20px;
-}
diff --git a/app/assets/stylesheets/projects.css.scss~ b/app/assets/stylesheets/projects.css.scss~
new file mode 100644
index 00000000000..4bdf5dee2f5
--- /dev/null
+++ b/app/assets/stylesheets/projects.css.scss~
@@ -0,0 +1,385 @@
+.git_url_wrapper { margin-right:50px }
+
+.sidebar aside a{
+ display: block;
+ position: relative;
+ padding: 15px 10px;
+ margin: 10px 0 0 0;
+
+ font-size:13px;
+ font-weight:bold;
+ color:#333;
+
+ &.current {
+ color: white;
+ background: $active_bg_color;
+ border: 1px solid $active_bd_color;
+ border-radius:5px;
+
+ -webkit-border-top-right-radius: 0;
+ -webkit-border-bottom-right-radius: 0;
+ -moz-border-radius-topright: 0px;
+ -moz-border-radius-bottomright: 0px;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ margin-right: -1px;
+ }
+}
+
+body table .commit a{color: #{$blue_link}}
+body table th, body table td{ border-bottom: 1px solid #DEE2E3;}
+body .fixed{position: fixed; }
+
+/** File stat **/
+.file_stats {
+ span {
+ img {
+ width:14px;
+ float:left;
+ margin-right: 6px;
+ padding:2px 0;
+ }
+ }
+}
+
+.round-borders {
+ @include round-borders-all(4px);
+ padding: 4px 0px;
+}
+
+table.round-borders {
+ float:left;
+ text-align: left;
+}
+
+
+
+/** PROJECTS **/
+input.ssh_project_url {
+ padding:5px;
+ margin:0px;
+ float:right;
+ width:400px;
+ text-align:center;
+}
+
+#projects-list .project {
+ height:50px;
+}
+
+#tree-slider .tree-item,
+#projects-list .project,
+#snippets-table .snippet,
+#issues-table .issue{
+ cursor:pointer;
+}
+
+.clear {
+ clear: both;
+}
+
+
+
+#user_projects_limit{
+ width: 60px;
+}
+
+.handle:hover{
+ cursor: move;
+}
+
+.project-refs-form {
+ span {
+ background: none !important;
+ position:static !important;
+ width:auto !important;
+ height: auto !important;
+ }
+}
+
+.project-refs-select {
+ width:200px;
+}
+
+.filter .left { margin-right:15px; }
+
+body table .commit {
+ a.tree-commit-link {
+ color:#444;
+ &:hover {
+ text-decoration:underline;
+ }
+ }
+}
+
+/** NEW PROJECT **/
+.new-project-hodler {
+ .icon span { background-position: -31px -70px; }
+ td { border-bottom: 1px solid #DEE2E3; }
+}
+
+/** Feed entry **/
+.commit,
+.snippet,
+.message {
+ .title {
+ color:#666;
+ a { color:#666 !important; }
+ p { margin-top:0px; }
+ }
+ .author { color: #999 }
+}
+
+/** JQuery UI **/
+.ui-autocomplete { @include round-borders-all(5px); }
+.ui-menu-item { cursor: pointer }
+.ui-selectmenu{
+ @include round-borders-all(4px);
+ margin-right:10px;
+ font-size:1.5em;
+ height:auto;
+ font-weight:bold;
+ .ui-selectmenu-status {
+ padding:3px 10px;
+ }
+}
+
+#holder {
+ background:#FAFAFA;
+ border: 1px solid #EEE;
+ cursor: move;
+ height: 70%;
+ overflow: hidden;
+}
+
+/* Project Dashboard Page */
+html, body { height: 100%; }
+
+.news-feed h2{float: left;}
+.news-feed .project-updates {margin-bottom: 20px; display: block; width: 100%;}
+.news-feed .project-updates .data{ padding: 0}
+.news-feed .project-updates a.project-update {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
+.news-feed .project-updates a.project-update:last-child{border-bottom: 0}
+.news-feed .project-updates a.project-update img{float: left; margin-right: 10px;}
+.news-feed .project-updates a.project-update span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;}
+.news-feed .project-updates a.project-update span.update-title{margin-bottom: 10px}
+.news-feed .project-updates a.project-update span.update-author{color: #999; font-weight: normal; font-style: italic;}
+.news-feed .project-updates a.project-update span.update-author strong{font-weight: bold; font-style: normal;}
+/* eo Dashboard Page */
+
+
+/** Update entry **/
+.update-data { padding: 0 }
+.update-data { width:100%; }
+.update-data.ui-box .data { padding:0; }
+a.update-item {padding: 10px; border-bottom: 1px solid #eee; overflow: hidden; display: block;}
+a.update-item:last-child{border-bottom: 0}
+a.update-item img{float: left; margin-right: 10px;}
+a.update-item span.update-title, .dashboard-page .news-feed .project-updates li a span.update-author{display: block;}
+a.update-item span.update-title{margin-bottom: 10px}
+a.update-item span.update-author{color: #999; font-weight: normal; font-style: italic;}
+a.update-item span.update-author strong{font-weight: bold; font-style: normal;}
+
+
+body .team_member_new .span-6, .team_member_edit .span-6{ padding:10px 0; }
+
+body.projects-page input.text.git-url.project_list_url { width:165px; }
+
+
+body table.no-borders th {
+ background:none;
+ border-bottom:1px solid #CCC;
+ color:#333;
+}
+
+body table.no-borders tr,
+body table.no-borders td{
+ border:none;
+}
+
+.ajax-tab-loading {
+ padding:40px;
+ display:none;
+}
+
+#tree-content-holder { float:left; width:100%; }
+
+#tree-readme-holder {
+ float:left;
+ width:100%;
+
+ .readme {
+ @include round-borders-all(4px);
+ padding: 4px 15px;
+ background:#F7F7F7;
+ }
+}
+
+
+
+/* Commit Page */
+.entity-info {float: right;}
+.entity-button{
+ background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.192, #fff), to(#f4f4f4));
+ background-image: -webkit-linear-gradient(#fff 19.2%, #f4f4f4);
+ background-image: -moz-linear-gradient(#fff 19.2%, #f4f4f4);
+ background-image: -o-linear-gradient(#fff 19.2%, #f4f4f4);
+ box-shadow: 0 -1px 0 white inset;
+ display: block;
+ border: 1px solid #eee;
+ border-radius: 5px;
+ margin-bottom: 2px;
+ position: relative;
+ padding: 4px 10px;
+ font-size: 11px;
+ padding-right: 20px;
+}
+
+.entity-button i{
+ background: url('images.png') no-repeat -138px -27px;
+ width: 6px;
+ height: 9px;
+ float: right;
+ position: absolute;
+ top: 6px;
+ right: 5px;
+}
+.box-arrow{float: right; background: #E3E5EA; padding: 10px; border-radius: 5px; margin-top: 2px; text-shadow: none; color: #999; margin: 1.5em 0;}
+
+h4.dash-tabs {
+ margin: 0;
+ border-bottom: 1px solid #ccc;
+ padding: 10px 10px;
+ font-size: 11px;
+ padding-left:20px;
+ font-weight: bold; text-transform: uppercase;
+ background: #F7F7F7;
+ margin-bottom:20px;
+ height:13px;
+
+}
+
+.dash-button {
+ border-right: 1px solid #ddd;
+ background:none;
+ padding: 10px 15px;
+ float:left;
+ position:relative;
+ top:-10px;
+ left:0px;
+ height:13px;
+
+ &:first-child {
+ border-left: 1px solid #ddd;
+ }
+ &.active {
+ background: #eaeaea;
+ }
+}
+
+
+.dashboard-loader {
+ float:right;
+ margin-right:30px;
+ display:none;
+}
+
+
+.merge-tabs {
+ margin: 0;
+ border: 1px solid #ccc;
+ padding: 5px;
+ font-size: 12px;
+ background: #F7F7F7;
+ margin-bottom:20px;
+ height:26px;
+
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+
+ .tab {
+ font-weight: bold;
+ border-right: 1px solid #ddd;
+ background:none;
+ padding: 10px;
+ min-width:60px;
+ float:left;
+ position:relative;
+ top:-5px;
+ left:-5px;
+ height:16px;
+ padding-left:34px;
+
+ span {
+ width: 20px;
+ height: 20px;
+ display: inline-block;
+ position: absolute;
+ left: 8px;
+ top: 8px;
+ }
+
+ &.active {
+ background: #eaeaea;
+ }
+ }
+}
+.merge-tabs.repository .tab span{ background: url("images.png") no-repeat -38px -77px; }
+.activities-tab span { background: url("images.png") no-repeat -161px -1px; }
+.stat-tab span,
+.team-tab span,
+.snippets-tab span { background: url("images.png") no-repeat -38px -77px; }
+.files-tab span { background: url("images.png") no-repeat -112px -23px; }
+
+.merge-notes-tab span { background: url("images.png") no-repeat -161px -1px; }
+.merge-commits-tab span { background: url("images.png") no-repeat -86px 1px; }
+.merge-diffs-tab span { background: url("images.png") no-repeat -118px 1px; }
+.merge-tabs .dashboard-loader { padding:8px; }
+
+.user-mention {
+ color: #2FA0BB;
+ font-weight: bold;
+}
+
+.author {
+ color: #999;
+}
+
+
+
+
+.dark_scheme_box {
+ padding:20px 0;
+
+ label {
+ float:left;
+ box-shadow: 0 0px 5px rgba(0,0,0,.3);
+
+ img {
+ }
+ }
+}
+
+a.project-update.titled {
+ position: relative;
+ padding-left: 235px !important;
+
+ .title-block {
+ padding: 10px;
+ width: 205px;
+ position: absolute;
+ left: 0;
+ top: 0;
+ }
+}
+
+.add_new {
+ float: right;
+ background: #A6B807;
+ color: white;
+ padding: 4px 10px;
+ @include round-borders-all(4px);
+ font-size:11px;
+ margin: 10px 0;
+}
diff --git a/app/assets/stylesheets/ref_select.scss b/app/assets/stylesheets/ref_select.scss
new file mode 100644
index 00000000000..ff0ffa9f522
--- /dev/null
+++ b/app/assets/stylesheets/ref_select.scss
@@ -0,0 +1,50 @@
+/** Branch/tag selector **/
+.project-refs-form {
+ margin:0;
+ span {
+ background:none !important;
+ position:static !important;
+ width:auto !important;
+ height:auto !important;
+ }
+}
+.project-refs-select {
+ width:120px;
+}
+
+.project-refs-form .chzn-container {
+ position: relative;
+ top: 0;
+ left: 0;
+ margin-right: 10px;
+
+ .chzn-drop {
+ margin:7px 0;
+ border: 1px solid #CCC;
+ min-width: 300px;
+
+ .chzn-results {
+ max-height:300px;
+ }
+
+ .chzn-search input {
+ min-width:200px;
+ }
+ }
+
+ .chzn-single {
+ background:#ddd;
+ //border:none;
+ //box-shadow:none;
+
+ div {
+ background:transparent;
+ border-left:none;
+ }
+
+ span {
+ font-weight: normal;
+ }
+ }
+}
+
diff --git a/app/assets/stylesheets/style.scss b/app/assets/stylesheets/style.scss
deleted file mode 100644
index 4bb5fef9269..00000000000
--- a/app/assets/stylesheets/style.scss
+++ /dev/null
@@ -1,802 +0,0 @@
-/* HTML5 ✰ Boilerplate
- * ==|== normalize ==========================================================
- */
-
-article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block; }
-audio, canvas, video { display: inline-block; *display: inline; *zoom: 1; }
-audio:not([controls]) { display: none; }
-[hidden] { display: none; }
-
-html { font-size: 100%; overflow-y: scroll; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
-body { margin: 0; font-size: 13px; line-height: 1.231; }
-body, button, input, select, textarea {
- font-family: "helvetica", "arial", "freesans", "clean", sans-serif;
-color: #222; }
-
-::-moz-selection { background: #79c3e0; color: #fff; text-shadow: none; }
-::selection { background: #79c3e0; color: #fff; text-shadow: none; }
-
-a { color: #00e; }
-a:hover { color: #06e; }
-a:focus { outline: thin dotted; }
-a:hover, a:active { outline: 0; }
-
-abbr[title] { border-bottom: 1px dotted; }
-b, strong { font-weight: bold; }
-blockquote { margin: 1em 40px; }
-dfn { font-style: italic; }
-hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
-ins { background: #ff9; color: #000; text-decoration: none; }
-mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }
-pre, code, kbd, samp { font-family: monospace, monospace; _font-family: 'courier new', monospace; font-size: 1em; }
-pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
-q { quotes: none; }
-q:before, q:after { content: ""; content: none; }
-small { font-size: 85%; }
-sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
-sup { top: -0.5em; }
-sub { bottom: -0.25em; }
-ul, ol { margin: 1em 0; padding: 0 0 0 40px; }
-dd { margin: 0 0 0 40px; }
-nav ul, nav ol { list-style: none; list-style-image: none; margin: 0; padding: 0; }
-img { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; }
-svg:not(:root) { overflow: hidden; }
-figure { margin: 0; }
-
-form { margin: 0; }
-fieldset { border: 0; margin: 0; padding: 0; }
-label { cursor: pointer; }
-legend { border: 0; *margin-left: -7px; padding: 0; }
-button, input, select, textarea { font-size: 100%; margin: 0; vertical-align: baseline; *vertical-align: middle; }
-button, input { line-height: normal; *overflow: visible; }
-table button, table input { *overflow: auto; }
-button, input[type="button"], input[type="reset"], input[type="submit"] { cursor: pointer; -webkit-appearance: button; }
-input[type="checkbox"], input[type="radio"] { box-sizing: border-box; }
-input[type="search"] { -webkit-appearance: textfield; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box; }
-input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
-button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
-textarea { overflow: auto; vertical-align: top; resize: vertical; }
-input:valid, textarea:valid { }
-input:invalid, textarea:invalid { background-color: #f0dddd; }
-
-table { border-collapse: collapse; border-spacing: 0; }
-td { vertical-align: top; }
-
-/* ==|== primary styles =====================================================
- Author: Ricardo Rauch
- ========================================================================== */
-
-/* 960gs */
-.container_4{width:98%;margin-left:1%;margin-right:1%}.grid_1,.grid_2,.grid_3,.grid_4{display:inline;float:left;position:relative;margin-left:1%;margin-right:1%}.alpha{margin-left:0}.omega{margin-right:0}.container_4 .grid_1{width:23.0%}.container_4 .grid_2{width:48.0%}.container_4 .grid_3{width:73.0%}.container_4 .grid_4{width:98.0%}.container_4 .prefix_1{padding-left:25.0%}.container_4 .prefix_2{padding-left:50.0%}.container_4 .prefix_3{padding-left:75.0%}.container_4 .suffix_1{padding-right:25.0%}.container_4 .suffix_2{padding-right:50.0%}.container_4 .suffix_3{padding-right:75.0%}.container_4 .push_1{left:25.0%}.container_4 .push_2{left:50.0%}.container_4 .push_3{left:75.0%}.container_4 .pull_1{left:-25.0%}.container_4 .pull_2{left:-50.0%}.container_4 .pull_3{left:-75.0%}.clear{clear:both;display:block;overflow:hidden;visibility:hidden;width:0;height:0}.clearfix:after{clear:both;content:' ';display:block;font-size:0;line-height:0;visibility:hidden;width:0;height:0}.clearfix{display:inline-block}* html .clearfix{height:1%}.clearfix{display:block}
-/* eo 960gs*/
-
-/* Vars */
-$color: "#4BB8D2";
-$blue_link: "#2fa0bb";
-/* eo Vars */
-
-html{ -webkit-font-smoothing:antialiased; }
-body {
- font-size: 12px;
- background-color: #FFFFFF;
-}
-a{text-decoration: none; font-weight: bold; color: #444}
-a:hover{color: #555}
-/* Typography */
-h1,h2,h3,h4,h5{font-weight: normal; color: #666}
-h2{margin: 1.5em 0}
-/* eo Typography */
-
-/* Forms */
-input[type="text"]:focus, input[type="password"]:focus { outline: none; }
-input.text{border: 1px solid #ccc; border-radius: 4px; display: block; padding: 10px}
-
-.form-row{
- padding: 0px 0px 10px 0px;
-}
-
-.form-row label{
- font-weight:bold;
- display: inline-block;
- padding: 0px 0px 5px 0px;
-}
-
-/* eo Forms */
-
-/* Tables */
-table {width:100%; border: 1px solid #DEE2E3; margin-bottom: 20px}
-table thead{
- -webkit-border-top-left-radius: 5px;
- -webkit-border-top-right-radius: 5px;
- -moz-border-radius-topleft: 5px;
- -moz-border-radius-topright: 5px;
- border-top-left-radius: 5px;
- border-top-right-radius: 5px;
-}
-table thead th{
- background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8));
- background-image: -webkit-linear-gradient(#fefefe 7.6%, #F6F7F8);
- background-image: -moz-linear-gradient(#fefefe 7.6%, #F6F7F8);
- background-image: -o-linear-gradient(#fefefe 7.6%, #F6F7F8);
- margin: 0;
- font-weight: normal;
- font-weight: bold;
- text-align: left;
- color: #97A0A5;
-}
-td, th{ padding: .9em 1em; vertical-align: middle; }
-
-table thead .image{width:100px}
-.listed_items tr.odd:hover{background-color:#FFFFCF}
-/* eo Tables */
-
-/* Buttons */
-.grey-button{
- border-radius: 5px;
- font-size: 12px;
- font-weight: bold;
- padding: 5px 17px;
- border: 1px solid #999;
- color: #666;
- display: inline-block;
- box-shadow: 0 1px 2px rgba(0,0,0,.3);
- background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #f7f7f7), to(#d5d5d5));
- background-image: -webkit-linear-gradient(#f7f7f7 7.6%, #d5d5d5);
- background-image: -moz-linear-gradient(#f7f7f7 7.6%, #d5d5d5);
- background-image: -o-linear-gradient(#f7f7f7 7.6%, #d5d5d5);
-}
-
-a.button, input.button {
- font-weight: bold;
- padding: 10px 20px;
- text-align: center;
- display: inline-block;
- border-radius: 5px;
- color: #578E91;
- font-size: 12px;
- text-transform: uppercase;
- border: 1px solid #8CE2E6;
- background-image: -webkit-gradient(linear, 0 0, 0 34, color-stop(0.794, #dbf5f6), to(#c5eef0));
- background-image: -webkit-linear-gradient(#dbf5f6 79.4%, #c5eef0);
- background-image: -moz-linear-gradient(#dbf5f6 79.4%, #c5eef0);
- background-image: -o-linear-gradient(#dbf5f6 79.4%, #c5eef0);
-}
-
-input.button{margin-bottom: 1.5em}
-
-.button:hover {color: rgba(0,0,0,.8)}
-
-.button.green {margin-right: 0; }
-
-.button.yellow{
- color: #908054;
- border-color: #DDCDA1;
- background-image: -webkit-gradient(linear, 0 0, 0 34, color-stop(0.794, #FFEFC3), to(#F3E3B7));
- background-image: -webkit-linear-gradient(#FFEFC3 79.4%, #F3E3B7);
- background-image: -moz-linear-gradient(#FFEFC3 79.4%, #F3E3B7);
- background-image: -o-linear-gradient(#FFEFC3 79.4%, #F3E3B7);
-}
-
-.button.blue{
- color: #417E97;
- border-color: #b2cdec;
- background-image: -webkit-gradient(linear, 0 0, 0 34, color-stop(0.794, #dbe8f6), to(#c7daf1));
- background-image: -webkit-linear-gradient(#dbe8f6 79.4%, #c7daf1);
- background-image: -moz-linear-gradient(#dbe8f6 79.4%, #c7daf1);
- background-image: -o-linear-gradient(#dbe8f6 79.4%, #c7daf1);
-}
-
-.button-small{ text-shadow: none; padding: 4px 10px; }
-.button-green{background: #A6B807; color: white}
-
-/* eo Buttons */
-
-/* UI Box */
-//.ui-box{border: 1px solid #DEDFE1; float: left; border-radius: 5px}
-.ui-box{float: left;}
-.ui-box h3{
- background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8));
- background-image: -webkit-linear-gradient(#fefefe 7.6%, #F6F7F8);
- background-image: -moz-linear-gradient(#fefefe 7.6%, #F6F7F8);
- background-image: -o-linear-gradient(#fefefe 7.6%, #F6F7F8);
- background:none;
- margin: 0;
- padding: 1em;
- font-size: 12px;
- font-weight: normal;
- font-weight: bold;
- font-size: 16px;
- border-bottom: 1px solid #DEDFE1;
- -webkit-border-top-left-radius: 5px;
- -webkit-border-top-right-radius: 5px;
- -moz-border-radius-topleft: 5px;
- -moz-border-radius-topright: 5px;
- border-top-left-radius: 5px;
- border-top-right-radius: 5px;
-}
-
-.ui-box.ui-box-small h3{
- padding: 8px 10px;
- font-size: 12px;
-}
-
-.ui-box .data{padding: .5em 1em}
-
-.ui-box .buttons{
- padding: 1em;
- border-top:1px solid $lite_border_color;
-}
-
-.ui-box .buttons .button{padding: 8px 9px; font-size: 11px}
-
-.ui-box.hover:hover{box-shadow: 0 0 10px rgba(0,0,0,.1); border: 1px solid #ccc;
-
- -webkit-transition: all 200ms cubic-bezier(0.470, 0.000, 0.745, 0.715);
- -moz-transition: all 200ms cubic-bezier(0.470, 0.000, 0.745, 0.715);
- -o-transition: all 200ms cubic-bezier(0.470, 0.000, 0.745, 0.715);
- transition: all 200ms cubic-bezier(0.470, 0.000, 0.745, 0.715);
-}
-
-/* eo UI Box */
-
-/* Login Page */
-body.login-page{background-color: #f1f1f1; padding-top: 10%}
-
-.login-box{
- width: 304px;
- position: relative;
- border-radius: 5px;
- margin: auto;
- padding: 20px;
- background: white;
- box-shadow: rgba(0, 0, 0, 0.07) 0 1px 0,white 0 2px 0,rgba(0, 0, 0, 0.07) 0 3px 0,white 0 4px 0, rgba(0, 0, 0, 0.07) 0 5px 0;
-}
-
-.login-box .login-logo{
- margin: 10px 0 30px 0;
- display: block;
-}
-
-.login-box input.text{background-color: #f1f1f1; font-size: 16px; border-radius: 0; padding: 14px 10px; width: 280px}
-
-.login-box input.text.top{
- -webkit-border-top-left-radius: 5px;
- -webkit-border-top-right-radius: 5px;
- -moz-border-radius-topleft: 5px;
- -moz-border-radius-topright: 5px;
- border-top-left-radius: 5px;
- border-top-right-radius: 5px;
-}
-
-.login-box input.text.bottom{
- -webkit-border-bottom-right-radius: 5px;
- -webkit-border-bottom-left-radius: 5px;
- -moz-border-radius-bottomright: 5px;
- -moz-border-radius-bottomleft: 5px;
- border-bottom-right-radius: 5px;
- border-bottom-left-radius: 5px;
- border-top: 0;
- margin-bottom: 20px;
-}
-
-.login-box a.forgot{float: right; padding-top: 6px}
-
-/* Icons */
-.directory, .file{
- display: inline-block;
- margin-right: 10px;
- width: 14px;
-}
-
-.directory{
- background: url('images.png') no-repeat -73px -26px;
- height: 11px;
- margin-bottom: -1px;
-}
-
-.file{
- background: url('images.png') no-repeat -114px -24px;
- height: 16px;
- margin-bottom: -3px;
-}
-
-/* eo Icons*/
-
-/* Errors */
-#error_explanation{background: #ffe5eb; padding: 20px; margin-bottom: 20px; border-radius: 5px}
-#error_explanation h2{margin: 0; margin-bottom: 20px; color: red}
-#error_explanation ul li{margin-bottom: 10px}
-#error_explanation ul li:last-child{margin-bottom: 0}
-.field_with_errors {
- input[type="text"],
- input[type="password"],
- textarea
- {
- border: 1px solid #D30 !important;
- }
-}
-/* eo Errors */
-
-/* Notices */
-#notice{background: #dfffe1; padding: 20px; margin-bottom: 20px; border-radius: 5px; color: green; font-size: 1.3em;}
-/* eo Notices */
-
-/* InfoBlock */
-#infoblock{
- background: #eeeeee;
- padding: 20px;
- margin-bottom: 20px;
- border-radius: 5px;
-}
-/* eo InfoBlock */
-
-/* Header */
-header{
- background: #474D57 url('bg-header.png') repeat-x bottom;
- z-index: 10000;
- height: 44px;
- padding: 10px 2% 6px 2%;
-}
-header a:hover{color: #f1f1f1}
-header h1{
- width: 65px;
-}
-header h1.logo{margin: 0; padding: 0}
-header h1.logo a{
- background: url('images.png') no-repeat -3px -7px;
- width: 65px;
- height: 26px;
- margin: 5px 0;
- padding: 0;
- display: block;
- float: left;
- text-indent: -1000em;
-}
-
-header nav{border-radius: 4px; box-shadow: 0 1px 2px black; width: 294px; margin: auto;
- background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #595d63), to(#31363e));
- background-image: -webkit-linear-gradient(#595d63 6.6%, #31363e);
- background-image: -moz-linear-gradient(#595d63 6.6%, #31363e);
- background-image: -o-linear-gradient(#595d63 6.6%, #31363e);
- margin-top: 2px;
- height:30px
-}
-header nav.shorter_nav{
- width: 207px;
-}
-header nav a{padding: 8px 12px 8px 34px; display: inline-block; color: #D6DADF; border-right: 1px solid #31363E; position: relative; box-shadow: 1px 0 0 rgba(255,255,255,.1); margin: 0}
-header nav a span{width: 20px; height: 20px; display: inline-block; background: red; position: absolute; left: 8px; top: 6px;}
-header nav a:last-child {border: 0; box-shadow: none}
-header nav a:hover, header nav a.current{
- background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #595d63), to(#2c2f35));
- background-image: -webkit-linear-gradient(#595d63 6.6%, #2c2f35);
- background-image: -moz-linear-gradient(#595d63 6.6%, #202227);
- background-image: -o-linear-gradient(#595d63 6.6%, #202227);
-}
-
-header nav a:active{
- box-shadow: 0 1px 4px rgba(0,0,0,.8) inset;
-}
-
-header nav a.dashboard {
- -webkit-border-top-left-radius: 4px;
- -webkit-border-bottom-left-radius: 4px;
- -moz-border-radius-topleft: 4px;
- -moz-border-radius-bottomleft: 4px;
- border-top-left-radius: 4px;
- border-bottom-left-radius: 4px;
-}
-
-header nav a.last_elem{
- -webkit-border-top-right-radius: 4px;
- -webkit-border-bottom-right-radius: 4px;
- -moz-border-radius-topright: 4px;
- -moz-border-radius-bottomright: 4px;
- border-top-right-radius: 4px;
- border-bottom-right-radius: 4px;
-}
-
-header .search{ display: inline-block; float: right; margin-right: 90px}
-
-header nav a span{width: 20px; height: 20px; display: inline-block; background: red; position: absolute; left: 8px; top: 6px;}
-
-header nav a.dashboard span{background: url('images.png') no-repeat -161px 0;}
-header nav a.admin span{background: url('images.png') no-repeat -184px 0;}
-header nav a.project span{background: url('images.png') no-repeat -209px -1px; top: 7px}
-header nav a.issues span{background: url('images.png') no-repeat -209px -1px; top: 7px}
-
-header .login-top{float: right; width: 180px;
- background-image: -webkit-gradient(linear, 0 0, 0 62, color-stop(0.032, #464c56), to(#363c45));
- background-image: -webkit-linear-gradient(#464c56 3.2%, #363c45);
- background-image: -moz-linear-gradient(#464c56 3.2%, #363c45);
- background-image: -o-linear-gradient(#464c56 3.2%, #363c45);
- padding: 0 10px;
- height: 44px;
-}
-header .login-top a{display: block;}
-header .login-top a.pic{float: left; margin-right: 10px;
- img{ height: 36px; width: 36px; border: 1px solid black}
-}
-header .login-top a.username{margin-bottom: 5px}
-header .login-top a.logout{color: #ccc}
-header{margin-bottom: 0; clear: both; position:relative;}
-
-.page-title{background-color: #f1f1f1;display: block; float: left; clear: both; width: 98%; padding: 1% 1%; border-bottom: 1px solid #ccc; box-shadow: 0 -1px 0 white inset; margin-bottom: 1.5em}
-.page-title h1{font-size: 20px; width: 400px; margin: 0; padding-top: 8px }
-.page-title a.grey-button{float: right;}
-.right{float: right;}
-
-/* Account box */
-header .account-box{
- position: absolute;
- right: 0;
- top: 8px;
- z-index: 10000;
- width: 128px;
- font-size: 11px;
- float: right;
- display: block;
- cursor: pointer;}
-header .account-box img{
- border-radius: 4px;
- right: 20px;
- position: absolute;
- width: 33px; height: 33px;
- display: block; top:0;}
-header .account-box img:after{
- content: " ";
- display: block;
- position: absolute;
- top: 0;
- right: 0;
-left: 0;
- bottom: 0;
-float: right;
- border-radius: 5px;
- border: 1px solid rgba(255, 255, 255, .1);
- border-bottom: 0;
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(255, 255, 255, .15)), to(rgba(0, 0, 0, .25))), -webkit-gradient(linear, left top, right bottom, color-stop(0, rgba(255, 255, 255, 0)), color-stop(0.5, rgba(255, 255, 255, .1)), color-stop(0.501, rgba(255, 255, 255, 0)), color-stop(1, rgba(255, 255, 255, 0)));
- background: -moz-linear-gradient(top, rgba(255, 255, 255, .15), rgba(0, 0, 0, .25)), -moz-linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, .1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
- background: linear-gradient(top, rgba(255, 255, 255, .15), rgba(0, 0, 0, .25)), linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, .1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
- -webkit-background-origin: border-box;
- -moz-background-origin: border;
- background-origin: border-box;
-}
-
-.account-box.hover{height: 138px;}
-
-.account-box:hover > .account-links{display: block;}
-header .account-links{
- background: #79C3E0; display: none; border-radius: 5px; width: 100px; margin-top: 0; float: right; box-shadow: 0 1px 1px rgba(0,0,0,.2); position:relative;}
-header .account-links:before {
- content: ".";
- width:0;
- height:0;
- position:absolute;
- border:5px solid transparent;
- border-color:rgba(255,255,255,0);
- border-bottom-color:#fafafa;
- text-indent:-9999px;
- top:-10px;
- line-height:0;
- right:10px;
- z-index:10;
-}
-
-/* Inspired by http://maxvoltar.com/temp/nowplaying/ */
-header .account-links{background: white; display: none; z-index: 100000; border-radius: 5px; width: 100px; position: absolute; right: 20px; top: 46px; margin-top: 0; float: right; box-shadow: 0 1px 1px rgba(0,0,0,.2); }
-header .account-links a{color: #666; padding: 6px 10px; display: block; text-shadow: none; border-bottom: 1px solid #eee}
-header .account-links a:hover{
- background: #3aacec;
- background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#39acec), to(#279ada), color-stop(.05, #4cbefe));
- background: -moz-linear-gradient(top, #39acec, #4cbefe 5%, #279ada);
- background: linear-gradient(top, #39acec, #4cbefe 5%, #279ada);
- color: #fff;
- text-shadow: #1488c8 0 -1px 0;
-}
-.account-box.hover .arrow-up{top: 41px; right: 6px; position: absolute}
-header .account-links a:first-child{
- -webkit-border-top-left-radius: 5px;
- -webkit-border-top-right-radius: 5px;
- -moz-border-radius-topleft: 5px;
- -moz-border-radius-topright: 5px;
- border-top-left-radius: 5px;
- border-top-right-radius: 5px;
-}
-
-header .account-links a:last-child{
- -webkit-border-bottom-right-radius: 5px;
- -webkit-border-bottom-left-radius: 5px;
- -moz-border-radius-bottomright: 5px;
- -moz-border-radius-bottomleft: 5px;
- border-bottom-right-radius: 5px;
- border-bottom-left-radius: 5px;
- border-bottom: 0;
-}
-
-.big-message{
- background-image: -webkit-gradient(linear, 0 48, 0 0, color-stop(0.041, #eccb40), to(#ffee4d));
- background-image: -webkit-linear-gradient(90deg, #eccb40 4.1%, #ffee4d);
- background-image: -moz-linear-gradient(90deg, #eccb40 4.1%, #ffee4d);
- background-image: -o-linear-gradient(90deg, #eccb40 4.1%, #ffee4d);
- text-align: center;
- font-weight: bold;
- padding: 10px 20px;
- text-shadow: 0 1px 0 rgba(255,255,255,.3);
- color: #333;
- color: rgba(0,0,0,.7);
- font-size: 14px;
- box-shadow: 0 1px 2px rgba(0,0,0,.7);
- z-index: 100000;
- margin-bottom: 2px;
-}
-
-.big-message a{color: #000; text-decoration: underline;}
-
-.big-message.error{
- background-color: #722523;
- background-image: -webkit-gradient(linear, 0 49, 0 0, color-stop(0.04, #722523), to(#ad4846));
- background-image: -webkit-linear-gradient(90deg, #9b403f 4%, #c16765);
- background-image: -moz-linear-gradient(90deg, #722523 4%, #ad4846);
- background-image: -o-linear-gradient(90deg, #722523 4%, #ad4846);
- color: #2E0D0C;
-}
-
-.big-message.success{
- background-color: #7a9339;
- background-image: -webkit-gradient(linear, 0 48, 0 0, color-stop(0.062, #7a9339), to(#93ae46));
- background-image: -webkit-linear-gradient(90deg, #7a9339 6.2%, #93ae46);
- background-image: -moz-linear-gradient(90deg, #7a9339 6.2%, #93ae46);
- background-image: -o-linear-gradient(90deg, #7a9339 6.2%, #93ae46)
-}
-
-.big-message.success{
- background-color: #7a9339;
- background-image: -webkit-gradient(linear, 0 48, 0 0, color-stop(0.062, #7a9339), to(#93ae46));
- background-image: -webkit-linear-gradient(90deg, #7a9339 6.2%, #93ae46);
- background-image: -moz-linear-gradient(90deg, #7a9339 6.2%, #93ae46);
- background-image: -o-linear-gradient(90deg, #7a9339 6.2%, #93ae46)
-}
-
-.big-message.notice{
- background-image: -webkit-gradient(linear, 0 49, 0 0, color-stop(0.061, #447790), color-stop(0.897, #5da2bf));
- background-image: -webkit-linear-gradient(90deg, #447790 6.1%, #5da2bf 89.7%);
- background-image: -moz-linear-gradient(90deg, #447790 6.1%, #5da2bf 89.7%);
- background-image: -o-linear-gradient(90deg, #447790 6.1%, #5da2bf 89.7%)
-}
-
-/* eo Account Box */
-input.search-input{
- float: left;
- text-shadow: none;
- width: 116px;
- background-image: url('icon-search.png') ;
- background-repeat: no-repeat;
- background-position: 10px;
- border-radius: 4px;
- border: 1px solid #AAA;
- background-color: #FFF;
- padding: 5px;
- padding-left: 26px;
- margin-top: 2px;
- margin-right: 10px;
-}
-/*input.search-input:focus{ background-color: white; width: 216px;}*/
-input.search-input::-webkit-input-placeholder {color: #666}
-/* eo Header */
-
-h2.icon{position: relative; padding-left: 40px; float: left; }
-/*h2 a{font-weight: normal;}*/
-h2.icon span{background: #E3E5EA url('images.png'); height: 32px; width: 32px; left: 0; top: -5px; border-radius: 4px; display: inline-block; position: absolute}
-
-/* Dashboard Page */
-html, body { height: 100%; }
-
-
-
-
-.grey-button.right{margin-top: 20px}
-
-/* Project Page */
-/* eo New Project Page */
-
-
-/* eo Project Page */
-
-/* Projects Page */
-body.projects-page h2.icon span{background-position: -31px -70px;}
-body.projects-page .project-box.ui-box .data .repository {margin-bottom: 20px}
-body.projects-page .project-box.ui-box .data .title span{ font-weight: bold;}
-body.projects-page .project-box{width: 100%; margin-bottom: 3em}
-body.projects-page .browse-code{margin-right: 10px}
-/* eo Projects Page */
-
-/* ==|== non-semantic helper classes ======================================== */
-.ir { display: block; border: 0; text-indent: -999em; overflow: hidden; background-color: transparent; background-repeat: no-repeat; text-align: left; direction: ltr; }
-.ir br { display: none; }
-.hidden { display: none !important; visibility: hidden; }
-.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
-.visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }
-.invisible { visibility: hidden; }
-.clearfix:before, .clearfix:after { content: ""; display: table; }
-.clearfix:after { clear: both; }
-.clearfix { zoom: 1; }
-
-/* ==|== media queries ====================================================== */
-
-@media only screen and (min-width: 480px) {
-
-}
-
-@media only screen and (min-width: 768px) {
-
-}
-
-/* ==|== print styles ======================================================= */
-
-@media print {
- * { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; }
- a, a:visited { text-decoration: underline; }
- a[href]:after { content: " (" attr(href) ")"; }
- abbr[title]:after { content: " (" attr(title) ")"; }
- .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
- pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
- thead { display: table-header-group; }
- tr, img { page-break-inside: avoid; }
- img { max-width: 100% !important; }
- @page { margin: 0.5cm; }
- p, h2, h3 { orphans: 3; widows: 3; }
- h2, h3 { page-break-after: avoid; }
-}
-
-body, button, input, select, textarea {
- font-family: "helvetica", "arial", "freesans", "clean", sans-serif;
-}
-
-/** FORM INPUTS **/
-.new_merge_request,
-.edit_merge_request,
-.user_new,
-.new_key,
-.new_issue,
-.new_note,
-.edit_user,
-.edit_issue,
-.new_project,
-.new_snippet,
-.edit_snippet,
-.edit_project {
- input[type='text'],
- input[type='email'],
- input[type='password'],
- textarea {
- width:400px;
- padding:8px;
- font-size:14px;
- @include round-borders-all(4px);
- }
-}
-
-.text_field {
- width:400px;
- padding:8px;
- font-size:14px;
- @include round-borders-all(4px);
-}
-
-.input_button {
- padding:8px;
- font-size:14px;
- cursor:pointer;
- background-color: #F5F5F5;
- border-color: #EEEEEE #DEDEDE #DEDEDE #EEEEEE;
- border-right: 1px solid #DEDEDE;
- border-style: solid;
- border-width: 1px;
-}
-
-/** FLASH **/
-#flash_container {
- height:45px;
- position:fixed;
- z-index:10001;
- top:0px;
- width:100%;
- margin-bottom:15px;
- overflow:hidden;
- background:white;
- cursor:pointer;
- border-bottom:1px solid #777;
-
- h4 {
- color:#444;
- font-size:22px;
- padding-top:5px;
- margin:2px;
- }
-}
-
-
-.errors_holder {
- background:#D30;
- color:#fff;
- @include round-borders-all(4px);
- border:1px solid #a30;
- padding:5px;
- list-style:none;
- font-weight: bold;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-
- li {
- padding:10px;
- }
-}
-
-.notice_holder {
- background:#DDF4FB;
- color:#444;
- border:1px solid #C6EDF9;
- @include round-borders-all(4px);
- padding:5px;
- list-style:none;
- font-weight: bold;
- text-shadow: 0 -1px 0 rgba(255, 255, 255, 0.25);
-
- li {
- padding:10px;
- }
-}
-
-.alert_holder {
- background:#FDF5D9;
- color:#444;
- border:1px solid #FCEEC1;
- @include round-borders-all(4px);
- padding:5px;
- list-style:none;
- font-weight: bold;
- text-shadow: 0 -1px 0 rgba(255, 255, 255, 0.25);
-
- li {
- padding:10px;
- }
-}
-
-.help_content {
- margin:20px;
- margin-top:71px;
-
- h2 {
- margin:0;
- padding:0;
- }
-
- .menu {
- float:left;
- width:20%;
-
- .active {
- color: $active_bd_color;
- }
- }
-
- .content {
- float:right;
- width:78%;
- }
-
- .bash {
- @include round-borders-all(4px);
- background:#eee;
- padding:5px;
- //overflow-x:scroll;
- pre{
- padding:0;
- line-height:2.0;
- margin:0;
- font-family: 'Courier New', 'andale mono','lucida console',monospace;
- color: #333;
- text-align:left;
- }
- }
-}
diff --git a/app/assets/stylesheets/tags.css.css b/app/assets/stylesheets/tags.css.css
deleted file mode 100644
index 829d2c78d9b..00000000000
--- a/app/assets/stylesheets/tags.css.css
+++ /dev/null
@@ -1,42 +0,0 @@
-.tags-list {
- padding : 0px 10px 10px 10px;
-
-}
-
-.tags-list a {
- display: inline-block;
- padding: 8px 11px 8px 11px;
- margin: 1px 5px 0px 0px;
- border-radius: 4px;
- border: 1px solid #72bbdf;
- background-color: #72bbdf;
- color: #0f326d;
- font-weight: bold;
- font-size: 14px;
-}
-
-.small-tags a{
- font-size: 9px;
-
- display: inline-block;
- padding: 2px 3px 1px 3px;
- margin: 0px 3px 0px 0px;
- border-radius: 2px;
- background-color: #72bbdf;
- color: #FFF;
- text-shadow: none;
- font-weight: bold;
-}
-
-.medium-tags a{
- font-size: 12px;
-
- display: inline-block;
- padding: 3px 4px 2px 4px;
- margin: 0px 7px 8px 0px;
- border-radius: 3px;
- background-color: #72bbdf;
- color: #FFF;
- text-shadow: none;
- font-weight: bold;
-}
diff --git a/app/assets/stylesheets/top_panel.scss b/app/assets/stylesheets/top_panel.scss
deleted file mode 100644
index 57c1e07725e..00000000000
--- a/app/assets/stylesheets/top_panel.scss
+++ /dev/null
@@ -1,146 +0,0 @@
-.main_links {
- width:130px;
- float:left;
-
- a {
- float:left;
- }
-}
-
-.dashboard_links {
- padding:7px;
- float:left;
- a {
- margin: 0 14px;
- float: left;
- font-size: 14px;
-
- &.active {
- color:$active_link_color;
- }
- &:hover {
- color:$active_link_color;
- }
- }
-}
-
-.top-tabs {
- margin: 0;
- padding: 5px;
- font-size: 14px;
- padding-bottom:10px;
- margin-bottom:20px;
- height:26px;
- border-bottom:1px solid #ccc;
-
- .tab {
- font-weight: bold;
- background:none;
- padding: 10px;
- float:left;
- padding-left:0px;
- padding-right:40px;
-
- &.active {
- color: $active_link_color;
- }
- }
-}
-
-body header {
- position:absolute;
- width:100%;
- padding:0;
- margin:0;
- top:0;
- left:0;
- background: #999; /* for non-css3 browsers */
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFF', endColorstr='#EAEAEA'); /* for IE */
- background: -webkit-gradient(linear, left top, left bottom, from(#FFFFFF), to(#EAEAEA)); /* for webkit browsers */
- background: -moz-linear-gradient(top, #FFFFFF, #EAEAEA); /* for firefox 3.6+ */
- background: -o-linear-gradient(top, #FFFFFF, #EAEAEA); /* for firefox 3.6+ */
- border-bottom: 1px solid #ccc;
-
- height:50px;
-
- .wrapper {
- margin:auto;
- width:$app_width;
- position:relative;
-
- .top_panel_content {
- padding:10px $app_padding;
- }
- }
-
- .project_name {
- float:left;
- width:235px;
- margin-right:30px;
- font-size:16px;
- font-weight:bold;
- padding:8px;
- color:#333;
- }
-
- .git_url_wrapper {
- padding:0px;
- margin:0px;
- float:left;
-
- .git-url {
- padding:0px;
- margin:0px;
- font-size: 12px;
-
- margin-right:10px;
- border-radius: 4px;
- -moz-border-radius: 4px;
-
-
- color: #666;
- border: 1px solid #AAA;
- padding: 0 10px 0 30px;
- background: transparent url('images.png') no-repeat 8px -42px;
- width: 160px;
- height:26px;
- }
- }
-}
-
-.top_panel_holder .chzn-container {
- position:relative;
-
- .chzn-drop {
- margin:7px 0;
- border: 1px solid #CCC;
- min-width: 300px;
-
- .chzn-results {
- max-height:300px;
- }
- }
-
- .chzn-single {
- background:transparent;
- -moz-border-radius: 4px;
- border-radius: 4px;
-
- div {
- background:transparent;
- border-left:none;
- }
-
- span {
- font-weight: normal;
- }
- }
-}
-
-.rss-icon {
- margin:0 15px;
- padding:3px;
- border:1px solid #AAA;
- border-radius:3px;
- float:left;
-}
diff --git a/app/assets/stylesheets/tree.scss b/app/assets/stylesheets/tree.scss
index 57070871680..592992541af 100644
--- a/app/assets/stylesheets/tree.scss
+++ b/app/assets/stylesheets/tree.scss
@@ -1,121 +1,178 @@
-#tree-breadcrumbs {
- div {
- margin:0;
- margin-bottom:20px;
+#tree-holder {
+ #tree-content-holder {
float:left;
- font-size:14px;
+ width:100%;
+ }
+ #tree-readme-holder {
+ float:left;
+ width:100%;
+ .readme {
+ @include round-borders-all(4px);
+ padding:4px 15px;
+ background: #F7F7F7;
+ }
}
-}
-.tree_progress {
- float:left;
- width:16px;
- height:16px;
- margin:2px 6px;
- &.loading {
- background-position: 0px 0px;
- background: url("ajax-loader-facebook.gif") no-repeat;
+ .tree_progress {
+ display:none;
+ margin:20px;
+ &.loading {
+ display:block;
+ }
}
-}
-/** FILE CONTENT VIEW **/
-.view_file_content{
- .old_line, .new_line {
- background:#ECECEC;
- color:#777;
- width:15px;
- float:left;
- padding: 0px 10px;
- border-right: 1px solid #ccc;
- }
- .old_line{
- display:none;
+ /** FILE CONTENT VIEW **/
+ .view_file_content{
+ .old_line, .new_line {
+ background:#ECECEC;
+ color:#777;
+ width:15px;
+ float:left;
+ padding: 0px 10px;
+ border-right: 1px solid #ccc;
+ }
+ .old_line{
+ display:none;
+ }
}
-}
-.view_file .view_file_header,
-.diff_file .diff_file_header {
- background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8));
- background-image: -webkit-linear-gradient(#fefefe 7.6%, #F6F7F8);
- background-image: -moz-linear-gradient(#fefefe 7.6%, #F6F7F8);
- background-image: -o-linear-gradient(#fefefe 7.6%, #F6F7F8);
+ .view_file .view_file_header,
+ .diff_file .diff_file_header {
+ background:#f5f5f5;
margin: 0;
font-weight: normal;
font-weight: bold;
text-align: left;
color: #666;
- border-bottom: 1px solid #DEE2E3;
+ border-bottom: 1px solid #ccc;
padding: 7px 10px;
.mode_text,
.file_icon {
- margin-right:15px;
- padding-right:15px;
- border-right:1px solid $lite_border_color;
- float:left;
color:#aaa;
}
+ }
- .file_icon {
- padding-left:15px;
+ .view_file {
+ border:1px solid #CCC;
+ margin-bottom:1em;
+
+ .view_file_content {
+ background:#fff;
+ color:#514721;
+ font-size: 11px;
}
-}
+ .view_file_content_image {
+ background:#eee;
+ text-align:center;
+ img {
+ padding:100px;
+ max-width:300px;
+ }
+ }
+ }
-.view_file {
- border:1px solid #CCC;
- margin-bottom:1em;
-
- .view_file_content {
- background:#fff;
- color:#514721;
- font-size: 11px;
- }
- .view_file_content_image {
- background:#eee;
- text-align:center;
- img {
- padding:100px;
- max-width:300px;
+ td.code {
+ width: 100%;
+ .highlight {
+ margin-left: 55px;
+ overflow:auto;
+ overflow-y:hidden;
}
}
-}
+ .highlight pre {
+ white-space: pre;
+ word-wrap:normal;
+ }
-td.code {
- width: 100%;
- .highlight {
- margin-left: 55px;
- overflow:auto;
- overflow-y:hidden;
- border-left: 1px solid #DEE2E3;
- background: white;
+ table.highlighttable {
+ border: none;
}
-}
-.highlight pre {
- white-space: pre;
- word-wrap:normal;
-}
+ body.project-page table.highlighttable td { border: none }
+ table.highlighttable tr:hover { background:none;}
-table.highlighttable {
- border: none;
- background: #F7F7F7;
-}
-body.project-page table.highlighttable td { border: none }
-table.highlighttable tr:hover { background:none;}
+ table.highlighttable pre{
+ line-height:16px !important;
+ font-size:12px !important;
+ }
-table.highlighttable pre{
- line-height:16px !important;
- font-size:12px !important;
-}
+ table.highlighttable .linenodiv pre {
+ text-align: right;
+ padding-right: 4px;
+ color:#888;
+ }
-table.highlighttable .linenodiv pre {
- text-align: right;
- padding-right: 4px;
- color:#888;
-}
+ .tree-item {
+ &:hover {
+ background: $hover;
+ cursor:pointer;
+ }
+
+
+ .tree-item-file-name {
+ font-weight:bold;
+ a {
+ color:$style_color;
+ }
+
+ img {
+ position: relative;
+ top: 2px;
+ }
+ }
+ }
+
+ ul.breadcrumb {
+ background:white;
+ border:none;
+
+ a {
+ color:#666;
+ font-weight:bold;
+ font-size:14px;
+ }
+ }
+
+ #tree-slider {
+ @include shade;
+
+ td {
+ padding:7px;
+ border-color:#f1f1f1;
+ }
+
+ th {
+ background:#f5f5f5;
+ }
+ }
+
+ .tree-commit-link {
+ color:#333;
+ }
+
+ #tree-content-holder .view_file{
+ @include shade;
+ }
+
+ #tree-readme-holder .readme {
+ @include shade;
+ margin-bottom:20px;
+ }
+
+ a.tree-commit-link {
+ color: #666;
+ &:hover {
+ text-decoration: underline;
+ }
+ }
-.tree-item {
- &:hover {
- background: #FFFFCF;
+ .arrow {
+ background: url("images.png") no-repeat -85px -77px;
+ width: 19px;
+ height: 16px;
+ float: left;
+ position: relative;
+ left: -10px;
}
}
diff --git a/app/assets/stylesheets/ui_basic.scss b/app/assets/stylesheets/ui_basic.scss
new file mode 100644
index 00000000000..b01e4d16974
--- /dev/null
+++ b/app/assets/stylesheets/ui_basic.scss
@@ -0,0 +1,309 @@
+/**
+ * This file represent some UI that can be changed
+ * during web app restyle or theme select.
+ *
+ * Next items should be placed there
+ * - link colors
+ * - header styles
+ * - main menu styles
+ *
+ */
+.ui_basic {
+ /*
+ * Common styles
+ *
+ */
+ a {
+ color: $link_color;
+ &:hover {
+ text-decoration:none;
+ color: $style_color;
+ }
+ }
+
+
+ /*
+ * Application Header
+ *
+ */
+ header {
+ width:100%;
+ padding:0;
+ margin:0;
+ top:1px;
+ left:0;
+ background: #F1F1F1; /* for non-css3 browsers */
+ border-bottom: 1px solid #ccc;
+ box-shadow: 0 -1px 0 white inset;
+ -moz-box-shadow: 0 -1px 0 white inset;
+ -webkit-box-shadow: 0 -1px 0 white inset;
+ z-index:10;
+ height:60px;
+
+ .app_logo {
+ width:230px;
+ float:left;
+
+ a {
+ float:left;
+
+ h1 {
+ float:left;
+ margin-left:5px;
+ font-size:20px;
+ line-height:34px;
+ font-weight:bold;
+ color:#aaa;
+ text-shadow: 0 1px 1px #FFF;
+ }
+
+ &.home {
+ img {
+ float: left;
+ position: relative;
+ top: -9px;
+ width:46px;
+
+ }
+ }
+ &.admin_link {
+ width:16px;
+ height:16px;
+ padding: 5px;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ margin: 0px;
+ background: #eee;
+ margin-left:20px;
+ &:hover {
+ background:#f7f7f7;
+ }
+ img {
+ width:16px;
+ }
+ }
+ }
+ }
+ .wrapper {
+ margin:auto;
+ min-width:$min_app_width;
+ max-width:$max_app_width;
+ position:relative;
+ padding:15px 0;
+
+ .top_panel_content {
+ margin:0 $app_padding;
+ }
+ }
+
+ .project_name {
+ float:left;
+ width:400px;
+ margin:0;
+ margin-right:30px;
+ font-size:20px;
+ line-height:34px;
+ font-weight:bold;
+ color:$style_color;
+ text-shadow: 0 1px 1px #FFF;
+ }
+
+ .git_url_wrapper {
+ padding:0px;
+ margin:0px;
+ float:left;
+
+ .git-url {
+ padding:0px;
+ margin:0px;
+ font-size: 12px;
+ margin-right:10px;
+ border-radius: 4px;
+ -moz-border-radius: 4px;
+ color: #666;
+ border: 1px solid #AAA;
+ padding: 0 10px 0 30px;
+ background: transparent url('images.png') no-repeat 8px -42px;
+ width: 260px;
+ height:26px;
+ }
+ }
+
+ /* Account box */
+ .account-box {
+ position: absolute;
+ right: 0;
+ top: 13px;
+ z-index: 10000;
+ width: 128px;
+ font-size: 11px;
+ float: right;
+ display: block;
+ cursor: pointer;
+ img {
+ border-radius: 4px;
+ right: 20px;
+ position: absolute;
+ width: 33px;
+ height: 33px;
+ display: block;
+ top: 0;
+ &:after {
+ content: " ";
+ display: block;
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ bottom: 0;
+ float: right;
+ border-radius: 5px;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ border-bottom: 0;
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(255, 255, 255, 0.15)), to(rgba(0, 0, 0, 0.25))), -webkit-gradient(linear, left top, right bottom, color-stop(0, rgba(255, 255, 255, 0)), color-stop(0.5, rgba(255, 255, 255, 0.1)), color-stop(0.501, rgba(255, 255, 255, 0)), color-stop(1, rgba(255, 255, 255, 0)));
+ background: -moz-linear-gradient(top, rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.25)), -moz-linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
+ background: linear-gradient(top, rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.25)), linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
+ -webkit-background-origin: border-box;
+ -moz-background-origin: border;
+ background-origin: border-box; } } }
+
+ .account-box {
+ &.hover {
+ height: 138px; }
+ &:hover > .account-links {
+ display: block; } }
+
+ .account-links {
+ background: #79C3E0;
+ display: none;
+ border-radius: 5px;
+ width: 100px;
+ margin-top: 0;
+ float: right;
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
+ position: relative;
+ &:before {
+ content: ".";
+ width: 0;
+ height: 0;
+ position: absolute;
+ border: 5px solid transparent;
+ border-color: rgba(255, 255, 255, 0);
+ border-bottom-color: #333;
+ text-indent: -9999px;
+ top: -10px;
+ line-height: 0;
+ right: 10px;
+ z-index: 10; }
+ background: #333;
+ display: none;
+ z-index: 100000;
+ border-radius: 5px;
+ width: 100px;
+ position: absolute;
+ right: 20px;
+ top: 46px;
+ margin-top: 0;
+ float: right;
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
+ a {
+ color: #EEE;
+ padding: 6px 10px;
+ display: block;
+ text-shadow: none;
+ border-bottom: 1px solid #555;
+ &:hover {
+ background: #444; } } }
+
+ .account-box.hover .arrow-up {
+ top: 41px;
+ right: 6px;
+ position: absolute; }
+
+ .account-links a {
+ &:first-child {
+ -webkit-border-top-left-radius: 5px;
+ -webkit-border-top-right-radius: 5px;
+ -moz-border-radius-topleft: 5px;
+ -moz-border-radius-topright: 5px;
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px; }
+ &:last-child {
+ -webkit-border-bottom-right-radius: 5px;
+ -webkit-border-bottom-left-radius: 5px;
+ -moz-border-radius-bottomright: 5px;
+ -moz-border-radius-bottomleft: 5px;
+ border-bottom-right-radius: 5px;
+ border-bottom-left-radius: 5px;
+ border-bottom: 0; } }
+
+ }
+ /*
+ * End of Application Header
+ *
+ */
+
+ /*
+ * Main Menu of Application
+ *
+ */
+ nav.main_menu {
+ overflow:hidden;
+ border-radius: 4px;
+ margin: auto;
+ margin:30px $app_padding;
+ background:#eee;
+ border:1px solid #ccc;
+ height:38px;
+ background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
+ background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);
+ background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
+ background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
+ @include shade;
+ .count {
+ color:#aaa;
+ margin-left:3px;
+ }
+ .label {
+ background:$hover;
+ text-shadow:none;
+ color:$style_color;
+ }
+ a {
+ font-weight:bold;
+ &:first-child{
+ -webkit-border-top-left-radius: 4px;
+ -webkit-border-bottom-left-radius: 4px;
+ -moz-border-radius-topleft: 4px;
+ -moz-border-radius-bottomleft: 4px;
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+ }
+ padding: 10px 25px;
+ display: inline-block;
+ color: $style_color;
+ border-right: 1px solid #d5d5d5;
+ position: relative;
+ box-shadow: 1px 0 0 rgba(255, 255, 255, 0.1);
+ margin: 0;
+ float:left;
+ text-shadow:0 1px 1px white;
+ &.home {
+ background: url(home_icon.PNG) no-repeat center center;
+ text-indent:-9999px;
+ min-width:40px;
+ img {
+ position:relative;
+ top:4px;
+ }
+ }
+ &.current {
+ background-color:#DDD;
+ }
+ }
+ }
+ /*
+ * End of Main Menu
+ *
+ */
+}
diff --git a/app/assets/stylesheets/ui_mars.scss b/app/assets/stylesheets/ui_mars.scss
new file mode 100644
index 00000000000..b2230f5be3e
--- /dev/null
+++ b/app/assets/stylesheets/ui_mars.scss
@@ -0,0 +1,337 @@
+/**
+ * This file represent some UI that can be changed
+ * during web app restyle or theme select.
+ *
+ * Next items should be placed there
+ * - link colors
+ * - header styles
+ * - main menu styles
+ *
+ */
+.ui_mars {
+
+ /*
+ * Common styles
+ *
+ */
+ a {
+ color: $link_color;
+ &:hover {
+ text-decoration:none;
+ color: $style_color;
+ }
+ }
+
+
+ /*
+ * Application Header
+ *
+ */
+ header {
+ width:100%;
+ padding:0;
+ margin:0;
+ top:1px;
+ left:0;
+
+
+ background: #474D57 url('bg-header.png') repeat-x bottom;
+
+ z-index:10;
+ height:60px;
+
+ .search-input {
+ background-image:url("icon-search.png");
+ float: right;
+ text-shadow: none;
+ width: 116px;
+ background-image: url("icon-search.png");
+ background-repeat: no-repeat;
+ background-position: 10px;
+ border-radius: 100px;
+ border: 1px solid rgba(0, 0, 0, 0.7);
+ box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2), 0 2px 2px rgba(0, 0, 0, 0.4) inset;
+ background-color: #D2D5DA;
+ background-color: rgba(255, 255, 255, 0.5);
+ padding: 5px;
+ padding-left: 26px;
+ margin-right: 50px;
+
+ &:focus {
+ background-color: white;
+ width: 166px;
+ }
+ }
+ .search-input::-webkit-input-placeholder {
+ color: #666;
+ }
+ .app_logo {
+ width:230px;
+ float:left;
+ position:relative;
+ top:-4px;
+
+ a {
+ float:left;
+
+ h1 {
+
+ background: url('images.png') no-repeat -3px -7px;
+ width: 65px;
+ height: 26px;
+ margin: 5px 0;
+ padding: 0;
+ display: block;
+ float: left;
+ text-indent: -1000em;
+
+ }
+
+ &.home {
+ img {
+ display:none
+
+ }
+ }
+ &.admin_link {
+ width:16px;
+ height:16px;
+ padding: 5px;
+ border: 1px solid #888;
+ border-radius: 4px;
+ margin: 0px;
+ background:#474D57 ;
+ margin-left:20px;
+ margin-top:4px;
+ &:hover {
+ background:#f7f7f7;
+ }
+ img {
+ width:16px;
+ }
+ }
+ }
+ }
+ .wrapper {
+ margin:auto;
+ min-width:$min_app_width;
+ max-width:$max_app_width;
+ position:relative;
+ padding:15px 0;
+
+ .top_panel_content {
+ margin:0 $app_padding;
+ }
+ }
+
+ .project_name {
+ float:left;
+ width:400px;
+ margin:0;
+ margin-right:30px;
+ font-size:20px;
+ line-height:34px;
+ font-weight:bold;
+ color:#fff;
+ text-shadow: 0 1px 1px #111;
+ }
+
+ .git_url_wrapper {
+ padding:0px;
+ margin:0px;
+ float:left;
+
+ .git-url {
+ padding:0px;
+ margin:0px;
+ font-size: 12px;
+ margin-right:10px;
+ border-radius: 4px;
+ -moz-border-radius: 4px;
+ color: #666;
+ border: 1px solid #AAA;
+ padding: 0 10px 0 30px;
+ background: transparent url('images.png') no-repeat 8px -42px;
+ width: 260px;
+ height:26px;
+ }
+ }
+
+ /* Account box */
+ .account-box {
+ position: absolute;
+ right: 0;
+ top: 13px;
+ z-index: 10000;
+ width: 128px;
+ font-size: 11px;
+ float: right;
+ display: block;
+ cursor: pointer;
+ img {
+ border-radius: 4px;
+ right: 20px;
+ position: absolute;
+ width: 33px;
+ height: 33px;
+ display: block;
+ top: 0;
+ &:after {
+ content: " ";
+ display: block;
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ bottom: 0;
+ float: right;
+ border-radius: 5px;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ border-bottom: 0;
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(255, 255, 255, 0.15)), to(rgba(0, 0, 0, 0.25))), -webkit-gradient(linear, left top, right bottom, color-stop(0, rgba(255, 255, 255, 0)), color-stop(0.5, rgba(255, 255, 255, 0.1)), color-stop(0.501, rgba(255, 255, 255, 0)), color-stop(1, rgba(255, 255, 255, 0)));
+ background: -moz-linear-gradient(top, rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.25)), -moz-linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
+ background: linear-gradient(top, rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.25)), linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
+ -webkit-background-origin: border-box;
+ -moz-background-origin: border;
+ background-origin: border-box; } } }
+
+ .account-box {
+ &.hover {
+ height: 138px; }
+ &:hover > .account-links {
+ display: block; } }
+
+ .account-links {
+ background: #79C3E0;
+ display: none;
+ border-radius: 5px;
+ width: 100px;
+ margin-top: 0;
+ float: right;
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
+ position: relative;
+ &:before {
+ content: ".";
+ width: 0;
+ height: 0;
+ position: absolute;
+ border: 5px solid transparent;
+ border-color: rgba(255, 255, 255, 0);
+ border-bottom-color: #333;
+ text-indent: -9999px;
+ top: -10px;
+ line-height: 0;
+ right: 10px;
+ z-index: 10; }
+ background: #333;
+ display: none;
+ z-index: 100000;
+ border-radius: 5px;
+ width: 100px;
+ position: absolute;
+ right: 20px;
+ top: 46px;
+ margin-top: 0;
+ float: right;
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
+ a {
+ color: #EEE;
+ padding: 6px 10px;
+ display: block;
+ text-shadow: none;
+ border-bottom: 1px solid #555;
+ &:hover {
+ background: #444; } } }
+
+ .account-box.hover .arrow-up {
+ top: 41px;
+ right: 6px;
+ position: absolute; }
+
+ .account-links a {
+ &:first-child {
+ -webkit-border-top-left-radius: 5px;
+ -webkit-border-top-right-radius: 5px;
+ -moz-border-radius-topleft: 5px;
+ -moz-border-radius-topright: 5px;
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px; }
+ &:last-child {
+ -webkit-border-bottom-right-radius: 5px;
+ -webkit-border-bottom-left-radius: 5px;
+ -moz-border-radius-bottomright: 5px;
+ -moz-border-radius-bottomleft: 5px;
+ border-bottom-right-radius: 5px;
+ border-bottom-left-radius: 5px;
+ border-bottom: 0; } }
+
+ }
+ /*
+ * End of Application Header
+ *
+ */
+
+ /*
+ * Main Menu of Application
+ *
+ */
+ nav.main_menu {
+ overflow:hidden;
+ border-radius: 4px;
+ margin: auto;
+ margin:30px $app_padding;
+ background:#eee;
+ border:1px solid #ccc;
+ height:38px;
+ background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
+ background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);
+ background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
+ background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
+ @include shade;
+ .count {
+ color:#aaa;
+ margin-left:3px;
+ }
+ .label {
+ background:$hover;
+ text-shadow:none;
+ color:$style_color;
+ }
+ a {
+ font-weight:bold;
+ &:first-child{
+ -webkit-border-top-left-radius: 4px;
+ -webkit-border-bottom-left-radius: 4px;
+ -moz-border-radius-topleft: 4px;
+ -moz-border-radius-bottomleft: 4px;
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+ }
+ padding: 10px 25px;
+ display: inline-block;
+ color: $style_color;
+ border-right: 1px solid #d5d5d5;
+ position: relative;
+ box-shadow: 1px 0 0 rgba(255, 255, 255, 0.1);
+ margin: 0;
+ float:left;
+ text-shadow:0 1px 1px white;
+ &.home {
+ background: url(home_icon.PNG) no-repeat center center;
+ text-indent:-9999px;
+ min-width:40px;
+ img {
+ position:relative;
+ top:4px;
+ }
+ }
+ &.current {
+ background-color:#DDD;
+ }
+ }
+ }
+ /*
+ * End of Main Menu
+ *
+ */
+}
diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb
index 813e135b77f..868bec7c9fe 100644
--- a/app/controllers/admin/projects_controller.rb
+++ b/app/controllers/admin/projects_controller.rb
@@ -52,6 +52,12 @@ class Admin::ProjectsController < ApplicationController
def update
@admin_project = Project.find_by_code(params[:id])
+ owner_id = params[:project].delete(:owner_id)
+
+ if owner_id
+ @admin_project.owner = User.find(owner_id)
+ end
+
if @admin_project.update_attributes(params[:project])
redirect_to [:admin, @admin_project], notice: 'Project was successfully updated.'
else
diff --git a/app/controllers/admin/team_members_controller.rb b/app/controllers/admin/team_members_controller.rb
index d04d32a63fe..57803b01e60 100644
--- a/app/controllers/admin/team_members_controller.rb
+++ b/app/controllers/admin/team_members_controller.rb
@@ -3,39 +3,15 @@ class Admin::TeamMembersController < ApplicationController
before_filter :authenticate_user!
before_filter :authenticate_admin!
- def index
- @admin_team_members = UsersProject.page(params[:page]).per(100).order("project_id DESC")
- end
-
- def show
- @admin_team_member = UsersProject.find(params[:id])
- end
-
- def new
- @admin_team_member = UsersProject.new(params[:team_member])
- end
-
def edit
@admin_team_member = UsersProject.find(params[:id])
end
- def create
- @admin_team_member = UsersProject.new(params[:team_member])
- @admin_team_member.project_id = params[:team_member][:project_id]
-
- if @admin_team_member.save
- redirect_to admin_team_member_path(@admin_team_member), notice: 'UsersProject was successfully created.'
- else
- render action: "new"
- end
- end
-
def update
@admin_team_member = UsersProject.find(params[:id])
- @admin_team_member.project_id = params[:team_member][:project_id]
if @admin_team_member.update_attributes(params[:team_member])
- redirect_to admin_team_member_path(@admin_team_member), notice: 'UsersProject was successfully updated.'
+ redirect_to [:admin, @admin_team_member.project], notice: 'Project Access was successfully updated.'
else
render action: "edit"
end
@@ -45,6 +21,6 @@ class Admin::TeamMembersController < ApplicationController
@admin_team_member = UsersProject.find(params[:id])
@admin_team_member.destroy
- redirect_to admin_team_members_url
+ redirect_to :back
end
end
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 85a95de5a17..216431456c0 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -9,8 +9,28 @@ class Admin::UsersController < ApplicationController
def show
@admin_user = User.find(params[:id])
+
+ @projects = if @admin_user.projects.empty?
+ Project
+ else
+ Project.without_user(@admin_user)
+ end.all
end
+ def team_update
+ @admin_user = User.find(params[:id])
+
+ UsersProject.user_bulk_import(
+ @admin_user,
+ params[:project_ids],
+ params[:project_access],
+ params[:repo_access]
+ )
+
+ redirect_to [:admin, @admin_user], notice: 'Teams were successfully updated.'
+ end
+
+
def new
@admin_user = User.new(:projects_limit => 10)
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 00ab93a153d..ff00208cff1 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -5,7 +5,11 @@ class ApplicationController < ActionController::Base
helper_method :abilities, :can?
rescue_from Gitlabhq::Gitolite::AccessDenied do |exception|
- render :file => File.join(Rails.root, "public", "githost_error"), :layout => false
+ render "errors/gitolite", :layout => "error"
+ end
+
+ rescue_from ActiveRecord::RecordNotFound do |exception|
+ render "errors/not_found", :layout => "error", :status => 404
end
layout :layout_by_resource
@@ -33,7 +37,8 @@ class ApplicationController < ActionController::Base
end
def project
- @project ||= Project.find_by_code(params[:project_id])
+ @project ||= current_user.projects.find_by_code(params[:project_id])
+ @project || render_404
end
def add_project_abilities
@@ -45,11 +50,23 @@ class ApplicationController < ActionController::Base
end
def authorize_project!(action)
- return render_404 unless can?(current_user, action, project)
+ return access_denied! unless can?(current_user, action, project)
+ end
+
+ def authorize_code_access!
+ return access_denied! unless can?(current_user, :download_code, project)
end
def access_denied!
- render_404
+ render "errors/access_denied", :layout => "error", :status => 404
+ end
+
+ def not_found!
+ render "errors/not_found", :layout => "error", :status => 404
+ end
+
+ def git_not_found!
+ render "errors/git_not_found", :layout => "error", :status => 404
end
def method_missing(method_sym, *arguments, &block)
@@ -78,21 +95,13 @@ class ApplicationController < ActionController::Base
redirect_to @project unless @project.repo_exists? && @project.has_commits?
end
- def respond_with_notes
- if params[:last_id] && params[:first_id]
- @notes = @notes.where("id >= ?", params[:first_id])
- elsif params[:last_id]
- @notes = @notes.where("id > ?", params[:last_id])
- elsif params[:first_id]
- @notes = @notes.where("id < ?", params[:first_id])
- else
- nil
- end
- end
-
def no_cache_headers
response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end
+
+ def render_full_content
+ @full_content = true
+ end
end
diff --git a/app/controllers/commits_controller.rb b/app/controllers/commits_controller.rb
index a938461fed1..0d36957c43f 100644
--- a/app/controllers/commits_controller.rb
+++ b/app/controllers/commits_controller.rb
@@ -7,12 +7,14 @@ class CommitsController < ApplicationController
# Authorize
before_filter :add_project_abilities
before_filter :authorize_read_project!
+ before_filter :authorize_code_access!
before_filter :require_non_empty_project
before_filter :load_refs, :only => :index # load @branch, @tag & @ref
+ before_filter :render_full_content
def index
@repo = project.repo
- @limit, @offset = (params[:limit] || 20), (params[:offset] || 0)
+ @limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
@commits = @project.commits(@ref, params[:path], @limit, @offset)
respond_to do |format|
@@ -24,14 +26,31 @@ class CommitsController < ApplicationController
def show
@commit = project.commit(params[:id])
- @notes = project.commit_notes(@commit).fresh.limit(20)
- @note = @project.build_commit_note(@commit)
+ git_not_found! and return unless @commit
+
+ @note = @project.build_commit_note(@commit)
+ @comments_allowed = true
@line_notes = project.commit_line_notes(@commit)
+ end
- respond_to do |format|
- format.html
- format.js { respond_with_notes }
+ def compare
+ first = project.commit(params[:to])
+ last = project.commit(params[:from])
+
+ @diffs = []
+ @commits = []
+ @line_notes = []
+
+ if first && last
+ commits = [first, last].sort_by(&:created_at)
+ younger = commits.first
+ older = commits.last
+
+
+ @commits = project.repo.commits_between(younger.id, older.id).map {|c| Commit.new(c)}
+ @diffs = project.repo.diff(younger.id, older.id) rescue []
+ @commit = Commit.new(older)
end
end
end
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index 6a8fd1c303c..fe9604ec38a 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -3,7 +3,16 @@ class DashboardController < ApplicationController
def index
@projects = current_user.projects.all
+
@active_projects = @projects.select(&:repo_exists?).select(&:last_activity_date_cached).sort_by(&:last_activity_date_cached).reverse
+
+ @merge_requests = MergeRequest.where("author_id = :id or assignee_id = :id", :id => current_user.id).opened.order("created_at DESC").limit(10)
+
+ @user = current_user
+ @issues = current_user.assigned_issues.opened.order("created_at DESC").limit(10)
+ @issues = @issues.includes(:author, :project)
+
+ @events = Event.where(:project_id => @projects.map(&:id)).recent.limit(20)
end
# Get authored or assigned open merge requests
diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb
index 3ef7aa46441..9f60c64590e 100644
--- a/app/controllers/errors_controller.rb
+++ b/app/controllers/errors_controller.rb
@@ -1,5 +1,7 @@
class ErrorsController < ApplicationController
+ layout "error"
+
def githost
- render :file => File.join(Rails.root, "public", "githost_error"), :layout => false
+ render "errors/gitolite"
end
end
diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb
index 7c10d2a8ef4..4e3be259463 100644
--- a/app/controllers/issues_controller.rb
+++ b/app/controllers/issues_controller.rb
@@ -1,6 +1,7 @@
class IssuesController < ApplicationController
before_filter :authenticate_user!
before_filter :project
+ before_filter :module_enabled
before_filter :issue, :only => [:edit, :update, :destroy, :show]
layout "project"
@@ -48,7 +49,6 @@ class IssuesController < ApplicationController
end
def show
- @notes = @issue.notes.inc_author.order("created_at DESC").limit(20)
@note = @project.notes.new(:noteable => @issue)
@commits = if @issue.branch_name && @project.repo.heads.map(&:name).include?(@issue.branch_name)
@@ -60,7 +60,7 @@ class IssuesController < ApplicationController
respond_to do |format|
format.html
- format.js { respond_with_notes }
+ format.js
end
end
@@ -69,7 +69,10 @@ class IssuesController < ApplicationController
@issue.author = current_user
@issue.save
- respond_with(@issue)
+ respond_to do |format|
+ format.html { redirect_to project_issue_path(@project, @issue) }
+ format.js
+ end
end
def update
@@ -125,11 +128,14 @@ class IssuesController < ApplicationController
end
def authorize_modify_issue!
- can?(current_user, :modify_issue, @issue) ||
- @issue.assignee == current_user
+ return render_404 unless can?(current_user, :modify_issue, @issue)
end
def authorize_admin_issue!
- can?(current_user, :admin_issue, @issue)
+ return render_404 unless can?(current_user, :admin_issue, @issue)
+ end
+
+ def module_enabled
+ return render_404 unless @project.issues_enabled
end
end
diff --git a/app/controllers/keys_controller.rb b/app/controllers/keys_controller.rb
index 33c6958d6ab..ce49e3e72c6 100644
--- a/app/controllers/keys_controller.rb
+++ b/app/controllers/keys_controller.rb
@@ -1,6 +1,6 @@
class KeysController < ApplicationController
layout "profile"
- respond_to :js
+ respond_to :js, :html
def index
@keys = current_user.keys.all
diff --git a/app/controllers/merge_requests_controller.rb b/app/controllers/merge_requests_controller.rb
index 3456a0a7fcb..cfb9e6dcbb7 100644
--- a/app/controllers/merge_requests_controller.rb
+++ b/app/controllers/merge_requests_controller.rb
@@ -1,6 +1,7 @@
class MergeRequestsController < ApplicationController
before_filter :authenticate_user!
before_filter :project
+ before_filter :module_enabled
before_filter :merge_request, :only => [:edit, :update, :destroy, :show, :commits, :diffs]
layout "project"
@@ -23,7 +24,9 @@ class MergeRequestsController < ApplicationController
@merge_requests = @project.merge_requests
@merge_requests = case params[:f].to_i
+ when 1 then @merge_requests
when 2 then @merge_requests.closed
+ when 2 then @merge_requests.opened.assigned(current_user)
else @merge_requests.opened
end
@@ -33,26 +36,31 @@ class MergeRequestsController < ApplicationController
def show
unless @project.repo.heads.map(&:name).include?(@merge_request.target_branch) &&
@project.repo.heads.map(&:name).include?(@merge_request.source_branch)
- head(404)and return
+ git_not_found! and return
end
- @notes = @merge_request.notes.inc_author.order("created_at DESC").limit(20)
@note = @project.notes.new(:noteable => @merge_request)
+ @commits = @project.repo.
+ commits_between(@merge_request.target_branch, @merge_request.source_branch).
+ map {|c| Commit.new(c)}.
+ sort_by(&:created_at).
+ reverse
+
+ render_full_content
+
respond_to do |format|
format.html
- format.js { respond_with_notes }
+ format.js
end
end
- def commits
- @commits = @project.repo.commits_between(@merge_request.target_branch, @merge_request.source_branch).map {|c| Commit.new(c)}
- end
-
def diffs
@diffs = @merge_request.diffs
@commit = @merge_request.last_commit
- @line_notes = []
+
+ @comments_allowed = true
+ @line_notes = @merge_request.notes.where("line_code is not null")
end
def new
@@ -105,11 +113,14 @@ class MergeRequestsController < ApplicationController
end
def authorize_modify_merge_request!
- can?(current_user, :modify_merge_request, @merge_request) ||
- @merge_request.assignee == current_user
+ return render_404 unless can?(current_user, :modify_merge_request, @merge_request)
end
def authorize_admin_merge_request!
- can?(current_user, :admin_merge_request, @merge_request)
+ return render_404 unless can?(current_user, :admin_merge_request, @merge_request)
+ end
+
+ def module_enabled
+ return render_404 unless @project.merge_requests_enabled
end
end
diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb
index 19c8571705d..a2638d9597c 100644
--- a/app/controllers/notes_controller.rb
+++ b/app/controllers/notes_controller.rb
@@ -9,6 +9,11 @@ class NotesController < ApplicationController
respond_to :js
+ def index
+ notes
+ respond_with(@notes)
+ end
+
def create
@note = @project.notes.new(params[:note])
@note.author = current_user
@@ -24,9 +29,7 @@ class NotesController < ApplicationController
def destroy
@note = @project.notes.find(params[:id])
-
return access_denied! unless can?(current_user, :admin_note, @note)
-
@note.destroy
respond_to do |format|
@@ -34,4 +37,28 @@ class NotesController < ApplicationController
end
end
+ protected
+
+ def notes
+ @notes = case params[:target_type]
+ when "commit"
+ then project.commit_notes(project.commit((params[:target_id]))).fresh.limit(20)
+ when "snippet"
+ then project.snippets.find(params[:target_id]).notes
+ when "wall"
+ then project.common_notes.order("created_at DESC").fresh.limit(50)
+ when "issue"
+ then project.issues.find(params[:target_id]).notes.inc_author.order("created_at DESC").limit(20)
+ when "merge_request"
+ then project.merge_requests.find(params[:target_id]).notes.inc_author.order("created_at DESC").limit(20)
+ end
+
+ @notes = if params[:last_id]
+ @notes.where("id > ?", params[:last_id])
+ elsif params[:first_id]
+ @notes.where("id < ?", params[:first_id])
+ else
+ @notes
+ end
+ end
end
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
new file mode 100644
index 00000000000..629b6819fb1
--- /dev/null
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -0,0 +1,13 @@
+class OmniauthCallbacksController < Devise::OmniauthCallbacksController
+
+ def ldap
+ # We only find ourselves here if the authentication to LDAP was successful.
+ info = request.env["omniauth.auth"]["info"]
+ @user = User.find_for_ldap_auth(info)
+ if @user.persisted?
+ @user.remember_me = true
+ end
+ sign_in_and_redirect @user
+ end
+
+end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 6bd72a860b3..26eabe5f94f 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -28,7 +28,7 @@ class ProjectsController < ApplicationController
Project.transaction do
@project.save!
- @project.users_projects.create!(:repo_access => Repository::REPO_RW , :project_access => Project::PROJECT_RWA, :user => current_user)
+ @project.users_projects.create!(:project_access => UsersProject::MASTER, :user => current_user)
# when project saved no team member exist so
# project repository should be updated after first user add
@@ -57,7 +57,7 @@ class ProjectsController < ApplicationController
def update
respond_to do |format|
if project.update_attributes(params[:project])
- format.html { redirect_to info_project_path(project), :notice => 'Project was successfully updated.' }
+ format.html { redirect_to edit_project_path(project), :notice => 'Project was successfully updated.' }
format.js
else
format.html { render action: "edit" }
@@ -68,33 +68,29 @@ class ProjectsController < ApplicationController
def show
return render "projects/empty" unless @project.repo_exists? && @project.has_commits?
- limit = (params[:limit] || 20).to_i
- @activities = @project.activities(limit)#updates_wo_repo(limit)
+ limit = (params[:limit] || 10).to_i
+ @activities = @project.activities(limit)
end
def files
@notes = @project.notes.where("attachment != 'NULL'").order("created_at DESC").limit(100)
end
- def info
- end
-
#
# Wall
#
def wall
+ return render_404 unless @project.wall_enabled
@note = Note.new
- @notes = @project.common_notes.order("created_at DESC")
- @notes = @notes.fresh.limit(20)
respond_to do |format|
format.html
- format.js { respond_with_notes }
end
end
def graph
+ render_full_content
@days_json, @commits_json = GraphCommit.to_graph(project)
end
@@ -114,6 +110,7 @@ class ProjectsController < ApplicationController
def project
@project ||= Project.find_by_code(params[:id])
+ @project || render_404
end
def determine_layout
diff --git a/app/controllers/protected_branches_controller.rb b/app/controllers/protected_branches_controller.rb
new file mode 100644
index 00000000000..0b86f5253ce
--- /dev/null
+++ b/app/controllers/protected_branches_controller.rb
@@ -0,0 +1,32 @@
+class ProtectedBranchesController < ApplicationController
+ before_filter :project
+
+ # Authorize
+ before_filter :add_project_abilities
+ before_filter :authorize_read_project!
+ before_filter :require_non_empty_project
+
+ before_filter :authorize_admin_project!, :only => [:destroy, :create]
+ before_filter :render_full_content
+
+ layout "project"
+
+ def index
+ @branches = @project.protected_branches.all
+ @protected_branch = @project.protected_branches.new
+ end
+
+ def create
+ @project.protected_branches.create(params[:protected_branch])
+ redirect_to project_protected_branches_path(@project)
+ end
+
+ def destroy
+ @project.protected_branches.find(params[:id]).destroy
+
+ respond_to do |format|
+ format.html { redirect_to project_protected_branches_path }
+ format.js { render :nothing => true }
+ end
+ end
+end
diff --git a/app/controllers/refs_controller.rb b/app/controllers/refs_controller.rb
index d2be5ad51db..b8ab1bce219 100644
--- a/app/controllers/refs_controller.rb
+++ b/app/controllers/refs_controller.rb
@@ -4,20 +4,32 @@ class RefsController < ApplicationController
# Authorize
before_filter :add_project_abilities
before_filter :authorize_read_project!
+ before_filter :authorize_code_access!
before_filter :require_non_empty_project
before_filter :ref
before_filter :define_tree_vars, :only => [:tree, :blob]
+ before_filter :render_full_content
+
layout "project"
def switch
- new_path = if params[:destination] == "tree"
- tree_project_ref_path(@project, params[:ref])
- else
- project_commits_path(@project, :ref => params[:ref])
- end
+ respond_to do |format|
+ format.html do
+ new_path = if params[:destination] == "tree"
+ tree_project_ref_path(@project, params[:ref])
+ else
+ project_commits_path(@project, :ref => params[:ref])
+ end
- redirect_to new_path
+ redirect_to new_path
+ end
+ format.js do
+ @ref = params[:ref]
+ define_tree_vars
+ render "tree"
+ end
+ end
end
#
@@ -37,7 +49,12 @@ class RefsController < ApplicationController
def blob
if @tree.is_blob?
- send_data(@tree.data, :type => @tree.mime_type, :disposition => 'inline', :filename => @tree.name)
+ send_data(
+ @tree.data,
+ :type => @tree.text? ? "text/plain" : @tree.mime_type,
+ :disposition => 'inline',
+ :filename => @tree.name
+ )
else
head(404)
end
@@ -48,6 +65,8 @@ class RefsController < ApplicationController
protected
def define_tree_vars
+ params[:path] = nil if params[:path].blank?
+
@repo = project.repo
@commit = project.commit(@ref)
@tree = Tree.new(@commit.tree, project, @ref, params[:path])
diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb
index 1e715931320..036eb3713bf 100644
--- a/app/controllers/repositories_controller.rb
+++ b/app/controllers/repositories_controller.rb
@@ -4,7 +4,9 @@ class RepositoriesController < ApplicationController
# Authorize
before_filter :add_project_abilities
before_filter :authorize_read_project!
+ before_filter :authorize_code_access!
before_filter :require_non_empty_project
+ before_filter :render_full_content
layout "project"
@@ -19,4 +21,28 @@ class RepositoriesController < ApplicationController
def tags
@tags = @project.repo.tags.sort_by(&:name).reverse
end
+
+ def archive
+ unless can?(current_user, :download_code, @project)
+ render_404 and return
+ end
+
+ ref = params[:ref] || @project.root_ref
+ commit = @project.commit(ref)
+ render_404 and return unless commit
+
+ # Build file path
+ file_name = @project.code + "-" + commit.id.to_s + ".tar.gz"
+ storage_path = File.join(Rails.root, "tmp", "repositories", @project.code)
+ file_path = File.join(storage_path, file_name)
+
+ # Create file if not exists
+ unless File.exists?(file_path)
+ FileUtils.mkdir_p storage_path
+ file = @project.repo.archive_to_file(ref, nil, file_path)
+ end
+
+ # Send file to user
+ send_file file_path
+ end
end
diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb
index 45b3f529c4c..bfcfda0fc71 100644
--- a/app/controllers/snippets_controller.rb
+++ b/app/controllers/snippets_controller.rb
@@ -1,6 +1,7 @@
class SnippetsController < ApplicationController
before_filter :authenticate_user!
before_filter :project
+ before_filter :snippet, :only => [:show, :edit, :destroy, :update]
layout "project"
# Authorize
@@ -41,11 +42,9 @@ class SnippetsController < ApplicationController
end
def edit
- @snippet = @project.snippets.find(params[:id])
end
def update
- @snippet = @project.snippets.find(params[:id])
@snippet.update_attributes(params[:snippet])
if @snippet.valid?
@@ -56,14 +55,11 @@ class SnippetsController < ApplicationController
end
def show
- @snippet = @project.snippets.find(params[:id])
- @notes = @snippet.notes
@note = @project.notes.new(:noteable => @snippet)
+ render_full_content
end
def destroy
- @snippet = @project.snippets.find(params[:id])
-
return access_denied! unless can?(current_user, :admin_snippet, @snippet)
@snippet.destroy
@@ -72,12 +68,15 @@ class SnippetsController < ApplicationController
end
protected
+ def snippet
+ @snippet ||= @project.snippets.find(params[:id])
+ end
def authorize_modify_snippet!
- can?(current_user, :modify_snippet, @snippet)
+ return render_404 unless can?(current_user, :modify_snippet, @snippet)
end
def authorize_admin_snippet!
- can?(current_user, :admin_snippet, @snippet)
+ return render_404 unless can?(current_user, :admin_snippet, @snippet)
end
end
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
deleted file mode 100644
index 938beb64403..00000000000
--- a/app/controllers/tags_controller.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class TagsController < ApplicationController
- def index
- @tags = Project.tag_counts.order('count DESC')
- @tags = @tags.where('name like ?', "%#{params[:term]}%") unless params[:term].blank?
-
- respond_to do |format|
- format.html
- format.json { render json: @tags.limit(8).map {|t| t.name}}
- end
- end
-end
diff --git a/app/controllers/team_members_controller.rb b/app/controllers/team_members_controller.rb
index c05602f9a80..ab51c19e0c8 100644
--- a/app/controllers/team_members_controller.rb
+++ b/app/controllers/team_members_controller.rb
@@ -40,7 +40,7 @@ class TeamMembersController < ApplicationController
@team_member.destroy
respond_to do |format|
- format.html { redirect_to root_path }
+ format.html { redirect_to team_project_path(@project) }
format.js { render :nothing => true }
end
end
diff --git a/app/controllers/wikis_controller.rb b/app/controllers/wikis_controller.rb
new file mode 100644
index 00000000000..9bcd20c3187
--- /dev/null
+++ b/app/controllers/wikis_controller.rb
@@ -0,0 +1,59 @@
+class WikisController < ApplicationController
+ before_filter :project
+ before_filter :add_project_abilities
+ before_filter :authorize_read_wiki!
+ before_filter :authorize_write_wiki!, :only => [:edit, :create, :history]
+ before_filter :authorize_admin_wiki!, :only => :destroy
+ layout "project"
+
+ def show
+ if params[:old_page_id]
+ @wiki = @project.wikis.find(params[:old_page_id])
+ else
+ @wiki = @project.wikis.where(:slug => params[:id]).order("created_at").last
+ end
+
+ unless @wiki
+ return render_404 unless can?(current_user, :write_wiki, @project)
+ end
+
+ respond_to do |format|
+ if @wiki
+ format.html
+ else
+ @wiki = @project.wikis.new(:slug => params[:id])
+ format.html { render "edit" }
+ end
+ end
+ end
+
+ def edit
+ @wiki = @project.wikis.where(:slug => params[:id]).order("created_at").last
+ @wiki = Wiki.regenerate_from @wiki
+ end
+
+ def create
+ @wiki = @project.wikis.new(params[:wiki])
+ @wiki.user = current_user
+
+ respond_to do |format|
+ if @wiki.save
+ format.html { redirect_to [@project, @wiki], notice: 'Wiki was successfully updated.' }
+ else
+ format.html { render action: "edit" }
+ end
+ end
+ end
+
+ def history
+ @wikis = @project.wikis.where(:slug => params[:id]).order("created_at")
+ end
+
+ def destroy
+ @wikis = @project.wikis.where(:slug => params[:id]).delete_all
+
+ respond_to do |format|
+ format.html { redirect_to project_wiki_path(@project, :index), notice: "Page was successfully deleted" }
+ end
+ end
+end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 9f0f1e68954..12fe333a74a 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -3,7 +3,8 @@ module ApplicationHelper
def gravatar_icon(user_email, size = 40)
gravatar_host = request.ssl? ? "https://secure.gravatar.com" : "http://www.gravatar.com"
- "#{gravatar_host}/avatar/#{Digest::MD5.hexdigest(user_email)}?s=#{size}&d=identicon"
+ user_email.strip!
+ "#{gravatar_host}/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=identicon"
end
def fixed_mode?
@@ -52,6 +53,13 @@ module ApplicationHelper
[ "Tag", @project.tags ]
]
+ # If reference is commit id -
+ # we should add it to branch/tag selectbox
+ if(@ref && !options.flatten.include?(@ref) &&
+ @ref =~ /^[0-9a-zA-Z]{6,52}$/)
+ options << ["Commit", [@ref]]
+ end
+
grouped_options_for_select(options, @ref || @project.default_branch)
end
@@ -71,11 +79,11 @@ module ApplicationHelper
if @project && !@project.new_record?
project_nav = [
- { :label => "#{@project.code} / Issues", :url => project_issues_path(@project) },
- { :label => "#{@project.code} / Wall", :url => wall_project_path(@project) },
- { :label => "#{@project.code} / Tree", :url => tree_project_ref_path(@project, @project.root_ref) },
- { :label => "#{@project.code} / Commits", :url => project_commits_path(@project) },
- { :label => "#{@project.code} / Team", :url => team_project_path(@project) }
+ { :label => "#{@project.name} / Issues", :url => project_issues_path(@project) },
+ { :label => "#{@project.name} / Wall", :url => wall_project_path(@project) },
+ { :label => "#{@project.name} / Tree", :url => tree_project_ref_path(@project, @project.root_ref) },
+ { :label => "#{@project.name} / Commits", :url => project_commits_path(@project) },
+ { :label => "#{@project.name} / Team", :url => team_project_path(@project) }
]
end
@@ -83,14 +91,26 @@ module ApplicationHelper
end
def project_layout
- @project && !@project.new_record?
+ layout == "project"
+ end
+
+ def admin_layout
+ layout == "admin"
end
def profile_layout
- controller.controller_name == "dashboard" || current_page?(projects_path) || controller.controller_name == "profile" || controller.controller_name == "keys"
+ layout == "profile"
end
def help_layout
controller.controller_name == "help"
end
+
+ def ldap_enable?
+ Devise.omniauth_providers.include?(:ldap)
+ end
+
+ def layout
+ controller.send :_layout
+ end
end
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index 4607e9daa07..d097c2712eb 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -7,16 +7,6 @@ module CommitsHelper
end
- def diff_line_class(line)
- if line[0] == "+"
- "new"
- elsif line[0] == "-"
- "old"
- else
- nil
- end
- end
-
def more_commits_link
offset = params[:offset] || 0
limit = params[:limit] || 100
@@ -42,11 +32,58 @@ module CommitsHelper
preserve out
end
- def build_line_code(line, index, line_new, line_old)
- if diff_line_class(line) == "new"
- "NEW_#{index}_#{line_new}"
+ def diff_line_class(line)
+ if line[0] == "+"
+ "new"
+ elsif line[0] == "-"
+ "old"
else
- "OLD_#{index}_#{line_old}"
+ nil
+ end
+ end
+
+ def build_line_code(line, index, line_new, line_old)
+ "#{index}_#{line_old}_#{line_new}"
+ end
+
+ def each_diff_line(diff_arr, index)
+ line_old = 1
+ line_new = 1
+ type = nil
+
+ lines_arr = diff_arr
+ lines_arr.each do |line|
+ next if line.match(/^\-\-\- \/dev\/null/)
+ next if line.match(/^\+\+\+ \/dev\/null/)
+ next if line.match(/^\-\-\- a/)
+ next if line.match(/^\+\+\+ b/)
+
+ full_line = html_escape(line.gsub(/\n/, '')).force_encoding("UTF-8")
+
+ if line.match(/^@@ -/)
+ type = "match"
+
+ line_old = line.match(/\-[0-9]*/)[0].to_i.abs rescue 0
+ line_new = line.match(/\+[0-9]*/)[0].to_i.abs rescue 0
+
+ next if line_old == 1 && line_new == 1
+ yield(line, type, nil, nil, nil)
+ next
+ else
+ type = diff_line_class(line)
+ line_code = build_line_code(line, index, line_new, line_old)
+ yield(full_line, type, line_code, line_new, line_old)
+ end
+
+
+ if line[0] == "+"
+ line_new += 1
+ elsif line[0] == "-"
+ line_old += 1
+ else
+ line_new += 1
+ line_old += 1
+ end
end
end
end
diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb
index 5cf1027854d..55ed901c210 100644
--- a/app/helpers/dashboard_helper.rb
+++ b/app/helpers/dashboard_helper.rb
@@ -3,6 +3,7 @@ module DashboardHelper
case object.class.name.to_s
when "Issue" then project_issue_path(project, project.issues.find(object.id))
when "Commit" then project_commit_path(project, project.repo.commits(object.id).first)
+ when "MergeRequest" then project_merge_request_path(project, object.id)
when "Note"
then
note = object
@@ -26,6 +27,7 @@ module DashboardHelper
when "Note" then markdown(object.note)
when "Issue" then object.title
when "Commit" then object.safe_message
+ when "MergeRequest" then object.title
else return "Project Wall"
end
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index d09fad5f33c..d902be0e19f 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -9,4 +9,26 @@ module IssuesHelper
params[:f] ||= cookies['issue_filter']
project_issues_path project, params
end
+
+ def link_to_issue_assignee(issue)
+ project = issue.project
+
+ tm = project.team_member_by_id(issue.assignee_id)
+ if tm
+ link_to issue.assignee_name, project_team_member_path(project, tm), :class => "author_link"
+ else
+ issue.assignee_name
+ end
+ end
+
+ def link_to_issue_author(issue)
+ project = issue.project
+
+ tm = project.team_member_by_id(issue.author_id)
+ if tm
+ link_to issue.author_name, project_team_member_path(project, tm), :class => "author_link"
+ else
+ issue.author_name
+ end
+ end
end
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index fac9870fc8a..afdf65bd568 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -1,2 +1,23 @@
module MergeRequestsHelper
+ def link_to_merge_request_assignee(merge_request)
+ project = merge_request.project
+
+ tm = project.team_member_by_id(merge_request.assignee_id)
+ if tm
+ link_to merge_request.assignee_name, project_team_member_path(project, tm), :class => "author_link"
+ else
+ merge_request.assignee_name
+ end
+ end
+
+ def link_to_merge_request_author(merge_request)
+ project = merge_request.project
+
+ tm = project.team_member_by_id(merge_request.author_id)
+ if tm
+ link_to merge_request.author_name, project_team_member_path(project, tm), :class => "author_link"
+ else
+ merge_request.author_name
+ end
+ end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 817ab475490..16e3d9d0056 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -17,11 +17,13 @@ module ProjectsHelper
end
def project_tab_class
- [:show, :files, :team, :edit, :update, :info].each do |action|
+ [:show, :files, :team, :edit, :update].each do |action|
return "current" if current_page?(:controller => "projects", :action => action, :id => @project)
end
if controller.controller_name == "snippets" ||
+ controller.controller_name == "hooks" ||
+ controller.controller_name == "deploy_keys" ||
controller.controller_name == "team_members"
"current"
end
@@ -33,9 +35,26 @@ module ProjectsHelper
end
def repository_tab_class
- if controller.controller_name == "repositories" ||
- controller.controller_name == "hooks"
- "current"
+ #if controller.controller_name == "repositories" ||
+ #controller.controller_name == "hooks" ||
+ #controller.controller_name == "deploy_keys"
+ #"current"
+ #end
+ end
+
+ def commit_tab_class
+ if controller.controller_name == "commits" ||
+ controller.controller_name == "repositories" ||
+ controller.controller_name == "protected_branches"
+ "current"
+ end
+ end
+
+ def branches_tab_class
+ if current_page?(branches_project_repository_path(@project)) ||
+ controller.controller_name == "protected_branches" ||
+ current_page?(project_repository_path(@project))
+ 'active'
end
end
end
diff --git a/app/helpers/wikis_helper.rb b/app/helpers/wikis_helper.rb
new file mode 100644
index 00000000000..0c24f57add6
--- /dev/null
+++ b/app/helpers/wikis_helper.rb
@@ -0,0 +1,5 @@
+module WikisHelper
+ def markdown_to_html(text)
+ RDiscount.new(text).to_html.html_safe
+ end
+end
diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb
index 6f40812577d..50ccb991a44 100644
--- a/app/mailers/notify.rb
+++ b/app/mailers/notify.rb
@@ -27,8 +27,7 @@ class Notify < ActionMailer::Base
@user = user
@note = note
@project = note.project
- @commit = @project.repo.commits(note.noteable_id).first
- return unless ( note.notify or ( note.notify_author and @commit.author.email == @user.email ) )
+ @commit = @note.target
mail(:to => @user.email, :subject => "gitlab | note for commit | #{@note.project.name} ")
end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index a02f44a4cb8..e97b662b8ce 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -5,6 +5,7 @@ class Ability
when "Issue" then issue_abilities(object, subject)
when "Note" then note_abilities(object, subject)
when "Snippet" then snippet_abilities(object, subject)
+ when "MergeRequest" then merge_request_abilities(object, subject)
else []
end
end
@@ -14,31 +15,40 @@ class Ability
rules << [
:read_project,
+ :read_wiki,
:read_issue,
:read_snippet,
:read_team_member,
:read_merge_request,
- :read_note
- ] if project.allow_read_for?(user)
-
- rules << [
+ :read_note,
:write_project,
:write_issue,
- :write_snippet,
- :write_merge_request,
:write_note
- ] if project.allow_write_for?(user)
+ ] if project.guest_access_for?(user)
+
+ rules << [
+ :download_code,
+ :write_merge_request,
+ :write_snippet
+ ] if project.report_access_for?(user)
+
+ rules << [
+ :write_wiki
+ ] if project.dev_access_for?(user)
rules << [
:modify_issue,
:modify_snippet,
+ :modify_merge_request,
:admin_project,
:admin_issue,
:admin_snippet,
:admin_team_member,
:admin_merge_request,
- :admin_note
- ] if project.allow_admin_for?(user)
+ :admin_note,
+ :admin_wiki
+ ] if project.master_access_for?(user) || project.owner == user
+
rules.flatten
end
@@ -53,6 +63,12 @@ class Ability
:"modify_#{name}",
:"admin_#{name}"
]
+ elsif subject.respond_to?(:assignee) && subject.assignee == user
+ [
+ :"read_#{name}",
+ :"write_#{name}",
+ :"modify_#{name}",
+ ]
else
subject.respond_to?(:project) ?
project_abilities(user, subject.project) : []
diff --git a/app/models/activity_observer.rb b/app/models/activity_observer.rb
new file mode 100644
index 00000000000..465641619e5
--- /dev/null
+++ b/app/models/activity_observer.rb
@@ -0,0 +1,12 @@
+class ActivityObserver < ActiveRecord::Observer
+ observe :issue, :merge_request, :note
+
+ def after_create(record)
+ Event.create(
+ :project => record.project,
+ :target_id => record.id,
+ :target_type => record.class.name,
+ :action => Event.determine_action(record)
+ )
+ end
+end
diff --git a/app/models/commit.rb b/app/models/commit.rb
index 695dfa5277e..a59e880370a 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -1,14 +1,18 @@
class Commit
+ include ActiveModel::Conversion
+ extend ActiveModel::Naming
attr_accessor :commit
attr_accessor :head
attr_accessor :refs
delegate :message,
+ :authored_date,
:committed_date,
:parents,
:sha,
:date,
+ :committer,
:author,
:message,
:diffs,
@@ -16,6 +20,10 @@ class Commit
:id,
:to => :commit
+ def persisted?
+ false
+ end
+
def initialize(raw_commit, head = nil)
@commit = raw_commit
@head = head
@@ -34,10 +42,22 @@ class Commit
end
def author_name
- author.name
+ author.name.force_encoding("UTF-8")
+ end
+
+ def committer_name
+ committer.name
+ end
+
+ def committer_email
+ committer.email
end
def prev_commit
parents.first
end
+
+ def prev_commit_id
+ prev_commit.id
+ end
end
diff --git a/app/models/event.rb b/app/models/event.rb
new file mode 100644
index 00000000000..e1732f0012a
--- /dev/null
+++ b/app/models/event.rb
@@ -0,0 +1,70 @@
+class Event < ActiveRecord::Base
+ Created = 1
+ Updated = 2
+ Closed = 3
+ Reopened = 4
+ Pushed = 5
+ Commented = 6
+
+ belongs_to :project
+ belongs_to :target, :polymorphic => true
+
+ serialize :data
+
+ scope :recent, order("created_at DESC")
+
+ def self.determine_action(record)
+ if [Issue, MergeRequest].include? record.class
+ Event::Created
+ elsif record.kind_of? Note
+ Event::Commented
+ end
+ end
+
+ def push?
+ action == self.class::Pushed
+ end
+
+ def new_branch?
+ data[:before] =~ /^00000/
+ end
+
+ def commit_from
+ data[:before]
+ end
+
+ def commit_to
+ data[:after]
+ end
+
+ def branch_name
+ @branch_name ||= data[:ref].gsub("refs/heads/", "")
+ end
+
+ def pusher
+ User.find_by_id(data[:user_id])
+ end
+
+ def commits
+ @commits ||= data[:commits].map do |commit|
+ project.commit(commit[:id])
+ end
+ end
+
+ delegate :id, :name, :email, :to => :pusher, :prefix => true, :allow_nil => true
+end
+# == Schema Information
+#
+# Table name: events
+#
+# id :integer not null, primary key
+# target_type :string(255)
+# target_id :integer
+# title :string(255)
+# data :text
+# project_id :integer
+# created_at :datetime not null
+# updated_at :datetime not null
+# action :integer
+#
+
diff --git a/app/models/key.rb b/app/models/key.rb
index fb59d75994a..4114e5261dc 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -14,6 +14,7 @@ class Key < ActiveRecord::Base
before_save :set_identifier
after_save :update_repository
after_destroy :repository_delete_key
+ delegate :name, :email, :to => :user, :prefix => true
def set_identifier
if is_deploy_key
diff --git a/app/models/mailer_observer.rb b/app/models/mailer_observer.rb
index 2bf383e5de0..f84cbdead59 100644
--- a/app/models/mailer_observer.rb
+++ b/app/models/mailer_observer.rb
@@ -27,20 +27,25 @@ class MailerObserver < ActiveRecord::Observer
end
def new_note(note)
- return unless note.notify or note.notify_author
- note.project.users.reject { |u| u.id == current_user.id } .each do |u|
- case note.noteable_type
- when "Commit" then
- Notify.note_commit_email(u, note).deliver
- when "Issue" then
- Notify.note_issue_email(u, note).deliver
- when "MergeRequest" then
- Notify.note_merge_request_email(u, note).deliver
- when "Snippet"
- true
- else
- Notify.note_wall_email(u, note).deliver
+ # Notify whole team except author of note
+ if note.notify
+ note.project.users.reject { |u| u.id == current_user.id } .each do |u|
+ case note.noteable_type
+ when "Commit" then
+ Notify.note_commit_email(u, note).deliver
+ when "Issue" then
+ Notify.note_issue_email(u, note).deliver
+ when "MergeRequest" then
+ Notify.note_merge_request_email(u, note).deliver
+ when "Snippet"
+ true
+ else
+ Notify.note_wall_email(u, note).deliver
+ end
end
+ # Notify only author of resource
+ elsif note.notify_author
+ Notify.note_commit_email(note.commit_author, note).deliver
end
end
diff --git a/app/models/note.rb b/app/models/note.rb
index f499b62d362..581f78335cf 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -58,21 +58,34 @@ class Note < ActiveRecord::Base
nil
end
- def line_file_id
- @line_file_id ||= line_code.split("_")[1].to_i if line_code
+ # Check if we can notify commit author
+ # with email about our comment
+ #
+ # If commit author email exist in project
+ # and commit author is not passed user we can
+ # send email to him
+ #
+ # params:
+ # user - current user
+ #
+ # return:
+ # Boolean
+ #
+ def notify_only_author?(user)
+ commit? && commit_author &&
+ commit_author.email != user.email
end
- def line_type_id
- @line_type_id ||= line_code.split("_").first if line_code
+ def commit?
+ noteable_type == "Commit"
end
- def line_number
- @line_number ||= line_code.split("_").last.to_i if line_code
- end
-
- def for_line?(file_id, old_line, new_line)
- line_file_id == file_id &&
- ((line_type_id == "NEW" && line_number == new_line) || (line_type_id == "OLD" && line_number == old_line ))
+ def commit_author
+ @commit_author ||=
+ project.users.find_by_email(target.author_email) ||
+ project.users.find_by_name(target.author_name)
+ rescue
+ nil
end
end
# == Schema Information
diff --git a/app/models/project.rb b/app/models/project.rb
index e1c66c95a23..c9b6f73bf41 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1,13 +1,9 @@
require "grit"
class Project < ActiveRecord::Base
- PROJECT_N = 0
- PROJECT_R = 1
- PROJECT_RW = 2
- PROJECT_RWA = 3
-
belongs_to :owner, :class_name => "User"
+ has_many :events, :dependent => :destroy
has_many :merge_requests, :dependent => :destroy
has_many :issues, :dependent => :destroy, :order => "position"
has_many :users_projects, :dependent => :destroy
@@ -16,6 +12,8 @@ class Project < ActiveRecord::Base
has_many :snippets, :dependent => :destroy
has_many :deploy_keys, :dependent => :destroy, :foreign_key => "project_id", :class_name => "Key"
has_many :web_hooks, :dependent => :destroy
+ has_many :protected_branches, :dependent => :destroy
+ has_many :wikis, :dependent => :destroy
acts_as_taggable
@@ -53,18 +51,14 @@ class Project < ActiveRecord::Base
attr_protected :private_flag, :owner_id
scope :public_only, where(:private_flag => false)
+ scope :without_user, lambda { |user| where("id not in (:ids)", :ids => user.projects.map(&:id) ) }
def self.active
joins(:issues, :notes, :merge_requests).order("issues.created_at, notes.created_at, merge_requests.created_at DESC")
end
def self.access_options
- {
- "Denied" => PROJECT_N,
- "Read" => PROJECT_R,
- "Report" => PROJECT_RW,
- "Admin" => PROJECT_RWA
- }
+ UsersProject.access_roles
end
def repository
@@ -96,21 +90,35 @@ class Project < ActiveRecord::Base
[GIT_HOST['host'], code].join("/")
end
- def execute_web_hooks(oldrev, newrev, ref)
+ def observe_push(oldrev, newrev, ref, author_key_id)
+ data = web_hook_data(oldrev, newrev, ref, author_key_id)
+
+ Event.create(
+ :project => self,
+ :action => Event::Pushed,
+ :data => data
+ )
+ end
+
+ def execute_web_hooks(oldrev, newrev, ref, author_key_id)
ref_parts = ref.split('/')
# Return if this is not a push to a branch (e.g. new commits)
return if ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000"
- data = web_hook_data(oldrev, newrev, ref)
+ data = web_hook_data(oldrev, newrev, ref, author_key_id)
+
web_hooks.each { |web_hook| web_hook.execute(data) }
end
- def web_hook_data(oldrev, newrev, ref)
+ def web_hook_data(oldrev, newrev, ref, author_key_id)
+ key = Key.find_by_identifier(author_key_id)
data = {
before: oldrev,
after: newrev,
ref: ref,
+ user_id: key.user.id,
+ user_name: key.user_name,
repository: {
name: name,
url: web_url,
@@ -137,6 +145,15 @@ class Project < ActiveRecord::Base
data
end
+ def open_branches
+ if protected_branches.empty?
+ self.repo.heads
+ else
+ pnames = protected_branches.map(&:name)
+ self.repo.heads.reject { |h| pnames.include?(h.name) }
+ end.sort_by(&:name)
+ end
+
def team_member_by_name_or_email(email = nil, name = nil)
user = users.where("email like ? or name like ?", email, name).first
users_projects.find_by_user_id(user.id) if user
@@ -182,11 +199,11 @@ class Project < ActiveRecord::Base
# Should be rewrited for new access rights
def add_access(user, *access)
access = if access.include?(:admin)
- { :project_access => PROJECT_RWA }
+ { :project_access => UsersProject::MASTER }
elsif access.include?(:write)
- { :project_access => PROJECT_RW }
+ { :project_access => UsersProject::DEVELOPER }
else
- { :project_access => PROJECT_R }
+ { :project_access => UsersProject::REPORTER }
end
opts = { :user => user }
opts.merge!(access)
@@ -199,38 +216,52 @@ class Project < ActiveRecord::Base
def repository_readers
keys = Key.joins({:user => :users_projects}).
- where("users_projects.project_id = ? AND users_projects.repo_access = ?", id, Repository::REPO_R)
+ where("users_projects.project_id = ? AND users_projects.project_access = ?", id, UsersProject::REPORTER)
keys.map(&:identifier) + deploy_keys.map(&:identifier)
end
def repository_writers
keys = Key.joins({:user => :users_projects}).
- where("users_projects.project_id = ? AND users_projects.repo_access = ?", id, Repository::REPO_RW)
+ where("users_projects.project_id = ? AND users_projects.project_access = ?", id, UsersProject::DEVELOPER)
+ keys.map(&:identifier)
+ end
+
+ def repository_masters
+ keys = Key.joins({:user => :users_projects}).
+ where("users_projects.project_id = ? AND users_projects.project_access = ?", id, UsersProject::MASTER)
keys.map(&:identifier)
end
def readers
- @readers ||= users_projects.includes(:user).where(:project_access => [PROJECT_R, PROJECT_RW, PROJECT_RWA]).map(&:user)
+ @readers ||= users_projects.includes(:user).map(&:user)
end
def writers
- @writers ||= users_projects.includes(:user).where(:project_access => [PROJECT_RW, PROJECT_RWA]).map(&:user)
+ @writers ||= users_projects.includes(:user).map(&:user)
end
def admins
- @admins ||= users_projects.includes(:user).where(:project_access => PROJECT_RWA).map(&:user)
+ @admins ||= users_projects.includes(:user).where(:project_access => UsersProject::MASTER).map(&:user)
end
def allow_read_for?(user)
- !users_projects.where(:user_id => user.id, :project_access => [PROJECT_R, PROJECT_RW, PROJECT_RWA]).empty?
+ !users_projects.where(:user_id => user.id).empty?
+ end
+
+ def guest_access_for?(user)
+ !users_projects.where(:user_id => user.id).empty?
+ end
+
+ def report_access_for?(user)
+ !users_projects.where(:user_id => user.id, :project_access => [UsersProject::REPORTER, UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
end
- def allow_write_for?(user)
- !users_projects.where(:user_id => user.id, :project_access => [PROJECT_RW, PROJECT_RWA]).empty?
+ def dev_access_for?(user)
+ !users_projects.where(:user_id => user.id, :project_access => [UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
end
- def allow_admin_for?(user)
- !users_projects.where(:user_id => user.id, :project_access => [PROJECT_RWA]).empty? || owner_id == user.id
+ def master_access_for?(user)
+ !users_projects.where(:user_id => user.id, :project_access => [UsersProject::MASTER]).empty? || owner_id == user.id
end
def root_ref
@@ -335,15 +366,19 @@ end
#
# Table name: projects
#
-# id :integer not null, primary key
-# name :string(255)
-# path :string(255)
-# description :text
-# created_at :datetime
-# updated_at :datetime
-# private_flag :boolean default(TRUE), not null
-# code :string(255)
-# owner_id :integer
-# default_branch :string(255) default("master"), not null
+# id :integer not null, primary key
+# name :string(255)
+# path :string(255)
+# description :text
+# created_at :datetime
+# updated_at :datetime
+# private_flag :boolean default(TRUE), not null
+# code :string(255)
+# owner_id :integer
+# default_branch :string(255) default("master"), not null
+# issues_enabled :boolean default(TRUE), not null
+# wall_enabled :boolean default(TRUE), not null
+# merge_requests_enabled :boolean default(TRUE), not null
+# wiki_enabled :boolean default(TRUE), not null
#
diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb
new file mode 100644
index 00000000000..9c2d391d0c1
--- /dev/null
+++ b/app/models/protected_branch.rb
@@ -0,0 +1,29 @@
+class ProtectedBranch < ActiveRecord::Base
+ belongs_to :project
+ validates_presence_of :project_id
+ validates_presence_of :name
+
+ after_save :update_repository
+ after_destroy :update_repository
+
+ def update_repository
+ Gitlabhq::GitHost.system.new.configure do |c|
+ c.update_project(project.path, project)
+ end
+ end
+
+ def commit
+ project.commit(self.name)
+ end
+end
+# == Schema Information
+#
+# Table name: protected_branches
+#
+# id :integer not null, primary key
+# project_id :integer not null
+# name :string(255) not null
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
diff --git a/app/models/repository.rb b/app/models/repository.rb
index f4fdfe54b57..1e78e588b69 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -1,10 +1,6 @@
require File.join(Rails.root, "lib", "gitlabhq", "git_host")
class Repository
- REPO_N = 0
- REPO_R = 1
- REPO_RW = 2
-
attr_accessor :project
def self.default_ref
@@ -12,11 +8,7 @@ class Repository
end
def self.access_options
- {
- "Denied" => REPO_N,
- "Pull" => REPO_R,
- "Pull & Push" => REPO_RW
- }
+ {}
end
def initialize(project)
@@ -56,7 +48,7 @@ class Repository
end
def path_to_repo
- GIT_HOST["base_path"] + path + ".git"
+ File.join(GIT_HOST["base_path"], "#{path}.git")
end
def update_repository
diff --git a/app/models/user.rb b/app/models/user.rb
index a13a6f77870..942f333702e 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -2,7 +2,7 @@ class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :token_authenticatable,
- :recoverable, :rememberable, :trackable, :validatable
+ :recoverable, :rememberable, :trackable, :validatable, :omniauthable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me,
@@ -62,6 +62,30 @@ class User < ActiveRecord::Base
def last_activity_project
projects.first
end
+
+ def self.generate_random_password
+ (0...8).map{ ('a'..'z').to_a[rand(26)] }.join
+ end
+
+ def first_name
+ name.split(" ").first unless name.blank?
+ end
+
+ def self.find_for_ldap_auth(omniauth_info)
+ name = omniauth_info.name
+ email = omniauth_info.email
+
+ if @user = User.find_by_email(email)
+ @user
+ else
+ password = generate_random_password
+ @user = User.create(:name => name,
+ :email => email,
+ :password => password,
+ :password_confirmation => password
+ )
+ end
+ end
end
# == Schema Information
#
diff --git a/app/models/users_project.rb b/app/models/users_project.rb
index b98aa1fded4..726a85ae5b0 100644
--- a/app/models/users_project.rb
+++ b/app/models/users_project.rb
@@ -1,4 +1,9 @@
class UsersProject < ActiveRecord::Base
+ GUEST = 10
+ REPORTER = 20
+ DEVELOPER = 30
+ MASTER = 40
+
belongs_to :user
belongs_to :project
@@ -17,7 +22,6 @@ class UsersProject < ActiveRecord::Base
UsersProject.transaction do
user_ids.each do |user_id|
users_project = UsersProject.new(
- :repo_access => repo_access,
:project_access => project_access,
:user_id => user_id
)
@@ -27,11 +31,45 @@ class UsersProject < ActiveRecord::Base
end
end
+ def self.user_bulk_import(user, project_ids, project_access, repo_access)
+ UsersProject.transaction do
+ project_ids.each do |project_id|
+ users_project = UsersProject.new(
+ :project_access => project_access,
+ )
+ users_project.project_id = project_id
+ users_project.user_id = user.id
+ users_project.save
+ end
+ end
+ end
+
+ def self.access_roles
+ {
+ "Guest" => GUEST,
+ "Reporter" => REPORTER,
+ "Developer" => DEVELOPER,
+ "Master" => MASTER
+ }
+ end
+
+ def role_access
+ project_access
+ end
+
def update_repository
Gitlabhq::GitHost.system.new.configure do |c|
c.update_project(project.path, project)
end
end
+
+ def project_access_human
+ Project.access_options.key(self.project_access)
+ end
+
+ def repo_access_human
+ ""
+ end
end
# == Schema Information
#
@@ -42,7 +80,6 @@ end
# project_id :integer not null
# created_at :datetime
# updated_at :datetime
-# repo_access :integer default(0), not null
# project_access :integer default(0), not null
#
diff --git a/app/models/wiki.rb b/app/models/wiki.rb
new file mode 100644
index 00000000000..ad3e4a38125
--- /dev/null
+++ b/app/models/wiki.rb
@@ -0,0 +1,47 @@
+class Wiki < ActiveRecord::Base
+ belongs_to :project
+ belongs_to :user
+
+ validates :content, :title, :user_id, :presence => true
+ validates :title, :length => 1..250
+
+ before_update :set_slug
+
+
+ def to_param
+ slug
+ end
+
+ protected
+
+ def set_slug
+ self.slug = self.title.parameterize
+ end
+
+ class << self
+ def regenerate_from wiki
+ regenerated_field = [:slug, :content, :title]
+
+ new_wiki = Wiki.new
+ regenerated_field.each do |field|
+ new_wiki.send("#{field}=", wiki.send(field))
+ end
+ new_wiki
+ end
+
+ end
+end
+# == Schema Information
+#
+# Table name: wikis
+#
+# id :integer not null, primary key
+# title :string(255)
+# content :text
+# project_id :integer
+# created_at :datetime not null
+# updated_at :datetime not null
+# slug :string(255)
+# user_id :integer
+#
+
diff --git a/app/views/admin/projects/_form.html.haml b/app/views/admin/projects/_form.html.haml
index ea42ed22311..4f6bc692b67 100644
--- a/app/views/admin/projects/_form.html.haml
+++ b/app/views/admin/projects/_form.html.haml
@@ -1,39 +1,66 @@
= form_for [:admin, @admin_project] do |f|
-if @admin_project.errors.any?
- #error_explanation
- %h2= "#{pluralize(@admin_project.errors.count, "error")} prohibited this admin_project from being saved:"
+ .alert-message.block-message.error
%ul
- @admin_project.errors.full_messages.each do |msg|
%li= msg
- .form-row
+ .clearfix
= f.label :name
- %br
- = f.text_field :name
- .form-row
- = f.label :code
- %br
- = f.text_field :code
- .form-row
- = f.label :path
- %br
- = f.text_field :path
-
- .form-row
- = f.label :tag_list
- %br
- = f.text_area :tag_list, :placeholder => "project tags", :style => "height:50px", :id => :tag_field
-
- .form-row
+ .input= f.text_field :name
+ .clearfix
+ = f.label :path do
+ Path
+ .input
+ .input-prepend
+ %span.add-on= "git@#{GIT_HOST["host"]}:"
+ = f.text_field :path, :placeholder => "example_project", :disabled => !@admin_project.new_record?
+ .clearfix
+ = f.label :code do
+ Code
+ .input
+ .input-prepend
+ %span.add-on= "http://#{GIT_HOST["host"]}/"
+ = f.text_field :code, :placeholder => "example"
+
+ - unless @admin_project.new_record?
+ .clearfix
+ = f.label :owner_id
+ .input= f.select :owner_id, User.all.map { |user| [user.name, user.id] }
+
+ - unless @admin_project.heads.empty?
+ .clearfix
+ = f.label :default_branch, "Default Branch"
+ .input= f.select(:default_branch, @admin_project.heads.map(&:name), {}, :style => "width:210px;")
+
+ .well
+ %h5 Features
+
+ .clearfix
+ = f.label :issues_enabled, "Issues"
+ .input= f.check_box :issues_enabled
+
+ .clearfix
+ = f.label :merge_requests_enabled, "Merge Requests"
+ .input= f.check_box :merge_requests_enabled
+
+ .clearfix
+ = f.label :wall_enabled, "Wall"
+ .input= f.check_box :wall_enabled
+
+ .clearfix
= f.label :description
- %br
- = f.text_area :description
+ .input= f.text_area :description, :class => "xxlarge"
.clear
%br
.actions
- = f.submit 'Save', :class => "grey-button"
+ = f.submit 'Save', :class => "btn primary"
+ = link_to 'Cancel', [:admin, @admin_project], :class => "btn"
+ = link_to 'Destroy', [:admin, @admin_project], :confirm => 'Are you sure?', :method => :delete, :class => "btn danger right"
:javascript
$(function(){
taggifyForm();
+ $('#project_owner_id').chosen();
+ $('#project_default_branch').chosen();
})
diff --git a/app/views/admin/projects/edit.html.haml b/app/views/admin/projects/edit.html.haml
index a6062be4014..b8d6f6899cb 100644
--- a/app/views/admin/projects/edit.html.haml
+++ b/app/views/admin/projects/edit.html.haml
@@ -1,7 +1,3 @@
-%h2= @admin_project.name
+%h3= @admin_project.name
+%hr
= render 'form'
-
-%br
-= link_to 'Back', admin_projects_path, :class => ""
-|
-= link_to 'Show', [:admin, @admin_project], :class => ""
diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml
index f57b98d0f34..7cda5220d68 100644
--- a/app/views/admin/projects/index.html.haml
+++ b/app/views/admin/projects/index.html.haml
@@ -1,7 +1,10 @@
-%table
+%h3
+ Projects
+ = link_to 'New Project', new_admin_project_path, :class => "btn small right"
+%hr
+%table.zebra-striped
%thead
%th Name
- %th Code
%th Path
%th Team Members
%th Last Commit
@@ -11,12 +14,9 @@
- @admin_projects.each do |project|
%tr
%td= link_to project.name, [:admin, project]
- %td= project.code
%td= project.path
%td= project.users_projects.count
%td= last_commit(project)
- %td= link_to 'Edit', edit_admin_project_path(project), :id => "edit_#{dom_id(project)}"
- %td= link_to 'Destroy', [:admin, project], :confirm => 'Are you sure?', :method => :delete
-
+ %td= link_to 'Edit', edit_admin_project_path(project), :id => "edit_#{dom_id(project)}", :class => "btn small"
+ %td= link_to 'Destroy', [:admin, project], :confirm => 'Are you sure?', :method => :delete, :class => "btn small danger"
= paginate @admin_projects
-= link_to 'New Project', new_admin_project_path, :class => "grey-button"
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index cc83add6db4..5142dac55c4 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -1,10 +1,10 @@
-- unless notice.nil?
- %p#notice= notice
+%h3
+ = @admin_project.name
+ = link_to 'Edit', edit_admin_project_path(@admin_project), :class => "btn right small"
+%hr
-%h2= @admin_project.name
-
-%table.round-borders
+%table.zebra-striped
%tr
%td
%b
@@ -29,14 +29,32 @@
Description:
%td
= @admin_project.description
- %tr
- %td{:colspan => 2}
- = link_to 'Edit', edit_admin_project_path(@admin_project), :class => "grey-button"
.span-14
- %h2 Team
+ %h3
+ Team
+ %small
+ ( #{@admin_project.users_projects.count} )
+
+ %hr
+
+ %table.zebra-striped
+ %thead
+ %tr
+ %th Name
+ %th Project Access
+ %th Repository Access
+ %th
+
+ - @admin_project.users_projects.each do |tm|
+ %tr
+ %td
+ = link_to tm.user_name, admin_users_path(tm.user)
+ %td= select_tag :tm_project_access, options_for_select(Project.access_options, tm.project_access), :class => "medium project-access-select", :disabled => :disabled
+ %td= link_to 'Edit Access', edit_admin_team_member_path(tm), :class => "btn small"
+ %td= link_to 'Remove from team', admin_team_member_path(tm), :confirm => 'Are you sure?', :method => :delete, :class => "btn danger small"
= form_tag team_update_admin_project_path(@admin_project), :class => "bulk_import", :method => :put do
%table
@@ -49,29 +67,9 @@
%tr
%td= select_tag :user_ids, options_from_collection_for_select(@users , :id, :name), :multiple => true
%td= select_tag :project_access, options_for_select(Project.access_options), :class => "project-access-select"
- %td= select_tag :repo_access, options_for_select(Repository.access_options), :class => "repo-access-select"
-
- %tr
- %td{ :colspan => 3 }
- = submit_tag 'Add', :class => "positive-button"
- %table.round-borders
- %thead
- %tr
- %th Name
- %th Added
- %th Project Access
- %th Repository Access
- %th
-
- - @admin_project.users_projects.each do |tm|
- %tr
- %td
- = link_to tm.user_name, admin_team_member_path(tm)
- %td= time_ago_in_words(tm.updated_at) + " ago"
- %td= select_tag :tm_project_access, options_for_select(Project.access_options, tm.project_access), :class => "project-access-select", :disabled => :disabled
- %td= select_tag :tm_repo_access, options_for_select(Repository.access_options, tm.repo_access), :class => "repo-access-select", :disabled => :disabled
- %td= link_to 'Destroy', admin_team_member_path(tm), :confirm => 'Are you sure?', :method => :delete
+ .actions
+ = submit_tag 'Add', :class => "btn primary"
:css
form select {
diff --git a/app/views/admin/team_members/_form.html.haml b/app/views/admin/team_members/_form.html.haml
index f8e7f1043d0..0bf9020f748 100644
--- a/app/views/admin/team_members/_form.html.haml
+++ b/app/views/admin/team_members/_form.html.haml
@@ -1,33 +1,19 @@
-= form_for @admin_team_member, :as => :team_member, :url => @admin_team_member.new_record? ? admin_team_members_path(@admin_team_member) : admin_team_member_path(@admin_team_member) do |f|
+= form_for @admin_team_member, :as => :team_member, :url => admin_team_member_path(@admin_team_member) do |f|
-if @admin_team_member.errors.any?
- #error_explanation
- %h2= "#{pluralize(@admin_team_member.errors.count, "error")} prohibited this admin_project from being saved:"
+ .alert-message.block-message.error
%ul
- @admin_team_member.errors.full_messages.each do |msg|
%li= msg
- - if @admin_team_member.new_record?
- .span-6
- = f.label :user_id
- .span-6
- = f.select :user_id, User.all.map { |user| [user.name, user.id] }
- .span-6
- = f.label :project_id
- .span-6
- = f.select :project_id, Project.all.map { |user| [user.name, user.id] }
+ .clearfix
+ %label Project Access:
+ .input
+ = f.select :project_access, options_for_select(Project.access_options, @admin_team_member.project_access), {}, :class => "project-access-select"
- .span-6
- %b Project Access:
- .span-6
- = f.select :project_access, options_for_select(Project.access_options, @admin_team_member.project_access), {}, :class => "project-access-select"
-
- .span-6
- %b Repository Access:
- .span-6
- = f.select :repo_access, options_for_select(Repository.access_options, @admin_team_member.repo_access), {}, :class => "repo-access-select"
%br
.actions
- = f.submit 'Save', :class => "grey-button"
+ = f.submit 'Save', :class => "btn primary"
+ = link_to 'Cancel', :back, :class => "btn"
:css
form select {
diff --git a/app/views/admin/team_members/edit.html.haml b/app/views/admin/team_members/edit.html.haml
index 2f4832b86c0..431387be152 100644
--- a/app/views/admin/team_members/edit.html.haml
+++ b/app/views/admin/team_members/edit.html.haml
@@ -1,6 +1,19 @@
-= render 'form'
+%h3
+ Edit access
+ %small
+ = @admin_team_member.project.name
+ &ndash;
+ = @admin_team_member.user_name
-%br
-= link_to 'Show', admin_team_member_path(@admin_team_member)
-\|
-= link_to 'Back', admin_team_members_path
+%hr
+%table.zebra-striped
+ %tr
+ %td User:
+ %td= @admin_team_member.user_name
+ %tr
+ %td Project:
+ %td= @admin_team_member.project.name
+ %tr
+ %td Since:
+ %td= @admin_team_member.updated_at.stamp("Nov 11, 2010")
+= render 'form'
diff --git a/app/views/admin/team_members/index.html.haml b/app/views/admin/team_members/index.html.haml
deleted file mode 100644
index 8033e690642..00000000000
--- a/app/views/admin/team_members/index.html.haml
+++ /dev/null
@@ -1,28 +0,0 @@
-- @admin_team_members.group_by(&:project).sort.each do |project, members|
- %h3= link_to project.name, [:admin, project]
- %table
- %thead
- %th Name
- %th Project Access
- %th Repo Access
- %th Added
- %th
- %th
- - members.each do |tm|
- - user = tm.user
- %tr
- %td.span-6
- = link_to tm.user_name, admin_team_member_path(tm)
- %br
- %br
- = tm.user_email
- %td.span-3= select_tag :project_access, options_for_select(Project.access_options, tm.project_access), :class => "project-access-select", :disabled => :disabled
- %td.span-3= select_tag :repo_access, options_for_select(Repository.access_options, tm.repo_access), :class => "repo-access-select", :disabled => :disabled
- %td.span-3= time_ago_in_words(tm.updated_at) + " ago"
- %td= link_to 'Edit', edit_admin_team_member_path(tm), :id => "edit_#{dom_id(tm)}"
- %td= link_to 'Destroy', admin_team_member_path(tm), :confirm => 'Are you sure?', :method => :delete
-
-%br
-
-= paginate @admin_team_members
-= link_to 'New Team Member', new_admin_team_member_path, :class => "grey-button"
diff --git a/app/views/admin/team_members/new.html.haml b/app/views/admin/team_members/new.html.haml
deleted file mode 100644
index c08ddc48eed..00000000000
--- a/app/views/admin/team_members/new.html.haml
+++ /dev/null
@@ -1,6 +0,0 @@
-%h1 New team member
-
-= render 'form'
-
-%br
-= link_to 'Back', admin_team_members_path
diff --git a/app/views/admin/team_members/show.html.haml b/app/views/admin/team_members/show.html.haml
deleted file mode 100644
index 8579b6afae0..00000000000
--- a/app/views/admin/team_members/show.html.haml
+++ /dev/null
@@ -1,26 +0,0 @@
-#infoblock
- %p
- %b Name:
- = @admin_team_member.user_name
- %p
- %b Project:
- = @admin_team_member.project.name
- %p
- %b Since:
- = @admin_team_member.updated_at.stamp("Nov 11, 2010")
-
-#infoblock
- .span-6
- %b Project Access:
- = select_tag :project_access, options_for_select(Project.access_options, @admin_team_member.project_access), :class => "project-access-select", :disabled => true
-
- %br
- .span-6
- %b Repository Access:
- = select_tag :repo_access, options_for_select(Repository.access_options, @admin_team_member.repo_access), :class => "repo-access-select", :disabled => true
-
-%br
-
-= link_to 'Edit', edit_admin_team_member_path(@admin_project)
-\|
-= link_to 'Back', admin_team_members_path
diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml
index e695332239f..bb54c184e78 100644
--- a/app/views/admin/users/_form.html.haml
+++ b/app/views/admin/users/_form.html.haml
@@ -2,48 +2,43 @@
= form_for [:admin, @admin_user] do |f|
-if @admin_user.errors.any?
#error_explanation
- %h2= "#{pluralize(@admin_user.errors.count, "error")} prohibited this admin_user from being saved:"
%ul
- @admin_user.errors.full_messages.each do |msg|
%li= msg
- .form-row
+ .clearfix
= f.label :name
- %br
- = f.text_field :name
- .form-row
+ .input= f.text_field :name
+ .clearfix
= f.label :email
- %br
- = f.text_field :email
- .form-row
+ .input= f.text_field :email
+ .clearfix
= f.label :password
- %br
- = f.password_field :password
- .form-row
+ .input= f.password_field :password
+ .clearfix
= f.label :password_confirmation
- %br
- = f.password_field :password_confirmation
- .form-row
- = f.check_box :admin
- = f.label :admin
+ .input= f.password_field :password_confirmation
- .form-row
- = f.text_field :projects_limit, :class => "small_input"
+ .clearfix
= f.label :projects_limit
+ .input= f.text_field :projects_limit, :class => "small_input"
- .form-row
+ .clearfix
= f.label :skype
- %br
- = f.text_field :skype
- .form-row
+ .input= f.text_field :skype
+ .clearfix
= f.label :linkedin
- %br
- = f.text_field :linkedin
- .form-row
+ .input= f.text_field :linkedin
+ .clearfix
= f.label :twitter
- %br
- = f.text_field :twitter
- .clear
- %br
+ .input= f.text_field :twitter
+ .clearfix
+ = f.label :admin do
+ = f.check_box :admin
+ %span Administrator
.actions
- = f.submit 'Save', :class => "grey-button"
+ = f.submit 'Save', :class => "btn primary"
+ - if @admin_user.new_record?
+ = link_to 'Cancel', admin_users_path, :class => "btn"
+ - else
+ = link_to 'Cancel', admin_user_path(@admin_user), :class => "btn"
diff --git a/app/views/admin/users/edit.html.haml b/app/views/admin/users/edit.html.haml
index 2ccd2f72546..0e94be9e12c 100644
--- a/app/views/admin/users/edit.html.haml
+++ b/app/views/admin/users/edit.html.haml
@@ -1,6 +1,3 @@
+%h3= @admin_user.name
+%hr
= render 'form'
-
-%br
-= link_to 'Back', admin_users_path, :class => ""
-|
-= link_to 'Show', [:admin, @admin_user], :class => ""
diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml
index db58a6b47a2..a0b4df1ff10 100644
--- a/app/views/admin/users/index.html.haml
+++ b/app/views/admin/users/index.html.haml
@@ -1,4 +1,8 @@
-%table
+%h3
+ Users
+ = link_to 'New User', new_admin_user_path, :class => "btn small right"
+%hr
+%table.zebra-striped
%thead
%th Admin
%th Name
@@ -13,9 +17,7 @@
%td= link_to user.name, [:admin, user]
%td= user.email
%td= user.users_projects.count
- %td= link_to 'Edit', edit_admin_user_path(user), :id => "edit_#{dom_id(user)}"
- %td= link_to 'Destroy', [:admin, user], :confirm => 'Are you sure?', :method => :delete
+ %td= link_to 'Edit', edit_admin_user_path(user), :id => "edit_#{dom_id(user)}", :class => "btn small"
+ %td= link_to 'Destroy', [:admin, user], :confirm => 'Are you sure?', :method => :delete, :class => "btn small danger"
= paginate @admin_users
-%br
-= link_to 'New User', new_admin_user_path, :class => "grey-button"
diff --git a/app/views/admin/users/new.html.haml b/app/views/admin/users/new.html.haml
index 87ea570b790..87d6b0f2757 100644
--- a/app/views/admin/users/new.html.haml
+++ b/app/views/admin/users/new.html.haml
@@ -1,6 +1,3 @@
-%h1 New user
-
+%h2 New user
+%hr
= render 'form'
-
-%br
-= link_to 'Back', admin_users_path, :class => ""
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index da8f4370cab..21529ab6305 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -1,6 +1,10 @@
-%h2= @admin_user.name
+%h3
+ = @admin_user.name
+ = link_to 'Edit', edit_admin_user_path(@admin_user), :class => "btn small right"
-%table.round-borders
+%hr
+
+%table.zebra-striped
%tr
%td
%b
@@ -39,31 +43,55 @@
Twitter:
%td
= @admin_user.twitter
- %tr
- %td{:colspan => 2}
- = link_to 'Edit', edit_admin_user_path(@admin_user), :class => "grey-button"
-.span-14
- %h2 Projects
+%h3 Projects
+%hr
+
+%table.zebra-striped
+ %tr
+ %thead
+ %th Name
+ %th Project Access
+ %th Repository Access
+ %th
+ %th
- %table.round-borders
+ - @admin_user.users_projects.each do |tm|
+ - project = tm.project
%tr
- %thead
- %th Name
- %th Added
- %th Project Access
- %th Repository Access
- %th
- %th
+ %td= link_to project.name, admin_project_path(project)
+ %td= select_tag :tm_project_access, options_for_select(Project.access_options, tm.project_access), :class => "medium project-access-select", :disabled => :disabled
+ %td= link_to 'Edit Access', edit_admin_team_member_path(tm), :class => "btn small"
+ %td= link_to 'Remove from team', admin_team_member_path(tm), :confirm => 'Are you sure?', :method => :delete, :class => "btn small danger"
- - @admin_user.users_projects.each do |tm|
- - project = tm.project
+= form_tag team_update_admin_user_path(@admin_user), :class => "bulk_import", :method => :put do
+ %table
+ %thead
%tr
- %td= link_to project.name, admin_project_path(project)
- %td= time_ago_in_words(tm.updated_at) + " ago"
- %td= select_tag :project_access, options_for_select(Project.access_options, tm.project_access), :class => "project-access-select", :disabled => :disabled
- %td= select_tag :repo_access, options_for_select(Repository.access_options, tm.repo_access), :class => "repo-access-select", :disabled => :disabled
- %td= link_to 'Edit', edit_admin_team_member_path(tm)
- %td= link_to 'Cancel', admin_team_member_path(tm), :confirm => 'Are you sure?', :method => :delete
+ %th Projects
+ %th Project Access:
+ %th Repo Access:
+
+ %tr
+ %td= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name), :multiple => true
+ %td= select_tag :project_access, options_for_select(Project.access_options), :class => "project-access-select"
+
+ .actions
+ = submit_tag 'Add', :class => "btn primary"
+
+
+:css
+ form select {
+ width:150px;
+ }
+
+ #project_ids {
+ width:300px;
+ }
+
+
+:javascript
+ $('select#project_ids').chosen();
+ $('select#repo_access').chosen();
+ $('select#project_access').chosen();
- = link_to 'Add To Another Project', new_admin_team_member_path(:team_member => {:user_id => @admin_user.id}), :class => "grey-button"
diff --git a/app/views/commits/_commit.html.haml b/app/views/commits/_commit.html.haml
new file mode 100644
index 00000000000..a579cca96bb
--- /dev/null
+++ b/app/views/commits/_commit.html.haml
@@ -0,0 +1,17 @@
+%li.wll.commit
+ .right.span2
+ %p
+ %strong= link_to "Browse Code »", tree_project_ref_path(@project, commit.id), :class => "right"
+ = link_to project_commit_path(@project, :id => commit.id) do
+ %p
+ %code.left= commit.id.to_s[0..10]
+ %strong.cgray= commit.author_name
+ &ndash;
+ = image_tag gravatar_icon(commit.author_email), :class => "avatar", :width => 16
+ %span.row_title= truncate(commit.safe_message, :length => 50) rescue "--broken encoding"
+
+ %span.right.cgray
+ = time_ago_in_words(commit.committed_date)
+ ago
+ &nbsp;
+
diff --git a/app/views/commits/_commits.html.haml b/app/views/commits/_commits.html.haml
index 108d1b4c4bf..c2c9ca624b2 100644
--- a/app/views/commits/_commits.html.haml
+++ b/app/views/commits/_commits.html.haml
@@ -1,24 +1,4 @@
- @commits.group_by { |c| c.committed_date.to_date }.each do |day, commits|
- %div{ :class => "commits-date ui-box ui-box-small ui-box-big" }
- .day-commits-table
- %h3= day.stamp("28 Aug, 2010")
- .data
- - commits.each do |commit|
- %a{ :class => "commit", :href => project_commit_path(@project, :id => commit.id) }
- %span.commit-info
- %data.commit-button
- = truncate(commit.id.to_s, :length => 16)
- %i
- %data.commit-browse{ :onclick => "location.href='#{tree_project_ref_path(@project, commit.id)}';return false;"}
- Browse Code
- - if commit.author_email
- = image_tag gravatar_icon(commit.author_email), :class => "left", :width => 40, :style => "padding-right:5px;"
- - else
- = image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;"
- %span.commit-title
- %strong
- = truncate(commit.safe_message, :length => 70)
- %span.commit-author
- %strong= commit.author_name
- = time_ago_in_words(commit.committed_date)
- ago
+ %div.ui-box
+ %h5= day.stamp("28 Aug, 2010")
+ %ul.unstyled= render commits
diff --git a/app/views/commits/_diff_head.html.haml b/app/views/commits/_diff_head.html.haml
index 6e32fca068f..20ec3cf11b0 100644
--- a/app/views/commits/_diff_head.html.haml
+++ b/app/views/commits/_diff_head.html.haml
@@ -1,5 +1,5 @@
%ul.bordered-list
- - @commit.diffs.each do |diff|
+ - diffs.each do |diff|
%li
- if diff.deleted_file
%span.removed_file
diff --git a/app/views/commits/_diff.html.haml b/app/views/commits/_diffs.html.haml
index 190c95dd745..29eae1c43c7 100644
--- a/app/views/commits/_diff.html.haml
+++ b/app/views/commits/_diffs.html.haml
@@ -1,24 +1,26 @@
.file_stats
- = render "commits/diff_head"
-
-- @commit.diffs.each_with_index do |diff, i|
+ = render "commits/diff_head", :diffs => diffs
+
+- diffs.each_with_index do |diff, i|
- next if diff.diff.empty?
- file = (@commit.tree / diff.b_path)
+ - file = (@commit.prev_commit.tree / diff.a_path) unless file
- next unless file
.diff_file
.diff_file_header
- if diff.deleted_file
- %strong{:id => "#{diff.b_path}"}= diff.a_path
+ %strong{:id => "#{diff.a_path}"}= diff.a_path
- else
= link_to tree_file_project_ref_path(@project, @commit.id, diff.b_path) do
%strong{:id => "#{diff.b_path}"}= diff.b_path
%br/
.diff_file_content
- if file.text?
- = render :partial => "commits/text_file", :locals => { :diff => diff, :index => i }
+ = render "commits/text_file", :diff => diff, :index => i
- elsif file.image?
.diff_file_content_image
%img{:src => "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
- else
%p
%center No preview for this file type
+
diff --git a/app/views/commits/_head.html.haml b/app/views/commits/_head.html.haml
new file mode 100644
index 00000000000..6951c3a283c
--- /dev/null
+++ b/app/views/commits/_head.html.haml
@@ -0,0 +1,35 @@
+%ul.tabs
+ %li
+ = form_tag switch_project_refs_path(@project), :method => :get, :class => "project-refs-form" do
+ = select_tag "ref", grouped_options_refs, :onchange => "$(this.form).trigger('submit');", :class => "project-refs-select"
+ = hidden_field_tag :destination, "commits"
+
+ %li{:class => "#{'active' if current_page?(project_commits_path(@project)) }"}
+ = link_to project_commits_path(@project) do
+ Commits
+ %li{:class => "#{'active' if current_page?(compare_project_commits_path(@project)) }"}
+ = link_to compare_project_commits_path(@project) do
+ Compare
+ %li{:class => "#{branches_tab_class}"}
+ = link_to project_repository_path(@project) do
+ Branches
+ %span.number= @project.repo.branches.count
+
+ %li{:class => "#{'active' if current_page?(tags_project_repository_path(@project)) }"}
+ = link_to tags_project_repository_path(@project) do
+ Tags
+ %span.number= @project.repo.tags.count
+
+
+ - if current_page?(project_commits_path(@project)) && current_user.private_token
+ %li.right
+ %span
+ = link_to project_commits_path(@project, :atom, { :private_token => current_user.private_token, :ref => @ref }), :class => "btn" do
+ feed
+ = image_tag "Rss-UI.PNG", :width => 14, :title => "feed"
+
+
+:javascript
+ $(function(){
+ $('.project-refs-select').chosen();
+ });
diff --git a/app/views/commits/_index.html.haml b/app/views/commits/_index.html.haml
deleted file mode 100644
index f1e4c7eb3f1..00000000000
--- a/app/views/commits/_index.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-= form_tag project_commits_path(@project), :method => :get do
- %h3
- = @project.name
- [ #{select_tag "branch", options_for_select(@repo.heads.map(&:name), @branch), :onchange => "this.form.submit();", :class => "small"} ]
-= link_to 'Back', project_path(@project), :class => "button"
-%h1 Listing commits
-%div{:id => dom_id(@project)}
- = render "commits"
-%br/
diff --git a/app/views/commits/_text_file.html.haml b/app/views/commits/_text_file.html.haml
index 513efdf02d9..441bdf2c210 100644
--- a/app/views/commits/_text_file.html.haml
+++ b/app/views/commits/_text_file.html.haml
@@ -1,38 +1,22 @@
%table
- - line_old = 0
- - line_new = 0
- - diff_str = diff.diff
- - lines_arr = diff_str.lines.to_a
- - lines_arr.each do |line|
- - next if line.match(/^--- \/dev\/null/)
- - next if line.match(/^--- a/)
- - next if line.match(/^\+\+\+ b/)
- - if line.match(/^@@ -/)
- - unless line_old.zero? && line_new.zero?
- %tr.line_holder
- %td.old_line= "..."
- %td.new_line= "..."
- %td.line_content &nbsp;
-
- - line_old = line.match(/\-[0-9]*/)[0].to_i.abs rescue 0
- - line_new = line.match(/\+[0-9]*/)[0].to_i.abs rescue 0
- - next
-
- - full_line = html_escape(line.gsub(/\n/, ''))
+ - each_diff_line(diff.diff.lines.to_a, index) do |line, type, line_code, line_new, line_old|
%tr.line_holder
- %td.old_line
- = link_to raw(diff_line_class(line) == "new" ? "&nbsp;" : line_old), "#OLD#{index}-#{line_old}", :id => "OLD#{index}-#{line_old}"
- %td.new_line
- = link_to raw(diff_line_class(line) == "old" ? "&nbsp;" : line_new) , "#NEW#{index}-#{line_new}", :id => "NEW#{index}-#{line_new}"
- %td.line_content{:class => "#{diff_line_class(full_line)} #{build_line_code(line, index, line_new, line_old)}", "line_code" => build_line_code(line, index, line_new, line_old)}= raw "#{full_line} &nbsp;"
- - comments = @line_notes.select { |n| n.for_line?(index, line_old, line_new) }.sort_by(&:created_at).reverse
- - unless comments.empty?
- - comments.each do |note|
- = render "notes/per_line_show", :note => note
- - if line[0] == "+"
- - line_new += 1
- - elsif line[0] == "-"
- - line_old += 1
- - else
- - line_new += 1
- - line_old += 1
+ - if type == "match"
+ %td.old_line= "..."
+ %td.new_line= "..."
+ %td.line_content.matched= line
+ - else
+ %td.old_line
+ = link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", :id => line_code
+ - if @comments_allowed
+ = link_to "", "#", :class => "line_note_link", "line_code" => line_code, :title => "Add note for this line"
+ %td.new_line= link_to raw(type == "old" ? "&nbsp;" : line_new) , "##{line_code}", :id => line_code
+ %td.line_content{:class => "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw "#{line} &nbsp;"
+
+ - if @comments_allowed
+ - comments = @line_notes.select { |n| n.line_code == line_code }.sort_by(&:created_at).reverse
+ - unless comments.empty?
+ - comments.each_with_index do |note, i|
+ = render "notes/reply_button", :line_code => line_code if i.zero?
+ = render "notes/per_line_show", :note => note
+ - @line_notes.reject!{ |n| n == note }
diff --git a/app/views/commits/compare.html.haml b/app/views/commits/compare.html.haml
new file mode 100644
index 00000000000..877bd40709b
--- /dev/null
+++ b/app/views/commits/compare.html.haml
@@ -0,0 +1,49 @@
+= render "head"
+
+%h3
+ Compare View
+%hr
+
+%div
+ %p
+ Fill input field with commit id like
+ %code '4eedf23'
+ or branch/tag name like
+ %code master
+ &amp; press compare button for commits list, code diff.
+
+ %br
+
+ = form_tag compare_project_commits_path(@project), :method => :get do
+ .clearfix
+ = text_field_tag :from, params[:from], :placeholder => "master", :class => "xlarge"
+ = "..."
+ = text_field_tag :to, params[:to], :placeholder => "aa8b4ef", :class => "xlarge"
+ .actions
+ = submit_tag "Compare", :class => "btn primary"
+
+
+- unless @commits.empty?
+ %h4 Commits
+ %ul.unstyled= render @commits
+
+- unless @diffs.empty?
+ %h4 Diff
+ = render "commits/diffs", :diffs => @diffs
+
+
+:javascript
+ $(function() {
+ var availableTags = #{@project.heads.map(&:name).to_json};
+
+ $( "#from" ).autocomplete({
+ source: availableTags,
+ minLength: 1
+ });
+
+ $( "#to" ).autocomplete({
+ source: availableTags,
+ minLength: 1
+ });
+ });
+
diff --git a/app/views/commits/index.html.haml b/app/views/commits/index.html.haml
index 5a760b3a2dc..6cc6ba5fdeb 100644
--- a/app/views/commits/index.html.haml
+++ b/app/views/commits/index.html.haml
@@ -1,16 +1,14 @@
-- content_for(:body_class, "project-page commits-page")
-- if current_user.private_token
- = content_for :rss_icon do
- .rss-icon
- = link_to project_commits_path(@project, :atom, { :private_token => current_user.private_token, :ref => @ref }) do
- = image_tag "Rss-UI.PNG", :width => 22, :title => "feed"
+= render "head"
- if params[:path]
- %h2
- = link_to project_commits_path(@project) do
- = @project.code
- \/
- %a{:href => "#"}= params[:path].split("/").join(" / ")
+ %ul.breadcrumb
+ %li
+ = link_to project_commits_path(@project) do
+ = @project.code
+ %span.divider
+ \/
+ %li
+ %a{:href => "#"}= params[:path].split("/").join(" / ")
%div{:id => dom_id(@project)}
#commits_list= render "commits"
@@ -21,5 +19,6 @@
- if @commits.count == @limit
:javascript
$(function(){
- CommitsList.init("#{@ref}", 20);
+ CommitsList.init("#{@ref}", #{@limit});
});
+
diff --git a/app/views/commits/show.html.haml b/app/views/commits/show.html.haml
index 3e847e78db5..9c1df54ea70 100644
--- a/app/views/commits/show.html.haml
+++ b/app/views/commits/show.html.haml
@@ -1,20 +1,16 @@
-- content_for(:body_class, "project-page commits-page")
.commit
- %span.commit-info
- = link_to tree_project_ref_path(@project, @commit.id) do
- %data.commit-button
- Browse Code
- %i
- - if @commit.author_email
- = image_tag gravatar_icon(@commit.author_email), :class => "left", :width => 40, :style => "padding-right:5px;"
- - else
- = image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;"
- %span.commit-title
- %strong
- = truncate(@commit.id.to_s, :length => 60)
- %span.commit-author
- %strong= @commit.author_name
- = @commit.created_at.stamp("Aug 21, 2011 9:23pm")
+ = link_to tree_project_ref_path(@project, @commit.id), :class => "btn right small" do
+ Browse Code »
+ = image_tag gravatar_icon(@commit.author_email), :class => "avatar"
+ %code= @commit.id.to_s
+ %h5
+ = @commit.author_name
+ %small= @commit.created_at.stamp("Aug 21, 2011 9:23pm")
+ - if @commit.author_name != @commit.committer_name or @commit.author_email != @commit.committer_email or @commit.authored_date != @commit.committed_date
+ &ndash;
+ %cite committed by
+ = @commit.committer_name
+ %small= @commit.committed_date.stamp("Aug 21, 2011 9:23pm")
%hr
%pre.commit_message
@@ -22,17 +18,20 @@
.clear
%br
-= render "commits/diff"
-= render "notes/notes"
+%p.cgray
+ Showing #{pluralize(@commit.diffs.count, "changed file")}
+= render "commits/diffs", :diffs => @commit.diffs
+= render "notes/notes", :tid => @commit.id, :tt => "commit"
= render "notes/per_line_form"
:javascript
$(document).ready(function(){
- $(".line_content").live("dblclick", function(e) {
+ $(".line_note_link, .line_note_reply_link").live("click", function(e) {
var form = $(".per_line_form");
- $(this).parent().after(form);
+ $(this).parent().parent().after(form);
form.find("#note_line_code").val($(this).attr("line_code"));
form.show();
+ return false;
});
});
diff --git a/app/views/dashboard/_events_feed.html.haml b/app/views/dashboard/_events_feed.html.haml
new file mode 100644
index 00000000000..e341319503e
--- /dev/null
+++ b/app/views/dashboard/_events_feed.html.haml
@@ -0,0 +1,19 @@
+- @events.each do |event|
+ .wll.event_feed
+ - if event.push?
+ - if event.new_branch?
+ User pushed new branch
+ - else
+ = image_tag gravatar_icon(event.pusher_email), :class => "avatar"
+ #{event.pusher_name} pushed to
+ = link_to project_commits_path(event.project, :ref => event.branch_name) do
+ %strong= event.branch_name
+ %span.cgray
+ = time_ago_in_words(event.created_at)
+ ago.
+ - if event.commits.count > 1
+ = link_to compare_project_commits_path(event.project, :from => event.commits.first.prev_commit_id, :to => event.commits.last.id) do
+ Compare #{event.commits.first.commit.id[0..8]}...#{event.commits.last.id[0..8]}
+ - @project = event.project
+ %ul.unstyled
+ = render event.commits
diff --git a/app/views/dashboard/_issues_feed.html.haml b/app/views/dashboard/_issues_feed.html.haml
index 45892664df7..5c0e05ef0a5 100644
--- a/app/views/dashboard/_issues_feed.html.haml
+++ b/app/views/dashboard/_issues_feed.html.haml
@@ -1,26 +1,10 @@
-#feeds_content_holder
- - unless @issues.empty?
- .project-box.project-updates.ui-box.ui-box-small.ui-box-big
- .data
- - @issues.each do |update|
- %a.project-update{:href => dashboard_feed_path(update.project, update)}
- %strong.issue-number= "##{update.id}"
- %span.update-title
- = truncate update.title, :length => 35
- .right= truncate update.project.name
- %span.update-author
- %strong= update.author_name
- authored
- = time_ago_in_words(update.created_at)
- ago
- .right
- - if update.critical
- %span.tag.high critical
- - if update.today?
- %span.tag.today today
-
- - else
- %h2
- No assigned
- %span.tag.open open
- issues
+- @issues.each do |issue|
+ .wll
+ = link_to [issue.project, issue] do
+ %p
+ %strong
+ %span.label= issue.project.name
+ &ndash;
+ Issue #
+ = issue.id
+ = truncate issue.title, :length => 50
diff --git a/app/views/dashboard/_menu.html.haml b/app/views/dashboard/_menu.html.haml
deleted file mode 100644
index 73d4149deb3..00000000000
--- a/app/views/dashboard/_menu.html.haml
+++ /dev/null
@@ -1,21 +0,0 @@
--#%h4.dash-tabs
- = link_to "Activities", dashboard_path, :remote => true, :class => "dash-button #{"active" if current_page?(dashboard_path) || current_page?(root_path) }", :id => "activities_slide"
- = link_to "Issues", dashboard_issues_path, :remote => true, :class => "dash-button #{"active" if current_page?(dashboard_issues_path)}", :id => "issues_slide"
- = link_to "Merge Requests", dashboard_merge_requests_path, :remote => true, :class => "dash-button #{"active" if current_page?(dashboard_merge_requests_path)}", :id => "merge_requests_slide"
- = image_tag "ajax-loader-facebook.gif", :class => "dashboard-loader"
-
-:javascript
- $(function(){
- $(".dash-button").live("click", function() {
- $(".dash-button").removeClass("active");
- $(this).addClass("active");
- });
-
- $(".dash-button").live("ajax:before", function() {
- $(".dashboard-loader").show();
- });
-
- $(".dash-button").live("ajax:complete", function() {
- $(".dashboard-loader").hide();
- });
- });
diff --git a/app/views/dashboard/_merge_requests_feed.html.haml b/app/views/dashboard/_merge_requests_feed.html.haml
index 1f8553e4a70..db1ebd32a63 100644
--- a/app/views/dashboard/_merge_requests_feed.html.haml
+++ b/app/views/dashboard/_merge_requests_feed.html.haml
@@ -1,24 +1,10 @@
-#feeds_content_holder
- - unless @merge_requests.empty?
- .project-box.project-updates.ui-box.ui-box-small.ui-box-big
- .data
- - @merge_requests.each do |update|
- %a.project-update{:href => project_merge_request_path(update.project, update)}
- = image_tag gravatar_icon(update.author_email), :class => "left", :width => 40
- %span.update-title
- = truncate update.title, :length => 35
- .right= truncate update.project.name
- %span.update-author
- %strong= update.author_name
- authored
- = time_ago_in_words(update.created_at)
- ago
- .right
- %span.tag.commit= update.source_branch
- &rarr;
- %span.tag.commit= update.target_branch
- - else
- %h2
- No authored or assigned
- %span.tag.open open
- merge requests
+- @merge_requests.each do |merge_request|
+ .wll
+ = link_to [merge_request.project, merge_request] do
+ %p
+ %strong
+ %span.label= merge_request.project.name
+ &ndash;
+ Merge Request #
+ = merge_request.id
+ = truncate merge_request.title, :length => 50
diff --git a/app/views/dashboard/_projects_feed.html.haml b/app/views/dashboard/_projects_feed.html.haml
index 0d347246355..1d53cf74849 100644
--- a/app/views/dashboard/_projects_feed.html.haml
+++ b/app/views/dashboard/_projects_feed.html.haml
@@ -1,20 +1,8 @@
-#feeds_content_holder
- - @active_projects.first(3).each do |project|
- .project-box.project-updates.ui-box.ui-box-small.ui-box-big
- = link_to project do
- %h3= project.name
- .data
- - project.updates(3).each do |update|
- %a.project-update{:href => dashboard_feed_path(project, update)}
- = image_tag gravatar_icon(update.author_email), :class => "left", :width => 40
- %span.update-title
- = dashboard_feed_title(update)
- %span.update-author
- %strong= update.author_name
- authored
- = time_ago_in_words(update.created_at)
- ago
- .right
- - klass = update.class.to_s.split("::").last.downcase
- %span.tag{ :class => klass }= klass
-
+- @active_projects.first(5).each do |project|
+ .wll
+ = link_to project do
+ %h4
+ = project.name
+ %small
+ last activity at
+ = project.last_activity_date_cached.stamp("Aug 25, 2011")
diff --git a/app/views/dashboard/_sidebar.html.haml b/app/views/dashboard/_sidebar.html.haml
deleted file mode 100644
index dec71186f73..00000000000
--- a/app/views/dashboard/_sidebar.html.haml
+++ /dev/null
@@ -1,15 +0,0 @@
-%aside
- %h4
- - if current_user.can_create_project?
- %a.button-small.button-green{:href => new_project_path} New Project
- Your Projects
- %ol.project-list
- - @projects.each do |project|
- %li
- %a{:href => project_path(project)}
- -#%span.arrow →
- %span.project-name= project.name
- %span.time
- %strong Last activity:
- = project.last_activity_date_cached ? time_ago_in_words(project.last_activity_date_cached) + " ago" : "Never"
-
diff --git a/app/views/dashboard/index.html.haml b/app/views/dashboard/index.html.haml
index 7f6beffb53f..27490e40c7e 100644
--- a/app/views/dashboard/index.html.haml
+++ b/app/views/dashboard/index.html.haml
@@ -1,6 +1,65 @@
-- content_for(:body_class, "dashboard-page")
+- if current_user.require_ssh_key?
+ .alert-message.warning
+ %p
+ You wont be able to pull/push project code unless you
+ = link_to new_key_path, :class => "vlink" do
+ add new key
+ to your profile
-#dashboard-content.dashboard-content.content
- = render "dashboard/sidebar"
- = render "dashboard/menu"
- #news-feed.news-feed= render "dashboard/projects_feed"
+%div.dashboard_category
+ %h3
+ Projects
+ %small
+ ( most recent )
+
+ %strong.right
+ = link_to projects_path do
+ Projects list &rarr;
+ %hr
+ .row
+ .dashboard_block
+ .row
+ .span9= render "dashboard/projects_feed"
+ .span3.right
+ - if current_user.can_create_project?
+ .alert-message.block-message.warning
+ You can create up to
+ = current_user.projects_limit
+ projects. Click on link below to add a new one
+ .link_holder
+ = link_to new_project_path, :class => "" do
+ New Project »
+
+
+- unless @merge_requests.blank?
+ %div.dashboard_category
+ %h3
+ Merge Requests
+ %small ( authored or assigned to you )
+ %strong.right
+ = link_to dashboard_merge_requests_path do
+ Vist merge requests page &rarr;
+ %hr
+ .row
+ .dashboard_block= render "dashboard/merge_requests_feed"
+
+- unless @issues.blank?
+ %div.dashboard_category
+ %h3
+ Issues
+ %small ( assigned to you )
+ %strong.right
+ = link_to dashboard_merge_requests_path do
+ Vist issues page &rarr;
+ %hr
+ .row
+ .dashboard_block= render "dashboard/issues_feed"
+
+- unless @events.blank?
+ %div.dashboard_category
+ %h3
+ Activities
+
+ %hr
+ .row
+ .dashboard_block= render "dashboard/events_feed"
diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml
index 4b7af96a646..b9c467a5235 100644
--- a/app/views/dashboard/issues.html.haml
+++ b/app/views/dashboard/issues.html.haml
@@ -1,6 +1,6 @@
-- content_for(:body_class, "dashboard-page")
+%h3
+ Issues
+ %small ( assigned to you )
-#dashboard-content.dashboard-content.content
- = render "dashboard/sidebar"
- = render "dashboard/menu"
- #news-feed.news-feed= render "dashboard/issues_feed"
+%br
+.ui-box= render "dashboard/issues_feed"
diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml
index 3497062c8f6..ec1c233c33c 100644
--- a/app/views/dashboard/merge_requests.html.haml
+++ b/app/views/dashboard/merge_requests.html.haml
@@ -1,6 +1,6 @@
-- content_for(:body_class, "dashboard-page")
+%h3
+ Merge Requests
+ %small ( authored or assigned to you )
-#dashboard-content.dashboard-content.content
- = render "dashboard/sidebar"
- = render "dashboard/menu"
- #news-feed.news-feed= render "dashboard/merge_requests_feed"
+%br
+.ui-box= render "dashboard/merge_requests_feed"
diff --git a/app/views/deploy_keys/_form.html.haml b/app/views/deploy_keys/_form.html.haml
index f0a300bb60e..2aa57cdc59b 100644
--- a/app/views/deploy_keys/_form.html.haml
+++ b/app/views/deploy_keys/_form.html.haml
@@ -1,18 +1,18 @@
%div
= form_for [@project, @key], :url => project_deploy_keys_path do |f|
-if @key.errors.any?
- %ul.errors_holder
- - @key.errors.full_messages.each do |msg|
- %li= msg
-
- %table.no-borders
- %tr
- %td= f.label :title
- %td= f.text_field :title, :style => "width:300px"
- %tr
- %td= f.label :key
- %td= f.text_area :key, :style => "width:300px; height:130px"
- %br
- .merge-tabs
- = f.submit 'Save', :class => "positive-button"
+ .alert-message.block-message.error
+ %ul
+ - @key.errors.full_messages.each do |msg|
+ %li= msg
+
+ .clearfix
+ = f.label :title
+ .input= f.text_field :title
+ .clearfix
+ = f.label :key
+ .input= f.text_area :key, :class => "xlarge"
+ .actions
+ = f.submit 'Save', :class => "primary btn"
+ = link_to "Cancel", project_deploy_keys_path(@project), :class => "btn"
diff --git a/app/views/deploy_keys/_show.html.haml b/app/views/deploy_keys/_show.html.haml
index b1622f35167..ff17b3cd66c 100644
--- a/app/views/deploy_keys/_show.html.haml
+++ b/app/views/deploy_keys/_show.html.haml
@@ -1,7 +1,12 @@
-%a.update-item{:href => project_deploy_key_path(key.project, key)}
- %span.update-title
- = key.title
- %span.update-author
- Added
- = time_ago_in_words(key.created_at)
- ago
+%tr
+ %td
+ %a{:href => project_deploy_key_path(key.project, key)}
+ %strong= key.title
+ %td
+ %span.update-author
+ Added
+ = time_ago_in_words(key.created_at)
+ ago
+ %td
+ = link_to 'Remove', project_deploy_key_path(key.project, key), :confirm => 'Are you sure?', :method => :delete, :class => "danger btn delete-key small right"
+
diff --git a/app/views/deploy_keys/index.html.haml b/app/views/deploy_keys/index.html.haml
index 02c8c135998..b03e7539806 100644
--- a/app/views/deploy_keys/index.html.haml
+++ b/app/views/deploy_keys/index.html.haml
@@ -1,17 +1,10 @@
= render "repositories/head"
-
-%div#keys-table{ :class => "update-data ui-box ui-box-small ui-box-big" }
- .data
- - @keys.each do |key|
- = render(:partial => 'show', :locals => {:key => key})
-
-- if @keys.blank?
- .notice_holder
- %li Deploy Keys do not exist yet.
- - if can? current_user, :admin_project, @project
- %li You can add a new one by clicking on "Add New" button
-
-:javascript
- $('.delete-key').live('ajax:success', function() {
- $(this).closest('.update-item').fadeOut(); });
-
+- if can? current_user, :admin_project, @project
+ .alert-message.block-message
+ Deploy keys allow read-only access to repository.
+ = link_to new_project_deploy_key_path(@project), :class => "btn small", :title => "New Deploy Key" do
+ Add Deploy Key
+
+%table.zebra-striped.borders
+ - @keys.each do |key|
+ = render(:partial => 'show', :locals => {:key => key})
diff --git a/app/views/deploy_keys/new.html.haml b/app/views/deploy_keys/new.html.haml
index 1e6b7e77144..a2f1010b454 100644
--- a/app/views/deploy_keys/new.html.haml
+++ b/app/views/deploy_keys/new.html.haml
@@ -1,5 +1,6 @@
= render "repositories/head"
-%h2 New Deploy key
+%h3 New Deploy key
+%hr
= render 'form'
diff --git a/app/views/deploy_keys/show.html.haml b/app/views/deploy_keys/show.html.haml
index 2c5c6149313..16c441bea73 100644
--- a/app/views/deploy_keys/show.html.haml
+++ b/app/views/deploy_keys/show.html.haml
@@ -1,10 +1,7 @@
-.ui-box.width-100p
- %h3= @key.title
- .data
- %pre= @key.key
- .clear
- .buttons
- = link_to 'Remove', project_deploy_key_path(@key.project, @key), :confirm => 'Are you sure?', :method => :delete, :class => "red-button delete-key right"
- .clear
-
-
+= render "repositories/head"
+%h3= @key.title
+%hr
+%pre= @key.key
+.actions
+ = link_to 'Remove', project_deploy_key_path(@key.project, @key), :confirm => 'Are you sure?', :method => :delete, :class => "danger btn delete-key"
+ .clear
diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb
deleted file mode 100644
index ff76588c144..00000000000
--- a/app/views/devise/passwords/edit.html.erb
+++ /dev/null
@@ -1,16 +0,0 @@
-<h2>Change your password</h2>
-
-<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f| %>
- <%= devise_error_messages! %>
- <%= f.hidden_field :reset_password_token %>
-
- <div><%= f.label :password, "New password" %><br />
- <%= f.password_field :password %></div>
-
- <div><%= f.label :password_confirmation, "Confirm new password" %><br />
- <%= f.password_field :password_confirmation %></div>
-
- <div><%= f.submit "Change my password" %></div>
-<% end %>
-
-<%= render :partial => "devise/shared/links" %>
diff --git a/app/views/devise/passwords/edit.html.haml b/app/views/devise/passwords/edit.html.haml
new file mode 100644
index 00000000000..dfd715ac13b
--- /dev/null
+++ b/app/views/devise/passwords/edit.html.haml
@@ -0,0 +1,12 @@
+= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put, :class => "login-box" }) do |f|
+ = image_tag "login-logo.png", :width => "304", :height => "66", :class => "login-logo", :alt => "Login Logo"
+ %h3 Change your password
+ = devise_error_messages!
+ = f.hidden_field :reset_password_token
+ %div
+ = f.password_field :password, :class => "text top", :placeholder => "New password"
+ %div
+ = f.password_field :password_confirmation, :class => "text bottom", :placeholder => "Confirm new password"
+ %div
+ = f.submit "Change my password", :class => "btn primary"
+ .right= render :partial => "devise/shared/links"
diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb
index 01cb3375d1d..cf56c5d2710 100644
--- a/app/views/devise/passwords/new.html.erb
+++ b/app/views/devise/passwords/new.html.erb
@@ -1,8 +1,9 @@
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :class => "login-box", :method => :post }) do |f| %>
<%= image_tag "login-logo.png", :width => "304", :height => "66", :class => "login-logo", :alt => "Login Logo" %>
<%= devise_error_messages! %>
- <%= f.email_field :email, :placeholder => "Email", :class => "text top" %>
+ <%= f.email_field :email, :placeholder => "Email", :class => "text" %>
<br/>
- <%= f.submit "Reset password", :class => "grey-button" %>
+ <br/>
+ <%= f.submit "Reset password", :class => "primary btn" %>
<div class="right"> <%= render :partial => "devise/shared/links" %></div>
<% end %>
diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb
index c17ff3f9914..f40a8794e92 100644
--- a/app/views/devise/sessions/new.html.erb
+++ b/app/views/devise/sessions/new.html.erb
@@ -4,9 +4,12 @@
<%= f.password_field :password, :class => "text bottom", :placeholder => "Password" %>
<% if devise_mapping.rememberable? -%>
- <div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
+ <div class="clearfix inputs-list"> <label for="user_remember_me"><%= f.check_box :remember_me %><span>Remember me</span></label></div>
<% end -%>
<br/>
- <%= f.submit "Sign in", :class => "grey-button" %>
+ <%= f.submit "Sign in", :class => "primary btn" %>
<div class="right"> <%= render :partial => "devise/shared/links" %></div>
+ <% if ldap_enable? -%>
+ <p><%= link_to "via LDAP", user_omniauth_authorize_path(:ldap)%></p>
+ <% end -%>
<% end %>
diff --git a/app/views/devise/shared/_links.erb b/app/views/devise/shared/_links.erb
index 33b1120f992..c624c2d54bf 100644
--- a/app/views/devise/shared/_links.erb
+++ b/app/views/devise/shared/_links.erb
@@ -1,5 +1,5 @@
<%- if controller_name != 'sessions' %>
- <%= link_to "Sign in", new_session_path(resource_name) %><br />
+ <%= link_to "Sign in", new_session_path(resource_name), :class => "btn" %><br />
<% end -%>
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
@@ -7,7 +7,7 @@
<% end -%>
<%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
- <%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
+<%= link_to "Forgot your password?", new_password_path(resource_name), :class => "btn" %><br />
<% end -%>
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
diff --git a/app/views/errors/access_denied.html.haml b/app/views/errors/access_denied.html.haml
new file mode 100644
index 00000000000..718663dbee1
--- /dev/null
+++ b/app/views/errors/access_denied.html.haml
@@ -0,0 +1,5 @@
+.alert-message.block-message.error
+ %h3 Access Denied
+ %hr
+ %p Youre not allowed to access this page
+ %p Read more about project permissions #{link_to "here", help_permissions_path, :class => "vlink"}
diff --git a/app/views/errors/git_not_found.html.haml b/app/views/errors/git_not_found.html.haml
new file mode 100644
index 00000000000..172bd4e678a
--- /dev/null
+++ b/app/views/errors/git_not_found.html.haml
@@ -0,0 +1,9 @@
+.alert-message.block-message.error
+ %h3 Git Resource Not found
+ %hr
+ %p
+ Application cant get access to some
+ %span.label branch
+ or
+ %span.label commit
+ in your repository. Maybe it was moved
diff --git a/app/views/errors/gitolite.html.haml b/app/views/errors/gitolite.html.haml
new file mode 100644
index 00000000000..41d7d83a1c9
--- /dev/null
+++ b/app/views/errors/gitolite.html.haml
@@ -0,0 +1,18 @@
+.alert-message.block-message.error
+ %h3 Gitolite Error
+ %hr
+ %h4 Application cant get access to your gitolite system.
+ %ol
+ %li
+ %p
+ Check 'config/gitlab.yml' for correct settings.
+ %li
+ %p
+ Make sure web server user has access to gitolite.
+ %a{:href => "https://github.com/gitlabhq/gitlabhq/wiki/Gitolite"} Setup tutorial
+ %li
+ %p
+ Try:
+ %pre
+ sudo chmod -R 770 /home/git/repositories/
+ sudo chown -R git:git /home/git/repositories/
diff --git a/app/views/errors/not_found.html.haml b/app/views/errors/not_found.html.haml
new file mode 100644
index 00000000000..9b76a9bf908
--- /dev/null
+++ b/app/views/errors/not_found.html.haml
@@ -0,0 +1,5 @@
+.alert-message.block-message.error
+ %h3 Not found
+ %hr
+ %p Resource you were looking for doesn't exist.
+ %P You may have mistyped the address or it was removed.
diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml
index fd1f512bbd8..2b0b5a191ff 100644
--- a/app/views/help/index.html.haml
+++ b/app/views/help/index.html.haml
@@ -1,43 +1,17 @@
-- bash_lexer = Pygments::Lexer[:bash]
-%div.help_content
- %h2
- Gitlabhq
- %span.right v2.1
- %hr
- %h3 Self Hosted Git Management
- %h3 Fast, secure and stable solution based on Ruby on Rails & Gitolite.
+%h3
+ Gitlabhq
+ %span.right v2.2
+%hr
+%h4 Self Hosted Git Management
+%h4 Fast, secure and stable solution based on Ruby on Rails & Gitolite.
- %hr
+%hr
- .menu
- %h3= link_to "Workflow", "#", :class => "active"
+%h3 Help
- .content
- %h3 Clone project
- .bash
- %pre
- git clone git@example.com:project-name.git
+%ol
+ %li
+ = link_to "Workflow", help_workflow_path
- %h3 Create branch with your feature
- .bash
- %pre
- git checkout -b $feature_name
-
- %h3 Write code. Commit changes
- .bash
- %pre
- git commit -am "My feature is ready"
-
- %h3 Push your branch to gitlabhq
- .bash
- %pre
- git push origin $feature_name
-
- %h3 Review your code
- .bash= image_tag "help_commit.png", :width => 600
-
-
- %h3 Open a merge request
- .bash= image_tag "help_merge_request.png", :width => 600
-
- %h3 Your team lead will review code &amp; merge it to main branch
+ %li
+ = link_to "Permissions", help_permissions_path
diff --git a/app/views/help/permissions.html.haml b/app/views/help/permissions.html.haml
new file mode 100644
index 00000000000..0e6e351b43e
--- /dev/null
+++ b/app/views/help/permissions.html.haml
@@ -0,0 +1,36 @@
+%h3 Permissions
+%hr
+
+%h4 Guest
+%ul
+ %li Create new issue
+ %li Leave comments
+ %li Write on project wall
+
+%h4 Reporter
+%ul
+ %li Pull project code
+ %li Download project
+ %li Create new issue
+ %li Create new merge request
+ %li Write on project wall
+ %li Create a code snippets
+
+
+%h4 Developer
+%ul
+ %li Pull project code
+ %li Create new branches
+ %li Push to non-protected branches
+ %li Remove non-protected branches
+ %li Add tags
+ %li Create new issue
+ %li Create new merge request
+ %li Write on project wall
+ %li Write a wiki
+
+%h4 Master
+%ul
+ %li Full repository access
+ %li Full project access
+ %li Add new team members
diff --git a/app/views/help/workflow.html.haml b/app/views/help/workflow.html.haml
new file mode 100644
index 00000000000..4785b367e65
--- /dev/null
+++ b/app/views/help/workflow.html.haml
@@ -0,0 +1,38 @@
+- bash_lexer = Pygments::Lexer[:bash]
+%h3 Workflow
+%hr
+
+%ol.help
+ %li
+ %p Clone project
+ .bash
+ %pre
+ git clone git@example.com:project-name.git
+
+ %li
+ %p Create branch with your feature
+ .bash
+ %pre
+ git checkout -b $feature_name
+
+ %li
+ %p Write code. Commit changes
+ .bash
+ %pre
+ git commit -am "My feature is ready"
+
+ %li
+ %p Push your branch to gitlabhq
+ .bash
+ %pre
+ git push origin $feature_name
+
+ %li
+ %p Review your code on Commits page
+
+ %li
+ %p Create a merge request
+
+ %li
+ %p Your team lead will review code &amp; merge it to main branch
+
diff --git a/app/views/hooks/index.html.haml b/app/views/hooks/index.html.haml
index 3bff76f47c0..69881752e4b 100644
--- a/app/views/hooks/index.html.haml
+++ b/app/views/hooks/index.html.haml
@@ -1,25 +1,22 @@
-= render "repositories/head"
-- unless @hooks.empty?
- %div.update-data.ui-box.ui-box-small
- .data
- - @hooks.each do |hook|
- %a.update-item{:href => project_hook_path(@project, hook)}
- %span.update-title{:style => "margin-bottom:0px;"}
- = hook.url
- %span.update-author.right
- Added
- = time_ago_in_words(hook.created_at)
- ago
-- else
- %h3 No hooks
+= render "projects/project_head"
-.clear
-%hr
-%p
- Post receive hooks. For now only POST request allowed. We send some data with request. Example below
+- if can? current_user, :admin_project, @project
+ .alert-message.block-message
+ Post receive hooks for binding events when someone push to repository.
+ = link_to new_project_hook_path(@project), :class => "btn small", :title => "New Web Hook" do
+ Add Post Receive Hook
-.view_file
- .view_file_header
- %strong POST data passed
- .data.no-padding
- = render "data_ex"
+%table.zebra-striped.borders
+ - @hooks.each do |hook|
+ %tr
+ %td
+ = link_to project_hook_path(@project, hook) do
+ = hook.url
+ %td
+ = link_to 'Remove', project_hook_path(@project, hook), :confirm => 'Are you sure?', :method => :delete, :class => "danger btn small"
+
+
+.alert-message.block-message
+ We send some data with POST request when someone makes git push
+
+.well= render "data_ex"
diff --git a/app/views/hooks/new.html.haml b/app/views/hooks/new.html.haml
index 8078aefa503..f2a5ef534f4 100644
--- a/app/views/hooks/new.html.haml
+++ b/app/views/hooks/new.html.haml
@@ -4,10 +4,9 @@
%ul
- @hook.errors.full_messages.each do |msg|
%li= msg
- = f.label :url, "URL:"
- = f.text_field :url, :class => "text_field"
- .clear
- %br
- .merge-tabs
- = f.submit "Save", :class => "grey-button"
+ .clearfix
+ = f.label :url, "URL:"
+ .input= f.text_field :url, :class => "text_field"
+ .actions
+ = f.submit "Save", :class => "btn"
diff --git a/app/views/hooks/show.html.haml b/app/views/hooks/show.html.haml
index 47c1ddeac40..5ec4d5d8758 100644
--- a/app/views/hooks/show.html.haml
+++ b/app/views/hooks/show.html.haml
@@ -1,11 +1,7 @@
= render "repositories/head"
-%h3
- %span.commit.tag POST
- = @hook.url
-
+%pre= @hook.url
- if can? current_user, :admin_project, @project
- .merge-tabs
- = link_to 'Test Hook', test_project_hook_path(@project, @hook), :class => "grey-button"
- .right
- = link_to 'Remove', project_hook_path(@project, @hook), :confirm => 'Are you sure?', :method => :delete, :class => "red-button"
+ .actions
+ = link_to 'Test Hook', test_project_hook_path(@project, @hook), :class => "btn"
+ = link_to 'Remove', project_hook_path(@project, @hook), :confirm => 'Are you sure?', :method => :delete, :class => "danger btn"
diff --git a/app/views/issues/_form.html.haml b/app/views/issues/_form.html.haml
index d13827e76ac..3b379198aed 100644
--- a/app/views/issues/_form.html.haml
+++ b/app/views/issues/_form.html.haml
@@ -1,51 +1,41 @@
%div.issue-form-holder
= form_for [@project, @issue], :remote => request.xhr? do |f|
- %div
- %span.entity-info
- - if request.xhr?
- = link_to "#back", :onclick => "backToIssues();" do
- .entity-button
- Issues
- %i
- - else
- - if @issue.new_record?
- = link_to project_issues_path(@project) do
- .entity-button
- Issues
- %i
- - else
- = link_to project_issue_path(@project, @issue) do
- .entity-button
- Show Issue
- %i
-
- %h2= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.id}"
- %hr
+ %h3= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.id}"
+ %hr
-if @issue.errors.any?
- %ul.errors_holder
- - @issue.errors.full_messages.each do |msg|
- %li= msg
+ .alert-message.block-message.error
+ %ul
+ - @issue.errors.full_messages.each do |msg|
+ %li= msg
- %table.no-borders
- %tr
- %td= f.label :assignee_id
- %td= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select user" })
+ .clearfix
+ = f.label :assignee_id
+ .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select user" })
- %tr
- %td= f.label :critical, "Critical"
- %td= f.check_box :critical
-
- - unless @issue.new_record?
- %tr
- %td= f.label :closed
- %td= f.check_box :closed
+ .clearfix
+ = f.label :critical, "Critical"
+ .input= f.check_box :critical
- = f.text_area :title, :style => "width:718px; height:100px", :maxlength => 255
- %br
- %br
- .merge-tabs
- = f.submit 'Save', :class => "positive-button"
- &nbsp;
+ - unless @issue.new_record?
+ .clearfix
+ = f.label :closed
+ .input= f.check_box :closed
+
+ .clearfix
+ = f.label :title
+ .input= f.text_area :title, :maxlength => 255, :class => "xxlarge"
+ .actions
+ = f.submit 'Save', :class => "primary btn"
+
+ - if request.xhr?
+ = link_to "Cancel", "#back", :onclick => "backToIssues();", :class => "btn"
+ - else
+ - if @issue.new_record?
+ = link_to "Cancel", project_issues_path(@project), :class => "btn"
+ - else
+ = link_to "Cancel", project_issue_path(@project, @issue), :class => "btn"
+
+
- unless @issue.new_record?
.right
- = link_to 'Remove', [@project, @issue], :confirm => 'Are you sure?', :method => :delete, :class => "red-button"
+ = link_to 'Remove', [@project, @issue], :confirm => 'Are you sure?', :method => :delete, :class => "danger btn"
diff --git a/app/views/issues/_head.html.haml b/app/views/issues/_head.html.haml
index 7d44b87564f..d539025296a 100644
--- a/app/views/issues/_head.html.haml
+++ b/app/views/issues/_head.html.haml
@@ -1,14 +1,4 @@
-.top-tabs
- = link_to project_issues_path(@project), :class => "tab #{'active' if current_page?(project_issues_path(@project)) }" do
- %span
- Issues
-
- -#= link_to project_issues_path(@project), :class => "tab" do
- %span
- Milestones
-
- - if current_page?(project_issues_path(@project))
- - if can? current_user, :write_issue, @project
- = link_to new_project_issue_path(@project), :class => "add_new", :title => "New Issue", :remote => true do
- Add new
-
+.tabs
+ %li{:class => "#{'active' if current_page?(project_issues_path(@project))}"}
+ = link_to project_issues_path(@project), :class => "tab" do
+ Issues
diff --git a/app/views/issues/_show.html.haml b/app/views/issues/_show.html.haml
index 8c095268493..1d5cbd21d75 100644
--- a/app/views/issues/_show.html.haml
+++ b/app/views/issues/_show.html.haml
@@ -1,26 +1,27 @@
-%tr{ :id => dom_id(issue), :class => "issue #{issue.critical ? "critical" : ""}", :url => project_issue_path(issue.project, issue) }
- %td
- %strong.issue-number{:class => sort_class}= "##{issue.id}"
- %span
- = truncate(html_escape(issue.title), :length => 100)
- %br
- %br
- %div.note-author
- %strong= issue.assignee.name
- %cite.cgray
- = time_ago_in_words(issue.created_at)
- ago
- - if issue.critical
- %span.tag.high critical
- - if issue.today?
- %span.tag.today today
- .right.action-links
- - if can? current_user, :write_issue, issue
- - if issue.closed
- = link_to 'Reopen', project_issue_path(issue.project, issue, :issue => {:closed => false }, :status_only => true), :method => :put, :class => "cgray", :remote => true
- - else
- = link_to 'Resolve', project_issue_path(issue.project, issue, :issue => {:closed => true }, :status_only => true), :method => :put, :class => "cgray", :remote => true
- - if can? current_user, :write_issue, issue
- = link_to 'Edit', edit_project_issue_path(issue.project, issue), :class => "cgray edit-issue-link", :remote => true
- - if can?(current_user, :admin_issue, @project) || issue.author == current_user
- = link_to 'Remove', [issue.project, issue], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "cred delete-issue negative", :id => "destroy_issue_#{issue.id}"
+%li.wll{ :id => dom_id(issue), :class => "issue #{issue.critical ? "critical" : ""}", :url => project_issue_path(issue.project, issue) }
+ .right
+ - if can? current_user, :modify_issue, issue
+ - if issue.closed
+ = link_to 'Reopen', project_issue_path(issue.project, issue, :issue => {:closed => false }, :status_only => true), :method => :put, :class => "btn small", :remote => true
+ - else
+ = link_to 'Resolve', project_issue_path(issue.project, issue, :issue => {:closed => true }, :status_only => true), :method => :put, :class => "success btn small", :remote => true
+ = link_to 'Edit', edit_project_issue_path(issue.project, issue), :class => "btn small edit-issue-link", :remote => true
+ -#- if can?(current_user, :admin_issue, @project) || issue.author == current_user
+ = link_to 'Remove', [issue.project, issue], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "danger btn small delete-issue", :id => "destroy_issue_#{issue.id}"
+ = image_tag gravatar_icon(issue.assignee_email), :class => "avatar"
+ %span.update-author
+ assigned to
+ %strong= issue.assignee_name
+ - if issue.critical
+ %span.label.important critical
+ - if issue.today?
+ %span.label.success today
+
+
+
+ = link_to project_issue_path(issue.project, issue) do
+ %p.row_title= truncate(issue.title, :length => 60)
+
+
+
+
diff --git a/app/views/issues/index.html.haml b/app/views/issues/index.html.haml
index 37654c83e1c..297eab259be 100644
--- a/app/views/issues/index.html.haml
+++ b/app/views/issues/index.html.haml
@@ -1,57 +1,54 @@
-= render "issues/head"
-- if current_user.private_token
- = content_for :rss_icon do
- .rss-icon
+.issues_content
+ %h3
+ Issues
+ %span.rss-icon
= link_to project_issues_path(@project, :atom, { :private_token => current_user.private_token }) do
= image_tag "Rss-UI.PNG", :width => 22, :title => "feed"
-%div#issues-table-holder
- .top_panel_issues
- = form_tag search_project_issues_path(@project), :method => :get, :remote => true, :class => :right, :id => "issue_search_form" do
- = hidden_field_tag :project_id, @project.id, { :id => 'project_id' }
- = search_field_tag :issue_search, nil, { :placeholder => 'Search', :class => 'issue_search' }
+ - if can? current_user, :write_issue, @project
+ = link_to new_project_issue_path(@project), :class => "right btn small", :title => "New Issue", :remote => true do
+ New Issue
+ %br
+ %div#issues-table-holder.ui-box
+ .title
+ .row
+ .span8
+ %ul.pills.left
+ %li{:class => ("active" if (params[:f] == "0" || !params[:f]))}
+ = link_to project_issues_path(@project, :f => 0) do
+ Open
+ %li{:class => ("active" if params[:f] == "2")}
+ = link_to project_issues_path(@project, :f => 2) do
+ Closed
+ %li{:class => ("active" if params[:f] == "3")}
+ = link_to project_issues_path(@project, :f => 3) do
+ To Me
+ %li{:class => ("active" if params[:f] == "1")}
+ = link_to project_issues_path(@project, :f => 1) do
+ All
- .left.issues_filter
- = form_tag project_issues_path(@project), :method => :get do
- .left
- = radio_button_tag :f, 0, (params[:f] || "0") == "0", :onclick => "setIssueFilter(this.form, 0)", :id => "open_issues", :class => "status"
- = label_tag "open_issues" do
- %span.tag.open Open
- .left
- = radio_button_tag :f, 2, params[:f] == "2", :onclick => "setIssueFilter(this.form, 2)", :id => "closed_issues", :class => "status"
- = label_tag "closed_issues" do
- %span.tag.closed Closed
- .left
- = radio_button_tag :f, 3, params[:f] == "3", :onclick => "setIssueFilter(this.form, 3)", :id => "my_issues", :class => "status"
- = label_tag "my_issues","To Me"
- .left
- = radio_button_tag :f, 1, params[:f] == "1", :onclick => "setIssueFilter(this.form, 1)", :id => "all_issues", :class => "status"
- = label_tag "all_issues","All"
+ .span3.right
+ = form_tag search_project_issues_path(@project), :method => :get, :remote => true, :id => "issue_search_form", :class => :right do
+ = hidden_field_tag :project_id, @project.id, { :id => 'project_id' }
+ = hidden_field_tag :status, params[:f]
+ = search_field_tag :issue_search, nil, { :placeholder => 'Search', :class => 'issue_search' }
+
+ %ul#issues-table.unstyled= render "issues"
- .clear
- %hr
- %table.no-borders#issues-table
- = render "issues"
- %br
:javascript
var href = $('.issue_search').parent().attr('action');
var last_terms = '';
- var setIssueFilter = function(form, value){
- $.cookie('issue_filter', value, { expires: 140 });
- form.submit();
- }
-
$('.issue_search').keyup(function() {
var terms = $(this).val();
var project_id = $('#project_id').val();
- var status = $('.status:checked').val();
+ var status = $('#status').val();
if (terms != last_terms) {
last_terms = terms;
if (terms.length >= 2 || terms.length == 0) {
$.get(href, { 'status': status, 'terms': terms, project: project_id }, function(response) {
- $('#issues-table tbody').html(response);
+ $('#issues-table').html(response);
setSortable();
});
}
@@ -62,7 +59,7 @@
$(this).closest('tr').fadeOut(); updatePage();});
function setSortable(){
- $('#issues-table>tbody').sortable({
+ $('#issues-table').sortable({
axis: 'y',
dropOnEmpty: false,
handle: '.handle',
@@ -73,10 +70,10 @@
update: function(){
$.ajax({
type: 'post',
- data: $('#issues-table>tbody').sortable('serialize'),
+ data: $('#issues-table').sortable('serialize'),
dataType: 'script',
complete: function(request){
- $('#issues-table>tbody').effect('highlight');
+ $('#issues-table').effect('highlight');
},
url: "#{sort_project_issues_path(@project)}"})
}
diff --git a/app/views/issues/index.js.haml b/app/views/issues/index.js.haml
index a08ffe5adbb..a534cfbf234 100644
--- a/app/views/issues/index.js.haml
+++ b/app/views/issues/index.js.haml
@@ -1,3 +1,3 @@
:plain
- $('#issues-table tbody').html("#{escape_javascript(render('issues'))}");
+ $('#issues-table').html("#{escape_javascript(render('issues'))}");
setSortable();
diff --git a/app/views/issues/show.html.haml b/app/views/issues/show.html.haml
index 48fca97d230..13292d4e096 100644
--- a/app/views/issues/show.html.haml
+++ b/app/views/issues/show.html.haml
@@ -1,49 +1,44 @@
-%div
- %span.entity-info
+%h3
+ Issue ##{@issue.id}
+ %small
+ created at
+ = @issue.created_at.stamp("Aug 21, 2011")
+
+ %span.right
+ - if can?(current_user, :admin_project, @project) || @issue.author == current_user
+ - if @issue.closed
+ = link_to 'Reopen', project_issue_path(@project, @issue, :issue => {:closed => false }, :status_only => true), :method => :put, :class => "btn"
+ - else
+ = link_to 'Close', project_issue_path(@project, @issue, :issue => {:closed => true }, :status_only => true), :method => :put, :class => "btn", :title => "Close Issue"
- if can?(current_user, :admin_project, @project) || @issue.author == current_user
- = link_to edit_project_issue_path(@project, @issue) do
- .entity-button
- Edit Issue
- %i
- = image_tag gravatar_icon(@issue.author_email), :class => "left", :width => 40, :style => "padding-right:5px;"
- %span.commit-title
- %strong
- = "Issue ##{@issue.id}:"
- %span.commit-author
- %strong
- = link_to project_team_member_path(@project, @project.team_member_by_id(@issue.author.id)) do
- %span.author= @issue.author_name
- - if @issue.author != @issue.assignee
- &rarr;
- = link_to project_team_member_path(@project, @project.team_member_by_id(@issue.assignee.id)) do
- %span.author= @issue.assignee_name
- &nbsp;
-
- &nbsp;
- = @issue.created_at.stamp("Aug 21, 2011 9:23pm")
-
- %hr
- %br
- %h3
- = simple_format @issue.title
-
-.clear
-%br
-%br
-
-.merge-tabs
- = link_to "#notes", :class => "merge-notes-tab active tab" do
- %span
- Notes
- .right
- - if @issue.closed
- = link_to 'Reopen', project_issue_path(@project, @issue, :issue => {:closed => false }, :status_only => true), :method => :put, :class => "red-button"
- - else
- = link_to 'Close', project_issue_path(@project, @issue, :issue => {:closed => true }, :status_only => true), :method => :put, :class => "positive-button"
-
-.merge-request-notes
- .issue_notes= render "notes/notes"
- .loading{ :style => "display:none;"}
- %center= image_tag "ajax-loader.gif"
- .clear
+ = link_to edit_project_issue_path(@project, @issue), :class => "btn small" do
+ Edit
+
+.back_link
+ = link_to project_issues_path(@project) do
+ &larr; To issues list
+
+
+%hr
+- if @issue.closed
+ .alert-message.error Closed
+- else
+ .alert-message.success Open
+
+
+%div.well
+ %div
+ %cite.cgray Created by
+ = image_tag gravatar_icon(@issue.author_email), :width => 16, :class => "lil_av"
+ %strong.author= link_to_issue_author(@issue)
+
+ %cite.cgray and currently assigned to
+ = image_tag gravatar_icon(@issue.assignee_email), :width => 16, :class => "lil_av"
+ %strong.author= link_to_issue_assignee(@issue)
+
+ %hr
+
+ %div= simple_format @issue.title
+
+.issue_notes= render "notes/notes", :tid => @issue.id, :tt => "issue"
diff --git a/app/views/issues/show.js.haml b/app/views/issues/show.js.haml
deleted file mode 100644
index ee31c0b8d3c..00000000000
--- a/app/views/issues/show.js.haml
+++ /dev/null
@@ -1 +0,0 @@
-= render "notes/load"
diff --git a/app/views/kaminari/_first_page.html.haml b/app/views/kaminari/_first_page.html.haml
new file mode 100644
index 00000000000..fee8112f6af
--- /dev/null
+++ b/app/views/kaminari/_first_page.html.haml
@@ -0,0 +1,9 @@
+-# Link to the "First" page
+-# available local variables
+-# url: url to the first page
+-# current_page: a page object for the currently displayed page
+-# num_pages: total number of pages
+-# per_page: number of items to fetch per page
+-# remote: data-remote
+%span.first
+ = link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, :remote => remote
diff --git a/app/views/kaminari/_gap.html.haml b/app/views/kaminari/_gap.html.haml
new file mode 100644
index 00000000000..f82f185ac35
--- /dev/null
+++ b/app/views/kaminari/_gap.html.haml
@@ -0,0 +1,8 @@
+-# Non-link tag that stands for skipped pages...
+-# available local variables
+-# current_page: a page object for the currently displayed page
+-# num_pages: total number of pages
+-# per_page: number of items to fetch per page
+-# remote: data-remote
+%span.page.gap
+ = raw(t 'views.pagination.truncate')
diff --git a/app/views/kaminari/_last_page.html.haml b/app/views/kaminari/_last_page.html.haml
new file mode 100644
index 00000000000..6e41d232b51
--- /dev/null
+++ b/app/views/kaminari/_last_page.html.haml
@@ -0,0 +1,9 @@
+-# Link to the "Last" page
+-# available local variables
+-# url: url to the last page
+-# current_page: a page object for the currently displayed page
+-# num_pages: total number of pages
+-# per_page: number of items to fetch per page
+-# remote: data-remote
+%span.last
+ = link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, {:remote => remote}
diff --git a/app/views/kaminari/_next_page.html.haml b/app/views/kaminari/_next_page.html.haml
new file mode 100644
index 00000000000..76f40e72373
--- /dev/null
+++ b/app/views/kaminari/_next_page.html.haml
@@ -0,0 +1,9 @@
+-# Link to the "Next" page
+-# available local variables
+-# url: url to the next page
+-# current_page: a page object for the currently displayed page
+-# num_pages: total number of pages
+-# per_page: number of items to fetch per page
+-# remote: data-remote
+%li.next
+ = link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, :rel => 'next', :remote => remote
diff --git a/app/views/kaminari/_page.html.haml b/app/views/kaminari/_page.html.haml
new file mode 100644
index 00000000000..5966812934f
--- /dev/null
+++ b/app/views/kaminari/_page.html.haml
@@ -0,0 +1,10 @@
+-# Link showing page number
+-# available local variables
+-# page: a page object for "this" page
+-# url: url to this page
+-# current_page: a page object for the currently displayed page
+-# num_pages: total number of pages
+-# per_page: number of items to fetch per page
+-# remote: data-remote
+%li{:class => "page#{' active' if page.current?}"}
+ = link_to page, url, {:remote => remote, :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil}
diff --git a/app/views/kaminari/_paginator.html.haml b/app/views/kaminari/_paginator.html.haml
new file mode 100644
index 00000000000..6f9fb332261
--- /dev/null
+++ b/app/views/kaminari/_paginator.html.haml
@@ -0,0 +1,17 @@
+-# The container tag
+-# available local variables
+-# current_page: a page object for the currently displayed page
+-# num_pages: total number of pages
+-# per_page: number of items to fetch per page
+-# remote: data-remote
+-# paginator: the paginator that renders the pagination tags inside
+= paginator.render do
+ %div.pagination
+ %ul
+ = prev_page_tag unless current_page.first?
+ - each_page do |page|
+ - if page.left_outer? || page.right_outer? || page.inside_window?
+ = page_tag page
+ - elsif !page.was_truncated?
+ = gap_tag
+ = next_page_tag unless current_page.last?
diff --git a/app/views/kaminari/_prev_page.html.haml b/app/views/kaminari/_prev_page.html.haml
new file mode 100644
index 00000000000..cef885ee0af
--- /dev/null
+++ b/app/views/kaminari/_prev_page.html.haml
@@ -0,0 +1,9 @@
+-# Link to the "Previous" page
+-# available local variables
+-# url: url to the previous page
+-# current_page: a page object for the currently displayed page
+-# num_pages: total number of pages
+-# per_page: number of items to fetch per page
+-# remote: data-remote
+%li{:class => "prev" }
+ = link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, :rel => 'prev', :remote => remote
diff --git a/app/views/keys/_form.html.haml b/app/views/keys/_form.html.haml
index 1cc7e336b5f..cdabdc739d6 100644
--- a/app/views/keys/_form.html.haml
+++ b/app/views/keys/_form.html.haml
@@ -1,16 +1,18 @@
%div
- = form_for @key, :remote => true do |f|
+ = form_for @key do |f|
-if @key.errors.any?
- %ul
- - @key.errors.full_messages.each do |msg|
- %li= msg
+ .alert-message.block-message.error
+ %ul
+ - @key.errors.full_messages.each do |msg|
+ %li= msg
- .form-row
+ .clearfix
= f.label :title
- = f.text_field :title, :style => "width:300px"
- .form-row
+ .input= f.text_field :title
+ .clearfix
= f.label :key
- = f.text_area :key, :style => "width:300px; height:130px"
- .form-row
- = f.submit 'Save', :class => "grey-button"
+ .input= f.text_area :key, :class => "xlarge"
+ .actions
+ = f.submit 'Save', :class => "primary btn"
+ = link_to "Cancel", keys_path, :class => "btn"
diff --git a/app/views/keys/_show.html.haml b/app/views/keys/_show.html.haml
index 3d506e425c9..1df9b91dffa 100644
--- a/app/views/keys/_show.html.haml
+++ b/app/views/keys/_show.html.haml
@@ -1,7 +1,13 @@
-%a.update-item{:href => key_path(key)}
- %span.update-title
- = key.title
- %span.update-author
- Added
- = time_ago_in_words(key.created_at)
- ago
+%tr
+ %td
+ = link_to key_path(key) do
+ %p
+ %strong= key.title
+ %td
+ %span.right.cgray
+ Added
+ = time_ago_in_words(key.created_at)
+ ago
+ %td
+ = link_to 'Remove', key, :confirm => 'Are you sure?', :method => :delete, :class => "btn small danger delete-key right"
+
diff --git a/app/views/keys/index.html.haml b/app/views/keys/index.html.haml
index 933eef63529..59ce7846b28 100644
--- a/app/views/keys/index.html.haml
+++ b/app/views/keys/index.html.haml
@@ -1,16 +1,9 @@
-%h2.icon
- %span>
+%h3
SSH Keys
-%div#new-key-holder.right
- = link_to "Add new", new_key_path, :remote => true, :class => "grey-button"
-%br
-
-%div#keys-table{ :class => "update-data ui-box ui-box-small ui-box-big" }
- .data
- - @keys.each do |key|
- = render(:partial => 'show', :locals => {:key => key})
-
-:javascript
- $('.delete-key').live('ajax:success', function() {
- $(this).closest('.update-item').fadeOut(); });
+ = link_to "Add new", new_key_path, :class => "btn small right"
+
+%hr
+%table#keys-table.zebra-striped.borders
+ - @keys.each do |key|
+ = render(:partial => 'show', :locals => {:key => key})
diff --git a/app/views/keys/new.html.haml b/app/views/keys/new.html.haml
index fed448b4e09..743a3173706 100644
--- a/app/views/keys/new.html.haml
+++ b/app/views/keys/new.html.haml
@@ -1,5 +1,3 @@
-%h1 New key
-
+%h3 New key
+%hr
= render 'form'
-
-= link_to 'Back', keys_path
diff --git a/app/views/keys/show.html.haml b/app/views/keys/show.html.haml
index 9dcaa093ce5..fe7f80d591f 100644
--- a/app/views/keys/show.html.haml
+++ b/app/views/keys/show.html.haml
@@ -1,10 +1,7 @@
-.ui-box.width-100p
- %h3= @key.title
- .data
- %pre= @key.key
- .clear
- .buttons
- = link_to 'Remove', @key, :confirm => 'Are you sure?', :method => :delete, :class => "red-button delete-key right"
- .clear
+%h3= @key.title
+%hr
+%pre= @key.key
+.actions
+ = link_to 'Remove', @key, :confirm => 'Are you sure?', :method => :delete, :class => "btn danger delete-key"
diff --git a/app/views/layouts/_app_menu.html.haml b/app/views/layouts/_app_menu.html.haml
new file mode 100644
index 00000000000..27d9b458bc9
--- /dev/null
+++ b/app/views/layouts/_app_menu.html.haml
@@ -0,0 +1,6 @@
+%nav.main_menu
+ = render "layouts/const_menu_links"
+ = link_to "Projects", projects_path, :class => "#{"current" if current_page?(projects_path)}"
+ = link_to "Issues", dashboard_issues_path, :class => "#{"current" if current_page?(dashboard_issues_path)}", :id => "issues_slide"
+ = link_to "Requests", dashboard_merge_requests_path, :class => "#{"current" if current_page?(dashboard_merge_requests_path)}", :id => "merge_requests_slide"
+ = link_to "Help", help_path, :class => "#{"current" if controller.controller_name == "help"}"
diff --git a/app/views/layouts/_const_menu_links.html.haml b/app/views/layouts/_const_menu_links.html.haml
new file mode 100644
index 00000000000..ffd028ec706
--- /dev/null
+++ b/app/views/layouts/_const_menu_links.html.haml
@@ -0,0 +1 @@
+= link_to "Home", root_path, :class => "home #{"current" if current_page?(dashboard_path) || current_page?(root_path)}", :title => "Home"
diff --git a/app/views/layouts/_flash.html.haml b/app/views/layouts/_flash.html.haml
index 4011485c55d..2e40f0a6281 100644
--- a/app/views/layouts/_flash.html.haml
+++ b/app/views/layouts/_flash.html.haml
@@ -1,16 +1,15 @@
- if alert || notice
- text = alert || notice
%div{:style => "display:none", :id => "flash_container"}
- .container
- %center
- %h4= text
+ %center
+ %h4= text
:javascript
$(function(){
$("#flash_container").slideDown("slow");
$("#flash_container").click(function(){
$(this).slideUp("slow");
});
- setTimeout("hideFlash()",2000);
+ setTimeout("hideFlash()",3000);
});
function hideFlash(){
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
new file mode 100644
index 00000000000..cbe509955a9
--- /dev/null
+++ b/app/views/layouts/_head.html.haml
@@ -0,0 +1,17 @@
+%head
+ %meta{:charset => "utf-8"}
+ %title
+ GitLab
+ = " - #{@project.name}" if @project && !@project.new_record?
+ = favicon_link_tag 'favicon.ico'
+ = stylesheet_link_tag "application"
+ = javascript_include_tag "application"
+
+ -# Atom feed
+ - if @project && !@project.new_record?
+ - if current_page?(tree_project_ref_path(@project, @project.root_ref)) || current_page?(project_commits_path(@project))
+ = auto_discovery_link_tag(:atom, project_commits_url(@project, :atom, :ref => @ref, :private_token => current_user.private_token), :title => "Recent commits to #{@project.name}:#{@ref}")
+ - if request.path == project_issues_path(@project)
+ = auto_discovery_link_tag(:atom, project_issues_url(@project, :atom, :private_token => current_user.private_token), :title => "#{@project.name} issues")
+ = csrf_meta_tags
+
diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml
index 5f7752283a1..86ad2bd0cf9 100644
--- a/app/views/layouts/_head_panel.html.haml
+++ b/app/views/layouts/_head_panel.html.haml
@@ -2,32 +2,19 @@
%header.top_panel_holder
.wrapper
.top_panel_content
- %div.main_links
+ %div.app_logo
= link_to root_path, :class => "home", :title => "Home" do
- = image_tag "logo.png", :width => 100
+ = image_tag "logo_tr.png", :width => 50
+ %h1
+ GITLAB
- - if project_layout
- .project_name
- = truncate @project.name, :length => 28
- .git_url_wrapper
- %input.git-url.text{:id => "", :name => "", :readonly => "", :type => "text", :value => @project.url_to_repo, :class => "one_click_select"}
- - if @project.repo_exists?
- .left{:style => "margin-left:5px;"}
- = render :partial => "projects/refs", :locals => { :destination => controller.controller_name == "commits" ? "commits" : "tree" }
- = yield :rss_icon
+ - if current_user.is_admin?
+ = link_to admin_projects_path, :class => "admin_link", :title => "Admin area" do
+ = image_tag "admin.PNG", :width => 16
+
+ %h1.project_name= title
+ .search= text_field_tag "search", nil, :placeholder => "Search", :class => "search-input"
- - else
- .dashboard_links
- = link_to "Activities", dashboard_path, :class => "#{"active" if current_page?(dashboard_path) || current_page?(root_path) }"
- = link_to "Projects", projects_path, :class => "#{"active" if current_page?(projects_path)}"
- = link_to "Issues", dashboard_issues_path, :class => "#{"active" if current_page?(dashboard_issues_path)}", :id => "issues_slide"
- = link_to "Requests", dashboard_merge_requests_path, :class => "#{"active" if current_page?(dashboard_merge_requests_path)}", :id => "merge_requests_slide"
- - if current_user.is_admin?
- = link_to admin_root_path, :class => "admin", :title => "Admin" do
- Admin
- = link_to "Help", help_path, :class => "#{"active" if controller.controller_name == "help"}"
- .search
- = text_field_tag "search", nil, :placeholder => "Search", :class => "search-input"
.account-box
= link_to profile_path, :class => "pic" do
@@ -36,16 +23,20 @@
= link_to profile_path, :class => "username" do
My profile
= link_to 'Logout', destroy_user_session_path, :class => "logout", :method => :delete
- - if current_user
- = javascript_tag do
- $(function(){
- $("#search").autocomplete({
- source: #{raw search_autocomplete_source},
- select: function(event, ui) { location.href = ui.item.url }
- });
- });
- -#- if current_user.require_ssh_key?
- #no_ssh_key_defined.big-message.error
- %p
- No SSH Key is defined. You won't be able to use any Git command!. Click #{link_to( 'here', keys_path )} to add one!
+:javascript
+ $(function(){
+ $("#search").autocomplete({
+ source: #{raw search_autocomplete_source},
+ select: function(event, ui) { location.href = ui.item.url }
+ });
+
+ $(document).keypress(function(e) {
+ if( $(e.target).is(":input") ) return;
+ switch(e.which) {
+ case 115: focusSearch();
+ e.preventDefault();
+ }
+ });
+ });
+
diff --git a/app/views/layouts/_project_menu.html.haml b/app/views/layouts/_project_menu.html.haml
new file mode 100644
index 00000000000..1f1b2e601a2
--- /dev/null
+++ b/app/views/layouts/_project_menu.html.haml
@@ -0,0 +1,27 @@
+%nav.main_menu
+ = render "layouts/const_menu_links"
+ = link_to project_path(@project), :class => "#{project_tab_class}", :title => "Project" do
+ Project
+
+ - if @project.repo_exists?
+ - if can? current_user, :download_code, @project
+ = link_to "Files", tree_project_ref_path(@project, @project.root_ref), :class => tree_tab_class
+ = link_to "Commits", project_commits_path(@project), :class => commit_tab_class
+
+ = link_to "Network", graph_project_path(@project), :class => current_page?(:controller => "projects", :action => "graph", :id => @project) ? "current" : nil
+ - if @project.issues_enabled
+ = link_to project_issues_filter_path(@project), :class => (controller.controller_name == "issues") ? "current" : nil do
+ Issues
+ %span.count= @project.issues.opened.count
+ - if @project.merge_requests_enabled
+ = link_to project_merge_requests_path(@project), :class => (controller.controller_name == "merge_requests") ? "current" : nil do
+ Merge Requests
+ %span.count= @project.merge_requests.opened.count
+
+ - if @project.wall_enabled
+ = link_to wall_project_path(@project), :class => current_page?(:controller => "projects", :action => "wall", :id => @project) ? "current" : nil do
+ Wall
+
+ - if @project.wiki_enabled
+ = link_to project_wiki_path(@project, :index), :class => (controller.controller_name == "wikis") ? "current" : nil do
+ Wiki
diff --git a/app/views/layouts/_project_side.html.haml b/app/views/layouts/_project_side.html.haml
deleted file mode 100644
index 00038cc373e..00000000000
--- a/app/views/layouts/_project_side.html.haml
+++ /dev/null
@@ -1,19 +0,0 @@
-.project-sidebar
- .fixed
- %aside
- = link_to project_path(@project), :class => project_tab_class do
- Project
-
- - if @project.repo_exists?
- = link_to "Repository", project_repository_path(@project), :class => repository_tab_class
- = link_to "Tree", tree_project_ref_path(@project, @ref || @project.root_ref), :class => tree_tab_class
- = link_to "Commits", project_commits_path(@project, :ref => (@ref || @project.root_ref)), :class => (controller.controller_name == "commits") ? "current" : nil
- = link_to "Network", graph_project_path(@project), :class => current_page?(:controller => "projects", :action => "graph", :id => @project) ? "current" : nil
- = link_to project_issues_filter_path(@project), :class => (controller.controller_name == "issues") ? "current" : nil do
- Issues
- = link_to wall_project_path(@project), :class => current_page?(:controller => "projects", :action => "wall", :id => @project) ? "current" : nil do
- Wall
- - if @project.common_notes.today.count > 0
- %span{ :class => "number" }= @project.common_notes.today.count
- = link_to project_merge_requests_path(@project), :class => (controller.controller_name == "merge_requests") ? "current" : nil do
- Requests
diff --git a/app/views/layouts/_project_side_right.html.haml b/app/views/layouts/_project_side_right.html.haml
new file mode 100644
index 00000000000..cc4e6b14260
--- /dev/null
+++ b/app/views/layouts/_project_side_right.html.haml
@@ -0,0 +1,8 @@
+%aside.project-right
+ - if content_for? :sidebar_all
+ = render :sidebar_all
+ - else
+ - if content_for? :sidebar_top_block
+ = yield :sidebar_top_block
+ = render "widgets/project_member"
+ = render "widgets/recent_projects"
diff --git a/app/views/layouts/_projects_side.html.haml b/app/views/layouts/_projects_side.html.haml
new file mode 100644
index 00000000000..4f0a2e49ae6
--- /dev/null
+++ b/app/views/layouts/_projects_side.html.haml
@@ -0,0 +1,21 @@
+%aside.projects
+ - if current_user.can_create_project?
+ .widget
+ You can create up to
+ = current_user.projects_limit
+ projects. Click on link below to add a new one
+ .link_holder
+ = link_to new_project_path, :class => "" do
+ New Project »
+
+ - if current_user.is_admin?
+ .widget
+ You have administrator privilegies. You can configure application following this button:
+ .link_holder
+ = link_to admin_root_path, :class => "", :title => "Admin" do
+ Visit Admin Area »
+
+ - if current_user.projects.count > 0
+ = render "widgets/recent_projects"
+
+
diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml
index 2b3188056f9..df47166016f 100644
--- a/app/views/layouts/admin.html.haml
+++ b/app/views/layouts/admin.html.haml
@@ -1,28 +1,15 @@
-!!!
-%html
- %head
- %title
- GitLab #{" - #{@project.name}" if @project && !@project.new_record?}
- = favicon_link_tag 'favicon.ico'
- = stylesheet_link_tag "application"
- = javascript_include_tag "application"
- = csrf_meta_tags
- = javascript_tag do
- REQ_URI = "#{request.env["REQUEST_URI"]}";
- REQ_REFFER = "#{request.env["HTTP_REFERER"]}";
- %body{ :class => body_class('project-page'), :id => yield(:boyd_id)}
- = render :partial => "layouts/flash"
- #container
- = render :partial => "layouts/head_panel"
- .project-container
- .project-sidebar
- .fixed
- %aside
- = link_to "Users", admin_users_path, :class => controller.controller_name == "users" ? "current" : nil
- = link_to "Projects", admin_projects_path, :class => controller.controller_name == "projects" ? "current" : nil
- = link_to "Teams", admin_team_members_path, :class => controller.controller_name == "team_members" ? "current" : nil
- = link_to "Emails", admin_emails_path, :class => controller.controller_name == "mailer" ? "current" : nil
- = link_to "Resque", "/info/resque"
+!!! 5
+%html{ :lang => "en"}
+ = render "layouts/head"
+ %body.ui_basic.admin
+ = render "layouts/flash"
+ = render "layouts/head_panel", :title => "Admin area"
+ .container
+ %nav.main_menu
+ = render "layouts/const_menu_links"
+ = link_to "Users", admin_users_path, :class => controller.controller_name == "users" ? "current" : nil
+ = link_to "Projects", admin_projects_path, :class => controller.controller_name == "projects" ? "current" : nil
+ = link_to "Emails", admin_emails_path, :class => controller.controller_name == "mailer" ? "current" : nil
+ = link_to "Resque", "/info/resque"
- .project-content
- = yield
+ .content= yield
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index e86e5c74fa4..8a1739f12a5 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -1,18 +1,10 @@
-!!!
-%html
- %head
- %title
- GitLab
- = favicon_link_tag 'favicon.ico'
- = stylesheet_link_tag "application"
- = javascript_include_tag "application"
- = csrf_meta_tags
- = javascript_tag do
- REQ_URI = "#{request.env["REQUEST_URI"]}";
- REQ_REFFER = "#{request.env["HTTP_REFERER"]}";
- %body{ :class => body_class, :id => yield(:boyd_id)}
- = render :partial => "layouts/flash"
- #container
- = render :partial => "layouts/head_panel"
- = render :partial => "layouts/page_title"
- = yield
+!!! 5
+%html{ :lang => "en"}
+ = render "layouts/head"
+ %body.ui_basic.application
+ = render "layouts/flash"
+ = render "layouts/head_panel", :title => "Dashboard"
+ .container
+ = render :partial => "layouts/app_menu"
+ .content
+ = yield
diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml
index 882195ae58d..c293734b368 100644
--- a/app/views/layouts/devise.html.haml
+++ b/app/views/layouts/devise.html.haml
@@ -1,15 +1,6 @@
-!!!
-%html
- %head
- %title
- GitLab #{" - #{@project.name}" if @project && !@project.new_record?}
- = favicon_link_tag 'favicon.ico'
- = stylesheet_link_tag "application"
- = javascript_include_tag "application"
- = csrf_meta_tags
- = javascript_tag do
- REQ_URI = "#{request.env["REQUEST_URI"]}";
- REQ_REFFER = "#{request.env["HTTP_REFERER"]}";
- %body.login-page
+!!! 5
+%html{ :lang => "en"}
+ = render "layouts/head"
+ %body.ui_basic.login-page
= render :partial => "layouts/flash"
- = yield
+ .container= yield
diff --git a/app/views/layouts/error.html.haml b/app/views/layouts/error.html.haml
new file mode 100644
index 00000000000..544fdcc7596
--- /dev/null
+++ b/app/views/layouts/error.html.haml
@@ -0,0 +1,11 @@
+!!! 5
+%html{ :lang => "en"}
+ = render "layouts/head"
+ %body.ui_basic.application
+ = render "layouts/flash"
+ = render "layouts/head_panel", :title => ""
+ .container
+ %nav.main_menu
+ = render "layouts/const_menu_links"
+ .content
+ %h3= yield
diff --git a/app/views/layouts/profile.html.haml b/app/views/layouts/profile.html.haml
index 6eeecb294be..091e85631f6 100644
--- a/app/views/layouts/profile.html.haml
+++ b/app/views/layouts/profile.html.haml
@@ -1,30 +1,18 @@
-!!!
-%html
- %head
- %title
- GitLab #{" - #{@project.name}" if @project && !@project.new_record?}
- = favicon_link_tag 'favicon.ico'
- = stylesheet_link_tag "application"
- = javascript_include_tag "application"
- = csrf_meta_tags
- = javascript_tag do
- REQ_URI = "#{request.env["REQUEST_URI"]}";
- REQ_REFFER = "#{request.env["HTTP_REFERER"]}";
- %body{ :class => body_class('project-page'), :id => yield(:boyd_id)}
- = render :partial => "layouts/flash"
- #container
- = render :partial => "layouts/head_panel"
- .project-container
- .project-sidebar
- .fixed
- %aside
- = link_to "Profile", profile_path, :class => current_page?(:controller => "profile", :action => :show) ? "current" : nil
- = link_to "Password & token", profile_password_path, :class => current_page?(:controller => "profile", :action => :password) ? "current" : nil
- = link_to "Design", profile_design_path, :class => current_page?(:controller => "profile", :action => :design) ? "current" : nil
- = link_to keys_path, :class => controller.controller_name == "keys" ? "current" : nil do
- Keys
- - unless current_user.keys.empty?
- %span{ :class => "number" }= current_user.keys.count
-
- .project-content
- = yield
+!!! 5
+%html{ :lang => "en"}
+ = render "layouts/head"
+ %body.ui_basic.profile
+ = render "layouts/flash"
+ = render "layouts/head_panel", :title => "Profile"
+ .container
+ %nav.main_menu
+ = render "layouts/const_menu_links"
+ = link_to "Profile", profile_path, :class => current_page?(:controller => "profile", :action => :show) ? "current" : nil
+ = link_to "Password & token", profile_password_path, :class => current_page?(:controller => "profile", :action => :password) ? "current" : nil
+ = link_to "Design", profile_design_path, :class => current_page?(:controller => "profile", :action => :design) ? "current" : nil
+ = link_to keys_path, :class => controller.controller_name == "keys" ? "current" : nil do
+ SSH Keys
+ .content
+ .row
+ .span12= yield
+ .sidebar= render "layouts/projects_side"
diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml
index a87b3400812..2bc326df8c4 100644
--- a/app/views/layouts/project.html.haml
+++ b/app/views/layouts/project.html.haml
@@ -1,24 +1,16 @@
-!!!
-%html
- %head
- %title
- GitLab #{" - #{@project.name}" if @project && !@project.new_record?}
- = favicon_link_tag 'favicon.ico'
- = stylesheet_link_tag "application"
- = javascript_include_tag "application"
- - if current_page?(tree_project_ref_path(@project, @project.root_ref)) || current_page?(project_commits_path(@project))
- = auto_discovery_link_tag(:atom, project_commits_url(@project, :atom, :ref => @ref, :private_token => current_user.private_token), :title => "Recent commits to #{@project.name}:#{@ref}")
- - if request.path == project_issues_path(@project)
- = auto_discovery_link_tag(:atom, project_issues_url(@project, :atom, :private_token => current_user.private_token), :title => "#{@project.name} issues")
- = csrf_meta_tags
- = javascript_tag do
- REQ_URI = "#{request.env["REQUEST_URI"]}";
- REQ_REFFER = "#{request.env["HTTP_REFERER"]}";
- %body{ :class => body_class('project-page'), :id => yield(:boyd_id)}
- = render :partial => "layouts/flash"
- #container
- = render :partial => "layouts/head_panel"
- .project-container
- = render :partial => "layouts/project_side"
- .project-content
+!!! 5
+%html{ :lang => "en"}
+ = render "layouts/head"
+ %body.ui_basic.project
+ = render "layouts/flash"
+ = render "layouts/head_panel", :title => @project.name
+ .container
+ = render :partial => "layouts/project_menu"
+ .content
+ - if @full_content
= yield
+ - else
+ .row
+ .span12= yield
+ .sidebar= render "layouts/project_side_right"
+
diff --git a/app/views/merge_requests/_commits.html.haml b/app/views/merge_requests/_commits.html.haml
index c0d7486b704..7606e71e7c0 100644
--- a/app/views/merge_requests/_commits.html.haml
+++ b/app/views/merge_requests/_commits.html.haml
@@ -1,19 +1,13 @@
-- if @commits.size > 0
- .merge-request-commits.ui-box.width-100p
- - @commits.each do |commit|
- %a{ :class => "commit", :href => project_commit_path(@project, :id => commit.id) }
- - if commit.author_email
- = image_tag gravatar_icon(commit.author_email), :class => "left", :width => 40, :style => "padding-right:5px;"
- - else
- = image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;"
- %span.update-title
- = truncate commit.safe_message, :length => 60
- %span.update-author
- %strong= commit.author_name
- authored
- = time_ago_in_words(commit.created_at)
- ago
- .clear
+- unless @commits.empty?
+ .ui-box
+ %h5 Commits
+ .merge-request-commits
+ %ul.unstyled= render @commits
-- if @commits.empty?
- %p.cgray Nothing to merge
+- else
+ %h5
+ Nothing to merge from
+ %span.label #{@merge_request.source_branch}
+ to
+ %span.label #{@merge_request.target_branch}
+ %br
diff --git a/app/views/merge_requests/_diffs.html.haml b/app/views/merge_requests/_diffs.html.haml
index ef6b0f1f4f8..bd904a77094 100644
--- a/app/views/merge_requests/_diffs.html.haml
+++ b/app/views/merge_requests/_diffs.html.haml
@@ -1,24 +1,3 @@
-- @diffs.each_with_index do |diff, i|
- - next if diff.diff.empty?
- - file = (@commit.tree / diff.b_path)
- - next unless file
- .diff_file
- .diff_file_header
- - if diff.deleted_file
- %strong{:id => "#{diff.b_path}"}= diff.a_path
- - else
- = link_to tree_file_project_ref_path(@project, @commit.id, diff.b_path) do
- %strong{:id => "#{diff.b_path}"}= diff.b_path
- %br/
- .diff_file_content
- - if file.text?
- = render :partial => "commits/text_file", :locals => { :diff => diff, :index => i }
- - elsif file.image?
- .diff_file_content_image
- %img{:src => "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
- - else
- %p
- %center No preview for this file type
-
+= render "commits/diffs", :diffs => @diffs
- if @diffs.empty?
%p.cgray Nothing to merge
diff --git a/app/views/merge_requests/_form.html.haml b/app/views/merge_requests/_form.html.haml
index d771661b03b..cab517dc3d5 100644
--- a/app/views/merge_requests/_form.html.haml
+++ b/app/views/merge_requests/_form.html.haml
@@ -1,46 +1,35 @@
= form_for [@project, @merge_request] do |f|
- %div
- %span.entity-info
- - if @merge_request.new_record?
- = link_to project_merge_requests_path(@project) do
- .entity-button
- Merge Requests
- %i
- - else
- = link_to project_merge_request_path(@project, @merge_request) do
- .entity-button
- Show Merge Request
- %i
+ -if @merge_request.errors.any?
+ .alert-message.block-message.error
+ %ul
+ - @merge_request.errors.full_messages.each do |msg|
+ %li= msg
- %h2= @merge_request.new_record? ? "New Merge Request" : "Edit Merge Request ##{@merge_request.id}"
+ .clearfix
+ = f.label :source_branch, "From"
+ .input= f.select(:source_branch, @project.heads.map(&:name), { :include_blank => "Select branch" }, :style => "width:250px")
+ .clearfix
+ = f.label :target_branch, "To"
+ .input= f.select(:target_branch, @project.heads.map(&:name), { :include_blank => "Select branch" }, :style => "width:250px")
+ .clearfix
+ = f.label :assignee_id, "Assign to"
+ .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select user" }, :style => "width:250px")
- %hr
- %table.no-borders
- -if @merge_request.errors.any?
- %tr
- %td{:colspan => 2}
- #error_explanation
- - @merge_request.errors.full_messages.each do |msg|
- %span= msg
- %br
- %tr
- %td= f.label :source_branch, "From"
- %td= f.select(:source_branch, @project.heads.map(&:name), { :include_blank => "Select branch" }, :style => "width:250px")
- %tr
- %td= f.label :target_branch, "To"
- %td= f.select(:target_branch, @project.heads.map(&:name), { :include_blank => "Select branch" }, :style => "width:250px")
- %tr
- %td= f.label :assignee_id, "Assign to"
- %td= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select user" }, :style => "width:250px")
- = f.text_area :title, :style => "width:718px; height:100px", :maxlength => 255
- %br
- %br
- .merge-tabs
- = f.submit 'Save', :class => "positive-button"
+ .clearfix
+ = f.label :title
+ .input= f.text_area :title, :class => "xlarge", :maxlength => 255, :rows => 5
+ .actions
+ = f.submit 'Save', :class => "primary btn"
+ - if @merge_request.new_record?
+ = link_to project_merge_requests_path(@project), :class => "btn" do
+ Cancel
+ - else
+ = link_to project_merge_request_path(@project, @merge_request), :class => "btn" do
+ Cancel
&nbsp;
- unless @merge_request.new_record?
.right
- = link_to 'Remove', [@project, @merge_request], :confirm => 'Are you sure?', :method => :delete, :class => "red-button"
+ = link_to 'Remove', [@project, @merge_request], :confirm => 'Are you sure?', :method => :delete, :class => "btn danger"
diff --git a/app/views/merge_requests/_head.html.haml b/app/views/merge_requests/_head.html.haml
index ccebd8ef047..3d847b302ae 100644
--- a/app/views/merge_requests/_head.html.haml
+++ b/app/views/merge_requests/_head.html.haml
@@ -2,11 +2,4 @@
= link_to project_merge_requests_path(@project), :class => "tab #{'active' if current_page?(project_merge_requests_path(@project)) }" do
%span
Merge Requests
-
-
- - if current_page?(project_merge_requests_path(@project))
- - if can? current_user, :write_merge_request, @project
- = link_to new_project_merge_request_path(@project), :class => "add_new", :title => "New Merge request" do
- Add new
-
diff --git a/app/views/merge_requests/_how_to_merge.html.haml b/app/views/merge_requests/_how_to_merge.html.haml
new file mode 100644
index 00000000000..19caca3fc08
--- /dev/null
+++ b/app/views/merge_requests/_how_to_merge.html.haml
@@ -0,0 +1,25 @@
+%div#modal_merge_info.modal.hide
+ .modal-header
+ %a.close{:href => "#"} ×
+ %h3 How To Merge
+ .modal-body
+ %pre
+ :erb
+ git fetch origin
+ git checkout -b <%=@merge_request.source_branch%> origin/<%=@merge_request.source_branch%>
+ git checkout <%=@merge_request.target_branch%>
+ git merge <%=@merge_request.source_branch%>
+ git push origin <%=@merge_request.target_branch%>
+
+
+:javascript
+ $(function(){
+ var modal = $('#modal_merge_info').modal({modal: true});
+ $('.info_link').bind("click", function(){
+ modal.show();
+ });
+ $('.modal-header .close').bind("click", function(){
+ modal.hide();
+ })
+ })
+
diff --git a/app/views/merge_requests/_merge_request.html.haml b/app/views/merge_requests/_merge_request.html.haml
index 262aa661c94..583cc44099c 100644
--- a/app/views/merge_requests/_merge_request.html.haml
+++ b/app/views/merge_requests/_merge_request.html.haml
@@ -1,14 +1,13 @@
-%a.update-item{:href => project_merge_request_path(merge_request.project, merge_request)}
- = image_tag gravatar_icon(merge_request.author_email), :class => "left", :width => 40
- %span.update-title
- = truncate(merge_request.title, :length => 60)
+%li.wll
+ = image_tag gravatar_icon(merge_request.author_email), :class => "avatar"
%span.update-author
%strong= merge_request.author_name
authored
= time_ago_in_words(merge_request.created_at)
ago
.right
- %span.tag.commit= merge_request.source_branch
+ %span.label= merge_request.source_branch
&rarr;
- %span.tag.commit= merge_request.target_branch
-
+ %span.label= merge_request.target_branch
+ = link_to project_merge_request_path(merge_request.project, merge_request) do
+ %p.row_title= truncate(merge_request.title, :length => 60)
diff --git a/app/views/merge_requests/edit.html.haml b/app/views/merge_requests/edit.html.haml
index bcc5832792f..9e4f9327cdc 100644
--- a/app/views/merge_requests/edit.html.haml
+++ b/app/views/merge_requests/edit.html.haml
@@ -1 +1,4 @@
+%h3
+ = "Edit merge request #{@merge_request.id}"
+%hr
= render 'form'
diff --git a/app/views/merge_requests/index.html.haml b/app/views/merge_requests/index.html.haml
index fa02be9e92c..9ced7a86938 100644
--- a/app/views/merge_requests/index.html.haml
+++ b/app/views/merge_requests/index.html.haml
@@ -1,30 +1,26 @@
-= render "merge_requests/head"
+%h3
+ Merge Requests
+ - if can? current_user, :write_issue, @project
+ = link_to new_project_merge_request_path(@project), :class => "right btn small", :title => "New Merge Request" do
+ New Merge Request
-.left.issues_filter
- = form_tag project_merge_requests_path(@project), :method => :get do
- .left
- = radio_button_tag :f, 0, (params[:f] || "0") == "0", :onclick => "this.form.submit()", :id => "open_merge_requests", :class => "status"
- = label_tag "open_merge_requests" do
- %span.tag.open Open
- .left
- = radio_button_tag :f, 2, params[:f] == "2", :onclick => "this.form.submit()", :id => "closed_merge_requests", :class => "status"
- = label_tag "closed_merge_requests" do
- %span.tag.closed Closed
+%br
-.clear
-%hr
+.ui-box
+ .title
+ %ul.pills
+ %li{:class => ("active" if (params[:f] == "0" || !params[:f]))}
+ = link_to project_merge_requests_path(@project, :f => 0) do
+ Open
+ %li{:class => ("active" if params[:f] == "2")}
+ = link_to project_merge_requests_path(@project, :f => 2) do
+ Closed
+ %li{:class => ("active" if params[:f] == "3")}
+ = link_to project_merge_requests_path(@project, :f => 3) do
+ To Me
+ %li{:class => ("active" if params[:f] == "1")}
+ = link_to project_merge_requests_path(@project, :f => 1) do
+ All
-- if @merge_requests.count > 0
- %div{ :class => "update-data ui-box ui-box-small ui-box-big" }
- .data
- = render @merge_requests
-
- .clear
- %br
-
-- unless @merge_requests.count > 0 || params[:f] == "2"
- .notice_holder
- %li Merge Requests do not exist yet.
- - if can? current_user, :write_merge_request, @project
- %li You can add a new one by clicking on "Add New" button
+ %ul.unstyled= render @merge_requests
diff --git a/app/views/merge_requests/new.html.haml b/app/views/merge_requests/new.html.haml
index bcc5832792f..efafa45d758 100644
--- a/app/views/merge_requests/new.html.haml
+++ b/app/views/merge_requests/new.html.haml
@@ -1 +1,3 @@
+%h3 New Merge Request
+%hr
= render 'form'
diff --git a/app/views/merge_requests/show.html.haml b/app/views/merge_requests/show.html.haml
index 6fc6d5c1bf9..e725c1981ad 100644
--- a/app/views/merge_requests/show.html.haml
+++ b/app/views/merge_requests/show.html.haml
@@ -1,65 +1,70 @@
-%div
- %span.entity-info
- - if can?(current_user, :admin_project, @project) || @merge_request.author == current_user
- = link_to edit_project_merge_request_path(@project, @merge_request) do
- .entity-button
- Edit Merge Request
- %i
- = image_tag gravatar_icon(@merge_request.author_email), :class => "left", :width => 40, :style => "padding-right:5px;"
- %span.commit-title
- %strong
- = "Merge Request ##{@merge_request.id}:"
- &nbsp;
- .tag.commit.inline= @merge_request.source_branch
- &rarr;
- .tag.commit.inline= @merge_request.target_branch
- %span.commit-author
- %strong
- = link_to project_team_member_path(@project, @project.team_member_by_id(@merge_request.author.id)) do
- %span.author= @merge_request.author_name
- &rarr;
- = link_to project_team_member_path(@project, @project.team_member_by_id(@merge_request.assignee.id)) do
- %span.author= @merge_request.assignee_name
-
- &nbsp;
- &nbsp;
- = @merge_request.created_at.stamp("Aug 21, 2011 9:23pm")
-
- %hr
- %br
- %h3
- = simple_format @merge_request.title
-
-.clear
-%br
-%br
-
-.merge-tabs
- = link_to "#notes", :class => "merge-notes-tab active tab" do
- %span
- Notes
- = link_to "#commits", "data-url" => commits_project_merge_request_path(@project, @merge_request), :class => "merge-commits-tab tab" do
- %span
- Commits
- = link_to "#diffs", "data-url" => diffs_project_merge_request_path(@project, @merge_request), :class => "merge-diffs-tab tab" do
- %span
- Diff
-
- - if can?(current_user, :admin_project, @project) || @merge_request.author == current_user
- .right
+%h3
+ = "Merge Request ##{@merge_request.id}:"
+ &nbsp;
+ %span.label= @merge_request.source_branch
+ &rarr;
+ %span.label= @merge_request.target_branch
+
+ %small
+ created at
+ = @merge_request.created_at.stamp("Aug 21, 2011")
+
+ %span.right
+ - if can?(current_user, :modify_merge_request, @merge_request)
- if @merge_request.closed
- = link_to 'Reopen', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => false }, :status_only => true), :method => :put, :class => "red-button"
+ = link_to 'Reopen', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => false }, :status_only => true), :method => :put, :class => "btn"
- else
- = link_to 'Close', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => true }, :status_only => true), :method => :put, :class => "positive-button", :title => "Close merge request"
- %img{:src => "/assets/ajax-loader-facebook.gif", :class => "dashboard-loader"}
+ = link_to 'Close', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => true }, :status_only => true), :method => :put, :class => "btn", :title => "Close merge request"
+ = link_to edit_project_merge_request_path(@project, @merge_request), :class => "btn small" do
+ Edit
+
+.back_link
+ = link_to project_merge_requests_path(@project) do
+ &larr; To merge requests
+
+
+%hr
+- if @merge_request.closed
+ .alert-message.error Closed
+- else
+ .alert-message.success
+ = link_to "#", :class => "info_link", :title => "How To Merge" do
+ = image_tag "Info-UI.PNG"
+ Open
+
+= render "merge_requests/how_to_merge"
+
+%div.well
+ %div
+ %cite.cgray Created by
+ = image_tag gravatar_icon(@merge_request.author_email), :width => 16, :class => "lil_av"
+ %strong.author= link_to_merge_request_author(@merge_request)
+
+ %cite.cgray and currently assigned to
+ = image_tag gravatar_icon(@merge_request.assignee_email), :width => 16, :class => "lil_av"
+ %strong.author= link_to_merge_request_assignee(@merge_request)
+
+ %hr
+
+
+ %div= simple_format @merge_request.title
+
+= render "merge_requests/commits"
+
+- unless @commits.empty?
+ .tabs
+ %li.active
+ = link_to "#notes", :class => "merge-notes-tab tab" do
+ Notes
+ %li
+ = link_to "#diffs", "data-url" => diffs_project_merge_request_path(@project, @merge_request), :class => "merge-diffs-tab tab" do
+ Diff
+
+ %img{:src => "/assets/ajax-loader-facebook.gif", :class => "dashboard-loader"}
.merge-request-notes
- .issue_notes= render "notes/notes"
- .loading{ :style => "display:none;"}
- %center= image_tag "ajax-loader.gif"
- .clear
+ .merge_request_notes= render "notes/notes", :tid => @merge_request.id, :tt => "merge_request"
-.merge-request-commits
.merge-request-diffs
@@ -67,3 +72,15 @@
$(function(){
MergeRequest.init();
})
+
+= render "notes/per_line_form"
+:javascript
+ $(document).ready(function(){
+ $(".line_note_link, .line_note_reply_link").live("click", function(e) {
+ var form = $(".per_line_form");
+ $(this).parent().parent().after(form);
+ form.find("#note_line_code").val($(this).attr("line_code"));
+ form.show();
+ return false;
+ });
+ });
diff --git a/app/views/notes/_create_common.js.haml b/app/views/notes/_create_common.js.haml
new file mode 100644
index 00000000000..583812bf502
--- /dev/null
+++ b/app/views/notes/_create_common.js.haml
@@ -0,0 +1,9 @@
+- if note.valid?
+ :plain
+ $("#new_note .errors").remove();
+ $('#new_note textarea').val("");
+ NoteList.prepend(#{note.id}, "#{escape_javascript(render :partial => "notes/show", :locals => {:note => note})}");
+- else
+ :plain
+ $("#new_note").replaceWith("#{escape_javascript(render('form'))}");
+
diff --git a/app/views/notes/_create_line.js.haml b/app/views/notes/_create_line.js.haml
new file mode 100644
index 00000000000..9cf085cd613
--- /dev/null
+++ b/app/views/notes/_create_line.js.haml
@@ -0,0 +1,8 @@
+- if note.valid?
+ :plain
+ $(".per_line_form").hide();
+ $('#new_note textarea').val("");
+ $("a.line_note_reply_link[line_code='#{note.line_code}']").closest("tr").remove();
+ var trEl = $(".#{note.line_code}").parent();
+ trEl.after("#{escape_javascript(render :partial => "notes/per_line_show", :locals => {:note => note})}");
+ trEl.after("#{escape_javascript(render :partial => "notes/reply_button", :locals => {:line_code => note.line_code})}");
diff --git a/app/views/notes/_form.html.haml b/app/views/notes/_form.html.haml
index 95a3b01acfe..0d20bb15835 100644
--- a/app/views/notes/_form.html.haml
+++ b/app/views/notes/_form.html.haml
@@ -1,37 +1,31 @@
-%div
- = form_for [@project, @note], :remote => "true", :multipart => true do |f|
- -if @note.errors.any?
- .errors.error
- - @note.errors.full_messages.each do |msg|
- %div= msg
+= form_for [@project, @note], :remote => "true", :multipart => true do |f|
+ %h3 Leave a note
+ -if @note.errors.any?
+ .alert-message.block-message.error
+ - @note.errors.full_messages.each do |msg|
+ %div= msg
- = f.hidden_field :noteable_id
- = f.hidden_field :noteable_type
+ = f.hidden_field :noteable_id
+ = f.hidden_field :noteable_type
+ = f.text_area :note, :size => 255
- %div
- = f.label :note
- %cite.cgray markdown supported
- %br
- %br
- = f.text_area :note, :size => 255
+ .row
+ .span4
+ %h5 Notify via email:
+ .clearfix
+ = label_tag :notify do
+ = check_box_tag :notify, 1, @note.noteable_type != "Commit"
+ %span Project team
- %div.attach_holder
- %br
- = f.label :attachment
- %cite.cgray (less than 10 MB)
- %br
- %br
- = f.file_field :attachment
-
- %p.notify_controls
- %span Notify:
- = check_box_tag :notify, 1, @note.noteable_type != "Commit"
- = label_tag :notify, "Project team"
+ - if @note.notify_only_author?(current_user)
+ = label_tag :notify_author do
+ = check_box_tag :notify_author, 1 , @note.noteable_type == "Commit"
+ %span Commit author
+ .span4
+ %h5 Attachment:
+ .clearfix
+ = f.label :attachment, "Any file, < 10 MB"
+ .input= f.file_field :attachment, :class => "input-file"
- -if @note.noteable_type == "Commit"
- = check_box_tag :notify_author, 1 , @note.noteable_type == "Commit"
- = label_tag :notify_author, "Commit author"
- .clear
- %br
- = f.submit 'Add note', :class => "positive-button", :id => "submit_note"
+ = f.submit 'Add note', :class => "btn primary", :id => "submit_note"
diff --git a/app/views/notes/_load.js.haml b/app/views/notes/_load.js.haml
index 62d44fe1d5f..fa373145298 100644
--- a/app/views/notes/_load.js.haml
+++ b/app/views/notes/_load.js.haml
@@ -1,12 +1,7 @@
- unless @notes.blank?
-
- - if params[:last_id] && params[:first_id]
- :plain
- NoteList.replace(#{@notes.last.id}, #{@notes.first.id}, "#{escape_javascript(render(:partial => 'notes/notes_list'))}");
-
- - elsif params[:last_id]
+ - if params[:last_id]
:plain
- NoteList.prepend(#{@notes.first.id}, "#{escape_javascript(render(:partial => 'notes/notes_list'))}");
+ NoteList.replace("#{escape_javascript(render(:partial => 'notes/notes_list'))}");
- elsif params[:first_id]
:plain
@@ -14,3 +9,9 @@
- else
:plain
+ NoteList.setContent(#{@notes.last.id}, #{@notes.first.id}, "#{escape_javascript(render(:partial => 'notes/notes_list'))}");
+
+- else
+ - if params[:first_id]
+ :plain
+ NoteList.append(#{params[:first_id]}, "");
diff --git a/app/views/notes/_notes.html.haml b/app/views/notes/_notes.html.haml
index 4a5c3aab353..e692e746465 100644
--- a/app/views/notes/_notes.html.haml
+++ b/app/views/notes/_notes.html.haml
@@ -2,25 +2,12 @@
= render "notes/form"
.clear
%hr
-%ul#notes-list= render "notes/notes_list"
+%ul#new_notes_list
+%ul#notes-list
+.status
-:javascript
- $('.delete-note').live('ajax:success', function() {
- $(this).closest('li').fadeOut(); });
-
- $("#new_note").live("ajax:before", function(){
- $("#submit_note").attr("disabled", "disabled");
- })
-
- $("#new_note").live("ajax:complete", function(){
- $("#submit_note").removeAttr("disabled");
- })
+:javascript
$(function(){
- $("#note_note").live("click", function(){
- $(this).css("height", "100px");
- $('.attach_holder').show();
- });
-
- NoteList.init("wall", #{@notes.last.try(:id) || 0}, #{@notes.first.try(:id) || 0});
+ NoteList.init("#{tid}", "#{tt}", "#{project_notes_path(@project)}");
});
diff --git a/app/views/notes/_per_line_form.html.haml b/app/views/notes/_per_line_form.html.haml
index 72989320226..28faa6301c0 100644
--- a/app/views/notes/_per_line_form.html.haml
+++ b/app/views/notes/_per_line_form.html.haml
@@ -1,29 +1,33 @@
%table{:style => "display:none;"}
%tr.per_line_form
%td{:colspan => 3 }
- %div
- = form_for [@project, @note], :remote => "true", :multipart => true do |f|
- -if @note.errors.any?
- .errors.error
- - @note.errors.full_messages.each do |msg|
- %div= msg
+ = form_for [@project, @note], :remote => "true", :multipart => true do |f|
+ %h3 Leave a note
+ .row
+ .span16
+ -if @note.errors.any?
+ .alert-message.block-message.error
+ - @note.errors.full_messages.each do |msg|
+ %div= msg
- = f.hidden_field :noteable_id
- = f.hidden_field :noteable_type
- = f.hidden_field :line_code
-
- %div
- = f.label :note
- %cite.cgray markdown supported
- %br
- %br
+ = f.hidden_field :noteable_id
+ = f.hidden_field :noteable_type
+ = f.hidden_field :line_code
= f.text_area :note, :size => 255
+ .actions
+ = f.submit 'Add note', :class => "btn primary", :id => "submit_note"
+ = link_to "Close", "#", :class => "btn hide-button"
+ .span6.entry
+ %h5 Notify via email:
+ .clearfix
+ = label_tag :notify do
+ = check_box_tag :notify, 1, @note.noteable_type != "Commit"
+ %span Project team
- .clear
- %br
- = f.submit 'Add note', :class => "positive-button", :id => "submit_note"
- .right
- = link_to "Close", "#", :class => "grey-button hide-button"
+ - if @note.notify_only_author?(current_user)
+ = label_tag :notify_author do
+ = check_box_tag :notify_author, 1 , @note.noteable_type == "Commit"
+ %span Commit author
:javascript
$(function(){
diff --git a/app/views/notes/_reply_button.html.haml b/app/views/notes/_reply_button.html.haml
new file mode 100644
index 00000000000..f53b8c8d364
--- /dev/null
+++ b/app/views/notes/_reply_button.html.haml
@@ -0,0 +1,3 @@
+%tr.line_notes_row.reply
+ %td{:colspan => 3}
+ = link_to "Reply", "#", :class => "line_note_reply_link", "line_code" => line_code, :title => "Add note for this line"
diff --git a/app/views/notes/_show.html.haml b/app/views/notes/_show.html.haml
index d91fea04b5b..6da1d5904bf 100644
--- a/app/views/notes/_show.html.haml
+++ b/app/views/notes/_show.html.haml
@@ -6,7 +6,7 @@
= time_ago_in_words(note.updated_at)
ago
- if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project)
- = link_to "Remove", [@project, note], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "cred delete-note right"
+ %strong= link_to "Remove", [@project, note], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "cred delete-note btn small"
%div.note-title
= markdown(note.note)
diff --git a/app/views/notes/create.js.haml b/app/views/notes/create.js.haml
index b81ea5b03e7..67110340001 100644
--- a/app/views/notes/create.js.haml
+++ b/app/views/notes/create.js.haml
@@ -1,18 +1,8 @@
-- if @note.valid?
- - if @note.line_code
- :plain
- $(".per_line_form").hide();
- $('#new_note textarea').val("");
- $(".#{@note.line_code}").parent().after("#{escape_javascript(render :partial => "notes/per_line_show", :locals => {:note => @note})}");
- - else
- :plain
- $("#new_note .errors").remove();
- $('#new_note textarea').val("");
- NoteList.prepend(#{@note.id}, "#{escape_javascript(render :partial => "notes/show", :locals => {:note => @note})}");
-- else
- - unless @note.line_code
- :plain
- $("#new_note").replaceWith("#{escape_javascript(render('form'))}");
+- if @note.line_code
+ = render "create_line", :note => @note
+- else
+ = render "create_common", :note => @note
+-# Enable submit button
:plain
$("#submit_note").removeAttr("disabled");
diff --git a/app/views/commits/show.js.haml b/app/views/notes/index.js.haml
index ee31c0b8d3c..ee31c0b8d3c 100644
--- a/app/views/commits/show.js.haml
+++ b/app/views/notes/index.js.haml
diff --git a/app/views/notify/note_commit_email.html.haml b/app/views/notify/note_commit_email.html.haml
index 81001d684c2..41501deebb8 100644
--- a/app/views/notify/note_commit_email.html.haml
+++ b/app/views/notify/note_commit_email.html.haml
@@ -4,7 +4,7 @@
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
%td{:align => "left", :style => "padding: 20px 0 0;"}
%h2{:style => "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
- New comment for commmit
+ New comment for commit
= link_to truncate(@commit.id.to_s, :length => 16), project_commit_url(@project, :id => @commit.id, :anchor => "note_#{@note.id}")
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
%tr
@@ -17,7 +17,7 @@
%table{:border => "0", :cellpadding => "0", :cellspacing => "0", :width => "558"}
%tr
%td{:valign => "top"}
- %cite{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
- = @note.note
+ %div{ :style => "background:#f5f5f5; padding:20px;border:1px solid #ddd" }
+ = RDiscount.new(@note.note, :autolink, :no_pseudo_protocols, :safelink, :smart, :filter_html).to_html.html_safe
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
diff --git a/app/views/notify/note_issue_email.html.haml b/app/views/notify/note_issue_email.html.haml
index 7d8e215609e..28db944f8e1 100644
--- a/app/views/notify/note_issue_email.html.haml
+++ b/app/views/notify/note_issue_email.html.haml
@@ -19,7 +19,7 @@
%table{:border => "0", :cellpadding => "0", :cellspacing => "0", :width => "558"}
%tr
%td{:valign => "top"}
- %cite{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
- = @note.note
+ %div{ :style => "background:#f5f5f5; padding:20px;border:1px solid #ddd" }
+ = RDiscount.new(@note.note, :autolink, :no_pseudo_protocols, :safelink, :smart, :filter_html).to_html.html_safe
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
diff --git a/app/views/notify/note_merge_request_email.html.haml b/app/views/notify/note_merge_request_email.html.haml
index 27854e23a3b..6a97f9cadc3 100644
--- a/app/views/notify/note_merge_request_email.html.haml
+++ b/app/views/notify/note_merge_request_email.html.haml
@@ -17,7 +17,7 @@
%table{:border => "0", :cellpadding => "0", :cellspacing => "0", :width => "558"}
%tr
%td{:valign => "top"}
- %cite{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
- = @note.note
+ %div{ :style => "background:#f5f5f5; padding:20px;border:1px solid #ddd" }
+ = RDiscount.new(@note.note, :autolink, :no_pseudo_protocols, :safelink, :smart, :filter_html).to_html.html_safe
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
diff --git a/app/views/notify/note_wall_email.html.haml b/app/views/notify/note_wall_email.html.haml
index a2bd5a76601..77b58f15eef 100644
--- a/app/views/notify/note_wall_email.html.haml
+++ b/app/views/notify/note_wall_email.html.haml
@@ -17,6 +17,6 @@
%table{:border => "0", :cellpadding => "0", :cellspacing => "0", :width => "558"}
%tr
%td{:valign => "top"}
- %cite{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
- = @note.note
+ %div{ :style => "background:#f5f5f5; padding:20px;border:1px solid #ddd" }
+ = RDiscount.new(@note.note, :autolink, :no_pseudo_protocols, :safelink, :smart, :filter_html).to_html.html_safe
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
diff --git a/app/views/profile/design.html.haml b/app/views/profile/design.html.haml
index 4a0f758d31f..68746fdc214 100644
--- a/app/views/profile/design.html.haml
+++ b/app/views/profile/design.html.haml
@@ -1,22 +1,20 @@
-.ui-box.width-100p
- %h3 Design
- = form_for @user, :url => profile_update_path, :method => :put do |f|
- .data
- .left.dark_scheme_box
- %label{:for => "user_dark_scheme_false"}
- = image_tag "white.png", :width => 310, :height => 212
- %center
- %h4
- = f.radio_button :dark_scheme, false
- White code preview
- .right.dark_scheme_box
- %label{:for => "user_dark_scheme_true"}
- = image_tag "dark.png", :width => 310, :height => 212
- %center
- %h4
- = f.radio_button :dark_scheme, true
- Dark code preview
- .clear
- .buttons
- = f.submit 'Save', :class => "grey-button"
+%h3 Design
+%hr
+= form_for @user, :url => profile_update_path, :method => :put do |f|
+ .row
+ %label.span4{:for => "user_dark_scheme_false"}
+ = image_tag "white.png", :width => 210
+ %center
+ %h4
+ = f.radio_button :dark_scheme, false
+ White code preview
+ %label.span4{:for => "user_dark_scheme_true"}
+ = image_tag "dark.png", :width => 210
+ %center
+ %h4
+ = f.radio_button :dark_scheme, true
+ Dark code preview
+ .clearfix
+ .actions
+ = f.submit 'Save', :class => "btn"
diff --git a/app/views/profile/password.html.haml b/app/views/profile/password.html.haml
index 893263f7d8d..dc1f221435e 100644
--- a/app/views/profile/password.html.haml
+++ b/app/views/profile/password.html.haml
@@ -1,44 +1,42 @@
-.ui-box.width-100p.append-bottom-20
- %h3 Password
- = form_for @user, :url => profile_password_path, :method => :put do |f|
- .data
+%h3 Password
+%hr
+= form_for @user, :url => profile_password_path, :method => :put do |f|
+ .data
+ .alert-message.block-message.warning
%p After successfull password update you will be redirected to login page where you should login with new password
- -if @user.errors.any?
- #error_explanation
- %ul
- - @user.errors.full_messages.each do |msg|
- %li= msg
+ -if @user.errors.any?
+ .alert-message.block-message.error
+ %ul
+ - @user.errors.full_messages.each do |msg|
+ %li= msg
- .form-row
- = f.label :password
- %br
- = f.password_field :password
- .form-row
- = f.label :password_confirmation
- %br
- = f.password_field :password_confirmation
- .buttons
- = f.submit 'Save', :class => "grey-button"
-.clear
-
-.ui-box.width-100p
- %h3
- Private token
- %em.cred.right
- keep it in secret!
- = form_for @user, :url => profile_reset_private_token_path, :method => :put do |f|
- .data
- %p Private token used to access application resources without authentication.
- %p For example its required to access commits feed.
- %hr
- %p.cgray
- - if current_user.private_token
- = text_field_tag "token", current_user.private_token
- - else
- You don`t have one yet. Click generate to fix it.
- .buttons
+ .clearfix
+ = f.label :password
+ .input= f.password_field :password
+ .clearfix
+ = f.label :password_confirmation
+ .input= f.password_field :password_confirmation
+ .actions
+ = f.submit 'Save', :class => "btn"
+
+%h3
+ Private token
+ %span.cred.right
+ keep it in secret!
+%hr
+= form_for @user, :url => profile_reset_private_token_path, :method => :put do |f|
+ .data
+ %p Private token used to access application resources without authentication.
+ %p For example its required to access commits feed.
+ %hr
+ %p.cgray
- if current_user.private_token
- = f.submit 'Reset', :confirm => "Are you sure?", :class => "grey-button"
+ = text_field_tag "token", current_user.private_token
- else
- = f.submit 'Generate', :class => "positive-button"
+ You don`t have one yet. Click generate to fix it.
+ .actions
+ - if current_user.private_token
+ = f.submit 'Reset', :confirm => "Are you sure?", :class => "btn"
+ - else
+ = f.submit 'Generate', :class => "btn"
diff --git a/app/views/profile/show.html.haml b/app/views/profile/show.html.haml
index 8ebb4dcb713..2c2249bf0d2 100644
--- a/app/views/profile/show.html.haml
+++ b/app/views/profile/show.html.haml
@@ -1,38 +1,33 @@
-.ui-box.width-100p
- %h3= @user.name
- = form_for @user, :url => profile_update_path, :method => :put do |f|
- .data
- .left
- -if @user.errors.any?
- #error_explanation
- %ul
- - @user.errors.full_messages.each do |msg|
- %li= msg
+.media-grid
+ = link_to "#" do
+ = image_tag gravatar_icon(@user.email, 90), :class => "thumbnail"
+ %h3.media_h= @user.name
- .form-row
- = f.label :name
- %br
- = f.text_field :name
- .form-row
- = f.label :email
- %br
- = f.text_field :email
- .form-row
- = f.label :skype
- %br
- = f.text_field :skype
- .form-row
- = f.label :linkedin
- %br
- = f.text_field :linkedin
- .form-row
- = f.label :twitter
- %br
- = f.text_field :twitter
+%hr
- .right
- = image_tag gravatar_icon(current_user.email,64), :width => 64, :style => "margin:5px; border:5px solid #eee;"
- .clear
- .buttons
- = f.submit 'Save', :class => "grey-button"
+= form_for @user, :url => profile_update_path, :method => :put do |f|
+ -if @user.errors.any?
+ %div.alert-message.block-message.error
+ %ul
+ - @user.errors.full_messages.each do |msg|
+ %li= msg
+
+ .clearfix
+ = f.label :name
+ .input= f.text_field :name
+ .clearfix
+ = f.label :email
+ .input= f.text_field :email
+ .clearfix
+ = f.label :skype
+ .input= f.text_field :skype
+ .clearfix
+ = f.label :linkedin
+ .input= f.text_field :linkedin
+ .clearfix
+ = f.label :twitter
+ .input= f.text_field :twitter
+
+ .actions
+ = f.submit 'Save', :class => "primary btn"
diff --git a/app/views/projects/_feed.html.haml b/app/views/projects/_feed.html.haml
index 4f8e59f8c51..f907b8a253f 100644
--- a/app/views/projects/_feed.html.haml
+++ b/app/views/projects/_feed.html.haml
@@ -1,79 +1,23 @@
-- if update.kind_of?(Note)
- %a.project-update.titled{:href => dashboard_feed_path(project, update)}
- = image_tag gravatar_icon(update.author_email), :class => "left", :width => 40
- %span.update-title
- = dashboard_feed_title(update)
- %span.update-author
- %strong= update.author_name
- = time_ago_in_words(update.created_at)
- ago
- - noteable = update.target
- - if noteable.kind_of?(MergeRequest)
- .title-block
- %span.update-title
- %span.commit.tag
- Merge Request #
- = noteable.id
- %span.update-author
- %span= noteable.source_branch
- &rarr;
- %span= noteable.target_branch
-
- - elsif noteable.kind_of?(Issue)
- .title-block
- %span.update-title
- %span.commit.tag
- Issue #
- = noteable.id
- %span.update-author
- .left= truncate noteable.title
-
- - elsif noteable.kind_of?(Commit)
- .title-block
- %span.update-title
- %span.commit.tag
- commit
- %span.update-author
- .left= truncate noteable.id
- - else
- .title-block
- %span.update-title
- %span.commit.tag
- Project Wall
-
-
-- elsif update.kind_of?(MergeRequest)
- %a.project-update.titled{:href => project_merge_request_path(project, update)}
- = image_tag gravatar_icon(update.author_email), :class => "left", :width => 40
- %span.update-title
- Opened merge request
- %span.update-author
- %strong= update.author_name
- = time_ago_in_words(update.created_at)
- ago
- .title-block
- %span.update-title
- %span.commit.tag
- Merge Request #
- = update.id
- %span.update-author
- %span= update.source_branch
- &rarr;
- %span= update.target_branch
-
-- elsif update.kind_of?(Issue)
- %a.project-update.titled{:href => dashboard_feed_path(project, update)}
- = image_tag gravatar_icon(update.author_email), :class => "left", :width => 40
- %span.update-title
- Created new Issue
- %span.update-author
- %strong= update.author_name
- = time_ago_in_words(update.created_at)
- ago
- .title-block
- %span.update-title
- %span.commit.tag
- Issue #
- = update.id
- %span.update-author
- .left= truncate update.title
+- @activities.each do |update|
+ .wll
+ = link_to dashboard_feed_path(@project, update) do
+ - if update.kind_of? Note
+ %p
+ %strong
+ - if update.target
+ = update.target.class.name.titleize
+ = truncate update.target.id.to_s, :length => 10
+ commented
+ - else
+ Project wall
+ &ndash;
+ = image_tag gravatar_icon(update.author_email), :class => "", :width => 16
+ = truncate dashboard_feed_title(update), :length => 50
+ - else
+ %p
+ %strong
+ = update.class.name.titleize
+ = truncate update.id.to_s
+ &ndash;
+ = image_tag gravatar_icon(update.author_email), :class => "", :width => 16
+ = truncate dashboard_feed_title(update), :length => 50
diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml
index 421e8409824..6137aa5e279 100644
--- a/app/views/projects/_form.html.haml
+++ b/app/views/projects/_form.html.haml
@@ -1,67 +1,60 @@
= form_for(@project, :remote => true) do |f|
- %div.form_content
- - unless @project.new_record?
- %h2.icon
- %span
- = @project.name
- .clear
- - if @project.errors.any?
- %ul.errors_holder
+ - if @project.errors.any?
+ .alert-message.block-message.error
+ %ul
- @project.errors.full_messages.each do |msg|
%li= msg
- %table
- %tr
- %td= f.label :name
- %td= f.text_field :name, :placeholder => "Example Project"
- %tr
- %td
- .left= f.label :path
- %cite.right= "git@#{GIT_HOST["host"]}:"
- %td
- = f.text_field :path, :placeholder => "example_project", :disabled => !@project.new_record?
- %tr
- %td
- .left= f.label :code
- %cite.right= "http://#{GIT_HOST["host"]}/"
- %td= f.text_field :code, :placeholder => "example"
+ .clearfix
+ = f.label :name
+ .input= f.text_field :name, :placeholder => "Example Project"
+ .clearfix
+ = f.label :path do
+ Path
+ .input
+ .input-prepend
+ %span.add-on= "git@#{GIT_HOST["host"]}:"
+ = f.text_field :path, :placeholder => "example_project", :disabled => !@project.new_record?
+ .clearfix
+ = f.label :code do
+ Code
+ .input
+ .input-prepend
+ %span.add-on= "http://#{GIT_HOST["host"]}/"
+ = f.text_field :code, :placeholder => "example"
- - unless @project.new_record? || @project.heads.empty?
- %tr
- %td= f.label :default_branch, "Default Branch"
- %td= f.select(:default_branch, @project.heads.map(&:name), {}, :style => "width:300px;")
+ - unless @project.new_record? || @project.heads.empty?
+ .clearfix
+ = f.label :default_branch, "Default Branch"
+ .input= f.select(:default_branch, @project.heads.map(&:name), {}, :style => "width:210px;")
- -#%tr
- %td= f.label :tag_list
- %td= f.text_area :tag_list, :placeholder => "project tags", :style => "height:50px", :id => :tag_field
- %tr
- %td= f.label :description
- %td= f.text_area :description, :placeholder => "project description", :style => "height:50px"
+ .alert-message.block-message.warning
+ %h5 Features
- %br
- %div{ :class => "ajax_loader", :style => "display:none;height:200px;"}
- %center
- = image_tag "ajax-loader.gif", :class => "append-bottom"
- - if @project.new_record?
- %h3.prepend-top Creating project &amp; repository. Please wait for few minutes
- - else
- %h3.prepend-top Updating project &amp; repository. Please wait for few minutes
-
- .merge-tabs
- = f.submit 'Save', :class => "grey-button"
- &nbsp;
- - unless @project.new_record?
- .right
- = link_to 'Remove', @project, :confirm => 'Are you sure?', :method => :delete, :class => "red-button"
+ .clearfix
+ = f.label :issues_enabled, "Issues"
+ .input= f.check_box :issues_enabled
+ .clearfix
+ = f.label :merge_requests_enabled, "Merge Requests"
+ .input= f.check_box :merge_requests_enabled
-:javascript
- $(function(){
- $('.new_project, .edit_project').bind('ajax:before', function() {
- $(this).find(".form_content").hide();
- $('.ajax_loader').show();
- });
-
- taggifyForm();
+ .clearfix
+ = f.label :wall_enabled, "Wall"
+ .input= f.check_box :wall_enabled
+
+ .clearfix
+ = f.label :wiki_enabled, "Wiki"
+ .input= f.check_box :wiki_enabled
- $('form #project_default_branch').chosen();
- })
+ .clearfix
+ = f.label :description
+ .input= f.text_area :description, :placeholder => "project description", :class => "xlarge", :rows => 4
+
+ %br
+
+ .actions
+ = f.submit 'Save', :class => "btn primary"
+ = link_to 'Cancel', @project, :class => "btn"
+ - unless @project.new_record?
+ .right
+ = link_to 'Remove', @project, :confirm => 'Are you sure?', :method => :delete, :class => "btn danger"
diff --git a/app/views/projects/_project_head.html.haml b/app/views/projects/_project_head.html.haml
index cbcd0660e10..ebf0748c8a4 100644
--- a/app/views/projects/_project_head.html.haml
+++ b/app/views/projects/_project_head.html.haml
@@ -1,27 +1,28 @@
-.top-tabs
- = link_to project_path(@project), :class => "activities-tab tab #{'active' if current_page?(project_path(@project)) }" do
- %span
- Activities
- = link_to info_project_path(@project), :class => "stat-tab tab #{'active' if current_page?(info_project_path(@project)) || current_page?(edit_project_path(@project)) }" do
- %span
- Info
- = link_to team_project_path(@project), :class => "team-tab tab #{'active' if current_page?(team_project_path(@project)) }" do
- %span
- Team
- = link_to files_project_path(@project), :class => "files-tab tab #{'active' if current_page?(files_project_path(@project)) }" do
- %span
- Files
- = link_to project_snippets_path(@project), :class => "snippets-tab tab #{'active' if current_page?(project_snippets_path(@project)) }" do
- %span
- Snippets
+%ul.tabs
+ %li{ :class => "#{'active' if current_page?(project_path(@project)) }" }
+ = link_to project_path(@project), :class => "activities-tab tab" do
+ Show
+ - if can? current_user, :admin_project, @project
+ %li{ :class => "#{'active' if current_page?(edit_project_path(@project)) }" }
+ = link_to edit_project_path(@project), :class => "stat-tab tab " do
+ Edit
+
+ %li{ :class => " #{'active' if (controller.controller_name == "team_members") || current_page?(team_project_path(@project)) }" }
+ = link_to team_project_path(@project), :class => "team-tab tab" do
+ Team
+ %li{ :class => "#{'active' if current_page?(files_project_path(@project)) }" }
+ = link_to files_project_path(@project), :class => "files-tab tab " do
+ Attachments
+ %li{ :class => " #{'active' if (controller.controller_name == "snippets") }" }
+ = link_to project_snippets_path(@project), :class => "snippets-tab tab" do
+ Snippets
- - if current_page?(project_snippets_path(@project))
- - if can? current_user, :write_snippet, @project
- = link_to new_project_snippet_path(@project), :class => "add_new", :title => "New Snippet" do
- Add new
-
-
- - if current_page?(team_project_path(@project))
- - if can? current_user, :admin_team_member, @project
- = link_to new_project_team_member_path(@project), :class => "add_new", :title => "New Team Member" do
- Add New
+ - if can? current_user, :admin_project, @project
+ %li{:class => "#{'active' if controller.controller_name == "hooks" }"}
+ = link_to project_hooks_path(@project) do
+ %span
+ Hooks
+ %li{:class => "#{'active' if controller.controller_name == "deploy_keys"}"}
+ = link_to project_deploy_keys_path(@project) do
+ %span
+ Deploy Keys
diff --git a/app/views/projects/_team.html.haml b/app/views/projects/_team.html.haml
index 3d033a85913..876270a8470 100644
--- a/app/views/projects/_team.html.haml
+++ b/app/views/projects/_team.html.haml
@@ -1,19 +1,10 @@
-%table.no-borders#team-table
- %thead
- %th Name
- %th Project
- %th Repository
- - if can? current_user, :admin_team_member, @project
- %th Actions
+%ul.media-grid
- @project.users_projects.each do |up|
= render(:partial => 'team_members/show', :locals => {:member => up})
:javascript
$(function(){
- $('#team-table .repo-access-select, #team-table .project-access-select').live("change", function() {
+ $('.repo-access-select, .project-access-select').live("change", function() {
$(this.form).submit();
});
})
-
- $('.delete-team-member').live('ajax:success', function() {
- $(this).closest('tr').fadeOut(); });
diff --git a/app/views/projects/_tile.html.haml b/app/views/projects/_tile.html.haml
index d9549045058..e49aa076230 100644
--- a/app/views/projects/_tile.html.haml
+++ b/app/views/projects/_tile.html.haml
@@ -1,20 +1,13 @@
- @projects.in_groups_of(3, false) do |projects|
- - projects.each_with_index do |project, i|
- %div.grid_1.projects_selector
- %div{ :class => "project-box ui-box ui-box-big" }
- = link_to project_path(project) do
- %h3= truncate(project.name, :length => 20)
+ .row
+ - projects.each_with_index do |project, i|
+ %div.project_tile
+ .title
+ = link_to project_path(project) do
+ %h3= truncate(project.name, :length => 28)
.data
- %p.title.repository.git_url_wrapper
- %span Repository:
+ %p
%input{ :value => project.url_to_repo, :class => ['git-url', 'one_click_select', 'text', 'project_list_url'], :readonly => 'readonly' }
- %p.title.activity
- %span Last Activity:
- - if project.last_activity_date_cached
- = project.last_activity_date_cached.stamp("Aug 24, 2011")
- - else
- Never
-
.buttons
- %a.browse-code.button.yellow{:href => tree_project_ref_path(project, project.root_ref)} Browse code
- %a.commits.button.green{:href => project_commits_path(project)} Commits
+ %a.btn.info{:href => tree_project_ref_path(project, project.root_ref)} Browse code
+ %a.btn{:href => project_commits_path(project)} Commits
diff --git a/app/views/projects/create.js.haml b/app/views/projects/create.js.haml
index c457527aed4..2b3106c8222 100644
--- a/app/views/projects/create.js.haml
+++ b/app/views/projects/create.js.haml
@@ -4,3 +4,4 @@
- else
:plain
$("#new_project").replaceWith("#{escape_javascript(render('form'))}");
+ $('.ajax_loader').hide();
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index 69e0f218ecd..be8aae7d712 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -1,69 +1,29 @@
= render "project_head"
-
-= form_for(@project, :remote => true) do |f|
- %div
- %span.entity-info
- = link_to info_project_path(@project) do
- .entity-button
- Info
- %i
- %h2= @project.name
- %hr
- %table.no-borders
- -if @project.errors.any?
- %tr
- %td{:colspan => 2}
- #error_explanation
- - @project.errors.full_messages.each do |msg|
- %span= msg
- %br
-
- %tr
- %td= f.label :name
- %td= f.text_field :name, :placeholder => "Example Project"
- %tr
- %td
- .left= f.label :path
- %cite.right= "git@#{GIT_HOST["host"]}:"
- %td
- = f.text_field :path, :placeholder => "example_project", :disabled => !@project.new_record?
- %tr
- %td
- .left= f.label :code
- %cite.right= "http://#{GIT_HOST["host"]}/"
- %td= f.text_field :code, :placeholder => "example"
-
- - unless @project.new_record? || @project.heads.empty?
- %tr
- %td= f.label :default_branch, "Default Branch"
- %td= f.select(:default_branch, @project.heads.map(&:name), {}, :style => "width:300px;")
-
- %tr
- %td= f.label :description
- %td= f.text_area :description, :placeholder => "project description", :style => "height:50px"
-
- %br
-
- .merge-tabs
- = f.submit 'Save', :class => "grey-button"
- &nbsp;
- - unless @project.new_record?
- .right
- = link_to 'Remove', @project, :confirm => 'Are you sure?', :method => :delete, :class => "red-button"
-
+%h3 Edit Project
+%hr
+= render "projects/form"
%div{ :class => "ajax_loader", :style => "display:none;height:200px;"}
%center
= image_tag "ajax-loader.gif", :class => "append-bottom"
- %h3.prepend-top Updating project &amp; repository. Please wait for few minutes
+ %h3.prepend-top Saving project &amp; repository. Please wait...
:javascript
- $('.edit_project').bind('ajax:before', function() {
- $(".edit_project").hide();
- $('.ajax_loader').show();
+ $(function(){
+ $("#project_name").live("change", function(){
+ var slug = slugify($(this).val());
+ $("#project_code").val(slug);
+ $("#project_path").val(slug);
+ });
});
-:javascript
+ function slugify(text) {
+ return text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase();
+ }
+
$(function(){
- $('#project_default_branch').chosen();
+ $('.edit_project').live('ajax:before', function() {
+ $(this).hide();
+ $('.ajax_loader').show();
+ });
+ $('form #project_default_branch').chosen();
})
-
diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml
index f089c6ec46b..5088c2e7297 100644
--- a/app/views/projects/empty.html.haml
+++ b/app/views/projects/empty.html.haml
@@ -1,20 +1,21 @@
- if current_user.require_ssh_key?
- %ul.errors_holder
- %li You have no ssh keys added yo tour profile.
- %li You wont be able to pull/push repository.
- %li Visit profile &rarr; keys and add public key of every machine you want to use for work with gitlabhq.
+ .alert-message.block-message.error
+ %ul
+ %li You have no ssh keys added to your profile.
+ %li You wont be able to pull/push repository.
+ %li Visit profile &rarr; keys and add public key of every machine you want to use for work with gitlabhq.
-
-%ul.alert_holder
- %li You should push repository to proceed.
- %li After push you will be able to browse code, commits etc.
+.alert-message.block-message.error
+ %ul.alert_holder
+ %li You should push repository to proceed.
+ %li After push you will be able to browse code, commits etc.
- bash_lexer = Pygments::Lexer[:bash]
%div.git-empty
%h3 Git global setup:
- setup_str = ["git config --global user.name \"#{current_user.name}\"",
"git config --global user.email \"#{current_user.email}\""].join("\n")
- = raw bash_lexer.highlight(setup_str)
+ = raw bash_lexer.highlight(setup_str, :lexer => 'bash', :options => {:encoding => 'utf-8'})
%br
%br
diff --git a/app/views/projects/files.html.haml b/app/views/projects/files.html.haml
index 8ea4ac8a130..48ceece772c 100644
--- a/app/views/projects/files.html.haml
+++ b/app/views/projects/files.html.haml
@@ -1,16 +1,17 @@
= render "project_head"
- unless @notes.empty?
- %div.update-data.ui-box.ui-box-small
- .data
- - @notes.each do |note|
- %a.update-item{:href => note.attachment.url}
- = image_tag gravatar_icon(note.author_email), :class => "left", :width => 16
- %span.update-title{:style => "margin-bottom:0px;"}
+ %table.zebra-striped.borders
+ - @notes.each do |note|
+ %tr
+ %td
+ %a{:href => note.attachment.url}
+ = image_tag gravatar_icon(note.author_email), :class => "left", :width => 16
+ &nbsp;
= note.attachment_identifier
- %span.update-author.right
- Added
- = time_ago_in_words(note.created_at)
- ago
+ %td
+ Added
+ = time_ago_in_words(note.created_at)
+ ago
- else
.notice_holder
%li All files attached to project wall, issues etc will be displayed here
diff --git a/app/views/projects/graph.html.haml b/app/views/projects/graph.html.haml
index 9dc973d7a46..394a11fdc47 100644
--- a/app/views/projects/graph.html.haml
+++ b/app/views/projects/graph.html.haml
@@ -1,8 +1,6 @@
-.top-tabs
- = link_to graph_project_path(@project), :class => "tab #{'active' if current_page?(graph_project_path(@project)) }" do
- %span
- Network Graph
-#holder.graph
+%h3 Network Graph
+%br
+#holder.graph.well
:javascript
var chunk1={commits:#{@commits_json}};
diff --git a/app/views/projects/index.html.haml b/app/views/projects/index.html.haml
index 8a4343b05ef..3838c3398a7 100644
--- a/app/views/projects/index.html.haml
+++ b/app/views/projects/index.html.haml
@@ -1,29 +1,23 @@
-- content_for(:body_class, "projects-page")
-.container_4
- .grid_4
- - if current_user.can_create_project?
- %a.grey-button.right{:href => new_project_path} Create new project
- %h2.icon
- %span
- Projects
+%h3
+ Projects
+ %small= "( #{current_user.projects.count} )"
+ - if current_user.can_create_project?
+ %span.right
+ = link_to new_project_path, :class => "btn small" do
+ New Project
+%hr
+- unless @projects.empty?
+ %div.content_list= render "tile"
- %div.clear
- - unless @projects.empty?
- %div{:class => "tile"}
- = render "tile"
+ -# If projects requris paging
+ -# We add ajax loader & init script
+ - if @projects.count == @limit
+ .loading{ :style => "display:none;"}
+ %center= image_tag "ajax-loader.gif"
- -# If projects requris paging
- -# We add ajax loader & init script
- - if @projects.count == @limit
- .clear
- .loading{ :style => "display:none;"}
- %center= image_tag "ajax-loader.gif"
-
- :javascript
- $(function(){
- ProjectsList.init(16);
- });
- - else
- %center.prepend-top
- %h2
- %cite Nothing here
+ :javascript
+ $(function(){
+ Pager.init(#{@limit});
+ });
+- else
+ %h2 Nothing here
diff --git a/app/views/projects/index.js.haml b/app/views/projects/index.js.haml
index 25da7cb4202..15bbd9730d0 100644
--- a/app/views/projects/index.js.haml
+++ b/app/views/projects/index.js.haml
@@ -1,2 +1,2 @@
:plain
- ProjectsList.append(#{@projects.count}, "#{escape_javascript(render(:partial => 'projects/tile'))}");
+ Pager.append(#{@projects.count}, "#{escape_javascript(render(:partial => 'projects/tile'))}");
diff --git a/app/views/projects/info.html.haml b/app/views/projects/info.html.haml
deleted file mode 100644
index 787ad06d30e..00000000000
--- a/app/views/projects/info.html.haml
+++ /dev/null
@@ -1,28 +0,0 @@
-= render "project_head"
-
-%div
- %span.entity-info
- = link_to edit_project_path(@project) do
- .entity-button
- Edit
- %i
- %h2= @project.name
- %hr
-
-%table.no-borders
- %tr
- %td Name
- %td= @project.name
-
- %tr
- %td Slug
- %td= @project.code
-
- %tr
- %td Created
- %td= @project.created_at.stamp("Aug 21, 2011")
-
- %tr
- %td{:colspan => 2}= simple_format @project.description
-
-
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index 02ddc683851..5883e7b8890 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -1,17 +1,14 @@
-- content_for(:body_class, "new-project-page")
-- content_for(:page_title) do
- .new-project-hodler
- .container
- %h2.icon
- %span
- New Project
-
- %div.clear
- = render 'form'
+%h3 New Project
+%hr
+= render 'form'
+%div{ :class => "ajax_loader", :style => "display:none;height:200px;"}
+ %center
+ = image_tag "ajax-loader.gif", :class => "append-bottom"
+ %h3.prepend-top Creating project &amp; repository. Please wait for few minutes
:javascript
$(function(){
- $("#project_name").change(function(){
+ $("#project_name").live("change", function(){
var slug = slugify($(this).val());
$("#project_code").val(slug);
$("#project_path").val(slug);
@@ -21,3 +18,11 @@
function slugify(text) {
return text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase();
}
+
+ $(function(){
+ $('.new_project').live('ajax:before', function() {
+ $(this).hide();
+ $('.ajax_loader').show();
+ });
+ $('form #project_default_branch').chosen();
+ })
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index 2eb220b589a..5fbed303da8 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -1,13 +1,22 @@
-- content_for(:body_class, "project-page dashboard")
-
= render "project_head"
-#news-feed.news-feed
- .project-box.project-updates
- - @activities.each do |update|
- = render "projects/feed", :update => update, :project => @project
+%h3
+ = @project.name
+ - if can? current_user, :download_code, @project
+ = link_to "Download", archive_project_repository_path(@project), :class => "btn small right"
+.back_link
+ = link_to projects_path do
+ &larr; To projects list
+%br
+.alert-message.block-message.warning
+ .input
+ .input-prepend
+ %span.add-on git clone
+ = text_field_tag :project_clone, @project.url_to_repo, :class => "xlarge one_click_select git_clone_url"
+
+= simple_format @project.description
+- unless @activities.blank?
+ .ui-box
+ %h5.cgray Recent Activity
+ .content_list= render "feed"
+
-:javascript
- function updateDashboard(){
- $('.project-content').load("#{escape_javascript(project_path(@project))} .project-content>*");
- }
- setInterval("updateDashboard()", 300000);
diff --git a/app/views/projects/team.html.haml b/app/views/projects/team.html.haml
index 295e212fbaa..7f2d6dccfe4 100644
--- a/app/views/projects/team.html.haml
+++ b/app/views/projects/team.html.haml
@@ -1,3 +1,12 @@
= render "project_head"
+
+- if can? current_user, :admin_team_member, @project
+ .alert-message.block-message
+ = link_to new_project_team_member_path(@project), :class => "btn small right", :title => "New Team Member" do
+ New Team Member
+ %p Read more about project permissions #{link_to "here", help_permissions_path, :class => "vlink"}
+ %p To open team member profile - click on avatar.
+
+
= render :partial => "team", :locals => {:project => @project}
diff --git a/app/views/projects/update.js.haml b/app/views/projects/update.js.haml
index 70d8490ebe2..de12527e004 100644
--- a/app/views/projects/update.js.haml
+++ b/app/views/projects/update.js.haml
@@ -1,6 +1,7 @@
- if @project.valid?
:plain
- location.href = "#{info_project_path(@project, :notice => 'Project was successfully updated.')}";
+ location.href = "#{edit_project_path(@project, :notice => 'Project was successfully updated.')}";
- else
:plain
$(".edit_project").replaceWith("#{escape_javascript(render('form'))}");
+ $('.ajax_loader').hide();
diff --git a/app/views/projects/wall.html.haml b/app/views/projects/wall.html.haml
index 4f0ec41ee92..bd538e8f971 100644
--- a/app/views/projects/wall.html.haml
+++ b/app/views/projects/wall.html.haml
@@ -1,6 +1,2 @@
%div.wall_page
- = render "notes/notes"
-
-.loading{ :style => "display:none;"}
- %center= image_tag "ajax-loader.gif"
-
+ = render "notes/notes", :tid => nil, :tt => "wall"
diff --git a/app/views/projects/wall.js.haml b/app/views/projects/wall.js.haml
deleted file mode 100644
index ee31c0b8d3c..00000000000
--- a/app/views/projects/wall.js.haml
+++ /dev/null
@@ -1 +0,0 @@
-= render "notes/load"
diff --git a/app/views/protected_branches/index.html.haml b/app/views/protected_branches/index.html.haml
new file mode 100644
index 00000000000..de04cc08906
--- /dev/null
+++ b/app/views/protected_branches/index.html.haml
@@ -0,0 +1,55 @@
+= render "repositories/branches_head"
+
+.alert-message.block-message
+ %p Protected branches designed to prevent push for all except #{link_to "masters", help_permissions_path, :class => "vlink"}.
+ %p This ability allows:
+ %ul
+ %li keep stable branches secured
+ %li forced code review before merge to protected branches
+ %p Read more about project permissions #{link_to "here", help_permissions_path, :class => "vlink"}
+
+
+
+- unless @branches.empty?
+ %table.zebra-striped
+ %thead
+ %tr
+ %th Name
+ %th Last commit
+ %th
+ %tbody
+ - @branches.each do |branch|
+ %tr
+ %td
+ = link_to project_commits_path(@project, :ref => branch.name) do
+ %strong= branch.name
+ - if branch.name == @project.root_ref
+ %span.label default
+ %td
+ = link_to project_commits_path(@project, branch.commit.id) do
+ = truncate branch.commit.id.to_s, :length => 10
+ = time_ago_in_words(branch.commit.committed_date)
+ ago
+ %td
+ - if can? current_user, :admin_project, @project
+ = link_to 'Unprotect', [@project, branch], :confirm => 'Are you sure?', :method => :delete, :class => "danger btn small"
+
+
+
+- if can? current_user, :admin_project, @project
+ = form_for [@project, @protected_branch] do |f|
+ -if @protected_branch.errors.any?
+ .alert-message.block-message.error
+ %ul
+ - @protected_branch.errors.full_messages.each do |msg|
+ %li= msg
+
+ .clearfix
+ = f.label :name
+ .input= f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , { :include_blank => "Select branch" }, { :style => "width:300px" })
+ .actions
+ = f.submit 'Add', :class => "primary btn"
+
+
+:javascript
+ $('select#protected_branch_name').chosen();
diff --git a/app/views/refs/_submodule_item.html.haml b/app/views/refs/_submodule_item.html.haml
new file mode 100644
index 00000000000..6db49310a08
--- /dev/null
+++ b/app/views/refs/_submodule_item.html.haml
@@ -0,0 +1,13 @@
+- url = content.url(@ref) rescue nil
+- name = content.basename
+- return unless url
+%tr{ :class => "tree-item", :url => url }
+ %td.tree-item-file-name
+ = image_tag "submodule.png"
+ %strong= truncate(name, :length => 40)
+ %td
+ %code= content.id[0..10]
+ %td
+ = link_to truncate(url, :length => 40), url
+
+
diff --git a/app/views/refs/_tree.html.haml b/app/views/refs/_tree.html.haml
index 0ab69574cee..e5908676ae8 100644
--- a/app/views/refs/_tree.html.haml
+++ b/app/views/refs/_tree.html.haml
@@ -1,19 +1,19 @@
-#tree-breadcrumbs
- %div
+%ul.breadcrumb
+ %li
+ %span.arrow
= link_to tree_project_ref_path(@project, @ref, :path => nil), :remote => true do
- = @project.code
- - tree.breadcrumbs(6) do |link|
- \/
- = link
- &nbsp;
- %span.tree_progress
+ = @project.name
+ - tree.breadcrumbs(6) do |link|
+ \/
+ %li= link
.clear
+%div.tree_progress
#tree-content-holder
- if tree.is_blob?
= render :partial => "refs/tree_file", :locals => { :name => tree.name, :content => tree.data, :file => tree }
- else
- contents = tree.contents
- %table#tree-slider.no-borders
+ %table#tree-slider.bordered-table
%thead
%th Name
%th Last Update
@@ -33,6 +33,8 @@
= render :partial => "refs/tree_item", :locals => { :content => content }
- contents.select{ |i| i.is_a?(Grit::Blob)}.each do |content|
= render :partial => "refs/tree_item", :locals => { :content => content }
+ - contents.select{ |i| i.is_a?(Grit::Submodule)}.each do |content|
+ = render :partial => "refs/submodule_item", :locals => { :content => content }
- if content = contents.select{ |c| c.is_a?(Grit::Blob) and c.name =~ /^readme/i }.first
#tree-readme-holder
@@ -43,12 +45,20 @@
- else
= simple_format(content.data)
+- if params[:path]
+ - history_path = tree_file_project_ref_path(@project, @ref, params[:path])
+- else
+ - history_path = tree_project_ref_path(@project, @ref)
:javascript
$(function(){
$('select#branch').selectmenu({style:'popup', width:200});
$('select#tag').selectmenu({style:'popup', width:200});
+ $('.project-refs-select').chosen();
+
+ history.pushState({ path: this.path }, '', "#{history_path}")
});
+
- if params[:path] && request.xhr?
:javascript
$(window).unbind('popstate');
diff --git a/app/views/refs/_tree_file.html.haml b/app/views/refs/_tree_file.html.haml
index 8b9a45c804b..78662229afa 100644
--- a/app/views/refs/_tree_file.html.haml
+++ b/app/views/refs/_tree_file.html.haml
@@ -1,13 +1,13 @@
:css
.view_file
.view_file_header
- %strong
- %span.file_icon= image_tag "txt.png"
- %span.mode_text= file.mode
- %span.file_name= name
- = link_to "raw", blob_project_ref_path(@project, @ref, :path => params[:path] ), :class => "right", :target => "_blank"
- = link_to "history", project_commits_path(@project, :path => params[:path], :ref => @ref ), :class => "right", :style => "margin-right:10px;"
- %br/
+ .row
+ .span1.file_icon= image_tag "txt.png"
+ .span2.mode_text= file.mode
+ .span7.file_name= name
+ .span4.right
+ = link_to "raw", blob_project_ref_path(@project, @ref, :path => params[:path] ), :class => "right", :target => "_blank"
+ = link_to "history", project_commits_path(@project, :path => params[:path], :ref => @ref ), :class => "right", :style => "margin-right:10px;"
- if file.text?
.view_file_content
- unless file.empty?
diff --git a/app/views/refs/_tree_item.html.haml b/app/views/refs/_tree_item.html.haml
index 73385514cd0..420307c7635 100644
--- a/app/views/refs/_tree_item.html.haml
+++ b/app/views/refs/_tree_item.html.haml
@@ -14,5 +14,5 @@
%td.commit
- tm = @project.team_member_by_name_or_email(content_commit.author_email, content_commit.author_name)
- if tm
- = link_to "[#{tm.user_name}]", project_team_member_path(@project, tm)
- = link_to truncate(content_commit.safe_message, :length => tm ? 20 : 40), project_commit_path(@project, content_commit.id), :class => "tree-commit-link"
+ %strong= link_to "[#{tm.user_name}]", project_team_member_path(@project, tm)
+ = link_to truncate(content_commit.safe_message, :length => tm ? 30 : 50), project_commit_path(@project, content_commit.id), :class => "tree-commit-link"
diff --git a/app/views/refs/tree.html.haml b/app/views/refs/tree.html.haml
index 46eeb6f5c29..ece6f188c97 100644
--- a/app/views/refs/tree.html.haml
+++ b/app/views/refs/tree.html.haml
@@ -1,3 +1,13 @@
+%ul.tabs
+ %li
+ = form_tag switch_project_refs_path(@project), :method => :get, :class => "project-refs-form", :remote => true do
+ = select_tag "ref", grouped_options_refs, :onchange => "$(this.form).trigger('submit');", :class => "project-refs-select"
+ = hidden_field_tag :destination, "tree"
+ = hidden_field_tag :path, params[:path]
+ %li{:class => "#{'active' if (controller.controller_name == "refs") }"}
+ = link_to tree_project_ref_path(@project, @ref) do
+ Code
+
#tree-holder= render :partial => "tree", :locals => {:repo => @repo, :commit => @commit, :tree => @tree}
:javascript
diff --git a/app/views/repositories/_branch.html.haml b/app/views/repositories/_branch.html.haml
new file mode 100644
index 00000000000..04f64fd5240
--- /dev/null
+++ b/app/views/repositories/_branch.html.haml
@@ -0,0 +1,20 @@
+%tr
+ %td
+ = link_to project_commits_path(@project, :ref => branch.name) do
+ %strong= branch.name
+ - if branch.name == @project.root_ref
+ %span.label default
+ %td
+ = link_to project_commit_path(@project, branch.commit.id) do
+ %code= branch.commit.id.to_s[0..10]
+
+ = image_tag gravatar_icon(Commit.new(branch.commit).author_email), :class => "", :width => 16
+ = truncate(Commit.new(branch.commit).safe_message, :length => 40)
+ %td
+ %span.update-author.right
+ = time_ago_in_words(branch.commit.committed_date)
+ ago
+ %td
+ - if can? current_user, :download_code, @project
+ = link_to "Download", archive_project_repository_path(@project, :ref => branch.name), :class => "visible_link download_repo_link"
+
diff --git a/app/views/repositories/_branches_head.html.haml b/app/views/repositories/_branches_head.html.haml
new file mode 100644
index 00000000000..9a189498413
--- /dev/null
+++ b/app/views/repositories/_branches_head.html.haml
@@ -0,0 +1,12 @@
+= render "commits/head"
+%ul.pills
+ %li{:class => ("active" if current_page?(project_repository_path(@project)))}
+ = link_to project_repository_path(@project) do
+ Recent
+ %li{:class => ("active" if current_page?(project_protected_branches_path(@project)))}
+ = link_to project_protected_branches_path(@project) do
+ Protected
+ %li{:class => ("active" if current_page?(branches_project_repository_path(@project)))}
+ = link_to branches_project_repository_path(@project) do
+ All
+%hr
diff --git a/app/views/repositories/_feed.html.haml b/app/views/repositories/_feed.html.haml
index f163b477d2c..9fdba10b926 100644
--- a/app/views/repositories/_feed.html.haml
+++ b/app/views/repositories/_feed.html.haml
@@ -1,15 +1,19 @@
-%a.project-update.titled{:href => project_commits_path(project, :ref => update.head.name)}
- = image_tag gravatar_icon(update.author_email), :class => "left", :width => 40
- %span.update-title
- = dashboard_feed_title(update)
- %span.update-author
- %strong= update.author_name
- authored
- = time_ago_in_words(update.created_at)
- ago
- .title-block
- %span.update-title
- %span.commit.tag= update.head.name
- %span.update-author
- .left= truncate update.commit.id
+- commit = update
+%tr
+ %td
+ = link_to project_commits_path(@project, :ref => commit.head.name) do
+ %strong
+ = commit.head.name
+ - if commit.head.name == @project.root_ref
+ %span.label default
+ %td
+ %div
+ = link_to project_commits_path(@project, commit.id) do
+ %code= commit.id.to_s[0..10]
+ = image_tag gravatar_icon(commit.author_email), :class => "", :width => 16
+ = truncate(commit.safe_message, :length => 40)
+ %td
+ %span.right.cgray
+ = time_ago_in_words(commit.committed_date)
+ ago
diff --git a/app/views/repositories/_head.html.haml b/app/views/repositories/_head.html.haml
index 0095098e894..bc96f306eee 100644
--- a/app/views/repositories/_head.html.haml
+++ b/app/views/repositories/_head.html.haml
@@ -1,28 +1 @@
-.top-tabs.repository
- = link_to project_repository_path(@project), :class => "activities-tab tab #{'active' if current_page?(project_repository_path(@project)) }" do
- %span
- Activities
- = link_to branches_project_repository_path(@project), :class => "tab #{'active' if current_page?(branches_project_repository_path(@project)) }" do
- %span
- Branches
- = link_to tags_project_repository_path(@project), :class => "tab #{'active' if current_page?(tags_project_repository_path(@project)) }" do
- %span
- Tags
- = link_to project_hooks_path, :class => "tab #{'active' if controller.controller_name == "hooks" }" do
- %span
- Hooks
- - if can? current_user, :admin_project, @project
- = link_to project_deploy_keys_path(@project), :class => "tab #{'active' if controller.controller_name == "deploy_keys"}" do
- %span
- Deploy Keys
-
- - if current_page?(project_hooks_path(@project))
- - if can? current_user, :admin_project, @project
- = link_to new_project_hook_path(@project), :class => "add_new", :title => "New Web Hook" do
- Add new
-
- - if current_page?(project_deploy_keys_path(@project))
- - if can? current_user, :admin_project, @project
- = link_to new_project_deploy_key_path(@project), :class => "add_new", :title => "New Deploy Key" do
- Add new
-
+= render "projects/project_head"
diff --git a/app/views/repositories/branches.html.haml b/app/views/repositories/branches.html.haml
index befa88cc8d0..c56b54d5349 100644
--- a/app/views/repositories/branches.html.haml
+++ b/app/views/repositories/branches.html.haml
@@ -1,13 +1,6 @@
-= render "head"
+= render "repositories/branches_head"
- unless @branches.empty?
- %div.update-data.ui-box.ui-box-small
- .data
+ %table.zebra-striped.borders
+ %tbody
- @branches.each do |branch|
- %a.update-item{:href => project_commits_path(@project, :ref => branch.name)}
- %span.update-title{:style => "margin-bottom:0px;"}
- = branch.name
- %span.update-author.right
- = time_ago_in_words(branch.commit.committed_date)
- ago
-- else
- %h3 No brances
+ = render "repositories/branch", :branch => branch
diff --git a/app/views/repositories/show.html.haml b/app/views/repositories/show.html.haml
index 3c9208cbd4b..43514551420 100644
--- a/app/views/repositories/show.html.haml
+++ b/app/views/repositories/show.html.haml
@@ -1,8 +1,6 @@
-- content_for(:body_class, "project-page dashboard")
-= render "head"
+= render "branches_head"
-#news-feed.news-feed
- .project-box.project-updates
- - @activities.each do |update|
- = render "repositories/feed", :update => update, :project => @project
+%table.zebra-striped.borders
+ - @activities.each do |update|
+ = render "repositories/branch", :branch => update.head
diff --git a/app/views/repositories/tags.html.haml b/app/views/repositories/tags.html.haml
index bff838fa7f0..16113853438 100644
--- a/app/views/repositories/tags.html.haml
+++ b/app/views/repositories/tags.html.haml
@@ -1,13 +1,23 @@
-= render "head"
+= render "commits/head"
- unless @tags.empty?
- %div.update-data.ui-box.ui-box-small
- .data
- - @tags.each do |tag|
- %a.update-item{:href => project_commits_path(@project, :ref => tag.name)}
- %span.update-title{:style => "margin-bottom:0px;"}
- = tag.name
- %span.update-author.right
- = time_ago_in_words(tag.commit.committed_date)
- ago
+ %table.zebra-striped.borders
+ - @tags.each do |tag|
+ %tr
+ %td
+ %strong= link_to tag.name, project_commits_path(@project, :ref => tag.name), :class => ""
+ %td
+ = link_to project_commits_path(@project, tag.commit.id) do
+ %code= tag.commit.id.to_s[0..10]
+ = image_tag gravatar_icon(Commit.new(tag.commit).author_email), :class => "", :width => 16
+ = truncate(Commit.new(tag.commit).safe_message, :length => 40)
+ %td
+ %span.update-author.right
+ = time_ago_in_words(tag.commit.committed_date)
+ ago
+ &nbsp;
+ %td
+ - if can? current_user, :download_code, @project
+ = link_to "Download", archive_project_repository_path(@project, :ref => tag.name), :class => "visible_link download_repo_link"
+
- else
%h3 No tags
diff --git a/app/views/snippets/_form.html.haml b/app/views/snippets/_form.html.haml
index 63ba3512e64..a0a00556030 100644
--- a/app/views/snippets/_form.html.haml
+++ b/app/views/snippets/_form.html.haml
@@ -1,48 +1,31 @@
+%h3= @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}"
+%hr
= form_for [@project, @snippet] do |f|
- %div
- %span.entity-info
- - if @snippet.new_record?
- = link_to project_snippets_path(@project) do
- .entity-button
- Snippets
- %i
- - else
- = link_to project_snippet_path(@project, @snippet) do
- .entity-button
- Show Snippet
- %i
- %h2= @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}"
-
- %hr
%table.no-borders
-if @snippet.errors.any?
- %tr
- %td{:colspan => 2}
- #error_explanation
- - @snippet.errors.full_messages.each do |msg|
- %span= msg
- %br
+ .alert-message.block-message.error
+ %ul
+ - @snippet.errors.full_messages.each do |msg|
+ %li= msg
- %tr
- %td= f.label :title
- %td= f.text_field :title, :placeholder => "Example Snippet"
- %tr
- %td= f.label :file_name
- %td= f.text_field :file_name, :placeholder => "example.rb"
- %tr
- %td= f.label "Lifetime"
- %td= f.select :expires_at, lifetime_select_options, {}, :style => "width:200px;"
- %tr
- %td{:colspan => 2}
- = f.label :content, "Code"
- %br
- %br
- = f.text_area :content
+ .clearfix
+ = f.label :title
+ .input= f.text_field :title, :placeholder => "Example Snippet"
+ .clearfix
+ = f.label :file_name
+ .input= f.text_field :file_name, :placeholder => "example.rb"
+ .clearfix
+ = f.label "Lifetime"
+ .input= f.select :expires_at, lifetime_select_options, {}, :style => "width:200px;"
+ .clearfix
+ = f.label :content, "Code"
+ = f.text_area :content, :class => "xxlarge"
- .merge-tabs
- = f.submit 'Save', :class => "positive-button"
+ .actions
+ = f.submit 'Save', :class => "primary btn"
+ = link_to "Cancel", project_snippets_path(@project), :class => " btn"
- unless @snippet.new_record?
- .right= link_to 'Destroy', [@project, @snippet], :confirm => 'Are you sure?', :method => :delete, :class => "red-button delete-snippet", :id => "destroy_snippet_#{@snippet.id}"
+ .right= link_to 'Destroy', [@project, @snippet], :confirm => 'Are you sure?', :method => :delete, :class => "btn right danger delete-snippet", :id => "destroy_snippet_#{@snippet.id}"
diff --git a/app/views/snippets/_snippet.html.haml b/app/views/snippets/_snippet.html.haml
index f8a483085ea..d6002362a15 100644
--- a/app/views/snippets/_snippet.html.haml
+++ b/app/views/snippets/_snippet.html.haml
@@ -1,12 +1,6 @@
-%a.update-item{:href => project_snippet_path(snippet.project, snippet)}
- = image_tag gravatar_icon(snippet.author_email), :class => "left", :width => 40
- %span.update-title
- = truncate(snippet.title, :length => 60)
- %span.update-author
- %strong= snippet.author_name
- authored
- = time_ago_in_words(snippet.created_at)
- ago
- .right
- %span.tag.commit= snippet.file_name
-
+%tr
+ %td
+ %a{:href => project_snippet_path(snippet.project, snippet)}
+ = truncate(snippet.title, :length => 60)
+ %span.right.cgray
+ = snippet.file_name
diff --git a/app/views/snippets/edit.html.haml b/app/views/snippets/edit.html.haml
index f81c0b8bc64..8afaf46e95d 100644
--- a/app/views/snippets/edit.html.haml
+++ b/app/views/snippets/edit.html.haml
@@ -1 +1,2 @@
+= render "projects/project_head"
= render "snippets/form"
diff --git a/app/views/snippets/index.html.haml b/app/views/snippets/index.html.haml
index 1021dd1f597..762265f16b3 100644
--- a/app/views/snippets/index.html.haml
+++ b/app/views/snippets/index.html.haml
@@ -1,12 +1,12 @@
= render "projects/project_head"
+- if can? current_user, :write_snippet, @project
+ .alert-message.block-message
+ = link_to new_project_snippet_path(@project), :class => "btn small add_new right", :title => "New Snippet" do
+ Add new snippet
+ Share code pastes with others if it cant be in a git repository
+ %br
+ To add new snippet - click on button.
+
- unless @snippets.fresh.empty?
- %div{ :class => "update-data ui-box ui-box-small ui-box-big" }
- .data
- = render @snippets.fresh
-- else
- .notice_holder
- %li Snippets do not exist yet.
- - if can? current_user, :write_snippet, @project
- %li You can add a new one by clicking on "Add New" button
-
+ %table.zebra-striped.borders= render @snippets.fresh
diff --git a/app/views/snippets/new.html.haml b/app/views/snippets/new.html.haml
index f81c0b8bc64..8afaf46e95d 100644
--- a/app/views/snippets/new.html.haml
+++ b/app/views/snippets/new.html.haml
@@ -1 +1,2 @@
+= render "projects/project_head"
= render "snippets/form"
diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml
index 59f810a77a3..6e8ee762337 100644
--- a/app/views/snippets/show.html.haml
+++ b/app/views/snippets/show.html.haml
@@ -1,20 +1,10 @@
-%div
- %span.entity-info
- - if can?(current_user, :admin_snippet, @project) || @snippet.author == current_user
- = link_to edit_project_snippet_path(@project, @snippet) do
- .entity-button
- Edit Snippet
- %i
- - if @snippet.author_email
- = image_tag gravatar_icon(@snippet.author_email), :class => "left", :width => 40, :style => "padding-right:5px;"
- - else
- = image_tag "no_avatar.png", :class => "left", :width => 40, :style => "padding-right:5px;"
- %span.commit-title
- %strong
- = truncate(@snippet.title, :length => 60)
- %span.commit-author
- %strong= @snippet.author_name
- = @snippet.created_at.stamp("Aug 21, 2011 9:23pm")
+= render "projects/project_head"
+
+%h3
+ = @snippet.title
+ %small= @snippet.file_name
+ - if can?(current_user, :admin_snippet, @project) || @snippet.author == current_user
+ = link_to "Edit", edit_project_snippet_path(@project, @snippet), :class => "btn small right"
%hr
@@ -24,8 +14,5 @@
.data.no-padding
:erb
<%= raw @snippet.colorize %>
-.clear
-%br
-.snippet_notes= render "notes/notes"
-.clear
+= render "notes/notes", :tid => @snippet.id, :tt => "snippet"
diff --git a/app/views/tags/index.html.haml b/app/views/tags/index.html.haml
deleted file mode 100644
index b7f422ad2c0..00000000000
--- a/app/views/tags/index.html.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-- content_for(:body_class, "projects-page")
-- content_for(:page_title) do
- .grid_4
- %h2
- Tags
-
- .tags-list
- - @tags.all.each do |tag|
- = link_to "#{tag.name}(#{tag.count})", tag_path(name)
-
diff --git a/app/views/team_members/_form.html.haml b/app/views/team_members/_form.html.haml
index 2a299fd0ba3..281776de036 100644
--- a/app/views/team_members/_form.html.haml
+++ b/app/views/team_members/_form.html.haml
@@ -1,33 +1,33 @@
+%h3= "New Team member"
+%hr
= form_for @team_member, :as => :team_member, :url => project_team_members_path(@project, @team_member) do |f|
- %div
- %span.entity-info
- - if request.xhr?
- = link_to project_team_members_path(@project) do
- .entity-button
- Team List
- %i
- %h3= "New Team member"
-
- %hr
-if @team_member.errors.any?
- %ul.errors_holder
- - @team_member.errors.full_messages.each do |msg|
- %li= msg
+ .alert-message.block-message.error
+ %ul
+ - @team_member.errors.full_messages.each do |msg|
+ %li= msg
+
+ .clearfix
+ = f.label :user_id, "Name"
+ .input= f.select(:user_id, User.not_in_project(@project).all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select user" }, { :style => "width:300px" })
+
+
+ .clearfix
+ = f.label :project_access, "Project Access"
+ .input= f.select :project_access, options_for_select(Project.access_options, @team_member.project_access), {}, :class => "project-access-select"
+
- .span-6.append-bottom
- %b Name
- .span-6
- = f.select(:user_id, User.not_in_project(@project).all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select user" }, { :style => "width:300px" })
- .span-6
- %b Project Access:
- .span-6
- = f.select :project_access, options_for_select(Project.access_options, @team_member.project_access), {}, :class => "project-access-select"
+ .actions
+ = f.submit 'Save', :class => "btn primary"
+ = link_to "Cancel", team_project_path(@project), :class => "btn"
- .span-6
- %b Repository Access:
- .span-6
- = f.select :repo_access, options_for_select(Repository.access_options, @team_member.repo_access), {}, :class => "repo-access-select"
- %br
- .merge-tabs
- = f.submit 'Save', :class => "grey-button"
+:css
+ form select {
+ width:300px;
+ }
+:javascript
+ $('select#team_member_user_id').chosen();
+ $('select#team_member_project_access').chosen();
+ //$('select#team_member_repo_access').chosen();
+ //$('select#team_member_project_access').chosen();
diff --git a/app/views/team_members/_show.html.haml b/app/views/team_members/_show.html.haml
index b0e8f17204f..febdef1dd58 100644
--- a/app/views/team_members/_show.html.haml
+++ b/app/views/team_members/_show.html.haml
@@ -1,19 +1,16 @@
- user = member.user
- allow_admin = can? current_user, :admin_project, @project
-%tr{:id => dom_id(member)}
- %td
- = link_to image_tag(gravatar_icon(user.email), :class => "left", :width => 40, :style => "padding:0 5px;"), project_team_member_path(@project, member)
+%li{:id => dom_id(member), :class => "team_member_row"}
+ = link_to project_team_member_path(@project, member), :title => user.name do
+ = image_tag gravatar_icon(user.email, 60), :class => "thumbnail"
+ .row
+ .span8
+ %h4
+ = truncate(user.name, :lenght => 24)
+ %small= truncate user.email, :lenght => 24
- = link_to truncate(user.name, :lenght => 24), project_team_member_path(@project, member)
- %br
- .cgray{:style => "padding-top:10px;"}= truncate user.email, :lenght => 24
- %td
+ .span3
= form_for(member, :as => :team_member, :url => project_team_member_path(@project, member)) do |f|
- = f.select :project_access, options_for_select(Project.access_options, member.project_access), {}, :class => "project-access-select", :disabled => !allow_admin
- %td
- = form_for(member, :as => :team_member, :url => project_team_member_path(@project, member)) do |f|
- = f.select :repo_access, options_for_select(Repository.access_options, member.repo_access), {}, :class => "repo-access-select", :disabled => !allow_admin
- - if allow_admin
- %td
- = link_to 'Cancel', project_team_member_path(:project_id => @project, :id => member.id), :confirm => 'Are you sure?', :method => :delete, :class => "grey-button negative delete-team-member", :remote => true
-
+ = f.select :project_access, options_for_select(UsersProject.access_roles, member.project_access), {}, :class => "medium project-access-select", :disabled => !allow_admin
+ - if @project.owner == user
+ %span.label Project Owner
diff --git a/app/views/team_members/create.js.haml b/app/views/team_members/create.js.haml
index 2f1d6108312..bfe8ca0d931 100644
--- a/app/views/team_members/create.js.haml
+++ b/app/views/team_members/create.js.haml
@@ -1,13 +1,13 @@
- if @team_member.valid?
:plain
- $("#team_member_new").hide("slide", { direction: "right" }, 150, function(){
+ $("#new_team_member").hide("slide", { direction: "right" }, 150, function(){
$("#team-table").show("slide", { direction: "left" }, 150, function() {
- $("#team_member_new").remove();
+ $("#new_team_member").remove();
$("#team-table").replaceWith("#{escape_javascript(render('projects/team'))}");
$(".add_new").show();
});
});
- else
:plain
- $("#team_member_new").replaceWith("#{escape_javascript(render('form'))}");
+ $("#new_team_member").replaceWith("#{escape_javascript(render('form'))}");
$('select#team_member_user_id').chosen();
diff --git a/app/views/team_members/show.html.haml b/app/views/team_members/show.html.haml
index 6293eee9789..d05ef740fb9 100644
--- a/app/views/team_members/show.html.haml
+++ b/app/views/team_members/show.html.haml
@@ -1,23 +1,19 @@
- allow_admin = can? current_user, :admin_project, @project
- user = @team_member.user
-%div
- %span.entity-info
- = link_to team_project_path(@project) do
- .entity-button
- Team
- %i
-
- = image_tag gravatar_icon(user.email), :class => "left", :width => 40, :style => "padding-right:5px;"
- %span.commit-title
- %strong
- = user.name
- %span.commit-author
- %strong
- = user.email
- %hr
- %br
-
-%table.no-borders
+.media-grid
+ = link_to "#" do
+ = image_tag gravatar_icon(user.email, 60), :class => "thumbnail", :width => 60
+ %h3.media_h
+ = user.name
+ %br
+ %small= user.email
+
+.back_link
+ = link_to team_project_path(@project), :class => "" do
+ &larr; To team list
+
+%br
+%table.zebra-striped.borders
%tr
%td Name
%td= user.name
@@ -31,17 +27,13 @@
%td= @team_member.created_at.stamp("Aug 21, 2011")
%tr
- %td Project Access
%td
- = form_for(@team_member, :as => :team_member, :url => project_team_member_path(@project, @team_member)) do |f|
- = f.select :project_access, options_for_select(Project.access_options, @team_member.project_access), {}, :class => "project-access-select", :disabled => !allow_admin
+ Project Access
+ (#{link_to "read more", help_permissions_path, :class => "vlink"})
- %tr
- %td Repository Access
%td
= form_for(@team_member, :as => :team_member, :url => project_team_member_path(@project, @team_member)) do |f|
- = f.select :repo_access, options_for_select(Repository.access_options, @team_member.repo_access), {}, :class => "repo-access-select", :disabled => !allow_admin
-
+ = f.select :project_access, options_for_select(Project.access_options, @team_member.project_access), {}, :class => "project-access-select", :disabled => !allow_admin
- unless user.skype.empty?
%tr
@@ -59,9 +51,8 @@
%td= user.twitter
- if can? current_user, :admin_project, @project
- .merge-tabs
- .right
- = link_to 'Remove from team', [@project, @issue], :confirm => 'Are you sure?', :method => :delete, :class => "red-button"
+ .actions
+ = link_to 'Remove from team', project_team_member_path(:project_id => @project, :id => @team_member.id), :confirm => 'Are you sure?', :method => :delete, :class => "btn danger"
:javascript
$(function(){
diff --git a/app/views/widgets/_project_member.html.haml b/app/views/widgets/_project_member.html.haml
new file mode 100644
index 00000000000..131853fa5af
--- /dev/null
+++ b/app/views/widgets/_project_member.html.haml
@@ -0,0 +1,54 @@
+- member = @project.team_member_by_id(current_user.id)
+.widget
+ .media-grid
+ %li
+ = link_to project_team_member_path(@project, member), :title => current_user.name do
+ = image_tag gravatar_icon(current_user.email, 60), :class => "thumbnail", :width => 60
+ %h4
+ Hey,
+ #{truncate current_user.first_name, :lenght => 24}!
+
+ %p
+ - if @project.issues_enabled
+ %span
+ Assigned Issues:
+ = current_user.assigned_issues.opened.count
+ %br
+ - if @project.merge_requests_enabled
+ %span
+ Assigned Requests:
+ = current_user.assigned_merge_requests.opened.count
+ %br
+ %br
+ - if @project.merge_requests_enabled && can?(current_user, :write_merge_request, @project)
+ = link_to new_project_merge_request_path(@project), :title => "New Merge Request", :class => "btn small padded" do
+ Merge Request
+ - if @project.issues_enabled && can?(current_user, :write_issue, @project)
+ = link_to new_project_issue_path(@project), :title => "New Issue", :class => "btn small" do
+ Issue
+
+ %hr
+ %p
+ Your access level in this project is
+ %code #{member.project_access_human}
+ %br
+ Visit member card for more information
+
+ .link_holder
+ = link_to project_team_member_path(@project, member), :title => current_user.name do
+ = "Member Card »"
+
+
+
+-#- if can? current_user, :write_project, @project
+ .widget
+ - if @project.issues_enabled && @project.merge_requests_enabled
+ .span3
+ %p You have access to create new issue or merge request.
+ %div
+ = link_to new_project_issue_path(@project), :title => "New Issue", :class => "" do
+ New Issue »
+ %div
+ = link_to new_project_merge_request_path(@project), :title => "New Merge Request", :class => "" do
+ New Merge Request »
+
diff --git a/app/views/widgets/_recent_projects.html.haml b/app/views/widgets/_recent_projects.html.haml
new file mode 100644
index 00000000000..7f1028bc683
--- /dev/null
+++ b/app/views/widgets/_recent_projects.html.haml
@@ -0,0 +1,11 @@
+- if current_user.projects.count > 0
+ %div.widget
+ %h4
+ Recent Projects:
+ %ul
+ - current_user.projects.order("id DESC").limit(5).each do |project|
+ %li
+ = link_to project_path(project) do
+ = project.name
+ .link_holder
+ = link_to "Projects » ", projects_path
diff --git a/app/views/wikis/_form.html.haml b/app/views/wikis/_form.html.haml
new file mode 100644
index 00000000000..55191250ceb
--- /dev/null
+++ b/app/views/wikis/_form.html.haml
@@ -0,0 +1,24 @@
+= form_for [@project, @wiki] do |f|
+ -if @wiki.errors.any?
+ #error_explanation
+ %h2= "#{pluralize(@wiki.errors.count, "error")} prohibited this wiki from being saved:"
+ %ul
+ - @wiki.errors.full_messages.each do |msg|
+ %li= msg
+
+ .alert-message.block-message.warning
+ %p
+ Wiki content is parsed with #{link_to "Markdown", "http://en.wikipedia.org/wiki/Markdown"}.
+ %br
+ To add link to new page you can just type
+ %code [Link Title](page-slug)
+ .clearfix
+ = f.label :title
+ .input= f.text_field :title, :class => :xxlarge
+ = f.hidden_field :slug
+ .clearfix
+ = f.label :content
+ .input= f.text_area :content, :class => :xxlarge
+ .actions
+ = f.submit 'Save', :class => "primary btn"
+ = link_to "Cancel", project_wiki_path(@project, :index), :class => "btn"
diff --git a/app/views/wikis/edit.html.haml b/app/views/wikis/edit.html.haml
new file mode 100644
index 00000000000..26cbd52a9a8
--- /dev/null
+++ b/app/views/wikis/edit.html.haml
@@ -0,0 +1,3 @@
+%h3 Editing page
+%hr
+= render 'form'
diff --git a/app/views/wikis/history.html.haml b/app/views/wikis/history.html.haml
new file mode 100644
index 00000000000..ad5a50b8136
--- /dev/null
+++ b/app/views/wikis/history.html.haml
@@ -0,0 +1,19 @@
+%h3 Versions
+%table
+ %thead
+ %tr
+ %th #
+ %th last edit
+ %th created by
+ %tbody
+ - @wikis.each_with_index do |wiki_page, i|
+ %tr
+ %td= i + 1
+ %td
+ = link_to wiki_page.created_at.to_s(:short), project_wiki_path(@project, wiki_page, :old_page_id => wiki_page.id)
+ (
+ = time_ago_in_words(wiki_page.created_at)
+ ago
+ )
+ %td= wiki_page.user.name
+
diff --git a/app/views/wikis/show.html.haml b/app/views/wikis/show.html.haml
new file mode 100644
index 00000000000..696f6ec753c
--- /dev/null
+++ b/app/views/wikis/show.html.haml
@@ -0,0 +1,16 @@
+%h3
+ = @wiki.title
+ %span.right
+ - if can? current_user, :write_wiki, @project
+ = link_to history_project_wiki_path(@project, @wiki), :class => "btn small padded" do
+ History
+ = link_to edit_project_wiki_path(@project, @wiki), :class => "btn small" do
+ Edit
+%hr
+
+= markdown_to_html @wiki.content
+
+%p.time Last edited by #{@wiki.user.name}, in #{time_ago_in_words @wiki.created_at}
+- if can? current_user, :admin_wiki, @project
+ = link_to project_wiki_path(@project, @wiki), :confirm => "Are you sure you want to delete this page?", :method => :delete do
+ Delete this page
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 922a66ebf86..d74f10a1ce5 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -1,10 +1,14 @@
class PostReceive
@queue = :post_receive
- def self.perform(reponame, oldrev, newrev, ref)
+ def self.perform(reponame, oldrev, newrev, ref, author_key_id)
project = Project.find_by_path(reponame)
return false if project.nil?
- project.execute_web_hooks(oldrev, newrev, ref)
+ # Ignore push from non-gitlab users
+ return false unless Key.find_by_identifier(author_key_id)
+
+ project.observe_push(oldrev, newrev, ref, author_key_id)
+ project.execute_web_hooks(oldrev, newrev, ref, author_key_id)
end
end
diff --git a/config/application.rb b/config/application.rb
index bdd5bbf35b8..a3ef29c0db2 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -23,7 +23,7 @@ module Gitlab
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
# Activate observers that should always be running.
- config.active_record.observers = :mailer_observer
+ config.active_record.observers = :mailer_observer, :activity_observer
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
diff --git a/config/database.yml b/config/database.yml.example
index 51a4dd459dc..51a4dd459dc 100644
--- a/config/database.yml
+++ b/config/database.yml.example
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 173bfc74c7c..87b095e27a1 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -30,4 +30,11 @@ Gitlab::Application.configure do
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
config.action_mailer.delivery_method = :letter_opener
+
+ # Raise exception on mass assignment protection for Active Record models
+ config.active_record.mass_assignment_sanitizer = :strict
+
+ # Log the query plan for queries taking more than this (works
+ # with SQLite, MySQL, and PostgreSQL)
+ config.active_record.auto_explain_threshold_in_seconds = 0.5
end
diff --git a/config/gitlab.yml b/config/gitlab.yml.example
index 5d40b2b3440..5d40b2b3440 100644
--- a/config/gitlab.yml
+++ b/config/gitlab.yml.example
diff --git a/config/initializers/carrierwave.rb b/config/initializers/carrierwave.rb
new file mode 100644
index 00000000000..9bb62f6d55a
--- /dev/null
+++ b/config/initializers/carrierwave.rb
@@ -0,0 +1 @@
+CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
index 68bf5a0ea39..ae378b73140 100644
--- a/config/initializers/devise.rb
+++ b/config/initializers/devise.rb
@@ -199,6 +199,15 @@ Devise.setup do |config|
# up on your models and hooks.
# config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo'
+ #config.omniauth :ldap,
+ # :host => 'YOUR_LDAP_SERVER',
+ # :base => 'THE_BASE_WHERE_YOU_SEARCH_FOR_USERS',
+ # :uid => 'sAMAccountName',
+ # :port => 389,
+ # :method => :plain,
+ # :bind_dn => 'THE_FULL_DN_OF_THE_USER_YOU_WILL_BIND_WITH',
+ # :password => 'THE_PASSWORD_OF_THE_BIND_USER'
+
# ==> Warden configuration
# If you want to use other strategies, that are not supported by Devise, or
# change the failure app, you can configure them inside the config.warden block.
diff --git a/config/initializers/gitlabhq/30_resque_queues.rb b/config/initializers/gitlabhq/30_resque_queues.rb
new file mode 100644
index 00000000000..5b0087ab025
--- /dev/null
+++ b/config/initializers/gitlabhq/30_resque_queues.rb
@@ -0,0 +1 @@
+Resque.watch_queue(PostReceive.instance_variable_get("@queue"))
diff --git a/config/routes.rb b/config/routes.rb
index b8149f8ff82..77c20380472 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,22 +1,27 @@
Gitlab::Application.routes.draw do
+
# Optionally, enable Resque here
require 'resque/server'
mount Resque::Server.new, at: '/info/resque'
- get 'tags'=> 'tags#index'
- get 'tags/:tag' => 'projects#index'
get 'help' => 'help#index'
+ get 'help/permissions' => 'help#permissions'
+ get 'help/workflow' => 'help#workflow'
namespace :admin do
- resources :users
+ resources :users do
+ member do
+ put :team_update
+ end
+ end
resources :projects, :constraints => { :id => /[^\/]+/ } do
member do
get :team
put :team_update
end
end
- resources :team_members
+ resources :team_members, :only => [:edit, :update, :destroy]
get 'emails', :to => 'mailer#preview'
get 'mailer/preview_note'
get 'mailer/preview_user_new'
@@ -41,25 +46,32 @@ Gitlab::Application.routes.draw do
resources :projects, :constraints => { :id => /[^\/]+/ }, :only => [:new, :create, :index]
resources :keys
- devise_for :users
+ devise_for :users, :controllers => { :omniauth_callbacks => :omniauth_callbacks }
resources :projects, :constraints => { :id => /[^\/]+/ }, :except => [:new, :create, :index], :path => "/" do
member do
get "team"
get "wall"
get "graph"
- get "info"
get "files"
end
+ resources :wikis, :only => [:show, :edit, :destroy, :create] do
+ member do
+ get "history"
+ end
+ end
+
resource :repository do
member do
get "branches"
get "tags"
+ get "archive"
end
end
resources :deploy_keys
+ resources :protected_branches, :only => [:index, :create, :destroy]
resources :refs, :only => [], :path => "/" do
collection do
@@ -88,7 +100,6 @@ Gitlab::Application.routes.draw do
resources :merge_requests do
member do
get :diffs
- get :commits
end
end
@@ -98,7 +109,11 @@ Gitlab::Application.routes.draw do
get :test
end
end
- resources :commits
+ resources :commits do
+ collection do
+ get :compare
+ end
+ end
resources :team_members
resources :issues do
collection do
@@ -106,7 +121,7 @@ Gitlab::Application.routes.draw do
get :search
end
end
- resources :notes, :only => [:create, :destroy]
+ resources :notes, :only => [:index, :create, :destroy]
end
root :to => "dashboard#index"
end
diff --git a/db/migrate/20120206170141_add_modularity_fields_to_project.rb b/db/migrate/20120206170141_add_modularity_fields_to_project.rb
new file mode 100644
index 00000000000..d63de0c2be3
--- /dev/null
+++ b/db/migrate/20120206170141_add_modularity_fields_to_project.rb
@@ -0,0 +1,7 @@
+class AddModularityFieldsToProject < ActiveRecord::Migration
+ def change
+ add_column :projects, :issues_enabled, :boolean, :null => false, :default => true
+ add_column :projects, :wall_enabled, :boolean, :null => false, :default => true
+ add_column :projects, :merge_requests_enabled, :boolean, :null => false, :default => true
+ end
+end
diff --git a/db/migrate/20120215182305_create_protected_branches.rb b/db/migrate/20120215182305_create_protected_branches.rb
new file mode 100644
index 00000000000..841d08c33d5
--- /dev/null
+++ b/db/migrate/20120215182305_create_protected_branches.rb
@@ -0,0 +1,10 @@
+class CreateProtectedBranches < ActiveRecord::Migration
+ def change
+ create_table :protected_branches do |t|
+ t.integer :project_id, :null => false
+ t.string :name, :null => false
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20120216085842_move_to_roles_permissions.rb b/db/migrate/20120216085842_move_to_roles_permissions.rb
new file mode 100644
index 00000000000..36d02cf972a
--- /dev/null
+++ b/db/migrate/20120216085842_move_to_roles_permissions.rb
@@ -0,0 +1,22 @@
+class MoveToRolesPermissions < ActiveRecord::Migration
+ def up
+ repo_n = 0
+ repo_r = 1
+ repo_rw = 2
+ project_rwa = 3
+
+
+ # Build masters and reset repo_access
+ UsersProject.update_all({:project_access => UsersProject::MASTER, :repo_access => 99 }, ["project_access = ?", project_rwa])
+
+ # Build other roles based on repo access
+ UsersProject.update_all ["project_access = ?", UsersProject::DEVELOPER], ["repo_access = ?", repo_rw]
+ UsersProject.update_all ["project_access = ?", UsersProject::REPORTER], ["repo_access = ?", repo_r]
+ UsersProject.update_all ["project_access = ?", UsersProject::GUEST], ["repo_access = ?", repo_n]
+
+ remove_column :users_projects, :repo_access
+ end
+
+ def down
+ end
+end
diff --git a/db/migrate/20120216215008_create_wikis.rb b/db/migrate/20120216215008_create_wikis.rb
new file mode 100644
index 00000000000..38947df389c
--- /dev/null
+++ b/db/migrate/20120216215008_create_wikis.rb
@@ -0,0 +1,11 @@
+class CreateWikis < ActiveRecord::Migration
+ def change
+ create_table :wikis do |t|
+ t.string :title
+ t.text :content
+ t.integer :project_id
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20120219130957_add_slug_to_wiki.rb b/db/migrate/20120219130957_add_slug_to_wiki.rb
new file mode 100644
index 00000000000..5f2d5970a89
--- /dev/null
+++ b/db/migrate/20120219130957_add_slug_to_wiki.rb
@@ -0,0 +1,6 @@
+class AddSlugToWiki < ActiveRecord::Migration
+ def change
+ add_column :wikis, :slug, :string
+
+ end
+end
diff --git a/db/migrate/20120219140810_add_wiki_enabled_to_project.rb b/db/migrate/20120219140810_add_wiki_enabled_to_project.rb
new file mode 100644
index 00000000000..ebd71bea84d
--- /dev/null
+++ b/db/migrate/20120219140810_add_wiki_enabled_to_project.rb
@@ -0,0 +1,6 @@
+class AddWikiEnabledToProject < ActiveRecord::Migration
+ def change
+ add_column :projects, :wiki_enabled, :boolean, :default => true, :null => false
+
+ end
+end
diff --git a/db/migrate/20120219193300_add_user_to_wiki.rb b/db/migrate/20120219193300_add_user_to_wiki.rb
new file mode 100644
index 00000000000..8a6c0a06ef0
--- /dev/null
+++ b/db/migrate/20120219193300_add_user_to_wiki.rb
@@ -0,0 +1,6 @@
+class AddUserToWiki < ActiveRecord::Migration
+ def change
+ add_column :wikis, :user_id, :integer
+
+ end
+end
diff --git a/db/migrate/20120228130210_create_events.rb b/db/migrate/20120228130210_create_events.rb
new file mode 100644
index 00000000000..c01f557aaaa
--- /dev/null
+++ b/db/migrate/20120228130210_create_events.rb
@@ -0,0 +1,14 @@
+class CreateEvents < ActiveRecord::Migration
+ def change
+ create_table :events do |t|
+ t.string :target_type, :null => true
+ t.integer :target_id, :null => true
+
+ t.string :title, :null => true
+ t.text :data, :null => true
+ t.integer :project_id, :null => true
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20120228134252_add_action_to_event.rb b/db/migrate/20120228134252_add_action_to_event.rb
new file mode 100644
index 00000000000..aade3d90a80
--- /dev/null
+++ b/db/migrate/20120228134252_add_action_to_event.rb
@@ -0,0 +1,5 @@
+class AddActionToEvent < ActiveRecord::Migration
+ def change
+ add_column :events, :action, :integer, :null => true
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 3e7866f318a..a0baf8e2d67 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,18 +11,17 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20120121122616) do
+ActiveRecord::Schema.define(:version => 20120228134252) do
- create_table "features", :force => true do |t|
- t.string "name"
- t.string "branch_name"
- t.integer "assignee_id"
- t.integer "author_id"
+ create_table "events", :force => true do |t|
+ t.string "target_type"
+ t.integer "target_id"
+ t.string "title"
+ t.text "data"
t.integer "project_id"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "version"
- t.integer "status", :default => 0, :null => false
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ t.integer "action"
end
create_table "issues", :force => true do |t|
@@ -85,10 +84,21 @@ ActiveRecord::Schema.define(:version => 20120121122616) do
t.text "description"
t.datetime "created_at"
t.datetime "updated_at"
- t.boolean "private_flag", :default => true, :null => false
+ t.boolean "private_flag", :default => true, :null => false
t.string "code"
t.integer "owner_id"
- t.string "default_branch", :default => "master", :null => false
+ t.string "default_branch", :default => "master", :null => false
+ t.boolean "issues_enabled", :default => true, :null => false
+ t.boolean "wall_enabled", :default => true, :null => false
+ t.boolean "merge_requests_enabled", :default => true, :null => false
+ t.boolean "wiki_enabled", :default => true, :null => false
+ end
+
+ create_table "protected_branches", :force => true do |t|
+ t.integer "project_id", :null => false
+ t.string "name", :null => false
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
end
create_table "snippets", :force => true do |t|
@@ -150,7 +160,6 @@ ActiveRecord::Schema.define(:version => 20120121122616) do
t.integer "project_id", :null => false
t.datetime "created_at"
t.datetime "updated_at"
- t.integer "repo_access", :default => 0, :null => false
t.integer "project_access", :default => 0, :null => false
end
@@ -161,4 +170,14 @@ ActiveRecord::Schema.define(:version => 20120121122616) do
t.datetime "updated_at"
end
+ create_table "wikis", :force => true do |t|
+ t.string "title"
+ t.text "content"
+ t.integer "project_id"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ t.string "slug"
+ t.integer "user_id"
+ end
+
end
diff --git a/lib/gitlabhq/gitolite.rb b/lib/gitlabhq/gitolite.rb
index e6eb8e5144b..4f911113ea0 100644
--- a/lib/gitlabhq/gitolite.rb
+++ b/lib/gitlabhq/gitolite.rb
@@ -64,21 +64,9 @@ module Gitlabhq
def update_project(repo_name, project)
ga_repo = ::Gitolite::GitoliteAdmin.new(File.join(@local_dir,'gitolite'))
conf = ga_repo.config
-
- repo = if conf.has_repo?(repo_name)
- conf.get_repo(repo_name)
- else
- ::Gitolite::Config::Repo.new(repo_name)
- end
-
- name_readers = project.repository_readers
- name_writers = project.repository_writers
-
- repo.clean_permissions
- repo.add_permission("R", "", name_readers) unless name_readers.blank?
- repo.add_permission("RW+", "", name_writers) unless name_writers.blank?
+ repo = update_project_config(project, conf)
conf.add_repo(repo, true)
-
+
ga_repo.save
end
@@ -89,25 +77,43 @@ module Gitlabhq
conf = ga_repo.config
projects.each do |project|
- repo_name = project.path
-
- repo = if conf.has_repo?(repo_name)
- conf.get_repo(repo_name)
- else
- ::Gitolite::Config::Repo.new(repo_name)
- end
-
- name_readers = project.repository_readers
- name_writers = project.repository_writers
-
- repo.clean_permissions
- repo.add_permission("R", "", name_readers) unless name_readers.blank?
- repo.add_permission("RW+", "", name_writers) unless name_writers.blank?
+ repo = update_project_config(project, conf)
conf.add_repo(repo, true)
end
ga_repo.save
end
+ def update_project_config(project, conf)
+ repo_name = project.path
+
+ repo = if conf.has_repo?(repo_name)
+ conf.get_repo(repo_name)
+ else
+ ::Gitolite::Config::Repo.new(repo_name)
+ end
+
+ name_readers = project.repository_readers
+ name_writers = project.repository_writers
+ name_masters = project.repository_masters
+
+ pr_br = project.protected_branches.map(&:name).join(" ")
+
+ repo.clean_permissions
+
+ # Deny access to protected branches for writers
+ unless name_writers.blank? || pr_br.blank?
+ repo.add_permission("-", pr_br, name_writers)
+ end
+
+ # Add read permissions
+ repo.add_permission("R", "", name_readers) unless name_readers.blank?
+
+ # Add write permissions
+ repo.add_permission("RW+", "", name_writers) unless name_writers.blank?
+ repo.add_permission("RW+", "", name_masters) unless name_masters.blank?
+
+ repo
+ end
end
end
diff --git a/lib/post-receive-hook b/lib/post-receive-hook
index d7354d6515b..93eb96c2a6d 100755
--- a/lib/post-receive-hook
+++ b/lib/post-receive-hook
@@ -8,5 +8,5 @@ do
# For every branch or tag that was pushed, create a Resque job in redis.
pwd=`pwd`
reponame=`basename "$pwd" | cut -d. -f1`
- env -i redis-cli rpush "resque:queue:post_receive" "{\"class\":\"PostReceive\",\"args\":[\"$reponame\",\"$oldrev\",\"$newrev\",\"$ref\"]}" > /dev/null 2>&1
+ env -i redis-cli rpush "resque:queue:post_receive" "{\"class\":\"PostReceive\",\"args\":[\"$reponame\",\"$oldrev\",\"$newrev\",\"$ref\",\"$GL_USER\"]}" > /dev/null 2>&1
done
diff --git a/lib/tasks/update_hooks.rake b/lib/tasks/update_hooks.rake
new file mode 100644
index 00000000000..472023c8f15
--- /dev/null
+++ b/lib/tasks/update_hooks.rake
@@ -0,0 +1,15 @@
+desc "Rewrite hooks for repos"
+task :update_hooks => :environment do
+ puts "Starting Projects"
+ Project.find_each(:batch_size => 100) do |project|
+ begin
+ if project.commit
+ project.repository.write_hooks
+ print ".".green
+ end
+ rescue Exception => e
+ print e.message.red
+ end
+ end
+ puts "\nDone with projects"
+end
diff --git a/lib/utils.rb b/lib/utils.rb
index 677322c98d4..82463f9ec0c 100644
--- a/lib/utils.rb
+++ b/lib/utils.rb
@@ -34,6 +34,10 @@ module Utils
:c
when /(\.cpp|\.hpp|\.c++|\.h++|\.cc|\.hh|\.cxx|\.hxx)$/
:cpp
+ when /(\.d|\.di)$/
+ :d
+ when /(\.hs|\.lhs)$/
+ :haskell
when /(\.rb|\.ru|\.rake|Rakefile|\.gemspec|\.rbx|Gemfile)$/
:ruby
when /(\.py|\.pyw|\.sc|SConstruct|SConscript|\.tac)$/
diff --git a/public/404.html b/public/404.html
index 16d8fcbca34..33325890b32 100644
--- a/public/404.html
+++ b/public/404.html
@@ -2,22 +2,12 @@
<html>
<head>
<title>The page you were looking for doesn't exist (404)</title>
- <style type="text/css">
- body { background-color: #EAEAEA; color: #666; text-align: center; font-family: arial, sans-serif; }
- div.dialog {
- width: 600px;
- padding: 0 4em;
- margin: 4em auto 0 auto;
- }
- h1 { font-size: 48px; color: #444; line-height: 1.5em; }
- h2 { font-size: 24px; color: #666; line-height: 1.5em; }
- </style>
+ <link href="static.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
- <!-- This file lives in public/404.html -->
- <div class="dialog">
- <h1>404</h1>
+ <h1>404</h1>
+ <div class="alert-message block-message error">
<h2>The page you were looking for doesn't exist.</h2>
<p>You may have mistyped the address or the page may have moved.</p>
</div>
diff --git a/public/422.html b/public/422.html
index 24532664370..8b19ea89ce5 100644
--- a/public/422.html
+++ b/public/422.html
@@ -2,22 +2,13 @@
<html>
<head>
<title>The change you wanted was rejected (422)</title>
- <style type="text/css">
- body { background-color: #EAEAEA; color: #666; text-align: center; font-family: arial, sans-serif; }
- div.dialog {
- width: 600px;
- padding: 0 4em;
- margin: 4em auto 0 auto;
- }
- h1 { font-size: 48px; color: #444; line-height: 1.5em; }
- h2 { font-size: 24px; color: #666; line-height: 1.5em; }
- </style>
+ <link href="static.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- This file lives in public/422.html -->
- <div class="dialog">
- <h1>422</h1>
+ <h1>422</h1>
+ <div class="alert-message block-message error">
<h2>The change you wanted was rejected.</h2>
<p>Maybe you tried to change something you didn't have access to.</p>
</div>
diff --git a/public/500.html b/public/500.html
index b1d544647a1..36e14b802ee 100644
--- a/public/500.html
+++ b/public/500.html
@@ -2,22 +2,13 @@
<html>
<head>
<title>We're sorry, but something went wrong (500)</title>
- <style type="text/css">
- body { background-color: #EAEAEA; color: #666; text-align: center; font-family: arial, sans-serif; }
- div.dialog {
- width: 600px;
- padding: 0 4em;
- margin: 4em auto 0 auto;
- }
- h1 { font-size: 48px; color: #444; line-height: 1.5em; }
- h2 { font-size: 24px; color: #666; line-height: 1.5em; }
- </style>
+ <link href="static.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- This file lives in public/500.html -->
- <div class="dialog">
- <h1>500</h1>
+ <h1>500</h1>
+ <div class="alert-message block-message error">
<h2>We're sorry, but something went wrong.</h2>
<p>We've been notified about this issue and we'll take a look at it shortly.</p>
</div>
diff --git a/public/static.css b/public/static.css
new file mode 100644
index 00000000000..6090d7b2abb
--- /dev/null
+++ b/public/static.css
@@ -0,0 +1,57 @@
+body { color: #666; text-align: center; font-family: arial, sans-serif; margin:0; padding:0; }
+h1 { font-size: 48px; color: #444; line-height: 1.5em; }
+h2 { font-size: 24px; color: #666; line-height: 1.5em; }
+
+.alert-message {
+ position: relative;
+ padding: 7px 15px;
+ margin-bottom: 18px;
+ color: #404040;
+ background-color: #eedc94;
+ background-repeat: repeat-x;
+ background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94));
+ background-image: -moz-linear-gradient(top, #fceec1, #eedc94);
+ background-image: -ms-linear-gradient(top, #fceec1, #eedc94);
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94));
+ background-image: -webkit-linear-gradient(top, #fceec1, #eedc94);
+ background-image: -o-linear-gradient(top, #fceec1, #eedc94);
+ background-image: linear-gradient(top, #fceec1, #eedc94);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFCEEC1', endColorstr='#FFEEDC94', GradientType=0);
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ border-color: #eedc94 #eedc94 #e4c652;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) fadein(rgba(0, 0, 0, 0.1), 15%);
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+ border-width: 1px;
+ border-style: solid;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
+}
+.alert-message .close {
+ margin-top: 1px;
+ *margin-top: 0;
+}
+.alert-message a {
+ font-weight: bold;
+ color: #404040;
+}
+.alert-message.danger p a, .alert-message.error p a, .alert-message.success p a, .alert-message.info p a {
+ color: #404040;
+}
+.alert-message h5 {
+ line-height: 18px;
+}
+.alert-message p {
+ margin-bottom: 0;
+}
+.alert-message div {
+ margin-top: 5px;
+ margin-bottom: 2px;
+ line-height: 28px;
+}
+
+.alert-message.block-message.error {
+ background: #FDDFDE;
+ border-color: #FBC7C6;
+}
+
diff --git a/resque.sh b/resque.sh
index 7c9850d0ec8..84a1066f087 100755
--- a/resque.sh
+++ b/resque.sh
@@ -1,2 +1,2 @@
mkdir tmp/pids
-nohup bundle exec rake environment resque:work QUEUE=* VVERBOSE=1 RAILS_ENV=production PIDFILE=tmp/pids/resque_worker_QUEUE.pid & >> log/resque_worker_QUEUE.log 2>&1
+nohup bundle exec rake environment resque:work QUEUE=* RAILS_ENV=production PIDFILE=tmp/pids/resque_worker_QUEUE.pid & >> log/resque_worker_QUEUE.log 2>&1
diff --git a/resque_dev.sh b/resque_dev.sh
new file mode 100755
index 00000000000..9df4dc1d087
--- /dev/null
+++ b/resque_dev.sh
@@ -0,0 +1 @@
+bundle exec rake environment resque:work QUEUE=* VVERBOSE=1
diff --git a/spec/factories.rb b/spec/factories.rb
index 15e54ed2120..2ca8d7649ad 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -32,10 +32,14 @@ end
Factory.add(:issue, Issue) do |obj|
obj.title = Faker::Lorem.sentence
+ obj.author = Factory :user
+ obj.assignee = Factory :user
end
Factory.add(:merge_request, MergeRequest) do |obj|
obj.title = Faker::Lorem.sentence
+ obj.author = Factory :user
+ obj.assignee = Factory :user
obj.source_branch = "master"
obj.target_branch = "master"
obj.closed = false
@@ -59,3 +63,13 @@ end
Factory.add(:web_hook, WebHook) do |obj|
obj.url = Faker::Internet.url
end
+
+Factory.add(:wikis, WebHook) do |obj|
+ obj.title = Faker::Lorem.sentence
+ obj.content = Faker::Lorem.sentence
+end
+
+Factory.add(:event, Event) do |obj|
+ obj.title = Faker::Lorem.sentence
+ obj.project = Factory(:project)
+end
diff --git a/spec/models/activity_observer_spec.rb b/spec/models/activity_observer_spec.rb
new file mode 100644
index 00000000000..9cd0dfb630d
--- /dev/null
+++ b/spec/models/activity_observer_spec.rb
@@ -0,0 +1,44 @@
+require 'spec_helper'
+
+describe ActivityObserver do
+ let(:project) { Factory :project }
+
+ def self.it_should_be_valid_event
+ it { @event.should_not be_nil }
+ it { @event.project.should == project }
+ end
+
+ describe "Merge Request created" do
+ before do
+ @merge_request = Factory :merge_request, :project => project
+ @event = Event.last
+ end
+
+ it_should_be_valid_event
+ it { @event.action.should == Event::Created }
+ it { @event.target.should == @merge_request }
+ end
+
+ describe "Issue created" do
+ before do
+ @issue = Factory :issue, :project => project
+ @event = Event.last
+ end
+
+ it_should_be_valid_event
+ it { @event.action.should == Event::Created }
+ it { @event.target.should == @issue }
+ end
+
+ describe "Issue commented" do
+ before do
+ @issue = Factory :issue, :project => project
+ @note = Factory :note, :noteable => @issue, :project => project
+ @event = Event.last
+ end
+
+ it_should_be_valid_event
+ it { @event.action.should == Event::Commented }
+ it { @event.target.should == @note }
+ end
+end
diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb
new file mode 100644
index 00000000000..50266fcf8ed
--- /dev/null
+++ b/spec/models/event_spec.rb
@@ -0,0 +1,32 @@
+# == Schema Information
+#
+# Table name: events
+#
+# id :integer not null, primary key
+# target_type :string(255)
+# target_id :integer
+# title :string(255)
+# data :text
+# project_id :integer
+# created_at :datetime not null
+# updated_at :datetime not null
+# action :integer
+#
+
+require 'spec_helper'
+
+describe Event do
+ describe "Associations" do
+ it { should belong_to(:project) }
+ end
+
+ describe "Creation" do
+ before do
+ @event = Factory :event
+ end
+
+ it "should create a valid event" do
+ @event.should be_valid
+ end
+ end
+end
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 75503fd9a75..70eba5cc194 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -42,27 +42,13 @@ describe Note do
:project => project,
:noteable_id => commit.id,
:noteable_type => "Commit",
- :line_code => "OLD_1_23"
+ :line_code => "0_16_1"
end
it "should save a valid note" do
@note.noteable_id.should == commit.id
@note.target.id.should == commit.id
end
-
- it { @note.line_type_id.should == "OLD" }
- it { @note.line_file_id.should == 1 }
- it { @note.line_number.should == 23 }
-
- it { @note.for_line?(1, 23, 34).should be_true }
- it { @note.for_line?(1, 23, nil).should be_true }
- it { @note.for_line?(1, 23, 0).should be_true }
- it { @note.for_line?(1, 23, 23).should be_true }
-
- it { @note.for_line?(1, nil, 34).should be_false }
- it { @note.for_line?(1, 24, nil).should be_false }
- it { @note.for_line?(1, 24, 0).should be_false }
- it { @note.for_line?(1, 24, 23).should be_false }
end
describe :authorization do
@@ -78,9 +64,8 @@ describe Note do
describe :read do
before do
- @p1.users_projects.create(:user => @u1, :project_access => Project::PROJECT_N)
- @p1.users_projects.create(:user => @u2, :project_access => Project::PROJECT_R)
- @p2.users_projects.create(:user => @u3, :project_access => Project::PROJECT_R)
+ @p1.users_projects.create(:user => @u2, :project_access => UsersProject::GUEST)
+ @p2.users_projects.create(:user => @u3, :project_access => UsersProject::GUEST)
end
it { @abilities.allowed?(@u1, :read_note, @p1).should be_false }
@@ -90,9 +75,8 @@ describe Note do
describe :write do
before do
- @p1.users_projects.create(:user => @u1, :project_access => Project::PROJECT_R)
- @p1.users_projects.create(:user => @u2, :project_access => Project::PROJECT_RW)
- @p2.users_projects.create(:user => @u3, :project_access => Project::PROJECT_RW)
+ @p1.users_projects.create(:user => @u2, :project_access => UsersProject::DEVELOPER)
+ @p2.users_projects.create(:user => @u3, :project_access => UsersProject::DEVELOPER)
end
it { @abilities.allowed?(@u1, :write_note, @p1).should be_false }
@@ -102,9 +86,9 @@ describe Note do
describe :admin do
before do
- @p1.users_projects.create(:user => @u1, :project_access => Project::PROJECT_R)
- @p1.users_projects.create(:user => @u2, :project_access => Project::PROJECT_RWA)
- @p2.users_projects.create(:user => @u3, :project_access => Project::PROJECT_RWA)
+ @p1.users_projects.create(:user => @u1, :project_access => UsersProject::REPORTER)
+ @p1.users_projects.create(:user => @u2, :project_access => UsersProject::MASTER)
+ @p2.users_projects.create(:user => @u3, :project_access => UsersProject::MASTER)
end
it { @abilities.allowed?(@u1, :admin_note, @p1).should be_false }
diff --git a/spec/models/project_hooks_spec.rb b/spec/models/project_hooks_spec.rb
new file mode 100644
index 00000000000..5a03b01f80b
--- /dev/null
+++ b/spec/models/project_hooks_spec.rb
@@ -0,0 +1,121 @@
+require 'spec_helper'
+
+describe Project, "Hooks" do
+ let(:project) { Factory :project }
+ before do
+ @key = Factory :key, :user => project.owner
+ @key_id = @key.identifier
+ end
+
+ describe "Post Receive Event" do
+ it "should create push event" do
+ oldrev, newrev, ref = '00000000000000000000000000000000', 'newrev', 'refs/heads/master'
+ project.observe_push(oldrev, newrev, ref, @key_id)
+ event = Event.last
+
+ event.should_not be_nil
+ event.project.should == project
+ event.action.should == Event::Pushed
+ event.data == project.web_hook_data(oldrev, newrev, ref, @key_id)
+ end
+ end
+
+ describe "Web hooks" do
+ context "with no web hooks" do
+ it "raises no errors" do
+ lambda {
+ project.execute_web_hooks('oldrev', 'newrev', 'ref', @key_id)
+ }.should_not raise_error
+ end
+ end
+
+ context "with web hooks" do
+ before do
+ @webhook = Factory(:web_hook)
+ @webhook_2 = Factory(:web_hook)
+ project.web_hooks << [@webhook, @webhook_2]
+ end
+
+ it "executes multiple web hook" do
+ @webhook.should_receive(:execute).once
+ @webhook_2.should_receive(:execute).once
+
+ project.execute_web_hooks('oldrev', 'newrev', 'refs/heads/master', @key_id)
+ end
+ end
+
+ context "does not execute web hooks" do
+ before do
+ @webhook = Factory(:web_hook)
+ project.web_hooks << [@webhook]
+ end
+
+ it "when pushing a branch for the first time" do
+ @webhook.should_not_receive(:execute)
+ project.execute_web_hooks('00000000000000000000000000000000', 'newrev', 'refs/heads/master', @key_id)
+ end
+
+ it "when pushing tags" do
+ @webhook.should_not_receive(:execute)
+ project.execute_web_hooks('oldrev', 'newrev', 'refs/tags/v1.0.0', @key_id)
+ end
+ end
+
+ context "when pushing new branches" do
+
+ end
+
+ context "when gathering commit data" do
+ before do
+ @oldrev, @newrev, @ref = project.fresh_commits(2).last.sha, project.fresh_commits(2).first.sha, 'refs/heads/master'
+ @commit = project.fresh_commits(2).first
+
+ # Fill nil/empty attributes
+ project.description = "This is a description"
+
+ @data = project.web_hook_data(@oldrev, @newrev, @ref, @key_id)
+ end
+
+ subject { @data }
+
+ it { should include(before: @oldrev) }
+ it { should include(after: @newrev) }
+ it { should include(ref: @ref) }
+ it { should include(user_id: project.owner.id) }
+ it { should include(user_name: project.owner.name) }
+
+ context "with repository data" do
+ subject { @data[:repository] }
+
+ it { should include(name: project.name) }
+ it { should include(url: project.web_url) }
+ it { should include(description: project.description) }
+ it { should include(homepage: project.web_url) }
+ it { should include(private: project.private?) }
+ end
+
+ context "with commits" do
+ subject { @data[:commits] }
+
+ it { should be_an(Array) }
+ it { should have(1).element }
+
+ context "the commit" do
+ subject { @data[:commits].first }
+
+ it { should include(id: @commit.id) }
+ it { should include(message: @commit.safe_message) }
+ it { should include(timestamp: @commit.date.xmlschema) }
+ it { should include(url: "http://localhost/#{project.code}/commits/#{@commit.id}") }
+
+ context "with a author" do
+ subject { @data[:commits].first[:author] }
+
+ it { should include(name: @commit.author_name) }
+ it { should include(email: @commit.author_email) }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/models/project_security_spec.rb b/spec/models/project_security_spec.rb
index 1899e8aa9ee..bd697af9652 100644
--- a/spec/models/project_security_spec.rb
+++ b/spec/models/project_security_spec.rb
@@ -12,8 +12,7 @@ describe Project do
describe "read access" do
before do
- @p1.users_projects.create(:project => @p1, :user => @u1, :project_access => Project::PROJECT_N)
- @p1.users_projects.create(:project => @p1, :user => @u2, :project_access => Project::PROJECT_R)
+ @p1.users_projects.create(:project => @p1, :user => @u2, :project_access => UsersProject::REPORTER)
end
it { @abilities.allowed?(@u1, :read_project, @p1).should be_false }
@@ -22,8 +21,7 @@ describe Project do
describe "write access" do
before do
- @p1.users_projects.create(:project => @p1, :user => @u1, :project_access => Project::PROJECT_R)
- @p1.users_projects.create(:project => @p1, :user => @u2, :project_access => Project::PROJECT_RW)
+ @p1.users_projects.create(:project => @p1, :user => @u2, :project_access => UsersProject::DEVELOPER)
end
it { @abilities.allowed?(@u1, :write_project, @p1).should be_false }
@@ -32,8 +30,8 @@ describe Project do
describe "admin access" do
before do
- @p1.users_projects.create(:project => @p1, :user => @u1, :project_access => Project::PROJECT_RW)
- @p1.users_projects.create(:project => @p1, :user => @u2, :project_access => Project::PROJECT_RWA)
+ @p1.users_projects.create(:project => @p1, :user => @u1, :project_access => UsersProject::DEVELOPER)
+ @p1.users_projects.create(:project => @p1, :user => @u2, :project_access => UsersProject::MASTER)
end
it { @abilities.allowed?(@u1, :admin_project, @p1).should be_false }
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 68bc82de898..f53b833f387 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -2,6 +2,7 @@ require 'spec_helper'
describe Project do
describe "Associations" do
+ it { should have_many(:events) }
it { should have_many(:users) }
it { should have_many(:users_projects) }
it { should have_many(:issues) }
@@ -69,106 +70,6 @@ describe Project do
end
end
- describe "web hooks" do
- let(:project) { Factory :project }
-
- context "with no web hooks" do
- it "raises no errors" do
- lambda {
- project.execute_web_hooks('oldrev', 'newrev', 'ref')
- }.should_not raise_error
- end
- end
-
- context "with web hooks" do
- before do
- @webhook = Factory(:web_hook)
- @webhook_2 = Factory(:web_hook)
- project.web_hooks << [@webhook, @webhook_2]
- end
-
- it "executes multiple web hook" do
- @webhook.should_receive(:execute).once
- @webhook_2.should_receive(:execute).once
-
- project.execute_web_hooks('oldrev', 'newrev', 'refs/heads/master')
- end
- end
-
- context "does not execute web hooks" do
- before do
- @webhook = Factory(:web_hook)
- project.web_hooks << [@webhook]
- end
-
- it "when pushing a branch for the first time" do
- @webhook.should_not_receive(:execute)
- project.execute_web_hooks('00000000000000000000000000000000', 'newrev', 'refs/heads/master')
- end
-
- it "when pushing tags" do
- @webhook.should_not_receive(:execute)
- project.execute_web_hooks('oldrev', 'newrev', 'refs/tags/v1.0.0')
- end
- end
-
- context "when pushing new branches" do
-
- end
-
- context "when gathering commit data" do
- before do
- @oldrev, @newrev, @ref = project.fresh_commits(2).last.sha, project.fresh_commits(2).first.sha, 'refs/heads/master'
- @commit = project.fresh_commits(2).first
-
- # Fill nil/empty attributes
- project.description = "This is a description"
-
- @data = project.web_hook_data(@oldrev, @newrev, @ref)
- end
-
- subject { @data }
-
- it { should include(before: @oldrev) }
- it { should include(after: @newrev) }
- it { should include(ref: @ref) }
-
- context "with repository data" do
- subject { @data[:repository] }
-
- it { should include(name: project.name) }
- it { should include(url: project.web_url) }
- it { should include(description: project.description) }
- it { should include(homepage: project.web_url) }
- it { should include(private: project.private?) }
- end
-
- context "with commits" do
- subject { @data[:commits] }
-
- it { should be_an(Array) }
- it { should have(1).element }
-
- context "the commit" do
- subject { @data[:commits].first }
-
- it { should include(id: @commit.id) }
- it { should include(message: @commit.safe_message) }
- it { should include(timestamp: @commit.date.xmlschema) }
- it { should include(url: "http://localhost/#{project.code}/commits/#{@commit.id}") }
-
- context "with a author" do
- subject { @data[:commits].first[:author] }
-
- it { should include(name: @commit.author_name) }
- it { should include(email: @commit.author_email) }
- end
- end
- end
-
- end
- end
-
describe "updates" do
let(:project) { Factory :project }
@@ -290,15 +191,19 @@ end
#
# Table name: projects
#
-# id :integer not null, primary key
-# name :string(255)
-# path :string(255)
-# description :text
-# created_at :datetime
-# updated_at :datetime
-# private_flag :boolean default(TRUE), not null
-# code :string(255)
-# owner_id :integer
-# default_branch :string(255) default("master"), not null
+# id :integer not null, primary key
+# name :string(255)
+# path :string(255)
+# description :text
+# created_at :datetime
+# updated_at :datetime
+# private_flag :boolean default(TRUE), not null
+# code :string(255)
+# owner_id :integer
+# default_branch :string(255) default("master"), not null
+# issues_enabled :boolean default(TRUE), not null
+# wall_enabled :boolean default(TRUE), not null
+# merge_requests_enabled :boolean default(TRUE), not null
+# wiki_enabled :boolean default(TRUE), not null
#
diff --git a/spec/models/protected_branch_spec.rb b/spec/models/protected_branch_spec.rb
new file mode 100644
index 00000000000..a0b0032a558
--- /dev/null
+++ b/spec/models/protected_branch_spec.rb
@@ -0,0 +1,16 @@
+# == Schema Information
+#
+# Table name: protected_branches
+#
+# id :integer not null, primary key
+# project_id :integer not null
+# name :string(255) not null
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+require 'spec_helper'
+
+describe ProtectedBranch do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/models/users_project_spec.rb b/spec/models/users_project_spec.rb
index 41e36b57204..85bc4d346b0 100644
--- a/spec/models/users_project_spec.rb
+++ b/spec/models/users_project_spec.rb
@@ -25,7 +25,6 @@ end
# project_id :integer not null
# created_at :datetime
# updated_at :datetime
-# repo_access :integer default(0), not null
# project_access :integer default(0), not null
#
diff --git a/spec/requests/admin/admin_projects_spec.rb b/spec/requests/admin/admin_projects_spec.rb
index ffa65fc255b..ceaf7245a10 100644
--- a/spec/requests/admin/admin_projects_spec.rb
+++ b/spec/requests/admin/admin_projects_spec.rb
@@ -18,7 +18,6 @@ describe "Admin::Projects" do
end
it "should have projects list" do
- page.should have_content(@project.code)
page.should have_content(@project.name)
end
end
@@ -103,4 +102,18 @@ describe "Admin::Projects" do
page.should have_content(@project.description)
end
end
+
+ describe "Add new team member" do
+ before do
+ @new_user = Factory :user
+ visit admin_project_path(@project)
+ end
+
+ it "should create new user" do
+ select @new_user.name, :from => "user_ids"
+ expect { click_button "Add" }.to change { UsersProject.count }.by(1)
+ page.should have_content @new_user.name
+ current_path.should == admin_project_path(@project)
+ end
+ end
end
diff --git a/spec/requests/admin/admin_users_spec.rb b/spec/requests/admin/admin_users_spec.rb
index aa78db99f42..91082a644b5 100644
--- a/spec/requests/admin/admin_users_spec.rb
+++ b/spec/requests/admin/admin_users_spec.rb
@@ -99,4 +99,18 @@ describe "Admin::Users" do
end
end
end
+
+ describe "Add new project" do
+ before do
+ @new_project = Factory :project
+ visit admin_user_path(@user)
+ end
+
+ it "should create new user" do
+ select @new_project.name, :from => "project_ids"
+ expect { click_button "Add" }.to change { UsersProject.count }.by(1)
+ page.should have_content @new_project.name
+ current_path.should == admin_user_path(@user)
+ end
+ end
end
diff --git a/spec/requests/admin/security_spec.rb b/spec/requests/admin/security_spec.rb
index 27b60196769..0b0edb85a37 100644
--- a/spec/requests/admin/security_spec.rb
+++ b/spec/requests/admin/security_spec.rb
@@ -13,12 +13,6 @@ describe "Admin::Projects" do
it { admin_users_path.should be_denied_for :visitor }
end
- describe "GET /admin/team_members" do
- it { admin_team_members_path.should be_allowed_for :admin }
- it { admin_team_members_path.should be_denied_for :user }
- it { admin_team_members_path.should be_denied_for :visitor }
- end
-
describe "GET /admin/emails" do
it { admin_emails_path.should be_allowed_for :admin }
it { admin_emails_path.should be_denied_for :user }
diff --git a/spec/requests/commits_spec.rb b/spec/requests/commits_spec.rb
index f79e9753c48..00b69379848 100644
--- a/spec/requests/commits_spec.rb
+++ b/spec/requests/commits_spec.rb
@@ -22,8 +22,8 @@ describe "Commits" do
end
it "should list commits" do
- page.should have_content(commit.author)
page.should have_content(commit.message)
+ page.should have_content(commit.id.to_s[0..5])
end
it "should render atom feed" do
@@ -55,4 +55,14 @@ describe "Commits" do
current_path.should == project_commit_path(project, commit.id)
end
end
+
+ describe "GET /commits/compare" do
+ before do
+ visit compare_project_commits_path(project)
+ end
+
+ it "should have valid path" do
+ current_path.should == compare_project_commits_path(project)
+ end
+ end
end
diff --git a/spec/requests/dashboard_issues_spec.rb b/spec/requests/dashboard_issues_spec.rb
index 46c5553e155..29c79313f7e 100644
--- a/spec/requests/dashboard_issues_spec.rb
+++ b/spec/requests/dashboard_issues_spec.rb
@@ -34,11 +34,9 @@ describe "User Issues Dashboard" do
it { should have_content(@issue1.title[0..10]) }
it { should have_content(@issue1.project.name) }
- it { should have_content(@issue1.assignee.name) }
it { should have_content(@issue2.title[0..10]) }
it { should have_content(@issue2.project.name) }
- it { should have_content(@issue2.assignee.name) }
describe "atom feed", :js => false do
it "should render atom feed via private token" do
diff --git a/spec/requests/dashboard_merge_requests_spec.rb b/spec/requests/dashboard_merge_requests_spec.rb
index e591609547e..f345a858ac8 100644
--- a/spec/requests/dashboard_merge_requests_spec.rb
+++ b/spec/requests/dashboard_merge_requests_spec.rb
@@ -34,14 +34,7 @@ describe "User MergeRequests" do
it { should have_content(@merge_request1.title[0..10]) }
it { should have_content(@merge_request1.project.name) }
- it { should have_content(@merge_request1.target_branch) }
- it { should have_content(@merge_request1.source_branch) }
- it { should have_content(@merge_request1.assignee.name) }
-
it { should have_content(@merge_request2.title[0..10]) }
it { should have_content(@merge_request2.project.name) }
- it { should have_content(@merge_request2.target_branch) }
- it { should have_content(@merge_request2.source_branch) }
- it { should have_content(@merge_request2.assignee.name) }
end
end
diff --git a/spec/requests/dashboard_spec.rb b/spec/requests/dashboard_spec.rb
index 69ddd1758ba..98de046fee1 100644
--- a/spec/requests/dashboard_spec.rb
+++ b/spec/requests/dashboard_spec.rb
@@ -1,5 +1,6 @@
require 'spec_helper'
-
+__END__
+# Disabled for now
describe "Dashboard" do
before do
@project = Factory :project
diff --git a/spec/requests/issues_spec.rb b/spec/requests/issues_spec.rb
index 62daf168b78..bff99531ee7 100644
--- a/spec/requests/issues_spec.rb
+++ b/spec/requests/issues_spec.rb
@@ -51,17 +51,17 @@ describe "Issues" do
# admin access to remove issue
@user.users_projects.destroy_all
project.add_access(@user, :read, :write, :admin)
- visit project_issues_path(project)
+ visit edit_project_issue_path(project, @issue)
end
it "should remove entry" do
expect {
- click_link "destroy_issue_#{@issue.id}"
+ click_link "Remove"
}.to change { Issue.count }.by(-1)
end
end
- describe "statuses", :js => true do
+ describe "statuses" do
before do
@closed_issue = Factory :issue,
:author => @user,
@@ -76,13 +76,13 @@ describe "Issues" do
end
it "should show only closed" do
- choose "closed_issues"
+ click_link "Closed"
should have_no_content(@issue.title)
should have_content(@closed_issue.title[0..25])
end
it "should show all" do
- choose "all_issues"
+ click_link "All"
should have_content(@issue.title[0..25])
should have_content(@closed_issue.title[0..25])
end
@@ -182,7 +182,6 @@ describe "Issues" do
:assignee => @user,
:project => project
visit project_issues_path(project)
- page.execute_script("$('.action-links').css('display', 'block');")
click_link "Edit"
end
@@ -200,7 +199,6 @@ describe "Issues" do
it "should update issue fields" do
click_button "Save"
- page.should_not have_content("Issue ##{@issue.id}")
page.should have_content @user.name
page.should have_content "bug 345"
page.should have_content project.name
@@ -226,7 +224,7 @@ describe "Issues" do
@issue.save
visit project_issues_path(project)
- choose 'closed_issues'
+ click_link 'Closed'
fill_in 'issue_search', :with => 'foobar'
page.should have_content 'foobar'
diff --git a/spec/requests/keys_spec.rb b/spec/requests/keys_spec.rb
index be1f42a497c..2bc7c75ba0d 100644
--- a/spec/requests/keys_spec.rb
+++ b/spec/requests/keys_spec.rb
@@ -26,14 +26,14 @@ describe "Issues" do
end
end
- describe "New key", :js => true do
+ describe "New key" do
before do
visit keys_path
click_link "Add new"
end
it "should open new key popup" do
- page.should have_content("Add new public key")
+ page.should have_content("New key")
end
describe "fill in" do
@@ -47,7 +47,7 @@ describe "Issues" do
it "should add new key to table" do
click_button "Save"
- page.should_not have_content("Add new public key")
+ page.should_not have_content("New key")
page.should have_content "laptop"
end
end
diff --git a/spec/requests/merge_requests_spec.rb b/spec/requests/merge_requests_spec.rb
index 7d9fd67b926..f7b7e919ca8 100644
--- a/spec/requests/merge_requests_spec.rb
+++ b/spec/requests/merge_requests_spec.rb
@@ -42,9 +42,7 @@ describe "MergeRequests" do
it { should have_content(@merge_request.title[0..10]) }
it "Show page should inform user that merge request closed" do
- within ".merge-tabs" do
- page.should have_content "Reopen"
- end
+ page.should have_content "Reopen"
end
end
end
diff --git a/spec/requests/projects_security_spec.rb b/spec/requests/projects_security_spec.rb
index f8942978a46..cf97716cc59 100644
--- a/spec/requests/projects_security_spec.rb
+++ b/spec/requests/projects_security_spec.rb
@@ -20,11 +20,9 @@ describe "Projects" do
@u2 = Factory :user
@u3 = Factory :user
# full access
- @project.users_projects.create(:user => @u1, :project_access => Project::PROJECT_RWA)
- # no access
- @project.users_projects.create(:user => @u2, :project_access => Project::PROJECT_N)
+ @project.users_projects.create(:user => @u1, :project_access => UsersProject::MASTER)
# readonly
- @project.users_projects.create(:user => @u3, :project_access => Project::PROJECT_R)
+ @project.users_projects.create(:user => @u3, :project_access => UsersProject::REPORTER)
end
describe "GET /project_code" do
diff --git a/spec/requests/projects_spec.rb b/spec/requests/projects_spec.rb
index 6db900c0d52..e6b6f19cbcd 100644
--- a/spec/requests/projects_spec.rb
+++ b/spec/requests/projects_spec.rb
@@ -5,7 +5,7 @@ describe "Projects" do
describe "GET /projects" do
before do
- @project = Factory :project
+ @project = Factory :project, :owner => @user
@project.add_access(@user, :read)
visit projects_path
end
@@ -15,7 +15,7 @@ describe "Projects" do
end
it "should have link to new project" do
- page.should have_content("Create new project")
+ page.should have_content("New Project")
end
it "should have project" do
@@ -26,7 +26,7 @@ describe "Projects" do
describe "GET /projects/new" do
before do
visit projects_path
- click_link "Create new project"
+ click_link "New Project"
end
it "should be correct path" do
@@ -68,7 +68,7 @@ describe "Projects" do
describe "GET /projects/show" do
before do
- @project = Factory :project
+ @project = Factory :project, :owner => @user
@project.add_access(@user, :read)
visit project_path(@project)
@@ -128,7 +128,7 @@ describe "Projects" do
describe "PUT /projects/:id" do
before do
- @project = Factory :project
+ @project = Factory :project, :owner => @user
@project.add_access(@user, :admin, :read)
visit edit_project_path(@project)
@@ -141,7 +141,7 @@ describe "Projects" do
end
it "should be correct path" do
- current_path.should == info_project_path(@project)
+ current_path.should == edit_project_path(@project)
end
it "should show project" do
diff --git a/spec/requests/projects_wall_spec.rb b/spec/requests/projects_wall_spec.rb
index bb734bdab23..b0ea6e6225a 100644
--- a/spec/requests/projects_wall_spec.rb
+++ b/spec/requests/projects_wall_spec.rb
@@ -8,7 +8,7 @@ describe "Projects", "Wall" do
project.add_access(@user, :read, :write)
end
- describe "View notes on wall" do
+ describe "View notes on wall", :js => true do
before do
Factory :note, :project => project, :note => "Project specs", :author => @user
visit wall_project_path(project)
diff --git a/spec/requests/repositories_spec.rb b/spec/requests/repositories_spec.rb
index 0b5d378daed..3fb5371bbbf 100644
--- a/spec/requests/repositories_spec.rb
+++ b/spec/requests/repositories_spec.rb
@@ -18,17 +18,8 @@ describe "Repository" do
current_path.should == project_repository_path(@project)
end
- it "should have link to repo activities" do
- page.should have_content("Activities")
- end
-
it "should have link to last commit for activities tab" do
page.should have_content(@project.commit.safe_message[0..20])
- page.should have_content(@project.commit.author_name)
- end
-
- it "should show commits list" do
- page.all(:css, ".project-update").size.should == @project.repo.branches.size
end
end
diff --git a/spec/requests/snippets_spec.rb b/spec/requests/snippets_spec.rb
index f0531a0a108..9b9bb0e96c5 100644
--- a/spec/requests/snippets_spec.rb
+++ b/spec/requests/snippets_spec.rb
@@ -21,7 +21,6 @@ describe "Snippets" do
it { should have_content(@snippet.title[0..10]) }
it { should have_content(@snippet.project.name) }
- it { should have_content(@snippet.author.name) }
describe "Destroy" do
before do
@@ -73,7 +72,7 @@ describe "Snippets" do
:author => @user,
:project => project
visit project_snippet_path(project, @snippet)
- click_link "Edit Snippet"
+ click_link "Edit"
end
it "should open edit page" do
diff --git a/spec/requests/team_members_spec.rb b/spec/requests/team_members_spec.rb
index 997de8b8356..78385725639 100644
--- a/spec/requests/team_members_spec.rb
+++ b/spec/requests/team_members_spec.rb
@@ -10,9 +10,7 @@ describe "TeamMembers" do
describe "View profile" do
it "should be available" do
visit(team_project_path(@project))
- within "#team-table" do
- click_link(@user.name)
- end
+ click_link(@user.name)
page.should have_content @user.skype
page.should_not have_content 'Twitter'
end
@@ -31,10 +29,9 @@ describe "TeamMembers" do
describe "fill in" do
before do
- within "#team_member_new" do
+ within "#new_team_member" do
select @user_1.name, :from => "team_member_user_id"
- select "Report", :from => "team_member_project_access"
- select "Pull", :from => "team_member_repo_access"
+ select "Reporter", :from => "team_member_project_access"
end
end
@@ -47,16 +44,15 @@ describe "TeamMembers" do
page.should have_content @user_1.name
@member.reload
- @member.project_access.should == Project::PROJECT_RW
- @member.repo_access.should == Repository::REPO_R
+ @member.project_access.should == UsersProject::REPORTER
end
end
end
describe "Cancel membership" do
it "should cancel membership" do
- visit team_project_path(@project)
- expect { click_link "Cancel" }.to change { UsersProject.count }.by(-1)
+ visit project_team_member_path(@project, @project.users_projects.last)
+ expect { click_link "Remove from team" }.to change { UsersProject.count }.by(-1)
end
end
end
diff --git a/spec/requests/wikis_spec.rb b/spec/requests/wikis_spec.rb
new file mode 100644
index 00000000000..fd66b5e4300
--- /dev/null
+++ b/spec/requests/wikis_spec.rb
@@ -0,0 +1,35 @@
+require 'spec_helper'
+
+describe "Wiki" do
+ let(:project) { Factory :project }
+
+ before do
+ login_as :user
+ project.add_access(@user, :read, :write)
+ end
+
+ describe "Add pages" do
+ before do
+ visit project_wiki_path(project, :index)
+ end
+
+ it "should see form" do
+ page.should have_content("Editing page")
+ end
+
+ it "should see added page" do
+ fill_in "Title", :with => 'Test title'
+ fill_in "Content", :with => '[link test](test)'
+ click_on "Save"
+
+ page.should have_content("Test title")
+ page.should have_content("link test")
+
+ click_link "link test"
+
+ page.should have_content("Editing page")
+ end
+
+ end
+
+end
diff --git a/spec/support/shared_examples.rb b/spec/support/shared_examples.rb
index 22699b0cfde..9fd207d0db2 100644
--- a/spec/support/shared_examples.rb
+++ b/spec/support/shared_examples.rb
@@ -2,8 +2,7 @@ shared_examples_for :project_side_pane do
subject { page }
it { should have_content((@project || project).name) }
it { should have_content("Commits") }
- it { should have_content("Team") }
- it { should have_content("Tree") }
+ it { should have_content("Files") }
end
shared_examples_for :tree_view do
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index 500a69982c7..c28273d5e81 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -10,17 +10,22 @@ describe PostReceive do
context "web hooks" do
let(:project) { Factory :project }
+ before do
+ @key = Factory :key, :user => project.owner
+ @key_id = @key.identifier
+ end
it "it retrieves the correct project" do
Project.should_receive(:find_by_path).with(project.path)
- PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master')
+ Key.should_receive(:find_by_identifier).with(project.path)
+ PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', @key_id)
end
it "asks the project to execute web hooks" do
Project.stub(find_by_path: project)
- project.should_receive(:execute_web_hooks).with('sha-old', 'sha-new', 'refs/heads/master')
+ project.should_receive(:execute_web_hooks).with('sha-old', 'sha-new', 'refs/heads/master', @key_id)
- PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master')
+ PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', @key_id)
end
end
end
diff --git a/vendor/assets/javascripts/bootstrap-modal.js b/vendor/assets/javascripts/bootstrap-modal.js
new file mode 100644
index 00000000000..b328217f813
--- /dev/null
+++ b/vendor/assets/javascripts/bootstrap-modal.js
@@ -0,0 +1,260 @@
+/* =========================================================
+ * bootstrap-modal.js v1.4.0
+ * http://twitter.github.com/bootstrap/javascript.html#modal
+ * =========================================================
+ * Copyright 2011 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================= */
+
+
+!function( $ ){
+
+ "use strict"
+
+ /* CSS TRANSITION SUPPORT (https://gist.github.com/373874)
+ * ======================================================= */
+
+ var transitionEnd
+
+ $(document).ready(function () {
+
+ $.support.transition = (function () {
+ var thisBody = document.body || document.documentElement
+ , thisStyle = thisBody.style
+ , support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined
+ return support
+ })()
+
+ // set CSS transition event type
+ if ( $.support.transition ) {
+ transitionEnd = "TransitionEnd"
+ if ( $.browser.webkit ) {
+ transitionEnd = "webkitTransitionEnd"
+ } else if ( $.browser.mozilla ) {
+ transitionEnd = "transitionend"
+ } else if ( $.browser.opera ) {
+ transitionEnd = "oTransitionEnd"
+ }
+ }
+
+ })
+
+
+ /* MODAL PUBLIC CLASS DEFINITION
+ * ============================= */
+
+ var Modal = function ( content, options ) {
+ this.settings = $.extend({}, $.fn.modal.defaults, options)
+ this.$element = $(content)
+ .delegate('.close', 'click.modal', $.proxy(this.hide, this))
+
+ if ( this.settings.show ) {
+ this.show()
+ }
+
+ return this
+ }
+
+ Modal.prototype = {
+
+ toggle: function () {
+ return this[!this.isShown ? 'show' : 'hide']()
+ }
+
+ , show: function () {
+ var that = this
+ this.isShown = true
+ this.$element.trigger('show')
+
+ escape.call(this)
+ backdrop.call(this, function () {
+ var transition = $.support.transition && that.$element.hasClass('fade')
+
+ that.$element
+ .appendTo(document.body)
+ .show()
+
+ if (transition) {
+ that.$element[0].offsetWidth // force reflow
+ }
+
+ that.$element.addClass('in')
+
+ transition ?
+ that.$element.one(transitionEnd, function () { that.$element.trigger('shown') }) :
+ that.$element.trigger('shown')
+
+ })
+
+ return this
+ }
+
+ , hide: function (e) {
+ e && e.preventDefault()
+
+ if ( !this.isShown ) {
+ return this
+ }
+
+ var that = this
+ this.isShown = false
+
+ escape.call(this)
+
+ this.$element
+ .trigger('hide')
+ .removeClass('in')
+
+ $.support.transition && this.$element.hasClass('fade') ?
+ hideWithTransition.call(this) :
+ hideModal.call(this)
+
+ return this
+ }
+
+ }
+
+
+ /* MODAL PRIVATE METHODS
+ * ===================== */
+
+ function hideWithTransition() {
+ // firefox drops transitionEnd events :{o
+ var that = this
+ , timeout = setTimeout(function () {
+ that.$element.unbind(transitionEnd)
+ hideModal.call(that)
+ }, 500)
+
+ this.$element.one(transitionEnd, function () {
+ clearTimeout(timeout)
+ hideModal.call(that)
+ })
+ }
+
+ function hideModal (that) {
+ this.$element
+ .hide()
+ .trigger('hidden')
+
+ backdrop.call(this)
+ }
+
+ function backdrop ( callback ) {
+ var that = this
+ , animate = this.$element.hasClass('fade') ? 'fade' : ''
+ if ( this.isShown && this.settings.backdrop ) {
+ var doAnimate = $.support.transition && animate
+
+ this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
+ .appendTo(document.body)
+
+ if ( this.settings.backdrop != 'static' ) {
+ this.$backdrop.click($.proxy(this.hide, this))
+ }
+
+ if ( doAnimate ) {
+ this.$backdrop[0].offsetWidth // force reflow
+ }
+
+ this.$backdrop.addClass('in')
+
+ doAnimate ?
+ this.$backdrop.one(transitionEnd, callback) :
+ callback()
+
+ } else if ( !this.isShown && this.$backdrop ) {
+ this.$backdrop.removeClass('in')
+
+ $.support.transition && this.$element.hasClass('fade')?
+ this.$backdrop.one(transitionEnd, $.proxy(removeBackdrop, this)) :
+ removeBackdrop.call(this)
+
+ } else if ( callback ) {
+ callback()
+ }
+ }
+
+ function removeBackdrop() {
+ this.$backdrop.remove()
+ this.$backdrop = null
+ }
+
+ function escape() {
+ var that = this
+ if ( this.isShown && this.settings.keyboard ) {
+ $(document).bind('keyup.modal', function ( e ) {
+ if ( e.which == 27 ) {
+ that.hide()
+ }
+ })
+ } else if ( !this.isShown ) {
+ $(document).unbind('keyup.modal')
+ }
+ }
+
+
+ /* MODAL PLUGIN DEFINITION
+ * ======================= */
+
+ $.fn.modal = function ( options ) {
+ var modal = this.data('modal')
+
+ if (!modal) {
+
+ if (typeof options == 'string') {
+ options = {
+ show: /show|toggle/.test(options)
+ }
+ }
+
+ return this.each(function () {
+ $(this).data('modal', new Modal(this, options))
+ })
+ }
+
+ if ( options === true ) {
+ return modal
+ }
+
+ if ( typeof options == 'string' ) {
+ modal[options]()
+ } else if ( modal ) {
+ modal.toggle()
+ }
+
+ return this
+ }
+
+ $.fn.modal.Modal = Modal
+
+ $.fn.modal.defaults = {
+ backdrop: false
+ , keyboard: false
+ , show: false
+ }
+
+
+ /* MODAL DATA- IMPLEMENTATION
+ * ========================== */
+
+ $(document).ready(function () {
+ $('body').delegate('[data-controls-modal]', 'click', function (e) {
+ e.preventDefault()
+ var $this = $(this).data('show', true)
+ $('#' + $this.attr('data-controls-modal')).modal( $this.data() )
+ })
+ })
+
+}( window.jQuery || window.ender );
diff --git a/vendor/assets/javascripts/bootstrap-popover.js b/vendor/assets/javascripts/bootstrap-popover.js
new file mode 100644
index 00000000000..cf6dadf0a5e
--- /dev/null
+++ b/vendor/assets/javascripts/bootstrap-popover.js
@@ -0,0 +1,86 @@
+/* ===========================================================
+ * bootstrap-popover.js v1.4.0
+ * http://twitter.github.com/bootstrap/javascript.html#popover
+ * ===========================================================
+ * Copyright 2011 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * =========================================================== */
+
+
+!function( $ ) {
+
+ "use strict"
+
+ var Popover = function ( element, options ) {
+ this.$element = $(element)
+ this.options = options
+ this.enabled = true
+ this.fixTitle()
+ }
+
+ /* NOTE: POPOVER EXTENDS BOOTSTRAP-TWIPSY.js
+ ========================================= */
+
+ Popover.prototype = $.extend({}, $.fn.twipsy.Twipsy.prototype, {
+
+ setContent: function () {
+ var $tip = this.tip()
+ $tip.find('.title')[this.options.html ? 'html' : 'text'](this.getTitle())
+ $tip.find('.content p')[this.options.html ? 'html' : 'text'](this.getContent())
+ $tip[0].className = 'popover'
+ }
+
+ , hasContent: function () {
+ return this.getTitle() || this.getContent()
+ }
+
+ , getContent: function () {
+ var content
+ , $e = this.$element
+ , o = this.options
+
+ if (typeof this.options.content == 'string') {
+ content = this.options.content
+ } else if (typeof this.options.content == 'function') {
+ content = this.options.content.call(this.$element[0])
+ }
+ return content
+ }
+
+ , tip: function() {
+ if (!this.$tip) {
+ this.$tip = $('<div class="popover" />')
+ .html(this.options.template)
+ }
+ return this.$tip
+ }
+
+ })
+
+
+ /* POPOVER PLUGIN DEFINITION
+ * ======================= */
+
+ $.fn.popover = function (options) {
+ if (typeof options == 'object') options = $.extend({}, $.fn.popover.defaults, options)
+ $.fn.twipsy.initWith.call(this, options, Popover, 'popover')
+ return this
+ }
+
+ $.fn.popover.defaults = $.extend({} , $.fn.twipsy.defaults, {
+ placement: 'right'
+ , template: '<div class="arrow"></div><div class="inner"><h3 class="title"></h3><div class="content"><p></p></div></div>'
+ })
+
+}( window.jQuery || window.ender ); \ No newline at end of file
diff --git a/vendor/assets/javascripts/jquery.endless-scroll.js b/vendor/assets/javascripts/jquery.endless-scroll.js
new file mode 100644
index 00000000000..38db6b05101
--- /dev/null
+++ b/vendor/assets/javascripts/jquery.endless-scroll.js
@@ -0,0 +1,128 @@
+/**
+ * Endless Scroll plugin for jQuery
+ *
+ * v1.4.8
+ *
+ * Copyright (c) 2008 Fred Wu
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ */
+
+/**
+ * Usage:
+ *
+ * // using default options
+ * $(document).endlessScroll();
+ *
+ * // using some custom options
+ * $(document).endlessScroll({
+ * fireOnce: false,
+ * fireDelay: false,
+ * loader: "<div class=\"loading\"><div>",
+ * callback: function(){
+ * alert("test");
+ * }
+ * });
+ *
+ * Configuration options:
+ *
+ * bottomPixels integer the number of pixels from the bottom of the page that triggers the event
+ * fireOnce boolean only fire once until the execution of the current event is completed
+ * fireDelay integer delay the subsequent firing, in milliseconds, 0 or false to disable delay
+ * loader string the HTML to be displayed during loading
+ * data string|function plain HTML data, can be either a string or a function that returns a string,
+ * when passed as a function it accepts one argument: fire sequence (the number
+ * of times the event triggered during the current page session)
+ * insertAfter string jQuery selector syntax: where to put the loader as well as the plain HTML data
+ * callback function callback function, accepts one argument: fire sequence (the number of times
+ * the event triggered during the current page session)
+ * resetCounter function resets the fire sequence counter if the function returns true, this function
+ * could also perform hook actions since it is applied at the start of the event
+ * ceaseFire function stops the event (no more endless scrolling) if the function returns true
+ *
+ * Usage tips:
+ *
+ * The plugin is more useful when used with the callback function, which can then make AJAX calls to retrieve content.
+ * The fire sequence argument (for the callback function) is useful for 'pagination'-like features.
+ */
+
+(function($){
+
+ $.fn.endlessScroll = function(options) {
+
+ var defaults = {
+ bottomPixels : 50,
+ fireOnce : true,
+ fireDelay : 150,
+ loader : "<br />Loading...<br />",
+ data : "",
+ insertAfter : "div:last",
+ resetCounter : function() { return false; },
+ callback : function() { return true; },
+ ceaseFire : function() { return false; }
+ };
+
+ var options = $.extend({}, defaults, options),
+ firing = true,
+ fired = false,
+ fireSequence = 0,
+ is_scrollable;
+
+ if (options.ceaseFire.apply(this) === true)
+ firing = false;
+
+ if (firing === true) {
+ $(this).scroll(function() {
+ if (options.ceaseFire.apply(this) === true) {
+ firing = false;
+ return; // Scroll will still get called, but nothing will happen
+ }
+
+ if (this == document || this == window) {
+ is_scrollable = $(document).height() - $(window).height() <= $(window).scrollTop() + options.bottomPixels;
+ } else {
+ // calculates the actual height of the scrolling container
+ var inner_wrap = $(".endless_scroll_inner_wrap", this);
+ if (inner_wrap.length == 0)
+ inner_wrap = $(this).wrapInner("<div class=\"endless_scroll_inner_wrap\" />").find(".endless_scroll_inner_wrap");
+ is_scrollable = inner_wrap.length > 0 &&
+ (inner_wrap.height() - $(this).height() <= $(this).scrollTop() + options.bottomPixels);
+ }
+
+ if (is_scrollable && (options.fireOnce == false || (options.fireOnce == true && fired != true))) {
+ if (options.resetCounter.apply(this) === true) fireSequence = 0;
+
+ fired = true;
+ fireSequence++;
+
+ $(options.insertAfter).after("<div id=\"endless_scroll_loader\">" + options.loader + "</div>");
+
+ data = typeof options.data == 'function' ? options.data.apply(this, [fireSequence]) : options.data;
+
+ if (data !== false) {
+ $(options.insertAfter).after("<div id=\"endless_scroll_data\">" + data + "</div>");
+ $("#endless_scroll_data").hide().fadeIn(250, function() {$(this).removeAttr("id");});
+
+ options.callback.apply(this, [fireSequence]);
+
+ if (options.fireDelay !== false || options.fireDelay !== 0) {
+ $("body").after("<div id=\"endless_scroll_marker\"></div>");
+ // slight delay for preventing event firing twice
+ $("#endless_scroll_marker").fadeTo(options.fireDelay, 1, function() {
+ $(this).remove();
+ fired = false;
+ });
+ }
+ else
+ fired = false;
+ }
+
+ $("#endless_scroll_loader").remove();
+ }
+ });
+ }
+ };
+
+})(jQuery); \ No newline at end of file