summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--.rails_footnotes3
-rw-r--r--.travis.yml3
-rw-r--r--CHANGELOG20
-rw-r--r--Gemfile66
-rw-r--r--Gemfile.lock102
-rw-r--r--VERSION2
-rw-r--r--app/assets/fonts/korolev-medium-compressed.otfbin0 -> 28796 bytes
-rw-r--r--app/assets/images/file_dir.pngbin485 -> 517 bytes
-rw-r--r--app/assets/images/gitlab_classic.pngbin0 -> 3054 bytes
-rw-r--r--app/assets/images/gitlab_default.pngbin0 -> 6435 bytes
-rw-r--r--app/assets/images/gitlab_modern.pngbin0 -> 3892 bytes
-rw-r--r--app/assets/images/logo_dark.pngbin0 -> 2858 bytes
-rw-r--r--app/assets/images/logo_white.pngbin0 -> 1681 bytes
-rw-r--r--app/assets/javascripts/application.js35
-rw-r--r--app/assets/javascripts/issues.js29
-rw-r--r--app/assets/javascripts/merge_requests.js1
-rw-r--r--app/assets/javascripts/note.js2
-rw-r--r--app/assets/javascripts/pager.js1
-rw-r--r--app/assets/stylesheets/application.css3
-rw-r--r--app/assets/stylesheets/common.scss281
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap.scss331
-rw-r--r--app/assets/stylesheets/jquery_ui.scss33
-rw-r--r--app/assets/stylesheets/main.scss52
-rw-r--r--app/assets/stylesheets/ref_select.scss4
-rw-r--r--app/assets/stylesheets/sections/commits.scss12
-rw-r--r--app/assets/stylesheets/sections/graph.scss6
-rw-r--r--app/assets/stylesheets/sections/header.scss (renamed from app/assets/stylesheets/header.scss)61
-rw-r--r--app/assets/stylesheets/sections/issues.scss65
-rw-r--r--app/assets/stylesheets/sections/login.scss (renamed from app/assets/stylesheets/login.scss)2
-rw-r--r--app/assets/stylesheets/sections/merge_requests.scss5
-rw-r--r--app/assets/stylesheets/sections/nav.scss (renamed from app/assets/stylesheets/nav.scss)7
-rw-r--r--app/assets/stylesheets/sections/notes.scss (renamed from app/assets/stylesheets/notes.scss)103
-rw-r--r--app/assets/stylesheets/sections/projects.scss22
-rw-r--r--app/assets/stylesheets/sections/tree.scss10
-rw-r--r--app/assets/stylesheets/themes/ui_basic.scss42
-rw-r--r--app/assets/stylesheets/themes/ui_mars.scss47
-rw-r--r--app/assets/stylesheets/themes/ui_modern.scss161
-rw-r--r--app/contexts/base_context.rb20
-rw-r--r--app/contexts/commit_load.rb33
-rw-r--r--app/contexts/issues_bulk_update_context.rb24
-rw-r--r--app/contexts/merge_requests_load.rb16
-rw-r--r--app/contexts/notes/create_context.rb12
-rw-r--r--app/contexts/notes/load_context.rb34
-rw-r--r--app/contexts/test_hook_context.rb8
-rw-r--r--app/controllers/admin/hooks_controller.rb44
-rw-r--r--app/controllers/admin/mailer_controller.rb45
-rw-r--r--app/controllers/admin/projects_controller.rb35
-rw-r--r--app/controllers/admin/users_controller.rb2
-rw-r--r--app/controllers/application_controller.rb19
-rw-r--r--app/controllers/commits_controller.rb60
-rw-r--r--app/controllers/dashboard_controller.rb12
-rw-r--r--app/controllers/deploy_keys_controller.rb2
-rw-r--r--app/controllers/hooks_controller.rb17
-rw-r--r--app/controllers/issues_controller.rb40
-rw-r--r--app/controllers/keys_controller.rb2
-rw-r--r--app/controllers/labels_controller.rb25
-rw-r--r--app/controllers/merge_requests_controller.rb32
-rw-r--r--app/controllers/milestones_controller.rb6
-rw-r--r--app/controllers/notes_controller.rb37
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb14
-rw-r--r--app/controllers/profile_controller.rb16
-rw-r--r--app/controllers/projects_controller.rb14
-rw-r--r--app/controllers/protected_branches_controller.rb4
-rw-r--r--app/controllers/refs_controller.rb18
-rw-r--r--app/controllers/search_controller.rb15
-rw-r--r--app/controllers/snippets_controller.rb16
-rw-r--r--app/controllers/team_members_controller.rb5
-rw-r--r--app/controllers/wikis_controller.rb32
-rw-r--r--app/decorators/application_decorator.rb4
-rw-r--r--app/decorators/event_decorator.rb2
-rw-r--r--app/decorators/tree_decorator.rb6
-rw-r--r--app/helpers/application_helper.rb58
-rw-r--r--app/helpers/commits_helper.rb18
-rw-r--r--app/helpers/gitlab_markdown_helper.rb70
-rw-r--r--app/helpers/issues_helper.rb11
-rw-r--r--app/helpers/merge_requests_helper.rb12
-rw-r--r--app/helpers/tab_helper.rb4
-rw-r--r--app/mailers/notify.rb76
-rw-r--r--app/models/commit.rb37
-rw-r--r--app/models/event.rb14
-rw-r--r--app/models/issue.rb46
-rw-r--r--app/models/key.rb12
-rw-r--r--app/models/merge_request.rb78
-rw-r--r--app/models/milestone.rb16
-rw-r--r--app/models/note.rb38
-rw-r--r--app/models/project.rb80
-rw-r--r--app/models/project_hook.rb3
-rw-r--r--app/models/snippet.rb20
-rw-r--r--app/models/system_hook.rb13
-rw-r--r--app/models/tree.rb2
-rw-r--r--app/models/user.rb87
-rw-r--r--app/models/users_project.rb12
-rw-r--r--app/models/web_hook.rb16
-rw-r--r--app/models/wiki.rb5
-rw-r--r--app/observers/activity_observer.rb20
-rw-r--r--app/observers/mailer_observer.rb3
-rw-r--r--app/observers/system_hook_observer.rb67
-rw-r--r--app/roles/account.rb10
-rw-r--r--app/roles/authority.rb26
-rw-r--r--app/roles/issue_commonality.rb52
-rw-r--r--app/roles/push_observer.rb (renamed from app/roles/git_push.rb)18
-rw-r--r--app/roles/repository.rb18
-rw-r--r--app/roles/ssh_key.rb2
-rw-r--r--app/roles/team.rb29
-rw-r--r--app/uploaders/attachment_uploader.rb4
-rw-r--r--app/views/admin/dashboard/index.html.haml16
-rw-r--r--app/views/admin/hooks/_data_ex.html.erb66
-rw-r--r--app/views/admin/hooks/index.html.haml39
-rw-r--r--app/views/admin/mailer/preview.html.haml28
-rw-r--r--app/views/admin/projects/_form.html.haml83
-rw-r--r--app/views/admin/projects/edit.html.haml4
-rw-r--r--app/views/admin/projects/index.html.haml18
-rw-r--r--app/views/admin/projects/new.html.haml4
-rw-r--r--app/views/admin/projects/show.html.haml24
-rw-r--r--app/views/admin/resque/show.html.haml2
-rw-r--r--app/views/admin/team_members/_form.html.haml8
-rw-r--r--app/views/admin/users/_form.html.haml122
-rw-r--r--app/views/admin/users/edit.html.haml2
-rw-r--r--app/views/admin/users/index.html.haml36
-rw-r--r--app/views/admin/users/new.html.haml4
-rw-r--r--app/views/admin/users/show.html.haml22
-rw-r--r--app/views/commits/_commit.html.haml23
-rw-r--r--app/views/commits/_commit_box.html.haml14
-rw-r--r--app/views/commits/_diff_head.html.haml8
-rw-r--r--app/views/commits/_diffs.html.haml16
-rw-r--r--app/views/commits/_head.html.haml16
-rw-r--r--app/views/commits/_text_file.html.haml14
-rw-r--r--app/views/commits/compare.html.haml15
-rw-r--r--app/views/commits/index.atom.builder4
-rw-r--r--app/views/commits/index.html.haml6
-rw-r--r--app/views/commits/index.js.haml2
-rw-r--r--app/views/commits/show.html.haml4
-rw-r--r--app/views/dashboard/index.html.haml32
-rw-r--r--app/views/dashboard/index.js.haml2
-rw-r--r--app/views/dashboard/issues.html.haml8
-rw-r--r--app/views/dashboard/merge_requests.html.haml10
-rw-r--r--app/views/deploy_keys/_form.html.haml8
-rw-r--r--app/views/deploy_keys/_show.html.haml4
-rw-r--r--app/views/deploy_keys/index.html.haml4
-rw-r--r--app/views/deploy_keys/show.html.haml2
-rw-r--r--app/views/devise/passwords/edit.html.haml12
-rw-r--r--app/views/errors/access_denied.html.haml9
-rw-r--r--app/views/errors/encoding.html.haml3
-rw-r--r--app/views/errors/git_not_found.html.haml15
-rw-r--r--app/views/errors/gitolite.html.haml24
-rw-r--r--app/views/errors/not_found.html.haml9
-rw-r--r--app/views/events/_commit.html.haml17
-rw-r--r--app/views/events/_event.html.haml6
-rw-r--r--app/views/events/_event_issue.html.haml4
-rw-r--r--app/views/events/_event_last_push.html.haml8
-rw-r--r--app/views/events/_event_merge_request.html.haml4
-rw-r--r--app/views/events/_event_push.html.haml10
-rw-r--r--app/views/help/api.html.haml38
-rw-r--r--app/views/help/index.html.haml9
-rw-r--r--app/views/help/markdown.html.haml25
-rw-r--r--app/views/help/permissions.html.haml6
-rw-r--r--app/views/help/ssh.html.haml25
-rw-r--r--app/views/help/system_hooks.html.haml13
-rw-r--r--app/views/help/web_hooks.html.haml8
-rw-r--r--app/views/help/workflow.html.haml13
-rw-r--r--app/views/hooks/index.html.haml12
-rw-r--r--app/views/issues/_form.html.haml34
-rw-r--r--app/views/issues/_head.html.haml15
-rw-r--r--app/views/issues/_issues.html.haml5
-rw-r--r--app/views/issues/_show.html.haml22
-rw-r--r--app/views/issues/create.js.haml2
-rw-r--r--app/views/issues/index.html.haml73
-rw-r--r--app/views/issues/show.html.haml18
-rw-r--r--app/views/kaminari/admin/_first_page.html.haml2
-rw-r--r--app/views/kaminari/admin/_last_page.html.haml2
-rw-r--r--app/views/kaminari/admin/_next_page.html.haml2
-rw-r--r--app/views/kaminari/admin/_page.html.haml4
-rw-r--r--app/views/kaminari/admin/_prev_page.html.haml4
-rw-r--r--app/views/kaminari/gitlab/_first_page.html.haml2
-rw-r--r--app/views/kaminari/gitlab/_last_page.html.haml2
-rw-r--r--app/views/kaminari/gitlab/_next_page.html.haml2
-rw-r--r--app/views/kaminari/gitlab/_page.html.haml4
-rw-r--r--app/views/kaminari/gitlab/_prev_page.html.haml2
-rw-r--r--app/views/keys/_form.html.haml12
-rw-r--r--app/views/keys/_show.html.haml2
-rw-r--r--app/views/keys/create.js.haml2
-rw-r--r--app/views/keys/index.html.haml6
-rw-r--r--app/views/keys/new.html.haml2
-rw-r--r--app/views/keys/show.html.haml2
-rw-r--r--app/views/labels/_label.html.haml4
-rw-r--r--app/views/labels/index.html.haml14
-rw-r--r--app/views/layouts/_app_menu.html.haml12
-rw-r--r--app/views/layouts/_flash.html.haml2
-rw-r--r--app/views/layouts/_head.html.haml9
-rw-r--r--app/views/layouts/_head_panel.html.haml16
-rw-r--r--app/views/layouts/_project_menu.html.haml18
-rw-r--r--app/views/layouts/admin.html.haml20
-rw-r--r--app/views/layouts/application.html.haml8
-rw-r--r--app/views/layouts/devise_layout.html.haml4
-rw-r--r--app/views/layouts/error.html.haml10
-rw-r--r--app/views/layouts/notify.html.haml33
-rw-r--r--app/views/layouts/profile.html.haml23
-rw-r--r--app/views/layouts/project.html.haml8
-rw-r--r--app/views/merge_requests/_form.html.haml20
-rw-r--r--app/views/merge_requests/_head.html.haml2
-rw-r--r--app/views/merge_requests/_merge_request.html.haml7
-rw-r--r--app/views/merge_requests/_show.html.haml11
-rw-r--r--app/views/merge_requests/branch_from.js.haml2
-rw-r--r--app/views/merge_requests/branch_to.js.haml2
-rw-r--r--app/views/merge_requests/commits.js.haml2
-rw-r--r--app/views/merge_requests/diffs.js.haml2
-rw-r--r--app/views/merge_requests/index.html.haml20
-rw-r--r--app/views/merge_requests/show.js.haml2
-rw-r--r--app/views/merge_requests/show/_commits.html.haml6
-rw-r--r--app/views/merge_requests/show/_diffs.html.haml4
-rw-r--r--app/views/merge_requests/show/_how_to_merge.html.haml13
-rw-r--r--app/views/merge_requests/show/_mr_accept.html.haml21
-rw-r--r--app/views/merge_requests/show/_mr_box.html.haml6
-rw-r--r--app/views/merge_requests/show/_mr_title.html.haml6
-rw-r--r--app/views/milestones/_form.html.haml28
-rw-r--r--app/views/milestones/_milestone.html.haml21
-rw-r--r--app/views/milestones/index.html.haml12
-rw-r--r--app/views/milestones/show.html.haml16
-rw-r--r--app/views/notes/_create_common.js.haml6
-rw-r--r--app/views/notes/_create_line.js.haml4
-rw-r--r--app/views/notes/_form.html.haml51
-rw-r--r--app/views/notes/_load.js.haml6
-rw-r--r--app/views/notes/_notes_list.html.haml2
-rw-r--r--app/views/notes/_per_line_form.html.haml36
-rw-r--r--app/views/notes/_per_line_show.html.haml4
-rw-r--r--app/views/notes/_reply_button.html.haml4
-rw-r--r--app/views/notes/_show.html.haml10
-rw-r--r--app/views/notes/create.js.haml4
-rw-r--r--app/views/notify/new_issue_email.html.haml23
-rw-r--r--app/views/notify/new_merge_request_email.html.haml24
-rw-r--r--app/views/notify/new_user_email.html.haml26
-rw-r--r--app/views/notify/note_commit_email.html.haml32
-rw-r--r--app/views/notify/note_issue_email.html.haml34
-rw-r--r--app/views/notify/note_merge_request_email.html.haml32
-rw-r--r--app/views/notify/note_wall_email.html.haml30
-rw-r--r--app/views/notify/note_wiki_email.html.haml23
-rw-r--r--app/views/notify/reassigned_issue_email.html.haml22
-rw-r--r--app/views/notify/reassigned_merge_request_email.html.haml22
-rw-r--r--app/views/profile/design.html.haml46
-rw-r--r--app/views/profile/password.html.haml4
-rw-r--r--app/views/profile/show.html.haml41
-rw-r--r--app/views/profile/token.html.haml8
-rw-r--r--app/views/projects/_form.html.haml16
-rw-r--r--app/views/projects/_new_form.html.haml10
-rw-r--r--app/views/projects/_project_head.html.haml24
-rw-r--r--app/views/projects/_refs.html.haml4
-rw-r--r--app/views/projects/_show.html.haml6
-rw-r--r--app/views/projects/_team.html.haml2
-rw-r--r--app/views/projects/create.js.haml2
-rw-r--r--app/views/projects/empty.html.haml67
-rw-r--r--app/views/projects/files.html.haml6
-rw-r--r--app/views/projects/new.html.haml2
-rw-r--r--app/views/projects/show.html.haml14
-rw-r--r--app/views/projects/team.html.haml6
-rw-r--r--app/views/projects/tree.js.haml2
-rw-r--r--app/views/projects/update.js.haml2
-rw-r--r--app/views/projects/wall.html.haml2
-rw-r--r--app/views/protected_branches/index.html.haml16
-rw-r--r--app/views/refs/_head.html.haml6
-rw-r--r--app/views/refs/_submodule_item.html.haml6
-rw-r--r--app/views/refs/_tree.html.haml20
-rw-r--r--app/views/refs/_tree_commit.html.haml4
-rw-r--r--app/views/refs/_tree_file.html.haml14
-rw-r--r--app/views/refs/_tree_item.html.haml6
-rw-r--r--app/views/refs/blame.html.haml14
-rw-r--r--app/views/refs/logs_tree.js.haml2
-rw-r--r--app/views/refs/tree.html.haml2
-rw-r--r--app/views/refs/tree.js.haml2
-rw-r--r--app/views/repositories/_branch.html.haml19
-rw-r--r--app/views/repositories/_branches_head.html.haml6
-rw-r--r--app/views/repositories/_feed.html.haml9
-rw-r--r--app/views/repositories/branches.html.haml3
-rw-r--r--app/views/repositories/show.html.haml3
-rw-r--r--app/views/repositories/tags.html.haml11
-rw-r--r--app/views/search/show.html.haml10
-rw-r--r--app/views/shared/_no_ssh.html.haml8
-rw-r--r--app/views/snippets/_form.html.haml14
-rw-r--r--app/views/snippets/_snippet.html.haml4
-rw-r--r--app/views/snippets/index.html.haml6
-rw-r--r--app/views/snippets/show.html.haml8
-rw-r--r--app/views/team_members/_form.html.haml10
-rw-r--r--app/views/team_members/_show.html.haml14
-rw-r--r--app/views/team_members/show.html.haml20
-rw-r--r--app/views/wikis/_form.html.haml32
-rw-r--r--app/views/wikis/edit.html.haml2
-rw-r--r--app/views/wikis/empty.html.haml4
-rw-r--r--app/views/wikis/history.html.haml9
-rw-r--r--app/views/wikis/pages.html.haml18
-rw-r--r--app/views/wikis/show.html.haml23
-rw-r--r--app/workers/system_hook_worker.rb7
-rw-r--r--config/application.rb5
-rw-r--r--config/gitlab.yml.example13
-rw-r--r--config/initializers/1_settings.rb4
-rw-r--r--config/initializers/grack_auth.rb10
-rw-r--r--config/initializers/omniauth.rb.sample4
-rw-r--r--config/initializers/rails_footnotes.rb3
-rw-r--r--config/routes.rb20
-rw-r--r--db/migrate/20120712080407_add_type_to_web_hook.rb5
-rw-r--r--db/migrate/20120729131232_add_extern_auth_provider_to_users.rb8
-rw-r--r--db/schema.rb10
-rw-r--r--doc/api/README.md2
-rw-r--r--doc/api/issues.md184
-rw-r--r--doc/api/projects.md149
-rw-r--r--doc/api/snippets.md100
-rw-r--r--doc/debian_ubuntu.sh2
-rw-r--r--doc/installation.md38
-rw-r--r--features/dashboard/dashboard.feature2
-rw-r--r--features/dashboard/issues.feature8
-rw-r--r--features/dashboard/merge_requests.feature8
-rw-r--r--features/profile/profile.feature6
-rw-r--r--features/projects/commits/branches.feature12
-rw-r--r--features/projects/commits/commit_comments.feature5
-rw-r--r--features/projects/commits/tags.feature3
-rw-r--r--features/projects/issues/issues.feature30
-rw-r--r--features/projects/issues/labels.feature13
-rw-r--r--features/projects/issues/milestones.feature18
-rw-r--r--features/projects/merge_requests.feature42
-rw-r--r--features/projects/network.feature4
-rw-r--r--features/projects/project.feature11
-rw-r--r--features/projects/source/browse_files.feature (renamed from features/projects/source/browse_files.feature.commented)0
-rw-r--r--features/projects/source/git_blame.feature10
-rw-r--r--features/projects/wiki.feature6
-rw-r--r--features/step_definitions/dashboard_steps.rb60
-rw-r--r--features/step_definitions/profile/profile_keys_steps.rb (renamed from features/step_definitions/profile_keys_steps.rb)0
-rw-r--r--features/step_definitions/profile/profile_steps.rb (renamed from features/step_definitions/profile_steps.rb)13
-rw-r--r--features/step_definitions/project/browse_code_steps.rb (renamed from features/step_definitions/browse_code_steps.rb)10
-rw-r--r--features/step_definitions/project/project_commits_steps.rb (renamed from features/step_definitions/project_commits_steps.rb)31
-rw-r--r--features/step_definitions/project/project_issues_steps.rb57
-rw-r--r--features/step_definitions/project/project_merge_requests_steps.rb47
-rw-r--r--features/step_definitions/project/project_milestones_steps.rb38
-rw-r--r--features/step_definitions/project/project_team_steps.rb (renamed from features/step_definitions/project_team_steps.rb)0
-rw-r--r--features/step_definitions/project/project_wiki_steps.rb (renamed from features/step_definitions/project_wiki_steps.rb)0
-rw-r--r--features/step_definitions/project/projects_steps.rb (renamed from features/step_definitions/projects_steps.rb)25
-rw-r--r--features/step_definitions/project_issues_steps.rb22
-rw-r--r--features/support/env.rb47
-rw-r--r--lib/api.rb3
-rw-r--r--lib/api/entities.rb26
-rw-r--r--lib/api/helpers.rb10
-rw-r--r--lib/api/issues.rb111
-rw-r--r--lib/api/projects.rb105
-rw-r--r--lib/api/users.rb6
-rw-r--r--lib/color.rb31
-rw-r--r--lib/file_size_validator.rb4
-rw-r--r--lib/gitlab/encode.rb2
-rw-r--r--lib/gitlab/gitolite.rb2
-rw-r--r--lib/gitlab/graph_commit.rb183
-rw-r--r--lib/gitlab/logger.rb1
-rw-r--r--lib/gitlab/markdown.rb107
-rw-r--r--lib/graph_commit.rb181
-rwxr-xr-xlib/hooks/post-receive (renamed from lib/post-receive-hook)0
-rw-r--r--lib/redcarpet/render/gitlab_html.rb18
-rw-r--r--lib/tasks/dev/repo.rake26
-rwxr-xr-xlib/tasks/dev/user.sh7
-rw-r--r--lib/tasks/gitlab/backup.rake10
-rw-r--r--lib/tasks/gitlab/setup.rake6
-rw-r--r--lib/tasks/gitlab/status.rake35
-rw-r--r--lib/tasks/gitlab/update_hooks.rake19
-rw-r--r--lib/tasks/gitlab/write_hook.rake23
-rw-r--r--public/404.html2
-rw-r--r--public/422.html2
-rw-r--r--public/500.html2
-rwxr-xr-xresque.sh2
-rwxr-xr-xresque_dev.sh2
-rw-r--r--spec/api/projects_spec.rb94
-rw-r--r--spec/factories.rb12
-rw-r--r--spec/helpers/application_helper_spec.rb26
-rw-r--r--spec/helpers/commit_helper_spec.rb67
-rw-r--r--spec/helpers/gitlab_flavored_markdown_spec.rb232
-rw-r--r--spec/mailers/notify_spec.rb44
-rw-r--r--spec/models/event_spec.rb30
-rw-r--r--spec/models/issue_spec.rb36
-rw-r--r--spec/models/merge_request_spec.rb21
-rw-r--r--spec/models/milestone_spec.rb31
-rw-r--r--spec/models/note_spec.rb34
-rw-r--r--spec/models/project_hooks_spec.rb30
-rw-r--r--spec/models/project_security_spec.rb8
-rw-r--r--spec/models/project_spec.rb66
-rw-r--r--spec/models/protected_branch_spec.rb17
-rw-r--r--spec/models/system_hook_spec.rb63
-rw-r--r--spec/models/user_spec.rb17
-rw-r--r--spec/models/web_hook_spec.rb20
-rw-r--r--spec/observers/activity_observer_spec.rb (renamed from spec/models/activity_observer_spec.rb)8
-rw-r--r--spec/observers/issue_observer_spec.rb (renamed from spec/models/issue_observer_spec.rb)16
-rw-r--r--spec/observers/user_observer_spec.rb (renamed from spec/models/user_observer_spec.rb)0
-rw-r--r--spec/requests/admin/admin_hooks_spec.rb53
-rw-r--r--spec/requests/admin/admin_projects_spec.rb32
-rw-r--r--spec/requests/admin/admin_users_spec.rb16
-rw-r--r--spec/requests/admin/security_spec.rb26
-rw-r--r--spec/requests/api/issues_spec.rb73
-rw-r--r--spec/requests/api/projects_spec.rb135
-rw-r--r--spec/requests/api/users_spec.rb (renamed from spec/api/users_spec.rb)10
-rw-r--r--spec/requests/atom/dashboard_issues_spec.rb47
-rw-r--r--spec/requests/atom/dashboard_spec.rb (renamed from spec/requests/dashboard_spec.rb)18
-rw-r--r--spec/requests/atom/issues_spec.rb40
-rw-r--r--spec/requests/commits_notes_spec.rb28
-rw-r--r--spec/requests/commits_spec.rb68
-rw-r--r--spec/requests/dashboard_issues_spec.rb55
-rw-r--r--spec/requests/dashboard_merge_requests_spec.rb40
-rw-r--r--spec/requests/file_blame_spec.rb25
-rw-r--r--spec/requests/gitlab_flavored_markdown_spec.rb241
-rw-r--r--spec/requests/hooks_spec.rb9
-rw-r--r--spec/requests/issues_notes_spec.rb27
-rw-r--r--spec/requests/issues_spec.rb234
-rw-r--r--spec/requests/keys_spec.rb65
-rw-r--r--spec/requests/last_push_widget_spec.rb52
-rw-r--r--spec/requests/merge_requests_spec.rb67
-rw-r--r--spec/requests/milestones_spec.rb51
-rw-r--r--spec/requests/profile_spec.rb82
-rw-r--r--spec/requests/projects_deploy_keys_spec.rb8
-rw-r--r--spec/requests/projects_security_spec.rb187
-rw-r--r--spec/requests/projects_spec.rb85
-rw-r--r--spec/requests/projects_tree_spec.rb90
-rw-r--r--spec/requests/projects_wall_spec.rb33
-rw-r--r--spec/requests/repositories_spec.rb49
-rw-r--r--spec/requests/search_spec.rb2
-rw-r--r--spec/requests/security/profile_access_spec.rb40
-rw-r--r--spec/requests/security/project_access_spec.rb219
-rw-r--r--spec/requests/snippets_spec.rb20
-rw-r--r--spec/requests/team_members_spec.rb68
-rw-r--r--spec/requests/user_security_spec.rb37
-rw-r--r--spec/requests/wikis_spec.rb35
-rw-r--r--spec/spec_helper.rb53
-rw-r--r--spec/support/api.rb7
-rw-r--r--spec/support/api_helpers.rb34
-rw-r--r--spec/support/db_cleaner.rb18
-rw-r--r--spec/support/js_patch.rb6
-rw-r--r--spec/support/login.rb30
-rw-r--r--spec/support/login_helpers.rb23
-rw-r--r--spec/support/monkeypatch.rb (renamed from spec/monkeypatch.rb)8
-rw-r--r--spec/support/shared_examples.rb16
-rw-r--r--spec/workers/post_receive_spec.rb6
-rw-r--r--vendor/assets/images/bg_fallback.pngbin0 -> 3721 bytes
-rw-r--r--vendor/assets/images/icon_sprite.pngbin0 -> 3217 bytes
-rw-r--r--vendor/assets/images/progress_bar.gifbin0 -> 502 bytes
-rw-r--r--vendor/assets/images/slider_handles.pngbin0 -> 4453 bytes
-rw-r--r--vendor/assets/images/ui-icons_222222_256x240.pngbin0 -> 4369 bytes
-rw-r--r--vendor/assets/images/ui-icons_454545_256x240.pngbin0 -> 4369 bytes
-rw-r--r--vendor/assets/javascripts/jquery.tagify.js143
-rw-r--r--vendor/assets/javascripts/jquery.ui.selectmenu.js844
-rw-r--r--vendor/assets/stylesheets/jquery-ui/jquery.tagify.css34
-rw-r--r--vendor/assets/stylesheets/jquery-ui/jquery.ui.selectmenu.css33
-rw-r--r--vendor/assets/stylesheets/jquery.ui.aristo.css738
443 files changed, 7191 insertions, 5750 deletions
diff --git a/.gitignore b/.gitignore
index 725f289db55..760487ca9b3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,6 @@ config/database.yml
config/initializers/omniauth.rb
config/unicorn.rb
db/data.yml
+.idea
+.DS_Store
+
diff --git a/.rails_footnotes b/.rails_footnotes
deleted file mode 100644
index 1019a70aa1b..00000000000
--- a/.rails_footnotes
+++ /dev/null
@@ -1,3 +0,0 @@
-#this code temporarily disables notes for all controllers
-# Footnotes::Filter.notes = []
-
diff --git a/.travis.yml b/.travis.yml
index 402fc8e0dd2..da67e37dbd0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,10 +1,9 @@
env:
- DB=mysql
- - DB=sqlite
before_install:
- sudo apt-get install libicu-dev -y
+ - sudo apt-get install libqt4-dev libqtwebkit-dev -y
- gem install charlock_holmes -v="0.6.8"
- - echo "yes" | gem uninstall json ffi
branches:
only:
- 'master'
diff --git a/CHANGELOG b/CHANGELOG
index fe243d65e4b..6868c07ba52 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,9 +1,29 @@
+v 2.8.1
+ - ability to disable gravatars
+ - improved MR diff logic
+ - ssh key help page
+
+v 2.8.0
+ - Gitlab Flavored Markdown
+ - Bulk issues update
+ - Issues API
+ - Cucumber coverage increased
+ - Post-receive files fixed
+ - UI improved
+ - Application cleanup
+ - more cucumber
+ - capybara-webkit + headless
+
v 2.7.0
- Issue Labels
- Inline diff
- Git HTTP
- API
- UI improved
+ - System hooks
+ - UI improved
+ - Dashboard events endless scroll
+ - Source perfomance increased
v 2.6.0
- UI polished
diff --git a/Gemfile b/Gemfile
index c89d244333f..045baa36974 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,6 +1,6 @@
source "http://rubygems.org"
-gem "rails", "3.2.5"
+gem "rails", "3.2.8"
# Supported DBs
gem "sqlite3"
@@ -13,35 +13,69 @@ gem "devise", "~> 2.1.0"
gem "grit", :git => "https://github.com/gitlabhq/grit.git", :ref => "7f35cb98ff17d534a07e3ce6ec3d580f67402837"
gem "gitolite", :git => "https://github.com/gitlabhq/gitolite-client.git", :ref => "9b715ca8bab6529f6c92204a25f84d12f25a6eb0"
gem "pygments.rb", :git => "https://github.com/gitlabhq/pygments.rb.git", :ref => "2cada028da5054616634a1d9ca6941b65b3ce188"
-gem "omniauth-ldap", :git => "https://github.com/gitlabhq/omniauth-ldap.git", :ref => "7edf27d0281e09561838122982c16b7e62181f44"
+gem "omniauth-ldap", :git => "https://github.com/gitlabhq/omniauth-ldap.git", :ref => "f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e"
gem 'yaml_db', :git => "https://github.com/gitlabhq/yaml_db.git"
gem 'grack', :git => "https://github.com/gitlabhq/grack.git"
gem "linguist", "~> 1.0.0", :git => "https://github.com/gitlabhq/linguist.git"
-gem "grape"
+# API
+gem "grape", "~> 0.2.1"
+
+# Format dates and times
+# based on human-friendly examples
gem "stamp"
+
+# Pagination
gem "kaminari"
+
+# HAML
gem "haml-rails"
+
+# Files attachments
gem "carrierwave"
+
+# Authorization
gem "six"
+
+# Generate Fake data
gem "ffaker"
+
+# Seed data
gem "seed-fu"
+
+# Markdown to HTML
gem "redcarpet", "~> 2.1.1"
+
+# Servers
gem "thin"
gem "unicorn"
-gem "git"
-gem "acts_as_list"
+
+# Issue tags
gem "acts-as-taggable-on", "2.3.1"
-gem "drapper"
+
+# Decorators
+gem "draper"
+
+# Background jobs
gem "resque", "~> 1.20.0"
+gem 'resque_mailer'
+
+# HTTP requests
gem "httparty"
+
+# Handle encodings
gem "charlock_holmes"
-gem "foreman"
+
+# Colored output to console
gem "colored"
-gem 'resque_mailer'
-gem 'tabs_on_rails'
+
+# GITLAB settings
gem 'settingslogic'
+# Misc
+gem "foreman"
+gem "git"
+
group :assets do
gem "sass-rails", "3.2.5"
gem "coffee-rails", "3.2.2"
@@ -53,33 +87,37 @@ group :assets do
gem "jquery-ui-rails", "0.5.0"
gem "modernizr", "2.5.3"
gem "raphael-rails", "1.5.2"
- gem 'bootstrap-sass', "2.0.3.1"
+ gem 'bootstrap-sass', "2.0.4"
end
group :development do
gem "letter_opener"
- gem "rails-footnotes"
gem "annotate", :git => "https://github.com/ctran/annotate_models.git"
+ gem 'rack-mini-profiler'
end
group :development, :test do
gem "rspec-rails"
gem "capybara"
+ gem "capybara-webkit"
+ gem "headless"
gem "autotest"
gem "autotest-rails"
gem "pry"
gem "awesome_print"
gem "database_cleaner"
gem "launchy"
- gem "webmock"
end
group :test do
gem 'cucumber-rails', :require => false
- gem 'minitest', ">= 2.10"
- gem "turn", :require => false
gem "simplecov", :require => false
gem "shoulda-matchers"
gem 'email_spec'
gem 'resque_spec'
+ gem "webmock"
+end
+
+group :production do
+ gem "gitlab_meta", '2.8'
end
diff --git a/Gemfile.lock b/Gemfile.lock
index e4c06fed229..656bede4766 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -42,8 +42,8 @@ GIT
GIT
remote: https://github.com/gitlabhq/omniauth-ldap.git
- revision: 7edf27d0281e09561838122982c16b7e62181f44
- ref: 7edf27d0281e09561838122982c16b7e62181f44
+ revision: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e
+ ref: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e
specs:
omniauth-ldap (1.0.2)
net-ldap (~> 0.2.2)
@@ -69,38 +69,36 @@ GEM
remote: http://rubygems.org/
specs:
ZenTest (4.8.1)
- actionmailer (3.2.5)
- actionpack (= 3.2.5)
+ actionmailer (3.2.8)
+ actionpack (= 3.2.8)
mail (~> 2.4.4)
- actionpack (3.2.5)
- activemodel (= 3.2.5)
- activesupport (= 3.2.5)
+ actionpack (3.2.8)
+ activemodel (= 3.2.8)
+ activesupport (= 3.2.8)
builder (~> 3.0.0)
erubis (~> 2.7.0)
- journey (~> 1.0.1)
+ journey (~> 1.0.4)
rack (~> 1.4.0)
rack-cache (~> 1.2)
rack-test (~> 0.6.1)
sprockets (~> 2.1.3)
- activemodel (3.2.5)
- activesupport (= 3.2.5)
+ activemodel (3.2.8)
+ activesupport (= 3.2.8)
builder (~> 3.0.0)
- activerecord (3.2.5)
- activemodel (= 3.2.5)
- activesupport (= 3.2.5)
+ activerecord (3.2.8)
+ activemodel (= 3.2.8)
+ activesupport (= 3.2.8)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
- activeresource (3.2.5)
- activemodel (= 3.2.5)
- activesupport (= 3.2.5)
- activesupport (3.2.5)
+ activeresource (3.2.8)
+ activemodel (= 3.2.8)
+ activesupport (= 3.2.8)
+ activesupport (3.2.8)
i18n (~> 0.6)
multi_json (~> 1.0)
acts-as-taggable-on (2.3.1)
rails (~> 3.0)
- acts_as_list (0.1.6)
addressable (2.2.8)
- ansi (1.4.2)
arel (3.0.2)
autotest (4.4.6)
ZenTest (>= 4.4.1)
@@ -109,7 +107,7 @@ GEM
awesome_print (1.0.2)
bcrypt-ruby (3.0.1)
blankslate (2.1.2.4)
- bootstrap-sass (2.0.3.1)
+ bootstrap-sass (2.0.4.0)
builder (3.0.0)
capybara (1.1.2)
mime-types (>= 1.16)
@@ -118,6 +116,9 @@ GEM
rack-test (>= 0.5.4)
selenium-webdriver (~> 2.0)
xpath (~> 0.1.4)
+ capybara-webkit (0.12.1)
+ capybara (>= 1.0.0, < 1.2)
+ json
carrierwave (0.6.2)
activemodel (>= 3.2.0)
activesupport (>= 3.2.0)
@@ -154,7 +155,9 @@ GEM
railties (~> 3.1)
warden (~> 1.2.1)
diff-lcs (1.1.3)
- drapper (0.8.4)
+ draper (0.17.0)
+ actionpack (~> 3.2)
+ activesupport (~> 3.2)
email_spec (1.2.1)
mail (~> 2.2)
rspec (~> 2.0)
@@ -170,7 +173,8 @@ GEM
gherkin (2.11.0)
json (>= 1.4.6)
git (1.2.5)
- grape (0.2.0)
+ gitlab_meta (2.8)
+ grape (0.2.1)
hashie (~> 1.2)
multi_json
multi_xml
@@ -184,19 +188,20 @@ GEM
railties (~> 3.0)
hashery (1.4.0)
hashie (1.2.0)
+ headless (0.3.1)
hike (1.2.1)
httparty (0.8.3)
multi_json (~> 1.0)
multi_xml
i18n (0.6.0)
- journey (1.0.3)
+ journey (1.0.4)
jquery-rails (2.0.2)
railties (>= 3.2.0, < 5.0)
thor (~> 0.14)
jquery-ui-rails (0.5.0)
jquery-rails
railties (>= 3.1.0)
- json (1.7.3)
+ json (1.7.4)
kaminari (0.13.0)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
@@ -214,8 +219,7 @@ GEM
mime-types (~> 1.16)
treetop (~> 1.4.8)
method_source (0.7.1)
- mime-types (1.18)
- minitest (3.1.0)
+ mime-types (1.19)
modernizr (2.5.3)
sprockets (~> 2.0)
multi_json (1.3.6)
@@ -237,6 +241,8 @@ GEM
rack (1.4.1)
rack-cache (1.2)
rack (>= 0.4)
+ rack-mini-profiler (0.1.9)
+ rack (>= 1.1.3)
rack-mount (0.8.3)
rack (>= 1.0.0)
rack-protection (1.2.0)
@@ -245,19 +251,17 @@ GEM
rack
rack-test (0.6.1)
rack (>= 1.0)
- rails (3.2.5)
- actionmailer (= 3.2.5)
- actionpack (= 3.2.5)
- activerecord (= 3.2.5)
- activeresource (= 3.2.5)
- activesupport (= 3.2.5)
+ rails (3.2.8)
+ actionmailer (= 3.2.8)
+ actionpack (= 3.2.8)
+ activerecord (= 3.2.8)
+ activeresource (= 3.2.8)
+ activesupport (= 3.2.8)
bundler (~> 1.0)
- railties (= 3.2.5)
- rails-footnotes (3.7.8)
- rails (>= 3.0.0)
- railties (3.2.5)
- actionpack (= 3.2.5)
- activesupport (= 3.2.5)
+ railties (= 3.2.8)
+ railties (3.2.8)
+ actionpack (= 3.2.8)
+ activesupport (= 3.2.8)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
@@ -333,20 +337,17 @@ GEM
tilt (~> 1.1, != 1.3.0)
sqlite3 (1.3.6)
stamp (0.1.6)
- tabs_on_rails (2.1.1)
therubyracer (0.10.1)
libv8 (~> 3.3.10)
thin (1.3.1)
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
rack (>= 1.0.0)
- thor (0.15.2)
+ thor (0.15.4)
tilt (1.3.3)
treetop (1.4.10)
polyglot
polyglot (>= 0.3.1)
- turn (0.9.5)
- ansi
tzinfo (0.3.33)
uglifier (1.0.3)
execjs (>= 0.3.0)
@@ -370,13 +371,13 @@ PLATFORMS
DEPENDENCIES
acts-as-taggable-on (= 2.3.1)
- acts_as_list
annotate!
autotest
autotest-rails
awesome_print
- bootstrap-sass (= 2.0.3.1)
+ bootstrap-sass (= 2.0.4)
capybara
+ capybara-webkit
carrierwave
charlock_holmes
chosen-rails
@@ -385,16 +386,18 @@ DEPENDENCIES
cucumber-rails
database_cleaner
devise (~> 2.1.0)
- drapper
+ draper
email_spec
ffaker
foreman
git
+ gitlab_meta (= 2.8)
gitolite!
grack!
- grape
+ grape (~> 0.2.1)
grit!
haml-rails
+ headless
httparty
jquery-rails (= 2.0.2)
jquery-ui-rails (= 0.5.0)
@@ -402,14 +405,13 @@ DEPENDENCIES
launchy
letter_opener
linguist (~> 1.0.0)!
- minitest (>= 2.10)
modernizr (= 2.5.3)
mysql2
omniauth-ldap!
pry
pygments.rb!
- rails (= 3.2.5)
- rails-footnotes
+ rack-mini-profiler
+ rails (= 3.2.8)
raphael-rails (= 1.5.2)
redcarpet (~> 2.1.1)
resque (~> 1.20.0)
@@ -424,10 +426,8 @@ DEPENDENCIES
six
sqlite3
stamp
- tabs_on_rails
therubyracer
thin
- turn
uglifier (= 1.0.3)
unicorn
webmock
diff --git a/VERSION b/VERSION
index 1daf7c48e6d..1817afea416 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.7.0pre
+2.8.2
diff --git a/app/assets/fonts/korolev-medium-compressed.otf b/app/assets/fonts/korolev-medium-compressed.otf
new file mode 100644
index 00000000000..e3817cec857
--- /dev/null
+++ b/app/assets/fonts/korolev-medium-compressed.otf
Binary files differ
diff --git a/app/assets/images/file_dir.png b/app/assets/images/file_dir.png
index bd941249c87..97b0539393d 100644
--- a/app/assets/images/file_dir.png
+++ b/app/assets/images/file_dir.png
Binary files differ
diff --git a/app/assets/images/gitlab_classic.png b/app/assets/images/gitlab_classic.png
new file mode 100644
index 00000000000..4e189e220ab
--- /dev/null
+++ b/app/assets/images/gitlab_classic.png
Binary files differ
diff --git a/app/assets/images/gitlab_default.png b/app/assets/images/gitlab_default.png
new file mode 100644
index 00000000000..6e9dfb58896
--- /dev/null
+++ b/app/assets/images/gitlab_default.png
Binary files differ
diff --git a/app/assets/images/gitlab_modern.png b/app/assets/images/gitlab_modern.png
new file mode 100644
index 00000000000..b2d73b7a789
--- /dev/null
+++ b/app/assets/images/gitlab_modern.png
Binary files differ
diff --git a/app/assets/images/logo_dark.png b/app/assets/images/logo_dark.png
new file mode 100644
index 00000000000..fab64c2d5a9
--- /dev/null
+++ b/app/assets/images/logo_dark.png
Binary files differ
diff --git a/app/assets/images/logo_white.png b/app/assets/images/logo_white.png
new file mode 100644
index 00000000000..3f74025449c
--- /dev/null
+++ b/app/assets/images/logo_white.png
Binary files differ
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 527b5c795e1..24d99a62ca5 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -7,8 +7,6 @@
//= require jquery
//= require jquery.ui.all
//= require jquery_ujs
-//= require jquery.ui.selectmenu
-//= require jquery.tagify
//= require jquery.cookie
//= require jquery.endless-scroll
//= require jquery.highlight
@@ -26,7 +24,6 @@ $(document).ready(function(){
$(this).select();
});
-
$('body').on('ajax:complete, ajax:beforeSend, submit', 'form', function(e){
var buttons = $('[type="submit"]', this);
switch( e.type ){
@@ -52,14 +49,6 @@ $(document).ready(function(){
}
});
- $("#issues-table .issue").live('click', function(e){
- if(e.target.nodeName != "A" && e.target.nodeName != "INPUT") {
- location.href = $(this).attr("url");
- e.stopPropagation();
- return false;
- }
- });
-
/**
* Focus search field by pressing 's' key
*/
@@ -78,6 +67,26 @@ $(document).ready(function(){
$(".supp_diff_link").bind("click", function() {
showDiff(this);
});
+
+ /**
+ * Note markdown preview
+ *
+ */
+ $(document).on('click', '#preview-link', function(e) {
+ $('#preview-note').text('Loading...');
+
+ var previewLinkText = ($(this).text() == 'Preview' ? 'Edit' : 'Preview');
+ $(this).text(previewLinkText);
+
+ var note = $('#note_note').val();
+ if (note.trim().length === 0) { note = 'Nothing to preview'; }
+ $.post($(this).attr('href'), {note: note}, function(data) {
+ $('#preview-note').html(data);
+ });
+
+ $('#preview-note, #note_note').toggle();
+ e.preventDefault();
+ });
});
function focusSearch() {
@@ -116,6 +125,6 @@ function showDiff(link) {
})(jQuery);
-function ajaxGet(url) {
- $.ajax({type: "GET", url: url, dataType: "script"});
+function ajaxGet(url) {
+ $.ajax({type: "GET", url: url, dataType: "script"});
}
diff --git a/app/assets/javascripts/issues.js b/app/assets/javascripts/issues.js
index 0acf9ec8aef..bc0569654e1 100644
--- a/app/assets/javascripts/issues.js
+++ b/app/assets/javascripts/issues.js
@@ -67,6 +67,10 @@ function initIssuesSearch() {
*/
function issuesPage(){
initIssuesSearch();
+ $("#update_status").chosen();
+ $("#update_assignee_id").chosen();
+ $("#update_milestone_id").chosen();
+
$("#label_name").chosen();
$("#assignee_id").chosen();
$("#milestone_id").chosen();
@@ -94,4 +98,29 @@ function issuesPage(){
});
});
+
+ $(".check_all_issues").click(function () {
+ $('.selected_issue').attr('checked', this.checked);
+ issuesCheckChanged();
+ });
+
+ $('.selected_issue').bind('change', issuesCheckChanged);
+}
+
+function issuesCheckChanged() {
+ var checked_issues = $('.selected_issue:checked');
+
+ if(checked_issues.length > 0) {
+ var ids = []
+ $.each(checked_issues, function(index, value) {
+ ids.push($(value).attr("data-id"));
+ })
+ $('#update_issues_ids').val(ids);
+ $('.issues_filters').hide();
+ $('.issues_bulk_update').show();
+ } else {
+ $('#update_issues_ids').val([]);
+ $('.issues_bulk_update').hide();
+ $('.issues_filters').show();
+ }
}
diff --git a/app/assets/javascripts/merge_requests.js b/app/assets/javascripts/merge_requests.js
index 4b1551927c5..0ab6f6e22a1 100644
--- a/app/assets/javascripts/merge_requests.js
+++ b/app/assets/javascripts/merge_requests.js
@@ -112,6 +112,7 @@ var MergeRequest = {
already_cannot_be_merged:
function(){
$(".automerge_widget").hide();
+ $(".merge_in_progress").hide();
$(".automerge_widget.already_cannot_be_merged").show();
}
}
diff --git a/app/assets/javascripts/note.js b/app/assets/javascripts/note.js
index c45a45d2fcb..d9ae45d93c7 100644
--- a/app/assets/javascripts/note.js
+++ b/app/assets/javascripts/note.js
@@ -33,7 +33,7 @@ init:
})
$("#note_note").live("focus", function(){
- $(this).css("height", "100px");
+ $(this).css("height", "80px");
$('.note_advanced_opts').show();
});
diff --git a/app/assets/javascripts/pager.js b/app/assets/javascripts/pager.js
index d42ae1e05d1..769e8a62343 100644
--- a/app/assets/javascripts/pager.js
+++ b/app/assets/javascripts/pager.js
@@ -8,7 +8,6 @@ var Pager = {
this.limit=limit;
this.offset=limit;
this.initLoadMore();
- $('.loading').show();
},
getOld:
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
index 6ce23320984..92d542a9866 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.css
@@ -3,8 +3,7 @@
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
* the top of the compiled file, but it's generally better to create a new file per style scope.
*= require jquery.ui.all
- *= require jquery-ui/jquery.ui.selectmenu
- *= require jquery-ui/jquery.tagify
+ *= require jquery.ui.aristo
*= require chosen
*= require_self
*= require main
diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss
index 0db803aae23..68f862b8d2a 100644
--- a/app/assets/stylesheets/common.scss
+++ b/app/assets/stylesheets/common.scss
@@ -6,28 +6,28 @@
/** LAYOUT **/
-.container {
+.container {
padding-top:0;
z-index:5;
}
-.container .content {
+.container .content {
margin:0 0;
}
-.container .sidebar {
+.container .sidebar {
width: 200px;
height:100%;
min-height:450px;
float:right;
}
-.profile_avatar_holder {
+.profile_avatar_holder {
float:left;
width:60px;
height:60px;
margin-right:20px;
- img {
+ img {
width:60px;
height:60px;
background:#eee;
@@ -36,11 +36,11 @@
.visible_link,
-.author_link {
+.author_link {
color: $link_color;
}
-.widget {
+.widget {
@include shade;
padding:20px;
margin-bottom:20px;
@@ -48,7 +48,7 @@
border-radius: 5px;
background:#fafafa;
- .link_holder {
+ .link_holder {
background:#eee;
position:relative;
left:-20px;
@@ -57,16 +57,16 @@
width:100%;
border-top:1px solid #ccc;
- a {
+ a {
font-size:14px;
color:#666;
}
}
}
-.help li { color:#111 }
+.help li { color:#111 }
-.back_link {
+.back_link {
text-decoration:underline;
font-size:14px;
font-weight:bold;
@@ -74,31 +74,31 @@
padding-bottom:0;
}
-.info_link {
+.info_link {
margin-right:5px;
float:left;
- img {
+ img {
width:20px;
}
}
-.download_repo_link {
+.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;
+.number {
+ border-radius: 4px;
+ text-shadow: none;
+ background: rgba(0,0,0,.12);
+ text-align: center;
+ padding: 2px 4px;
line-height:18px;
margin-left:2px;
}
-table a code {
+table a code {
position: relative;
top: -2px;
margin-right: 3px;
@@ -108,7 +108,7 @@ table a code {
margin-top: 5px;
}
-.loading {
+.loading {
margin:20px auto;
background: url(ajax_loader.gif) no-repeat center center;
width:40px;
@@ -129,10 +129,12 @@ table a code {
border-bottom:1px solid #ccc;
h4 {
- color:#444;
- font-size:22px;
+ color:#666;
+ font-size:18px;
+ line-height:38px;
padding-top:5px;
margin:2px;
+ font-weight:normal;
}
}
@@ -198,12 +200,12 @@ a.project-update.titled {
}
}
-input.git_clone_url {
+input.git_clone_url {
width:325px;
}
.merge-request-form-holder {
- select {
+ select {
width:300px;
}
}
@@ -217,17 +219,17 @@ input.git_clone_url {
height: 100px;
}
-.project_list_url {
+.project_list_url {
width:250px;
background:#fff !important;
}
/** bordered list **/
-ul.bordered-list {
+ul.bordered-list {
margin:5px 0px;
padding:0px;
- li {
+ li {
padding: 5px 0;
border-bottom: 1px solid #EEE;
overflow: hidden;
@@ -236,25 +238,25 @@ ul.bordered-list {
}
}
-ul.bordered-list li:last-child { border:none }
+ul.bordered-list li:last-child { border:none }
-.line_holder {
- &:hover {
- td {
+.line_holder {
+ &:hover {
+ td {
background: #FFFFCF !important;
}
}
}
-li.commit {
- .avatar {
+li.commit {
+ .avatar {
width:24px;
- top:-3px;
+ top:-5px;
margin-right:10px;
margin-left:10px;
}
- code {
+ code {
padding: 2px 2px 0;
margin-top: -2px;
&:hover {
@@ -270,21 +272,21 @@ p.time {
}
-/**
+/**
* Dashboard page
- *
+ *
*/
-.dashboard_category {
+.dashboard_category {
margin-bottom:30px;
- h3 a {
+ h3 a {
color:#474D57;
- &:hover {
+ &:hover {
text-decoration:underline;
}
}
- .dashboard_block {
- .dash_project_item {
+ .dashboard_block {
+ .dash_project_item {
margin-bottom:10px;
border:none;
padding:0px 5px;
@@ -292,7 +294,7 @@ p.time {
color:#888;
&:hover {
color:#111;
- .ico.project {
+ .ico.project {
background-position:-209px -21px;
}
}
@@ -304,32 +306,27 @@ p.time {
}
}
-.styled_image {
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
- -moz-box-shadow: 0 0 5px #888;
- -webkit-box-shadow: 0 0 5px#888;
- box-shadow: 0 0 5px #888;
+.styled_image {
+ border:2px solid #ddd;
}
-.event_feed {
+.event_feed {
min-height:40px;
border-bottom:1px solid #ddd;
- .avatar {
+ .avatar {
width:32px;
}
- .event_icon {
+ .event_icon {
float:right;
margin-right:2px;
- img {
+ img {
width:20px;
}
}
- ul {
+ ul {
margin-left:50px;
margin-bottom:5px;
- .avatar {
+ .avatar {
width:24px;
}
}
@@ -337,9 +334,19 @@ p.time {
padding: 15px 5px;
&:last-child { border:none }
.wll:hover { background:none }
+
+ .event_commits {
+ margin-top: 5px;
+
+ li.commit {
+ background: transparent;
+ padding:5px;
+ border:none;
+ }
+ }
}
-.ico {
+.ico {
background: url("images.png") no-repeat -85px -77px;
width: 19px;
height: 16px;
@@ -348,24 +355,24 @@ p.time {
margin-right: 10px;
top: 8px;
- &.project {
+ &.project {
background-position: -37px -77px;
}
- &.activities {
+ &.activities {
background-position:-162px -22px;
}
- &.projects {
+ &.projects {
background-position:-209px -21px;
}
}
-.leftbar {
- h5, .title {
+.leftbar {
+ h5, .title {
padding:5px 10px;
}
- h4 {
+ h4 {
font-size:14px;
padding:2px 10px;
color:#666;
@@ -373,41 +380,41 @@ p.time {
}
a:last-child h4 { border:none; }
- a:hover {
+ a:hover {
h4 {
color:#111;
background:$hover;
border-color:#CCC;
- .ico.project {
+ .ico.project {
background-position:-209px -21px;
}
}
}
- .bottom {
+ .bottom {
padding:10px;
}
}
-.btn {
- &.very_small {
+.btn {
+ &.very_small {
font-size:11px;
padding:2px 6px;
margin:2px;
}
- &.grouped {
+ &.grouped {
margin-right:7px;
float:left;
}
- &.padded {
+ &.padded {
margin-right:3px;
padding:4px 10px 4px;
}
}
-.prettyprint {
+.prettyprint {
background-color: #fefbf3;
padding: 9px;
border: 1px solid rgba(0,0,0,.2);
@@ -434,7 +441,7 @@ p.time {
.readme {
pre {
background: white !important;
-
+
code {
background: none !important;
}
@@ -442,11 +449,11 @@ p.time {
}
-.highlight_word {
+.highlight_word {
background:#EEDC94;
}
-.status_info {
+.status_info {
font-size:14px;
padding:5px 15px;
line-height:24px;
@@ -455,13 +462,13 @@ p.time {
float:left;
margin-right:20px;
- &.success {
+ &.success {
background: #5BB75B;
color: white;
text-shadow: 0 1px #111;
border-color: #9A9;
}
- &.error {
+ &.error {
background: #DA4E49;
border-color: #BD362F;
color: white;
@@ -469,7 +476,7 @@ p.time {
}
}
-.arrow{
+.arrow{
background: #E3E5EA;
padding: 5px;
margin-top:5px;
@@ -484,12 +491,12 @@ p.time {
height: 150px;
}
-.gitlab_pagination {
+.gitlab_pagination {
span a { color:$link_color; }
- .prev, .next, .current, .page a {
+ .prev, .next, .current, .page a {
padding:10px;
}
- .current {
+ .current {
border-bottom:2px solid $style_color;
}
}
@@ -515,8 +522,8 @@ li.note {
}
}
-.markdown {
- img {
+.markdown {
+ img {
max-width:100%;
}
}
@@ -525,20 +532,20 @@ li.note {
background-color: inherit;
}
-.team_member_show {
- td:first-child {
+.team_member_show {
+ td:first-child {
color:#aaa;
}
}
-.remember_me {
+.remember_me {
text-align:left;
- input {
+ input {
margin:0;
}
- span {
+ span {
padding-left:5px;
}
}
@@ -549,7 +556,7 @@ li.note {
*
*/
-.milestone {
+.milestone {
@extend .wll;
}
@@ -557,10 +564,10 @@ li.note {
* Admin area
*
*/
-.admin_dash {
- .data {
- a {
- h1 {
+.admin_dash {
+ .data {
+ a {
+ h1 {
line-height:48px;
font-size:48px;
padding:20px;
@@ -576,7 +583,7 @@ li.note {
vertical-align:top;
}
- strong {
+ strong {
line-height:24px;
}
}
@@ -584,20 +591,20 @@ li.note {
/* CHZN reset few styles */
-.chzn-container-single .chzn-single {
+.chzn-container-single .chzn-single {
background:#FFF;
border: 1px solid #bbb;
box-shadow:none;
}
-.chzn-container-active .chzn-single {
+.chzn-container-active .chzn-single {
background:#fff;
}
/**
* Push event widget
- *
+ *
*/
-.event_lp {
+.event_lp {
@extend .alert-info;
margin-bottom:20px;
padding:8px;
@@ -606,19 +613,19 @@ li.note {
@include border-radius(4px);
min-height:22px;
- .avatar {
+ .avatar {
width:24px;
}
}
.supp_diff_link,
-.mr_show_all_commits {
+.mr_show_all_commits {
cursor:pointer;
}
/**
- * Issues, MRs legend
- *
+ * Issues, MRs legend
+ *
*/
.list_legend {
@@ -631,32 +638,32 @@ li.note {
margin-right:5px;
margin-top: 2px;
@include border-radius(4px);
- &.today{
+ &.today{
background: #ADA;
border:1px solid #8B8;
}
- &.closed {
+ &.closed {
background: #DDD;
border:1px solid #BBB;
}
- &.yours {
+ &.yours {
background: #AAD;
border:1px solid #88B;
}
- &.merged {
+ &.merged {
background: #DAD;
border:1px solid #B8B;
}
}
- .text {
+ .text {
padding-bottom: 10px;
float:left;
}
}
.merge_request,
-.issue {
- .list_legend {
+.issue {
+ .list_legend {
margin-right: 5px;
margin-top: 14px;
.icon {
@@ -669,34 +676,72 @@ li.note {
}
}
- &.today{
+ &.today{
background: #EFE;
border-color:#CEC;
- .icon {
+ .icon {
background: #ADA;
border:1px solid #8B8;
}
}
- &.closed {
+ &.closed {
background: #F5f5f5;
border-color:#E5E5E5;
- .icon {
+ .icon {
background: #DDD;
border:1px solid #BBB;
}
}
- &.yours {
- .icon {
+ &.yours {
+ .icon {
background: #AAD;
border:1px solid #88B;
}
}
- &.merged {
+ &.merged {
background: #F5f5f5;
border-color:#E5E5E5;
- .icon {
+ .icon {
background: #DAD;
border:1px solid #B8B;
}
}
}
+
+.themes_opts {
+ padding-left:20px;
+
+ label {
+ width:175px;
+ margin-right:40px;
+
+ .prev {
+ @extend .borders;
+ height:120px;
+ width:175px;
+ margin-bottom:10px;
+ img {
+ width:180px;
+ }
+ }
+ }
+}
+
+.git_error_tips {
+ @extend .span6;
+ text-align:left;
+ margin-top:40px;
+ pre {
+ background:white;
+ border:none;
+ font-size: 12px;
+ }
+}
+
+.error_message {
+ @extend .cred;
+ border-bottom: 1px solid #D21;
+ padding-bottom:20px;
+ text-align:center;
+ margin-bottom:10px;
+}
diff --git a/app/assets/stylesheets/gitlab_bootstrap.scss b/app/assets/stylesheets/gitlab_bootstrap.scss
index b2bc4593a29..a1faf0601cb 100644
--- a/app/assets/stylesheets/gitlab_bootstrap.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap.scss
@@ -1,31 +1,42 @@
-body {
+body {
margin-bottom:20px;
}
+
+pre {
+ font-family:'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
+
+ &.dark {
+ background: #333;
+ color:#f5f5f5;
+ }
+}
+
a {
outline: none;
color: $link_color;
- &:hover {
- text-decoration:none;
+ &:hover {
+ text-decoration:none;
color: $blue_link;
}
- &.btn {
+ &.btn {
color: $style_color;
}
- &.dark {
+ &.dark {
color: $style_color;
}
- &.lined {
- text-decoration:underlined;
+ &.lined {
+ text-decoration:underline;
+ &:hover { text-decoration:underline; }
}
- &.gray {
+ &.gray {
color:gray;
}
- &.supp_diff_link {
+ &.supp_diff_link {
text-align:center;
padding:20px 0;
background:#f1f1f1;
@@ -38,24 +49,24 @@ a {
}
}
-.neib {
+.neib {
margin-right:10px;
}
-.alert-message {
+.alert-message {
@extend .alert;
- &.success {
+ &.success {
@extend .alert-success;
}
- &.error {
+ &.error {
@extend .alert-error;
}
}
-.alert {
- &.alert-well {
+.alert {
+ &.alert-well {
background:#ddd;
border:1px solid #ccc;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #ddd), to(#dfdfdf));
@@ -70,16 +81,12 @@ h3, h4, h5, h6 {
line-height: 36px;
}
-h5 {
+h5 {
font-size:14px;
}
-code {
- background:#FCEEC1;
- color:$style_color;
-}
-table {
+table {
width:100%;
th {
padding-top: 9px;
@@ -100,12 +107,12 @@ table {
border-radius: 4px;
}
- &.zebra-striped {
+ &.zebra-striped {
@extend .table-striped;
}
}
-.btn {
+.btn {
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f1f1f1), color-stop(25%, #f1f1f1), to(#e6e6e6));
background-image: -webkit-linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6);
background-image: -moz-linear-gradient(top, #f1f1f1, #f1f1f1 25%, #e6e6e6);
@@ -113,63 +120,63 @@ table {
background-image: -o-linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6);
background-image: linear-gradient(#f1f1f1, #f1f1f1 25%, #e6e6e6);
- &:hover {
+ &:hover {
}
- &.btn-primary {
+ &.btn-primary {
background:$link_color;
border-color: #2A79A3;
- &:hover {
+ &:hover {
background:$blue_link;
}
}
- &.primary {
+ &.primary {
@extend .btn-primary;
}
- &.success {
+ &.success {
color: #fff;
text-shadow: 0 0 1px #111;
background: #5bb75b;;
font-weight: bold;
- &:hover {
+ &:hover {
background-color: #51a351;
color: #fff;
}
}
&.danger,
- &.btn-danger {
+ &.btn-danger {
color:#fff;
background: #DA4E49;
border-color: #BD362F;
- &:hover {
+ &:hover {
color:#fff;
background: #EE4E49;
}
}
- &.danger {
+ &.danger {
@extend .btn-danger;
}
- &.small {
+ &.small {
@extend .btn-small;
}
- &.active {
+ &.active {
border-color:#aaa;
background-color:#ccc;
}
}
-a:focus {
- outline: none;
+a:focus {
+ outline: none;
}
-.nav-pills a:hover {
+.nav-pills a:hover {
background-color:#888;
}
@@ -177,20 +184,20 @@ a:focus {
background-color: $style_color;
}
-.label {
+.label {
background-color: #474D57;
- &.label-important {
+ &.label-important {
background-color: #B94A48;
}
- &.label-issue {
+ &.label-issue {
background-color: #eee;
border: 1px solid #ccc;
padding:4px 6px;
color:#444;
text-shadow:0 0 1px #fff;
- &.grouped {
+ &.grouped {
float: left;
margin-right: 6px;
padding: 6px;
@@ -202,7 +209,7 @@ a:focus {
color:$style_color;
}
-.nav-tabs > .active > a {
+.nav-tabs > .active > a {
font-weight:bold;
}
@@ -251,39 +258,39 @@ a:focus {
margin-top:20px;
}
-.padded {
+.padded {
padding:20px;
}
-.ipadded {
+.ipadded {
padding:20px !important;
}
-.lborder {
+.lborder {
border-left:1px solid #eee;
}
-.borders {
+.borders {
border: 1px solid #ccc;
@include shade;
}
-.no-borders {
+.no-borders {
border:none;
}
-table.no-borders {
+table.no-borders {
border:none;
tr, td { border:none }
}
-.no-padding {
+.no-padding {
padding:0 !important;
}
-.underlined {
+.underlined {
border-bottom: 1px solid $border_color;
}
-.vlink {
+.vlink {
color: $link_color !important;
}
-.pretty_label {
+.pretty_label {
@include round-borders-all(4px);
padding:2px 4px;
background-image: -webkit-gradient(linear, 0 0, 0 26, color-stop(0.076, #fefefe), to(#F6F7F8));
@@ -293,7 +300,7 @@ table.no-borders {
color: #777;
border: 1px solid #DEDFE1;
- &.branch {
+ &.branch {
border:none;
font-size:13px;
background: #474D57;
@@ -303,70 +310,75 @@ table.no-borders {
}
}
-.event_label {
+.event_label {
@extend .label;
background-color: #999;
- &.pushed {
+ &.pushed {
background-color: #3A87AD;
}
- &.opened {
+ &.opened {
background-color: #468847;
}
- &.closed {
+ &.closed {
background-color: #B94A48;
}
- &.merged {
+ &.merged {
background-color: #2A2;
}
}
-img.avatar {
+img.avatar {
float:left;
margin-right:15px;
width:40px;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
+ border:1px solid #ddd;
+ padding:1px;
- &.s16 {
+ &.s16 {
width:16px;
+ height:16px;
}
- &.s24 {
+ &.s24 {
width:24px;
+ height:24px;
+ }
+ &.s32 {
+ width:32px;
+ height:32px;
}
}
-img.lil_av {
+img.lil_av {
padding-left: 4px;
padding-right:3px;
}
-form {
+form {
@extend .form-horizontal;
- .actions {
+ .actions {
@extend .form-actions;
}
- .clearfix {
+ .clearfix {
@extend .control-group;
}
- .input {
+ .input {
@extend .controls;
}
- label {
+ label {
@extend .control-label;
}
- .xlarge {
+ .xlarge {
@extend .input-xlarge;
}
- .xxlarge {
+ .xxlarge {
@extend .input-xxlarge;
}
}
@@ -375,26 +387,25 @@ form {
* List li block element #1
*
*/
-.wll {
+.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;
- &.smoke {
+ &.smoke {
background-color:#f5f5f5;
}
- &:hover {
+ &:hover {
background:$hover;
}
&:last-child { border:none }
p { padding-top:5px; margin:0; color:$style_color;}
.author { color: #999; }
- p {
+ p {
color:#222;
margin-bottom: 0;
- img {
+ img {
position:relative;
top:3px;
}
@@ -406,7 +417,7 @@ form {
* Block element #2
*
*/
-.entry {
+.entry {
position: relative;
padding: 7px 15px;
margin-bottom: 18px;
@@ -428,10 +439,10 @@ form {
border: 1px solid #ccc;
- p {
+ p {
color:$style_color;
margin-bottom: 0;
- img {
+ img {
position:relative;
top:3px;
}
@@ -443,66 +454,60 @@ form {
* Big UI Block for show page content
*
*/
-.ui-box {
+.ui-box {
background:#F9F9F9;
margin-bottom: 25px;
@include round-borders-all(4px);
border-color: #CCC;
+ @include solid_shade;
- ul {
+ ul {
margin:0;
}
- h5, .title {
+ h5, .title {
padding: 0 10px;
@include round-borders-top(4px);
+ @include bg-gray-gradient;
border-bottom: 1px solid #bbb;
- background:#eee;
- 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);
- &.small {
+ &.small {
line-height: 28px;
font-size: 14px;
line-height:28px;
text-shadow: 0 1px 1px white;
}
- form {
+ form {
padding:9px 0;
margin:0px;
}
- .nav-pills {
- li {
+ .nav-pills {
+ li {
padding:3px 0;
&.active a { background-color:$style_color; }
- a {
+ a {
border-radius:7px;
}
}
}
}
- .bottom {
- 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);
+ .bottom {
+ @include bg-gray-gradient;
@include round-borders-bottom(4px);
border-bottom:none;
border-top: 1px solid #bbb;
}
- &.padded {
- h5, .title {
+ &.padded {
+ h5, .title {
margin: -20px;
margin-bottom: 0;
padding: 5px 20px;
}
- .middle_title {
+ .middle_title {
background:#f5f5f5;
margin:20px -20px;
padding: 0 20px;
@@ -512,22 +517,23 @@ form {
color:#777;
}
}
- .row_title {
+ .row_title {
font-weight:bold;
color:#444;
- &:hover {
+ &:hover {
+ color:#444;
text-decoration:underline;
}
}
li, .wll {
padding:10px;
- &:first-child {
+ &:first-child {
@include round-borders-top(4px);
border-top:none;
}
- &:last-child {
+ &:last-child {
@include round-borders-bottom(4px);
border:none;
}
@@ -536,20 +542,17 @@ form {
}
table.admin-table {
- @extend .table-bordered;
+ @extend .table-bordered;
@extend .zebra-striped;
- th {
+ @include solid_shade;
+ th {
border-color: #CCC;
border-bottom: 1px solid #bbb;
- background:#eee;
- 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 bg-gray-gradient;
}
}
-.field_with_errors {
+.field_with_errors {
display:inline;
}
@@ -561,13 +564,13 @@ ul.breadcrumb {
text-shadow: 0 1px 0 white
}
- a {
+ a {
color:#474D57;
font-weight:bold;
font-size:14px;
}
- .arrow {
+ .arrow {
background: url("images.png") no-repeat -85px -77px;
width: 19px;
height: 16px;
@@ -579,22 +582,24 @@ ul.breadcrumb {
}
}
-.nothing_here_message {
+.nothing_here_message {
text-align:center;
padding:20px;
color:#777;
}
/**
- * UI box element
+ * UI box element
* contains top, middle, bottom blocks
- *
+ *
*/
-.main_box {
+.main_box {
@extend .borders;
@extend .prepend-top-20;
@extend .append-bottom-20;
border-width:1px;
+ @include solid_shade;
+
img { max-width: 100%; }
@@ -604,9 +609,9 @@ ul.breadcrumb {
}
}
- .top_box_content,
- .middle_box_content,
- .bottom_box_content {
+ .top_box_content,
+ .middle_box_content,
+ .bottom_box_content {
padding:15px;
pre {
@@ -617,7 +622,7 @@ ul.breadcrumb {
}
}
- .middle_box_content {
+ .middle_box_content {
border-radius:0;
border:none;
font-size:12px;
@@ -626,20 +631,20 @@ ul.breadcrumb {
border-top:1px solid #eee;
}
- .bottom_box_content {
+ .bottom_box_content {
border-top:1px solid #eee;
}
}
-input[type=text] {
- &.large_text {
+input[type=text] {
+ &.large_text {
padding:6px;
font-size:16px;
}
}
-p {
- &.slead {
+p {
+ &.slead {
color:#456;
font-size:16px;
margin-bottom: 12px;
@@ -648,7 +653,7 @@ p {
}
}
-h3.page_title {
+h3.page_title {
color:#456;
font-size:20px;
font-weight: normal;
@@ -656,21 +661,17 @@ h3.page_title {
}
/**
- * File content holder
+ * File content holder
*
*/
-.file_holder {
+.file_holder {
border:1px solid #CCC;
margin-bottom:1em;
- @include shade;
+ @include solid_shade;
- .file_title {
+ .file_title {
border-bottom: 1px solid #bbb;
- background:#eee;
- 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 bg-gray-gradient;
margin: 0;
font-weight: normal;
font-weight: bold;
@@ -679,16 +680,16 @@ h3.page_title {
padding: 9px 10px;
height:18px;
- .options {
+ .options {
float:right;
margin-top: -5px;
}
- .file_name {
+ .file_name {
color:$style_color;
font-size:14px;
text-shadow: 0 1px 1px #fff;
- small {
+ small {
color:#999;
font-size:13px;
}
@@ -698,21 +699,21 @@ h3.page_title {
background:#fff;
font-size: 11px;
- &.wiki {
+ &.wiki {
font-size: 13px;
- code {
+ code {
padding:0 4px;
}
padding:20px;
- h1, h2 {
- line-height: 46px;
- }
- h3, h4 {
- line-height: 40px;
- }
+ h1, h2 {
+ line-height: 46px;
+ }
+ h3, h4 {
+ line-height: 40px;
+ }
}
- &.image_file {
+ &.image_file {
background:#eee;
text-align:center;
img {
@@ -721,27 +722,27 @@ h3.page_title {
}
}
- &.blob_file {
+ &.blob_file {
}
/**
* Blame file
*/
- &.blame {
- tr {
+ &.blame {
+ tr {
border-bottom: 1px solid #eee;
}
- td {
+ td {
padding:5px;
}
- .author,
- .blame_commit {
+ .author,
+ .blame_commit {
background:#f5f5f5;
vertical-align:top;
}
- .lines {
- pre {
+ .lines {
+ pre {
padding:0;
margin:0;
background:none;
@@ -750,27 +751,27 @@ h3.page_title {
}
}
- &.logs {
+ &.logs {
background:#eee;
max-height: 700px;
overflow-y: auto;
- ol {
+ ol {
margin-left:40px;
padding: 10px 0;
border-left: 1px solid #CCC;
margin-bottom:0;
background: white;
- li {
+ li {
color:#888;
- p {
+ p {
margin:0;
color:#333;
line-height:24px;
padding-left: 10px;
}
- &:hover {
+ &:hover {
background:$hover;
}
}
@@ -780,7 +781,7 @@ h3.page_title {
/**
* Code file
*/
- &.code {
+ &.code {
padding:0;
td.code {
width: 100%;
diff --git a/app/assets/stylesheets/jquery_ui.scss b/app/assets/stylesheets/jquery_ui.scss
deleted file mode 100644
index 1063f1d080e..00000000000
--- a/app/assets/stylesheets/jquery_ui.scss
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * JQUERY UI datepicker
- *
- */
-.ui-datepicker {
- border-color:#eee;
- padding:20px;
-
- .ui-state-default {
- background:#f1f1f1;
- padding:5px;
- }
- .ui-state-active {
- background:#fff;
- }
-}
-
-/**
- * JQUERY UI progressbar
- *
- */
-.ui-progressbar {
- border:1px solid #ddd;
- height:6px;
- margin:0;
- padding:0;
-
- .ui-progressbar-value {
- background-color: #62C462;//$blue_link;
- margin:0;
- }
-}
-
diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss
index 5f13f301f35..b4f0ebf8ba0 100644
--- a/app/assets/stylesheets/main.scss
+++ b/app/assets/stylesheets/main.scss
@@ -3,8 +3,8 @@
/** GITLAB colors **/
$text_color:#222;
-$lite_text_color: #666;
-$link_color:#2A79A3;
+$lite_text_color: #666;
+$link_color:#2A79A3;
$active_link_color:#2FA0BB;
$active_bg_color:#79C3E0;
$active_bd_color: #2FA0BB;
@@ -23,6 +23,8 @@ $blue_link: #2fa0bb;
$style_color: #474D57;
$hover: #FDF5D9;
+/** GITLAB Fonts **/
+@font-face { font-family: Korolev; src: url('korolev-medium-compressed.otf'); }
/** MIXINS **/
@mixin shade {
@@ -31,6 +33,12 @@ $hover: #FDF5D9;
box-shadow: 0 0 3px #ddd;
}
+@mixin solid_shade {
+ -moz-box-shadow: 0 0 0 3px #eee;
+ -webkit-box-shadow: 0 0 0 3px #eee;
+ box-shadow: 0 0 0 3px #eee;
+}
+
@mixin border-radius($radius) {
-moz-border-radius: $radius;
-webkit-border-radius: $radius;
@@ -64,24 +72,30 @@ $hover: #FDF5D9;
border-radius: $radius;
}
-
+@mixin bg-gray-gradient {
+ background:#eee;
+ 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);
+}
/**
- * Header of application.
+ * Header of application.
* Contain application logo, search panel, profile icon
*/
-@import "header.scss";
+@import "sections/header.scss";
/**
- * Navigation menu of application.
+ * Navigation menu of application.
* Panel with links to pages depends on project, profile or admin area
*/
-@import "nav.scss";
+@import "sections/nav.scss";
/**
- * This file represent some UI that can be changed
- * during web app restyle or theme select.
- *
+ * This file represent some UI that can be changed
+ * during web app restyle or theme select.
+ *
* Next items should be placed there
* - link, button colors
* - header restyles
@@ -112,7 +126,7 @@ $hover: #FDF5D9;
* 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";
@@ -134,19 +148,19 @@ $hover: #FDF5D9;
@import "ref_select.scss";
/**
- * Code (files list) styles. Browsing project files there
+ * Code (files list) styles. Browsing project files there
*/
@import "sections/tree.scss";
/**
- * This file represent notes(comments) styles
+ * This file represent notes(comments) styles
*/
-@import "notes.scss";
+@import "sections/notes.scss";
/**
- * Devise styles
+ * Devise styles
*/
-@import "login.scss";
+@import "sections/login.scss";
/**
* CODE HIGHTLIGHT BASE
@@ -159,9 +173,3 @@ $hover: #FDF5D9;
*
*/
@import "highlight/dark.scss";
-
-/**
- * JQUERY UI ext
- *
- */
-@import "jquery_ui.scss";
diff --git a/app/assets/stylesheets/ref_select.scss b/app/assets/stylesheets/ref_select.scss
index 6f6a1bc983d..5b52e11b355 100644
--- a/app/assets/stylesheets/ref_select.scss
+++ b/app/assets/stylesheets/ref_select.scss
@@ -33,9 +33,7 @@
}
.chzn-single {
- background:#ddd;
- //border:none;
- //box-shadow:none;
+ @include bg-gray-gradient;
div {
background:transparent;
diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss
index 6052ec3fabb..e2db701db71 100644
--- a/app/assets/stylesheets/sections/commits.scss
+++ b/app/assets/stylesheets/sections/commits.scss
@@ -194,4 +194,16 @@
float:right;
@extend .cgray;
}
+
+ code {
+ background:#FCEEC1;
+ color:$style_color;
+ }
+
+ .commit_short_id {
+ float:left;
+ @extend .lined;
+ min-width:65px;
+ font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
+ }
}
diff --git a/app/assets/stylesheets/sections/graph.scss b/app/assets/stylesheets/sections/graph.scss
index 33d91de5391..2aa4463e45e 100644
--- a/app/assets/stylesheets/sections/graph.scss
+++ b/app/assets/stylesheets/sections/graph.scss
@@ -6,11 +6,7 @@
h4 {
padding:0 10px;
border-bottom: 1px solid #bbb;
- background:#eee;
- 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 bg-gray-gradient;
}
.graph {
diff --git a/app/assets/stylesheets/header.scss b/app/assets/stylesheets/sections/header.scss
index c3a570036bb..d0fb662e69e 100644
--- a/app/assets/stylesheets/header.scss
+++ b/app/assets/stylesheets/sections/header.scss
@@ -2,14 +2,14 @@
* Application Header
*
*/
-header {
+header {
width:100%;
padding:0;
margin:0;
top:1px;
left:0;
background: #F1F1F1; /* for non-css3 browsers */
- border-bottom: 1px solid #ccc;
+ 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;
@@ -17,7 +17,7 @@ header {
height:60px;
/**
- *
+ *
* Logo holder
*
*/
@@ -26,23 +26,25 @@ header {
float:left;
position:relative;
top:-5px;
-
- a {
+ a {
float:left;
- h1 {
- text-indent:-9999px;
+ h1 {
+ padding-top: 5px;
width:102px;
- background: url('logo_text.png') no-repeat 0px -3px;
+ background: url('logo_dark.png') no-repeat 0px -3px;
float:left;
margin-left:5px;
- font-size:20px;
+ font-size:36px;
line-height:36px;
- font-weight:bold;
- color:#aaa;
+ font-weight:normal;
+ color:$style_color;
text-shadow: 0 1px 1px #FFF;
padding-left:50px;
+ height:40px;
+ font-family: 'Korolev', sans-serif;
}
+
}
.separator {
margin-left:20px;
@@ -54,8 +56,8 @@ header {
margin-top: -10px;
}
}
- .container {
- .top_panel_content {
+ .container {
+ .top_panel_content {
margin:auto;
position:relative;
padding:15px 0;
@@ -63,25 +65,27 @@ header {
}
/**
- *
+ *
* Project / Area name
*
*/
.project_name {
+ position:relative;
float:left;
margin:0;
margin-right:30px;
- font-size:24px;
+ font-size:36px;
line-height:36px;
- font-weight:500;
+ font-weight:normal;
color:$style_color;
text-shadow: 0 1px 1px #FFF;
+ font-family: 'Korolev', sans-serif;
}
- .fbtn {
+ .fbtn {
float: right;
margin-right:10px;
- .btn {
+ .btn {
margin-left:7px;
background: #F1F1F1;
border: 1px solid #CCC;
@@ -90,13 +94,13 @@ header {
/**
- *
+ *
* Search box
*
*/
- .search {
+ .search {
float: right;
- margin-right: 50px;
+ margin-right: 45px;
.search-input {
@extend .span2;
@@ -110,7 +114,7 @@ header {
}
/**
- *
+ *
* Account box
*
*/
@@ -125,16 +129,13 @@ header {
display: block;
cursor: pointer;
img {
- -moz-box-shadow: 0 0 5px #ccc;
- -webkit-box-shadow: 0 0 5px #ccc;
- box-shadow: 0 0 5px #ccc;
- border-radius: 4px;
+ @include border-radius(4px);
right: 5px;
position: absolute;
- width: 31px;
- height: 31px;
+ width: 28px;
+ height: 28px;
display: block;
- top: 0;
+ top: 2px;
&:after {
content: " ";
display: block;
@@ -189,7 +190,7 @@ header {
width: 100px;
position: absolute;
right: 10px;
- top: 46px;
+ top: 42px;
margin-top: 0;
float: right;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
diff --git a/app/assets/stylesheets/sections/issues.scss b/app/assets/stylesheets/sections/issues.scss
index dd1c22d4e76..1b61ec3fe85 100644
--- a/app/assets/stylesheets/sections/issues.scss
+++ b/app/assets/stylesheets/sections/issues.scss
@@ -30,13 +30,72 @@
.issue {
padding:7px 10px;
+ .issue_check {
+ float:left;
+ padding: 8px 0;
+ padding-right: 8px;
+ min-width: 15px;
+ }
+
+ p {
+ padding-top:0;
+ padding-bottom:2px;
+ }
+
img.avatar {
width:32px;
margin-top:4px;
}
- p.row_title {
- padding:0px;
- padding-bottom:2px;
+ }
+}
+
+input.check_all_issues {
+ float:left;
+ padding: 0;
+ margin:0;
+ margin-right: 10px;
+ position: relative;
+ top: 8px;
+ height: 22px;
+}
+
+.issues_content {
+ .title {
+ height: 40px;
+ }
+}
+
+#issues-table-holder {
+ .issues_filters {
+ form {
+ padding:0;
+ margin:0;
+ margin-top:7px
+ }
+ }
+
+ .issues_bulk_update {
+ margin: 0;
+ form {
+ padding:0;
+ margin:0;
+ margin-top:7px
+ }
+ .update_selected_issues {
+ position:relative;
+ top:-2px;
+ margin-left:4px;
+ float:left;
+ }
+
+ .update_issues_text {
+ padding:3px;
+ line-height: 18px;
+ float:left;
}
}
}
+
+#update_status {
+ width:100px;
+}
diff --git a/app/assets/stylesheets/login.scss b/app/assets/stylesheets/sections/login.scss
index 3bba7062a24..5b8763cfec0 100644
--- a/app/assets/stylesheets/login.scss
+++ b/app/assets/stylesheets/sections/login.scss
@@ -27,6 +27,7 @@ body.login-page{
-moz-border-radius-topright: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
+ margin-bottom:0px;
}
.login-box input.text.bottom{
@@ -41,4 +42,3 @@ body.login-page{
}
.login-box a.forgot{float: right; padding-top: 6px}
-
diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss
index 34f43acf839..ec84a64e23a 100644
--- a/app/assets/stylesheets/sections/merge_requests.scss
+++ b/app/assets/stylesheets/sections/merge_requests.scss
@@ -94,3 +94,8 @@ li.merge_request {
padding-bottom: 2px;
}
}
+
+.merge_in_progress {
+ @extend .padded;
+ @extend .append-bottom-10;
+}
diff --git a/app/assets/stylesheets/nav.scss b/app/assets/stylesheets/sections/nav.scss
index 93df41939a7..fc7293b2864 100644
--- a/app/assets/stylesheets/nav.scss
+++ b/app/assets/stylesheets/sections/nav.scss
@@ -6,14 +6,11 @@ ul.main_menu {
border-radius: 4px;
margin: auto;
margin:30px 0;
- background:#eee;
border:1px solid #bbb;
height:37px;
- 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 bg-gray-gradient;
position:relative;
+ overflow:hidden;
@include shade;
.count {
position: relative;
diff --git a/app/assets/stylesheets/notes.scss b/app/assets/stylesheets/sections/notes.scss
index 39db704b1a9..30587ef5b63 100644
--- a/app/assets/stylesheets/notes.scss
+++ b/app/assets/stylesheets/sections/notes.scss
@@ -14,7 +14,8 @@
border-bottom:1px solid #aaa;
}
-.issue_notes {
+.issue_notes,
+.wiki_notes {
.note_content {
float:left;
width:400px;
@@ -23,8 +24,8 @@
/* Note textare */
#note_note {
- height:100px;
- width:97%;
+ height:80px;
+ width:99%;
font-size:14px;
}
@@ -37,21 +38,31 @@
}
}
-.note .delete-note {
- display:none;
- float:right;
+.note {
+ padding: 8px 0;
+ border-bottom: 1px solid #eee;
+ overflow: hidden;
+ display: block;
+ img {float: left; margin-right: 10px;}
+ .note-author cite{font-style: italic;}
+ p { color:$style_color; }
+ .note-author { color: $style_color;}
+
+ .note-title { margin-left:45px; padding-top: 5px;}
+ .avatar {
+ margin-top:3px;
+ }
+
+ .delete-note {
+ display:none;
+ float:right;
+ }
+
+ &:hover {
+ .delete-note { display:block; }
+ }
}
-.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;
@@ -99,8 +110,25 @@ tr.line_notes_row {
td {
border-bottom:1px solid #ddd;
}
- .actions {
+ .note_actions {
margin:0;
+ padding-top: 10px;
+
+ .buttons {
+ float:left;
+ width:300px;
+ }
+ .options {
+ .labels {
+ float:left;
+ padding-left:10px;
+ label {
+ padding: 6px 0;
+ margin: 0;
+ width:120px;
+ }
+ }
+ }
}
}
@@ -141,23 +169,38 @@ td .line_note_link {
margin: 0;
}
- .file_upload {
- position: absolute;
- right:14px;
- top:7px;
+ .note_advanced_opts {
+ h6 {
+ line-height: 32px;
+ padding-right: 15px;
+ }
}
- div.attachments {
+ .attachments {
position:relative;
width: 350px;
- height: 36px;
+ height: 50px;
overflow:hidden;
margin:0 0 5px !important;
- }
- .file_name {
- line-height:30px;
- width:240px;
- height:28px;
- overflow:hidden;
+
+ .input_file {
+ .file_upload {
+ position: absolute;
+ right:14px;
+ top:7px;
+ }
+
+ .file_name {
+ line-height:30px;
+ width:240px;
+ height:28px;
+ overflow:hidden;
+ }
+ .input-file {
+ width: 260px;
+ height: 41px;
+ float: right;
+ }
+ }
}
}
diff --git a/app/assets/stylesheets/sections/projects.scss b/app/assets/stylesheets/sections/projects.scss
index 8c79e45e703..0866b43f71d 100644
--- a/app/assets/stylesheets/sections/projects.scss
+++ b/app/assets/stylesheets/sections/projects.scss
@@ -1,17 +1,18 @@
-.projects {
+.projects {
@extend .row;
.activities {
}
- .side {
+ .side {
@extend .span4;
@extend .right;
- .projects_box {
- h5 {
+ .projects_box {
+ h5 {
color:$style_color;
font-size:16px;
text-shadow: 0 1px 1px #fff;
+ padding: 2px 10px;
}
@extend .leftbar;
@extend .ui-box;
@@ -19,21 +20,22 @@
}
}
-.new_project,
-.edit_project {
- .project_name_holder {
+.new_project,
+.edit_project {
+ .project_name_holder {
input,
- label {
+ label {
font-size:16px;
line-height:20px;
padding:8px;
}
- label {
+ label {
color:#888;
}
- .btn {
+ .btn {
padding:6px;
margin-left:10px;
+ margin-bottom:8px;
}
}
}
diff --git a/app/assets/stylesheets/sections/tree.scss b/app/assets/stylesheets/sections/tree.scss
index 072d6103c8d..891f5e20871 100644
--- a/app/assets/stylesheets/sections/tree.scss
+++ b/app/assets/stylesheets/sections/tree.scss
@@ -38,9 +38,7 @@
.tree-item {
.tree-item-file-name {
vertical-align:middle;
- font-weight:bold;
a {
- color:$style_color;
&:hover {
color:$blue_link;
}
@@ -55,7 +53,7 @@
#tree-slider {
- @include shade;
+ @include solid_shade;
width:100%;
border-color:#ccc;
@@ -74,11 +72,7 @@
th {
border-color: #CCC;
border-bottom: 1px solid #bbb;
- background:#eee;
- 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 bg-gray-gradient;
}
}
diff --git a/app/assets/stylesheets/themes/ui_basic.scss b/app/assets/stylesheets/themes/ui_basic.scss
index 1b731c9192b..cf5eda1c893 100644
--- a/app/assets/stylesheets/themes/ui_basic.scss
+++ b/app/assets/stylesheets/themes/ui_basic.scss
@@ -1,18 +1,50 @@
/**
- * This file represent some UI that can be changed
- * during web app restyle or theme select.
+ * This file represent some UI that can be changed
+ * during web app restyle or theme select.
*
*/
-.ui_basic {
+.ui_basic {
/*
* Common styles
*
*/
a {
color: $link_color;
- &:hover {
- text-decoration:none;
+ &:hover {
+ text-decoration:none;
color: $blue_link;
}
}
+
+ header {
+ .fbtn {
+ .btn {
+ background-color: #F8F8F8;
+ background-image: -webkit-gradient(linear,left top,left bottom,from(#F8F8F8),to(#ECECEC));
+ background-image: -webkit-linear-gradient(top,#F8F8F8,#ECECEC);
+ background-image: -moz-linear-gradient(top,#F8F8F8,#ECECEC);
+ background-image: -ms-linear-gradient(top,#F8F8F8,#ECECEC);
+ background-image: -o-linear-gradient(top,#F8F8F8,#ECECEC);
+ background-image: linear-gradient(top,#F8F8F8,#ECECEC);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f8f8f8',EndColorStr='#ececec');
+ border-color: #C6C6C6;
+ margin-left:7px;
+ @include border-radius(3px);
+ box-shadow:none;
+ color:#666;
+ }
+ }
+ .search {
+ .search-input {
+ @include border-radius(3px);
+ border-color: #C6C6C6;
+ box-shadow:none;
+ }
+ }
+ .pic {
+ img {
+ @include border-radius(3px);
+ }
+ }
+ }
}
diff --git a/app/assets/stylesheets/themes/ui_mars.scss b/app/assets/stylesheets/themes/ui_mars.scss
index 0fea6144431..c630f388945 100644
--- a/app/assets/stylesheets/themes/ui_mars.scss
+++ b/app/assets/stylesheets/themes/ui_mars.scss
@@ -1,7 +1,7 @@
/**
- * This file represent some UI that can be changed
- * during web app restyle or theme select.
- *
+ * 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 restyles
@@ -13,25 +13,33 @@
* Application Header
*
*/
- header {
+ header {
background: #474D57 url('bg-header.png') repeat-x bottom;
box-shadow:none;
border-bottom: 1px solid #444;
- .fbtn {
- .btn {
+ .fbtn {
+ .btn {
+ i {
+ position: relative;
+ top: 1px;
+ }
margin-left:8px;
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);
font-size: 12px;
- &:hover {
+ &:hover {
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);
background-position:0 0;
+ color:#fff;
+ i {
+ @extend .icon-white;
+ }
}
border: 1px solid #31363E;
@@ -39,10 +47,10 @@
text-shadow: 0 -1px 0 #000000;
}
}
- .search {
+ .search {
float: right;
- margin-right: 55px;
- .search-input {
+ margin-right: 45px;
+ .search-input {
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;
@@ -57,26 +65,19 @@
color: #666;
}
.app_logo {
- a {
- h1 {
- background: url('images.png') no-repeat -3px -6px;
- width: 65px;
- height: 26px;
- margin: 6px 0;
- padding: 0;
- float: left;
- text-indent: -1000em;
- float:left;
+ a {
+ h1 {
+ background: url('logo_white.png') no-repeat 0px -3px;
+ color:#fff;
+ text-shadow: 0 1px 1px #111;
}
}
.separator {
- border-color:#444;
- background:#31363E;
+ display:none;
}
}
.project_name {
- line-height:38px;
color:#fff;
text-shadow: 0 1px 1px #111;
}
diff --git a/app/assets/stylesheets/themes/ui_modern.scss b/app/assets/stylesheets/themes/ui_modern.scss
index 1aeaafb7056..1f0d795562b 100644
--- a/app/assets/stylesheets/themes/ui_modern.scss
+++ b/app/assets/stylesheets/themes/ui_modern.scss
@@ -1,69 +1,134 @@
/**
- * This file represent some UI that can be changed
- * during web app restyle or theme select.
- *
+ * 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_modern {
- ul.main_menu {
- background:none;
- box-shadow:none;
- @include border-radius(0px);
- border:none;
- border-bottom:2px solid #456;
+.ui_modern {
+ /*
+ * Application Header
+ *
+ */
+ header {
+ height:40px;
+ background-image: -moz-linear-gradient(top, #333, #222);
+ background-image: -ms-linear-gradient(top, #333, #222);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333), to(#222));
+ background-image: -webkit-linear-gradient(top, #333, #222);
+ background-image: -o-linear-gradient(top, #333, #222);
+ background-image: linear-gradient(top, #333, #222);
+ background-repeat: repeat-x;
+ background-repeat: repeat-x;
+ filter: progid:dximagetransform.microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);
+ -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
+ -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
+
+ .container .top_panel_content { padding: 5px 0; }
- li {
- border:none;
- &.current {
- border-bottom:2px solid #f90;
- background-color:#fff;
- position:relative;
- top:2px;
+ /**
+ *
+ * Logo holder
+ *
+ */
+ .app_logo {
+ width:160px;
+ a {
+ h1 {
+ background: none;
+ color:#DDD;
+ font-size:30px;
+ text-shadow: 0 1px 1px #111;
+ padding-left: 0;
+ }
+ }
+ .separator {
+ width: 1px;
+ height: 40px;
+ margin: 0 10px;
+ overflow: hidden;
+ background: #222;
+ border-left: 1px solid #333;
}
}
- }
- /*
- * Common styles
- *
- */
- a {
- color: #E28934;
- &:hover {
- text-decoration:none;
- color: #f90;
+ .fbtn {
+ .btn {
+ i {
+ position: relative;
+ top: 2px;
+ }
+ background:none;
+ margin-left:8px;
+ font-size: 13px;
+ line-height: 19px;
+ color:#ccc;
+ &:hover {
+ color:#fff;
+ i {
+ @extend .icon-white;
+ }
+ }
+ border: none;
+ box-shadow:none;
+ text-shadow: 0 -1px 0 #000000;
+ border-left: 1px solid #333;
+ }
}
- }
- .btn {
- &.primary,
- &.btn-primary {
- border-color:#C60;
- background:#D70;
+ /**
+ *
+ * Search box
+ *
+ */
+ .search {
+ float: right;
+ margin-right: 45px;
+ .search-input {
+ 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);
- &:hover {
- background:#F90;
+ &:focus {
+ background-color: white;
+ }
+ }
+ .search-input::-webkit-input-placeholder {
+ color: #666;
}
}
- }
-
- .alert-info {
- border-color:#FDA;
- background:#FED;
- color:#D70;
- }
-
- .progress .bar {
- background:#D80;
- }
+ /**
+ *
+ * Project / Area name
+ *
+ */
+ .project_name {
+ line-height:36px;
+ font-size:30px;
+ color:#DDD;
+ text-shadow: 0 1px 1px #111;
+ }
- .back_link {
- color:#D80;
+ /**
+ *
+ * Account box
+ *
+ */
+ .account-box {
+ top:6px;
+ img {
+ top:1px;
+ right: 5px;
+ width: 26px;
+ height: 26px;
+ }
+ }
}
}
diff --git a/app/contexts/base_context.rb b/app/contexts/base_context.rb
new file mode 100644
index 00000000000..101be50d54b
--- /dev/null
+++ b/app/contexts/base_context.rb
@@ -0,0 +1,20 @@
+class BaseContext
+ attr_accessor :project, :current_user, :params
+
+ def initialize(project, user, params)
+ @project, @current_user, @params = project, user, params.dup
+ end
+
+ def abilities
+ @abilities ||= begin
+ abilities = Six.new
+ abilities << Ability
+ abilities
+ end
+ end
+
+ def can?(object, action, subject)
+ abilities.allowed?(object, action, subject)
+ end
+end
+
diff --git a/app/contexts/commit_load.rb b/app/contexts/commit_load.rb
new file mode 100644
index 00000000000..81fb4925cc8
--- /dev/null
+++ b/app/contexts/commit_load.rb
@@ -0,0 +1,33 @@
+class CommitLoad < BaseContext
+ def execute
+ result = {
+ commit: nil,
+ suppress_diff: false,
+ line_notes: [],
+ notes_count: 0,
+ note: nil,
+ status: :ok
+ }
+
+ commit = project.commit(params[:id])
+
+ if commit
+ commit = CommitDecorator.decorate(commit)
+ line_notes = project.commit_line_notes(commit)
+
+ result[:commit] = commit
+ result[:note] = project.build_commit_note(commit)
+ result[:line_notes] = line_notes
+ result[:notes_count] = line_notes.count + project.commit_notes(commit).count
+
+ begin
+ result[:suppress_diff] = true if commit.diffs.size > 200 && !params[:force_show_diff]
+ rescue Grit::Git::GitTimeout
+ result[:suppress_diff] = true
+ result[:status] = :huge_commit
+ end
+ end
+
+ result
+ end
+end
diff --git a/app/contexts/issues_bulk_update_context.rb b/app/contexts/issues_bulk_update_context.rb
new file mode 100644
index 00000000000..7c3c1d4f7c3
--- /dev/null
+++ b/app/contexts/issues_bulk_update_context.rb
@@ -0,0 +1,24 @@
+class IssuesBulkUpdateContext < BaseContext
+ def execute
+ update_data = params[:update]
+
+ issues_ids = update_data[:issues_ids].split(",")
+ milestone_id = update_data[:milestone_id]
+ assignee_id = update_data[:assignee_id]
+ status = update_data[:status]
+
+ opts = {}
+ opts[:milestone_id] = milestone_id if milestone_id.present?
+ opts[:assignee_id] = assignee_id if assignee_id.present?
+ opts[:closed] = (status == "closed") if status.present?
+
+ issues = Issue.where(id: issues_ids).all
+ issues = issues.select { |issue| can?(current_user, :modify_issue, issue) }
+ issues.each { |issue| issue.update_attributes(opts) }
+ {
+ count: issues.count,
+ success: !issues.count.zero?
+ }
+ end
+end
+
diff --git a/app/contexts/merge_requests_load.rb b/app/contexts/merge_requests_load.rb
new file mode 100644
index 00000000000..6778db3bce5
--- /dev/null
+++ b/app/contexts/merge_requests_load.rb
@@ -0,0 +1,16 @@
+class MergeRequestsLoad < BaseContext
+ def execute
+ type = params[:f].to_i
+
+ merge_requests = project.merge_requests
+
+ merge_requests = case type
+ when 1 then merge_requests
+ when 2 then merge_requests.closed
+ when 3 then merge_requests.opened.assigned(current_user)
+ else merge_requests.opened
+ end.page(params[:page]).per(20)
+
+ merge_requests.includes(:author, :project).order("closed, created_at desc")
+ end
+end
diff --git a/app/contexts/notes/create_context.rb b/app/contexts/notes/create_context.rb
new file mode 100644
index 00000000000..d93adb835ef
--- /dev/null
+++ b/app/contexts/notes/create_context.rb
@@ -0,0 +1,12 @@
+module Notes
+ class CreateContext < BaseContext
+ def execute
+ note = project.notes.new(params[:note])
+ note.author = current_user
+ note.notify = true if params[:notify] == '1'
+ note.notify_author = true if params[:notify_author] == '1'
+ note.save
+ note
+ end
+ end
+end
diff --git a/app/contexts/notes/load_context.rb b/app/contexts/notes/load_context.rb
new file mode 100644
index 00000000000..c89a7d19761
--- /dev/null
+++ b/app/contexts/notes/load_context.rb
@@ -0,0 +1,34 @@
+module Notes
+ class LoadContext < BaseContext
+ def execute
+ target_type = params[:target_type]
+ target_id = params[:target_id]
+ first_id = params[:first_id]
+ last_id = params[:last_id]
+
+
+ @notes = case target_type
+ when "commit"
+ then project.commit_notes(project.commit(target_id)).fresh.limit(20)
+ when "snippet"
+ then project.snippets.find(target_id).notes
+ when "wall"
+ then project.common_notes.order("created_at DESC").fresh.limit(50)
+ when "issue"
+ then project.issues.find(target_id).notes.inc_author.order("created_at DESC").limit(20)
+ when "merge_request"
+ then project.merge_requests.find(target_id).notes.inc_author.order("created_at DESC").limit(20)
+ when "wiki"
+ then project.wikis.reverse.map {|w| w.notes.fresh }.flatten[0..20]
+ end
+
+ @notes = if last_id
+ @notes.where("id > ?", last_id)
+ elsif first_id
+ @notes.where("id < ?", first_id)
+ else
+ @notes
+ end
+ end
+ end
+end
diff --git a/app/contexts/test_hook_context.rb b/app/contexts/test_hook_context.rb
new file mode 100644
index 00000000000..cba5d1f87c2
--- /dev/null
+++ b/app/contexts/test_hook_context.rb
@@ -0,0 +1,8 @@
+class TestHookContext < BaseContext
+ def execute
+ hook = project.hooks.find(params[:id])
+ commits = project.commits(project.default_branch, nil, 3)
+ data = project.post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{project.default_branch}", current_user)
+ hook.execute(data)
+ end
+end
diff --git a/app/controllers/admin/hooks_controller.rb b/app/controllers/admin/hooks_controller.rb
new file mode 100644
index 00000000000..7f832fd5697
--- /dev/null
+++ b/app/controllers/admin/hooks_controller.rb
@@ -0,0 +1,44 @@
+class Admin::HooksController < ApplicationController
+ layout "admin"
+ before_filter :authenticate_user!
+ before_filter :authenticate_admin!
+
+ def index
+ @hooks = SystemHook.all
+ @hook = SystemHook.new
+ end
+
+ def create
+ @hook = SystemHook.new(params[:hook])
+
+ if @hook.save
+ redirect_to admin_hooks_path, notice: 'Hook was successfully created.'
+ else
+ @hooks = SystemHook.all
+ render :index
+ end
+ end
+
+ def destroy
+ @hook = SystemHook.find(params[:id])
+ @hook.destroy
+
+ redirect_to admin_hooks_path
+ end
+
+
+ def test
+ @hook = SystemHook.find(params[:hook_id])
+ data = {
+ event_name: "project_create",
+ name: "Ruby",
+ path: "ruby",
+ project_id: 1,
+ owner_name: "Someone",
+ owner_email: "example@gitlabhq.com"
+ }
+ @hook.execute(data)
+
+ redirect_to :back
+ end
+end
diff --git a/app/controllers/admin/mailer_controller.rb b/app/controllers/admin/mailer_controller.rb
deleted file mode 100644
index 2352e189204..00000000000
--- a/app/controllers/admin/mailer_controller.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-class Admin::MailerController < ApplicationController
- layout "admin"
- before_filter :authenticate_user!
- before_filter :authenticate_admin!
-
- def preview
-
- end
-
- def preview_note
- @note = Note.first
- @user = @note.author
- @project = @note.project
- case params[:type]
- when "Commit" then
- @commit = @project.commit
- render :file => 'notify/note_commit_email', :layout => 'notify'
- when "Issue" then
- @issue = Issue.first
- render :file => 'notify/note_issue_email', :layout => 'notify'
- else
- render :file => 'notify/note_wall_email', :layout => 'notify'
- end
- rescue
- render :text => "Preview not available"
- end
-
- def preview_user_new
- @user = User.first
- @password = "DHasJKDHAS!"
-
- render :file => 'notify/new_user_email', :layout => 'notify'
- rescue
- render :text => "Preview not available"
- end
-
- def preview_issue_new
- @issue = Issue.first
- @user = @issue.assignee
- @project = @issue.project
- render :file => 'notify/new_issue_email', :layout => 'notify'
- rescue
- render :text => "Preview not available"
- end
-end
diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb
index 0ff97bf2c32..80d11f03ef0 100644
--- a/app/controllers/admin/projects_controller.rb
+++ b/app/controllers/admin/projects_controller.rb
@@ -2,6 +2,7 @@ class Admin::ProjectsController < ApplicationController
layout "admin"
before_filter :authenticate_user!
before_filter :authenticate_admin!
+ before_filter :admin_project, only: [:edit, :show, :update, :destroy, :team_update]
def index
@admin_projects = Project.scoped
@@ -10,13 +11,9 @@ class Admin::ProjectsController < ApplicationController
end
def show
- @admin_project = Project.find_by_code(params[:id])
-
- @users = if @admin_project.users.empty?
- User
- else
- User.not_in_project(@admin_project)
- end.all
+ @users = User.scoped
+ @users = @users.not_in_project(@admin_project) if @admin_project.users.present?
+ @users = @users.all
end
def new
@@ -24,19 +21,10 @@ class Admin::ProjectsController < ApplicationController
end
def edit
- @admin_project = Project.find_by_code(params[:id])
end
def team_update
- @admin_project = Project.find_by_code(params[:id])
-
- UsersProject.bulk_import(
- @admin_project,
- params[:user_ids],
- params[:project_access]
- )
-
- @admin_project.update_repository
+ @admin_project.add_users_ids_to_team(params[:user_ids], params[:project_access])
redirect_to [:admin, @admin_project], notice: 'Project was successfully updated.'
end
@@ -48,13 +36,11 @@ class Admin::ProjectsController < ApplicationController
if @admin_project.save
redirect_to [:admin, @admin_project], notice: 'Project was successfully created.'
else
- render :action => "new"
+ render action: "new"
end
end
def update
- @admin_project = Project.find_by_code(params[:id])
-
owner_id = params[:project].delete(:owner_id)
if owner_id
@@ -64,14 +50,19 @@ class Admin::ProjectsController < ApplicationController
if @admin_project.update_attributes(params[:project])
redirect_to [:admin, @admin_project], notice: 'Project was successfully updated.'
else
- render :action => "edit"
+ render action: "edit"
end
end
def destroy
- @admin_project = Project.find_by_code(params[:id])
@admin_project.destroy
redirect_to admin_projects_url, notice: 'Project was successfully deleted.'
end
+
+ private
+
+ def admin_project
+ @admin_project = Project.find_by_code(params[:id])
+ end
end
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 4b123e4f032..1e8f420b098 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -34,7 +34,7 @@ class Admin::UsersController < ApplicationController
def new
- @admin_user = User.new(:projects_limit => Gitlab.config.default_projects_limit)
+ @admin_user = User.new(projects_limit: Gitlab.config.default_projects_limit)
end
def edit
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 3265046d2ae..7c1941ec859 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -4,21 +4,22 @@ class ApplicationController < ActionController::Base
before_filter :set_current_user_for_mailer
before_filter :check_token_auth
before_filter :set_current_user_for_observers
+ before_filter :dev_tools if Rails.env == 'development'
protect_from_forgery
helper_method :abilities, :can?
rescue_from Gitlab::Gitolite::AccessDenied do |exception|
- render "errors/gitolite", :layout => "error"
+ render "errors/gitolite", layout: "error"
end
rescue_from Encoding::CompatibilityError do |exception|
- render "errors/encoding", :layout => "error", :status => 404
+ render "errors/encoding", layout: "error", status: 404
end
rescue_from ActiveRecord::RecordNotFound do |exception|
- render "errors/not_found", :layout => "error", :status => 404
+ render "errors/not_found", layout: "error", status: 404
end
layout :layout_by_resource
@@ -96,15 +97,15 @@ class ApplicationController < ActionController::Base
end
def access_denied!
- render "errors/access_denied", :layout => "error", :status => 404
+ render "errors/access_denied", layout: "error", status: 404
end
def not_found!
- render "errors/not_found", :layout => "error", :status => 404
+ render "errors/not_found", layout: "error", status: 404
end
def git_not_found!
- render "errors/git_not_found", :layout => "error", :status => 404
+ render "errors/git_not_found", layout: "error", status: 404
end
def method_missing(method_sym, *arguments, &block)
@@ -126,7 +127,7 @@ class ApplicationController < ActionController::Base
end
def render_404
- render :file => File.join(Rails.root, "public", "404"), :layout => false, :status => "404"
+ render file: File.join(Rails.root, "public", "404"), layout: false, status: "404"
end
def require_non_empty_project
@@ -142,4 +143,8 @@ class ApplicationController < ActionController::Base
def render_full_content
@full_content = true
end
+
+ def dev_tools
+ Rack::MiniProfiler.authorize_request
+ end
end
diff --git a/app/controllers/commits_controller.rb b/app/controllers/commits_controller.rb
index 25e980e017b..717912d9e92 100644
--- a/app/controllers/commits_controller.rb
+++ b/app/controllers/commits_controller.rb
@@ -9,7 +9,7 @@ class CommitsController < ApplicationController
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 :load_refs, only: :index # load @branch, @tag & @ref
before_filter :render_full_content
def index
@@ -17,52 +17,44 @@ class CommitsController < ApplicationController
@limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
@commits = @project.commits(@ref, params[:path], @limit, @offset)
+ @commits = CommitDecorator.decorate(@commits)
respond_to do |format|
format.html # index.html.erb
format.js
- format.atom { render :layout => false }
+ format.atom { render layout: false }
end
end
def show
- @commit = project.commit(params[:id])
-
- git_not_found! and return unless @commit
-
- @commit = CommitDecorator.decorate(@commit)
-
- @note = @project.build_commit_note(@commit)
- @comments_allowed = true
- @line_notes = project.commit_line_notes(@commit)
-
- @notes_count = @line_notes.count + project.commit_notes(@commit).count
+ result = CommitLoad.new(project, current_user, params).execute
+
+ @commit = result[:commit]
+
+ if @commit
+ @suppress_diff = result[:suppress_diff]
+ @note = result[:note]
+ @line_notes = result[:line_notes]
+ @notes_count = result[:notes_count]
+ @comments_allowed = true
+ else
+ return git_not_found!
+ end
- if @commit.diffs.size > 200 && !params[:force_show_diff]
- @suppress_diff = true
+ if result[:status] == :huge_commit
+ render "huge_commit" and return
end
- rescue Grit::Git::GitTimeout
- render "huge_commit"
end
def compare
- first = project.commit(params[:to].try(:strip))
- last = project.commit(params[:from].try(:strip))
+ result = Commit.compare(project, params[:from], params[:to])
- @diffs = []
- @commits = []
+ @commits = result[:commits]
+ @commit = result[:commit]
+ @diffs = result[:diffs]
@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
+ @commits = CommitDecorator.decorate(@commits)
end
def patch
@@ -70,9 +62,9 @@ class CommitsController < ApplicationController
send_data(
@commit.to_patch,
- :type => "text/plain",
- :disposition => 'attachment',
- :filename => (@commit.id.to_s + ".patch")
+ type: "text/plain",
+ disposition: 'attachment',
+ filename: (@commit.id.to_s + ".patch")
)
end
end
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index a054940738e..7696e97a7b2 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -2,16 +2,14 @@ class DashboardController < ApplicationController
respond_to :html
def index
- @projects = current_user.projects.includes(:events).order("events.created_at DESC")
- @projects = @projects.page(params[:page]).per(40)
-
- @events = Event.where(:project_id => current_user.projects.map(&:id)).recent.limit(20)
-
+ @projects = current_user.projects_with_events.page(params[:page]).per(40)
+ @events = Event.recent_for_user(current_user).limit(20).offset(params[:offset] || 0)
@last_push = current_user.recent_push
respond_to do |format|
format.html
- format.atom { render :layout => false }
+ format.js
+ format.atom { render layout: false }
end
end
@@ -30,7 +28,7 @@ class DashboardController < ApplicationController
respond_to do |format|
format.html
- format.atom { render :layout => false }
+ format.atom { render layout: false }
end
end
end
diff --git a/app/controllers/deploy_keys_controller.rb b/app/controllers/deploy_keys_controller.rb
index 9d4e0483d65..82c10512a64 100644
--- a/app/controllers/deploy_keys_controller.rb
+++ b/app/controllers/deploy_keys_controller.rb
@@ -40,7 +40,7 @@ class DeployKeysController < ApplicationController
respond_to do |format|
format.html { redirect_to project_deploy_keys_url }
- format.js { render :nothing => true }
+ format.js { render nothing: true }
end
end
end
diff --git a/app/controllers/hooks_controller.rb b/app/controllers/hooks_controller.rb
index 9627aba9771..c81e6b05cb3 100644
--- a/app/controllers/hooks_controller.rb
+++ b/app/controllers/hooks_controller.rb
@@ -6,38 +6,35 @@ class HooksController < ApplicationController
# Authorize
before_filter :add_project_abilities
before_filter :authorize_read_project!
- before_filter :authorize_admin_project!, :only => [:new, :create, :destroy]
+ before_filter :authorize_admin_project!, only: [:new, :create, :destroy]
respond_to :html
def index
- @hooks = @project.web_hooks.all
- @hook = WebHook.new
+ @hooks = @project.hooks.all
+ @hook = ProjectHook.new
end
def create
- @hook = @project.web_hooks.new(params[:hook])
+ @hook = @project.hooks.new(params[:hook])
@hook.save
if @hook.valid?
redirect_to project_hooks_path(@project)
else
- @hooks = @project.web_hooks.all
+ @hooks = @project.hooks.all
render :index
end
end
def test
- @hook = @project.web_hooks.find(params[:id])
- commits = @project.commits(@project.default_branch, nil, 3)
- data = @project.post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{@project.default_branch}", current_user)
- @hook.execute(data)
+ TestHookContext.new(project, current_user, params).execute
redirect_to :back
end
def destroy
- @hook = @project.web_hooks.find(params[:id])
+ @hook = @project.hooks.find(params[:id])
@hook.destroy
redirect_to project_hooks_path(@project)
diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb
index c36258c818a..889a7d98033 100644
--- a/app/controllers/issues_controller.rb
+++ b/app/controllers/issues_controller.rb
@@ -2,7 +2,7 @@ class IssuesController < ApplicationController
before_filter :authenticate_user!
before_filter :project
before_filter :module_enabled
- before_filter :issue, :only => [:edit, :update, :destroy, :show]
+ before_filter :issue, only: [:edit, :update, :destroy, :show]
helper_method :issues_filter
layout "project"
@@ -14,13 +14,13 @@ class IssuesController < ApplicationController
before_filter :authorize_read_issue!
# Allow write(create) issue
- before_filter :authorize_write_issue!, :only => [:new, :create]
+ before_filter :authorize_write_issue!, only: [:new, :create]
# Allow modify issue
- before_filter :authorize_modify_issue!, :only => [:close, :edit, :update]
+ before_filter :authorize_modify_issue!, only: [:close, :edit, :update]
# Allow destroy issue
- before_filter :authorize_admin_issue!, :only => [:destroy]
+ before_filter :authorize_admin_issue!, only: [:destroy]
respond_to :js, :html
@@ -32,7 +32,7 @@ class IssuesController < ApplicationController
respond_to do |format|
format.html # index.html.erb
format.js
- format.atom { render :layout => false }
+ format.atom { render layout: false }
end
end
@@ -46,7 +46,7 @@ class IssuesController < ApplicationController
end
def show
- @note = @project.notes.new(:noteable => @issue)
+ @note = @project.notes.new(noteable: @issue)
respond_to do |format|
format.html
@@ -66,7 +66,7 @@ class IssuesController < ApplicationController
end
def update
- @issue.update_attributes(params[:issue].merge(:author_id_of_changes => current_user.id))
+ @issue.update_attributes(params[:issue].merge(author_id_of_changes: current_user.id))
respond_to do |format|
format.js
@@ -87,20 +87,20 @@ class IssuesController < ApplicationController
respond_to do |format|
format.html { redirect_to project_issues_path }
- format.js { render :nothing => true }
+ format.js { render nothing: true }
end
end
def sort
return render_404 unless can?(current_user, :admin_issue, @project)
- @issues = @project.issues.where(:id => params['issue'])
+ @issues = @project.issues.where(id: params['issue'])
@issues.each do |issue|
issue.position = params['issue'].index(issue.id.to_s) + 1
issue.save
end
- render :nothing => true
+ render nothing: true
end
def search
@@ -110,7 +110,12 @@ class IssuesController < ApplicationController
@issues = @issues.where("title LIKE ?", "%#{terms}%") unless terms.blank?
@issues = @issues.page(params[:page]).per(100)
- render :partial => 'issues'
+ render partial: 'issues'
+ end
+
+ def bulk_update
+ result = IssuesBulkUpdateContext.new(project, current_user, params).execute
+ redirect_to :back, notice: "#{result[:count]} issues updated"
end
protected
@@ -139,10 +144,19 @@ class IssuesController < ApplicationController
else @project.issues.opened
end
- @issues = @issues.where(:assignee_id => params[:assignee_id]) if params[:assignee_id].present?
- @issues = @issues.where(:milestone_id => params[:milestone_id]) if params[:milestone_id].present?
@issues = @issues.tagged_with(params[:label_name]) if params[:label_name].present?
@issues = @issues.includes(:author, :project).order("updated_at")
+
+ # Filter by specific assignee_id (or lack thereof)?
+ if params[:assignee_id].present?
+ @issues = @issues.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id]))
+ end
+
+ # Filter by specific milestone_id (or lack thereof)?
+ if params[:milestone_id].present?
+ @issues = @issues.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id]))
+ end
+
@issues
end
diff --git a/app/controllers/keys_controller.rb b/app/controllers/keys_controller.rb
index ce49e3e72c6..1a25d834e12 100644
--- a/app/controllers/keys_controller.rb
+++ b/app/controllers/keys_controller.rb
@@ -29,7 +29,7 @@ class KeysController < ApplicationController
respond_to do |format|
format.html { redirect_to keys_url }
- format.js { render :nothing => true }
+ format.js { render nothing: true }
end
end
end
diff --git a/app/controllers/labels_controller.rb b/app/controllers/labels_controller.rb
new file mode 100644
index 00000000000..e703f822982
--- /dev/null
+++ b/app/controllers/labels_controller.rb
@@ -0,0 +1,25 @@
+class LabelsController < ApplicationController
+ before_filter :authenticate_user!
+ before_filter :project
+ before_filter :module_enabled
+
+ layout "project"
+
+ # Authorize
+ before_filter :add_project_abilities
+
+ # Allow read any issue
+ before_filter :authorize_read_issue!
+
+ respond_to :js, :html
+
+ def index
+ @labels = @project.issues.tag_counts_on(:labels).order('count DESC')
+ end
+
+ protected
+
+ def module_enabled
+ return render_404 unless @project.issues_enabled
+ end
+end
diff --git a/app/controllers/merge_requests_controller.rb b/app/controllers/merge_requests_controller.rb
index ec4ed45fedf..187bb407b2d 100644
--- a/app/controllers/merge_requests_controller.rb
+++ b/app/controllers/merge_requests_controller.rb
@@ -2,9 +2,9 @@ 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, :automerge, :automerge_check, :raw]
- before_filter :validates_merge_request, :only => [:show, :diffs, :raw]
- before_filter :define_show_vars, :only => [:show, :diffs]
+ before_filter :merge_request, only: [:edit, :update, :destroy, :show, :commits, :diffs, :automerge, :automerge_check, :raw]
+ before_filter :validates_merge_request, only: [:show, :diffs, :raw]
+ before_filter :define_show_vars, only: [:show, :diffs]
layout "project"
# Authorize
@@ -14,26 +14,17 @@ class MergeRequestsController < ApplicationController
before_filter :authorize_read_merge_request!
# Allow write(create) merge_request
- before_filter :authorize_write_merge_request!, :only => [:new, :create]
+ before_filter :authorize_write_merge_request!, only: [:new, :create]
# Allow modify merge_request
- before_filter :authorize_modify_merge_request!, :only => [:close, :edit, :update, :sort]
+ before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort]
# Allow destroy merge_request
- before_filter :authorize_admin_merge_request!, :only => [:destroy]
+ before_filter :authorize_admin_merge_request!, only: [:destroy]
def index
- @merge_requests = @project.merge_requests
-
- @merge_requests = case params[:f].to_i
- when 1 then @merge_requests
- when 2 then @merge_requests.closed
- when 3 then @merge_requests.opened.assigned(current_user)
- else @merge_requests.opened
- end.page(params[:page]).per(20)
-
- @merge_requests = @merge_requests.includes(:author, :project).order("closed, created_at desc")
+ @merge_requests = MergeRequestsLoad.new(project, current_user, params).execute
end
def show
@@ -75,7 +66,7 @@ class MergeRequestsController < ApplicationController
end
def update
- if @merge_request.update_attributes(params[:merge_request].merge(:author_id_of_changes => current_user.id))
+ if @merge_request.update_attributes(params[:merge_request].merge(author_id_of_changes: current_user.id))
@merge_request.reload_code
@merge_request.mark_as_unchecked
redirect_to [@project, @merge_request], notice: 'Merge request was successfully updated.'
@@ -88,7 +79,7 @@ class MergeRequestsController < ApplicationController
if @merge_request.unchecked?
@merge_request.check_if_can_be_merged
end
- render :json => {:state => @merge_request.human_state}
+ render json: {state: @merge_request.human_state}
end
def automerge
@@ -112,10 +103,12 @@ class MergeRequestsController < ApplicationController
def branch_from
@commit = project.commit(params[:ref])
+ @commit = CommitDecorator.decorate(@commit)
end
def branch_to
@commit = project.commit(params[:ref])
+ @commit = CommitDecorator.decorate(@commit)
end
protected
@@ -147,10 +140,11 @@ class MergeRequestsController < ApplicationController
def define_show_vars
# Build a note object for comment form
- @note = @project.notes.new(:noteable => @merge_request)
+ @note = @project.notes.new(noteable: @merge_request)
# Get commits from repository
# or from cache if already merged
@commits = @merge_request.commits
+ @commits = CommitDecorator.decorate(@commits)
end
end
diff --git a/app/controllers/milestones_controller.rb b/app/controllers/milestones_controller.rb
index 1f2490cb6ef..7acb3781fbb 100644
--- a/app/controllers/milestones_controller.rb
+++ b/app/controllers/milestones_controller.rb
@@ -2,7 +2,7 @@ class MilestonesController < ApplicationController
before_filter :authenticate_user!
before_filter :project
before_filter :module_enabled
- before_filter :milestone, :only => [:edit, :update, :destroy, :show]
+ before_filter :milestone, only: [:edit, :update, :destroy, :show]
layout "project"
# Authorize
@@ -12,7 +12,7 @@ class MilestonesController < ApplicationController
before_filter :authorize_read_milestone!
# Allow admin milestone
- before_filter :authorize_admin_milestone!, :except => [:index, :show]
+ before_filter :authorize_admin_milestone!, except: [:index, :show]
respond_to :html
@@ -77,7 +77,7 @@ class MilestonesController < ApplicationController
respond_to do |format|
format.html { redirect_to project_milestones_path }
- format.js { render :nothing => true }
+ format.js { render nothing: true }
end
end
diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb
index a2638d9597c..f003ea7bf66 100644
--- a/app/controllers/notes_controller.rb
+++ b/app/controllers/notes_controller.rb
@@ -5,7 +5,7 @@ class NotesController < ApplicationController
before_filter :add_project_abilities
before_filter :authorize_read_note!
- before_filter :authorize_write_note!, :only => [:create]
+ before_filter :authorize_write_note!, only: [:create]
respond_to :js
@@ -15,11 +15,7 @@ class NotesController < ApplicationController
end
def create
- @note = @project.notes.new(params[:note])
- @note.author = current_user
- @note.notify = true if params[:notify] == '1'
- @note.notify_author = true if params[:notify_author] == '1'
- @note.save
+ @note = Notes::CreateContext.new(project, current_user, params).execute
respond_to do |format|
format.html {redirect_to :back}
@@ -33,32 +29,17 @@ class NotesController < ApplicationController
@note.destroy
respond_to do |format|
- format.js { render :nothing => true }
+ format.js { render nothing: true }
end
end
- protected
+ def preview
+ render text: view_context.markdown(params[:note])
+ end
- 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
+ protected
- @notes = if params[:last_id]
- @notes.where("id > ?", params[:last_id])
- elsif params[:first_id]
- @notes.where("id < ?", params[:first_id])
- else
- @notes
- end
+ def notes
+ @notes = Notes::LoadContext.new(project, current_user, params).execute
end
end
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index fb759c371c4..d472936b4b4 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -3,20 +3,16 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
# Extend the standard message generation to accept our custom exception
def failure_message
exception = env["omniauth.error"]
- if exception.class == OmniAuth::Error
- error = exception.message
- else
- error = exception.error_reason if exception.respond_to?(:error_reason)
- error ||= exception.error if exception.respond_to?(:error)
- error ||= env["omniauth.error.type"].to_s
- end
+ error = exception.error_reason if exception.respond_to?(:error_reason)
+ error ||= exception.error if exception.respond_to?(:error)
+ error ||= exception.message if exception.respond_to?(:message)
+ error ||= env["omniauth.error.type"].to_s
error.to_s.humanize if error
end
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)
+ @user = User.find_for_ldap_auth(request.env["omniauth.auth"], current_user)
if @user.persisted?
@user.remember_me = true
end
diff --git a/app/controllers/profile_controller.rb b/app/controllers/profile_controller.rb
index 0da463757f3..a95a331096a 100644
--- a/app/controllers/profile_controller.rb
+++ b/app/controllers/profile_controller.rb
@@ -1,36 +1,32 @@
class ProfileController < ApplicationController
layout "profile"
+ before_filter :user
+
def show
- @user = current_user
end
def design
- @user = current_user
end
def update
- @user = current_user
@user.update_attributes(params[:user])
redirect_to :back
end
def token
- @user = current_user
end
def password
- @user = current_user
end
def password_update
params[:user].reject!{ |k, v| k != "password" && k != "password_confirmation"}
- @user = current_user
if @user.update_attributes(params[:user])
flash[:notice] = "Password was successfully updated. Please login with it"
redirect_to new_user_session_path
else
- render :action => "password"
+ render action: "password"
end
end
@@ -38,4 +34,10 @@ class ProfileController < ApplicationController
current_user.reset_authentication_token!
redirect_to profile_token_path
end
+
+ private
+
+ def user
+ @user = current_user
+ end
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 26b62cba9f9..bd7f811e59f 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -1,14 +1,14 @@
-require File.join(Rails.root, 'lib', 'graph_commit')
+require Rails.root.join('lib', 'gitlab', 'graph_commit')
class ProjectsController < ApplicationController
- before_filter :project, :except => [:index, :new, :create]
+ before_filter :project, except: [:index, :new, :create]
layout :determine_layout
# Authorize
before_filter :add_project_abilities
- before_filter :authorize_read_project!, :except => [:index, :new, :create]
- before_filter :authorize_admin_project!, :only => [:edit, :update, :destroy]
- before_filter :require_non_empty_project, :only => [:blob, :tree, :graph]
+ before_filter :authorize_read_project!, except: [:index, :new, :create]
+ before_filter :authorize_admin_project!, only: [:edit, :update, :destroy]
+ before_filter :require_non_empty_project, only: [:blob, :tree, :graph]
def new
@project = Project.new
@@ -35,7 +35,7 @@ class ProjectsController < ApplicationController
def update
respond_to do |format|
if project.update_attributes(params[:project])
- format.html { redirect_to edit_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" }
@@ -78,7 +78,7 @@ class ProjectsController < ApplicationController
end
def graph
- @days_json, @commits_json = GraphCommit.to_graph(project)
+ @days_json, @commits_json = Gitlab::GraphCommit.to_graph(project)
end
def destroy
diff --git a/app/controllers/protected_branches_controller.rb b/app/controllers/protected_branches_controller.rb
index 0b86f5253ce..78c9c9effa6 100644
--- a/app/controllers/protected_branches_controller.rb
+++ b/app/controllers/protected_branches_controller.rb
@@ -6,7 +6,7 @@ class ProtectedBranchesController < ApplicationController
before_filter :authorize_read_project!
before_filter :require_non_empty_project
- before_filter :authorize_admin_project!, :only => [:destroy, :create]
+ before_filter :authorize_admin_project!, only: [:destroy, :create]
before_filter :render_full_content
layout "project"
@@ -26,7 +26,7 @@ class ProtectedBranchesController < ApplicationController
respond_to do |format|
format.html { redirect_to project_protected_branches_path }
- format.js { render :nothing => true }
+ format.js { render nothing: true }
end
end
end
diff --git a/app/controllers/refs_controller.rb b/app/controllers/refs_controller.rb
index b610c9f34d4..3f81a2ca1a3 100644
--- a/app/controllers/refs_controller.rb
+++ b/app/controllers/refs_controller.rb
@@ -9,7 +9,7 @@ class RefsController < ApplicationController
before_filter :require_non_empty_project
before_filter :ref
- before_filter :define_tree_vars, :only => [:tree, :blob, :blame, :logs_tree]
+ before_filter :define_tree_vars, only: [:tree, :blob, :blame, :logs_tree]
before_filter :render_full_content
layout "project"
@@ -20,7 +20,7 @@ class RefsController < ApplicationController
new_path = if params[:destination] == "tree"
tree_project_ref_path(@project, params[:ref])
else
- project_commits_path(@project, :ref => params[:ref])
+ project_commits_path(@project, ref: params[:ref])
end
redirect_to new_path
@@ -51,9 +51,10 @@ class RefsController < ApplicationController
@logs = contents.map do |content|
file = params[:path] ? File.join(params[:path], content.name) : content.name
last_commit = @project.commits(@commit.id, file, 1).last
- {
- :file_name => content.name,
- :commit => last_commit
+ last_commit = CommitDecorator.decorate(last_commit)
+ {
+ file_name: content.name,
+ commit: last_commit
}
end
end
@@ -69,9 +70,9 @@ class RefsController < ApplicationController
send_data(
@tree.data,
- :type => mime_type,
- :disposition => 'inline',
- :filename => @tree.name
+ type: mime_type,
+ disposition: 'inline',
+ filename: @tree.name
)
else
head(404)
@@ -89,6 +90,7 @@ class RefsController < ApplicationController
@repo = project.repo
@commit = project.commit(@ref)
+ @commit = CommitDecorator.decorate(@commit)
@tree = Tree.new(@commit.tree, project, @ref, params[:path])
@tree = TreeDecorator.new(@tree)
@hex_path = Digest::SHA1.hexdigest(params[:path] || "/")
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index dfc318c5fb1..71e2d92b2b2 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -1,14 +1,15 @@
class SearchController < ApplicationController
def show
query = params[:search]
- if query.blank?
- @projects = []
- @merge_requests = []
- @issues = []
- else
+
+ @projects = []
+ @merge_requests = []
+ @issues = []
+
+ if query.present?
@projects = current_user.projects.search(query).limit(10)
- @merge_requests = MergeRequest.where(:project_id => current_user.project_ids).search(query).limit(10)
- @issues = Issue.where(:project_id => current_user.project_ids).search(query).limit(10)
+ @merge_requests = MergeRequest.where(project_id: current_user.project_ids).search(query).limit(10)
+ @issues = Issue.where(project_id: current_user.project_ids).search(query).limit(10)
end
end
end
diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb
index 3d56bebe2fe..f852e425891 100644
--- a/app/controllers/snippets_controller.rb
+++ b/app/controllers/snippets_controller.rb
@@ -1,7 +1,7 @@
class SnippetsController < ApplicationController
before_filter :authenticate_user!
before_filter :project
- before_filter :snippet, :only => [:show, :edit, :destroy, :update, :raw]
+ before_filter :snippet, only: [:show, :edit, :destroy, :update, :raw]
layout "project"
# Authorize
@@ -11,13 +11,13 @@ class SnippetsController < ApplicationController
before_filter :authorize_read_snippet!
# Allow write(create) snippet
- before_filter :authorize_write_snippet!, :only => [:new, :create]
+ before_filter :authorize_write_snippet!, only: [:new, :create]
# Allow modify snippet
- before_filter :authorize_modify_snippet!, :only => [:edit, :update]
+ before_filter :authorize_modify_snippet!, only: [:edit, :update]
# Allow destroy snippet
- before_filter :authorize_admin_snippet!, :only => [:destroy]
+ before_filter :authorize_admin_snippet!, only: [:destroy]
respond_to :html
@@ -55,7 +55,7 @@ class SnippetsController < ApplicationController
end
def show
- @note = @project.notes.new(:noteable => @snippet)
+ @note = @project.notes.new(noteable: @snippet)
render_full_content
end
@@ -70,9 +70,9 @@ class SnippetsController < ApplicationController
def raw
send_data(
@snippet.content,
- :type => "text/plain",
- :disposition => 'inline',
- :filename => @snippet.file_name
+ type: "text/plain",
+ disposition: 'inline',
+ filename: @snippet.file_name
)
end
diff --git a/app/controllers/team_members_controller.rb b/app/controllers/team_members_controller.rb
index ab51c19e0c8..0846f096554 100644
--- a/app/controllers/team_members_controller.rb
+++ b/app/controllers/team_members_controller.rb
@@ -5,10 +5,11 @@ class TeamMembersController < ApplicationController
# Authorize
before_filter :add_project_abilities
before_filter :authorize_read_project!
- before_filter :authorize_admin_project!, :except => [:show]
+ before_filter :authorize_admin_project!, except: [:show]
def show
@team_member = project.users_projects.find(params[:id])
+ @events = @team_member.user.recent_events.where(:project_id => @project.id).limit(7)
end
def new
@@ -41,7 +42,7 @@ class TeamMembersController < ApplicationController
respond_to do |format|
format.html { redirect_to team_project_path(@project) }
- format.js { render :nothing => true }
+ format.js { render nothing: true }
end
end
end
diff --git a/app/controllers/wikis_controller.rb b/app/controllers/wikis_controller.rb
index 9bcd20c3187..55ccfe72116 100644
--- a/app/controllers/wikis_controller.rb
+++ b/app/controllers/wikis_controller.rb
@@ -2,33 +2,37 @@ 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
+ before_filter :authorize_write_wiki!, only: [:edit, :create, :history]
+ before_filter :authorize_admin_wiki!, only: :destroy
layout "project"
+ def pages
+ @wikis = @project.wikis.group(:slug).order("created_at")
+ end
+
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
+ @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
+ @note = @project.notes.new(noteable: @wiki)
- respond_to do |format|
- if @wiki
- format.html
+ if @wiki
+ render 'show'
+ else
+ if can?(current_user, :write_wiki, @project)
+ @wiki = @project.wikis.new(slug: params[:id])
+ render 'edit'
else
- @wiki = @project.wikis.new(:slug => params[:id])
- format.html { render "edit" }
+ render 'empty'
end
end
end
def edit
- @wiki = @project.wikis.where(:slug => params[:id]).order("created_at").last
+ @wiki = @project.wikis.where(slug: params[:id]).order("created_at").last
@wiki = Wiki.regenerate_from @wiki
end
@@ -46,11 +50,11 @@ class WikisController < ApplicationController
end
def history
- @wikis = @project.wikis.where(:slug => params[:id]).order("created_at")
+ @wikis = @project.wikis.where(slug: params[:id]).order("created_at")
end
def destroy
- @wikis = @project.wikis.where(:slug => params[:id]).delete_all
+ @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" }
diff --git a/app/decorators/application_decorator.rb b/app/decorators/application_decorator.rb
index 8c35cae98fd..3023699e700 100644
--- a/app/decorators/application_decorator.rb
+++ b/app/decorators/application_decorator.rb
@@ -1,4 +1,4 @@
-class ApplicationDecorator < Drapper::Base
+class ApplicationDecorator < Draper::Base
# Lazy Helpers
# PRO: Call Rails helpers without the h. proxy
# ex: number_to_currency(model.price)
@@ -15,7 +15,7 @@ class ApplicationDecorator < Drapper::Base
#
# def formatted_timestamp(time)
# h.content_tag :span, time.strftime("%a %m/%d/%y"),
- # :class => 'timestamp'
+ # class: 'timestamp'
# end
#
# def created_at
diff --git a/app/decorators/event_decorator.rb b/app/decorators/event_decorator.rb
index 50aaa615d49..7df9081f045 100644
--- a/app/decorators/event_decorator.rb
+++ b/app/decorators/event_decorator.rb
@@ -19,7 +19,7 @@ class EventDecorator < ApplicationDecorator
elsif self.merge_request?
h.project_merge_request_url(self.project, self.merge_request)
elsif self.push?
- h.project_commits_url(self.project, :ref => self.ref_name)
+ h.project_commits_url(self.project, ref: self.ref_name)
end
end
end
diff --git a/app/decorators/tree_decorator.rb b/app/decorators/tree_decorator.rb
index 2b82a42561b..80c48da75bf 100644
--- a/app/decorators/tree_decorator.rb
+++ b/app/decorators/tree_decorator.rb
@@ -8,14 +8,14 @@ class TreeDecorator < ApplicationDecorator
#parts = parts[0...-1] if is_blob?
- yield(h.link_to("..", "#", :remote => :true)) if parts.count > max_links
+ yield(h.link_to("..", "#", remote: :true)) if parts.count > max_links
parts.each do |part|
part_path = File.join(part_path, part) unless part_path.empty?
part_path = part if part_path.empty?
next unless parts.last(2).include?(part) if parts.count > max_links
- yield(h.link_to(h.truncate(part, :length => 40), h.tree_file_project_ref_path(project, ref, :path => part_path), :remote => :true))
+ yield(h.link_to(h.truncate(part, length: 40), h.tree_file_project_ref_path(project, ref, path: part_path), remote: :true))
end
end
end
@@ -30,7 +30,7 @@ class TreeDecorator < ApplicationDecorator
end
def history_path
- h.project_commits_path(project, :path => path, :ref => ref)
+ h.project_commits_path(project, path: path, ref: ref)
end
def mb_size
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 3f15fd9237f..38191f55571 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -2,10 +2,13 @@ require 'digest/md5'
module ApplicationHelper
def gravatar_icon(user_email = '', size = 40)
- return unless user_email
- gravatar_host = request.ssl? ? "https://secure.gravatar.com" : "http://www.gravatar.com"
- user_email.strip!
- "#{gravatar_host}/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=identicon"
+ if Gitlab.config.disable_gravatar? || user_email.blank?
+ 'no_avatar.png'
+ else
+ gravatar_prefix = request.ssl? ? "https://secure" : "http://www"
+ user_email.strip!
+ "#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=identicon"
+ end
end
def request_protocol
@@ -42,39 +45,24 @@ module ApplicationHelper
grouped_options_for_select(options, @ref || @project.default_branch)
end
- def markdown(text)
- @__renderer ||= Redcarpet::Markdown.new(Redcarpet::Render::GitlabHTML.new(filter_html: true), {
- no_intra_emphasis: true,
- tables: true,
- fenced_code_blocks: true,
- autolink: true,
- strikethrough: true,
- lax_html_blocks: true,
- space_after_headers: true,
- superscript: true
- })
-
- @__renderer.render(text).html_safe
- end
-
def search_autocomplete_source
- projects = current_user.projects.map{ |p| { :label => p.name, :url => project_path(p) } }
+ projects = current_user.projects.map{ |p| { label: p.name, url: project_path(p) } }
default_nav = [
- { :label => "Profile", :url => profile_path },
- { :label => "Keys", :url => keys_path },
- { :label => "Dashboard", :url => root_path },
- { :label => "Admin", :url => admin_root_path }
+ { label: "Profile", url: profile_path },
+ { label: "Keys", url: keys_path },
+ { label: "Dashboard", url: root_path },
+ { label: "Admin", url: admin_root_path }
]
project_nav = []
if @project && !@project.new_record?
project_nav = [
- { :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) }
+ { 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
@@ -104,7 +92,7 @@ module ApplicationHelper
when :wall; wall_tab?
when :wiki; controller.controller_name == "wikis"
when :issues; issues_tab?
- when :network; current_page?(:controller => "projects", :action => "graph", :id => @project)
+ when :network; current_page?(controller: "projects", action: "graph", id: @project)
when :merge_requests; controller.controller_name == "merge_requests"
# Dashboard Area
@@ -115,17 +103,17 @@ module ApplicationHelper
when :root; current_page?(dashboard_path) || current_page?(root_path)
# Profile Area
- when :profile; current_page?(:controller => "profile", :action => :show)
- when :password; current_page?(:controller => "profile", :action => :password)
- when :token; current_page?(:controller => "profile", :action => :token)
- when :design; current_page?(:controller => "profile", :action => :design)
+ when :profile; current_page?(controller: "profile", action: :show)
+ when :password; current_page?(controller: "profile", action: :password)
+ when :token; current_page?(controller: "profile", action: :token)
+ when :design; current_page?(controller: "profile", action: :design)
when :ssh_keys; controller.controller_name == "keys"
# Admin Area
when :admin_root; controller.controller_name == "dashboard"
when :admin_users; controller.controller_name == 'users'
when :admin_projects; controller.controller_name == "projects"
- when :admin_emails; controller.controller_name == 'mailer'
+ when :admin_hooks; controller.controller_name == 'hooks'
when :admin_resque; controller.controller_name == 'resque'
when :admin_logs; controller.controller_name == 'logs'
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index fa87632d176..16ecfb1f89b 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -1,22 +1,4 @@
module CommitsHelper
- def commit_msg_with_link_to_issues(project, message)
- return '' unless message
- out = ''
- message.split(/(#[0-9]+)/m).each do |m|
- if m =~ /(#([0-9]+))/m
- begin
- issue = project.issues.find($2)
- out += link_to($1, project_issue_path(project, $2))
- rescue
- out += $1
- end
- else
- out += m
- end
- end
- preserve out
- end
-
def identification_type(line)
if line[0] == "+"
"new"
diff --git a/app/helpers/gitlab_markdown_helper.rb b/app/helpers/gitlab_markdown_helper.rb
new file mode 100644
index 00000000000..88e3473baf2
--- /dev/null
+++ b/app/helpers/gitlab_markdown_helper.rb
@@ -0,0 +1,70 @@
+module GitlabMarkdownHelper
+ # Replaces references (i.e. @abc, #123, !456, ...) in the text with links to
+ # the appropriate items in Gitlab.
+ #
+ # text - the source text
+ # html_options - extra options for the reference links as given to link_to
+ #
+ # note: reference links will only be generated if @project is set
+ #
+ # see Gitlab::Markdown for details on the supported syntax
+ def gfm(text, html_options = {})
+ return text if text.nil?
+ return text if @project.nil?
+
+ # Extract pre blocks so they are not altered
+ # from http://github.github.com/github-flavored-markdown/
+ extractions = {}
+ text.gsub!(%r{<pre>.*?</pre>|<code>.*?</code>}m) do |match|
+ md5 = Digest::MD5.hexdigest(match)
+ extractions[md5] = match
+ "{gfm-extraction-#{md5}}"
+ end
+
+ # TODO: add popups with additional information
+
+ parser = Gitlab::Markdown.new(@project, html_options)
+ text = parser.parse(text)
+
+ # Insert pre block extractions
+ text.gsub!(/\{gfm-extraction-(\h{32})\}/) do
+ extractions[$1]
+ end
+
+ text.html_safe
+ end
+
+ # Use this in places where you would normally use link_to(gfm(...), ...).
+ #
+ # It solves a problem occurring with nested links (i.e.
+ # "<a>outer text <a>gfm ref</a> more outer text</a>"). This will not be
+ # interpreted as intended. Browsers will parse something like
+ # "<a>outer text </a><a>gfm ref</a> more outer text" (notice the last part is
+ # not linked any more). link_to_gfm corrects that. It wraps all parts to
+ # explicitly produce the correct linking behavior (i.e.
+ # "<a>outer text </a><a>gfm ref</a><a> more outer text</a>").
+ def link_to_gfm(body, url, html_options = {})
+ gfm_body = gfm(body, html_options)
+
+ gfm_body.gsub!(%r{<a.*?>.*?</a>}m) do |match|
+ "</a>#{match}#{link_to("", url, html_options)[0..-5]}" # "</a>".length +1
+ end
+
+ link_to(gfm_body.html_safe, url, html_options)
+ end
+
+ def markdown(text)
+ @__renderer ||= Redcarpet::Markdown.new(Redcarpet::Render::GitlabHTML.new(self, filter_html: true, with_toc_data: true), {
+ no_intra_emphasis: true,
+ tables: true,
+ fenced_code_blocks: true,
+ autolink: true,
+ strikethrough: true,
+ lax_html_blocks: true,
+ space_after_headers: true,
+ superscript: true
+ })
+
+ @__renderer.render(text).html_safe
+ end
+end
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 0982aaccc2e..d4d6c2d4205 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -9,7 +9,7 @@ module IssuesHelper
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"
+ link_to issue.assignee_name, project_team_member_path(project, tm), class: "author_link"
else
issue.assignee_name
end
@@ -20,7 +20,7 @@ module IssuesHelper
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"
+ link_to issue.author_name, project_team_member_path(project, tm), class: "author_link"
else
issue.author_name
end
@@ -36,4 +36,11 @@ module IssuesHelper
def issue_tags
@project.issues.tag_counts_on(:labels).map(&:name)
end
+
+ # Returns an OpenStruct object suitable for use by <tt>options_from_collection_for_select</tt>
+ # to allow filtering issues by an unassigned User or Milestone
+ def unassigned_filter
+ # Milestone uses :title, Issue uses :name
+ OpenStruct.new(id: 0, title: 'Unspecified', name: 'Unassigned')
+ end
end
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index f9bfc8cdcf6..62ac5e55d43 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -4,7 +4,7 @@ module MergeRequestsHelper
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"
+ link_to merge_request.assignee_name, project_team_member_path(project, tm), class: "author_link"
else
merge_request.assignee_name
end
@@ -15,7 +15,7 @@ module MergeRequestsHelper
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"
+ link_to merge_request.author_name, project_team_member_path(project, tm), class: "author_link"
else
merge_request.author_name
end
@@ -24,10 +24,10 @@ module MergeRequestsHelper
def new_mr_path_from_push_event(event)
new_project_merge_request_path(
event.project,
- :merge_request => {
- :source_branch => event.branch_name,
- :target_branch => event.project.root_ref,
- :title => event.branch_name.titleize
+ merge_request: {
+ source_branch: event.branch_name,
+ target_branch: event.project.root_ref,
+ title: event.branch_name.titleize
}
)
end
diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb
index fa5ca166d6b..1740864bbb2 100644
--- a/app/helpers/tab_helper.rb
+++ b/app/helpers/tab_helper.rb
@@ -4,12 +4,12 @@ module TabHelper
end
def wall_tab?
- current_page?(:controller => "projects", :action => "wall", :id => @project)
+ current_page?(controller: "projects", action: "wall", id: @project)
end
def project_tab_class
[:show, :files, :team, :edit, :update].each do |action|
- return "current" if current_page?(:controller => "projects", :action => action, :id => @project)
+ return "current" if current_page?(controller: "projects", action: action, id: @project)
end
if ['snippets', 'hooks', 'deploy_keys', 'team_members'].include? controller.controller_name
diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb
index c673eb3d161..d0571b7b2c2 100644
--- a/app/mailers/notify.rb
+++ b/app/mailers/notify.rb
@@ -1,6 +1,7 @@
class Notify < ActionMailer::Base
include Resque::Mailer
add_template_helper ApplicationHelper
+ add_template_helper GitlabMarkdownHelper
default_url_options[:host] = Gitlab.config.web_host
default_url_options[:protocol] = Gitlab.config.web_protocol
@@ -11,57 +12,102 @@ class Notify < ActionMailer::Base
def new_user_email(user_id, password)
@user = User.find(user_id)
@password = password
- mail(:to => @user.email, :subject => "gitlab | Account was created for you")
+ mail(to: @user.email, subject: subject("Account was created for you"))
end
def new_issue_email(issue_id)
@issue = Issue.find(issue_id)
- mail(:to => @issue.assignee_email, :subject => "gitlab | New Issue was created")
+ @project = @issue.project
+ mail(to: @issue.assignee_email, subject: subject("new issue ##{@issue.id}", @issue.title))
end
def note_wall_email(recipient_id, note_id)
- recipient = User.find(recipient_id)
@note = Note.find(note_id)
- mail(:to => recipient.email, :subject => "gitlab | #{@note.project_name} ")
+ @project = @note.project
+ mail(to: recipient(recipient_id), subject: subject)
end
def note_commit_email(recipient_id, note_id)
- recipient = User.find(recipient_id)
@note = Note.find(note_id)
@commit = @note.target
- mail(:to => recipient.email, :subject => "gitlab | note for commit | #{@note.project_name} ")
+ @commit = CommitDecorator.decorate(@commit)
+ @project = @note.project
+ mail(to: recipient(recipient_id), subject: subject("note for commit #{@commit.short_id}", @commit.title))
end
def note_merge_request_email(recipient_id, note_id)
- recipient = User.find(recipient_id)
@note = Note.find(note_id)
@merge_request = @note.noteable
- mail(:to => recipient.email, :subject => "gitlab | note for merge request | #{@note.project_name} ")
+ @project = @note.project
+ mail(to: recipient(recipient_id), subject: subject("note for merge request !#{@merge_request.id}"))
end
def note_issue_email(recipient_id, note_id)
- recipient = User.find(recipient_id)
@note = Note.find(note_id)
@issue = @note.noteable
- mail(:to => recipient.email, :subject => "gitlab | note for issue #{@issue.id} | #{@note.project_name} ")
+ @project = @note.project
+ mail(to: recipient(recipient_id), subject: subject("note for issue ##{@issue.id}"))
+ end
+
+ def note_wiki_email(recipient_id, note_id)
+ @note = Note.find(note_id)
+ @wiki = @note.noteable
+ @project = @note.project
+ mail(to: recipient(recipient_id), subject: subject("note for wiki"))
end
def new_merge_request_email(merge_request_id)
@merge_request = MergeRequest.find(merge_request_id)
- mail(:to => @merge_request.assignee_email, :subject => "gitlab | new merge request | #{@merge_request.title} ")
+ @project = @merge_request.project
+ mail(to: @merge_request.assignee_email, subject: subject("new merge request !#{@merge_request.id}", @merge_request.title))
end
def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id)
- recipient = User.find(recipient_id)
@merge_request = MergeRequest.find(merge_request_id)
@previous_assignee ||= User.find(previous_assignee_id)
- mail(:to => recipient.email, :subject => "gitlab | merge request changed | #{@merge_request.title} ")
+ @project = @merge_request.project
+ mail(to: recipient(recipient_id), subject: subject("changed merge request !#{@merge_request.id}", @merge_request.title))
end
def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id)
- recipient = User.find(recipient_id)
@issue = Issue.find(issue_id)
@previous_assignee ||= User.find(previous_assignee_id)
- mail(:to => recipient.email, :subject => "gitlab | changed issue | #{@issue.title} ")
+ @project = @issue.project
+ mail(to: recipient(recipient_id), subject: subject("changed issue ##{@issue.id}", @issue.title))
+ end
+
+ private
+
+ # Look up a User by their ID and return their email address
+ #
+ # recipient_id - User ID
+ #
+ # Returns a String containing the User's email address.
+ def recipient(recipient_id)
+ if recipient = User.find(recipient_id)
+ recipient.email
+ end
+ end
+
+ # Formats arguments into a String suitable for use as an email subject
+ #
+ # extra - Extra Strings to be inserted into the subject
+ #
+ # Examples
+ #
+ # >> subject('Lorem ipsum')
+ # => "gitlab | Lorem ipsum"
+ #
+ # # Automatically inserts Project name when @project is set
+ # >> @project = Project.last
+ # => #<Project id: 1, name: "Ruby on Rails", path: "ruby_on_rails", ...>
+ # >> subject('Lorem ipsum')
+ # => "gitlab | Lorem ipsum | Ruby on Rails"
+ #
+ # # Accepts multiple arguments
+ # >> subject('Lorem ipsum', 'Dolor sit amet')
+ # => "gitlab | Lorem ipsum | Dolor sit amet"
+ def subject(*extra)
+ "gitlab | " << extra.join(' | ') << (@project ? " | #{@project.name}" : "")
end
end
diff --git a/app/models/commit.rb b/app/models/commit.rb
index 800ad19b9f1..5c6b4d88d96 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -20,7 +20,7 @@ class Commit
:tree,
:id,
:to_patch,
- :to => :commit
+ to: :commit
class << self
@@ -57,7 +57,7 @@ class Commit
def commits_since(repo, date)
commits = repo.heads.map do |h|
- repo.log(h.name, nil, :since => date).each { |c| Commit.new(c, h) }
+ repo.log(h.name, nil, since: date).each { |c| Commit.new(c, h) }
end.flatten.uniq { |c| c.id }
commits.sort! do |x, y|
@@ -69,7 +69,7 @@ class Commit
def commits(repo, ref, path = nil, limit = nil, offset = nil)
if path
- repo.log(ref, path, :max_count => limit, :skip => offset)
+ repo.log(ref, path, max_count: limit, skip: offset)
elsif limit && offset
repo.commits(ref, limit, offset)
else
@@ -80,6 +80,29 @@ class Commit
def commits_between(repo, from, to)
repo.commits_between(from, to).map { |c| Commit.new(c) }
end
+
+ def compare(project, from, to)
+ first = project.commit(to.try(:strip))
+ last = project.commit(from.try(:strip))
+
+ result = {
+ commits: [],
+ diffs: [],
+ commit: nil
+ }
+
+ if first && last
+ commits = [first, last].sort_by(&:created_at)
+ younger = commits.first
+ older = commits.last
+
+ result[:commits] = project.repo.commits_between(younger.id, older.id).map {|c| Commit.new(c)}
+ result[:diffs] = project.repo.diff(younger.id, older.id) rescue []
+ result[:commit] = Commit.new(older)
+ end
+
+ result
+ end
end
def persisted?
@@ -91,6 +114,10 @@ class Commit
@head = head
end
+ def short_id(length = 10)
+ id.to_s[0..length]
+ end
+
def safe_message
utf8 message
end
@@ -127,4 +154,8 @@ class Commit
def prev_commit_id
prev_commit.try :id
end
+
+ def parents_count
+ parents && parents.count || 0
+ end
end
diff --git a/app/models/event.rb b/app/models/event.rb
index dc7dfa16dd5..e20b79e2a82 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -12,13 +12,13 @@ class Event < ActiveRecord::Base
Merged = 7
belongs_to :project
- belongs_to :target, :polymorphic => true
+ belongs_to :target, polymorphic: true
# For Hash only
serialize :data
scope :recent, order("created_at DESC")
- scope :code_push, where(:action => Pushed)
+ scope :code_push, where(action: Pushed)
def self.determine_action(record)
if [Issue, MergeRequest].include? record.class
@@ -28,6 +28,10 @@ class Event < ActiveRecord::Base
end
end
+ def self.recent_for_user user
+ where(project_id: user.projects.map(&:id)).recent
+ end
+
# Next events currently enabled for system
# - push
# - new issue
@@ -102,9 +106,9 @@ class Event < ActiveRecord::Base
end
end
- delegate :name, :email, :to => :author, :prefix => true, :allow_nil => true
- delegate :title, :to => :issue, :prefix => true, :allow_nil => true
- delegate :title, :to => :merge_request, :prefix => true, :allow_nil => true
+ delegate :name, :email, to: :author, prefix: true, allow_nil: true
+ delegate :title, to: :issue, prefix: true, allow_nil: true
+ delegate :title, to: :merge_request, prefix: true, allow_nil: true
end
# == Schema Information
#
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 7f935900911..6409eebac63 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -1,60 +1,18 @@
class Issue < ActiveRecord::Base
+ include IssueCommonality
include Upvote
acts_as_taggable_on :labels
- belongs_to :project
belongs_to :milestone
- belongs_to :author, :class_name => "User"
- belongs_to :assignee, :class_name => "User"
- has_many :notes, :as => :noteable, :dependent => :destroy
-
- attr_protected :author, :author_id, :project, :project_id
- attr_accessor :author_id_of_changes
-
- validates_presence_of :project_id
- validates_presence_of :author_id
-
- delegate :name,
- :email,
- :to => :author,
- :prefix => true
-
- delegate :name,
- :email,
- :to => :assignee,
- :allow_nil => true,
- :prefix => true
-
- validates :title,
- :presence => true,
- :length => { :within => 0..255 }
validates :description,
- :length => { :within => 0..2000 }
-
- scope :opened, where(:closed => false)
- scope :closed, where(:closed => true)
- scope :assigned, lambda { |u| where(:assignee_id => u.id)}
-
- acts_as_list
+ length: { within: 0..2000 }
def self.open_for(user)
opened.assigned(user)
end
- def self.search query
- where("title like :query", :query => "%#{query}%")
- end
-
- def today?
- Date.today == created_at.to_date
- end
-
- def new?
- today? && created_at == updated_at
- end
-
def is_assigned?
!!assignee_id
end
diff --git a/app/models/key.rb b/app/models/key.rb
index 6b90b315d82..cfcb1f63c26 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -6,16 +6,16 @@ class Key < ActiveRecord::Base
belongs_to :project
validates :title,
- :presence => true,
- :length => { :within => 0..255 }
+ presence: true,
+ length: { within: 0..255 }
validates :key,
- :presence => true,
- :length => { :within => 0..5000 }
+ presence: true,
+ length: { within: 0..5000 }
before_save :set_identifier
before_validation :strip_white_space
- delegate :name, :email, :to => :user, :prefix => true
+ delegate :name, :email, to: :user, prefix: true
validate :unique_key
def strip_white_space
@@ -23,7 +23,7 @@ class Key < ActiveRecord::Base
end
def unique_key
- query = Key.where(:key => key)
+ query = Key.where(key: key)
query = query.where('(project_id IS NULL OR project_id = ?)', project_id) if project_id
if (query.count > 0)
errors.add :key, 'already exist.'
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 2581f3be4c9..542817b0eea 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -1,6 +1,7 @@
require File.join(Rails.root, "app/models/commit")
class MergeRequest < ActiveRecord::Base
+ include IssueCommonality
include Upvote
BROKEN_DIFF = "--broken-diff"
@@ -9,49 +10,17 @@ class MergeRequest < ActiveRecord::Base
CAN_BE_MERGED = 2
CANNOT_BE_MERGED = 3
- belongs_to :project
- belongs_to :author, :class_name => "User"
- belongs_to :assignee, :class_name => "User"
- has_many :notes, :as => :noteable, :dependent => :destroy
-
serialize :st_commits
serialize :st_diffs
- attr_protected :author, :author_id, :project, :project_id
- attr_accessor :author_id_of_changes,
- :should_remove_source_branch
+ attr_accessor :should_remove_source_branch
- validates_presence_of :project_id
- validates_presence_of :author_id
validates_presence_of :source_branch
validates_presence_of :target_branch
validate :validate_branches
- delegate :name,
- :email,
- :to => :author,
- :prefix => true
-
- delegate :name,
- :email,
- :to => :assignee,
- :allow_nil => true,
- :prefix => true
-
- validates :title,
- :presence => true,
- :length => { :within => 0..255 }
-
- scope :opened, where(:closed => false)
- scope :closed, where(:closed => true)
- scope :assigned, lambda { |u| where(:assignee_id => u.id)}
-
- def self.search query
- where("title like :query", :query => "%#{query}%")
- end
-
def self.find_all_by_branch(branch_name)
- where("source_branch like :branch or target_branch like :branch", :branch => branch_name)
+ where("source_branch like :branch or target_branch like :branch", branch: branch_name)
end
def human_state
@@ -79,7 +48,7 @@ class MergeRequest < ActiveRecord::Base
end
def mark_as_unchecked
- self.update_attributes(:state => UNCHECKED)
+ self.update_attributes(state: UNCHECKED)
end
def can_be_merged?
@@ -95,14 +64,6 @@ class MergeRequest < ActiveRecord::Base
self.save
end
- def today?
- Date.today == created_at.to_date
- end
-
- def new?
- today? && created_at == updated_at
- end
-
def diffs
st_diffs || []
end
@@ -127,24 +88,27 @@ class MergeRequest < ActiveRecord::Base
end
def unmerged_diffs
- commits = project.repo.commits_between(target_branch, source_branch).map {|c| Commit.new(c)}
- diffs = project.repo.diff(commits.first.prev_commit.id, commits.last.id) rescue []
+ # Only show what is new in the source branch compared to the target branch, not the other way around.
+ # The linex below with merge_base is equivalent to diff with three dots (git diff branch1...branch2)
+ # From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B"
+ common_commit = project.repo.git.native(:merge_base, {}, [target_branch, source_branch]).strip
+ diffs = project.repo.diff(common_commit, source_branch)
end
def last_commit
commits.first
end
- def merged?
+ def merged?
merged && merge_event
end
def merge_event
- self.project.events.where(:target_id => self.id, :target_type => "MergeRequest", :action => Event::Merged).last
+ self.project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::Merged).last
end
def closed_event
- self.project.events.where(:target_id => self.id, :target_type => "MergeRequest", :action => Event::Closed).last
+ self.project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::Closed).last
end
def commits
@@ -152,7 +116,7 @@ class MergeRequest < ActiveRecord::Base
end
def probably_merged?
- unmerged_commits.empty? &&
+ unmerged_commits.empty? &&
commits.any? && open?
end
@@ -167,11 +131,11 @@ class MergeRequest < ActiveRecord::Base
end
def mark_as_unmergable
- self.update_attributes :state => CANNOT_BE_MERGED
+ self.update_attributes state: CANNOT_BE_MERGED
end
- def reloaded_commits
- if open? && unmerged_commits.any?
+ def reloaded_commits
+ if open? && unmerged_commits.any?
self.st_commits = unmerged_commits
save
end
@@ -189,11 +153,11 @@ class MergeRequest < ActiveRecord::Base
def merge!(user_id)
self.mark_as_merged!
Event.create(
- :project => self.project,
- :action => Event::Merged,
- :target_id => self.id,
- :target_type => "MergeRequest",
- :author_id => user_id
+ project: self.project,
+ action: Event::Merged,
+ target_id: self.id,
+ target_type: "MergeRequest",
+ author_id: user_id
)
end
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index 7fdfe29edc8..d416fb630c5 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -24,21 +24,13 @@ class Milestone < ActiveRecord::Base
end
def participants
- User.where(:id => issues.map(&:assignee_id))
+ User.where(id: issues.map(&:assignee_id))
end
def percent_complete
- @percent_complete ||= begin
- total_i = self.issues.count
- closed_i = self.issues.closed.count
- if total_i > 0
- (closed_i * 100) / total_i
- else
- 100
- end
- rescue => ex
- 0
- end
+ ((self.issues.closed.count * 100) / self.issues.count).abs
+ rescue ZeroDivisionError
+ 100
end
def expires_at
diff --git a/app/models/note.rb b/app/models/note.rb
index 8a26cd05b44..711a4ee6935 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -3,18 +3,18 @@ require 'file_size_validator'
class Note < ActiveRecord::Base
belongs_to :project
- belongs_to :noteable, :polymorphic => true
+ belongs_to :noteable, polymorphic: true
belongs_to :author,
- :class_name => "User"
+ class_name: "User"
delegate :name,
- :to => :project,
- :prefix => true
+ to: :project,
+ prefix: true
delegate :name,
:email,
- :to => :author,
- :prefix => true
+ to: :author,
+ prefix: true
attr_protected :author, :author_id
attr_accessor :notify
@@ -23,19 +23,19 @@ class Note < ActiveRecord::Base
validates_presence_of :project
validates :note,
- :presence => true,
- :length => { :within => 0..5000 }
+ presence: true,
+ length: { within: 0..5000 }
validates :attachment,
- :file_size => {
- :maximum => 10.megabytes.to_i
+ file_size: {
+ maximum: 10.megabytes.to_i
}
- scope :common, where(:noteable_id => nil)
+ scope :common, where(noteable_id: nil)
- scope :today, where("created_at >= :date", :date => Date.today)
- scope :last_week, where("created_at >= :date", :date => (Date.today - 7.days))
- scope :since, lambda { |day| where("created_at >= :date", :date => (day)) }
+ scope :today, where("created_at >= :date", date: Date.today)
+ scope :last_week, where("created_at >= :date", date: (Date.today - 7.days))
+ scope :since, lambda { |day| where("created_at >= :date", date: (day)) }
scope :fresh, order("created_at DESC")
scope :inc_author_project, includes(:project, :author)
scope :inc_author, includes(:author)
@@ -43,11 +43,11 @@ class Note < ActiveRecord::Base
mount_uploader :attachment, AttachmentUploader
def self.create_status_change_note(noteable, author, status)
- create({ :noteable => noteable,
- :project => noteable.project,
- :author => author,
- :note => "_Status changed to #{status}_" },
- :without_protection => true)
+ create({ noteable: noteable,
+ project: noteable.project,
+ author: author,
+ note: "_Status changed to #{status}_" },
+ without_protection: true)
end
def notify
diff --git a/app/models/project.rb b/app/models/project.rb
index ec4893e2b17..3fe11916504 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -2,26 +2,26 @@ require "grit"
class Project < ActiveRecord::Base
include Repository
- include GitPush
+ include PushObserver
include Authority
include Team
#
# Relations
#
- belongs_to :owner, :class_name => "User"
- has_many :users, :through => :users_projects
- has_many :events, :dependent => :destroy
- has_many :merge_requests, :dependent => :destroy
- has_many :issues, :dependent => :destroy, :order => "closed, created_at DESC"
- has_many :milestones, :dependent => :destroy
- has_many :users_projects, :dependent => :destroy
- has_many :notes, :dependent => :destroy
- 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 :wikis, :dependent => :destroy
- has_many :protected_branches, :dependent => :destroy
+ belongs_to :owner, class_name: "User"
+ has_many :users, through: :users_projects
+ has_many :events, dependent: :destroy
+ has_many :merge_requests, dependent: :destroy
+ has_many :issues, dependent: :destroy, order: "closed, created_at DESC"
+ has_many :milestones, dependent: :destroy
+ has_many :users_projects, dependent: :destroy
+ has_many :notes, dependent: :destroy
+ has_many :snippets, dependent: :destroy
+ has_many :deploy_keys, dependent: :destroy, foreign_key: "project_id", class_name: "Key"
+ has_many :hooks, dependent: :destroy, class_name: "ProjectHook"
+ has_many :wikis, dependent: :destroy
+ has_many :protected_branches, dependent: :destroy
attr_accessor :error_code
@@ -33,15 +33,15 @@ class Project < ActiveRecord::Base
#
# Scopes
#
- scope :public_only, where(:private_flag => false)
- scope :without_user, lambda { |user| where("id not in (:ids)", :ids => user.projects.map(&: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.search query
- where("name like :query or code like :query or path like :query", :query => "%#{query}%")
+ where("name like :query or code like :query or path like :query", query: "%#{query}%")
end
def self.create_by_user(params, user)
@@ -53,7 +53,7 @@ class Project < ActiveRecord::Base
project.save!
# Add user as project master
- project.users_projects.create!(:project_access => UsersProject::MASTER, :user => user)
+ project.users_projects.create!(project_access: UsersProject::MASTER, user: user)
# when project saved no team member exist so
# project repository should be updated after first user add
@@ -66,7 +66,7 @@ class Project < ActiveRecord::Base
project
rescue => ex
project.error_code = :db
- project.errors.add(:base, "Cant save project. Please try again later")
+ project.errors.add(:base, "Can't save project. Please try again later")
project
end
@@ -82,28 +82,28 @@ class Project < ActiveRecord::Base
# Validations
#
validates :name,
- :uniqueness => true,
- :presence => true,
- :length => { :within => 0..255 }
+ uniqueness: true,
+ presence: true,
+ length: { within: 0..255 }
validates :path,
- :uniqueness => true,
- :presence => true,
- :format => { :with => /^[a-zA-Z][a-zA-Z0-9_\-\.]*$/,
- :message => "only letters, digits & '_' '-' '.' allowed. Letter should be first" },
- :length => { :within => 0..255 }
+ uniqueness: true,
+ presence: true,
+ format: { with: /^[a-zA-Z][a-zA-Z0-9_\-\.]*$/,
+ message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" },
+ length: { within: 0..255 }
validates :description,
- :length => { :within => 0..2000 }
+ length: { within: 0..2000 }
validates :code,
- :presence => true,
- :uniqueness => true,
- :format => { :with => /^[a-zA-Z][a-zA-Z0-9_\-\.]*$/,
- :message => "only letters, digits & '_' '-' '.' allowed. Letter should be first" },
- :length => { :within => 1..255 }
+ presence: true,
+ uniqueness: true,
+ format: { with: /^[a-zA-Z][a-zA-Z0-9_\-\.]*$/,
+ message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" },
+ length: { within: 1..255 }
- validates :owner, :presence => true
+ validates :owner, presence: true
validate :check_limit
validate :repo_name
@@ -112,7 +112,7 @@ class Project < ActiveRecord::Base
errors[:base] << ("Your own projects limit is #{owner.projects_limit}! Please contact administrator to increase it")
end
rescue
- errors[:base] << ("Cant check your ability to create project")
+ errors[:base] << ("Can't check your ability to create project")
end
def repo_name
@@ -120,7 +120,7 @@ class Project < ActiveRecord::Base
errors.add(:path, " like 'gitolite-admin' is not allowed")
end
end
-
+
def self.access_options
UsersProject.access_roles
end
@@ -134,19 +134,19 @@ class Project < ActiveRecord::Base
end
def common_notes
- notes.where(:noteable_type => ["", nil]).inc_author_project
+ notes.where(noteable_type: ["", nil]).inc_author_project
end
def build_commit_note(commit)
- notes.new(:noteable_id => commit.id, :noteable_type => "Commit")
+ notes.new(noteable_id: commit.id, noteable_type: "Commit")
end
def commit_notes(commit)
- notes.where(:noteable_id => commit.id, :noteable_type => "Commit", :line_code => nil)
+ notes.where(noteable_id: commit.id, noteable_type: "Commit", line_code: nil)
end
def commit_line_notes(commit)
- notes.where(:noteable_id => commit.id, :noteable_type => "Commit").where("line_code is not null")
+ notes.where(noteable_id: commit.id, noteable_type: "Commit").where("line_code is not null")
end
def public?
diff --git a/app/models/project_hook.rb b/app/models/project_hook.rb
new file mode 100644
index 00000000000..06388aaeb4c
--- /dev/null
+++ b/app/models/project_hook.rb
@@ -0,0 +1,3 @@
+class ProjectHook < WebHook
+ belongs_to :project
+end
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index e5f04bb228b..2c941499f1f 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -2,29 +2,29 @@ class Snippet < ActiveRecord::Base
include Linguist::BlobHelper
belongs_to :project
- belongs_to :author, :class_name => "User"
- has_many :notes, :as => :noteable, :dependent => :destroy
+ belongs_to :author, class_name: "User"
+ has_many :notes, as: :noteable, dependent: :destroy
delegate :name,
:email,
- :to => :author,
- :prefix => true
+ to: :author,
+ prefix: true
attr_protected :author, :author_id, :project, :project_id
validates_presence_of :project_id
validates_presence_of :author_id
validates :title,
- :presence => true,
- :length => { :within => 0..255 }
+ presence: true,
+ length: { within: 0..255 }
validates :file_name,
- :presence => true,
- :length => { :within => 0..255 }
+ presence: true,
+ length: { within: 0..255 }
validates :content,
- :presence => true,
- :length => { :within => 0..10000 }
+ presence: true,
+ length: { within: 0..10000 }
scope :fresh, order("created_at DESC")
scope :non_expired, where(["expires_at IS NULL OR expires_at > ?", Time.current])
diff --git a/app/models/system_hook.rb b/app/models/system_hook.rb
new file mode 100644
index 00000000000..8517d43a9de
--- /dev/null
+++ b/app/models/system_hook.rb
@@ -0,0 +1,13 @@
+class SystemHook < WebHook
+
+ def async_execute(data)
+ Resque.enqueue(SystemHookWorker, id, data)
+ end
+
+ def self.all_hooks_fire(data)
+ SystemHook.all.each do |sh|
+ sh.async_execute data
+ end
+ end
+
+end
diff --git a/app/models/tree.rb b/app/models/tree.rb
index 9d60f83015f..bc95d335520 100644
--- a/app/models/tree.rb
+++ b/app/models/tree.rb
@@ -11,7 +11,7 @@ class Tree
:size,
:text?,
:colorize,
- :to => :tree
+ to: :tree
def initialize(raw_tree, project, ref = nil, path = nil)
@project, @ref, @path = project, ref, path,
diff --git a/app/models/user.rb b/app/models/user.rb
index 0836ca4919f..ad6af6a6dd0 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,4 +1,5 @@
class User < ActiveRecord::Base
+
include Account
devise :database_authenticatable, :token_authenticatable, :lockable,
@@ -6,62 +7,64 @@ class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation, :remember_me, :bio,
:name, :projects_limit, :skype, :linkedin, :twitter, :dark_scheme,
- :theme_id, :force_random_password
+ :theme_id, :force_random_password, :extern_uid, :provider
attr_accessor :force_random_password
- has_many :users_projects, :dependent => :destroy
- has_many :projects, :through => :users_projects
- has_many :my_own_projects, :class_name => "Project", :foreign_key => :owner_id
- has_many :keys, :dependent => :destroy
+ has_many :users_projects, dependent: :destroy
+ has_many :projects, through: :users_projects
+ has_many :my_own_projects, class_name: "Project", foreign_key: :owner_id
+ has_many :keys, dependent: :destroy
has_many :events,
- :class_name => "Event",
- :foreign_key => :author_id,
- :dependent => :destroy
+ class_name: "Event",
+ foreign_key: :author_id,
+ dependent: :destroy
has_many :recent_events,
- :class_name => "Event",
- :foreign_key => :author_id,
- :order => "id DESC"
+ class_name: "Event",
+ foreign_key: :author_id,
+ order: "id DESC"
has_many :issues,
- :foreign_key => :author_id,
- :dependent => :destroy
+ foreign_key: :author_id,
+ dependent: :destroy
has_many :notes,
- :foreign_key => :author_id,
- :dependent => :destroy
+ foreign_key: :author_id,
+ dependent: :destroy
has_many :assigned_issues,
- :class_name => "Issue",
- :foreign_key => :assignee_id,
- :dependent => :destroy
+ class_name: "Issue",
+ foreign_key: :assignee_id,
+ dependent: :destroy
has_many :merge_requests,
- :foreign_key => :author_id,
- :dependent => :destroy
+ foreign_key: :author_id,
+ dependent: :destroy
has_many :assigned_merge_requests,
- :class_name => "MergeRequest",
- :foreign_key => :assignee_id,
- :dependent => :destroy
+ class_name: "MergeRequest",
+ foreign_key: :assignee_id,
+ dependent: :destroy
validates :projects_limit,
- :presence => true,
- :numericality => {:greater_than_or_equal_to => 0}
+ presence: true,
+ numericality: {greater_than_or_equal_to: 0}
+
+ validates :bio, length: { within: 0..255 }
- validates :bio, :length => { :within => 0..255 }
+ validates :extern_uid, :allow_blank => true, :uniqueness => {:scope => :provider}
before_save :ensure_authentication_token
alias_attribute :private_token, :authentication_token
- scope :not_in_project, lambda { |project| where("id not in (:ids)", :ids => project.users.map(&:id) ) }
- scope :admins, where(:admin => true)
- scope :blocked, where(:blocked => true)
- scope :active, where(:blocked => false)
+ scope :not_in_project, lambda { |project| where("id not in (:ids)", ids: project.users.map(&:id) ) }
+ scope :admins, where(admin: true)
+ scope :blocked, where(blocked: true)
+ scope :active, where(blocked: false)
- before_validation :generate_password, :on => :create
+ before_validation :generate_password, on: :create
def generate_password
if self.force_random_password
@@ -83,16 +86,26 @@ class User < ActiveRecord::Base
where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)')
end
- def self.find_for_ldap_auth(omniauth_info)
- name = omniauth_info.name.force_encoding("utf-8")
- email = omniauth_info.email.downcase unless omniauth_info.email.nil?
- raise OmniAuth::Error, "LDAP accounts must provide an email address" if email.nil?
+ def self.find_for_ldap_auth(auth, signed_in_resource=nil)
+ uid = auth.info.uid
+ provider = auth.provider
+ name = auth.info.name.force_encoding("utf-8")
+ email = auth.info.email.downcase unless auth.info.email.nil?
+ raise OmniAuth::Error, "LDAP accounts must provide an uid and email address" if uid.nil? or email.nil?
- if @user = User.find_by_email(email)
+ if @user = User.find_by_extern_uid_and_provider(uid, provider)
+ @user
+ # workaround for backward compatibility
+ elsif @user = User.find_by_email(email)
+ logger.info "Updating legacy LDAP user #{email} with extern_uid => #{uid}"
+ @user.update_attributes(:extern_uid => uid, :provider => provider)
@user
else
+ logger.info "Creating user from LDAP login {uid => #{uid}, name => #{name}, email => #{email}}"
password = Devise.friendly_token[0, 8].downcase
@user = User.create(
+ :extern_uid => uid,
+ :provider => provider,
:name => name,
:email => email,
:password => password,
@@ -103,7 +116,7 @@ class User < ActiveRecord::Base
end
def self.search query
- where("name like :query or email like :query", :query => "%#{query}%")
+ where("name like :query or email like :query", query: "%#{query}%")
end
end
# == Schema Information
diff --git a/app/models/users_project.rb b/app/models/users_project.rb
index 6ba72370931..36e6d9045b6 100644
--- a/app/models/users_project.rb
+++ b/app/models/users_project.rb
@@ -12,18 +12,18 @@ class UsersProject < ActiveRecord::Base
after_save :update_repository
after_destroy :update_repository
- validates_uniqueness_of :user_id, :scope => [:project_id]
+ validates_uniqueness_of :user_id, scope: [:project_id]
validates_presence_of :user_id
validates_presence_of :project_id
- delegate :name, :email, :to => :user, :prefix => true
+ delegate :name, :email, to: :user, prefix: true
def self.bulk_import(project, user_ids, project_access)
UsersProject.transaction do
user_ids.each do |user_id|
users_project = UsersProject.new(
- :project_access => project_access,
- :user_id => user_id
+ project_access: project_access,
+ user_id: user_id
)
users_project.project = project
users_project.save
@@ -35,7 +35,7 @@ class UsersProject < ActiveRecord::Base
UsersProject.transaction do
project_ids.each do |project_id|
users_project = UsersProject.new(
- :project_access => project_access,
+ project_access: project_access,
)
users_project.project_id = project_id
users_project.user_id = user.id
@@ -68,7 +68,7 @@ class UsersProject < ActiveRecord::Base
end
def repo_access_human
- ""
+ self.class.access_roles.invert[self.project_access]
end
end
# == Schema Information
diff --git a/app/models/web_hook.rb b/app/models/web_hook.rb
index 26288476a6c..76efa50198b 100644
--- a/app/models/web_hook.rb
+++ b/app/models/web_hook.rb
@@ -4,8 +4,6 @@ class WebHook < ActiveRecord::Base
# HTTParty timeout
default_timeout 10
- belongs_to :project
-
validates :url,
presence: true,
format: {
@@ -13,10 +11,18 @@ class WebHook < ActiveRecord::Base
message: "should be a valid url" }
def execute(data)
- WebHook.post(url, body: data.to_json, headers: { "Content-Type" => "application/json" })
- rescue
- # There was a problem calling this web hook, let's forget about it.
+ parsed_url = URI.parse(url)
+ if parsed_url.userinfo.blank?
+ WebHook.post(url, body: data.to_json, headers: { "Content-Type" => "application/json" })
+ else
+ post_url = url.gsub(parsed_url.userinfo+"@", "")
+ WebHook.post(post_url,
+ body: data.to_json,
+ headers: { "Content-Type" => "application/json" },
+ basic_auth: {username: parsed_url.user, password: parsed_url.password})
+ end
end
+
end
# == Schema Information
#
diff --git a/app/models/wiki.rb b/app/models/wiki.rb
index ecc46fb4efb..3c4952cd291 100644
--- a/app/models/wiki.rb
+++ b/app/models/wiki.rb
@@ -1,9 +1,10 @@
class Wiki < ActiveRecord::Base
belongs_to :project
belongs_to :user
+ has_many :notes, as: :noteable, dependent: :destroy
- validates :content, :title, :user_id, :presence => true
- validates :title, :length => 1..250
+ validates :content, :title, :user_id, presence: true
+ validates :title, length: 1..250
before_update :set_slug
diff --git a/app/observers/activity_observer.rb b/app/observers/activity_observer.rb
index 324d8207d22..48351bac667 100644
--- a/app/observers/activity_observer.rb
+++ b/app/observers/activity_observer.rb
@@ -3,22 +3,22 @@ class ActivityObserver < ActiveRecord::Observer
def after_create(record)
Event.create(
- :project => record.project,
- :target_id => record.id,
- :target_type => record.class.name,
- :action => Event.determine_action(record),
- :author_id => record.author_id
+ project: record.project,
+ target_id: record.id,
+ target_type: record.class.name,
+ action: Event.determine_action(record),
+ author_id: record.author_id
)
end
def after_save(record)
if record.changed.include?("closed")
Event.create(
- :project => record.project,
- :target_id => record.id,
- :target_type => record.class.name,
- :action => (record.closed ? Event::Closed : Event::Reopened),
- :author_id => record.author_id_of_changes
+ project: record.project,
+ target_id: record.id,
+ target_type: record.class.name,
+ action: (record.closed ? Event::Closed : Event::Reopened),
+ author_id: record.author_id_of_changes
)
end
end
diff --git a/app/observers/mailer_observer.rb b/app/observers/mailer_observer.rb
index 451deccd14f..331aaa35e3d 100644
--- a/app/observers/mailer_observer.rb
+++ b/app/observers/mailer_observer.rb
@@ -34,6 +34,7 @@ class MailerObserver < ActiveRecord::Observer
case note.noteable_type
when "Commit"; Notify.note_commit_email(u.id, note.id).deliver
when "Issue"; Notify.note_issue_email(u.id, note.id).deliver
+ when "Wiki"; Notify.note_wiki_email(u.id, note.id).deliver
when "MergeRequest"; Notify.note_merge_request_email(u.id, note.id).deliver
when "Snippet"; true
else
@@ -70,7 +71,7 @@ class MailerObserver < ActiveRecord::Observer
# Create comment about status changed
if target.closed_changed?
- note = Note.new(:noteable => target, :project => target.project)
+ note = Note.new(noteable: target, project: target.project)
note.author = current_user
note.note = "_Status changed to #{target.closed ? 'closed' : 'reopened'}_"
note.save()
diff --git a/app/observers/system_hook_observer.rb b/app/observers/system_hook_observer.rb
new file mode 100644
index 00000000000..312cd2b3622
--- /dev/null
+++ b/app/observers/system_hook_observer.rb
@@ -0,0 +1,67 @@
+class SystemHookObserver < ActiveRecord::Observer
+ observe :user, :project, :users_project
+
+ def after_create(model)
+ if model.kind_of? Project
+ SystemHook.all_hooks_fire({
+ event_name: "project_create",
+ name: model.name,
+ path: model.path,
+ project_id: model.id,
+ owner_name: model.owner.name,
+ owner_email: model.owner.email,
+ created_at: model.created_at
+ })
+ elsif model.kind_of? User
+ SystemHook.all_hooks_fire({
+ event_name: "user_create",
+ name: model.name,
+ email: model.email,
+ created_at: model.created_at
+ })
+
+ elsif model.kind_of? UsersProject
+ SystemHook.all_hooks_fire({
+ event_name: "user_add_to_team",
+ project_name: model.project.name,
+ project_path: model.project.path,
+ project_id: model.project_id,
+ user_name: model.user.name,
+ user_email: model.user.email,
+ project_access: model.repo_access_human,
+ created_at: model.created_at
+ })
+
+ end
+ end
+
+ def after_destroy(model)
+ if model.kind_of? Project
+ SystemHook.all_hooks_fire({
+ event_name: "project_destroy",
+ name: model.name,
+ path: model.path,
+ project_id: model.id,
+ owner_name: model.owner.name,
+ owner_email: model.owner.email,
+ })
+ elsif model.kind_of? User
+ SystemHook.all_hooks_fire({
+ event_name: "user_destroy",
+ name: model.name,
+ email: model.email
+ })
+
+ elsif model.kind_of? UsersProject
+ SystemHook.all_hooks_fire({
+ event_name: "user_remove_from_team",
+ project_name: model.project.name,
+ project_path: model.project.path,
+ project_id: model.project_id,
+ user_name: model.user.name,
+ user_email: model.user.email,
+ project_access: model.repo_access_human
+ })
+ end
+ end
+end
diff --git a/app/roles/account.rb b/app/roles/account.rb
index afa1f8a347d..63a9b5c51bf 100644
--- a/app/roles/account.rb
+++ b/app/roles/account.rb
@@ -1,6 +1,6 @@
module Account
def identifier
- email.gsub /[@.]/, "_"
+ email.gsub /[^[:alnum:]]/, "_"
end
def is_admin?
@@ -24,7 +24,7 @@ module Account
end
def cared_merge_requests
- MergeRequest.where("author_id = :id or assignee_id = :id", :id => self.id).opened
+ MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id).opened
end
def project_ids
@@ -50,9 +50,13 @@ module Account
def recent_push project_id = nil
# Get push events not earlier than 2 hours ago
events = recent_events.code_push.where("created_at > ?", Time.now - 2.hours)
- events = events.where(:project_id => project_id) if project_id
+ events = events.where(project_id: project_id) if project_id
# Take only latest one
events = events.recent.limit(1).first
end
+
+ def projects_with_events
+ projects.includes(:events).order("events.created_at DESC")
+ end
end
diff --git a/app/roles/authority.rb b/app/roles/authority.rb
index a03b54a3ee7..9d9153db66e 100644
--- a/app/roles/authority.rb
+++ b/app/roles/authority.rb
@@ -3,56 +3,56 @@ module Authority
# Should be rewrited for new access rights
def add_access(user, *access)
access = if access.include?(:admin)
- { :project_access => UsersProject::MASTER }
+ { project_access: UsersProject::MASTER }
elsif access.include?(:write)
- { :project_access => UsersProject::DEVELOPER }
+ { project_access: UsersProject::DEVELOPER }
else
- { :project_access => UsersProject::REPORTER }
+ { project_access: UsersProject::REPORTER }
end
- opts = { :user => user }
+ opts = { user: user }
opts.merge!(access)
users_projects.create(opts)
end
def reset_access(user)
- users_projects.where(:project_id => self.id, :user_id => user.id).destroy if self.id
+ users_projects.where(project_id: self.id, user_id: user.id).destroy if self.id
end
def repository_readers
- keys = Key.joins({:user => :users_projects}).
+ keys = Key.joins({user: :users_projects}).
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}).
+ keys = Key.joins({user: :users_projects}).
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}).
+ keys = Key.joins({user: :users_projects}).
where("users_projects.project_id = ? AND users_projects.project_access = ?", id, UsersProject::MASTER)
keys.map(&:identifier)
end
def allow_read_for?(user)
- !users_projects.where(:user_id => user.id).empty?
+ !users_projects.where(user_id: user.id).empty?
end
def guest_access_for?(user)
- !users_projects.where(:user_id => user.id).empty?
+ !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?
+ !users_projects.where(user_id: user.id, project_access: [UsersProject::REPORTER, UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
end
def dev_access_for?(user)
- !users_projects.where(:user_id => user.id, :project_access => [UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
+ !users_projects.where(user_id: user.id, project_access: [UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
end
def master_access_for?(user)
- !users_projects.where(:user_id => user.id, :project_access => [UsersProject::MASTER]).empty? || owner_id == user.id
+ !users_projects.where(user_id: user.id, project_access: [UsersProject::MASTER]).empty? || owner_id == user.id
end
end
diff --git a/app/roles/issue_commonality.rb b/app/roles/issue_commonality.rb
new file mode 100644
index 00000000000..a8fd679df81
--- /dev/null
+++ b/app/roles/issue_commonality.rb
@@ -0,0 +1,52 @@
+# Contains common functionality shared between Issues and MergeRequests
+module IssueCommonality
+ extend ActiveSupport::Concern
+
+ included do
+ attr_protected :author, :author_id, :project, :project_id
+
+ belongs_to :project
+ belongs_to :author, class_name: "User"
+ belongs_to :assignee, class_name: "User"
+ has_many :notes, as: :noteable, dependent: :destroy
+
+ validates_presence_of :project_id
+ validates_presence_of :author_id
+
+ validates :title,
+ presence: true,
+ length: { within: 0..255 }
+
+
+ scope :opened, where(closed: false)
+ scope :closed, where(closed: true)
+ scope :assigned, lambda { |u| where(assignee_id: u.id)}
+
+ delegate :name,
+ :email,
+ to: :author,
+ prefix: true
+
+ delegate :name,
+ :email,
+ to: :assignee,
+ allow_nil: true,
+ prefix: true
+
+ attr_accessor :author_id_of_changes
+ end
+
+ module ClassMethods
+ def search(query)
+ where("title like :query", query: "%#{query}%")
+ end
+ end
+
+ def today?
+ Date.today == created_at.to_date
+ end
+
+ def new?
+ today? && created_at == updated_at
+ end
+end
diff --git a/app/roles/git_push.rb b/app/roles/push_observer.rb
index b4c59472a5a..1067404d5af 100644
--- a/app/roles/git_push.rb
+++ b/app/roles/push_observer.rb
@@ -1,12 +1,12 @@
-module GitPush
+module PushObserver
def observe_push(oldrev, newrev, ref, user)
data = post_receive_data(oldrev, newrev, ref, user)
Event.create(
- :project => self,
- :action => Event::Pushed,
- :data => data,
- :author_id => data[:user_id]
+ project: self,
+ action: Event::Pushed,
+ data: data,
+ author_id: data[:user_id]
)
end
@@ -20,14 +20,14 @@ module GitPush
mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }
# Close merge requests
- mrs = self.merge_requests.opened.where(:target_branch => branch_name).all
+ mrs = self.merge_requests.opened.where(target_branch: branch_name).all
mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
mrs.each { |merge_request| merge_request.merge!(user.id) }
true
end
- def execute_web_hooks(oldrev, newrev, ref, user)
+ def execute_hooks(oldrev, newrev, ref, user)
ref_parts = ref.split('/')
# Return if this is not a push to a branch (e.g. new commits)
@@ -35,7 +35,7 @@ module GitPush
data = post_receive_data(oldrev, newrev, ref, user)
- web_hooks.each { |web_hook| web_hook.execute(data) }
+ hooks.each { |hook| hook.execute(data) }
end
def post_receive_data(oldrev, newrev, ref, user)
@@ -97,7 +97,7 @@ module GitPush
self.update_merge_requests(oldrev, newrev, ref, user)
# Execute web hooks
- self.execute_web_hooks(oldrev, newrev, ref, user)
+ self.execute_hooks(oldrev, newrev, ref, user)
# Create satellite
self.satellite.create unless self.satellite.exists?
diff --git a/app/roles/repository.rb b/app/roles/repository.rb
index 8d5b018de77..7f1d6f84549 100644
--- a/app/roles/repository.rb
+++ b/app/roles/repository.rb
@@ -30,26 +30,10 @@ module Repository
Commit.commits_between(repo, from, to)
end
- def write_hooks
- %w(post-receive).each do |hook|
- write_hook(hook, File.read(File.join(Rails.root, 'lib', "#{hook}-hook")))
- end
- end
-
def satellite
@satellite ||= Gitlab::Satellite.new(self)
end
- def write_hook(name, content)
- hook_file = File.join(path_to_repo, 'hooks', name)
-
- File.open(hook_file, 'w') do |f|
- f.write(content)
- end
-
- File.chmod(0775, hook_file)
- end
-
def has_post_receive_file?
hook_file = File.join(path_to_repo, 'hooks', 'post-receive')
File.exists?(hook_file)
@@ -73,8 +57,6 @@ module Repository
def update_repository
Gitlab::GitHost.system.update_project(path, self)
-
- write_hooks if File.exists?(path_to_repo)
end
def destroy_repository
diff --git a/app/roles/ssh_key.rb b/app/roles/ssh_key.rb
index f1143c5d065..5e1d2c23d15 100644
--- a/app/roles/ssh_key.rb
+++ b/app/roles/ssh_key.rb
@@ -9,7 +9,7 @@ module SshKey
def repository_delete_key
Gitlab::GitHost.system.new.configure do |c|
#delete key file is there is no identically deploy keys
- if !is_deploy_key || Key.where(:identifier => identifier).count() == 0
+ if !is_deploy_key || Key.where(identifier: identifier).count() == 0
c.delete_key(identifier)
end
c.update_projects(projects)
diff --git a/app/roles/team.rb b/app/roles/team.rb
index 2a477b6edba..27b1cc65897 100644
--- a/app/roles/team.rb
+++ b/app/roles/team.rb
@@ -4,7 +4,36 @@ module Team
users_projects.find_by_user_id(user.id) if user
end
+ # Get Team Member record by user id
def team_member_by_id(user_id)
users_projects.find_by_user_id(user_id)
end
+
+ # Add user to project
+ # with passed access role
+ def add_user_to_team(user, access_role)
+ add_user_id_to_team(user.id, access_role)
+ end
+
+ # Add multiple users to project
+ # with same access role
+ def add_users_to_team(users, access_role)
+ add_users_ids_to_team(users.map(&:id), access_role)
+ end
+
+ # Add user to project
+ # with passed access role by user id
+ def add_user_id_to_team(user_id, access_role)
+ users_projects.create(
+ user_id: user_id,
+ project_access: access_role
+ )
+ end
+
+ # Add multiple users to project
+ # with same access role by user ids
+ def add_users_ids_to_team(users_ids, access_role)
+ UsersProject.bulk_import(self, users_ids, access_role)
+ self.update_repository
+ end
end
diff --git a/app/uploaders/attachment_uploader.rb b/app/uploaders/attachment_uploader.rb
index 4ba19ace8d1..bb7dc0dab10 100644
--- a/app/uploaders/attachment_uploader.rb
+++ b/app/uploaders/attachment_uploader.rb
@@ -23,7 +23,7 @@ class AttachmentUploader < CarrierWave::Uploader::Base
# end
# Process files as they are uploaded:
- # process :scale => [200, 300]
+ # process scale: [200, 300]
#
# def scale(width, height)
# # do something
@@ -31,7 +31,7 @@ class AttachmentUploader < CarrierWave::Uploader::Base
# Create different versions of your uploaded files:
# version :thumb do
- # process :scale => [50, 50]
+ # process scale: [50, 50]
# end
# Add a white list of extensions which are allowed to be uploaded.
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index 886943be6de..3e26f566a2e 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -5,11 +5,11 @@
Resque Workers
.data.padded
= link_to admin_resque_path do
- %h1{:class => @workers.present? ? "cgreen" : "cred"}
+ %h1{class: @workers.present? ? "cgreen" : "cred"}
= @workers.count
%hr
%p
- %strong{:class => @pending_jobs > 0 ? "cred" : "cgreen"}
+ %strong{class: @pending_jobs > 0 ? "cred" : "cgreen"}
#{@pending_jobs} post receive jobs waiting
.span4
@@ -19,7 +19,7 @@
= link_to admin_projects_path do
%h1= Project.count
%hr
- = link_to 'New Project', new_admin_project_path, :class => "btn small"
+ = link_to 'New Project', new_admin_project_path, class: "btn small"
.span4
.ui-box
%h5 Users
@@ -27,7 +27,7 @@
= link_to admin_users_path do
%h1= User.count
%hr
- = link_to 'New User', new_admin_user_path, :class => "btn small"
+ = link_to 'New User', new_admin_user_path, class: "btn small"
.row
@@ -35,11 +35,13 @@
%h3 Latest projects
%hr
- @projects.each do |project|
- %h5
+ %p
= link_to project.name, [:admin, project]
.span6
%h3 Latest users
%hr
- @users.each do |user|
- %h5
- = link_to user.name, [:admin, user]
+ %p
+ = link_to [:admin, user] do
+ = user.name
+ %small= user.email
diff --git a/app/views/admin/hooks/_data_ex.html.erb b/app/views/admin/hooks/_data_ex.html.erb
new file mode 100644
index 00000000000..652ee5aa56f
--- /dev/null
+++ b/app/views/admin/hooks/_data_ex.html.erb
@@ -0,0 +1,66 @@
+<% data_ex_str = <<eos
+1. Project created:
+{
+ "created_at": "2012-07-21T07:30:54Z",
+ "event_name": "project_create",
+ "name": "StoreCloud",
+ "owner_email": "johnsmith@gmail.com",
+ "owner_name": "John Smith",
+ "path": "storecloud",
+ "project_id": 74
+}
+
+2. Project destroyed:
+{
+ "event_name": "project_destroy",
+ "name": "Underscore",
+ "owner_email": "johnsmith@gmail.com",
+ "owner_name": "John Smith",
+ "path": "underscore",
+ "project_id": 73
+}
+
+3. New Team Member:
+{
+ "created_at": "2012-07-21T07:30:56Z",
+ "event_name": "user_add_to_team",
+ "project_access": "Master",
+ "project_id": 74,
+ "project_name": "StoreCloud",
+ "project_path": "storecloud",
+ "owner_email": "johnsmith@gmail.com",
+ "owner_name": "John Smith",
+}
+
+4. Team Member Removed:
+{
+ "created_at": "2012-07-21T07:30:56Z",
+ "event_name": "user_remove_from_team",
+ "project_access": "Master",
+ "project_id": 74,
+ "project_name": "StoreCloud",
+ "project_path": "storecloud",
+ "owner_email": "johnsmith@gmail.com",
+ "owner_name": "John Smith",
+}
+
+5. User created:
+{
+ "created_at": "2012-07-21T07:44:07Z",
+ "email": "js@gitlabhq.com",
+ "event_name": "user_create",
+ "name": "John Smith"
+}
+
+6. User removed:
+{
+ "created_at": "2012-07-21T07:44:07Z",
+ "email": "js@gitlabhq.com",
+ "event_name": "user_destroy",
+ "name": "John Smith"
+}
+
+eos
+%>
+<% js_lexer = Pygments::Lexer[:js] %>
+<%= raw js_lexer.highlight(data_ex_str) %>
diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml
new file mode 100644
index 00000000000..43288424e8e
--- /dev/null
+++ b/app/views/admin/hooks/index.html.haml
@@ -0,0 +1,39 @@
+.alert.alert-info
+ %span
+ Post receive hooks for binding events.
+ %br
+ Read more about system hooks
+ %strong #{link_to "here", help_system_hooks_path, class: "vlink"}
+
+= form_for @hook, as: :hook, url: admin_hooks_path, html: { class: 'form-inline' } do |f|
+ -if @hook.errors.any?
+ .alert-message.block-message.error
+ - @hook.errors.full_messages.each do |msg|
+ %p= msg
+ .clearfix
+ = f.label :url, "URL:"
+ .input
+ = f.text_field :url, class: "text_field xxlarge"
+ &nbsp;
+ = f.submit "Add System Hook", class: "btn primary"
+%hr
+
+-if @hooks.any?
+ %h3
+ Hooks
+ %small (#{@hooks.count})
+ %br
+ %table.admin-table
+ %tr
+ %th URL
+ %th Method
+ %th
+ - @hooks.each do |hook|
+ %tr
+ %td
+ = link_to admin_hook_path(hook) do
+ %strong= hook.url
+ = link_to 'Test Hook', admin_hook_test_path(hook), class: "btn small right"
+ %td POST
+ %td
+ = link_to 'Remove', admin_hook_path(hook), confirm: 'Are you sure?', method: :delete, class: "danger btn small right"
diff --git a/app/views/admin/mailer/preview.html.haml b/app/views/admin/mailer/preview.html.haml
deleted file mode 100644
index 23ea7381cf5..00000000000
--- a/app/views/admin/mailer/preview.html.haml
+++ /dev/null
@@ -1,28 +0,0 @@
-%p This is page with preview for all system emails that are sent to user
-%p Email previews built based on existing Project/Commit/Issue base - so some preview maybe unavailable unless object appear in system
-
-#accordion
- %h3
- %a New user
- %div
- %iframe{ :src=> admin_mailer_preview_user_new_path, :width=>"100%", :height=>"350"}
- %h3
- %a New issue
- %div
- %iframe{ :src=> admin_mailer_preview_issue_new_path, :width=>"100%", :height=>"350"}
- %h3
- %a Commit note
- %div
- %iframe{ :src=> admin_mailer_preview_note_path(:type => "Commit"), :width=>"100%", :height=>"350"}
- %h3
- %a Issue note
- %div
- %iframe{ :src=> admin_mailer_preview_note_path(:type => "Issue"), :width=>"100%", :height=>"350"}
- %h3
- %a Wall note
- %div
- %iframe{ :src=> admin_mailer_preview_note_path(:type => "Wall"), :width=>"100%", :height=>"350"}
-
-:javascript
- $(function() {
- $("#accordion").accordion(); });
diff --git a/app/views/admin/projects/_form.html.haml b/app/views/admin/projects/_form.html.haml
index 41c620a0218..7cebddf2890 100644
--- a/app/views/admin/projects/_form.html.haml
+++ b/app/views/admin/projects/_form.html.haml
@@ -1,40 +1,49 @@
-= form_for [:admin, @admin_project] do |f|
- -if @admin_project.errors.any?
+= form_for [:admin, project] do |f|
+ -if project.errors.any?
.alert-message.block-message.error
%ul
- - @admin_project.errors.full_messages.each do |msg|
+ - project.errors.full_messages.each do |msg|
%li= msg
- .clearfix
- = f.label :name
- .input= f.text_field :name
- .clearfix
- = f.label :path do
- Path
+ .clearfix.project_name_holder
+ = f.label :name do
+ Project name is
.input
- .input-prepend
- %span.add-on= Gitlab.config.ssh_path
- = f.text_field :path, :placeholder => "example_project", :disabled => !@admin_project.new_record?
- .clearfix
- = f.label :code do
- Code
- .input
- .input-prepend
- %span.add-on= web_app_url
- = f.text_field :code, :placeholder => "example"
+ = f.text_field :name, placeholder: "Example Project", class: "xxlarge"
+ = f.submit project.new_record? ? 'Create project' : 'Save Project', class: "btn primary"
- - unless @admin_project.new_record?
+ %hr
+ .alert.alert-info
+ %h5 Advanced settings:
+ .clearfix
+ = f.label :path do
+ Git Clone
+ .input
+ .input-prepend
+ %span.add-on= Gitlab.config.ssh_path
+ = f.text_field :path, placeholder: "example_project", disabled: !!project.id
+ %span.add-on= ".git"
.clearfix
- = f.label :owner_id
- .input= f.select :owner_id, User.all.map { |user| [user.name, user.id] }
+ = f.label :code do
+ URL
+ .input
+ .input-prepend
+ %span.add-on= web_app_url
+ = f.text_field :code, placeholder: "example"
- - if @admin_project.repo_exists?
+ - unless project.new_record?
.clearfix
- = f.label :default_branch, "Default Branch"
- .input= f.select(:default_branch, @admin_project.heads.map(&:name), {}, :style => "width:210px;")
+ = f.label :owner_id
+ .input= f.select :owner_id, User.all.map { |user| [user.name, user.id] }
- .well
- %h5 Features
+ - if project.repo_exists?
+ .clearfix
+ = f.label :default_branch, "Default Branch"
+ .input= f.select(:default_branch, project.heads.map(&:name), {}, style: "width:210px;")
+
+ - unless project.new_record?
+ .alert.alert-info
+ %h5 Features:
.clearfix
= f.label :issues_enabled, "Issues"
@@ -48,19 +57,19 @@
= f.label :wall_enabled, "Wall"
.input= f.check_box :wall_enabled
- .clearfix
- = f.label :description
- .input= f.text_area :description, :class => "xxlarge"
- .clear
- %br
- .actions
- = f.submit 'Save', :class => "btn primary"
- = link_to 'Cancel', [:admin, @admin_project], :class => "btn"
- - unless @admin_project.new_record?
- = link_to 'Destroy', [:admin, @admin_project], :confirm => 'Are you sure?', :method => :delete, :class => "btn danger right"
+ .clearfix
+ = f.label :wiki_enabled, "Wiki"
+ .input= f.check_box :wiki_enabled
+
+ - unless project.new_record?
+ .actions
+ = f.submit 'Save Project', class: "btn primary"
+
+
:javascript
$(function(){
$('#project_owner_id').chosen();
new Projects();
})
+
diff --git a/app/views/admin/projects/edit.html.haml b/app/views/admin/projects/edit.html.haml
index b8d6f6899cb..b5255671154 100644
--- a/app/views/admin/projects/edit.html.haml
+++ b/app/views/admin/projects/edit.html.haml
@@ -1,3 +1,3 @@
-%h3= @admin_project.name
+%h3.page_title #{@admin_project.name} &rarr; Edit project
%hr
-= render 'form'
+= render 'form', project: @admin_project
diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml
index 7218eebb62a..f7dd486ddac 100644
--- a/app/views/admin/projects/index.html.haml
+++ b/app/views/admin/projects/index.html.haml
@@ -1,10 +1,10 @@
-%h3
+%h3.page_title
Projects
- = link_to 'New Project', new_admin_project_path, :class => "btn small right"
+ = link_to 'New Project', new_admin_project_path, class: "btn small right"
%br
-= form_tag admin_projects_path, :method => :get do
- = text_field_tag :name, params[:name], :class => "xlarge"
- = submit_tag "Search", :class => "btn submit primary"
+= form_tag admin_projects_path, method: :get, class: 'form-inline' do
+ = text_field_tag :name, params[:name], class: "xlarge"
+ = submit_tag "Search", class: "btn submit primary"
%table.admin-table
%thead
@@ -21,8 +21,8 @@
%td= link_to project.name, [:admin, project]
%td= project.path
%td= project.users_projects.count
- %td= check_box_tag :post_receive_file, 1, project.has_post_receive_file?, :disabled => true
+ %td= check_box_tag :post_receive_file, 1, project.has_post_receive_file?, disabled: true
%td= last_commit(project)
- %td= link_to 'Edit', edit_admin_project_path(project), :id => "edit_#{dom_id(project)}", :class => "btn small"
- %td.bgred= link_to 'Destroy', [:admin, project], :confirm => "REMOVE #{project.name}? Are you sure?", :method => :delete, :class => "btn small danger"
-= paginate @admin_projects, :theme => "admin"
+ %td= link_to 'Edit', edit_admin_project_path(project), id: "edit_#{dom_id(project)}", class: "btn small"
+ %td.bgred= link_to 'Destroy', [:admin, project], confirm: "REMOVE #{project.name}? Are you sure?", method: :delete, class: "btn small danger"
+= paginate @admin_projects, theme: "admin"
diff --git a/app/views/admin/projects/new.html.haml b/app/views/admin/projects/new.html.haml
index 1e1c7aac46e..ac6526bfa4b 100644
--- a/app/views/admin/projects/new.html.haml
+++ b/app/views/admin/projects/new.html.haml
@@ -1,3 +1,3 @@
-%h2 New project
+%h3.page_title New project
%hr
-= render 'form'
+= render 'form', project: @admin_project
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index 8ba2943e7f9..5ed56477905 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -1,6 +1,6 @@
%h3
= @admin_project.name
- = link_to 'Edit', edit_admin_project_path(@admin_project), :class => "btn right small"
+ = link_to 'Edit', edit_admin_project_path(@admin_project), class: "btn right small"
%br
%table.zebra-striped.table-bordered
@@ -25,15 +25,15 @@
%tr
%td
%b
- Description:
+ Owner:
%td
- = @admin_project.description
+ = @admin_project.owner.name
%tr
%td
%b
Post Receive File:
%td
- = check_box_tag :post_receive_file, 1, @admin_project.has_post_receive_file?, :disabled => true
+ = check_box_tag :post_receive_file, 1, @admin_project.has_post_receive_file?, disabled: true
%br
%h3
Team
@@ -52,14 +52,14 @@
%tr
%td
= link_to tm.user_name, admin_user_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"
+ %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"
%br
%h3 Add new team member
%br
-= form_tag team_update_admin_project_path(@admin_project), :class => "bulk_import", :method => :put do
+= form_tag team_update_admin_project_path(@admin_project), class: "bulk_import", method: :put do
%table.zebra-striped.table-bordered
%thead
%tr
@@ -67,14 +67,14 @@
%th Project Access:
%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 :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"
%tr
- %td= submit_tag 'Add', :class => "btn primary"
+ %td= submit_tag 'Add', class: "btn primary"
%td
Read more about project permissions
- %strong= link_to "here", help_permissions_path, :class => "vlink"
+ %strong= link_to "here", help_permissions_path, class: "vlink"
:css
form select {
diff --git a/app/views/admin/resque/show.html.haml b/app/views/admin/resque/show.html.haml
index 267129530bd..0375d94bc9d 100644
--- a/app/views/admin/resque/show.html.haml
+++ b/app/views/admin/resque/show.html.haml
@@ -1,2 +1,2 @@
%h3 Resque
-%iframe{:src => "/info/resque", :width => 1168, :height => 600, :style => "border: none"} \ No newline at end of file
+%iframe{src: "/info/resque", width: 1168, height: 600, style: "border: none"} \ No newline at end of file
diff --git a/app/views/admin/team_members/_form.html.haml b/app/views/admin/team_members/_form.html.haml
index 034757620ec..6a128de94b2 100644
--- a/app/views/admin/team_members/_form.html.haml
+++ b/app/views/admin/team_members/_form.html.haml
@@ -1,4 +1,4 @@
-= form_for @admin_team_member, :as => :team_member, :url => 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?
.alert-message.block-message.error
%ul
@@ -8,12 +8,12 @@
.clearfix
%label Project Access:
.input
- = f.select :project_access, options_for_select(Project.access_options, @admin_team_member.project_access), {}, :class => "project-access-select"
+ = f.select :project_access, options_for_select(Project.access_options, @admin_team_member.project_access), {}, class: "project-access-select"
%br
.actions
- = f.submit 'Save', :class => "btn primary"
- = link_to 'Cancel', :back, :class => "btn"
+ = f.submit 'Save', class: "btn primary"
+ = link_to 'Cancel', :back, class: "btn"
:css
form select {
diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml
index bd2e136247a..2014472375b 100644
--- a/app/views/admin/users/_form.html.haml
+++ b/app/views/admin/users/_form.html.haml
@@ -2,71 +2,79 @@
= form_for [:admin, @admin_user] do |f|
-if @admin_user.errors.any?
#error_explanation
- %ul
+ %ul.unstyled.alert.alert-error
- @admin_user.errors.full_messages.each do |msg|
%li= msg
.row
- .span6
- .clearfix
- = f.label :name
- .input
- = f.text_field :name
- %span.help-inline * required
- .clearfix
- = f.label :email
- .input
- = f.text_field :email
- %span.help-inline * required
- %hr
-
- -if f.object.new_record?
- .clearfix
- = f.label :admin, :class => "checkbox" do
- = f.check_box :force_random_password, {}, true, nil
- %span Generate random password
-
- %div.password-fields
+ .span7
+ .ui-box
+ %br
.clearfix
- = f.label :password
- .input= f.password_field :password, :disabled => f.object.force_random_password
+ = f.label :name
+ .input
+ = f.text_field :name
+ %span.help-inline * required
.clearfix
- = f.label :password_confirmation
- .input= f.password_field :password_confirmation, :disabled => f.object.force_random_password
- %hr
- .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
- .span6
- .clearfix
- = f.label :projects_limit
- .input= f.text_field :projects_limit, :class => "small_input"
+ = f.label :email
+ .input
+ = f.text_field :email
+ %span.help-inline * required
+ %hr
+ -if f.object.new_record?
+ .clearfix
+ = f.label :force_random_password do
+ %span Generate random password
+ .input= f.check_box :force_random_password, {}, true, nil
+
+ %div.password-fields
+ .clearfix
+ = f.label :password
+ .input= f.password_field :password, disabled: f.object.force_random_password
+ .clearfix
+ = f.label :password_confirmation
+ .input= f.password_field :password_confirmation, disabled: f.object.force_random_password
+ %hr
+ .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
+ .span5
+ .ui-box
+ %br
+ .clearfix
+ = f.label :projects_limit
+ .input= f.number_field :projects_limit
- .alert
.clearfix
- %p Give user ability to manage application.
- = f.label :admin, :class => "checkbox" do
- = f.check_box :admin
- %span Administrator
- - unless @admin_user.new_record?
- .alert.alert-error
- - if @admin_user.blocked
- %span
- = link_to 'Unblock', unblock_admin_user_path(@admin_user), :method => :put, :class => "btn small"
- This user is blocked and is not able to login GitLab
- - else
- %span
- = link_to 'Block', block_admin_user_path(@admin_user), :confirm => 'USER WILL BE BLOCKED! Are you sure?', :method => :put, :class => "btn small danger"
- Blocked user will removed from all projects &amp; will not be able to login to GitLab.
+ = f.label :admin do
+ %strong.cred Administrator
+ .input= f.check_box :admin
+ - unless @admin_user.new_record?
+ %hr
+ .padded.cred
+ - if @admin_user.blocked
+ %span
+ This user is blocked and is not able to login to GitLab
+ .clearfix
+ = link_to 'Unblock User', unblock_admin_user_path(@admin_user), method: :put, class: "btn small right"
+ - else
+ %span
+ Blocked users will be removed from all projects &amp; will not be able to login to GitLab.
+ .clearfix
+ = link_to 'Block User', block_admin_user_path(@admin_user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn small right danger"
+
+ .row
+ .span6
+ .span6
.actions
- = f.submit 'Save', :class => "btn primary"
+ = f.submit 'Save', class: "btn primary"
- if @admin_user.new_record?
- = link_to 'Cancel', admin_users_path, :class => "btn"
+ = link_to 'Cancel', admin_users_path, class: "btn"
- else
- = link_to 'Cancel', admin_user_path(@admin_user), :class => "btn"
+ = 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 0e94be9e12c..032e3cfaa99 100644
--- a/app/views/admin/users/edit.html.haml
+++ b/app/views/admin/users/edit.html.haml
@@ -1,3 +1,3 @@
-%h3= @admin_user.name
+%h3.page_title #{@admin_user.name} &rarr; Edit user
%hr
= render 'form'
diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml
index 5d5320db0e3..f21baabf8eb 100644
--- a/app/views/admin/users/index.html.haml
+++ b/app/views/admin/users/index.html.haml
@@ -1,22 +1,22 @@
-%h3
+%h3.page_title
Users
- = link_to 'New User', new_admin_user_path, :class => "btn small right"
+ = link_to 'New User', new_admin_user_path, class: "btn small right"
%br
-= form_tag admin_users_path, :method => :get do
- = text_field_tag :name, params[:name], :class => "xlarge"
- = submit_tag "Search", :class => "btn submit primary"
+= form_tag admin_users_path, method: :get, class: 'form-inline' do
+ = text_field_tag :name, params[:name], class: "xlarge"
+ = submit_tag "Search", class: "btn submit primary"
%ul.nav.nav-pills
- %li{:class => "#{'active' unless params[:filter]}"}
+ %li{class: "#{'active' unless params[:filter]}"}
= link_to "Active", admin_users_path
- %li{:class => "#{'active' if params[:filter] == "admins"}"}
- = link_to admin_users_path(:filter => "admins") do
+ %li{class: "#{'active' if params[:filter] == "admins"}"}
+ = link_to admin_users_path(filter: "admins") do
Admins
- %li{:class => "#{'active' if params[:filter] == "blocked"}"}
- = link_to admin_users_path(:filter => "blocked") do
+ %li{class: "#{'active' if params[:filter] == "blocked"}"}
+ = link_to admin_users_path(filter: "blocked") do
Blocked
- %li{:class => "#{'active' if params[:filter] == "wop"}"}
- = link_to admin_users_path(:filter => "wop") do
+ %li{class: "#{'active' if params[:filter] == "wop"}"}
+ = link_to admin_users_path(filter: "wop") do
Without projects
%table.admin-table
@@ -31,16 +31,16 @@
- @admin_users.each do |user|
%tr
- %td= check_box_tag "admin", 1, user.admin, :disabled => :disabled
+ %td= check_box_tag "admin", 1, user.admin, disabled: :disabled
%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)}", :class => "btn small"
+ %td= link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: "btn small"
%td
- if user.blocked
- = link_to 'Unblock', unblock_admin_user_path(user), :method => :put, :class => "btn small success"
+ = link_to 'Unblock', unblock_admin_user_path(user), method: :put, class: "btn small success"
- else
- = link_to 'Block', block_admin_user_path(user), :confirm => 'USER WILL BE BLOCKED! Are you sure?', :method => :put, :class => "btn small danger"
- %td.bgred= link_to 'Destroy', [:admin, user], :confirm => "USER #{user.name} WILL BE REMOVED! Are you sure?", :method => :delete, :class => "btn small danger"
+ = link_to 'Block', block_admin_user_path(user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn small danger"
+ %td.bgred= link_to 'Destroy', [:admin, user], confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?", method: :delete, class: "btn small danger"
-= paginate @admin_users, :theme => "admin"
+= paginate @admin_users, theme: "admin"
diff --git a/app/views/admin/users/new.html.haml b/app/views/admin/users/new.html.haml
index 87d6b0f2757..70ead0d3f7d 100644
--- a/app/views/admin/users/new.html.haml
+++ b/app/views/admin/users/new.html.haml
@@ -1,3 +1,3 @@
-%h2 New user
-%hr
+%h3.page_title New user
+%br
= render 'form'
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index 7510b1446dc..4cca8ed7a4e 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -4,7 +4,7 @@
%small Blocked
- if @admin_user.admin
%small Administrator
- = link_to 'Edit', edit_admin_user_path(@admin_user), :class => "btn small right"
+ = link_to 'Edit', edit_admin_user_path(@admin_user), class: "btn small right"
%br
@@ -19,12 +19,12 @@
%td
%b
Admin:
- %td= check_box_tag "admin", 1, @admin_user.admin, :disabled => :disabled
+ %td= check_box_tag "admin", 1, @admin_user.admin, disabled: :disabled
%tr
%td
%b
Blocked:
- %td= check_box_tag "blocked", 1, @admin_user.blocked, :disabled => :disabled
+ %td= check_box_tag "blocked", 1, @admin_user.blocked, disabled: :disabled
%tr
%td
%b
@@ -56,7 +56,7 @@
%br
%h3 Add User to Projects
%br
-= form_tag team_update_admin_user_path(@admin_user), :class => "bulk_import", :method => :put do
+= form_tag team_update_admin_user_path(@admin_user), class: "bulk_import", method: :put do
%table.table-bordered
%thead
%tr
@@ -64,14 +64,14 @@
%th Project 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"
+ %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"
%tr
- %td= submit_tag 'Add', :class => "btn primary"
+ %td= submit_tag 'Add', class: "btn primary"
%td
Read more about project permissions
- %strong= link_to "here", help_permissions_path, :class => "vlink"
+ %strong= link_to "here", help_permissions_path, class: "vlink"
%br
- if @admin_user.projects.present?
@@ -90,9 +90,9 @@
- project = tm.project
%tr
%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"
+ %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"
:css
form select {
diff --git a/app/views/commits/_commit.html.haml b/app/views/commits/_commit.html.haml
index 9f9502e30d4..686a4337b3a 100644
--- a/app/views/commits/_commit.html.haml
+++ b/app/views/commits/_commit.html.haml
@@ -1,17 +1,16 @@
%li.commit
.browse_code_link_holder
%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)
+ %strong= link_to "Browse Code »", tree_project_ref_path(@project, commit.id), class: "right"
+ %p
+ = link_to commit.short_id(8), project_commit_path(@project, id: commit.id), class: "commit_short_id"
+ %strong.cgray= commit.author_name
+ &ndash;
+ = image_tag gravatar_icon(commit.author_email), class: "avatar", width: 16
+ = link_to_gfm truncate(commit.title, length: 50), project_commit_path(@project, id: commit.id), class: "row_title"
- %span.committed_ago
- = time_ago_in_words(commit.committed_date)
- ago
- &nbsp;
+ %span.committed_ago
+ = time_ago_in_words(commit.committed_date)
+ ago
+ &nbsp;
diff --git a/app/views/commits/_commit_box.html.haml b/app/views/commits/_commit_box.html.haml
index 8ccb3f1b72a..506f4e092a1 100644
--- a/app/views/commits/_commit_box.html.haml
+++ b/app/views/commits/_commit_box.html.haml
@@ -1,24 +1,24 @@
-.commit-box{class: @commit.parents.count > 1 ? "merge-commit" : ""}
+.commit-box{class: @commit.parents_count > 1 ? "merge-commit" : ""}
.commit-head
.right
- if @notes_count > 0
%span.btn.disabled.grouped
%i.icon-comment
= @notes_count
- = link_to patch_project_commit_path(@project, @commit.id), :class => "btn small grouped" do
+ = link_to patch_project_commit_path(@project, @commit.id), class: "btn small grouped" do
%i.icon-download-alt
- Get Patch
- = link_to tree_project_ref_path(@project, @commit.id), :class => "browse-button primary grouped" do
+ Get Patch
+ = link_to tree_project_ref_path(@project, @commit.id), class: "browse-button primary grouped" do
%strong Browse Code »
%h3.commit-title.page_title
- = commit_msg_with_link_to_issues(@project, @commit.title)
+ = gfm @commit.title
- if @commit.description.present?
%pre.commit-description
- = commit_msg_with_link_to_issues(@project, @commit.description)
+ = gfm @commit.description
.commit-info
.row
.span4
- = image_tag gravatar_icon(@commit.author_email, 40), :class => "avatar"
+ = image_tag gravatar_icon(@commit.author_email, 40), class: "avatar"
.author
%strong= @commit.author_name
authored
diff --git a/app/views/commits/_diff_head.html.haml b/app/views/commits/_diff_head.html.haml
index 11d6ca169d0..710e8857649 100644
--- a/app/views/commits/_diff_head.html.haml
+++ b/app/views/commits/_diff_head.html.haml
@@ -3,24 +3,24 @@
%li
- if diff.deleted_file
%span.removed_file
- %a{:href => "##{diff.old_path}"}
+ %a{href: "##{diff.old_path}"}
= diff.old_path
= image_tag "diff_file_delete.png"
- elsif diff.renamed_file
%span.moved_file
- %a{:href => "##{diff.new_path}"}
+ %a{href: "##{diff.new_path}"}
= diff.old_path
= "->"
= diff.new_path
= image_tag "diff_file_notice.png"
- elsif diff.new_file
%span.new_file
- %a{:href => "##{diff.new_path}"}
+ %a{href: "##{diff.new_path}"}
= diff.new_path
= image_tag "diff_file_add.png"
- else
%span.edit_file
- %a{:href => "##{diff.new_path}"}
+ %a{href: "##{diff.new_path}"}
= diff.new_path
= image_tag "diff_file_info.png"
diff --git a/app/views/commits/_diffs.html.haml b/app/views/commits/_diffs.html.haml
index d51561d90f8..b590d64c06e 100644
--- a/app/views/commits/_diffs.html.haml
+++ b/app/views/commits/_diffs.html.haml
@@ -5,12 +5,12 @@
%p To prevent performance issue we rejected diff information.
%p
But if you still want to see diff
- = link_to "click this link", project_commit_path(@project, @commit.id, :force_show_diff => true), :class => "dark"
+ = link_to "click this link", project_commit_path(@project, @commit.id, force_show_diff: true), class: "dark"
%p.cgray
Showing #{pluralize(diffs.count, "changed file")}
.file_stats
- = render "commits/diff_head", :diffs => diffs
+ = render "commits/diff_head", diffs: diffs
- unless @suppress_diff
- diffs.each_with_index do |diff, i|
@@ -22,26 +22,26 @@
.diff_file_header
- if diff.deleted_file
%i.icon-file
- %span{:id => "#{diff.old_path}"}= diff.old_path
+ %span{id: "#{diff.old_path}"}= diff.old_path
- else
= link_to tree_file_project_ref_path(@project, @commit.id, diff.new_path) do
%i.icon-file
- %span{:id => "#{diff.new_path}"}= diff.new_path
+ %span{id: "#{diff.new_path}"}= diff.new_path
%br/
.diff_file_content
-# Skipp all non non-supported blobs
- next unless file.respond_to?('text?')
- if file.text?
- = render "commits/text_file", :diff => diff, :index => i
+ = render "commits/text_file", diff: diff, index: i
- elsif file.image?
- if diff.renamed_file || diff.new_file || diff.deleted_file
.diff_file_content_image
- %img{:class => image_diff_class(diff), :src => "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
+ %img{class: image_diff_class(diff), src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
- else
- old_file = (@commit.prev_commit.tree / diff.old_path)
.diff_file_content_image.img_compared
- %img{:class => "diff_image_removed", :src => "data:#{file.mime_type};base64,#{Base64.encode64(old_file.data)}"}
- %img{:class => "diff_image_added", :src => "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
+ %img{class: "diff_image_removed", src: "data:#{file.mime_type};base64,#{Base64.encode64(old_file.data)}"}
+ %img{class: "diff_image_added", src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
- else
%p.nothing_here_message No preview for this file type
diff --git a/app/views/commits/_head.html.haml b/app/views/commits/_head.html.haml
index 453ca4eac12..a211329f349 100644
--- a/app/views/commits/_head.html.haml
+++ b/app/views/commits/_head.html.haml
@@ -1,21 +1,21 @@
%ul.nav.nav-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"
+ = 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)) }"}
+ %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)) }"}
+ %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}"}
+ %li{class: "#{branches_tab_class}"}
= link_to project_repository_path(@project) do
Branches
%span.badge= @project.repo.branch_count
- %li{:class => "#{'active' if current_page?(tags_project_repository_path(@project)) }"}
+ %li{class: "#{'active' if current_page?(tags_project_repository_path(@project)) }"}
= link_to tags_project_repository_path(@project) do
Tags
%span.badge= @project.repo.tag_count
@@ -24,8 +24,8 @@
- if current_page?(project_commits_path(@project)) && current_user.private_token
%li.right
%span.rss-icon
- = link_to project_commits_path(@project, :atom, { :private_token => current_user.private_token, :ref => @ref }), :title => "Feed" do
- = image_tag "rss_ui.png", :title => "feed"
+ = link_to project_commits_path(@project, :atom, { private_token: current_user.private_token, ref: @ref }), title: "Feed" do
+ = image_tag "rss_ui.png", title: "feed"
:javascript
$(function(){
diff --git a/app/views/commits/_text_file.html.haml b/app/views/commits/_text_file.html.haml
index cab066410b4..0f6210f2b5a 100644
--- a/app/views/commits/_text_file.html.haml
+++ b/app/views/commits/_text_file.html.haml
@@ -2,7 +2,7 @@
- if too_big
%a.supp_diff_link Diff suppressed. Click to show
-%table{:class => "#{'hide' if too_big}"}
+%table{class: "#{'hide' if too_big}"}
- each_diff_line(diff.diff.lines.to_a, index) do |line, type, line_code, line_new, line_old|
%tr.line_holder
- if type == "match"
@@ -11,16 +11,16 @@
%td.line_content.matched= line
- else
%td.old_line
- = link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", :id => line_code
+ = 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;"
+ = 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
+ = 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
index 66ed8dad595..be915cd1038 100644
--- a/app/views/commits/compare.html.haml
+++ b/app/views/commits/compare.html.haml
@@ -14,22 +14,23 @@
%br
- = form_tag compare_project_commits_path(@project), :method => :get do
+ = form_tag compare_project_commits_path(@project), method: :get do
.clearfix
- = text_field_tag :from, params[:from], :placeholder => "master", :class => "xlarge"
+ = text_field_tag :from, params[:from], placeholder: "master", class: "xlarge"
= "..."
- = text_field_tag :to, params[:to], :placeholder => "aa8b4ef", :class => "xlarge"
+ = text_field_tag :to, params[:to], placeholder: "aa8b4ef", class: "xlarge"
.actions
- = submit_tag "Compare", :class => "btn btn-primary"
+ = submit_tag "Compare", class: "btn btn-primary"
- unless @commits.empty?
- %h4 Commits (#{@commits.count})
- %ul.unstyled= render @commits
+ %div.ui-box
+ %h5.small Commits (#{@commits.count})
+ %ul.unstyled= render @commits
- unless @diffs.empty?
%h4 Diff
- = render "commits/diffs", :diffs => @diffs
+ = render "commits/diffs", diffs: @diffs
:javascript
$(function() {
diff --git a/app/views/commits/index.atom.builder b/app/views/commits/index.atom.builder
index 2a352dac1b7..cca704560e4 100644
--- a/app/views/commits/index.atom.builder
+++ b/app/views/commits/index.atom.builder
@@ -10,14 +10,14 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.entry do
xml.id project_commit_url(@project, :id => commit.id)
xml.link :href => project_commit_url(@project, :id => commit.id)
- xml.title truncate(commit.safe_message, :length => 80)
+ xml.title truncate(commit.title, :length => 80)
xml.updated commit.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ")
xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(commit.author_email)
xml.author do |author|
xml.name commit.author_name
xml.email commit.author_email
end
- xml.summary commit.safe_message
+ xml.summary gfm(commit.description)
end
end
end
diff --git a/app/views/commits/index.html.haml b/app/views/commits/index.html.haml
index 385b4357e4e..11ffdb6afc3 100644
--- a/app/views/commits/index.html.haml
+++ b/app/views/commits/index.html.haml
@@ -9,12 +9,12 @@
%span.divider
\/
%li
- %a{:href => "#"}= params[:path].split("/").join(" / ")
+ %a{href: "#"}= params[:path].split("/").join(" / ")
-%div{:id => dom_id(@project)}
+%div{id: dom_id(@project)}
#commits_list= render "commits"
.clear
-.loading{ :style => "display:none;"}
+.loading{ style: "display:none;"}
- if @commits.count == @limit
:javascript
diff --git a/app/views/commits/index.js.haml b/app/views/commits/index.js.haml
index 39b7108c505..797bc14cc1b 100644
--- a/app/views/commits/index.js.haml
+++ b/app/views/commits/index.js.haml
@@ -1,3 +1,3 @@
:plain
- CommitsList.append(#{@commits.count}, "#{escape_javascript(render(:partial => 'commits/commits'))}");
+ CommitsList.append(#{@commits.count}, "#{escape_javascript(render(partial: 'commits/commits'))}");
diff --git a/app/views/commits/show.html.haml b/app/views/commits/show.html.haml
index 7119bd04b9e..9a483aa2a9a 100644
--- a/app/views/commits/show.html.haml
+++ b/app/views/commits/show.html.haml
@@ -1,6 +1,6 @@
= render "commits/commit_box"
-= render "commits/diffs", :diffs => @commit.diffs
-= render "notes/notes", :tid => @commit.id, :tt => "commit"
+= render "commits/diffs", diffs: @commit.diffs
+= render "notes/notes", tid: @commit.id, tt: "commit"
= render "notes/per_line_form"
diff --git a/app/views/dashboard/index.html.haml b/app/views/dashboard/index.html.haml
index b38544509b2..ba7d019cb63 100644
--- a/app/views/dashboard/index.html.haml
+++ b/app/views/dashboard/index.html.haml
@@ -1,20 +1,14 @@
- if @projects.any?
.projects
.activities.span8
- - if current_user.require_ssh_key?
- .alert.alert-error.padded
- %span
- You wont be able to pull/push project code unless you
- %strong
- = link_to new_key_path, :class => "vlink" do
- add new key
- to your profile
+ = render 'shared/no_ssh'
- if @events.any?
- = render @events
+ .content_list= render @events
- else
%h4.nothing_here_message Projects activity will be displayed here
+ .loading.hide
.side
- = render "events/event_last_push", :event => @last_push
+ = render "events/event_last_push", event: @last_push
.projects_box
%h5
Projects
@@ -22,23 +16,23 @@
(#{@projects.total_count})
- if current_user.can_create_project?
%span.right
- = link_to new_project_path, :class => "btn very_small info" do
+ = link_to new_project_path, class: "btn very_small info" do
%i.icon-plus
New Project
- @projects.each do |project|
- = link_to project_path(project), :class => dom_class(project) do
+ = link_to project_path(project), class: dom_class(project) do
%h4
%span.ico.project
- = truncate(project.name, :length => 25)
+ = truncate(project.name, length: 25)
%span.right
&rarr;
- .bottom= paginate @projects, :theme => "gitlab"
+ .bottom= paginate @projects, theme: "gitlab"
%hr
%div
%span.rss-icon
- = link_to dashboard_path(:atom, { :private_token => current_user.private_token }) do
- = image_tag "rss_ui.png", :title => "feed"
+ = link_to dashboard_path(:atom, { private_token: current_user.private_token }) do
+ = image_tag "rss_ui.png", title: "feed"
%strong News Feed
- else
@@ -50,7 +44,11 @@
= current_user.projects_limit
projects. Click on button below to add a new one
.link_holder
- = link_to new_project_path, :class => "btn primary" do
+ = link_to new_project_path, class: "btn primary" do
New Project »
- else
If you will be added to project - it will be displayed here
+
+
+:javascript
+ $(function(){ Pager.init(20); });
diff --git a/app/views/dashboard/index.js.haml b/app/views/dashboard/index.js.haml
index aa038e75928..7e5a148e5ef 100644
--- a/app/views/dashboard/index.js.haml
+++ b/app/views/dashboard/index.js.haml
@@ -1,2 +1,2 @@
:plain
- $(".projects .activities").append("#{escape_javascript(render(@events))}");
+ Pager.append(#{@events.count}, "#{escape_javascript(render(@events))}");
diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml
index ca87fc6f573..cc488d57e9e 100644
--- a/app/views/dashboard/issues.html.haml
+++ b/app/views/dashboard/issues.html.haml
@@ -8,12 +8,12 @@
- if @issues.any?
- @issues.group_by(&:project).each do |group|
%div.ui-box
- - project = group[0]
- %h5= project.name
+ - @project = group[0]
+ %h5= @project.name
%ul.unstyled.issues_table
- group[1].each do |issue|
- = render(:partial => 'issues/show', :locals => {:issue => issue})
+ = render(partial: 'issues/show', locals: {issue: issue})
%hr
- = paginate @issues, :theme => "gitlab"
+ = paginate @issues, theme: "gitlab"
- else
%h3.nothing_here_message Nothing to show here
diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml
index ce3cd6b5959..23a7e7222d7 100644
--- a/app/views/dashboard/merge_requests.html.haml
+++ b/app/views/dashboard/merge_requests.html.haml
@@ -1,18 +1,18 @@
%h3.page_title
Merge Requests
- %small (authored or assigned to you)
+ %small (authored by or assigned to you)
%small.right #{@merge_requests.total_count} merge requests
%br
- if @merge_requests.any?
- @merge_requests.group_by(&:project).each do |group|
%ul.unstyled.ui-box
- - project = group[0]
- %h5= project.name
+ - @project = group[0]
+ %h5= @project.name
- group[1].each do |merge_request|
- = render(:partial => 'merge_requests/merge_request', :locals => {:merge_request => merge_request})
+ = render(partial: 'merge_requests/merge_request', locals: {merge_request: merge_request})
%hr
- = paginate @merge_requests, :theme => "gitlab"
+ = paginate @merge_requests, theme: "gitlab"
- else
%h3.nothing_here_message Nothing to show here
diff --git a/app/views/deploy_keys/_form.html.haml b/app/views/deploy_keys/_form.html.haml
index 2aa57cdc59b..461f1f5d84a 100644
--- a/app/views/deploy_keys/_form.html.haml
+++ b/app/views/deploy_keys/_form.html.haml
@@ -1,5 +1,5 @@
%div
- = form_for [@project, @key], :url => project_deploy_keys_path do |f|
+ = form_for [@project, @key], url: project_deploy_keys_path do |f|
-if @key.errors.any?
.alert-message.block-message.error
%ul
@@ -11,8 +11,8 @@
.input= f.text_field :title
.clearfix
= f.label :key
- .input= f.text_area :key, :class => "xlarge"
+ .input= f.text_area :key, class: "xlarge"
.actions
- = f.submit 'Save', :class => "primary btn"
- = link_to "Cancel", project_deploy_keys_path(@project), :class => "btn"
+ = 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 ff17b3cd66c..a5314ae92ad 100644
--- a/app/views/deploy_keys/_show.html.haml
+++ b/app/views/deploy_keys/_show.html.haml
@@ -1,6 +1,6 @@
%tr
%td
- %a{:href => project_deploy_key_path(key.project, key)}
+ %a{href: project_deploy_key_path(key.project, key)}
%strong= key.title
%td
%span.update-author
@@ -8,5 +8,5 @@
= 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"
+ = 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 19899de3cf6..0ee9d03b0f5 100644
--- a/app/views/deploy_keys/index.html.haml
+++ b/app/views/deploy_keys/index.html.haml
@@ -2,10 +2,10 @@
- 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
+ = link_to new_project_deploy_key_path(@project), class: "btn small", title: "New Deploy Key" do
Add Deploy Key
- if @keys.any?
%table
- @keys.each do |key|
- = render(:partial => 'show', :locals => {:key => key})
+ = render(partial: 'show', locals: {key: key})
diff --git a/app/views/deploy_keys/show.html.haml b/app/views/deploy_keys/show.html.haml
index 16c441bea73..b1e0dc5ce27 100644
--- a/app/views/deploy_keys/show.html.haml
+++ b/app/views/deploy_keys/show.html.haml
@@ -3,5 +3,5 @@
%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"
+ = 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.haml b/app/views/devise/passwords/edit.html.haml
index dfd715ac13b..31d355673ab 100644
--- a/app/views/devise/passwords/edit.html.haml
+++ b/app/views/devise/passwords/edit.html.haml
@@ -1,12 +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"
+= 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"
+ = f.password_field :password, class: "text top", placeholder: "New password"
%div
- = f.password_field :password_confirmation, :class => "text bottom", :placeholder => "Confirm new password"
+ = 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"
+ = f.submit "Change my password", class: "btn primary"
+ .right= render partial: "devise/shared/links"
diff --git a/app/views/errors/access_denied.html.haml b/app/views/errors/access_denied.html.haml
index 718663dbee1..3b60ed8b0ee 100644
--- a/app/views/errors/access_denied.html.haml
+++ b/app/views/errors/access_denied.html.haml
@@ -1,5 +1,4 @@
-.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"}
+%h1 Access Denied
+%hr
+%h2 You are 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/encoding.html.haml b/app/views/errors/encoding.html.haml
index 0ffbadeb08d..4662437f2d2 100644
--- a/app/views/errors/encoding.html.haml
+++ b/app/views/errors/encoding.html.haml
@@ -2,5 +2,4 @@
%h3 Encoding Error
%hr
%p
- Page cant be loaded cause of encoding error
-
+ Page can't be loaded because of an encoding error.
diff --git a/app/views/errors/git_not_found.html.haml b/app/views/errors/git_not_found.html.haml
index b2399ac51dc..cd01ea1b0e6 100644
--- a/app/views/errors/git_not_found.html.haml
+++ b/app/views/errors/git_not_found.html.haml
@@ -1,9 +1,6 @@
-.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
+%h1 404
+%hr
+%h2 Git Resource Not found
+%p
+ Application can't get access to some branch or commit in your repository. It
+ may have been moved.
diff --git a/app/views/errors/gitolite.html.haml b/app/views/errors/gitolite.html.haml
index 3691b309698..d5f51951d5e 100644
--- a/app/views/errors/gitolite.html.haml
+++ b/app/views/errors/gitolite.html.haml
@@ -1,19 +1,25 @@
-.alert-message.block-message.error
- %h3 Gitolite Error
- %hr
- %h4 Application cant get access to your gitolite system.
+%h1 Git Error
+%hr
+%h2 Gitlab was unable to access your Gitolite system.
+
+.git_error_tips
+ %h4 Tips for Administrator:
%ol
%li
%p
- Check 'config/gitlab.yml' for correct settings.
+ Check git logs in admin area
%li
%p
- Make sure web server user has access to gitolite.
- %a{:href => "https://github.com/gitlabhq/gitlabhq/wiki/Gitolite"} Setup tutorial
+ Check config/gitlab.yml for correct settings.
%li
%p
- Try:
+ Diagnostic tool:
+ %pre
+ bundle exec rake gitlab:app:status RAILS_ENV=production
+ %li
+ %p
+ Permissions:
%pre
= preserve do
sudo chmod -R 770 #{Gitlab.config.git_base_path}
- sudo chown -R git:git #{Gitlab.config.git_base_path} \ No newline at end of file
+ sudo chown -R git:git #{Gitlab.config.git_base_path}
diff --git a/app/views/errors/not_found.html.haml b/app/views/errors/not_found.html.haml
index 9b76a9bf908..a4e8d0204a9 100644
--- a/app/views/errors/not_found.html.haml
+++ b/app/views/errors/not_found.html.haml
@@ -1,5 +1,4 @@
-.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.
+%h1 404
+%hr
+%h2 The resource you were looking for doesn't exist.
+%p You may have mistyped the address or the page may have moved.
diff --git a/app/views/events/_commit.html.haml b/app/views/events/_commit.html.haml
index 60112b508a8..1e5c00cb4f4 100644
--- a/app/views/events/_commit.html.haml
+++ b/app/views/events/_commit.html.haml
@@ -1,9 +1,8 @@
-%li.wll.commit
- = 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"
-
+- commit = CommitDecorator.decorate(commit)
+%li.commit
+ %p
+ = link_to commit.short_id(8), project_commit_path(project, id: commit.id), class: "commit_short_id"
+ %strong.cdark= commit.author_name
+ &ndash;
+ = image_tag gravatar_icon(commit.author_email), class: "avatar", width: 16
+ = gfm truncate(commit.title, length: 50) rescue "--broken encoding"
diff --git a/app/views/events/_event.html.haml b/app/views/events/_event.html.haml
index b3db83c26dd..d49f0382dea 100644
--- a/app/views/events/_event.html.haml
+++ b/app/views/events/_event.html.haml
@@ -1,13 +1,13 @@
- if event.allowed?
- if event.issue?
.event_feed
- = render "events/event_issue", :event => event
+ = render "events/event_issue", event: event
- elsif event.merge_request?
.event_feed
- = render "events/event_merge_request", :event => event
+ = render "events/event_merge_request", event: event
- elsif event.push?
.event_feed
- = render "events/event_push", :event => event
+ = render "events/event_push", event: event
diff --git a/app/views/events/_event_issue.html.haml b/app/views/events/_event_issue.html.haml
index 4293be8204e..4d357b7f912 100644
--- a/app/views/events/_event_issue.html.haml
+++ b/app/views/events/_event_issue.html.haml
@@ -1,6 +1,6 @@
-= image_tag gravatar_icon(event.author_email), :class => "avatar"
+= image_tag gravatar_icon(event.author_email), class: "avatar"
%strong #{event.author_name}
-%span.event_label{:class => event.action_name}= event.action_name
+%span.event_label{class: event.action_name}= event.action_name
issue
= link_to project_issue_path(event.project, event.issue) do
%strong= truncate event.issue_title
diff --git a/app/views/events/_event_last_push.html.haml b/app/views/events/_event_last_push.html.haml
index 212ef817e60..4ef927495ae 100644
--- a/app/views/events/_event_last_push.html.haml
+++ b/app/views/events/_event_last_push.html.haml
@@ -1,13 +1,13 @@
- if show_last_push_widget?(event)
.event_lp
%div
- = image_tag gravatar_icon(event.author_email), :class => "avatar"
+ = image_tag gravatar_icon(event.author_email), class: "avatar"
%span Your pushed to
= event.ref_type
- = link_to project_commits_path(event.project, :ref => event.ref_name) do
- %strong= truncate(event.ref_name, :length => 28)
+ = link_to project_commits_path(event.project, ref: event.ref_name) do
+ %strong= truncate(event.ref_name, length: 28)
at
%strong= link_to event.project.name, event.project
- = link_to new_mr_path_from_push_event(event), :title => "New Merge Request", :class => "btn very_small primary" do
+ = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn very_small primary" do
Create Merge Request
diff --git a/app/views/events/_event_merge_request.html.haml b/app/views/events/_event_merge_request.html.haml
index 774921a7f2a..ceb39371a3a 100644
--- a/app/views/events/_event_merge_request.html.haml
+++ b/app/views/events/_event_merge_request.html.haml
@@ -1,8 +1,8 @@
- if event.action_name == "merged"
.event_icon= image_tag "event_mr_merged.png"
-= image_tag gravatar_icon(event.author_email), :class => "avatar"
+= image_tag gravatar_icon(event.author_email), class: "avatar"
%strong #{event.author_name}
-%span.event_label{:class => event.action_name}= event.action_name
+%span.event_label{class: event.action_name}= event.action_name
merge request
= link_to project_merge_request_path(event.project, event.merge_request) do
%strong= truncate event.merge_request_title
diff --git a/app/views/events/_event_push.html.haml b/app/views/events/_event_push.html.haml
index 59d8962bb16..0adcaf9d10e 100644
--- a/app/views/events/_event_push.html.haml
+++ b/app/views/events/_event_push.html.haml
@@ -1,10 +1,10 @@
%div
.event_icon= image_tag "event_push.png"
- = image_tag gravatar_icon(event.author_email), :class => "avatar"
+ = image_tag gravatar_icon(event.author_email), class: "avatar"
%strong #{event.author_name}
%span.event_label.pushed= event.push_action_name
= event.ref_type
- = link_to project_commits_path(event.project, :ref => event.ref_name) do
+ = link_to project_commits_path(event.project, ref: event.ref_name) do
%strong= event.ref_name
at
%strong= link_to event.project.name, event.project
@@ -14,17 +14,17 @@
- if event.push_with_commits?
- if event.commits_count > 1
- = link_to compare_project_commits_path(event.project, :from => event.parent_commit.id, :to => event.last_commit.id) do
+ = link_to compare_project_commits_path(event.project, from: event.parent_commit.id, to: event.last_commit.id) do
%strong #{event.parent_commit.id[0..7]}...#{event.last_commit.id[0..7]}
- project = event.project
%ul.unstyled.event_commits
- if event.commits_count > 3
- event.commits[0...2].each do |commit|
- = render "events/commit", :commit => commit, :project => project
+ = render "events/commit", commit: commit, project: project
%li
%br
\... and #{event.commits_count - 2} more commits
- else
- event.commits.each do |commit|
- = render "events/commit", :commit => commit, :project => project
+ = render "events/commit", commit: commit, project: project
diff --git a/app/views/help/api.html.haml b/app/views/help/api.html.haml
index 4964c1bbd87..4f7af193741 100644
--- a/app/views/help/api.html.haml
+++ b/app/views/help/api.html.haml
@@ -1,16 +1,20 @@
%h3 API
.back_link
- = link_to help_path do
+ = link_to help_path do
&larr; to index
%hr
%ol
- %li
- %a{:href => "#README"} README
- %li
- %a{:href => "#projects"} Projects
- %li
- %a{:href => "#users"} Users
+ %li
+ %a{href: "#README"} README
+ %li
+ %a{href: "#projects"} Projects
+ %li
+ %a{href: "#snippets"} Snippets
+ %li
+ %a{href: "#users"} Users
+ %li
+ %a{href: "#issues"} Issues
.file_holder#README
.file_title
@@ -32,6 +36,16 @@
%br
+.file_holder#snippets
+ .file_title
+ %i.icon-file
+ Projects Snippets
+ .file_content.wiki
+ = preserve do
+ = markdown File.read(Rails.root.join("doc", "api", "snippets.md"))
+
+%br
+
.file_holder#users
.file_title
%i.icon-file
@@ -39,3 +53,13 @@
.file_content.wiki
= preserve do
= markdown File.read(Rails.root.join("doc", "api", "users.md"))
+
+%br
+
+.file_holder#issues
+ .file_title
+ %i.icon-file
+ Issues
+ .file_content.wiki
+ = preserve do
+ = markdown File.read(Rails.root.join("doc", "api", "issues.md"))
diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml
index b6c52712c4d..02549577282 100644
--- a/app/views/help/index.html.haml
+++ b/app/views/help/index.html.haml
@@ -24,4 +24,13 @@
%h5= link_to "Web Hooks", help_web_hooks_path
%li
+ %h5= link_to "System Hooks", help_system_hooks_path
+
+ %li
%h5= link_to "API", help_api_path
+
+ %li
+ %h5= link_to "Gitlab Markdown", help_markdown_path
+
+ %li
+ %h5= link_to "SSH keys", help_ssh_path
diff --git a/app/views/help/markdown.html.haml b/app/views/help/markdown.html.haml
new file mode 100644
index 00000000000..8d6fb2a590f
--- /dev/null
+++ b/app/views/help/markdown.html.haml
@@ -0,0 +1,25 @@
+- bash_lexer = Pygments::Lexer[:bash]
+%h3.page_title Gitlab Markdown
+.back_link
+ = link_to help_path do
+ &larr; to index
+%hr
+
+%p.slead We extend Markdown with some GITLAB specific syntax. It allows you to link to:
+
+%ul
+ %li issues (#123)
+ %li merge request (!123)
+ %li commits (1234567)
+ %li team members (@foo)
+ %li snippets ($123)
+
+%p.slead in
+
+%ul
+ %li commit messages
+ %li notes/comments/wall posts
+ %li issues
+ %li merge requests
+ %li milestones
+ %li wiki pages
diff --git a/app/views/help/permissions.html.haml b/app/views/help/permissions.html.haml
index 860cfc8669c..f9287fa0996 100644
--- a/app/views/help/permissions.html.haml
+++ b/app/views/help/permissions.html.haml
@@ -1,6 +1,6 @@
-%h3 Permissions
+%h3.page_title Permissions
.back_link
- = link_to help_path do
+ = link_to help_path do
&larr; to index
%hr
@@ -38,7 +38,6 @@
%li Push to non-protected branches
%li Remove non-protected branches
%li Add tags
- %li Create new merge request
%li Write a wiki
.ui-box.span3
@@ -55,7 +54,6 @@
%li Push to non-protected branches
%li Remove non-protected branches
%li Add tags
- %li Create new merge request
%li Write a wiki
%li Add new team members
%li Push to protected branches
diff --git a/app/views/help/ssh.html.haml b/app/views/help/ssh.html.haml
new file mode 100644
index 00000000000..6a5812040e7
--- /dev/null
+++ b/app/views/help/ssh.html.haml
@@ -0,0 +1,25 @@
+%h3.page_title SSH Keys
+.back_link
+ = link_to help_path do
+ &larr; to index
+%hr
+
+%p.slead
+ SSH key allows you to establish a secure connection between your computer and Gitlab
+
+%p.slead
+ To generate a new SSH key just open your terminal and use code below.
+
+%pre.dark
+ ssh-keygen -t rsa -C "#{current_user.email}"
+
+ \# Creates a new ssh key using the provided email
+ \# Generating public/private rsa key pair...
+
+%p.slead
+ Next just use code below to dump your public key and add to GITLAB SSH Keys
+
+%pre.dark
+ cat ~/.ssh/id_rsa.pub
+
+ \# ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6eNtGpNGwstc....
diff --git a/app/views/help/system_hooks.html.haml b/app/views/help/system_hooks.html.haml
new file mode 100644
index 00000000000..9fc8cbabf17
--- /dev/null
+++ b/app/views/help/system_hooks.html.haml
@@ -0,0 +1,13 @@
+%h3 System hooks
+.back_link
+ = link_to :back do
+ &larr; back
+%hr
+
+%p.slead
+ Your Gitlab instance can perform HTTP POST request on next event: create_project, delete_project, create_user, delete_user, change_team_member.
+ %br
+ System Hooks can be used for logging or change information in LDAP server.
+ %br
+%h5 Hooks request example:
+= render "admin/hooks/data_ex"
diff --git a/app/views/help/web_hooks.html.haml b/app/views/help/web_hooks.html.haml
index 3acea62cf90..263eadf6583 100644
--- a/app/views/help/web_hooks.html.haml
+++ b/app/views/help/web_hooks.html.haml
@@ -1,11 +1,11 @@
-%h3 Web hooks
+%h3.page_title Web hooks
.back_link
- = link_to help_path do
+ = link_to help_path do
&larr; to index
%hr
-%p.slead
- Every Gitlab project can trigger a web server whenever the repo is pushed to.
+%p.slead
+ Every Gitlab project can trigger a web server whenever the repo is pushed to.
%br
Web Hooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server.
%br
diff --git a/app/views/help/workflow.html.haml b/app/views/help/workflow.html.haml
index 7db8133b7f3..a3fe3b01d46 100644
--- a/app/views/help/workflow.html.haml
+++ b/app/views/help/workflow.html.haml
@@ -1,7 +1,6 @@
-- bash_lexer = Pygments::Lexer[:bash]
-%h3 Workflow
+%h3.page_title Workflow
.back_link
- = link_to help_path do
+ = link_to help_path do
&larr; to index
%hr
@@ -9,25 +8,25 @@
%li
%p Clone project
.bash
- %pre
+ %pre.dark
git clone git@example.com:project-name.git
%li
%p Create branch with your feature
.bash
- %pre
+ %pre.dark
git checkout -b $feature_name
%li
%p Write code. Commit changes
.bash
- %pre
+ %pre.dark
git commit -am "My feature is ready"
%li
%p Push your branch to gitlabhq
.bash
- %pre
+ %pre.dark
git push origin $feature_name
%li
diff --git a/app/views/hooks/index.html.haml b/app/views/hooks/index.html.haml
index 15699fc4390..3d2a381e746 100644
--- a/app/views/hooks/index.html.haml
+++ b/app/views/hooks/index.html.haml
@@ -6,9 +6,9 @@
Post receive hooks for binding events when someone push to repository.
%br
Read more about web hooks
- %strong #{link_to "here", help_web_hooks_path, :class => "vlink"}
+ %strong #{link_to "here", help_web_hooks_path, class: "vlink"}
-= form_for [@project, @hook], :as => :hook, :url => project_hooks_path(@project) do |f|
+= form_for [@project, @hook], as: :hook, url: project_hooks_path(@project), html: { class: 'form-inline' } do |f|
-if @hook.errors.any?
.alert-message.block-message.error
- @hook.errors.full_messages.each do |msg|
@@ -16,9 +16,9 @@
.clearfix
= f.label :url, "URL:"
.input
- = f.text_field :url, :class => "text_field xxlarge"
+ = f.text_field :url, class: "text_field xxlarge"
&nbsp;
- = f.submit "Add Web Hook", :class => "btn primary"
+ = f.submit "Add Web Hook", class: "btn primary"
%hr
-if @hooks.any?
@@ -36,7 +36,7 @@
%td
= link_to project_hook_path(@project, hook) do
%strong= hook.url
- = link_to 'Test Hook', test_project_hook_path(@project, hook), :class => "btn small right"
+ = link_to 'Test Hook', test_project_hook_path(@project, hook), class: "btn small right"
%td POST
%td
- = link_to 'Remove', project_hook_path(@project, hook), :confirm => 'Are you sure?', :method => :delete, :class => "danger btn small right"
+ = link_to 'Remove', project_hook_path(@project, hook), confirm: 'Are you sure?', method: :delete, class: "danger btn small right"
diff --git a/app/views/issues/_form.html.haml b/app/views/issues/_form.html.haml
index 4f6f8396661..1b67eabd5a5 100644
--- a/app/views/issues/_form.html.haml
+++ b/app/views/issues/_form.html.haml
@@ -1,6 +1,6 @@
%div.issue-form-holder
- %h3= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.id}"
- = form_for [@project, @issue], :remote => request.xhr? do |f|
+ %h3.page_title= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.id}"
+ = form_for [@project, @issue], remote: request.xhr? do |f|
-if @issue.errors.any?
.alert-message.block-message.error
%ul
@@ -9,48 +9,48 @@
.issue_form_box
.issue_title
.clearfix
- = f.label :title do
+ = f.label :title do
%strong= "Subject *"
.input
- = f.text_field :title, :maxlength => 255, :class => "xxlarge"
+ = f.text_field :title, maxlength: 255, class: "xxlarge"
.issue_middle_block
.issue_assignee
- = f.label :assignee_id do
+ = f.label :assignee_id do
%i.icon-user
Assign to
- .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select a user" })
+ .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select a user" })
.issue_milestone
- = f.label :milestone_id do
+ = f.label :milestone_id do
%i.icon-time
Milestone
- .input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { :include_blank => "Select milestone" })
+ .input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" })
.issue_description
.clearfix
- = f.label :label_list do
- %i.icon-tag
+ = f.label :label_list do
+ %i.icon-tag
Labels
.input
- = f.text_field :label_list, :maxlength => 2000, :class => "xxlarge"
+ = f.text_field :label_list, maxlength: 2000, class: "xxlarge"
%p.hint Separate with comma.
.clearfix
= f.label :description, "Details"
.input
- = f.text_area :description, :maxlength => 2000, :class => "xxlarge", :rows => 14
+ = f.text_area :description, maxlength: 2000, class: "xxlarge", rows: 14
%p.hint Markdown is enabled.
.actions
- if @issue.new_record?
- = f.submit 'Submit new issue', :class => "primary btn"
+ = f.submit 'Submit new issue', class: "primary btn"
-else
- = f.submit 'Save changes', :class => "primary btn"
+ = f.submit 'Save changes', class: "primary btn"
- if request.xhr?
- = link_to "Cancel", "#back", :onclick => "backToIssues();", :class => "btn"
+ = link_to "Cancel", "#back", onclick: "backToIssues();", class: "btn"
- else
- if @issue.new_record?
- = link_to "Cancel", project_issues_path(@project), :class => "btn"
+ = link_to "Cancel", project_issues_path(@project), class: "btn"
- else
- = link_to "Cancel", project_issue_path(@project, @issue), :class => "btn"
+ = link_to "Cancel", project_issue_path(@project, @issue), class: "btn"
diff --git a/app/views/issues/_head.html.haml b/app/views/issues/_head.html.haml
index 701b0625852..8ebe3e057bc 100644
--- a/app/views/issues/_head.html.haml
+++ b/app/views/issues/_head.html.haml
@@ -1,11 +1,14 @@
%ul.nav.nav-tabs
- %li{:class => "#{'active' if current_page?(project_issues_path(@project))}"}
- = link_to project_issues_path(@project), :class => "tab" do
+ %li{class: "#{'active' if current_page?(project_issues_path(@project))}"}
+ = link_to project_issues_path(@project), class: "tab" do
Browse Issues
- %li{:class => "#{'active' if current_page?(project_milestones_path(@project))}"}
- = link_to project_milestones_path(@project), :class => "tab" do
+ %li{class: "#{'active' if current_page?(project_milestones_path(@project))}"}
+ = link_to project_milestones_path(@project), class: "tab" do
Milestones
+ %li{class: "#{'active' if current_page?(project_labels_path(@project))}"}
+ = link_to project_labels_path(@project), class: "tab" do
+ Labels
%li.right
%span.rss-icon
- = link_to project_issues_path(@project, :atom, { :private_token => current_user.private_token }) do
- = image_tag "rss_ui.png", :title => "feed"
+ = link_to project_issues_path(@project, :atom, { private_token: current_user.private_token }) do
+ = image_tag "rss_ui.png", title: "feed"
diff --git a/app/views/issues/_issues.html.haml b/app/views/issues/_issues.html.haml
index 17141cc453c..f82ae8bde58 100644
--- a/app/views/issues/_issues.html.haml
+++ b/app/views/issues/_issues.html.haml
@@ -1,10 +1,10 @@
- @issues.each do |issue|
- = render(:partial => 'issues/show', :locals => {:issue => issue})
+ = render(partial: 'issues/show', locals: {issue: issue})
- if @issues.present?
%li.bottom
.row
- .span7= paginate @issues, :remote => true, :theme => "gitlab"
+ .span7= paginate @issues, remote: true, theme: "gitlab"
.span3.right
%span.cgray.right
%span.issue_counter #{@issues.total_count}
@@ -12,3 +12,4 @@
- else
%li
%h4.nothing_here_message Nothing to show here
+
diff --git a/app/views/issues/_show.html.haml b/app/views/issues/_show.html.haml
index e12c3c1a99c..8500cd40a6e 100644
--- a/app/views/issues/_show.html.haml
+++ b/app/views/issues/_show.html.haml
@@ -1,6 +1,7 @@
-%li.wll{ :id => dom_id(issue), :class => issue_css_classes(issue), :url => project_issue_path(issue.project, issue) }
- .list_legend
- .icon
+%li.wll{ id: dom_id(issue), class: issue_css_classes(issue), url: project_issue_path(issue.project, issue) }
+ - if controller.controller_name == 'issues'
+ .issue_check
+ = check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, class: "selected_issue", disabled: !can?(current_user, :modify_issue, issue)
.right
- issue.labels.each do |label|
%span.label.label-issue.grouped
@@ -12,20 +13,19 @@
= issue.notes.count
- 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 grouped reopen_issue", :remote => true
+ = link_to 'Reopen', project_issue_path(issue.project, issue, issue: {closed: false }, status_only: true), method: :put, class: "btn small grouped reopen_issue", remote: true
- else
- = link_to 'Resolve', project_issue_path(issue.project, issue, :issue => {:closed => true }, :status_only => true), :method => :put, :class => "success btn small grouped close_issue", :remote => true
- = link_to edit_project_issue_path(issue.project, issue), :class => "btn small edit-issue-link", :remote => true do
+ = link_to 'Resolve', project_issue_path(issue.project, issue, issue: {closed: true }, status_only: true), method: :put, class: "success btn small grouped close_issue", remote: true
+ = link_to edit_project_issue_path(issue.project, issue), class: "btn small edit-issue-link", remote: true do
%i.icon-edit
Edit
- if issue.assignee
- = image_tag gravatar_icon(issue.assignee_email), :class => "avatar"
+ = image_tag gravatar_icon(issue.assignee_email), class: "avatar"
- else
- = image_tag "no_avatar.png", :class => "avatar"
+ = image_tag "no_avatar.png", class: "avatar"
- = link_to project_issue_path(issue.project, issue) do
- %p.row_title= truncate(issue.title, :length => 100)
+ %p= link_to_gfm truncate(issue.title, length: 100), project_issue_path(issue.project, issue), class: "row_title"
%span.update-author
%small.cdark= "##{issue.id}"
@@ -35,4 +35,4 @@
&nbsp;
- if issue.upvotes > 0
- %span.badge.badge-success= "+#{issue.upvotes}" \ No newline at end of file
+ %span.badge.badge-success= "+#{issue.upvotes}"
diff --git a/app/views/issues/create.js.haml b/app/views/issues/create.js.haml
index abf3f6b858b..d90cbf0d30c 100644
--- a/app/views/issues/create.js.haml
+++ b/app/views/issues/create.js.haml
@@ -1,7 +1,7 @@
- if @issue.valid?
:plain
switchFromNewIssue();
- $("#issues-table").prepend("#{escape_javascript(render(:partial => 'show', :locals => {:issue => @issue}))}");
+ $("#issues-table").prepend("#{escape_javascript(render(partial: 'show', locals: {issue: @issue}))}");
$.ajax({type: "GET", url: location.href, dataType: "script"});
- else
:plain
diff --git a/app/views/issues/index.html.haml b/app/views/issues/index.html.haml
index fb8b9f8ee8e..a6836fd4fd1 100644
--- a/app/views/issues/index.html.haml
+++ b/app/views/issues/index.html.haml
@@ -6,43 +6,60 @@
.right
.span5
- if can? current_user, :write_issue, @project
- = link_to new_project_issue_path(@project), :class => "right btn small", :title => "New Issue", :remote => true do
+ = link_to new_project_issue_path(@project), class: "right btn small", title: "New Issue", remote: true do
+ %i.icon-plus
New Issue
- = 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' }
+ = 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 span3 right neib' }
+ = search_field_tag :issue_search, nil, { placeholder: 'Search', class: 'issue_search span3 right neib' }
.clearfix
+
%div#issues-table-holder.ui-box
.title
- .left
- %ul.nav.nav-pills.left
- %li{:class => ("active" if (params[:f] == issues_filter[:open] || !params[:f]))}
- = link_to project_issues_path(@project, :f => issues_filter[:open], :milestone_id => params[:milestone_id]) do
- Open
- %li{:class => ("active" if params[:f] == issues_filter[:closed])}
- = link_to project_issues_path(@project, :f => issues_filter[:closed], :milestone_id => params[:milestone_id]) do
- Closed
- %li{:class => ("active" if params[:f] == issues_filter[:to_me])}
- = link_to project_issues_path(@project, :f => issues_filter[:to_me], :milestone_id => params[:milestone_id]) do
- To Me
- %li{:class => ("active" if params[:f] == issues_filter[:all])}
- = link_to project_issues_path(@project, :f => issues_filter[:all], :milestone_id => params[:milestone_id]) do
- All
-
- .right
- = form_tag project_issues_path(@project), :method => :get, :class => :right do
- = select_tag(:label_name, options_for_select(issue_tags, params[:label_name]), :prompt => "Labels")
- = select_tag(:assignee_id, options_from_collection_for_select(@project.users.all, "id", "name", params[:assignee_id]), :prompt => "Assignee")
- = select_tag(:milestone_id, options_from_collection_for_select(@project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), :prompt => "Milestone")
- = hidden_field_tag :f, params[:f]
- .clearfix
-
+ = check_box_tag "check_all_issues", nil, false, class: "check_all_issues left"
+
+
+ .issues_bulk_update.hide
+ = form_tag bulk_update_project_issues_path(@project), method: :post do
+ %span.update_issues_text Update selected issues with &nbsp;
+ .left
+ = select_tag('update[status]', options_for_select(['open', 'closed']), prompt: "Status")
+ = select_tag('update[assignee_id]', options_from_collection_for_select(@project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee")
+ = select_tag('update[milestone_id]', options_from_collection_for_select(@project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone")
+ = hidden_field_tag 'update[issues_ids]', []
+ = hidden_field_tag :f, params[:f]
+ = button_tag "Save", class: "btn update_selected_issues"
+ .issues_filters
+ .left
+ %ul.nav.nav-pills.left
+ %li{class: ("active" if (params[:f] == issues_filter[:open] || !params[:f]))}
+ = link_to project_issues_path(@project, f: issues_filter[:open], milestone_id: params[:milestone_id]) do
+ Open
+ %li{class: ("active" if params[:f] == issues_filter[:closed])}
+ = link_to project_issues_path(@project, f: issues_filter[:closed], milestone_id: params[:milestone_id]) do
+ Closed
+ %li{class: ("active" if params[:f] == issues_filter[:to_me])}
+ = link_to project_issues_path(@project, f: issues_filter[:to_me], milestone_id: params[:milestone_id]) do
+ To Me
+ %li{class: ("active" if params[:f] == issues_filter[:all])}
+ = link_to project_issues_path(@project, f: issues_filter[:all], milestone_id: params[:milestone_id]) do
+ All
+
+ .right
+ = form_tag project_issues_path(@project), method: :get, class: :right do
+ = select_tag(:label_name, options_for_select(issue_tags, params[:label_name]), prompt: "Labels")
+ = select_tag(:assignee_id, options_from_collection_for_select([unassigned_filter] + @project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee")
+ = select_tag(:milestone_id, options_from_collection_for_select([unassigned_filter] + @project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone")
+ = hidden_field_tag :f, params[:f]
+ .clearfix
+
%ul#issues-table.unstyled.issues_table
= render "issues"
+
:javascript
$(function(){
issuesPage();
- }) \ No newline at end of file
+ })
diff --git a/app/views/issues/show.html.haml b/app/views/issues/show.html.haml
index 8ffc9c2b662..dce8cf6a59d 100644
--- a/app/views/issues/show.html.haml
+++ b/app/views/issues/show.html.haml
@@ -8,11 +8,11 @@
%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 small"
+ = link_to 'Reopen', project_issue_path(@project, @issue, issue: {closed: false }, status_only: true), method: :put, class: "btn small"
- else
- = link_to 'Close', project_issue_path(@project, @issue, :issue => {:closed => true }, :status_only => true), :method => :put, :class => "btn small", :title => "Close Issue"
+ = link_to 'Close', project_issue_path(@project, @issue, issue: {closed: true }, status_only: true), method: :put, class: "btn small", title: "Close Issue"
- if can?(current_user, :admin_project, @project) || @issue.author == current_user
- = link_to edit_project_issue_path(@project, @issue), :class => "btn small" do
+ = link_to edit_project_issue_path(@project, @issue), class: "btn small" do
%i.icon-edit
Edit
@@ -31,24 +31,22 @@
.alert-message.error.status_info Closed
- else
.alert-message.success.status_info Open
- = @issue.title
+ = gfm @issue.title
.middle_box_content
%cite.cgray Created by
- = image_tag gravatar_icon(@issue.author_email), :width => 16, :class => "lil_av"
+ = image_tag gravatar_icon(@issue.author_email), width: 16, class: "lil_av"
%strong.author= link_to_issue_author(@issue)
- if @issue.assignee
%cite.cgray and currently assigned to
- = image_tag gravatar_icon(@issue.assignee_email), :width => 16, :class => "lil_av"
+ = image_tag gravatar_icon(@issue.assignee_email), width: 16, class: "lil_av"
%strong.author= link_to_issue_assignee(@issue)
- if @issue.milestone
- milestone = @issue.milestone
%cite.cgray and attached to milestone
- = link_to project_milestone_path(milestone.project, milestone) do
- %strong
- = truncate(milestone.title, :length => 20)
+ %strong= link_to_gfm truncate(milestone.title, length: 20), project_milestone_path(milestone.project, milestone)
.right
- @issue.labels.each do |label|
@@ -63,4 +61,4 @@
= markdown @issue.description
-.issue_notes#notes= render "notes/notes", :tid => @issue.id, :tt => "issue"
+.issue_notes#notes= render "notes/notes", tid: @issue.id, tt: "issue"
diff --git a/app/views/kaminari/admin/_first_page.html.haml b/app/views/kaminari/admin/_first_page.html.haml
index fee8112f6af..41c9c0b3af6 100644
--- a/app/views/kaminari/admin/_first_page.html.haml
+++ b/app/views/kaminari/admin/_first_page.html.haml
@@ -6,4 +6,4 @@
-# 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
+ = link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, remote: remote
diff --git a/app/views/kaminari/admin/_last_page.html.haml b/app/views/kaminari/admin/_last_page.html.haml
index 6e41d232b51..b03a206224c 100644
--- a/app/views/kaminari/admin/_last_page.html.haml
+++ b/app/views/kaminari/admin/_last_page.html.haml
@@ -6,4 +6,4 @@
-# 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}
+ = link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, {remote: remote}
diff --git a/app/views/kaminari/admin/_next_page.html.haml b/app/views/kaminari/admin/_next_page.html.haml
index 76f40e72373..00c5f0b6f4e 100644
--- a/app/views/kaminari/admin/_next_page.html.haml
+++ b/app/views/kaminari/admin/_next_page.html.haml
@@ -6,4 +6,4 @@
-# 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
+ = link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote
diff --git a/app/views/kaminari/admin/_page.html.haml b/app/views/kaminari/admin/_page.html.haml
index 5966812934f..a52d883b9a8 100644
--- a/app/views/kaminari/admin/_page.html.haml
+++ b/app/views/kaminari/admin/_page.html.haml
@@ -6,5 +6,5 @@
-# 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}
+%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/admin/_prev_page.html.haml b/app/views/kaminari/admin/_prev_page.html.haml
index cef885ee0af..f673abdb3ae 100644
--- a/app/views/kaminari/admin/_prev_page.html.haml
+++ b/app/views/kaminari/admin/_prev_page.html.haml
@@ -5,5 +5,5 @@
-# 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
+%li{class: "prev" }
+ = link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote
diff --git a/app/views/kaminari/gitlab/_first_page.html.haml b/app/views/kaminari/gitlab/_first_page.html.haml
index fee8112f6af..41c9c0b3af6 100644
--- a/app/views/kaminari/gitlab/_first_page.html.haml
+++ b/app/views/kaminari/gitlab/_first_page.html.haml
@@ -6,4 +6,4 @@
-# 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
+ = link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, remote: remote
diff --git a/app/views/kaminari/gitlab/_last_page.html.haml b/app/views/kaminari/gitlab/_last_page.html.haml
index 6e41d232b51..b03a206224c 100644
--- a/app/views/kaminari/gitlab/_last_page.html.haml
+++ b/app/views/kaminari/gitlab/_last_page.html.haml
@@ -6,4 +6,4 @@
-# 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}
+ = link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, {remote: remote}
diff --git a/app/views/kaminari/gitlab/_next_page.html.haml b/app/views/kaminari/gitlab/_next_page.html.haml
index e87ab4e0534..296cceb080b 100644
--- a/app/views/kaminari/gitlab/_next_page.html.haml
+++ b/app/views/kaminari/gitlab/_next_page.html.haml
@@ -6,4 +6,4 @@
-# per_page: number of items to fetch per page
-# remote: data-remote
%span.next
- = link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, :rel => 'next', :remote => remote
+ = link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote
diff --git a/app/views/kaminari/gitlab/_page.html.haml b/app/views/kaminari/gitlab/_page.html.haml
index 528bba8f116..19456dcc058 100644
--- a/app/views/kaminari/gitlab/_page.html.haml
+++ b/app/views/kaminari/gitlab/_page.html.haml
@@ -6,5 +6,5 @@
-# num_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
-%span{:class => "page#{' current' if page.current?}"}
- = link_to_unless page.current?, page, url, {:remote => remote, :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil}
+%span{class: "page#{' current' if page.current?}"}
+ = link_to_unless page.current?, page, url, {remote: remote, rel: page.next? ? 'next' : page.prev? ? 'prev' : nil}
diff --git a/app/views/kaminari/gitlab/_prev_page.html.haml b/app/views/kaminari/gitlab/_prev_page.html.haml
index 13f0d8adec5..5c2061690ac 100644
--- a/app/views/kaminari/gitlab/_prev_page.html.haml
+++ b/app/views/kaminari/gitlab/_prev_page.html.haml
@@ -6,4 +6,4 @@
-# per_page: number of items to fetch per page
-# remote: data-remote
%span.prev
- = link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, :rel => 'prev', :remote => remote
+ = 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 c25e8d073b8..9c6e229bf49 100644
--- a/app/views/keys/_form.html.haml
+++ b/app/views/keys/_form.html.haml
@@ -11,8 +11,14 @@
.input= f.text_field :title
.clearfix
= f.label :key
- .input= f.text_area :key, :class => [:xxlarge, :thin_area]
+ .input
+ = f.text_area :key, class: [:xxlarge, :thin_area]
+ %p.hint
+ Paste your public key here. Read more about how generate it
+ = link_to "here", help_ssh_path
+
+
.actions
- = f.submit 'Save', :class => "primary btn"
- = link_to "Cancel", keys_path, :class => "btn"
+ = 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 7035e609f2c..a0af8eea44c 100644
--- a/app/views/keys/_show.html.haml
+++ b/app/views/keys/_show.html.haml
@@ -9,5 +9,5 @@
= 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"
+ = link_to 'Remove', key, confirm: 'Are you sure?', method: :delete, class: "btn small danger delete-key right"
diff --git a/app/views/keys/create.js.haml b/app/views/keys/create.js.haml
index b0d7f528be1..1dccf6fdb91 100644
--- a/app/views/keys/create.js.haml
+++ b/app/views/keys/create.js.haml
@@ -1,7 +1,7 @@
- if @key.valid?
:plain
$("#new_key_dialog").dialog("close");
- $("#keys-table .data").append("#{escape_javascript(render(:partial => 'show', :locals => {:key => @key}))}");
+ $("#keys-table .data").append("#{escape_javascript(render(partial: 'show', locals: {key: @key}))}");
$("#no_ssh_key_defined").hide();
- else
:plain
diff --git a/app/views/keys/index.html.haml b/app/views/keys/index.html.haml
index 35cda178242..04e9e4cbc33 100644
--- a/app/views/keys/index.html.haml
+++ b/app/views/keys/index.html.haml
@@ -1,6 +1,6 @@
%h3.page_title
SSH Keys
- = link_to "Add new", new_key_path, :class => "btn small right"
+ = link_to "Add new", new_key_path, class: "btn small right"
%hr
%p.slead
@@ -14,9 +14,9 @@
%th Added
%th
- @keys.each do |key|
- = render(:partial => 'show', :locals => {:key => key})
+ = render(partial: 'show', locals: {key: key})
- if @keys.blank?
%tr
- %td{:colspan => 3}
+ %td{colspan: 3}
%h3.nothing_here_message There are no SSH keys with access to your account.
diff --git a/app/views/keys/new.html.haml b/app/views/keys/new.html.haml
index 02e782b9f85..fff3805890e 100644
--- a/app/views/keys/new.html.haml
+++ b/app/views/keys/new.html.haml
@@ -1,4 +1,4 @@
-%h3.page_title New key
+%h3.page_title Add an SSH Key
%hr
= render 'form'
diff --git a/app/views/keys/show.html.haml b/app/views/keys/show.html.haml
index 79f51257fd9..ffd52b96e5a 100644
--- a/app/views/keys/show.html.haml
+++ b/app/views/keys/show.html.haml
@@ -11,4 +11,4 @@
%pre= @key.key
.actions
- = link_to 'Remove', @key, :confirm => 'Are you sure?', :method => :delete, :class => "btn danger delete-key"
+ = link_to 'Remove', @key, confirm: 'Are you sure?', method: :delete, class: "btn danger delete-key"
diff --git a/app/views/labels/_label.html.haml b/app/views/labels/_label.html.haml
new file mode 100644
index 00000000000..32158c20adc
--- /dev/null
+++ b/app/views/labels/_label.html.haml
@@ -0,0 +1,4 @@
+%li.wll
+ %strong= label.name
+ .right
+ %span= pluralize label.count, 'issue'
diff --git a/app/views/labels/index.html.haml b/app/views/labels/index.html.haml
new file mode 100644
index 00000000000..4e41d375d6a
--- /dev/null
+++ b/app/views/labels/index.html.haml
@@ -0,0 +1,14 @@
+= render "issues/head"
+
+%h3.page_title
+ Labels
+%br
+%div.ui-box
+ %ul.unstyled.labels-table
+ - @labels.each do |label|
+ = render 'label', label: label
+
+ - unless @labels.present?
+ %li
+ %h3.nothing_here_message Nothing to show here
+
diff --git a/app/views/layouts/_app_menu.html.haml b/app/views/layouts/_app_menu.html.haml
index 6575ee99168..025314891f8 100644
--- a/app/views/layouts/_app_menu.html.haml
+++ b/app/views/layouts/_app_menu.html.haml
@@ -1,19 +1,19 @@
%ul.main_menu
- %li.home{:class => tab_class(:root)}
- = link_to "Home", root_path, :title => "Home"
+ %li.home{class: tab_class(:root)}
+ = link_to "Home", root_path, title: "Home"
- %li{:class => tab_class(:dash_issues)}
+ %li{class: tab_class(:dash_issues)}
= link_to dashboard_issues_path do
Issues
%span.count= current_user.assigned_issues.opened.count
- %li{:class => tab_class(:dash_mr)}
+ %li{class: tab_class(:dash_mr)}
= link_to dashboard_merge_requests_path do
Merge Requests
%span.count= current_user.cared_merge_requests.count
- %li{:class => tab_class(:search)}
+ %li{class: tab_class(:search)}
= link_to "Search", search_path
- %li{:class => tab_class(:help)}
+ %li{class: tab_class(:help)}
= link_to "Help", help_path
diff --git a/app/views/layouts/_flash.html.haml b/app/views/layouts/_flash.html.haml
index 2e40f0a6281..86564ad7110 100644
--- a/app/views/layouts/_flash.html.haml
+++ b/app/views/layouts/_flash.html.haml
@@ -1,6 +1,6 @@
- if alert || notice
- text = alert || notice
- %div{:style => "display:none", :id => "flash_container"}
+ %div{style: "display:none", id: "flash_container"}
%center
%h4= text
:javascript
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index e609557b17a..c076a3a1b45 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -1,18 +1,17 @@
%head
- %meta{:charset => "utf-8"}
+ %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 controller_name == 'projects' && action_name == 'index'
- = auto_discovery_link_tag :atom, projects_url(:atom, :private_token => current_user.private_token), :title => "Dashboard feed"
+ = auto_discovery_link_tag :atom, projects_url(:atom, private_token: current_user.private_token), title: "Dashboard 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}")
+ = 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")
+ = 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 9e019021c89..d6247d36b0d 100644
--- a/app/views/layouts/_head_panel.html.haml
+++ b/app/views/layouts/_head_panel.html.haml
@@ -3,30 +3,30 @@
.container
.top_panel_content
%div.app_logo
- = link_to root_path, :class => "home", :title => "Home" do
+ = link_to root_path, class: "home", title: "Home" do
%h1
GITLAB
%span.separator
%h1.project_name= title
.search
- = form_tag search_path, :method => :get do |f|
- = text_field_tag "search", nil, :placeholder => "Search", :class => "search-input"
+ = form_tag search_path, method: :get do |f|
+ = text_field_tag "search", nil, placeholder: "Search", class: "search-input"
.fbtn
- if current_user.is_admin?
- = link_to admin_root_path, :class => "btn small", :title => "Admin area" do
+ = link_to admin_root_path, class: "btn small", title: "Admin area" do
%i.icon-cog
Admin
- if current_user.can_create_project?
- = link_to new_project_path, :class => "btn small", :title => "Create New Project" do
+ = link_to new_project_path, class: "btn small", title: "Create New Project" do
%i.icon-plus
Project
.account-box
- = link_to profile_path, :class => "pic" do
+ = link_to profile_path, class: "pic" do
= image_tag gravatar_icon(current_user.email)
.account-links
- = link_to profile_path, :class => "username" do
+ = link_to profile_path, class: "username" do
My profile
- = link_to 'Logout', destroy_user_session_path, :class => "logout", :method => :delete
+ = link_to 'Logout', destroy_user_session_path, class: "logout", method: :delete
:javascript
$(function(){
diff --git a/app/views/layouts/_project_menu.html.haml b/app/views/layouts/_project_menu.html.haml
index 3f58fc5a664..04eaec5accc 100644
--- a/app/views/layouts/_project_menu.html.haml
+++ b/app/views/layouts/_project_menu.html.haml
@@ -1,37 +1,37 @@
%ul.main_menu
- %li.home{:class => project_tab_class}
- = link_to @project.code, project_path(@project), :title => "Project"
+ %li.home{class: project_tab_class}
+ = link_to @project.code, project_path(@project), title: "Project"
- if @project.repo_exists?
- if can? current_user, :download_code, @project
- %li{:class => tree_tab_class}
+ %li{class: tree_tab_class}
= link_to tree_project_ref_path(@project, @project.root_ref) do
Files
- %li{:class => commit_tab_class}
+ %li{class: commit_tab_class}
= link_to "Commits", project_commits_path(@project)
- %li{:class => tab_class(:network)}
+ %li{class: tab_class(:network)}
= link_to "Network", graph_project_path(@project)
- if @project.issues_enabled
- %li{:class => tab_class(:issues)}
+ %li{class: tab_class(:issues)}
= link_to project_issues_filter_path(@project) do
Issues
%span.count.issue_counter= @project.issues.opened.count
- if @project.repo_exists?
- if @project.merge_requests_enabled
- %li{:class => tab_class(:merge_requests)}
+ %li{class: tab_class(:merge_requests)}
= link_to project_merge_requests_path(@project) do
Merge Requests
%span.count.merge_counter= @project.merge_requests.opened.count
- if @project.wall_enabled
- %li{:class => tab_class(:wall)}
+ %li{class: tab_class(:wall)}
= link_to wall_project_path(@project) do
Wall
- if @project.wiki_enabled
- %li{:class => tab_class(:wiki)}
+ %li{class: tab_class(:wiki)}
= link_to project_wiki_path(@project, :index) do
Wiki
diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml
index 8de25821ee7..6af0f641fc4 100644
--- a/app/views/layouts/admin.html.haml
+++ b/app/views/layouts/admin.html.haml
@@ -1,22 +1,22 @@
!!! 5
-%html{ :lang => "en"}
+%html{ lang: "en"}
= render "layouts/head"
- %body{:class => "#{app_theme} admin"}
+ %body{class: "#{app_theme} admin"}
= render "layouts/flash"
- = render "layouts/head_panel", :title => "Admin area"
+ = render "layouts/head_panel", title: "Admin area"
.container
%ul.main_menu
- %li.home{:class => tab_class(:admin_root)}
+ %li.home{class: tab_class(:admin_root)}
= link_to "Stats", admin_root_path
- %li{:class => tab_class(:admin_projects)}
+ %li{class: tab_class(:admin_projects)}
= link_to "Projects", admin_projects_path
- %li{:class => tab_class(:admin_users)}
+ %li{class: tab_class(:admin_users)}
= link_to "Users", admin_users_path
- %li{:class => tab_class(:admin_logs)}
+ %li{class: tab_class(:admin_logs)}
= link_to "Logs", admin_logs_path
- %li{:class => tab_class(:admin_emails)}
- = link_to "Emails", admin_emails_path
- %li{:class => tab_class(:admin_resque)}
+ %li{class: tab_class(:admin_hooks)}
+ = link_to "Hooks", admin_hooks_path
+ %li{class: tab_class(:admin_resque)}
= link_to "Resque", admin_resque_path
.content= yield
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 0d5d829e00d..dda10d5d137 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -1,10 +1,10 @@
!!! 5
-%html{ :lang => "en"}
+%html{ lang: "en"}
= render "layouts/head"
- %body{:class => "#{app_theme} application"}
+ %body{class: "#{app_theme} application"}
= render "layouts/flash"
- = render "layouts/head_panel", :title => "Dashboard"
+ = render "layouts/head_panel", title: "Dashboard"
.container
- = render :partial => "layouts/app_menu"
+ = render partial: "layouts/app_menu"
.content
= yield
diff --git a/app/views/layouts/devise_layout.html.haml b/app/views/layouts/devise_layout.html.haml
index c293734b368..70c4f007ba1 100644
--- a/app/views/layouts/devise_layout.html.haml
+++ b/app/views/layouts/devise_layout.html.haml
@@ -1,6 +1,6 @@
!!! 5
-%html{ :lang => "en"}
+%html{ lang: "en"}
= render "layouts/head"
%body.ui_basic.login-page
- = render :partial => "layouts/flash"
+ = render partial: "layouts/flash"
.container= yield
diff --git a/app/views/layouts/error.html.haml b/app/views/layouts/error.html.haml
index 943dbe778c4..1f5c03bdced 100644
--- a/app/views/layouts/error.html.haml
+++ b/app/views/layouts/error.html.haml
@@ -1,10 +1,10 @@
!!! 5
-%html{ :lang => "en"}
+%html{ lang: "en"}
= render "layouts/head"
- %body{:class => "#{app_theme} application"}
+ %body{class: "#{app_theme} application"}
= render "layouts/flash"
- = render "layouts/head_panel", :title => ""
+ = render "layouts/head_panel", title: ""
.container
.content
- %br
- %h3= yield
+ %center.padded.prepend-top-20
+ = yield
diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml
index 0cef736c80a..a1938df43a1 100644
--- a/app/views/layouts/notify.html.haml
+++ b/app/views/layouts/notify.html.haml
@@ -1,6 +1,6 @@
-%html{:lang => "en"}
+%html{lang: "en"}
%head
- %meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"}
+ %meta{content: "text/html; charset=utf-8", "http-equiv" => "Content-Type"}
%title
gitlabhq
:css
@@ -11,26 +11,29 @@
.content a {color: #0eb6ce; text-decoration: none;}
.footer p {font-size: 11px; color:#7d7a7a; margin: 0; padding: 0; font-family: Helvetica, Arial, sans-serif;}
.footer a {color: #0eb6ce; text-decoration: none;}
- %body{:bgcolor => "#EAEAEA", :style => "margin: 0; padding: 0; background: #EAEAEA"}
- %table{:align => "center", :border => "0", :cellpadding => "0", :cellspacing => "0", :style => "padding: 35px 0; background: #EAEAEA;", :width => "100%"}
+ %body{bgcolor: "#EAEAEA", style: "margin: 0; padding: 0; background: #EAEAEA"}
+ %table{align: "center", border: "0", cellpadding: "0", cellspacing: "0", style: "padding: 35px 0; background: #EAEAEA;", width: "100%"}
%tr
- %td{:align => "center", :style => "margin: 0; padding: 0; background: #EAEAEA;"}
- %table.header{:align => "center", :border => "0", :cellpadding => "0", :cellspacing => "0", :style => "font-family: Helvetica, Arial, sans-serif; background:#333", :width => "600"}
+ %td{align: "center", style: "margin: 0; padding: 0; background: #EAEAEA;"}
+ %table.header{align: "center", border: "0", cellpadding: "0", cellspacing: "0", style: "font-family: Helvetica, Arial, sans-serif; background:#333", width: "600"}
%tr
- %td{:style => "font-size: 0px;", :width => "20"}
+ %td{style: "font-size: 0px;", width: "20"}
\ 
- %td{:align => "left", :style => "padding: 18px 0 10px;", :width => "580"}
- %h1{:style => "color: #BBBBBB; font: normal 32px Helvetica, Arial, sans-serif; margin: 0; padding: 0; line-height: 40px;"}
+ %td{align: "left", style: "padding: 18px 0 10px;", width: "580"}
+ %h1{style: "color: #BBBBBB; font: normal 32px Helvetica, Arial, sans-serif; margin: 0; padding: 0; line-height: 40px;"}
gitlab
- if @project
| #{@project.name}
- %table{:align => "center", :bgcolor => "#fff", :border => "0", :cellpadding => "0", :cellspacing => "0", :style => "font-family: Helvetica, Arial, sans-serif; background: #fff;", :width => "600"}
+ %table{align: "center", bgcolor: "#fff", border: "0", cellpadding: "0", cellspacing: "0", style: "font-family: Helvetica, Arial, sans-serif; background: #fff;", width: "600"}
%tr= yield
%tr
- %td{:align => "left", :colspan => "2", :height => "3", :style => "padding: font-size: 0; line-height: 0; height: 3px;", :width => "600"}
- %table.footer{:align => "center", :border => "0", :cellpadding => "0", :cellspacing => "0", :style => "font-family: Helvetica, Arial, sans-serif; line-height: 10px;", :width => "600"}
+ %td{align: "left", colspan: "2", height: "3", style: "padding: font-size: 0; line-height: 0; height: 3px;", width: "600"}
+ %table.footer{align: "center", border: "0", cellpadding: "0", cellspacing: "0", style: "font-family: Helvetica, Arial, sans-serif; line-height: 10px;", width: "600"}
%tr
- %td{:align => "center", :style => "padding: 5px 0 10px; font-size: 11px; color:#7d7a7a; margin: 0; line-height: 1.2;font-family: Helvetica, Arial, sans-serif;", :valign => "top"}
+ %td{align: "center", style: "padding: 5px 0 10px; font-size: 11px; color:#7d7a7a; margin: 0; line-height: 1.2;font-family: Helvetica, Arial, sans-serif;", valign: "top"}
%br
- %p{:style => "font-size: 11px; color:#7d7a7a; margin: 0; padding: 0; font-family: Helvetica, Arial, sans-serif;"}
- You're receiving this newsletter because you are in project team.
+ %p{style: "font-size: 11px; color:#7d7a7a; margin: 0; padding: 0; font-family: Helvetica, Arial, sans-serif;"}
+ You're receiving this notification because you are a member of the
+ - if @project
+ #{@project.name}
+ project team.
diff --git a/app/views/layouts/profile.html.haml b/app/views/layouts/profile.html.haml
index dfe48d68240..b624415dfe1 100644
--- a/app/views/layouts/profile.html.haml
+++ b/app/views/layouts/profile.html.haml
@@ -1,27 +1,28 @@
!!! 5
-%html{ :lang => "en"}
+%html{ lang: "en"}
= render "layouts/head"
- %body{:class => "#{app_theme} profile"}
+ %body{class: "#{app_theme} profile"}
= render "layouts/flash"
- = render "layouts/head_panel", :title => "Profile"
+ = render "layouts/head_panel", title: "Profile"
.container
%ul.main_menu
- %li.home{:class => tab_class(:profile)}
+ %li.home{class: tab_class(:profile)}
= link_to "Profile", profile_path
- %li{:class => tab_class(:password)}
+ %li{class: tab_class(:password)}
= link_to "Password", profile_password_path
- %li{:class => tab_class(:token)}
+ %li{class: tab_class(:ssh_keys)}
+ = link_to keys_path do
+ SSH Keys
+ %span.count= current_user.keys.count
+
+ %li{class: tab_class(:token)}
= link_to "Token", profile_token_path
- %li{:class => tab_class(:design)}
+ %li{class: tab_class(:design)}
= link_to "Design", profile_design_path
- %li{:class => tab_class(:ssh_keys)}
- = link_to keys_path do
- SSH Keys
- %span.count= current_user.keys.count
.content
= yield
diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml
index d9843c65fce..56a947d2a9d 100644
--- a/app/views/layouts/project.html.haml
+++ b/app/views/layouts/project.html.haml
@@ -1,11 +1,11 @@
!!! 5
-%html{ :lang => "en"}
+%html{ lang: "en"}
= render "layouts/head"
- %body{:class => "#{app_theme} project"}
+ %body{class: "#{app_theme} project"}
= render "layouts/flash"
- = render "layouts/head_panel", :title => @project.name
+ = render "layouts/head_panel", title: @project.name
.container
- = render :partial => "layouts/project_menu"
+ = render partial: "layouts/project_menu"
.content
= yield
diff --git a/app/views/merge_requests/_form.html.haml b/app/views/merge_requests/_form.html.haml
index 4f20a06fd25..b6c12397d6c 100644
--- a/app/views/merge_requests/_form.html.haml
+++ b/app/views/merge_requests/_form.html.haml
@@ -1,4 +1,4 @@
-= form_for [@project, @merge_request], :html => { :class => "new_merge_request form-horizontal" } do |f|
+= form_for [@project, @merge_request], html: { class: "new_merge_request form-horizontal" } do |f|
-if @merge_request.errors.any?
.alert-message.block-message.error
%ul
@@ -14,9 +14,9 @@
%h5 From (Head Branch)
.body
.padded
- = f.label :source_branch, "From", :class => "control-label"
+ = f.label :source_branch, "From", class: "control-label"
.controls
- = f.select(:source_branch, @project.heads.map(&:name), { :include_blank => "Select branch" }, :style => "width:250px")
+ = f.select(:source_branch, @project.heads.map(&:name), { include_blank: "Select branch" }, style: "width:250px")
.bottom_commit
.mr_source_commit
@@ -25,9 +25,9 @@
%h5 To (Base Branch)
.body
.padded
- = f.label :target_branch, "To", :class => "control-label"
+ = f.label :target_branch, "To", class: "control-label"
.controls
- = f.select(:target_branch, @project.heads.map(&:name), { :include_blank => "Select branch" }, :style => "width:250px")
+ = f.select(:target_branch, @project.heads.map(&:name), { include_blank: "Select branch" }, style: "width:250px")
.bottom_commit
.mr_target_commit
@@ -38,22 +38,22 @@
.top_box_content
= f.label :title do
%strong= "Title *"
- .input= f.text_field :title, :class => "input-xxlarge pad", :maxlength => 255, :rows => 5
+ .input= f.text_field :title, class: "input-xxlarge pad", maxlength: 255, rows: 5
.middle_box_content
= f.label :assignee_id do
%i.icon-user
Assign to
- .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { :include_blank => "Select user" }, :style => "width:250px")
+ .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, style: "width:250px")
.control-group
.form-actions
- = f.submit 'Save', :class => "btn-primary btn"
+ = f.submit 'Save', class: "btn-primary btn"
- if @merge_request.new_record?
- = link_to project_merge_requests_path(@project), :class => "btn" do
+ = link_to project_merge_requests_path(@project), class: "btn" do
Cancel
- else
- = link_to project_merge_request_path(@project, @merge_request), :class => "btn" do
+ = link_to project_merge_request_path(@project, @merge_request), class: "btn" do
Cancel
diff --git a/app/views/merge_requests/_head.html.haml b/app/views/merge_requests/_head.html.haml
index c578c794060..35a86e6511c 100644
--- a/app/views/merge_requests/_head.html.haml
+++ b/app/views/merge_requests/_head.html.haml
@@ -1,5 +1,5 @@
.top-tabs
- = link_to project_merge_requests_path(@project), :class => "tab #{'active' if current_page?(project_merge_requests_path(@project)) }" do
+ = link_to project_merge_requests_path(@project), class: "tab #{'active' if current_page?(project_merge_requests_path(@project)) }" do
%span
Merge Requests
diff --git a/app/views/merge_requests/_merge_request.html.haml b/app/views/merge_requests/_merge_request.html.haml
index b9a005e08be..7499609066a 100644
--- a/app/views/merge_requests/_merge_request.html.haml
+++ b/app/views/merge_requests/_merge_request.html.haml
@@ -1,4 +1,4 @@
-%li.wll{ :class => mr_css_classes(merge_request) }
+%li.wll{ class: mr_css_classes(merge_request) }
.right
.left
- if merge_request.merged?
@@ -14,10 +14,9 @@
= merge_request.source_branch
&rarr;
= merge_request.target_branch
- = image_tag gravatar_icon(merge_request.author_email), :class => "avatar"
+ = image_tag gravatar_icon(merge_request.author_email), class: "avatar"
- = link_to project_merge_request_path(merge_request.project, merge_request) do
- %p.row_title= truncate(merge_request.title, :length => 80)
+ %p= link_to_gfm truncate(merge_request.title, length: 80), project_merge_request_path(merge_request.project, merge_request), class: "row_title"
%span.update-author
%small.cdark= "##{merge_request.id}"
diff --git a/app/views/merge_requests/_show.html.haml b/app/views/merge_requests/_show.html.haml
index c0b3dd9f5aa..f1b3fa9fe98 100644
--- a/app/views/merge_requests/_show.html.haml
+++ b/app/views/merge_requests/_show.html.haml
@@ -7,16 +7,16 @@
- if @commits.present?
%ul.nav.nav-tabs.mr_nav_tabs
%li
- = link_to "#notes", "data-url" => project_merge_request_path(@project, @merge_request), :class => "merge-notes-tab tab" do
+ = link_to "#notes", "data-url" => project_merge_request_path(@project, @merge_request), class: "merge-notes-tab tab" do
%i.icon-comment
Comments
%li
- = link_to "#diffs", "data-url" => diffs_project_merge_request_path(@project, @merge_request), :class => "merge-diffs-tab tab" do
+ = link_to "#diffs", "data-url" => diffs_project_merge_request_path(@project, @merge_request), class: "merge-diffs-tab tab" do
%i.icon-list-alt
Diff
-.merge_request_notes#notes{ :class => (controller.action_name == 'show') ? "" : "hide" }
- = render("notes/notes", :tid => @merge_request.id, :tt => "merge_request")
+.merge_request_notes#notes{ class: (controller.action_name == 'show') ? "" : "hide" }
+ = render("notes/notes", tid: @merge_request.id, tt: "merge_request")
.merge-request-diffs
= render "merge_requests/show/diffs" if @diffs
.status
@@ -33,7 +33,8 @@
});
$(".edit_merge_request").live("ajax:beforeSend", function() {
- $(this).replaceWith('#{image_tag "ajax_loader.gif"}');
+ $('.can_be_merged').hide();
+ $('.merge_in_progress').show();
})
})
diff --git a/app/views/merge_requests/branch_from.js.haml b/app/views/merge_requests/branch_from.js.haml
index 3e278015b49..156b4f0dc73 100644
--- a/app/views/merge_requests/branch_from.js.haml
+++ b/app/views/merge_requests/branch_from.js.haml
@@ -1,2 +1,2 @@
:plain
- $(".mr_source_commit").html("#{escape_javascript(render 'commits/commit', :commit => @commit)}");
+ $(".mr_source_commit").html("#{escape_javascript(render 'commits/commit', commit: @commit)}");
diff --git a/app/views/merge_requests/branch_to.js.haml b/app/views/merge_requests/branch_to.js.haml
index 1ab1f6c43a9..8a201d42088 100644
--- a/app/views/merge_requests/branch_to.js.haml
+++ b/app/views/merge_requests/branch_to.js.haml
@@ -1,3 +1,3 @@
:plain
- $(".mr_target_commit").html("#{escape_javascript(render 'commits/commit', :commit => @commit)}");
+ $(".mr_target_commit").html("#{escape_javascript(render 'commits/commit', commit: @commit)}");
diff --git a/app/views/merge_requests/commits.js.haml b/app/views/merge_requests/commits.js.haml
index 2055aa9b4bd..76322bdb210 100644
--- a/app/views/merge_requests/commits.js.haml
+++ b/app/views/merge_requests/commits.js.haml
@@ -1,4 +1,4 @@
:plain
- $(".merge-request-commits").html("#{escape_javascript(render(:partial => "commits"))}");
+ $(".merge-request-commits").html("#{escape_javascript(render(partial: "commits"))}");
diff --git a/app/views/merge_requests/diffs.js.haml b/app/views/merge_requests/diffs.js.haml
index 4be5ec132e3..b147e5be71c 100644
--- a/app/views/merge_requests/diffs.js.haml
+++ b/app/views/merge_requests/diffs.js.haml
@@ -1,4 +1,4 @@
:plain
- $(".merge-request-diffs").html("#{escape_javascript(render(:partial => "merge_requests/show/diffs"))}");
+ $(".merge-request-diffs").html("#{escape_javascript(render(partial: "merge_requests/show/diffs"))}");
diff --git a/app/views/merge_requests/index.html.haml b/app/views/merge_requests/index.html.haml
index 5210b95e3e4..4ad6e5c18ce 100644
--- a/app/views/merge_requests/index.html.haml
+++ b/app/views/merge_requests/index.html.haml
@@ -1,7 +1,7 @@
%h3.page_title
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
+ = link_to new_project_merge_request_path(@project), class: "right btn small", title: "New Merge Request" do
New Merge Request
%br
@@ -10,17 +10,17 @@
.ui-box
.title
%ul.nav.nav-pills
- %li{:class => ("active" if (params[:f] == "0" || !params[:f]))}
- = link_to project_merge_requests_path(@project, :f => 0) do
+ %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
+ %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
+ %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
+ %li{class: ("active" if params[:f] == "1")}
+ = link_to project_merge_requests_path(@project, f: 1) do
All
%ul.unstyled
@@ -31,7 +31,7 @@
- if @merge_requests.present?
%li.bottom
.row
- .span7= paginate @merge_requests, :theme => "gitlab"
+ .span7= paginate @merge_requests, theme: "gitlab"
.span4.right
%span.cgray.right #{@merge_requests.total_count} merge requests for this filter
diff --git a/app/views/merge_requests/show.js.haml b/app/views/merge_requests/show.js.haml
index 2922b3bc6f0..7a27b166849 100644
--- a/app/views/merge_requests/show.js.haml
+++ b/app/views/merge_requests/show.js.haml
@@ -1,2 +1,2 @@
:plain
- $(".merge-request-notes").html("#{escape_javascript(render("notes/notes", :tid => @merge_request.id, :tt => "merge_request"))}");
+ $(".merge-request-notes").html("#{escape_javascript(render("notes/notes", tid: @merge_request.id, tt: "merge_request"))}");
diff --git a/app/views/merge_requests/show/_commits.html.haml b/app/views/merge_requests/show/_commits.html.haml
index d10e8fd597a..d25e707c64e 100644
--- a/app/views/merge_requests/show/_commits.html.haml
+++ b/app/views/merge_requests/show/_commits.html.haml
@@ -7,19 +7,19 @@
- if @commits.count > 8
%ul.first_mr_commits.unstyled
- @commits.first(8).each do |commit|
- = render "commits/commit", :commit => commit
+ = render "commits/commit", commit: commit
%li.bottom
8 of #{@commits.count} commits displayed.
%strong
%a.mr_show_all_commits Click here to show all
%ul.all_mr_commits.hide.unstyled
- @commits.each do |commit|
- = render "commits/commit", :commit => commit
+ = render "commits/commit", commit: commit
- else
%ul.unstyled
- @commits.each do |commit|
- = render "commits/commit", :commit => commit
+ = render "commits/commit", commit: commit
- else
%h5
diff --git a/app/views/merge_requests/show/_diffs.html.haml b/app/views/merge_requests/show/_diffs.html.haml
index 80776f19132..7685090311a 100644
--- a/app/views/merge_requests/show/_diffs.html.haml
+++ b/app/views/merge_requests/show/_diffs.html.haml
@@ -1,8 +1,8 @@
- if @merge_request.valid_diffs?
- = render "commits/diffs", :diffs => @diffs
+ = render "commits/diffs", diffs: @diffs
- elsif @merge_request.broken_diffs?
%h4.nothing_here_message
Can't load diff.
- You can #{link_to "download MR patch", raw_project_merge_request_path(@project, @merge_request), :class => "vlink"} instead.
+ You can #{link_to "download MR patch", raw_project_merge_request_path(@project, @merge_request), class: "vlink"} instead.
- else
%h4.nothing_here_message Nothing to merge
diff --git a/app/views/merge_requests/show/_how_to_merge.html.haml b/app/views/merge_requests/show/_how_to_merge.html.haml
index 2512d254fe0..69881d4352f 100644
--- a/app/views/merge_requests/show/_how_to_merge.html.haml
+++ b/app/views/merge_requests/show/_how_to_merge.html.haml
@@ -1,15 +1,14 @@
%div#modal_merge_info.modal.hide
.modal-header
- %a.close{:href => "#"} ×
+ %a.close{href: "#"} ×
%h3 How To Merge
.modal-body
- %pre
+ %pre.dark
= preserve do
- :erb
- git checkout <%= @merge_request.target_branch %>
- git fetch origin
- git merge origin/<%= @merge_request.source_branch %>
- git push origin <%= @merge_request.target_branch %>
+ git checkout #{@merge_request.target_branch}
+ git fetch origin
+ git merge origin/#{@merge_request.source_branch}
+ git push origin #{@merge_request.target_branch}
:javascript
diff --git a/app/views/merge_requests/show/_mr_accept.html.haml b/app/views/merge_requests/show/_mr_accept.html.haml
index c158ef88bba..f24228856ff 100644
--- a/app/views/merge_requests/show/_mr_accept.html.haml
+++ b/app/views/merge_requests/show/_mr_accept.html.haml
@@ -4,31 +4,31 @@
- if @merge_request.open? && @commits.any? && can?(current_user, :accept_mr, @project)
- .automerge_widget.can_be_merged{:style => "display:none"}
+ .automerge_widget.can_be_merged{style: "display:none"}
.alert.alert-success
%span
- = form_for [:automerge, @project, @merge_request], :remote => true, :method => :get do |f|
+ = form_for [:automerge, @project, @merge_request], remote: true, method: :get do |f|
%p
You can accept this request automatically.
If you still want to do it manually -
- %strong= link_to "click here", "#", :class => "how_to_merge_link vlink", :title => "How To Merge"
+ %strong= link_to "click here", "#", class: "how_to_merge_link vlink", title: "How To Merge"
for instructions
.accept_group
- = f.submit "Accept Merge Request", :class => "btn small success accept_merge_request"
+ = f.submit "Accept Merge Request", class: "btn small success accept_merge_request"
- unless @project.root_ref? @merge_request.source_branch
.remove_branch_holder
- = label_tag :should_remove_source_branch, :class => "checkbox" do
+ = label_tag :should_remove_source_branch, class: "checkbox" do
= check_box_tag :should_remove_source_branch
Remove source-branch
.clearfix
- .automerge_widget.cannot_be_merged{:style => "display:none"}
+ .automerge_widget.cannot_be_merged{style: "display:none"}
.alert.alert-info
%span
- = link_to "Show how to merge", "#", :class => "how_to_merge_link btn small padded", :title => "How To Merge"
+ = link_to "Show how to merge", "#", class: "how_to_merge_link btn small padded", title: "How To Merge"
&nbsp;
- %strong This request cant be merged with GitLab. You should do it manually
+ %strong This request can't be merged with GitLab. You should do it manually
.automerge_widget.unchecked
.alert-message
@@ -36,7 +36,10 @@
%i.icon-refresh
Checking for ability to automatically merge…
- .automerge_widget.already_cannot_be_merged{:style => "display:none"}
+ .automerge_widget.already_cannot_be_merged{style: "display:none"}
.alert.alert-info
%strong This merge request already can not be merged. Try to reload page.
+ .merge_in_progress.hide
+ %span.cgray Merge is in progress. Please wait. Page will be automatically reloaded. &nbsp;
+ = image_tag "ajax_loader.gif"
diff --git a/app/views/merge_requests/show/_mr_box.html.haml b/app/views/merge_requests/show/_mr_box.html.haml
index b542dac98e0..81ab83f3436 100644
--- a/app/views/merge_requests/show/_mr_box.html.haml
+++ b/app/views/merge_requests/show/_mr_box.html.haml
@@ -5,17 +5,17 @@
.alert-message.error.status_info Closed
- else
.alert-message.success.status_info Open
- = @merge_request.title
+ = gfm @merge_request.title
.middle_box_content
%div
%cite.cgray Created at #{@merge_request.created_at.stamp("Aug 21, 2011")} by
- = image_tag gravatar_icon(@merge_request.author_email), :width => 16, :class => "lil_av"
+ = image_tag gravatar_icon(@merge_request.author_email), width: 16, class: "lil_av"
%strong.author= link_to_merge_request_author(@merge_request)
- if @merge_request.assignee
%cite.cgray and currently assigned to
- = image_tag gravatar_icon(@merge_request.assignee_email), :width => 16, :class => "lil_av"
+ = image_tag gravatar_icon(@merge_request.assignee_email), width: 16, class: "lil_av"
%strong.author= link_to_merge_request_assignee(@merge_request)
diff --git a/app/views/merge_requests/show/_mr_title.html.haml b/app/views/merge_requests/show/_mr_title.html.haml
index 3f6060b0645..31fa0779fd2 100644
--- a/app/views/merge_requests/show/_mr_title.html.haml
+++ b/app/views/merge_requests/show/_mr_title.html.haml
@@ -13,13 +13,13 @@
= "MERGED"
- if can?(current_user, :modify_merge_request, @merge_request)
- if @merge_request.open?
- = link_to raw_project_merge_request_path(@project, @merge_request), :class => "btn grouped" do
+ = link_to raw_project_merge_request_path(@project, @merge_request), class: "btn grouped" do
%i.icon-download-alt
Get Patch
- = link_to 'Close', project_merge_request_path(@project, @merge_request, :merge_request => {:closed => true }, :status_only => true), :method => :put, :class => "btn grouped danger", :title => "Close merge request"
+ = link_to 'Close', project_merge_request_path(@project, @merge_request, merge_request: {closed: true }, status_only: true), method: :put, class: "btn grouped danger", title: "Close merge request"
- = link_to edit_project_merge_request_path(@project, @merge_request), :class => "btn grouped" do
+ = link_to edit_project_merge_request_path(@project, @merge_request), class: "btn grouped" do
%i.icon-edit
Edit
diff --git a/app/views/milestones/_form.html.haml b/app/views/milestones/_form.html.haml
index 69567eff417..1cd08ac3bcf 100644
--- a/app/views/milestones/_form.html.haml
+++ b/app/views/milestones/_form.html.haml
@@ -1,11 +1,11 @@
-%h3= @milestone.new_record? ? "New Milestone" : "Edit Milestone ##{@milestone.id}"
+%h3.page_title= @milestone.new_record? ? "New Milestone" : "Edit Milestone ##{@milestone.id}"
.back_link
= link_to project_milestones_path(@project) do
&larr; To milestones
%hr
-= form_for [@project, @milestone], :html => {:class => "new_milestone form-horizontal"} do |f|
+= form_for [@project, @milestone], html: {class: "new_milestone form-horizontal"} do |f|
-if @milestone.errors.any?
.alert-message.block-message.error
%ul
@@ -14,35 +14,35 @@
.row
.span6
.control-group
- = f.label :title, "Title", :class => "control-label"
+ = f.label :title, "Title", class: "control-label"
.controls
- = f.text_field :title, :maxlength => 255, :class => "input-xlarge"
- %p.help-block Required
+ = f.text_field :title, maxlength: 255, class: "input-xlarge"
+ %p.hint Required
.control-group
- = f.label :description, "Description", :class => "control-label"
+ = f.label :description, "Description", class: "control-label"
.controls
- = f.text_area :description, :maxlength => 2000, :class => "input-xlarge", :rows => 10
- %p.help-block Markdown is enabled.
+ = f.text_area :description, maxlength: 2000, class: "input-xlarge", rows: 10
+ %p.hint Markdown is enabled.
.span6
.control-group
- = f.label :due_date, "Due Date", :class => "control-label"
+ = f.label :due_date, "Due Date", class: "control-label"
.input= f.hidden_field :due_date
.controls
.datepicker
.form-actions
- if @milestone.new_record?
- = f.submit 'Create milestone', :class => "primary btn"
+ = f.submit 'Create milestone', class: "primary btn"
-else
- = f.submit 'Save changes', :class => "primary btn"
+ = f.submit 'Save changes', class: "primary btn"
- if request.xhr?
- = link_to "Cancel", "#back", :onclick => "backToIssues();", :class => "btn"
+ = link_to "Cancel", "#back", onclick: "backToIssues();", class: "btn"
- else
- if @milestone.new_record?
- = link_to "Cancel", project_milestones_path(@project), :class => "btn"
+ = link_to "Cancel", project_milestones_path(@project), class: "btn"
- else
- = link_to "Cancel", project_milestone_path(@project, @milestone), :class => "btn"
+ = link_to "Cancel", project_milestone_path(@project, @milestone), class: "btn"
:javascript
$(function() {
diff --git a/app/views/milestones/_milestone.html.haml b/app/views/milestones/_milestone.html.haml
index 9912cf9ed54..205b864f80f 100644
--- a/app/views/milestones/_milestone.html.haml
+++ b/app/views/milestones/_milestone.html.haml
@@ -1,19 +1,18 @@
-%li{:class => "milestone", :id => dom_id(milestone) }
+%li{class: "milestone", id: dom_id(milestone) }
.right
- if milestone.issues.any?
%span.btn.small.disabled.grouped= pluralize milestone.issues.count, 'issues'
- if milestone.issues.count > 0
- = link_to 'Browse Issues', project_issues_path(milestone.project, :milestone_id => milestone.id), :class => "btn small grouped"
+ = link_to 'Browse Issues', project_issues_path(milestone.project, milestone_id: milestone.id), class: "btn small grouped"
- if can? current_user, :admin_milestone, milestone.project
- = link_to 'Edit', edit_project_milestone_path(milestone.project, milestone), :class => "btn small edit-milestone-link grouped"
- = link_to project_milestone_path(milestone.project, milestone) do
- %h4.row_title
- = truncate(milestone.title, :length => 100)
- %small
- = milestone.expires_at
- %br
- .progress.progress-success.span3
- .bar{:style => "width: #{milestone.percent_complete}%;"}
+ = link_to 'Edit', edit_project_milestone_path(milestone.project, milestone), class: "btn small edit-milestone-link grouped"
+ %h4
+ = link_to_gfm truncate(milestone.title, length: 100), project_milestone_path(milestone.project, milestone), class: "row_title"
+ %small
+ = milestone.expires_at
+ %br
+ .progress.progress-success.span3
+ .bar{style: "width: #{milestone.percent_complete}%;"}
&nbsp;
diff --git a/app/views/milestones/index.html.haml b/app/views/milestones/index.html.haml
index ed85166fbb2..ecb008dc144 100644
--- a/app/views/milestones/index.html.haml
+++ b/app/views/milestones/index.html.haml
@@ -3,23 +3,23 @@
%h3.page_title
Milestones
- if can? current_user, :admin_milestone, @project
- = link_to "New Milestone", new_project_milestone_path(@project), :class => "right btn small", :title => "New Milestone"
+ = link_to "New Milestone", new_project_milestone_path(@project), class: "right btn small", title: "New Milestone"
%br
%div.ui-box
.title
%ul.nav.nav-pills
- %li{:class => ("active" if (params[:f] == "0" || !params[:f]))}
- = link_to project_milestones_path(@project, :f => 0) do
+ %li{class: ("active" if (params[:f] == "0" || !params[:f]))}
+ = link_to project_milestones_path(@project, f: 0) do
Active
- %li{:class => ("active" if params[:f] == "1")}
- = link_to project_milestones_path(@project, :f => 1) do
+ %li{class: ("active" if params[:f] == "1")}
+ = link_to project_milestones_path(@project, f: 1) do
All
%ul.unstyled
= render @milestones
- if @milestones.present?
- %li.bottom= paginate @milestones, :remote => true, :theme => "gitlab"
+ %li.bottom= paginate @milestones, remote: true, theme: "gitlab"
- else
%li
%h3.nothing_here_message Nothing to show here
diff --git a/app/views/milestones/show.html.haml b/app/views/milestones/show.html.haml
index dc3dcd01de8..b7da7b668ea 100644
--- a/app/views/milestones/show.html.haml
+++ b/app/views/milestones/show.html.haml
@@ -4,9 +4,9 @@
= @milestone.expires_at
%span.right
- = link_to 'Browse Issues', project_issues_path(@milestone.project, :milestone_id => @milestone.id), :class => "btn edit-milestone-link small grouped"
+ = link_to 'Browse Issues', project_issues_path(@milestone.project, milestone_id: @milestone.id), class: "btn edit-milestone-link small grouped"
- if can?(current_user, :admin_milestone, @project)
- = link_to edit_project_milestone_path(@project, @milestone), :class => "btn small grouped" do
+ = link_to edit_project_milestone_path(@project, @milestone), class: "btn small grouped" do
%i.icon-edit
Edit
@@ -21,7 +21,7 @@
.alert-message.error.status_info Closed
- else
.alert-message.success.status_info Open
- = @milestone.title
+ = gfm @milestone.title
%small.right= @milestone.expires_at
.middle_box_content
@@ -32,7 +32,7 @@
&ndash;
#{@milestone.issues.closed.count} closed
.progress.progress-success
- .bar{:style => "width: #{@milestone.percent_complete}%;"}
+ .bar{style: "width: #{@milestone.percent_complete}%;"}
- if @milestone.description.present?
@@ -50,10 +50,10 @@
%td
= link_to [@project, issue] do
%span.badge.badge-info ##{issue.id}
- &ndash;
- = truncate issue.title, :length => 60
+ &ndash;
+ = link_to_gfm truncate(issue.title, length: 60), [@project, issue]
%br
- = paginate @issues, :theme => "gitlab"
+ = paginate @issues, theme: "gitlab"
.span6
%table.admin-table
@@ -62,6 +62,6 @@
- @users.each do |user|
%tr
%td
- = image_tag gravatar_icon(user.email, 24), :width => "24"
+ = image_tag gravatar_icon(user.email, 24), width: "24"
&nbsp;
= user.name
diff --git a/app/views/notes/_create_common.js.haml b/app/views/notes/_create_common.js.haml
index 583812bf502..e9538902754 100644
--- a/app/views/notes/_create_common.js.haml
+++ b/app/views/notes/_create_common.js.haml
@@ -1,8 +1,10 @@
- if note.valid?
:plain
- $("#new_note .errors").remove();
+ $("#new_note .error").remove();
$('#new_note textarea').val("");
- NoteList.prepend(#{note.id}, "#{escape_javascript(render :partial => "notes/show", :locals => {:note => note})}");
+ $('#preview-link').text('Preview');
+ $('#preview-note').hide(); $('#note_note').show();
+ 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
index 9cf085cd613..13809bec1b9 100644
--- a/app/views/notes/_create_line.js.haml
+++ b/app/views/notes/_create_line.js.haml
@@ -4,5 +4,5 @@
$('#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})}");
+ 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 f5aa1495796..dac026bd23d 100644
--- a/app/views/notes/_form.html.haml
+++ b/app/views/notes/_form.html.haml
@@ -1,5 +1,5 @@
-= form_for [@project, @note], :remote => "true", :multipart => true do |f|
- %h3 Leave a comment
+= form_for [@project, @note], remote: "true", multipart: true do |f|
+ %h3.page_title Leave a comment
-if @note.errors.any?
.alert-message.block-message.error
- @note.errors.full_messages.each do |msg|
@@ -7,29 +7,32 @@
= f.hidden_field :noteable_id
= f.hidden_field :noteable_type
- = f.text_area :note, :size => 255
- %p.hint Markdown is enabled.
+ = f.text_area :note, size: 255
+ #preview-note.well.hide
+ %p.hint
+ = link_to "Gitlab Markdown", help_markdown_path, target: '_blank'
+ is enabled.
+ = link_to 'Preview', preview_project_notes_path(@project), id: 'preview-link'
.row.note_advanced_opts.hide
- .span4
- %h5 Notify via email:
- .clearfix
- = label_tag :notify do
- = check_box_tag :notify, 1, @note.noteable_type != "Commit"
- %span Project team
+ .span2
+ = f.submit 'Add Comment', class: "btn primary submit_note", id: "submit_note"
+ .span4.notify_opts
+ %h6.left Notify via email:
+ = label_tag :notify do
+ = check_box_tag :notify, 1, @note.noteable_type != "Commit"
+ %span 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
- .span8
- %h5 Attachment:
- .clearfix
- .attachments
- %div.file_name File name...
- %button.file_upload.btn.small Upload File
- .input= f.file_field :attachment, :class => "input-file"
- %span Any file less than 10 MB
+ - 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
+ .span6.attachments
+ %h6.left Attachment:
+ %span.file_name File name...
+
+ .input.input_file
+ %a.file_upload.btn.small Upload File
+ = f.file_field :attachment, class: "input-file"
+ %span.hint Any file less than 10 MB
-
- = f.submit 'Add Comment', :class => "btn primary submit_note", :id => "submit_note"
diff --git a/app/views/notes/_load.js.haml b/app/views/notes/_load.js.haml
index 1f3559670d1..c16a699a1b7 100644
--- a/app/views/notes/_load.js.haml
+++ b/app/views/notes/_load.js.haml
@@ -1,15 +1,15 @@
- unless @notes.blank?
- if params[:last_id]
:plain
- NoteList.replace("#{escape_javascript(render(:partial => 'notes/notes_list'))}");
+ NoteList.replace("#{escape_javascript(render(partial: 'notes/notes_list'))}");
- elsif params[:first_id]
:plain
- NoteList.append(#{@notes.last.id}, "#{escape_javascript(render(:partial => 'notes/notes_list'))}");
+ NoteList.append(#{@notes.last.id}, "#{escape_javascript(render(partial: 'notes/notes_list'))}");
- else
:plain
- NoteList.setContent(#{@notes.last.id}, #{@notes.first.id}, "#{escape_javascript(render(:partial => 'notes/notes_list'))}");
+ NoteList.setContent(#{@notes.last.id}, #{@notes.first.id}, "#{escape_javascript(render(partial: 'notes/notes_list'))}");
- else
- if params[:first_id]
diff --git a/app/views/notes/_notes_list.html.haml b/app/views/notes/_notes_list.html.haml
index 1e4a6bb2b2f..5673988d87d 100644
--- a/app/views/notes/_notes_list.html.haml
+++ b/app/views/notes/_notes_list.html.haml
@@ -1,4 +1,4 @@
- @notes.each do |note|
- next unless note.author
- = render :partial => "notes/show", :locals => {:note => note}
+ = render partial: "notes/show", locals: {note: note}
diff --git a/app/views/notes/_per_line_form.html.haml b/app/views/notes/_per_line_form.html.haml
index 8beaf9b5e0c..afb0b30dca3 100644
--- a/app/views/notes/_per_line_form.html.haml
+++ b/app/views/notes/_per_line_form.html.haml
@@ -1,8 +1,8 @@
-%table{:style => "display:none;"}
+%table{style: "display:none;"}
%tr.per_line_form
- %td{:colspan => 3 }
- = form_for [@project, @note], :remote => "true", :multipart => true do |f|
- %h3 Leave a note
+ %td{colspan: 3 }
+ = form_for [@project, @note], remote: "true", multipart: true do |f|
+ %h3.page_title Leave a note
%div.span10
-if @note.errors.any?
.alert-message.block-message.error
@@ -12,20 +12,22 @@
= f.hidden_field :noteable_id
= f.hidden_field :noteable_type
= f.hidden_field :line_code
- = f.text_area :note, :size => 255
- %h5 Notify via email:
- .clearfix
- = label_tag :notify do
- = check_box_tag :notify, 1, @note.noteable_type != "Commit"
- %span Project team
+ = f.text_area :note, size: 255
+ .note_actions
+ .buttons
+ = f.submit 'Add note', class: "btn primary submit_note", id: "submit_note"
+ = link_to "Cancel", "#", class: "btn hide-button"
+ .options
+ %h6.left Notify via email:
+ .labels
+ = label_tag :notify do
+ = check_box_tag :notify, 1, @note.noteable_type != "Commit"
+ %span 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
- .actions
- = f.submit 'Add note', :class => "btn primary submit_note", :id => "submit_note"
- = link_to "Close", "#", :class => "btn 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/_per_line_show.html.haml b/app/views/notes/_per_line_show.html.haml
index e239c618b11..cf1769c0517 100644
--- a/app/views/notes/_per_line_show.html.haml
+++ b/app/views/notes/_per_line_show.html.haml
@@ -1,5 +1,5 @@
%tr.line_notes_row
- %td{:colspan => 3}
+ %td{colspan: 3}
%ul
- = render :partial => "notes/show", :locals => {:note => note}
+ = render partial: "notes/show", locals: {note: note}
diff --git a/app/views/notes/_reply_button.html.haml b/app/views/notes/_reply_button.html.haml
index db6b35b7ada..c981fb9fc72 100644
--- a/app/views/notes/_reply_button.html.haml
+++ b/app/views/notes/_reply_button.html.haml
@@ -1,4 +1,4 @@
%tr.line_notes_row.reply
- %td{:colspan => 3}
+ %td{colspan: 3}
%i.icon-comment
- = link_to "Reply", "#", :class => "line_note_reply_link", "line_code" => line_code, :title => "Add note for this line"
+ = 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 3cd72c38929..3412e4ebae5 100644
--- a/app/views/notes/_show.html.haml
+++ b/app/views/notes/_show.html.haml
@@ -1,5 +1,5 @@
-%li{:id => dom_id(note), :class => "note"}
- = image_tag gravatar_icon(note.author.email), :class => "left", :width => 40, :style => "padding-right:5px;"
+%li{id: dom_id(note), class: "note"}
+ = image_tag gravatar_icon(note.author.email), class: "avatar s32"
%div.note-author
%strong= note.author_name
= link_to "##{dom_id(note)}", name: dom_id(note) do
@@ -7,7 +7,9 @@
= time_ago_in_words(note.updated_at)
ago
- if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project)
- %strong= link_to "Remove", [@project, note], :confirm => 'Are you sure?', :method => :delete, :remote => true, :class => "cred delete-note btn small"
+ = link_to [@project, note], confirm: 'Are you sure?', method: :delete, remote: true, class: "cred delete-note btn very_small" do
+ %i.icon-trash
+ Remove
%div.note-title
= preserve do
@@ -15,5 +17,5 @@
- if note.attachment.url
.right
%div.file
- = link_to note.attachment_identifier, note.attachment.url, :target => "_blank"
+ = link_to note.attachment_identifier, note.attachment.url, target: "_blank"
.clear
diff --git a/app/views/notes/create.js.haml b/app/views/notes/create.js.haml
index e87dbcf63c1..8f631f38f79 100644
--- a/app/views/notes/create.js.haml
+++ b/app/views/notes/create.js.haml
@@ -1,7 +1,7 @@
- if @note.line_code
- = render "create_line", :note => @note
+ = render "create_line", note: @note
- else
- = render "create_common", :note => @note
+ = render "create_common", note: @note
-# Enable submit button
:plain
diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml
index dd6f50c0686..654d6cd12be 100644
--- a/app/views/notify/new_issue_email.html.haml
+++ b/app/views/notify/new_issue_email.html.haml
@@ -1,16 +1,15 @@
-%td.content{:align => "left", :style => "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", :valign => "top", :width => "600"}
- %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :style => "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", :width => "600"}
+%td.content{align: "left", style: "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", valign: "top", width: "600"}
+ %table{border: "0", cellpadding: "0", cellspacing: "0", style: "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", width: "600"}
%tr
- %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; "}
+ %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 Issue was created and assigned to you.
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
%tr
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
- %td{:align => "left", :style => "padding: 20px 0 0;"}
- %h2{:style => "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
- = link_to project_issue_url(@issue.project, @issue), :title => @issue.title do
- = "Issue ##{@issue.id.to_s}"
- = truncate(@issue.title, :length => 45)
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{align: "left", style: "padding: 20px 0 0;"}
+ %h2{style: "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
+ = "Issue ##{@issue.id}"
+ = link_to_gfm truncate(@issue.title, length: 45), project_issue_url(@issue.project, @issue), title: @issue.title
%br
diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml
index f7ec01e84b3..151aac451fb 100644
--- a/app/views/notify/new_merge_request_email.html.haml
+++ b/app/views/notify/new_merge_request_email.html.haml
@@ -1,18 +1,18 @@
-%td.content{:align => "left", :style => "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", :valign => "top", :width => "600"}
- %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :style => "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", :width => "600"}
+%td.content{align: "left", style: "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", valign: "top", width: "600"}
+ %table{border: "0", cellpadding: "0", cellspacing: "0", style: "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", width: "600"}
%tr
- %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 Merge Request
- = link_to truncate(@merge_request.title, :length => 16), project_merge_request_url(@merge_request.project, @merge_request)
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
+ %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 Merge Request !#{@merge_request.id}"
+ = link_to_gfm truncate(@merge_request.title, length: 16), project_merge_request_url(@merge_request.project, @merge_request)
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
%tr
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
- %td{:style => "padding: 15px 0 15px;", :valign => "top"}
- %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{style: "padding: 15px 0 15px;", valign: "top"}
+ %p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
Branches: #{@merge_request.source_branch} &rarr; #{@merge_request.target_branch}
- %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
+ %p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
Asignee: #{@merge_request.author_name} &rarr; #{@merge_request.assignee_name}
%td
diff --git a/app/views/notify/new_user_email.html.haml b/app/views/notify/new_user_email.html.haml
index b0f198a50fd..d96afc92fe2 100644
--- a/app/views/notify/new_user_email.html.haml
+++ b/app/views/notify/new_user_email.html.haml
@@ -1,23 +1,23 @@
-%td.content{:align => "left", :style => "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", :valign => "top", :width => "600"}
- %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :style => "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", :width => "600"}
+%td.content{align: "left", style: "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", valign: "top", width: "600"}
+ %table{border: "0", cellpadding: "0", cellspacing: "0", style: "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", width: "600"}
%tr
- %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; "}
+ %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; "}
Hi #{@user['name']}!
- %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
+ %p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
Administrator created account for you. Now you are a member of company gitlab application.
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
%tr
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
- %td{:style => "padding: 15px 0 15px;", :valign => "top"}
- %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 28px; font-size: 16px;font-family: Helvetica, Arial, sans-serif; "}
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{style: "padding: 15px 0 15px;", valign: "top"}
+ %p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 28px; font-size: 16px;font-family: Helvetica, Arial, sans-serif; "}
login..........................................
%code= @user['email']
- %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 28px; font-size: 16px;font-family: Helvetica, Arial, sans-serif; "}
+ %p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 28px; font-size: 16px;font-family: Helvetica, Arial, sans-serif; "}
password..................................
%code= @password
- %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 28px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
+ %p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 28px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
= link_to "Click here to login", root_url
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
diff --git a/app/views/notify/note_commit_email.html.haml b/app/views/notify/note_commit_email.html.haml
index 99b89632ea4..e87f9c120e4 100644
--- a/app/views/notify/note_commit_email.html.haml
+++ b/app/views/notify/note_commit_email.html.haml
@@ -1,23 +1,23 @@
-%td.content{:align => "left", :style => "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", :valign => "top", :width => "600"}
- %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :style => "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", :width => "600"}
+%td.content{align: "left", style: "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", valign: "top", width: "600"}
+ %table{border: "0", cellpadding: "0", cellspacing: "0", style: "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", width: "600"}
%tr
- %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 commit
- = link_to truncate(@commit.id.to_s, :length => 16), project_commit_url(@note.project, :id => @commit.id, :anchor => "note_#{@note.id}")
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
+ %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 Commit #{@commit.short_id}"
+ = link_to_gfm truncate(@commit.title, length: 16), project_commit_url(@note.project, id: @commit.id, anchor: "note_#{@note.id}")
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
%tr
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
- %td{:style => "padding: 15px 0 15px;", :valign => "top"}
- %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
- %a{:href => "#", :style => "color: #0eb6ce; text-decoration: none;"} #{@note.author_name}
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{style: "padding: 15px 0 15px;", valign: "top"}
+ %p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
+ %a{href: "#", style: "color: #0eb6ce; text-decoration: none;"} #{@note.author_name}
left next message:
%br
- %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :width => "558"}
+ %table{border: "0", cellpadding: "0", cellspacing: "0", width: "558"}
%tr
- %td{:valign => "top"}
- %div{ :style => "background:#f5f5f5; padding:20px;border:1px solid #ddd" }
+ %td{valign: "top"}
+ %div{ style: "background:#f5f5f5; padding:20px;border:1px solid #ddd" }
= markdown(@note.note)
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
+ %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 17d58bdec73..832f5df4463 100644
--- a/app/views/notify/note_issue_email.html.haml
+++ b/app/views/notify/note_issue_email.html.haml
@@ -1,25 +1,23 @@
-%td.content{:align => "left", :style => "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", :valign => "top", :width => "600"}
- %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :style => "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", :width => "600"}
+%td.content{align: "left", style: "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", valign: "top", width: "600"}
+ %table{border: "0", cellpadding: "0", cellspacing: "0", style: "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", width: "600"}
%tr
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
- %td{:align => "left", :style => "padding: 20px 0 0;"}
- %h2{:style => "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
- New comment -
- = link_to project_issue_url(@issue.project, @issue, :anchor => "note_#{@note.id}") do
- = "Issue ##{@issue.id.to_s}"
- = truncate(@issue.title, :length => 35)
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{align: "left", style: "padding: 20px 0 0;"}
+ %h2{style: "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
+ = "New comment for Issue ##{@issue.id}"
+ = link_to_gfm truncate(@issue.title, length: 35), project_issue_url(@issue.project, @issue, anchor: "note_#{@note.id}")
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
%tr
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
- %td{:style => "padding: 15px 0 15px;", :valign => "top"}
- %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
- %a{:href => "#", :style => "color: #0eb6ce; text-decoration: none;"} #{@note.author_name}
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{style: "padding: 15px 0 15px;", valign: "top"}
+ %p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
+ %a{href: "#", style: "color: #0eb6ce; text-decoration: none;"} #{@note.author_name}
left next message:
%br
- %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :width => "558"}
+ %table{border: "0", cellpadding: "0", cellspacing: "0", width: "558"}
%tr
- %td{:valign => "top"}
- %div{ :style => "background:#f5f5f5; padding:20px;border:1px solid #ddd" }
+ %td{valign: "top"}
+ %div{ style: "background:#f5f5f5; padding:20px;border:1px solid #ddd" }
= markdown(@note.note)
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
+ %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 9c2284a6457..764cd094b76 100644
--- a/app/views/notify/note_merge_request_email.html.haml
+++ b/app/views/notify/note_merge_request_email.html.haml
@@ -1,23 +1,23 @@
-%td.content{:align => "left", :style => "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", :valign => "top", :width => "600"}
- %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :style => "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", :width => "600"}
+%td.content{align: "left", style: "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", valign: "top", width: "600"}
+ %table{border: "0", cellpadding: "0", cellspacing: "0", style: "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", width: "600"}
%tr
- %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 Merge Request
- = link_to truncate(@merge_request.title, :length => 16), project_merge_request_url(@merge_request.project, @merge_request, :anchor => "note_#{@note.id}")
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
+ %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 Merge Request !#{@merge_request.id}"
+ = link_to_gfm truncate(@merge_request.title, length: 16), project_merge_request_url(@merge_request.project, @merge_request, anchor: "note_#{@note.id}")
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
%tr
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
- %td{:style => "padding: 15px 0 15px;", :valign => "top"}
- %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
- %a{:href => "#", :style => "color: #0eb6ce; text-decoration: none;"} #{@note.author_name}
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{style: "padding: 15px 0 15px;", valign: "top"}
+ %p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
+ %a{href: "#", style: "color: #0eb6ce; text-decoration: none;"} #{@note.author_name}
left next message:
%br
- %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :width => "558"}
+ %table{border: "0", cellpadding: "0", cellspacing: "0", width: "558"}
%tr
- %td{:valign => "top"}
- %div{ :style => "background:#f5f5f5; padding:20px;border:1px solid #ddd" }
+ %td{valign: "top"}
+ %div{ style: "background:#f5f5f5; padding:20px;border:1px solid #ddd" }
= markdown(@note.note)
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
+ %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 f62e1f917cd..0661c5801b8 100644
--- a/app/views/notify/note_wall_email.html.haml
+++ b/app/views/notify/note_wall_email.html.haml
@@ -1,22 +1,22 @@
-%td.content{:align => "left", :style => "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", :valign => "top", :width => "600"}
- %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :style => "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", :width => "600"}
+%td.content{align: "left", style: "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", valign: "top", width: "600"}
+ %table{border: "0", cellpadding: "0", cellspacing: "0", style: "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", width: "600"}
%tr
- %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; "}
+ %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 message on
- = link_to "Project Wall", wall_project_url(@note.project, :anchor => "note_#{@note.id}")
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
+ = link_to "Project Wall", wall_project_url(@note.project, anchor: "note_#{@note.id}")
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
%tr
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
- %td{:style => "padding: 15px 0 15px;", :valign => "top"}
- %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
- %a{:href => "#", :style => "color: #0eb6ce; text-decoration: none;"} #{@note.author_name}
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{style: "padding: 15px 0 15px;", valign: "top"}
+ %p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
+ %a{href: "#", style: "color: #0eb6ce; text-decoration: none;"} #{@note.author_name}
left next message:
%br
- %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :width => "558"}
+ %table{border: "0", cellpadding: "0", cellspacing: "0", width: "558"}
%tr
- %td{:valign => "top"}
- %div{ :style => "background:#f5f5f5; padding:20px;border:1px solid #ddd" }
+ %td{valign: "top"}
+ %div{ style: "background:#f5f5f5; padding:20px;border:1px solid #ddd" }
= markdown(@note.note)
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
diff --git a/app/views/notify/note_wiki_email.html.haml b/app/views/notify/note_wiki_email.html.haml
new file mode 100644
index 00000000000..d3840cdac06
--- /dev/null
+++ b/app/views/notify/note_wiki_email.html.haml
@@ -0,0 +1,23 @@
+%td.content{align: "left", style: "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", valign: "top", width: "600"}
+ %table{border: "0", cellpadding: "0", cellspacing: "0", style: "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", width: "600"}
+ %tr
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{align: "left", style: "padding: 20px 0 0;"}
+ %h2{style: "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
+ New comment for Wiki page
+ = link_to_gfm @wiki.title, project_issue_url(@wiki.project, @wiki, anchor: "note_#{@note.id}")
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %tr
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{style: "padding: 15px 0 15px;", valign: "top"}
+ %p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
+ %a{href: "#", style: "color: #0eb6ce; text-decoration: none;"} #{@note.author_name}
+ commented on Wiki page:
+ %br
+ %table{border: "0", cellpadding: "0", cellspacing: "0", width: "558"}
+ %tr
+ %td{valign: "top"}
+ %div{ style: "background:#f5f5f5; padding:20px;border:1px solid #ddd" }
+ = markdown(@note.note)
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+
diff --git a/app/views/notify/reassigned_issue_email.html.haml b/app/views/notify/reassigned_issue_email.html.haml
index 43579b274d3..c7896af3a54 100644
--- a/app/views/notify/reassigned_issue_email.html.haml
+++ b/app/views/notify/reassigned_issue_email.html.haml
@@ -1,16 +1,16 @@
-%td.content{:align => "left", :style => "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", :valign => "top", :width => "600"}
- %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :style => "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", :width => "600"}
+%td.content{align: "left", style: "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", valign: "top", width: "600"}
+ %table{border: "0", cellpadding: "0", cellspacing: "0", style: "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", width: "600"}
%tr
- %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; "}
- Reassigned Issue
- = link_to truncate(@issue.title, :length => 16), project_issue_url(@issue.project, @issue)
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
+ %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; "}
+ = "Reassigned Issue ##{@issue.id}"
+ = link_to_gfm truncate(@issue.title, length: 16), project_issue_url(@issue.project, @issue)
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
%tr
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
- %td{:style => "padding: 15px 0 15px;", :valign => "top"}
- %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{style: "padding: 15px 0 15px;", valign: "top"}
+ %p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
Assignee changed from #{@previous_assignee.name} to #{@issue.assignee_name}
%td
diff --git a/app/views/notify/reassigned_merge_request_email.html.haml b/app/views/notify/reassigned_merge_request_email.html.haml
index 30b1f4fec42..e49b783635c 100644
--- a/app/views/notify/reassigned_merge_request_email.html.haml
+++ b/app/views/notify/reassigned_merge_request_email.html.haml
@@ -1,16 +1,16 @@
-%td.content{:align => "left", :style => "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", :valign => "top", :width => "600"}
- %table{:border => "0", :cellpadding => "0", :cellspacing => "0", :style => "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", :width => "600"}
+%td.content{align: "left", style: "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", valign: "top", width: "600"}
+ %table{border: "0", cellpadding: "0", cellspacing: "0", style: "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", width: "600"}
%tr
- %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; "}
- Reassigned Merge Request
- = link_to truncate(@merge_request.title, :length => 16), project_merge_request_url(@merge_request.project, @merge_request)
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
+ %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; "}
+ = "Reassigned Merge Request !#{@merge_request.id}"
+ = link_to_gfm truncate(@merge_request.title, length: 16), project_merge_request_url(@merge_request.project, @merge_request)
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
%tr
- %td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
- %td{:style => "padding: 15px 0 15px;", :valign => "top"}
- %p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
+ %td{style: "font-size: 1px; line-height: 1px;", width: "21"}
+ %td{style: "padding: 15px 0 15px;", valign: "top"}
+ %p{style: "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
Assignee changed from #{@previous_assignee.name} to #{@merge_request.assignee_name}
%td
diff --git a/app/views/profile/design.html.haml b/app/views/profile/design.html.haml
index ff6ae7f5778..d70483a25d8 100644
--- a/app/views/profile/design.html.haml
+++ b/app/views/profile/design.html.haml
@@ -1,37 +1,41 @@
-= form_for @user, :url => profile_update_path, :remote => true, :method => :put do |f|
+= form_for @user, url: profile_update_path, remote: true, method: :put do |f|
%div
- %h3 Application theme
- %hr
- .clearfix
+ %h3.page_title Application theme
+ %br
+ .themes_opts
= label_tag do
+ .prev
+ = image_tag "gitlab_default.png"
= f.radio_button :theme_id, 1
Default
= label_tag do
+ .prev
+ = image_tag "gitlab_classic.png"
= f.radio_button :theme_id, 2
Classic
= label_tag do
+ .prev
+ = image_tag "gitlab_modern.png"
= f.radio_button :theme_id, 3
Modern
%br
- %h3 Code review
- %hr
- .row
- %label.span3{:for => "user_dark_scheme_false"}
- .thumbnail
- = image_tag "white.png", :width => 260, :class => "styled_image"
- .caption
- %h5
- = f.radio_button :dark_scheme, false
- White code preview
- %label.span3{:for => "user_dark_scheme_true"}
- .thumbnail
- = image_tag "dark.png", :width => 260, :class => "styled_image"
- .caption
- %h5
- = f.radio_button :dark_scheme, true
- Dark code preview
+ .clearfix
+
+ %h3.page_title Code review
+ %br
+ .themes_opts
+ = label_tag do
+ .prev
+ = image_tag "white.png"
+ = f.radio_button :dark_scheme, false
+ White code preview
+ = label_tag do
+ .prev
+ = image_tag "dark.png"
+ = f.radio_button :dark_scheme, true
+ Dark code preview
:javascript
$(function(){
diff --git a/app/views/profile/password.html.haml b/app/views/profile/password.html.haml
index 1662f4d9c58..257dacb1ad3 100644
--- a/app/views/profile/password.html.haml
+++ b/app/views/profile/password.html.haml
@@ -1,6 +1,6 @@
%h3.page_title Password
%hr
-= form_for @user, :url => profile_password_path, :method => :put do |f|
+= form_for @user, url: profile_password_path, method: :put do |f|
.data
%p.slead After successful password update you will be redirected to login page where you should login with new password
-if @user.errors.any?
@@ -16,4 +16,4 @@
= f.label :password_confirmation
.input= f.password_field :password_confirmation
.actions
- = f.submit 'Save', :class => "btn primary"
+ = f.submit 'Save', class: "btn primary"
diff --git a/app/views/profile/show.html.haml b/app/views/profile/show.html.haml
index b26890131bb..a7b6a18ad2d 100644
--- a/app/views/profile/show.html.haml
+++ b/app/views/profile/show.html.haml
@@ -1,5 +1,5 @@
.profile_avatar_holder
- = image_tag gravatar_icon(@user.email, 90), :class => "styled_image"
+ = image_tag gravatar_icon(@user.email, 90), class: "styled_image"
%h3.page_title
= @user.name
%br
@@ -9,7 +9,7 @@
%hr
-= form_for @user, :url => profile_update_path, :method => :put, :html => { :class => "edit_user form-horizontal" } do |f|
+= form_for @user, url: profile_update_path, method: :put, html: { class: "edit_user form-horizontal" } do |f|
-if @user.errors.any?
%div.alert-message.block-message.error
%ul
@@ -18,36 +18,37 @@
.row
.span7
.control-group
- = f.label :name, :class => "control-label"
+ = f.label :name, class: "control-label"
.controls
- = f.text_field :name, :class => "input-xlarge"
+ = f.text_field :name, class: "input-xlarge"
%span.help-block Enter your name, so people you know can recognize you.
.control-group
- = f.label :email, :class => "control-label"
+ = f.label :email, class: "control-label"
.controls
- = f.text_field :email, :class => "input-xlarge"
+ = f.text_field :email, class: "input-xlarge"
%span.help-block We also use email for avatar detection.
%hr
.control-group
- = f.label :skype, :class => "control-label"
- .controls= f.text_field :skype, :class => "input-xlarge"
+ = f.label :skype, class: "control-label"
+ .controls= f.text_field :skype, class: "input-xlarge"
.control-group
- = f.label :linkedin, :class => "control-label"
- .controls= f.text_field :linkedin, :class => "input-xlarge"
+ = f.label :linkedin, class: "control-label"
+ .controls= f.text_field :linkedin, class: "input-xlarge"
.control-group
- = f.label :twitter, :class => "control-label"
- .controls= f.text_field :twitter, :class => "input-xlarge"
+ = f.label :twitter, class: "control-label"
+ .controls= f.text_field :twitter, class: "input-xlarge"
.control-group
- = f.label :bio, :class => "control-label"
+ = f.label :bio, class: "control-label"
.controls
- = f.text_area :bio, :rows => 6, :class => "input-xlarge", :maxlength => 250
+ = f.text_area :bio, rows: 6, class: "input-xlarge", maxlength: 250
%span.help-block Tell us about yourself in fewer than 250 characters.
.span5.right
- %p.alert.alert-info
- %strong Tip:
- You can change your avatar at gravatar.com
+ -unless Gitlab.config.disable_gravatar?
+ %p.alert.alert-info
+ %strong Tip:
+ You can change your avatar at gravatar.com
%h4
Personal projects:
@@ -56,14 +57,14 @@
of
%span= current_user.projects_limit
.progress
- .bar{:style => "width: #{current_user.projects_limit_percent}%;"}
+ .bar{style: "width: #{current_user.projects_limit_percent}%;"}
%h4
SSH public keys:
%small.right
%span= link_to current_user.keys.count, keys_path
- = link_to "Add Public Key", new_key_path, :class => "btn small right"
+ = link_to "Add Public Key", new_key_path, class: "btn small right"
.form-actions
- = f.submit 'Save', :class => "btn-primary btn"
+ = f.submit 'Save', class: "btn-primary btn"
diff --git a/app/views/profile/token.html.haml b/app/views/profile/token.html.haml
index 3a0ec90bbef..6c870c364de 100644
--- a/app/views/profile/token.html.haml
+++ b/app/views/profile/token.html.haml
@@ -3,7 +3,7 @@
%span.cred.right
keep it in secret!
%hr
-= form_for @user, :url => profile_reset_private_token_path, :method => :put do |f|
+= form_for @user, url: profile_reset_private_token_path, method: :put do |f|
.data
%p.slead
Private token used to access application resources without authentication.
@@ -11,13 +11,13 @@
It can be used for atom feed or API
%p.cgray
- if current_user.private_token
- = text_field_tag "token", current_user.private_token, :class => "xxlarge large_text"
+ = text_field_tag "token", current_user.private_token, class: "xxlarge large_text"
- else
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"
+ = f.submit 'Reset', confirm: "Are you sure?", class: "btn"
- else
- = f.submit 'Generate', :class => "btn primary"
+ = f.submit 'Generate', class: "btn primary"
diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml
index 6bc48df9183..ce66b2cf930 100644
--- a/app/views/projects/_form.html.haml
+++ b/app/views/projects/_form.html.haml
@@ -1,4 +1,4 @@
-= form_for(@project, :remote => true) do |f|
+= form_for(@project, remote: true) do |f|
- if @project.errors.any?
.alert-message.block-message.error
%ul
@@ -8,7 +8,7 @@
= f.label :name do
Project name is
.input
- = f.text_field :name, :placeholder => "Example Project", :class => "xxlarge"
+ = f.text_field :name, placeholder: "Example Project", class: "xxlarge"
%h5.page_title
.alert.alert-info
@@ -19,19 +19,19 @@
.input
.input-prepend
%strong
- = text_field_tag :ppath, @project.path_to_repo, :class => "xlarge", :disabled => true
+ = text_field_tag :ppath, @project.path_to_repo, class: "xlarge", disabled: true
.clearfix
= f.label :code do
URL
.input
.input-prepend
%span.add-on= web_app_url
- = f.text_field :code, :placeholder => "example"
+ = f.text_field :code, placeholder: "example"
- 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;")
+ .input= f.select(:default_branch, @project.heads.map(&:name), {}, style: "width:210px;")
- unless @project.new_record?
.alert.alert-info
@@ -56,8 +56,8 @@
%br
.actions
- = f.submit 'Save', :class => "btn primary"
- = link_to 'Cancel', @project, :class => "btn"
+ = 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"
+ = link_to 'Remove', @project, confirm: 'Are you sure?', method: :delete, class: "btn danger"
diff --git a/app/views/projects/_new_form.html.haml b/app/views/projects/_new_form.html.haml
index 9f3bfa86b91..5104df83a2c 100644
--- a/app/views/projects/_new_form.html.haml
+++ b/app/views/projects/_new_form.html.haml
@@ -1,4 +1,4 @@
-= form_for(@project, :remote => true) do |f|
+= form_for(@project, remote: true) do |f|
- if @project.errors.any?
.alert-message.block-message.error
%span= @project.errors.full_messages.first
@@ -6,8 +6,8 @@
= f.label :name do
Project name is
.input
- = f.text_field :name, :placeholder => "Example Project", :class => "xxlarge"
- = f.submit 'Create project', :class => "btn primary"
+ = f.text_field :name, placeholder: "Example Project", class: "xxlarge"
+ = f.submit 'Create project', class: "btn primary"
%hr
.alert.alert-info
@@ -18,7 +18,7 @@
.input
.input-prepend
%span.add-on= Gitlab.config.ssh_path
- = f.text_field :path, :placeholder => "example_project", :disabled => !@project.new_record?
+ = f.text_field :path, placeholder: "example_project", disabled: !@project.new_record?
%span.add-on= ".git"
.clearfix
= f.label :code do
@@ -26,4 +26,4 @@
.input
.input-prepend
%span.add-on= web_app_url
- = f.text_field :code, :placeholder => "example"
+ = f.text_field :code, placeholder: "example"
diff --git a/app/views/projects/_project_head.html.haml b/app/views/projects/_project_head.html.haml
index f3ac3c27ccf..ba64ee7f996 100644
--- a/app/views/projects/_project_head.html.haml
+++ b/app/views/projects/_project_head.html.haml
@@ -1,29 +1,29 @@
%ul.nav.nav-tabs
- %li{ :class => "#{'active' if current_page?(project_path(@project)) }" }
- = link_to project_path(@project), :class => "activities-tab tab" do
+ %li{ class: "#{'active' if current_page?(project_path(@project)) }" }
+ = link_to project_path(@project), class: "activities-tab tab" do
%i.icon-home
Show
- %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
+ %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
%i.icon-user
Team
- %li{ :class => "#{'active' if current_page?(files_project_path(@project)) }" }
- = link_to files_project_path(@project), :class => "files-tab tab " do
+ %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
+ %li{ class: " #{'active' if (controller.controller_name == "snippets") }" }
+ = link_to project_snippets_path(@project), class: "snippets-tab tab" do
Snippets
- if can? current_user, :admin_project, @project
- %li.right{:class => "#{'active' if controller.controller_name == "deploy_keys"}"}
+ %li.right{class: "#{'active' if controller.controller_name == "deploy_keys"}"}
= link_to project_deploy_keys_path(@project) do
%span
Deploy Keys
- %li.right{:class => "#{'active' if controller.controller_name == "hooks" }"}
+ %li.right{class: "#{'active' if controller.controller_name == "hooks" }"}
= link_to project_hooks_path(@project) do
%span
Hooks
- %li.right{ :class => "#{'active' if current_page?(edit_project_path(@project)) }" }
- = link_to edit_project_path(@project), :class => "stat-tab tab " do
+ %li.right{ class: "#{'active' if current_page?(edit_project_path(@project)) }" }
+ = link_to edit_project_path(@project), class: "stat-tab tab " do
%i.icon-edit
Edit
diff --git a/app/views/projects/_refs.html.haml b/app/views/projects/_refs.html.haml
index af15fbdfb3d..804b852340e 100644
--- a/app/views/projects/_refs.html.haml
+++ b/app/views/projects/_refs.html.haml
@@ -1,5 +1,5 @@
-= form_tag switch_project_refs_path(@project), :method => :get, :class => "project-refs-form" do
- = select_tag "ref", grouped_options_refs, :onchange => "this.form.submit();", :class => "project-refs-select"
+= form_tag switch_project_refs_path(@project), method: :get, class: "project-refs-form" do
+ = select_tag "ref", grouped_options_refs, onchange: "this.form.submit();", class: "project-refs-select"
= hidden_field_tag :destination, destination
:javascript
diff --git a/app/views/projects/_show.html.haml b/app/views/projects/_show.html.haml
index c6755fa730a..e8a5b00dd0e 100644
--- a/app/views/projects/_show.html.haml
+++ b/app/views/projects/_show.html.haml
@@ -2,9 +2,9 @@
= @project.name
%br
%div
- %a.btn.info{:href => tree_project_ref_path(@project, @project.root_ref)} Browse code
+ %a.btn.info{href: tree_project_ref_path(@project, @project.root_ref)} Browse code
&nbsp;
- %a.btn{:href => project_commits_path(@project)} Commits
+ %a.btn{href: project_commits_path(@project)} Commits
%strong.right
= link_to project_path(@project) do
Switch to project &rarr;
@@ -13,7 +13,7 @@
.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"
+ = text_field_tag :project_clone, @project.url_to_repo, class: "xlarge one_click_select git_clone_url"
= simple_format @project.description
- unless @events.blank?
diff --git a/app/views/projects/_team.html.haml b/app/views/projects/_team.html.haml
index 5839346052a..175aea27ed4 100644
--- a/app/views/projects/_team.html.haml
+++ b/app/views/projects/_team.html.haml
@@ -5,7 +5,7 @@
%th Permissions
%tbody
- @project.users_projects.each do |up|
- = render(:partial => 'team_members/show', :locals => {:member => up})
+ = render(partial: 'team_members/show', locals: {member: up})
:javascript
diff --git a/app/views/projects/create.js.haml b/app/views/projects/create.js.haml
index eeefc1729c8..2f6264a15af 100644
--- a/app/views/projects/create.js.haml
+++ b/app/views/projects/create.js.haml
@@ -1,6 +1,6 @@
- if @project.saved?
:plain
- location.href = "#{project_path(@project, :notice => 'Project was successfully created.')}";
+ location.href = "#{project_path(@project, notice: 'Project was successfully created.')}";
- else
- if @project.git_error?
location.href = "#{errors_githost_path}";
diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml
index eef113e002b..907d5ef4666 100644
--- a/app/views/projects/empty.html.haml
+++ b/app/views/projects/empty.html.haml
@@ -1,47 +1,30 @@
-- if current_user.require_ssh_key?
- .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.
-
-.alert-message.block-message.error
- %ul.unstyled.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]
+= render 'shared/no_ssh'
%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")
- = preserve do
- = raw bash_lexer.highlight(setup_str, :lexer => 'bash', :options => {:encoding => 'utf-8'})
-
- %br
- %br
- %h3 Create Repository
- - repo_setup_str = ["mkdir #{@project.path}",
- "cd #{@project.path}",
- "git init",
- "touch README",
- "git add README",
- "git commit -m 'first commit'",
- "git remote add origin #{@project.url_to_repo}",
- "git push -u origin master"].join("\n")
+ %h4 Git global setup:
+ %pre.dark
+ = preserve do
+ git config --global user.name "#{current_user.name}"
+ git config --global user.email "#{current_user.email}"
- = preserve do
- = raw bash_lexer.highlight(repo_setup_str)
+ %h4.prepend-top-20 Create Repository
+ %pre.dark
+ = preserve do
+ mkdir #{@project.path}
+ cd #{@project.path}
+ git init
+ touch README
+ git add README
+ git commit -m 'first commit'
+ git remote add origin #{@project.url_to_repo}
+ git push -u origin master
- %br
- %br
- %h3 Existing Git Repo?
- - exist_repo_setup_str = ["cd existing_git_repo",
- "git remote add origin #{@project.url_to_repo}",
- "git push -u origin master"].join("\n")
- = preserve do
- = raw bash_lexer.highlight(exist_repo_setup_str)
+ %h4.prepend-top-20 Existing Git Repo?
+ %pre.dark
+ = preserve do
+ cd existing_git_repo
+ git remote add origin #{@project.url_to_repo}
+ git push -u origin master
- if can? current_user, :admin_project, @project
- .alert-message.block-message.error.prepend-top-20
- = link_to 'Remove project', @project, :confirm => 'Are you sure?', :method => :delete, :class => "btn danger"
+ .prepend-top-20
+ = link_to 'Remove project', @project, confirm: 'Are you sure?', method: :delete, class: "btn danger right"
diff --git a/app/views/projects/files.html.haml b/app/views/projects/files.html.haml
index d171b0d09a1..68d51df0b56 100644
--- a/app/views/projects/files.html.haml
+++ b/app/views/projects/files.html.haml
@@ -4,8 +4,8 @@
- @notes.each do |note|
%tr
%td
- %a{:href => note.attachment.url}
- = image_tag gravatar_icon(note.author_email), :class => "left", :width => 16
+ %a{href: note.attachment.url}
+ = image_tag gravatar_icon(note.author_email), class: "left", width: 16
&nbsp;
= note.attachment_identifier
%td
@@ -14,6 +14,6 @@
ago
- else
.alert-message.block-message
- %p All files attached to project wall, issues etc will be displayed here
+ %span All files attached to project wall, issues etc will be displayed here
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index 0d119bd1d96..703e558ae41 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -6,7 +6,7 @@
%div.ajax_loader.hide
%center
%div.padded= image_tag "ajax_loader.gif"
- %h3.prepend-top Creating project &amp; repository. Please wait for few minutes
+ %h3.prepend-top Creating project &amp; repository. Please wait a few minutes
:javascript
$(function(){ new Projects(); });
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index 7c5b11e4be0..ebd2c8e4495 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -7,23 +7,23 @@
.input-prepend.project_clone_holder
%span.add-on git clone
- = link_to "SSH", "#", :class => "btn small active", :"data-clone" => @project.ssh_url_to_repo
- = link_to "HTTP", "#", :class => "btn small", :"data-clone" => @project.http_url_to_repo
- = text_field_tag :project_clone, @project.url_to_repo, :class => "one_click_select span5"
+ = link_to "SSH", "#", class: "btn small active", :"data-clone" => @project.ssh_url_to_repo
+ = link_to "HTTP", "#", class: "btn small", :"data-clone" => @project.http_url_to_repo
+ = text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select span5"
.span4.right
.right
- if can? current_user, :download_code, @project
- = link_to archive_project_repository_path(@project), :class => "btn small grouped" do
+ = link_to archive_project_repository_path(@project), class: "btn small grouped" do
%i.icon-download-alt
Download
- 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 grouped" do
+ = link_to new_project_merge_request_path(@project), title: "New Merge Request", class: "btn small grouped" 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 grouped" do
+ = link_to new_project_issue_path(@project), title: "New Issue", class: "btn small grouped" do
Issue
-= render "events/event_last_push", :event => @last_push
+= render "events/event_last_push", event: @last_push
.content_list= render @events
:javascript
diff --git a/app/views/projects/team.html.haml b/app/views/projects/team.html.haml
index 90be041479d..e8a825c741e 100644
--- a/app/views/projects/team.html.haml
+++ b/app/views/projects/team.html.haml
@@ -5,11 +5,11 @@
- if can? current_user, :admin_team_member, @project
%p.slead
- = link_to new_project_team_member_path(@project), :class => "btn small right", :title => "New Team Member" do
+ = link_to new_project_team_member_path(@project), class: "btn small right", title: "New Team Member" do
New Team Member
Read more about project permissions
- %strong= link_to "here", help_permissions_path, :class => "vlink"
+ %strong= link_to "here", help_permissions_path, class: "vlink"
-= render :partial => "team", :locals => {:project => @project}
+= render partial: "team", locals: {project: @project}
diff --git a/app/views/projects/tree.js.haml b/app/views/projects/tree.js.haml
index eb08adb1ddd..ba5d53c16a2 100644
--- a/app/views/projects/tree.js.haml
+++ b/app/views/projects/tree.js.haml
@@ -1,5 +1,5 @@
:plain
$("#tree-holder table").hide("slide", { direction: "left" }, 150, function(){
- $("#tree-holder").html("#{escape_javascript(render(:partial => "tree", :locals => {:repo => @repo, :commit => @commit, :tree => @tree}))}");
+ $("#tree-holder").html("#{escape_javascript(render(partial: "tree", locals: {repo: @repo, commit: @commit, tree: @tree}))}");
$("#tree-holder table").show("slide", { direction: "right" }, 150);
});
diff --git a/app/views/projects/update.js.haml b/app/views/projects/update.js.haml
index ee0d36996b5..a961dc39791 100644
--- a/app/views/projects/update.js.haml
+++ b/app/views/projects/update.js.haml
@@ -1,6 +1,6 @@
- if @project.valid?
:plain
- location.href = "#{edit_project_path(@project, :notice => 'Project was successfully updated.')}";
+ location.href = "#{edit_project_path(@project, notice: 'Project was successfully updated.')}";
- else
:plain
$('.project_edit_holder').show();
diff --git a/app/views/projects/wall.html.haml b/app/views/projects/wall.html.haml
index bd538e8f971..97765d7ac88 100644
--- a/app/views/projects/wall.html.haml
+++ b/app/views/projects/wall.html.haml
@@ -1,2 +1,2 @@
%div.wall_page
- = render "notes/notes", :tid => nil, :tt => "wall"
+ = render "notes/notes", tid: nil, tt: "wall"
diff --git a/app/views/protected_branches/index.html.haml b/app/views/protected_branches/index.html.haml
index bd1e9cebb1a..2b93b0a83db 100644
--- a/app/views/protected_branches/index.html.haml
+++ b/app/views/protected_branches/index.html.haml
@@ -1,12 +1,12 @@
= render "repositories/branches_head"
.alert
- %p Protected branches designed to prevent push for all except #{link_to "masters", help_permissions_path, :class => "vlink"}.
+ %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"}
+ %p Read more about project permissions #{link_to "here", help_permissions_path, class: "vlink"}
- if can? current_user, :admin_project, @project
= form_for [@project, @protected_branch] do |f|
@@ -19,9 +19,9 @@
.entry.clearfix
= f.label :name, "Branch"
.span3
- = f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , { :include_blank => "-- Select branch" }, { :class => "span3" })
+ = f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , { include_blank: "-- Select branch" }, { class: "span3" })
&nbsp;
- = f.submit 'Protect', :class => "primary btn"
+ = f.submit 'Protect', class: "primary btn"
- unless @branches.empty?
%table.admin-table
@@ -34,18 +34,18 @@
- @branches.each do |branch|
%tr
%td
- = link_to project_commits_path(@project, :ref => branch.name) do
+ = 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
+ = link_to project_commit_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"
+ = link_to 'Unprotect', [@project, branch], confirm: 'Are you sure?', method: :delete, class: "danger btn small"
:javascript
$('select#protected_branch_name').chosen();
diff --git a/app/views/refs/_head.html.haml b/app/views/refs/_head.html.haml
index 16a0cddfa24..8825493a0ec 100644
--- a/app/views/refs/_head.html.haml
+++ b/app/views/refs/_head.html.haml
@@ -1,10 +1,10 @@
%ul.nav.nav-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"
+ = 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") }"}
+ %li{class: "#{'active' if (controller.controller_name == "refs") }"}
= link_to tree_project_ref_path(@project, @ref) do
Source
diff --git a/app/views/refs/_submodule_item.html.haml b/app/views/refs/_submodule_item.html.haml
index 6db49310a08..6b9f5877028 100644
--- a/app/views/refs/_submodule_item.html.haml
+++ b/app/views/refs/_submodule_item.html.haml
@@ -1,13 +1,13 @@
- url = content.url(@ref) rescue nil
- name = content.basename
- return unless url
-%tr{ :class => "tree-item", :url => url }
+%tr{ class: "tree-item", url: url }
%td.tree-item-file-name
= image_tag "submodule.png"
- %strong= truncate(name, :length => 40)
+ %strong= truncate(name, length: 40)
%td
%code= content.id[0..10]
%td
- = link_to truncate(url, :length => 40), url
+ = link_to truncate(url, length: 40), url
diff --git a/app/views/refs/_tree.html.haml b/app/views/refs/_tree.html.haml
index ba0bd69116b..c231c40735c 100644
--- a/app/views/refs/_tree.html.haml
+++ b/app/views/refs/_tree.html.haml
@@ -1,7 +1,7 @@
%ul.breadcrumb
%li
%span.arrow
- = link_to tree_project_ref_path(@project, @ref, :path => nil), :remote => true do
+ = link_to tree_project_ref_path(@project, @ref, path: nil), remote: true do
= @project.name
- tree.breadcrumbs(6) do |link|
\/
@@ -10,32 +10,32 @@
%div.tree_progress
#tree-content-holder
- if tree.is_blob?
- = render :partial => "refs/tree_file", :locals => { :name => tree.name, :content => tree.data, :file => tree }
+ = render partial: "refs/tree_file", locals: { name: tree.name, content: tree.data, file: tree }
- else
- contents = tree.contents
- %table#tree-slider.bordered-table.table{:class => "table_#{@hex_path}" }
+ %table#tree-slider.bordered-table.table{class: "table_#{@hex_path}" }
%thead
%th Name
%th Last Update
%th
Last commit
- = link_to "History", tree.history_path, :class => "right"
+ = link_to "History", tree.history_path, class: "right"
- if tree.up_dir?
- %tr{ :class => "tree-item", :url => tree.up_dir_path }
+ %tr{ class: "tree-item", url: tree.up_dir_path }
%td.tree-item-file-name
= image_tag "file_empty.png"
- = link_to "..", tree.up_dir_path, :remote => :true
+ = link_to "..", tree.up_dir_path, remote: :true
%td
%td
- index = 0
- contents.select{ |i| i.is_a?(Grit::Tree)}.each do |content|
- = render :partial => "refs/tree_item", :locals => { :content => content, :index => (index += 1) }
+ = render partial: "refs/tree_item", locals: { content: content, index: (index += 1) }
- contents.select{ |i| i.is_a?(Grit::Blob)}.each do |content|
- = render :partial => "refs/tree_item", :locals => { :content => content, :index => (index += 1) }
+ = render partial: "refs/tree_item", locals: { content: content, index: (index += 1) }
- contents.select{ |i| i.is_a?(Grit::Submodule)}.each do |content|
- = render :partial => "refs/submodule_item", :locals => { :content => content, :index => (index += 1) }
+ = render partial: "refs/submodule_item", locals: { content: content, index: (index += 1) }
- if content = contents.select{ |c| c.is_a?(Grit::Blob) and c.name =~ /^readme/i }.first
.file_holder#README
@@ -51,8 +51,6 @@
: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}");
diff --git a/app/views/refs/_tree_commit.html.haml b/app/views/refs/_tree_commit.html.haml
index 1f2524a4c3a..1bcf1a7ea1d 100644
--- a/app/views/refs/_tree_commit.html.haml
+++ b/app/views/refs/_tree_commit.html.haml
@@ -1,3 +1,3 @@
- if tm
- %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"
+ = link_to "[#{tm.user_name}]", project_team_member_path(@project, tm)
+= link_to_gfm truncate(content_commit.title, length: tm ? 30 : 50), project_commit_path(@project, content_commit.id), class: "tree-commit-link"
diff --git a/app/views/refs/_tree_file.html.haml b/app/views/refs/_tree_file.html.haml
index d45a03df8aa..b5ed61bb45a 100644
--- a/app/views/refs/_tree_file.html.haml
+++ b/app/views/refs/_tree_file.html.haml
@@ -5,9 +5,9 @@
= name
%small #{file.mode}
%span.options
- = link_to "raw", blob_project_ref_path(@project, @ref, :path => params[:path]), :class => "btn very_small", :target => "_blank"
- = link_to "history", project_commits_path(@project, :path => params[:path], :ref => @ref), :class => "btn very_small"
- = link_to "blame", blame_file_project_ref_path(@project, @ref, :path => params[:path]), :class => "btn very_small"
+ = link_to "raw", blob_project_ref_path(@project, @ref, path: params[:path]), class: "btn very_small", target: "_blank"
+ = link_to "history", project_commits_path(@project, path: params[:path], ref: @ref), class: "btn very_small"
+ = link_to "blame", blame_file_project_ref_path(@project, @ref, path: params[:path]), class: "btn very_small"
- if file.text?
- if name =~ /\.(md|markdown)$/i
.file_content.wiki
@@ -16,7 +16,7 @@
- else
.file_content.code
- unless file.empty?
- %div{:class => current_user.dark_scheme ? "black" : "white"}
+ %div{class: current_user.dark_scheme ? "black" : "white"}
= preserve do
= raw file.colorize(options: { linenos: 'True'})
- else
@@ -24,14 +24,14 @@
- elsif file.image?
.file_content.image_file
- %img{ :src => "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
+ %img{ src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"}
- else
.file_content.blob_file
%center
- = link_to blob_project_ref_path(@project, @ref, :path => params[:path]) do
+ = link_to blob_project_ref_path(@project, @ref, path: params[:path]) do
%div.padded
%br
- = image_tag "download.png", :width => 64
+ = image_tag "download.png", width: 64
%h3
Download (#{file.mb_size})
diff --git a/app/views/refs/_tree_item.html.haml b/app/views/refs/_tree_item.html.haml
index 4ce16b22ddd..2e6bbf6221b 100644
--- a/app/views/refs/_tree_item.html.haml
+++ b/app/views/refs/_tree_item.html.haml
@@ -1,11 +1,11 @@
- file = tree_full_path(content)
-%tr{ :class => "tree-item #{tree_hex_class(content)}", :url => tree_file_project_ref_path(@project, @ref, file) }
+%tr{ class: "tree-item #{tree_hex_class(content)}", url: tree_file_project_ref_path(@project, @ref, file) }
%td.tree-item-file-name
= tree_icon(content)
- = link_to truncate(content.name, :length => 40), tree_file_project_ref_path(@project, @ref || @commit.id, file), :remote => :true
+ = link_to truncate(content.name, length: 40), tree_file_project_ref_path(@project, @ref || @commit.id, file), remote: :true
%td.tree_time_ago.cgray
- if index == 1
%span.log_loading
Loading commit data..
- = image_tag "ajax_loader_tree.gif", :width => 14
+ = image_tag "ajax_loader_tree.gif", width: 14
%td.tree_commit
diff --git a/app/views/refs/blame.html.haml b/app/views/refs/blame.html.haml
index 6a86b91fe74..34478d4b491 100644
--- a/app/views/refs/blame.html.haml
+++ b/app/views/refs/blame.html.haml
@@ -4,7 +4,7 @@
%ul.breadcrumb
%li
%span.arrow
- = link_to tree_project_ref_path(@project, @ref, :path => nil) do
+ = link_to tree_project_ref_path(@project, @ref, path: nil) do
= @project.name
- @tree.breadcrumbs(6) do |link|
\/
@@ -18,22 +18,22 @@
= @tree.name
%small blame
%span.options
- = link_to "raw", blob_project_ref_path(@project, @ref, :path => params[:path]), :class => "btn very_small", :target => "_blank"
- = link_to "history", project_commits_path(@project, :path => params[:path], :ref => @ref), :class => "btn very_small"
- = link_to "source", tree_file_project_ref_path(@project, @ref, :path => params[:path]), :class => "btn very_small"
+ = link_to "raw", blob_project_ref_path(@project, @ref, path: params[:path]), class: "btn very_small", target: "_blank"
+ = link_to "history", project_commits_path(@project, path: params[:path], ref: @ref), class: "btn very_small"
+ = link_to "source", tree_file_project_ref_path(@project, @ref, path: params[:path]), class: "btn very_small"
.file_content.blame
%table
- @blame.each do |commit, lines|
- commit = Commit.new(commit)
+ - commit = CommitDecorator.decorate(commit)
%tr
%td.author
= image_tag gravatar_icon(commit.author_email, 16)
= commit.author_name
%td.blame_commit
&nbsp;
- = link_to project_commit_path(@project, :id => commit.id) do
- %code= commit.id.to_s[0..10]
- %span.row_title= truncate(commit.safe_message, :length => 30) rescue "--broken encoding"
+ %code= link_to commit.short_id, project_commit_path(@project, id: commit.id)
+ = link_to_gfm truncate(commit.title, length: 30), project_commit_path(@project, id: commit.id), class: "row_title" rescue "--broken encoding"
%td.lines
= preserve do
%pre
diff --git a/app/views/refs/logs_tree.js.haml b/app/views/refs/logs_tree.js.haml
index 402f5aa72bc..61ccbaee1fe 100644
--- a/app/views/refs/logs_tree.js.haml
+++ b/app/views/refs/logs_tree.js.haml
@@ -6,4 +6,4 @@
:plain
var row = $("table.table_#{@hex_path} tr.file_#{hexdigest(file_name)}");
row.find("td.tree_time_ago").html('#{escape_javascript(time_ago_in_words(content_commit.committed_date))} ago');
- row.find("td.tree_commit").html('#{escape_javascript(render("tree_commit", :tm => tm, :content_commit => content_commit))}');
+ row.find("td.tree_commit").html('#{escape_javascript(render("tree_commit", tm: tm, content_commit: content_commit))}');
diff --git a/app/views/refs/tree.html.haml b/app/views/refs/tree.html.haml
index b48f7f91782..181be6426d4 100644
--- a/app/views/refs/tree.html.haml
+++ b/app/views/refs/tree.html.haml
@@ -1,5 +1,5 @@
= render "head"
-#tree-holder= render :partial => "tree", :locals => {:repo => @repo, :commit => @commit, :tree => @tree}
+#tree-holder= render partial: "tree", locals: {repo: @repo, commit: @commit, tree: @tree}
:javascript
$(function() {
diff --git a/app/views/refs/tree.js.haml b/app/views/refs/tree.js.haml
index 9cf55057a6a..2eccf8c19a6 100644
--- a/app/views/refs/tree.js.haml
+++ b/app/views/refs/tree.js.haml
@@ -1,6 +1,6 @@
:plain
// Load Files list
- $("#tree-holder").html("#{escape_javascript(render(:partial => "tree", :locals => {:repo => @repo, :commit => @commit, :tree => @tree}))}");
+ $("#tree-holder").html("#{escape_javascript(render(partial: "tree", locals: {repo: @repo, commit: @commit, tree: @tree}))}");
$("#tree-content-holder").show("slide", { direction: "right" }, 150);
$('.project-refs-form #path').val("#{params[:path]}");
diff --git a/app/views/repositories/_branch.html.haml b/app/views/repositories/_branch.html.haml
index 4742b92bd74..cf8558ec33e 100644
--- a/app/views/repositories/_branch.html.haml
+++ b/app/views/repositories/_branch.html.haml
@@ -1,20 +1,21 @@
+- commit = Commit.new(branch.commit)
+- commit = CommitDecorator.decorate(commit)
%tr
%td
- = link_to project_commits_path(@project, :ref => branch.name) do
- %strong= branch.name
+ = link_to project_commits_path(@project, ref: branch.name) do
+ %strong= truncate(branch.name, length: 60)
- if branch.name == @project.root_ref
%span.label default
%td
- = link_to project_commit_path(@project, :id => branch.commit.id) do
- %code= branch.commit.id.to_s[0..10]
+ = link_to project_commit_path(@project, id: commit.id) do
+ %code= commit.short_id
- = image_tag gravatar_icon(Commit.new(branch.commit).author_email), :class => "", :width => 16
- = truncate(Commit.new(branch.commit).safe_message, :length => 40)
- %td
+ = image_tag gravatar_icon(commit.author_email), class: "", width: 16
+ = gfm truncate(commit.title, length: 40)
%span.update-author.right
- = time_ago_in_words(branch.commit.committed_date)
+ = time_ago_in_words(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"
+ = 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
index 0c94f298270..6afff627b94 100644
--- a/app/views/repositories/_branches_head.html.haml
+++ b/app/views/repositories/_branches_head.html.haml
@@ -1,11 +1,11 @@
= render "commits/head"
%ul.nav.nav-pills
- %li{:class => ("active" if current_page?(project_repository_path(@project)))}
+ %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)))}
+ %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)))}
+ %li{class: ("active" if current_page?(branches_project_repository_path(@project)))}
= link_to branches_project_repository_path(@project) do
All
diff --git a/app/views/repositories/_feed.html.haml b/app/views/repositories/_feed.html.haml
index 0734327233e..ac4eb483945 100644
--- a/app/views/repositories/_feed.html.haml
+++ b/app/views/repositories/_feed.html.haml
@@ -1,7 +1,8 @@
- commit = update
+- commit = CommitDecorator.new(commit)
%tr
%td
- = link_to project_commits_path(@project, :ref => commit.head.name) do
+ = link_to project_commits_path(@project, ref: commit.head.name) do
%strong
= commit.head.name
- if commit.head.name == @project.root_ref
@@ -10,9 +11,9 @@
%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)
+ %code= commit.short_id
+ = image_tag gravatar_icon(commit.author_email), class: "", width: 16
+ = gfm truncate(commit.title, length: 40)
%td
%span.right.cgray
= time_ago_in_words(commit.committed_date)
diff --git a/app/views/repositories/branches.html.haml b/app/views/repositories/branches.html.haml
index 52c0bf8e618..45004bdff43 100644
--- a/app/views/repositories/branches.html.haml
+++ b/app/views/repositories/branches.html.haml
@@ -5,9 +5,8 @@
%tr
%th Name
%th Last commit
- %th Updated at
%th
%tbody
- @branches.each do |branch|
- = render "repositories/branch", :branch => branch
+ = render "repositories/branch", branch: branch
diff --git a/app/views/repositories/show.html.haml b/app/views/repositories/show.html.haml
index ceb971a4e17..a09cdd6212b 100644
--- a/app/views/repositories/show.html.haml
+++ b/app/views/repositories/show.html.haml
@@ -5,8 +5,7 @@
%tr
%th Name
%th Last commit
- %th Updated at
%th
- @activities.each do |update|
- = render "repositories/branch", :branch => update.head
+ = render "repositories/branch", branch: update.head
diff --git a/app/views/repositories/tags.html.haml b/app/views/repositories/tags.html.haml
index 5e5cca31d8f..7fc2c3bfd2f 100644
--- a/app/views/repositories/tags.html.haml
+++ b/app/views/repositories/tags.html.haml
@@ -9,14 +9,15 @@
%th
- @tags.each do |tag|
- commit = Commit.new(tag.commit)
+ - commit = CommitDecorator.decorate(commit)
%tr
%td
- %strong= link_to tag.name, project_commits_path(@project, :ref => tag.name), :class => ""
+ %strong= link_to tag.name, project_commits_path(@project, ref: tag.name), class: ""
%td
= link_to project_commit_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)
+ %code= commit.short_id
+ = image_tag gravatar_icon(commit.author_email), class: "", width: 16
+ = gfm truncate(commit.title, length: 40)
%td
%span.update-author.right
= time_ago_in_words(commit.committed_date)
@@ -24,7 +25,7 @@
&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"
+ = 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/search/show.html.haml b/app/views/search/show.html.haml
index b93a03af2f1..9a0b4789588 100644
--- a/app/views/search/show.html.haml
+++ b/app/views/search/show.html.haml
@@ -1,10 +1,10 @@
-= form_tag search_path, :method => :get do |f|
+= form_tag search_path, method: :get, class: 'form-inline' do |f|
.padded
= label_tag :search do
%strong Looking for
.input
- = text_field_tag :search, params[:search], :placeholder => "issue 143", :class => "input-xxlarge", :id => "dashboard_search"
- = submit_tag 'Search', :class => "btn btn-primary"
+ = text_field_tag :search, params[:search], placeholder: "issue 143", class: "input-xxlarge", id: "dashboard_search"
+ = submit_tag 'Search', class: "btn btn-primary"
- if params[:search].present?
%br
%h3
@@ -41,7 +41,7 @@
= link_to [merge_request.project, merge_request] do
%span.badge.badge-info ##{merge_request.id}
&ndash;
- %strong.term= truncate merge_request.title, :length => 50
+ %strong.term= truncate merge_request.title, length: 50
%strong.right
%span.label= merge_request.project.name
- if @merge_requests.blank?
@@ -59,7 +59,7 @@
= link_to [issue.project, issue] do
%span.badge.badge-info ##{issue.id}
&ndash;
- %strong.term= truncate issue.title, :length => 40
+ %strong.term= truncate issue.title, length: 40
%strong.right
%span.label= issue.project.name
- if @issues.blank?
diff --git a/app/views/shared/_no_ssh.html.haml b/app/views/shared/_no_ssh.html.haml
new file mode 100644
index 00000000000..b6ab666bc5d
--- /dev/null
+++ b/app/views/shared/_no_ssh.html.haml
@@ -0,0 +1,8 @@
+- if current_user.require_ssh_key?
+ %h6.error_message
+ %span
+ You wont be able to pull/push project code unless you
+ %strong
+ = link_to new_key_path, class: "vlink" do
+ add SSH key
+ to your profile
diff --git a/app/views/snippets/_form.html.haml b/app/views/snippets/_form.html.haml
index c9128f642fc..b8d8c09849d 100644
--- a/app/views/snippets/_form.html.haml
+++ b/app/views/snippets/_form.html.haml
@@ -10,22 +10,22 @@
.clearfix
= f.label :title
- .input= f.text_field :title, :placeholder => "Example Snippet"
+ .input= f.text_field :title, placeholder: "Example Snippet"
.clearfix
= f.label :file_name
- .input= f.text_field :file_name, :placeholder => "example.rb"
+ .input= f.text_field :file_name, placeholder: "example.rb"
.clearfix
= f.label "Lifetime"
- .input= f.select :expires_at, lifetime_select_options, {}, :style => "width:200px;"
+ .input= f.select :expires_at, lifetime_select_options, {}, style: "width:200px;"
.clearfix
= f.label :content, "Code"
- .input= f.text_area :content, :class => "span8"
+ .input= f.text_area :content, class: "span8"
.actions
- = f.submit 'Save', :class => "primary btn"
- = link_to "Cancel", project_snippets_path(@project), :class => " btn"
+ = 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 => "btn right danger 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 0385d753207..a2d3a65e6cb 100644
--- a/app/views/snippets/_snippet.html.haml
+++ b/app/views/snippets/_snippet.html.haml
@@ -1,7 +1,7 @@
%tr
%td
- %a{:href => project_snippet_path(snippet.project, snippet)}
- %strong= truncate(snippet.title, :length => 60)
+ %a{href: project_snippet_path(snippet.project, snippet)}
+ %strong= truncate(snippet.title, length: 60)
%td
= snippet.file_name
%td
diff --git a/app/views/snippets/index.html.haml b/app/views/snippets/index.html.haml
index a6b07716ccb..7229b587bc8 100644
--- a/app/views/snippets/index.html.haml
+++ b/app/views/snippets/index.html.haml
@@ -2,9 +2,9 @@
- 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
+ = 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
+ Share code pastes with others if it can't be in a git repository
%br
To add new snippet - click on button.
@@ -17,5 +17,5 @@
= render @snippets.fresh
- if @snippets.fresh.empty?
%tr
- %td{:colspan => 3}
+ %td{colspan: 3}
%h3.nothing_here_message Nothing here.
diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml
index b266e4d2156..0800b81d330 100644
--- a/app/views/snippets/show.html.haml
+++ b/app/views/snippets/show.html.haml
@@ -4,7 +4,7 @@
= @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"
+ = link_to "Edit", edit_project_snippet_path(@project, @snippet), class: "btn small right"
%br
.file_holder
@@ -12,9 +12,9 @@
%i.icon-file
%strong= @snippet.file_name
%span.options
- = link_to "raw", raw_project_snippet_path(@project, @snippet), :class => "btn very_small", :target => "_blank"
+ = link_to "raw", raw_project_snippet_path(@project, @snippet), class: "btn very_small", target: "_blank"
.file_content.code
- %div{:class => current_user.dark_scheme ? "black" : ""}
+ %div{class: current_user.dark_scheme ? "black" : ""}
= raw @snippet.colorize(options: { linenos: 'True'})
-= render "notes/notes", :tid => @snippet.id, :tt => "snippet"
+= render "notes/notes", tid: @snippet.id, tt: "snippet"
diff --git a/app/views/team_members/_form.html.haml b/app/views/team_members/_form.html.haml
index 1d882e295d9..208794b9ee2 100644
--- a/app/views/team_members/_form.html.haml
+++ b/app/views/team_members/_form.html.haml
@@ -1,6 +1,6 @@
%h3= "New Team member"
%hr
-= form_for @team_member, :as => :team_member, :url => project_team_members_path(@project, @team_member) do |f|
+= form_for @team_member, as: :team_member, url: project_team_members_path(@project, @team_member) do |f|
-if @team_member.errors.any?
.alert-message.block-message.error
%ul
@@ -9,17 +9,17 @@
.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" })
+ .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"
+ .input= 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"
+ = f.submit 'Save', class: "btn primary"
+ = link_to "Cancel", team_project_path(@project), class: "btn"
:css
form select {
diff --git a/app/views/team_members/_show.html.haml b/app/views/team_members/_show.html.haml
index 9f023c416ae..2dc4fb652dd 100644
--- a/app/views/team_members/_show.html.haml
+++ b/app/views/team_members/_show.html.haml
@@ -1,6 +1,6 @@
- user = member.user
- allow_admin = can? current_user, :admin_project, @project
-%tr{:id => dom_id(member), :class => "team_member_row user_#{user.id}"}
+%tr{id: dom_id(member), class: "team_member_row user_#{user.id}"}
%td
.right
- if @project.owner == user
@@ -8,13 +8,13 @@
- if user.blocked
%span.label Blocked
- = link_to project_team_member_path(@project, member), :title => user.name, :class => "dark" do
- = image_tag gravatar_icon(user.email, 40), :class => "avatar"
- = link_to project_team_member_path(@project, member), :title => user.name, :class => "dark" do
- %strong= truncate(user.name, :lenght => 40)
+ = link_to project_team_member_path(@project, member), title: user.name, class: "dark" do
+ = image_tag gravatar_icon(user.email, 40), class: "avatar s32"
+ = link_to project_team_member_path(@project, member), title: user.name, class: "dark" do
+ %strong= truncate(user.name, lenght: 40)
%br
%div.cgray= user.email
%td
- = form_for(member, :as => :team_member, :url => project_team_member_path(@project, member)) do |f|
- = f.select :project_access, options_for_select(UsersProject.access_roles, member.project_access), {}, :class => "medium project-access-select", :disabled => !allow_admin
+ = form_for(member, as: :team_member, url: project_team_member_path(@project, member)) do |f|
+ = f.select :project_access, options_for_select(UsersProject.access_roles, member.project_access), {}, class: "medium project-access-select", disabled: !allow_admin
diff --git a/app/views/team_members/show.html.haml b/app/views/team_members/show.html.haml
index f8a203d43c1..6cb357cddfc 100644
--- a/app/views/team_members/show.html.haml
+++ b/app/views/team_members/show.html.haml
@@ -2,16 +2,19 @@
- user = @team_member.user
.team_member_show
+ - if can? current_user, :admin_project, @project
+ = link_to 'Remove from team', project_team_member_path(project_id: @project, id: @team_member.id), confirm: 'Are you sure?', method: :delete, class: "right btn btn-danger"
.profile_avatar_holder
- = image_tag gravatar_icon(user.email, 60), :class => "borders"
+ = image_tag gravatar_icon(user.email, 60), class: "borders"
%h3
= user.name
%small
= user.email
+
%hr
.back_link
%br
- = link_to team_project_path(@project), :class => "" do
+ = link_to team_project_path(@project), class: "" do
&larr; To team list
%br
.row
@@ -43,17 +46,12 @@
%tr
%td
Project Access:
- %small (#{link_to "read more", help_permissions_path, :class => "vlink"})
+ %small (#{link_to "read more", help_permissions_path, class: "vlink"})
%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
+ = 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
%hr
- = render user.recent_events.limit(3)
- - if can? current_user, :admin_project, @project
- .form-horizontal
- .form-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 btn-danger"
-
+ = render @events
:javascript
$(function(){
$('.repo-access-select, .project-access-select').live("change", function() {
diff --git a/app/views/wikis/_form.html.haml b/app/views/wikis/_form.html.haml
index dbb8648d664..6b6411be55b 100644
--- a/app/views/wikis/_form.html.haml
+++ b/app/views/wikis/_form.html.haml
@@ -6,19 +6,21 @@
- @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
+ .main_box
+ .top_box_content
+ = f.label :title
+ .input= f.text_field :title, class: 'span8'
+ = f.hidden_field :slug
+ .middle_box_content
+ .input
+ %span.cgray
+ Wiki content is parsed with #{link_to "Markdown", "http://en.wikipedia.org/wiki/Markdown"}.
+ To add link to new page you can just type
+ %code [Link Title](page-slug)
+
+ .bottom_box_content
+ = f.label :content
+ .input= f.text_area :content, class: 'span8'
.actions
- = f.submit 'Save', :class => "primary btn"
- = link_to "Cancel", project_wiki_path(@project, :index), :class => "btn"
+ = 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
index 26cbd52a9a8..27d2a8f915f 100644
--- a/app/views/wikis/edit.html.haml
+++ b/app/views/wikis/edit.html.haml
@@ -1,3 +1,3 @@
-%h3 Editing page
+%h3.page_title Editing page
%hr
= render 'form'
diff --git a/app/views/wikis/empty.html.haml b/app/views/wikis/empty.html.haml
new file mode 100644
index 00000000000..32b1c9258c5
--- /dev/null
+++ b/app/views/wikis/empty.html.haml
@@ -0,0 +1,4 @@
+%h3.page_title Empty page
+%hr
+.alert-message.block-message.warning
+ %span You are not allowed to create wiki pages
diff --git a/app/views/wikis/history.html.haml b/app/views/wikis/history.html.haml
index 6a9b56ae771..e31c5dc2426 100644
--- a/app/views/wikis/history.html.haml
+++ b/app/views/wikis/history.html.haml
@@ -1,5 +1,8 @@
-%h3 Versions
-%table
+%h3.page_title
+ %span.cgray History for
+ = @wikis.last.title
+%br
+%table.admin-table
%thead
%tr
%th #
@@ -10,7 +13,7 @@
%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)
+ = 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/pages.html.haml b/app/views/wikis/pages.html.haml
new file mode 100644
index 00000000000..2bfd0deb149
--- /dev/null
+++ b/app/views/wikis/pages.html.haml
@@ -0,0 +1,18 @@
+%h3.page_title All Pages
+%br
+%table.admin-table
+ %thead
+ %tr
+ %th Title
+ %th slug
+ %th created by
+ %tbody
+ - @wikis.each_with_index do |wiki_page, i|
+ %tr
+ %td
+ = link_to wiki_page.title, project_wiki_path(@project, wiki_page, old_page_id: wiki_page.id)
+ (#{time_ago_in_words(wiki_page.created_at)}
+ ago)
+ %td= wiki_page.slug
+ %td= wiki_page.user.name
+
diff --git a/app/views/wikis/show.html.haml b/app/views/wikis/show.html.haml
index 9aa287dff07..fc2352271d5 100644
--- a/app/views/wikis/show.html.haml
+++ b/app/views/wikis/show.html.haml
@@ -1,17 +1,24 @@
-%h3
+%h3.page_title
= @wiki.title
%span.right
+ = link_to pages_project_wikis_path(@project), class: "btn small grouped" do
+ Pages
- if can? current_user, :write_wiki, @project
- = link_to history_project_wiki_path(@project, @wiki), :class => "btn small grouped" do
+ = link_to history_project_wiki_path(@project, @wiki), class: "btn small grouped" do
History
- = link_to edit_project_wiki_path(@project, @wiki), :class => "btn small grouped" do
+ = link_to edit_project_wiki_path(@project, @wiki), class: "btn small grouped" do
+ %i.icon-edit
Edit
-%hr
-.wiki_content
- = preserve do
- = markdown @wiki.content
+%br
+.file_holder
+ .file_content.wiki
+ = preserve do
+ = markdown @wiki.content
%p.time Last edited by #{@wiki.user.name}, #{time_ago_in_words @wiki.created_at} ago
- 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
+ = link_to project_wiki_path(@project, @wiki), confirm: "Are you sure you want to delete this page?", method: :delete do
Delete this page
+
+%hr
+.wiki_notes#notes= render "notes/notes", tid: @wiki.id, tt: "wiki"
diff --git a/app/workers/system_hook_worker.rb b/app/workers/system_hook_worker.rb
new file mode 100644
index 00000000000..ca154136b97
--- /dev/null
+++ b/app/workers/system_hook_worker.rb
@@ -0,0 +1,7 @@
+class SystemHookWorker
+ @queue = :system_hook
+
+ def self.perform(hook_id, data)
+ SystemHook.find(hook_id).execute data
+ end
+end
diff --git a/config/application.rb b/config/application.rb
index 3585c4b0a87..ecd88b15d15 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, :activity_observer, :project_observer, :key_observer, :issue_observer, :user_observer
+ config.active_record.observers = :mailer_observer, :activity_observer, :project_observer, :key_observer, :issue_observer, :user_observer, :system_hook_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.
@@ -44,5 +44,8 @@ module Gitlab
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
+
+ # Add fonts
+ config.assets.paths << "#{Rails.root}/app/assets/fonts"
end
end
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 1818f2c0d01..be36ee6da0d 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -1,4 +1,4 @@
-# # # # # # # # # # # # # # # # # #
+# # # # # # # # # # # # # # # # # #
# Gitlab application config file #
# # # # # # # # # # # # # # # # # #
@@ -19,14 +19,14 @@ email:
# Application specific settings
# Like default project limit for user etc
-app:
- default_projects_limit: 10
+app:
+ default_projects_limit: 10
# backup_path: "/vol/backups" # default: Rails.root + backups/
# backup_keep_time: 604800 # default: 0 (forever) (in seconds)
+ # disable_gravatar: true # default: false - Disable user avatars from Gravatar.com
-
-#
-# 2. Advanced settings:
+#
+# 2. Advanced settings:
# ==========================
# Git Hosting configuration
@@ -39,7 +39,6 @@ git_host:
receive_pack: true
# port: 22
-
# Git settings
# Use default values unless you understand it
git:
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 5c5987a8857..8165d6c2eea 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -111,5 +111,9 @@ class Settings < Settingslogic
def backup_keep_time
app['backup_keep_time'] || 0
end
+
+ def disable_gravatar?
+ app['disable_gravatar'] || false
+ end
end
end
diff --git a/config/initializers/grack_auth.rb b/config/initializers/grack_auth.rb
index 5995b873de9..4f77c327373 100644
--- a/config/initializers/grack_auth.rb
+++ b/config/initializers/grack_auth.rb
@@ -42,13 +42,13 @@ module Grack
def current_ref
if @env["HTTP_CONTENT_ENCODING"] =~ /gzip/
- input = Zlib::GzipReader.new(@request.body).string
+ input = Zlib::GzipReader.new(@request.body).read
else
- input = @request.body.string
+ input = @request.body.read
end
-
- oldrev, newrev, ref = input.split(' ')
- /refs\/heads\/([\w-]+)/.match(ref).to_a.last
+ # Need to reset seek point
+ @request.body.rewind
+ /refs\/heads\/([\w-]+)/.match(input).to_a.first
end
end# Auth
end# Grack
diff --git a/config/initializers/omniauth.rb.sample b/config/initializers/omniauth.rb.sample
index 8728472f076..6e844efde23 100644
--- a/config/initializers/omniauth.rb.sample
+++ b/config/initializers/omniauth.rb.sample
@@ -2,7 +2,7 @@
# The wiki has further details on configuring each provider.
Devise.setup do |config|
- # config.omniauth :github 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo'
+ # config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo'
# config.omniauth :ldap,
# :host => 'YOUR_LDAP_SERVER',
@@ -12,4 +12,4 @@ Devise.setup do |config|
# :method => :plain,
# :bind_dn => 'THE_FULL_DN_OF_THE_USER_YOU_WILL_BIND_WITH',
# :password => 'THE_PASSWORD_OF_THE_BIND_USER'
-end \ No newline at end of file
+end
diff --git a/config/initializers/rails_footnotes.rb b/config/initializers/rails_footnotes.rb
deleted file mode 100644
index afe6f3ad383..00000000000
--- a/config/initializers/rails_footnotes.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-#if defined?(Footnotes) && Rails.env.development?
- #Footnotes.run! # first of all
-#end
diff --git a/config/routes.rb b/config/routes.rb
index 73b9f643ad5..f895478fb12 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -28,6 +28,9 @@ Gitlab::Application.routes.draw do
get 'help/workflow' => 'help#workflow'
get 'help/api' => 'help#api'
get 'help/web_hooks' => 'help#web_hooks'
+ get 'help/system_hooks' => 'help#system_hooks'
+ get 'help/markdown' => 'help#markdown'
+ get 'help/ssh' => 'help#ssh'
#
# Admin Area
@@ -47,11 +50,13 @@ Gitlab::Application.routes.draw do
end
end
resources :team_members, :only => [:edit, :update, :destroy]
- get 'emails', :to => 'mailer#preview'
get 'mailer/preview_note'
get 'mailer/preview_user_new'
get 'mailer/preview_issue_new'
+ resources :hooks, :only => [:index, :create, :destroy] do
+ get :test
+ end
resource :logs
resource :resque, :controller => 'resque'
root :to => "dashboard#index"
@@ -94,6 +99,10 @@ Gitlab::Application.routes.draw do
end
resources :wikis, :only => [:show, :edit, :destroy, :create] do
+ collection do
+ get :pages
+ end
+
member do
get "history"
end
@@ -188,13 +197,20 @@ Gitlab::Application.routes.draw do
end
resources :team_members
resources :milestones
+ resources :labels, :only => [:index]
resources :issues do
+
collection do
post :sort
+ post :bulk_update
get :search
end
end
- resources :notes, :only => [:index, :create, :destroy]
+ resources :notes, :only => [:index, :create, :destroy] do
+ collection do
+ post :preview
+ end
+ end
end
root :to => "dashboard#index"
end
diff --git a/db/migrate/20120712080407_add_type_to_web_hook.rb b/db/migrate/20120712080407_add_type_to_web_hook.rb
new file mode 100644
index 00000000000..18ab024c817
--- /dev/null
+++ b/db/migrate/20120712080407_add_type_to_web_hook.rb
@@ -0,0 +1,5 @@
+class AddTypeToWebHook < ActiveRecord::Migration
+ def change
+ add_column :web_hooks, :type, :string, :default => "ProjectHook"
+ end
+end
diff --git a/db/migrate/20120729131232_add_extern_auth_provider_to_users.rb b/db/migrate/20120729131232_add_extern_auth_provider_to_users.rb
new file mode 100644
index 00000000000..d5e66ba4d3b
--- /dev/null
+++ b/db/migrate/20120729131232_add_extern_auth_provider_to_users.rb
@@ -0,0 +1,8 @@
+class AddExternAuthProviderToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :extern_uid, :string
+ add_column :users, :provider, :string
+
+ add_index :users, [:extern_uid, :provider], :unique => true
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index f40ee260dc3..46461e44aad 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20120706065612) do
+ActiveRecord::Schema.define(:version => 20120729131232) do
create_table "events", :force => true do |t|
t.string "target_type"
@@ -171,9 +171,12 @@ ActiveRecord::Schema.define(:version => 20120706065612) do
t.boolean "blocked", :default => false, :null => false
t.integer "failed_attempts", :default => 0
t.datetime "locked_at"
+ t.string "extern_uid"
+ t.string "provider"
end
add_index "users", ["email"], :name => "index_users_on_email", :unique => true
+ add_index "users", ["extern_uid", "provider"], :name => "index_users_on_extern_uid_and_provider", :unique => true
add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true
create_table "users_projects", :force => true do |t|
@@ -187,8 +190,9 @@ ActiveRecord::Schema.define(:version => 20120706065612) do
create_table "web_hooks", :force => true do |t|
t.string "url"
t.integer "project_id"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ t.string "type", :default => "ProjectHook"
end
create_table "wikis", :force => true do |t|
diff --git a/doc/api/README.md b/doc/api/README.md
index dcf75afda1f..d32573aaa6b 100644
--- a/doc/api/README.md
+++ b/doc/api/README.md
@@ -27,3 +27,5 @@ The API uses JSON to serialize data. You don't need to specify `.json` at the en
+ [Users](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/users.md)
+ [Projects](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/projects.md)
++ [Snippets](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/snippets.md)
++ [Issues](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/issues.md)
diff --git a/doc/api/issues.md b/doc/api/issues.md
new file mode 100644
index 00000000000..aaad3305489
--- /dev/null
+++ b/doc/api/issues.md
@@ -0,0 +1,184 @@
+## List issues
+
+Get all issues created by authenticed user.
+
+```
+GET /issues
+```
+
+```json
+[
+ {
+ "id": 43,
+ "project_id": 8,
+ "title": "4xx/5xx pages",
+ "description": "",
+ "labels": [ ],
+ "milestone": null,
+ "assignee": null,
+ "author": {
+ "id": 1,
+ "email": "john@example.com",
+ "name": "John Smith",
+ "blocked": false,
+ "created_at": "2012-05-23T08:00:58Z"
+ },
+ "closed": true,
+ "updated_at": "2012-07-02T17:53:12Z",
+ "created_at": "2012-07-02T17:53:12Z"
+ },
+ {
+ "id": 42,
+ "project_id": 8,
+ "title": "Add user settings",
+ "description": "",
+ "labels": [
+ "feature"
+ ],
+ "milestone": {
+ "id": 1,
+ "title": "v1.0",
+ "description": "",
+ "due_date": "2012-07-20",
+ "closed": false,
+ "updated_at": "2012-07-04T13:42:48Z",
+ "created_at": "2012-07-04T13:42:48Z"
+ },
+ "assignee": {
+ "id": 2,
+ "email": "jack@example.com",
+ "name": "Jack Smith",
+ "blocked": false,
+ "created_at": "2012-05-23T08:01:01Z"
+ },
+ "author": {
+ "id": 1,
+ "email": "john@example.com",
+ "name": "John Smith",
+ "blocked": false,
+ "created_at": "2012-05-23T08:00:58Z"
+ },
+ "closed": false,
+ "updated_at": "2012-07-12T13:43:19Z",
+ "created_at": "2012-06-28T12:58:06Z"
+ }
+]
+```
+
+## List project issues
+
+Get a list of project issues.
+
+```
+GET /projects/:id/issues
+```
+
+Parameters:
+
++ `id` (required) - The ID or code name of a project
+
+## Single issue
+
+Get a project issue.
+
+```
+GET /projects/:id/issues/:issue_id
+```
+
+Parameters:
+
++ `id` (required) - The ID or code name of a project
++ `issue_id` (required) - The ID of a project issue
+
+```json
+{
+ "id": 42,
+ "project_id": 8,
+ "title": "Add user settings",
+ "description": "",
+ "labels": [
+ "feature"
+ ],
+ "milestone": {
+ "id": 1,
+ "title": "v1.0",
+ "description": "",
+ "due_date": "2012-07-20",
+ "closed": false,
+ "updated_at": "2012-07-04T13:42:48Z",
+ "created_at": "2012-07-04T13:42:48Z"
+ },
+ "assignee": {
+ "id": 2,
+ "email": "jack@example.com",
+ "name": "Jack Smith",
+ "blocked": false,
+ "created_at": "2012-05-23T08:01:01Z"
+ },
+ "author": {
+ "id": 1,
+ "email": "john@example.com",
+ "name": "John Smith",
+ "blocked": false,
+ "created_at": "2012-05-23T08:00:58Z"
+ },
+ "closed": false,
+ "updated_at": "2012-07-12T13:43:19Z",
+ "created_at": "2012-06-28T12:58:06Z"
+}
+```
+
+## New issue
+
+Create a new project issue.
+
+```
+POST /projects/:id/issues
+```
+
+Parameters:
+
++ `id` (required) - The ID or code name of a project
++ `title` (required) - The title of an issue
++ `description` (optional) - The description of an issue
++ `assignee_id` (optional) - The ID of a user to assign issue
++ `milestone_id` (optional) - The ID of a milestone to assign issue
++ `labels` (optional) - Comma-separated label names for an issue
+
+Will return created issue with status `201 Created` on success, or `404 Not found` on fail.
+
+## Edit issue
+
+Update an existing project issue.
+
+```
+PUT /projects/:id/issues/:issue_id
+```
+
+Parameters:
+
++ `id` (required) - The ID or code name of a project
++ `issue_id` (required) - The ID of a project's issue
++ `title` (optional) - The title of an issue
++ `description` (optional) - The description of an issue
++ `assignee_id` (optional) - The ID of a user to assign issue
++ `milestone_id` (optional) - The ID of a milestone to assign issue
++ `labels` (optional) - Comma-separated label names for an issue
++ `closed` (optional) - The state of an issue (0 = false, 1 = true)
+
+Will return updated issue with status `200 OK` on success, or `404 Not found` on fail.
+
+## Delete issue
+
+Delete existing project issue.
+
+```
+DELETE /projects/:id/issues/:issue_id
+```
+
+Parameters:
+
++ `id` (required) - The ID or code name of a project
++ `issue_id` (required) - The ID of a project's issue
+
+Status code `200` will be returned on success.
diff --git a/doc/api/projects.md b/doc/api/projects.md
index c748745e063..d680b5d8597 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -1,6 +1,6 @@
## List projects
-Get a list of authenticated users' projects.
+Get a list of authenticated user's projects.
```
GET /projects
@@ -63,7 +63,7 @@ GET /projects/:id
Parameters:
-+ `id` (required) - The code name of a project
++ `id` (required) - The ID or code name of a project
```json
{
@@ -91,7 +91,7 @@ Parameters:
## Project repository branches
-Get a list of project repository branches.
+Get a list of project repository branches sorted by name alphabetically.
```
GET /projects/:id/repository/branches
@@ -99,7 +99,7 @@ GET /projects/:id/repository/branches
Parameters:
-+ `id` (required) - The code name of a project
++ `id` (required) - The ID or code name of a project
```json
[
@@ -129,9 +129,46 @@ Parameters:
]
```
+Get a single project repository branch.
+
+```
+GET /projects/:id/repository/branches/:branch
+```
+
+Parameters:
+
++ `id` (required) - The ID or code name of a project
++ `branch` (required) - The name of the branch
+
+```json
+{
+ "name": "master",
+ "commit": {
+ "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c",
+ "parents": [
+ {
+ "id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8"
+ }
+ ],
+ "tree": "46e82de44b1061621357f24c05515327f2795a95",
+ "message": "add projects API",
+ "author": {
+ "name": "John Smith",
+ "email": "john@example.com"
+ },
+ "committer": {
+ "name": "John Smith",
+ "email": "john@example.com"
+ },
+ "authored_date": "2012-06-27T05:51:39-07:00",
+ "committed_date": "2012-06-28T03:44:20-07:00"
+ }
+}
+```
+
## Project repository tags
-Get a list of project repository tags.
+Get a list of project repository tags sorted by name in reverse alphabetical order.
```
GET /projects/:id/repository/tags
@@ -139,7 +176,7 @@ GET /projects/:id/repository/tags
Parameters:
-+ `id` (required) - The code name of a project
++ `id` (required) - The ID or code name of a project
```json
[
@@ -167,104 +204,18 @@ Parameters:
]
```
-# Project Snippets
-
-## List snippets
-
-Not implemented.
-
-## Single snippet
-
-Get a project snippet.
-
-```
-GET /projects/:id/snippets/:snippet_id
-```
-
-Parameters:
-
-+ `id` (required) - The code name of a project
-+ `snippet_id` (required) - The ID of a project's snippet
-
-```json
-{
- "id": 1,
- "title": "test",
- "file_name": "add.rb",
- "author": {
- "id": 1,
- "email": "john@example.com",
- "name": "John Smith",
- "blocked": false,
- "created_at": "2012-05-23T08:00:58Z"
- },
- "expires_at": null,
- "updated_at": "2012-06-28T10:52:04Z",
- "created_at": "2012-06-28T10:52:04Z"
-}
-```
-
-## Snippet content
-
-Get a raw project snippet.
-
-```
-GET /projects/:id/snippets/:snippet_id/raw
-```
-
-Parameters:
-
-+ `id` (required) - The code name of a project
-+ `snippet_id` (required) - The ID of a project's snippet
-
-## New snippet
-
-Create a new project snippet.
-
-```
-POST /projects/:id/snippets
-```
-
-Parameters:
-
-+ `id` (required) - The code name of a project
-+ `title` (required) - The title of a snippet
-+ `file_name` (required) - The name of a snippet file
-+ `lifetime` (optional) - The expiration date of a snippet
-+ `code` (required) - The content of a snippet
-
-Will return created snippet with status `201 Created` on success, or `404 Not found` on fail.
-
-## Edit snippet
-
-Update an existing project snippet.
-
-```
-PUT /projects/:id/snippets/:snippet_id
-```
-
-Parameters:
-
-+ `id` (required) - The code name of a project
-+ `snippet_id` (required) - The ID of a project's snippet
-+ `title` (optional) - The title of a snippet
-+ `file_name` (optional) - The name of a snippet file
-+ `lifetime` (optional) - The expiration date of a snippet
-+ `code` (optional) - The content of a snippet
-
-Will return updated snippet with status `200 OK` on success, or `404 Not found` on fail.
-
-## Delete snippet
+## Raw blob content
-Delete existing project snippet.
+Get the raw file contents for a file.
```
-DELETE /projects/:id/snippets/:snippet_id
+GET /projects/:id/repository/commits/:sha/blob
```
Parameters:
-+ `id` (required) - The code name of a project
-+ `snippet_id` (required) - The ID of a project's snippet
++ `id` (required) - The ID or code name of a project
++ `sha` (required) - The commit or branch name
++ `filepath` (required) - The path the file
-Status code `200` will be returned on success.
+Will return the raw file contents.
diff --git a/doc/api/snippets.md b/doc/api/snippets.md
new file mode 100644
index 00000000000..0cd29ce530b
--- /dev/null
+++ b/doc/api/snippets.md
@@ -0,0 +1,100 @@
+## List snippets
+
+Not implemented.
+
+## Single snippet
+
+Get a project snippet.
+
+```
+GET /projects/:id/snippets/:snippet_id
+```
+
+Parameters:
+
++ `id` (required) - The ID or code name of a project
++ `snippet_id` (required) - The ID of a project's snippet
+
+```json
+{
+ "id": 1,
+ "title": "test",
+ "file_name": "add.rb",
+ "author": {
+ "id": 1,
+ "email": "john@example.com",
+ "name": "John Smith",
+ "blocked": false,
+ "created_at": "2012-05-23T08:00:58Z"
+ },
+ "expires_at": null,
+ "updated_at": "2012-06-28T10:52:04Z",
+ "created_at": "2012-06-28T10:52:04Z"
+}
+```
+
+## Snippet content
+
+Get a raw project snippet.
+
+```
+GET /projects/:id/snippets/:snippet_id/raw
+```
+
+Parameters:
+
++ `id` (required) - The ID or code name of a project
++ `snippet_id` (required) - The ID of a project's snippet
+
+## New snippet
+
+Create a new project snippet.
+
+```
+POST /projects/:id/snippets
+```
+
+Parameters:
+
++ `id` (required) - The ID or code name of a project
++ `title` (required) - The title of a snippet
++ `file_name` (required) - The name of a snippet file
++ `lifetime` (optional) - The expiration date of a snippet
++ `code` (required) - The content of a snippet
+
+Will return created snippet with status `201 Created` on success, or `404 Not found` on fail.
+
+## Edit snippet
+
+Update an existing project snippet.
+
+```
+PUT /projects/:id/snippets/:snippet_id
+```
+
+Parameters:
+
++ `id` (required) - The ID or code name of a project
++ `snippet_id` (required) - The ID of a project's snippet
++ `title` (optional) - The title of a snippet
++ `file_name` (optional) - The name of a snippet file
++ `lifetime` (optional) - The expiration date of a snippet
++ `code` (optional) - The content of a snippet
+
+Will return updated snippet with status `200 OK` on success, or `404 Not found` on fail.
+
+## Delete snippet
+
+Delete existing project snippet.
+
+```
+DELETE /projects/:id/snippets/:snippet_id
+```
+
+Parameters:
+
++ `id` (required) - The ID or code name of a project
++ `snippet_id` (required) - The ID of a project's snippet
+
+Status code `200` will be returned on success.
+
diff --git a/doc/debian_ubuntu.sh b/doc/debian_ubuntu.sh
index 11533285849..a0b4710b5eb 100644
--- a/doc/debian_ubuntu.sh
+++ b/doc/debian_ubuntu.sh
@@ -3,7 +3,7 @@
sudo apt-get update
sudo apt-get upgrade
-sudo apt-get install -y git git-core wget curl gcc checkinstall libxml2-dev libxslt-dev sqlite3 libsqlite3-dev libcurl4-openssl-dev libreadline-gplv2-dev libc6-dev libssl-dev libmysql++-dev make build-essential zlib1g-dev libicu-dev redis-server openssh-server python-dev python-pip libyaml-dev
+sudo apt-get install -y git git-core wget curl gcc checkinstall libxml2-dev libxslt-dev sqlite3 libsqlite3-dev libcurl4-openssl-dev libreadline-gplv2-dev libc6-dev libssl-dev libmysql++-dev make build-essential zlib1g-dev libicu-dev redis-server openssh-server python-dev python-pip libyaml-dev postfix
wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p194.tar.gz
tar xfvz ruby-1.9.3-p194.tar.gz
diff --git a/doc/installation.md b/doc/installation.md
index 3dfedfe10ad..1d32e1b7582 100644
--- a/doc/installation.md
+++ b/doc/installation.md
@@ -60,7 +60,7 @@ Also read the [Read this before you submit an issue](https://github.com/gitlabhq
sudo apt-get update
sudo apt-get upgrade
- sudo apt-get install -y wget curl gcc checkinstall libxml2-dev libxslt-dev sqlite3 libsqlite3-dev libcurl4-openssl-dev libreadline6-dev libc6-dev libssl-dev libmysql++-dev make build-essential zlib1g-dev libicu-dev redis-server openssh-server git-core python-dev python-pip libyaml-dev sendmail
+ sudo apt-get install -y wget curl gcc checkinstall libxml2-dev libxslt-dev sqlite3 libsqlite3-dev libcurl4-openssl-dev libreadline6-dev libc6-dev libssl-dev libmysql++-dev make build-essential zlib1g-dev libicu-dev redis-server openssh-server git-core python-dev python-pip libyaml-dev postfix
# If you want to use MySQL:
sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev
@@ -133,7 +133,7 @@ Permissions:
# 4. Install gitlab and configuration. Check status configuration.
- sudo gem install charlock_holmes
+ sudo gem install charlock_holmes --version '0.6.8'
sudo pip install pygments
sudo gem install bundler
cd /home/gitlab
@@ -152,8 +152,22 @@ Permissions:
# Or
# Mysql
+ # Install MySQL as directed in Step #1
+
+ # Login to MySQL
+ $ mysql -u root -p
+
+ # Create the gitlabhq production database
+ mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`;
+
+ # Create the MySQL User change $password to a real password
+ mysql> CREATE USER 'gitlab'@'localhost' IDENTIFIED BY '$password';
+
+ # Grant proper permissions to the MySQL User
+ mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost';
+
+ # Exit MySQL Server and copy the example config, make sure to update username/password in config/database.yml
sudo -u gitlab cp config/database.yml.example config/database.yml
- # Change username/password of config/database.yml to real one
#### Install gems
@@ -162,6 +176,11 @@ Permissions:
#### Setup DB
sudo -u gitlab bundle exec rake gitlab:app:setup RAILS_ENV=production
+
+#### Setup gitlab hooks
+
+ sudo cp ./lib/hooks/post-receive /home/git/share/gitolite/hooks/common/post-receive
+ sudo chown git:git /home/git/share/gitolite/hooks/common/post-receive
Checking status:
@@ -181,6 +200,7 @@ Checking status:
Resolving deltas: 100% (174/174), done.
Can clone gitolite-admin?............YES
UMASK for .gitolite.rc is 0007? ............YES
+ /home/git/share/gitolite/hooks/common/post-receive exists? ............YES
If you got all YES - congrats! You can go to next step.
@@ -194,14 +214,20 @@ Application can be started with next command:
# As daemon
sudo -u gitlab bundle exec rails s -e production -d
+You can login via web using admin generated with setup:
+
+ admin@local.host
+ 5iveL!fe
+
# 6. Run resque process (for processing queue).
# Manually
sudo -u gitlab bundle exec rake environment resque:work QUEUE=* RAILS_ENV=production BACKGROUND=yes
# Gitlab start script
- ./resque.sh
-
+ sudo -u gitlab ./resque.sh
+ # if you run this as root /home/gitlab/gitlab/tmp/pids/resque_worker.pid will be owned by root
+ # causing the resque worker not to start via init script on next boot/service restart
**Ok - we have a working application now. **
**But keep going - there are some thing that should be done **
@@ -301,13 +327,11 @@ Create init script in /etc/init.d/gitlab:
restart)
echo -n "Restarting $DESC: "
kill -USR2 `cat $PID`
- kill -USR2 `cat $RESQUE_PID`
echo "$NAME."
;;
reload)
echo -n "Reloading $DESC configuration: "
kill -HUP `cat $PID`
- kill -HUP `cat $RESQUE_PID`
echo "$NAME."
;;
*)
diff --git a/features/dashboard/dashboard.feature b/features/dashboard/dashboard.feature
index 2d66af53b7b..a8c2205c143 100644
--- a/features/dashboard/dashboard.feature
+++ b/features/dashboard/dashboard.feature
@@ -10,7 +10,7 @@ Feature: Dashboard
Then I should see "Shop" project link
Then I should see project "Shop" activity feed
- Scenario: I should see last pish widget
+ Scenario: I should see last push widget
Then I should see last push widget
And I click "Create Merge Request" link
Then I see prefilled new Merge Request page
diff --git a/features/dashboard/issues.feature b/features/dashboard/issues.feature
new file mode 100644
index 00000000000..c3361bb313f
--- /dev/null
+++ b/features/dashboard/issues.feature
@@ -0,0 +1,8 @@
+Feature: Dashboard Issues
+ Background:
+ Given I signin as a user
+ And I have assigned issues
+ And I visit dashboard issues page
+
+ Scenario: I should see issues list
+ Then I should see issues assigned to me
diff --git a/features/dashboard/merge_requests.feature b/features/dashboard/merge_requests.feature
new file mode 100644
index 00000000000..90b8749c5a7
--- /dev/null
+++ b/features/dashboard/merge_requests.feature
@@ -0,0 +1,8 @@
+Feature: Dashboard MR
+ Background:
+ Given I signin as a user
+ And I have authored merge requests
+ And I visit dashboard merge requests page
+
+ Scenario: I should see projects list
+ Then I should see my merge requests
diff --git a/features/profile/profile.feature b/features/profile/profile.feature
index e3d71abc746..afda4b55081 100644
--- a/features/profile/profile.feature
+++ b/features/profile/profile.feature
@@ -6,6 +6,11 @@ Feature: Profile
Given I visit profile page
Then I should see my profile info
+ Scenario: I edit profile
+ Given I visit profile page
+ Then I change my contact info
+ And I should see new contact info
+
Scenario: I change my password
Given I visit profile password page
Then I change my password
@@ -15,4 +20,3 @@ Feature: Profile
Given I visit profile token page
Then I reset my token
And I should see new token
-
diff --git a/features/projects/commits/branches.feature b/features/projects/commits/branches.feature
index 2b136e1b582..74575c51c5a 100644
--- a/features/projects/commits/branches.feature
+++ b/features/projects/commits/branches.feature
@@ -2,9 +2,19 @@ Feature: Browse branches
Background:
Given I signin as a user
And I own project "Shop"
+ And project "Shop" has protected branches
Given I visit project branches page
- Scenario: I can see all git branches
+ Scenario: I can see project recent git branches
+ Then I should see "Shop" recent branches list
+
+ Scenario: I can see project all git branches
+ Given I click link "All"
+ Then I should see "Shop" all branches list
+
+ Scenario: I can see project protected git branches
+ Given I click link "Protected"
+ Then I should see "Shop" protected branches list
Scenario: I can download project by branch
diff --git a/features/projects/commits/commit_comments.feature b/features/projects/commits/commit_comments.feature
index bdf47b88fc3..9bd56d29f1e 100644
--- a/features/projects/commits/commit_comments.feature
+++ b/features/projects/commits/commit_comments.feature
@@ -4,4 +4,7 @@ Feature: Comment commit
And I own project "Shop"
Given I visit project commit page
- Scenario: I leave a comment for commit
+ @javascript
+ Scenario: I comment commit
+ Given I leave a comment like "XML attached"
+ Then I should see comment "XML attached"
diff --git a/features/projects/commits/tags.feature b/features/projects/commits/tags.feature
index 81221748500..f7899fc3ce0 100644
--- a/features/projects/commits/tags.feature
+++ b/features/projects/commits/tags.feature
@@ -5,7 +5,6 @@ Feature: Browse tags
Given I visit project tags page
Scenario: I can see all git tags
+ Then I should see "Shop" all tags list
Scenario: I can download project by tag
-
-
diff --git a/features/projects/issues/issues.feature b/features/projects/issues/issues.feature
index 0ca0792dd8a..180710cf6bc 100644
--- a/features/projects/issues/issues.feature
+++ b/features/projects/issues/issues.feature
@@ -7,6 +7,32 @@ Feature: Issues
And I visit project "Shop" issues page
Scenario: I should see open issues
- Given I should see "Release 0.4" open issue
- And I should not see "Release 0.3" closed issue
+ Given I should see "Release 0.4" in issues
+ And I should not see "Release 0.3" in issues
+ Scenario: I should see closed issues
+ Given I click link "Closed"
+ Then I should see "Release 0.3" in issues
+ And I should not see "Release 0.4" in issues
+
+ Scenario: I should see all issues
+ Given I click link "All"
+ Then I should see "Release 0.3" in issues
+ And I should see "Release 0.4" in issues
+
+ Scenario: I visit issue page
+ Given I click link "Release 0.4"
+ Then I should see issue "Release 0.4"
+
+ @javascript
+ Scenario: I submit new unassigned issue
+ Given I click link "New Issue"
+ And I submit new issue "500 error on profile"
+ Given I click link "500 error on profile"
+ Then I should see issue "500 error on profile"
+
+ @javascript
+ Scenario: I comment issue
+ Given I visit issue page "Release 0.4"
+ And I leave a comment like "XML attached"
+ Then I should see comment "XML attached"
diff --git a/features/projects/issues/labels.feature b/features/projects/issues/labels.feature
new file mode 100644
index 00000000000..5a20bfd6d14
--- /dev/null
+++ b/features/projects/issues/labels.feature
@@ -0,0 +1,13 @@
+Feature: Labels
+ Background:
+ Given I signin as a user
+ And I own project "Shop"
+ And project "Shop" have issues tags:
+ | name |
+ | bug |
+ | feature |
+ Given I visit project "Shop" labels page
+
+ Scenario: I should see active milestones
+ Then I should see label "bug"
+ And I should see label "feature"
diff --git a/features/projects/issues/milestones.feature b/features/projects/issues/milestones.feature
index e69de29bb2d..d78096a4f16 100644
--- a/features/projects/issues/milestones.feature
+++ b/features/projects/issues/milestones.feature
@@ -0,0 +1,18 @@
+Feature: Milestones
+ Background:
+ Given I signin as a user
+ And I own project "Shop"
+ And project "Shop" has milestone "v2.2"
+ Given I visit project "Shop" milestones page
+
+ Scenario: I should see active milestones
+ Then I should see milestone "v2.2"
+
+ Scenario: I should see milestone
+ Given I click link "v2.2"
+ Then I should see milestone "v2.2"
+
+ Scenario: I create new milestone
+ Given I click link "New Milestone"
+ And I submit new milestone "v2.3"
+ Then I should see milestone "v2.3"
diff --git a/features/projects/merge_requests.feature b/features/projects/merge_requests.feature
index e69de29bb2d..54b6ccde7f9 100644
--- a/features/projects/merge_requests.feature
+++ b/features/projects/merge_requests.feature
@@ -0,0 +1,42 @@
+Feature: Merge Requests
+ Background:
+ Given I signin as a user
+ And I own project "Shop"
+ And project "Shop" have "Bug NS-04" open merge request
+ And project "Shop" have "Feature NS-03" closed merge request
+ And I visit project "Shop" merge requests page
+
+ Scenario: I should see open merge requests
+ Then I should see "Bug NS-04" in merge requests
+ And I should not see "Feature NS-03" in merge requests
+
+ Scenario: I should see closed merge requests
+ Given I click link "Closed"
+ Then I should see "Feature NS-03" in merge requests
+ And I should not see "Bug NS-04" in merge requests
+
+ Scenario: I should see all merge requests
+ Given I click link "All"
+ Then I should see "Feature NS-03" in merge requests
+ And I should see "Bug NS-04" in merge requests
+
+ Scenario: I visit merge request page
+ Given I click link "Bug NS-04"
+ Then I should see merge request "Bug NS-04"
+
+ Scenario: I close merge request page
+ Given I click link "Bug NS-04"
+ And I click link "Close"
+ Then I should see closed merge request "Bug NS-04"
+
+ Scenario: I submit new unassigned merge request
+ Given I click link "New Merge Request"
+ And I submit new merge request "Wiki Feature"
+ Then I should see merge request "Wiki Feature"
+
+ @javascript
+ Scenario: I comment merge request
+ Given I visit merge request page "Bug NS-04"
+ And I leave a comment like "XML attached"
+ Then I should see comment "XML attached"
+
diff --git a/features/projects/network.feature b/features/projects/network.feature
index 9655184cfe1..61c05eb367e 100644
--- a/features/projects/network.feature
+++ b/features/projects/network.feature
@@ -4,9 +4,7 @@ Feature: Project Network Graph
Background:
Given I signin as a user
And I own project "Shop"
- And I visit project "Shop" network page
+ And I visit project "Shop" network page
Scenario: I should see project network
Then page should have network graph
-
-
diff --git a/features/projects/project.feature b/features/projects/project.feature
new file mode 100644
index 00000000000..895a928ff81
--- /dev/null
+++ b/features/projects/project.feature
@@ -0,0 +1,11 @@
+Feature: Project
+ Background:
+ Given I signin as a user
+ And I own project "Shop"
+ And I visit project "Shop" page
+
+ Scenario: I should see project activity
+
+ Scenario: I edit project
+
+ Scenario: I visit attachments
diff --git a/features/projects/source/browse_files.feature.commented b/features/projects/source/browse_files.feature
index 04aebc19732..04aebc19732 100644
--- a/features/projects/source/browse_files.feature.commented
+++ b/features/projects/source/browse_files.feature
diff --git a/features/projects/source/git_blame.feature b/features/projects/source/git_blame.feature
index e69de29bb2d..6aa6be47deb 100644
--- a/features/projects/source/git_blame.feature
+++ b/features/projects/source/git_blame.feature
@@ -0,0 +1,10 @@
+Feature: Browse git repo
+ Background:
+ Given I signin as a user
+ And I own project "Shop"
+ Given I visit project source page
+
+ Scenario: I blame file
+ Given I click on file from repo
+ And I click blame button
+ Then I should see git file blame
diff --git a/features/projects/wiki.feature b/features/projects/wiki.feature
index ed69e87c91a..4441ada2847 100644
--- a/features/projects/wiki.feature
+++ b/features/projects/wiki.feature
@@ -7,3 +7,9 @@ Feature: Wiki
Scenario: Add new page
Given I create Wiki page
Then I should see newly created wiki page
+
+ @javascript
+ Scenario: I comment wiki page
+ Given I create Wiki page
+ And I leave a comment like "XML attached"
+ Then I should see comment "XML attached"
diff --git a/features/step_definitions/dashboard_steps.rb b/features/step_definitions/dashboard_steps.rb
index 7133d799995..d910ec90d19 100644
--- a/features/step_definitions/dashboard_steps.rb
+++ b/features/step_definitions/dashboard_steps.rb
@@ -65,3 +65,63 @@ Given /^I search for "(.*?)"$/ do |arg1|
fill_in "dashboard_search", :with => arg1
click_button "Search"
end
+
+Given /^I visit dashboard issues page$/ do
+ visit dashboard_issues_path
+end
+
+Then /^I should see issues assigned to me$/ do
+ issues = @user.issues
+ issues.each do |issue|
+ page.should have_content(issue.title[0..10])
+ page.should have_content(issue.project.name)
+ end
+end
+
+Given /^I visit dashboard merge requests page$/ do
+ visit dashboard_merge_requests_path
+end
+
+Then /^I should see my merge requests$/ do
+ merge_requests = @user.merge_requests
+ merge_requests.each do |mr|
+ page.should have_content(mr.title[0..10])
+ page.should have_content(mr.project.name)
+ end
+end
+
+Given /^I have assigned issues$/ do
+ project = Factory :project
+ project.add_access(@user, :read, :write)
+
+ issue1 = Factory :issue,
+ :author => @user,
+ :assignee => @user,
+ :project => project
+
+ issue2 = Factory :issue,
+ :author => @user,
+ :assignee => @user,
+ :project => project
+end
+
+Given /^I have authored merge requests$/ do
+ project1 = Factory :project,
+ :path => "gitlabhq_1",
+ :code => "gitlabhq_1"
+
+ project2 = Factory :project,
+ :path => "gitlabhq_2",
+ :code => "gitlabhq_2"
+
+ project1.add_access(@user, :read, :write)
+ project2.add_access(@user, :read, :write)
+
+ merge_request1 = Factory :merge_request,
+ :author => @user,
+ :project => project1
+
+ merge_request2 = Factory :merge_request,
+ :author => @user,
+ :project => project2
+end
diff --git a/features/step_definitions/profile_keys_steps.rb b/features/step_definitions/profile/profile_keys_steps.rb
index 5ab7e0480ad..5ab7e0480ad 100644
--- a/features/step_definitions/profile_keys_steps.rb
+++ b/features/step_definitions/profile/profile_keys_steps.rb
diff --git a/features/step_definitions/profile_steps.rb b/features/step_definitions/profile/profile_steps.rb
index 7510c5365e1..4661139c180 100644
--- a/features/step_definitions/profile_steps.rb
+++ b/features/step_definitions/profile/profile_steps.rb
@@ -36,3 +36,16 @@ Then /^I should see new token$/ do
find("#token").value.should == @user.reload.private_token
end
+Then /^I change my contact info$/ do
+ fill_in "user_skype", :with => "testskype"
+ fill_in "user_linkedin", :with => "testlinkedin"
+ fill_in "user_twitter", :with => "testtwitter"
+ click_button "Save"
+ @user.reload
+end
+
+Then /^I should see new contact info$/ do
+ @user.skype.should == 'testskype'
+ @user.linkedin.should == 'testlinkedin'
+ @user.twitter.should == 'testtwitter'
+end
diff --git a/features/step_definitions/browse_code_steps.rb b/features/step_definitions/project/browse_code_steps.rb
index fc3cf56a83b..7f9001bb989 100644
--- a/features/step_definitions/browse_code_steps.rb
+++ b/features/step_definitions/project/browse_code_steps.rb
@@ -38,3 +38,13 @@ end
Then /^I should see raw file content$/ do
page.source.should == ValidCommit::BLOB_FILE
end
+
+Given /^I click blame button$/ do
+ click_link "blame"
+end
+
+Then /^I should see git file blame$/ do
+ page.should have_content("rubygems.org")
+ page.should have_content("Dmitriy Zaporozhets")
+ page.should have_content("bc3735004cb Moving to rails 3.2")
+end
diff --git a/features/step_definitions/project_commits_steps.rb b/features/step_definitions/project/project_commits_steps.rb
index 9bfccfc06ed..35fcb4d11ab 100644
--- a/features/step_definitions/project_commits_steps.rb
+++ b/features/step_definitions/project/project_commits_steps.rb
@@ -16,11 +16,11 @@ Given /^I click atom feed link$/ do
end
Then /^I see commits atom feed$/ do
- commit = @project.commit
+ commit = CommitDecorator.decorate(@project.commit)
page.response_headers['Content-Type'].should have_content("application/atom+xml")
page.body.should have_selector("title", :text => "Recent commits to #{@project.name}")
page.body.should have_selector("author email", :text => commit.author_email)
- page.body.should have_selector("entry summary", :text => commit.message)
+ page.body.should have_selector("entry summary", :text => commit.description)
end
Given /^I click on commit link$/ do
@@ -59,3 +59,30 @@ end
Given /^I visit project tags page$/ do
visit tags_project_repository_path(@project)
end
+
+Then /^I should see "(.*?)" recent branches list$/ do |arg1|
+ page.should have_content("Branches")
+ page.should have_content("master")
+end
+
+Then /^I should see "(.*?)" all branches list$/ do |arg1|
+ page.should have_content("Branches")
+ page.should have_content("master")
+end
+
+Then /^I should see "(.*?)" all tags list$/ do |arg1|
+ page.should have_content("Tags")
+ page.should have_content("v1.2.1")
+end
+
+Then /^I should see "(.*?)" protected branches list$/ do |arg1|
+ within "table" do
+ page.should have_content "stable"
+ page.should_not have_content "master"
+ end
+end
+
+Given /^project "(.*?)" has protected branches$/ do |arg1|
+ project = Project.find_by_name(arg1)
+ project.protected_branches.create(:name => "stable")
+end
diff --git a/features/step_definitions/project/project_issues_steps.rb b/features/step_definitions/project/project_issues_steps.rb
new file mode 100644
index 00000000000..27de03d5489
--- /dev/null
+++ b/features/step_definitions/project/project_issues_steps.rb
@@ -0,0 +1,57 @@
+Given /^project "(.*?)" have "(.*?)" open issue$/ do |arg1, arg2|
+ project = Project.find_by_name(arg1)
+ Factory.create(:issue, :title => arg2, :project => project, :author => project.users.first)
+end
+
+Given /^project "(.*?)" have "(.*?)" closed issue$/ do |arg1, arg2|
+ project = Project.find_by_name(arg1)
+ Factory.create(:issue, :title => arg2, :project => project, :author => project.users.first, :closed => true)
+end
+
+Given /^I visit project "(.*?)" issues page$/ do |arg1|
+ visit project_issues_path(Project.find_by_name(arg1))
+end
+
+Given /^I should see "(.*?)" in issues$/ do |arg1|
+ page.should have_content arg1
+end
+
+Given /^I should not see "(.*?)" in issues$/ do |arg1|
+ page.should_not have_content arg1
+end
+
+Then /^I should see issue "(.*?)"$/ do |arg1|
+ issue = Issue.find_by_title(arg1)
+ page.should have_content issue.title
+ page.should have_content issue.author_name
+ page.should have_content issue.project.name
+end
+
+Given /^I visit issue page "(.*?)"$/ do |arg1|
+ issue = Issue.find_by_title(arg1)
+ visit project_issue_path(issue.project, issue)
+end
+
+Given /^I submit new issue "(.*?)"$/ do |arg1|
+ fill_in "issue_title", with: arg1
+ click_button "Submit new issue"
+end
+
+Given /^project "(.*?)" have issues tags:$/ do |arg1, table|
+ project = Project.find_by_name(arg1)
+ table.hashes.each do |hash|
+ Factory :issue,
+ project: project,
+ label_list: [hash[:name]]
+ end
+end
+
+Given /^I visit project "(.*?)" labels page$/ do |arg1|
+ visit project_labels_path(Project.find_by_name(arg1))
+end
+
+Then /^I should see label "(.*?)"$/ do |arg1|
+ within ".labels-table" do
+ page.should have_content arg1
+ end
+end
diff --git a/features/step_definitions/project/project_merge_requests_steps.rb b/features/step_definitions/project/project_merge_requests_steps.rb
new file mode 100644
index 00000000000..2bdb967d3c5
--- /dev/null
+++ b/features/step_definitions/project/project_merge_requests_steps.rb
@@ -0,0 +1,47 @@
+Given /^project "(.*?)" have "(.*?)" open merge request$/ do |arg1, arg2|
+ project = Project.find_by_name(arg1)
+ Factory.create(:merge_request, :title => arg2, :project => project, :author => project.users.first)
+end
+
+Given /^project "(.*?)" have "(.*?)" closed merge request$/ do |arg1, arg2|
+ project = Project.find_by_name(arg1)
+ Factory.create(:merge_request, :title => arg2, :project => project, :author => project.users.first, :closed => true)
+end
+
+Given /^I visit project "(.*?)" merge requests page$/ do |arg1|
+ visit project_merge_requests_path(Project.find_by_name(arg1))
+end
+
+Then /^I should see "(.*?)" in merge requests$/ do |arg1|
+ page.should have_content arg1
+end
+
+Then /^I should not see "(.*?)" in merge requests$/ do |arg1|
+ page.should_not have_content arg1
+end
+
+Then /^I should see merge request "(.*?)"$/ do |arg1|
+ merge_request = MergeRequest.find_by_title(arg1)
+ page.should have_content(merge_request.title[0..10])
+ page.should have_content(merge_request.target_branch)
+ page.should have_content(merge_request.source_branch)
+end
+
+Given /^I submit new merge request "(.*?)"$/ do |arg1|
+ fill_in "merge_request_title", :with => arg1
+ select "master", :from => "merge_request_source_branch"
+ select "stable", :from => "merge_request_target_branch"
+ click_button "Save"
+end
+
+Given /^I visit merge request page "(.*?)"$/ do |arg1|
+ mr = MergeRequest.find_by_title(arg1)
+ visit project_merge_request_path(mr.project, mr)
+end
+
+Then /^I should see closed merge request "(.*?)"$/ do |arg1|
+ mr = MergeRequest.find_by_title(arg1)
+ mr.closed.should be_true
+ page.should have_content "Closed by"
+end
+
diff --git a/features/step_definitions/project/project_milestones_steps.rb b/features/step_definitions/project/project_milestones_steps.rb
new file mode 100644
index 00000000000..6749773e2b5
--- /dev/null
+++ b/features/step_definitions/project/project_milestones_steps.rb
@@ -0,0 +1,38 @@
+Given /^project "(.*?)" has milestone "(.*?)"$/ do |arg1, arg2|
+ project = Project.find_by_name(arg1)
+
+ milestone = Factory :milestone,
+ :title => arg2,
+ :project => project
+
+ 3.times do |i|
+ issue = Factory :issue,
+ :project => project,
+ :milestone => milestone
+ end
+end
+
+Given /^I visit project "(.*?)" milestones page$/ do |arg1|
+ @project = Project.find_by_name(arg1)
+ visit project_milestones_path(@project)
+end
+
+Then /^I should see active milestones$/ do
+ milestone = @project.milestones.first
+ page.should have_content(milestone.title[0..10])
+ page.should have_content(milestone.expires_at)
+ page.should have_content("Browse Issues")
+end
+
+Then /^I should see milestone "(.*?)"$/ do |arg1|
+ milestone = @project.milestones.find_by_title(arg1)
+ page.should have_content(milestone.title[0..10])
+ page.should have_content(milestone.expires_at)
+ page.should have_content("Browse Issues")
+end
+
+Given /^I submit new milestone "(.*?)"$/ do |arg1|
+ fill_in "milestone_title", :with => arg1
+ click_button "Create milestone"
+end
+
diff --git a/features/step_definitions/project_team_steps.rb b/features/step_definitions/project/project_team_steps.rb
index f0bab29a6f8..f0bab29a6f8 100644
--- a/features/step_definitions/project_team_steps.rb
+++ b/features/step_definitions/project/project_team_steps.rb
diff --git a/features/step_definitions/project_wiki_steps.rb b/features/step_definitions/project/project_wiki_steps.rb
index 10de38d9ae3..10de38d9ae3 100644
--- a/features/step_definitions/project_wiki_steps.rb
+++ b/features/step_definitions/project/project_wiki_steps.rb
diff --git a/features/step_definitions/projects_steps.rb b/features/step_definitions/project/projects_steps.rb
index bca1213908d..d981e1f3802 100644
--- a/features/step_definitions/projects_steps.rb
+++ b/features/step_definitions/project/projects_steps.rb
@@ -1,4 +1,4 @@
-include LoginMacros
+include LoginHelpers
Given /^I signin as a user$/ do
login_as :user
@@ -50,8 +50,18 @@ Given /^I write new comment "(.*?)"$/ do |arg1|
click_button "Add Comment"
end
+Given /^I visit project "(.*?)" page$/ do |arg1|
+ project = Project.find_by_name(arg1)
+ visit project_path(project)
+end
+
Given /^I visit project "(.*?)" network page$/ do |arg1|
project = Project.find_by_name(arg1)
+
+ # Stub out find_all to speed this up (10 commits vs. 650)
+ commits = Grit::Commit.find_all(project.repo, nil, {max_count: 10})
+ Grit::Commit.stub(:find_all).and_return(commits)
+
visit graph_project_path(project)
end
@@ -62,7 +72,16 @@ end
Given /^page should have network graph$/ do
page.should have_content "Project Network Graph"
within ".graph" do
- page.should have_content "stable"
- page.should have_content "notes_refacto..."
+ page.should have_content "master"
+ page.should have_content "scss_refactor..."
end
end
+
+Given /^I leave a comment like "(.*?)"$/ do |arg1|
+ fill_in "note_note", :with => arg1
+ click_button "Add Comment"
+end
+
+Then /^I should see comment "(.*?)"$/ do |arg1|
+ page.should have_content(arg1)
+end
diff --git a/features/step_definitions/project_issues_steps.rb b/features/step_definitions/project_issues_steps.rb
deleted file mode 100644
index e83c0e7f399..00000000000
--- a/features/step_definitions/project_issues_steps.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-Given /^project "(.*?)" have "(.*?)" open issue$/ do |arg1, arg2|
- project = Project.find_by_name(arg1)
- Factory.create(:issue, :title => arg2, :project => project, :author => project.users.first)
-end
-
-Given /^project "(.*?)" have "(.*?)" closed issue$/ do |arg1, arg2|
- project = Project.find_by_name(arg1)
- Factory.create(:issue, :title => arg2, :project => project, :author => project.users.first, :closed => true)
-end
-
-Given /^I visit project "(.*?)" issues page$/ do |arg1|
- visit project_issues_path(Project.find_by_name(arg1))
-end
-
-Given /^I should see "(.*?)" open issue$/ do |arg1|
- page.should have_content arg1
-end
-
-Given /^I should not see "(.*?)" closed issue$/ do |arg1|
- page.should_not have_content arg1
-end
-
diff --git a/features/support/env.rb b/features/support/env.rb
index ce68081b739..80a465b472c 100644
--- a/features/support/env.rb
+++ b/features/support/env.rb
@@ -1,28 +1,23 @@
-# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
-# It is recommended to regenerate this file in the future when you upgrade to a
-# newer version of cucumber-rails. Consider adding your own code to a new file
-# instead of editing this one. Cucumber will automatically load all features/**/*.rb
-# files.
+unless ENV['CI']
+ require 'simplecov'
+ SimpleCov.start 'rails'
+end
-require "selenium-webdriver"
require 'cucumber/rails'
require 'webmock/cucumber'
WebMock.allow_net_connect!
-require Rails.root.join 'spec/monkeypatch'
require Rails.root.join 'spec/factories'
-require Rails.root.join 'spec/support/login'
+require Rails.root.join 'spec/support/monkeypatch'
+require Rails.root.join 'spec/support/login_helpers'
require Rails.root.join 'spec/support/valid_commit'
-# Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In
-# order to ease the transition to Capybara we set the default here. If you'd
-# prefer to use XPath just remove this line and adjust any selectors in your
-# steps to use the XPath syntax.
Capybara.default_selector = :css
+Capybara.javascript_driver = :webkit
# By default, any exception happening in your Rails application will bubble up
-# to Cucumber so that your scenario will fail. This is a different from how
-# your application behaves in the production environment, where an error page will
+# to Cucumber so that your scenario will fail. This is a different from how
+# your application behaves in the production environment, where an error page will
# be rendered instead.
#
# Sometimes we want to override this default behaviour and allow Rails to rescue
@@ -45,23 +40,11 @@ rescue NameError
raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
end
-# You may also want to configure DatabaseCleaner to use different strategies for certain features and scenarios.
-# See the DatabaseCleaner documentation for details. Example:
-#
-# Before('@no-txn,@selenium,@culerity,@celerity,@javascript') do
-# # { :except => [:widgets] } may not do what you expect here
-# # as tCucumber::Rails::Database.javascript_strategy overrides
-# # this setting.
-# DatabaseCleaner.strategy = :truncation
-# end
-#
-# Before('~@no-txn', '~@selenium', '~@culerity', '~@celerity', '~@javascript') do
-# DatabaseCleaner.strategy = :transaction
-# end
-#
-
-# Possible values are :truncation and :transaction
-# The :transaction strategy is faster, but might give you threading problems.
-# See https://github.com/cucumber/cucumber-rails/blob/master/features/choose_javascript_database_strategy.feature
Cucumber::Rails::Database.javascript_strategy = :truncation
+require 'headless'
+
+headless = Headless.new
+headless.start
+
+require 'cucumber/rspec/doubles'
diff --git a/lib/api.rb b/lib/api.rb
index e24e0a78f71..3ff3b3836f4 100644
--- a/lib/api.rb
+++ b/lib/api.rb
@@ -3,7 +3,7 @@ Dir["#{Rails.root}/lib/api/*.rb"].each {|file| require file}
module Gitlab
class API < Grape::API
VERSION = 'v2'
- version VERSION, :using => :path
+ version VERSION, using: :path
rescue_from ActiveRecord::RecordNotFound do
rack_response({'message' => '404 Not found'}.to_json, 404)
@@ -15,5 +15,6 @@ module Gitlab
mount Users
mount Projects
+ mount Issues
end
end
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 35ad4d430ad..96ccd87a407 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -11,23 +11,33 @@ module Gitlab
class Project < Grape::Entity
expose :id, :code, :name, :description, :path, :default_branch
- expose :owner, :using => Entities::UserBasic
- expose :private_flag, :as => :private
+ expose :owner, using: Entities::UserBasic
+ expose :private_flag, as: :private
expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :created_at
end
- class ProjectRepositoryBranches < Grape::Entity
- expose :name, :commit
- end
-
- class ProjectRepositoryTags < Grape::Entity
+ class RepoObject < Grape::Entity
expose :name, :commit
end
class ProjectSnippet < Grape::Entity
expose :id, :title, :file_name
- expose :author, :using => Entities::UserBasic
+ expose :author, using: Entities::UserBasic
expose :expires_at, :updated_at, :created_at
end
+
+ class Milestone < Grape::Entity
+ expose :id, :title, :description, :due_date, :closed, :updated_at, :created_at
+ end
+
+ class Issue < Grape::Entity
+ expose :id
+ expose (:project_id) {|issue| issue.project.id}
+ expose :title, :description
+ expose :label_list, as: :labels
+ expose :milestone, using: Entities::Milestone
+ expose :assignee, :author, using: Entities::UserBasic
+ expose :closed, :updated_at, :created_at
+ end
end
end
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 424a17b283c..c1ea05667ae 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -4,6 +4,16 @@ module Gitlab
@current_user ||= User.find_by_authentication_token(params[:private_token])
end
+ def user_project
+ if @project ||= current_user.projects.find_by_id(params[:id]) ||
+ current_user.projects.find_by_code(params[:id])
+ else
+ error!({'message' => '404 Not found'}, 404)
+ end
+
+ @project
+ end
+
def authenticate!
error!({'message' => '401 Unauthorized'}, 401) unless current_user
end
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
new file mode 100644
index 00000000000..2abc20ad34e
--- /dev/null
+++ b/lib/api/issues.rb
@@ -0,0 +1,111 @@
+module Gitlab
+ # Issues API
+ class Issues < Grape::API
+ before { authenticate! }
+
+ resource :issues do
+ # Get currently authenticated user's issues
+ #
+ # Example Request:
+ # GET /issues
+ get do
+ present current_user.issues, with: Entities::Issue
+ end
+ end
+
+ resource :projects do
+ # Get a list of project issues
+ #
+ # Parameters:
+ # id (required) - The ID or code name of a project
+ # Example Request:
+ # GET /projects/:id/issues
+ get ":id/issues" do
+ present user_project.issues, with: Entities::Issue
+ end
+
+ # Get a single project issue
+ #
+ # Parameters:
+ # id (required) - The ID or code name of a project
+ # issue_id (required) - The ID of a project issue
+ # Example Request:
+ # GET /projects/:id/issues/:issue_id
+ get ":id/issues/:issue_id" do
+ @issue = user_project.issues.find(params[:issue_id])
+ present @issue, with: Entities::Issue
+ end
+
+ # Create a new project issue
+ #
+ # Parameters:
+ # id (required) - The ID or code name of a project
+ # title (required) - The title of an issue
+ # description (optional) - The description of an issue
+ # assignee_id (optional) - The ID of a user to assign issue
+ # milestone_id (optional) - The ID of a milestone to assign issue
+ # labels (optional) - The labels of an issue
+ # Example Request:
+ # POST /projects/:id/issues
+ post ":id/issues" do
+ @issue = user_project.issues.new(
+ title: params[:title],
+ description: params[:description],
+ assignee_id: params[:assignee_id],
+ milestone_id: params[:milestone_id],
+ label_list: params[:labels]
+ )
+ @issue.author = current_user
+
+ if @issue.save
+ present @issue, with: Entities::Issue
+ else
+ error!({'message' => '404 Not found'}, 404)
+ end
+ end
+
+ # Update an existing issue
+ #
+ # Parameters:
+ # id (required) - The ID or code name of a project
+ # issue_id (required) - The ID of a project issue
+ # title (optional) - The title of an issue
+ # description (optional) - The description of an issue
+ # assignee_id (optional) - The ID of a user to assign issue
+ # milestone_id (optional) - The ID of a milestone to assign issue
+ # labels (optional) - The labels of an issue
+ # closed (optional) - The state of an issue (0 = false, 1 = true)
+ # Example Request:
+ # PUT /projects/:id/issues/:issue_id
+ put ":id/issues/:issue_id" do
+ @issue = user_project.issues.find(params[:issue_id])
+ parameters = {
+ title: (params[:title] || @issue.title),
+ description: (params[:description] || @issue.description),
+ assignee_id: (params[:assignee_id] || @issue.assignee_id),
+ milestone_id: (params[:milestone_id] || @issue.milestone_id),
+ label_list: (params[:labels] || @issue.label_list),
+ closed: (params[:closed] || @issue.closed)
+ }
+
+ if @issue.update_attributes(parameters)
+ present @issue, with: Entities::Issue
+ else
+ error!({'message' => '404 Not found'}, 404)
+ end
+ end
+
+ # Delete a project issue
+ #
+ # Parameters:
+ # id (required) - The ID or code name of a project
+ # issue_id (required) - The ID of a project issue
+ # Example Request:
+ # DELETE /projects/:id/issues/:issue_id
+ delete ":id/issues/:issue_id" do
+ @issue = user_project.issues.find(params[:issue_id])
+ @issue.destroy
+ end
+ end
+ end
+end
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 70f8fa2aa62..eb23641c605 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -10,59 +10,67 @@ module Gitlab
# GET /projects
get do
@projects = current_user.projects
- present @projects, :with => Entities::Project
+ present @projects, with: Entities::Project
end
# Get a single project
#
# Parameters:
- # id (required) - The code of a project
+ # id (required) - The ID or code name of a project
# Example Request:
# GET /projects/:id
get ":id" do
- @project = current_user.projects.find_by_code(params[:id])
- present @project, :with => Entities::Project
+ present user_project, with: Entities::Project
end
# Get a project repository branches
#
# Parameters:
- # id (required) - The code of a project
+ # id (required) - The ID or code name of a project
# Example Request:
# GET /projects/:id/repository/branches
get ":id/repository/branches" do
- @project = current_user.projects.find_by_code(params[:id])
- present @project.repo.heads.sort_by(&:name), :with => Entities::ProjectRepositoryBranches
+ present user_project.repo.heads.sort_by(&:name), with: Entities::RepoObject
+ end
+
+ # Get a single branch
+ #
+ # Parameters:
+ # id (required) - The ID or code name of a project
+ # branch (required) - The name of the branch
+ # Example Request:
+ # GET /projects/:id/repository/branches/:branch
+ get ":id/repository/branches/:branch" do
+ @branch = user_project.repo.heads.find { |item| item.name == params[:branch] }
+ present @branch, with: Entities::RepoObject
end
# Get a project repository tags
#
# Parameters:
- # id (required) - The code of a project
+ # id (required) - The ID or code name of a project
# Example Request:
# GET /projects/:id/repository/tags
get ":id/repository/tags" do
- @project = current_user.projects.find_by_code(params[:id])
- present @project.repo.tags.sort_by(&:name).reverse, :with => Entities::ProjectRepositoryTags
+ present user_project.repo.tags.sort_by(&:name).reverse, with: Entities::RepoObject
end
# Get a project snippet
#
# Parameters:
- # id (required) - The code of a project
+ # id (required) - The ID or code name of a project
# snippet_id (required) - The ID of a project snippet
# Example Request:
# GET /projects/:id/snippets/:snippet_id
get ":id/snippets/:snippet_id" do
- @project = current_user.projects.find_by_code(params[:id])
- @snippet = @project.snippets.find(params[:snippet_id])
- present @snippet, :with => Entities::ProjectSnippet
+ @snippet = user_project.snippets.find(params[:snippet_id])
+ present @snippet, with: Entities::ProjectSnippet
end
# Create a new project snippet
#
# Parameters:
- # id (required) - The code name of a project
+ # id (required) - The ID or code name of a project
# title (required) - The title of a snippet
# file_name (required) - The name of a snippet file
# lifetime (optional) - The expiration date of a snippet
@@ -70,17 +78,16 @@ module Gitlab
# Example Request:
# POST /projects/:id/snippets
post ":id/snippets" do
- @project = current_user.projects.find_by_code(params[:id])
- @snippet = @project.snippets.new(
- :title => params[:title],
- :file_name => params[:file_name],
- :expires_at => params[:lifetime],
- :content => params[:code]
+ @snippet = user_project.snippets.new(
+ title: params[:title],
+ file_name: params[:file_name],
+ expires_at: params[:lifetime],
+ content: params[:code]
)
@snippet.author = current_user
if @snippet.save
- present @snippet, :with => Entities::ProjectSnippet
+ present @snippet, with: Entities::ProjectSnippet
else
error!({'message' => '404 Not found'}, 404)
end
@@ -89,7 +96,7 @@ module Gitlab
# Update an existing project snippet
#
# Parameters:
- # id (required) - The code name of a project
+ # id (required) - The ID or code name of a project
# snippet_id (required) - The ID of a project snippet
# title (optional) - The title of a snippet
# file_name (optional) - The name of a snippet file
@@ -98,17 +105,16 @@ module Gitlab
# Example Request:
# PUT /projects/:id/snippets/:snippet_id
put ":id/snippets/:snippet_id" do
- @project = current_user.projects.find_by_code(params[:id])
- @snippet = @project.snippets.find(params[:snippet_id])
+ @snippet = user_project.snippets.find(params[:snippet_id])
parameters = {
- :title => (params[:title] || @snippet.title),
- :file_name => (params[:file_name] || @snippet.file_name),
- :expires_at => (params[:lifetime] || @snippet.expires_at),
- :content => (params[:code] || @snippet.content)
+ title: (params[:title] || @snippet.title),
+ file_name: (params[:file_name] || @snippet.file_name),
+ expires_at: (params[:lifetime] || @snippet.expires_at),
+ content: (params[:code] || @snippet.content)
}
if @snippet.update_attributes(parameters)
- present @snippet, :with => Entities::ProjectSnippet
+ present @snippet, with: Entities::ProjectSnippet
else
error!({'message' => '404 Not found'}, 404)
end
@@ -117,28 +123,55 @@ module Gitlab
# Delete a project snippet
#
# Parameters:
- # id (required) - The code of a project
+ # id (required) - The ID or code name of a project
# snippet_id (required) - The ID of a project snippet
# Example Request:
# DELETE /projects/:id/snippets/:snippet_id
delete ":id/snippets/:snippet_id" do
- @project = current_user.projects.find_by_code(params[:id])
- @snippet = @project.snippets.find(params[:snippet_id])
+ @snippet = user_project.snippets.find(params[:snippet_id])
@snippet.destroy
end
# Get a raw project snippet
#
# Parameters:
- # id (required) - The code of a project
+ # id (required) - The ID or code name of a project
# snippet_id (required) - The ID of a project snippet
# Example Request:
# GET /projects/:id/snippets/:snippet_id/raw
get ":id/snippets/:snippet_id/raw" do
- @project = current_user.projects.find_by_code(params[:id])
- @snippet = @project.snippets.find(params[:snippet_id])
+ @snippet = user_project.snippets.find(params[:snippet_id])
+ content_type 'text/plain'
present @snippet.content
end
+
+ # Get a raw file contents
+ #
+ # Parameters:
+ # id (required) - The ID or code name of a project
+ # sha (required) - The commit or branch name
+ # filepath (required) - The path to the file to display
+ # Example Request:
+ # GET /projects/:id/repository/commits/:sha/blob
+ get ":id/repository/commits/:sha/blob" do
+ ref = params[:sha]
+
+ commit = user_project.commit ref
+ error!('404 Commit Not Found', 404) unless commit
+
+ tree = Tree.new commit.tree, user_project, ref, params[:filepath]
+ error!('404 File Not Found', 404) unless tree.try(:tree)
+
+ if tree.text?
+ encoding = Gitlab::Encode.detect_encoding(tree.data)
+ content_type encoding ? "text/plain; charset=#{encoding}" : "text/plain"
+ else
+ content_type tree.mime_type
+ end
+
+ present tree.data
+ end
+
end
end
end
diff --git a/lib/api/users.rb b/lib/api/users.rb
index ef3762f30fc..81cb2a0e684 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -10,7 +10,7 @@ module Gitlab
# GET /users
get do
@users = User.all
- present @users, :with => Entities::User
+ present @users, with: Entities::User
end
# Get a single user
@@ -21,7 +21,7 @@ module Gitlab
# GET /users/:id
get ":id" do
@user = User.find(params[:id])
- present @user, :with => Entities::User
+ present @user, with: Entities::User
end
end
@@ -30,7 +30,7 @@ module Gitlab
# Example Request:
# GET /user
get "/user" do
- present @current_user, :with => Entities::User
+ present @current_user, with: Entities::User
end
end
end
diff --git a/lib/color.rb b/lib/color.rb
deleted file mode 100644
index 4723804e5f8..00000000000
--- a/lib/color.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-module Color
- extend self
-
- def colorize(text, color_code)
- "\033[#{color_code}#{text}\033[0m"
- end
-
- def red(text)
- colorize(text, "31m")
- end
-
- def green(text)
- colorize(text, "32m")
- end
-
- def yellow(text)
- colorize(text, "93m")
- end
-
- def command(string)
- `#{string}`
- if $?.to_i > 0
- puts red " == #{string} - FAIL"
- puts red " == Error during configure"
- exit
- else
- puts green " == #{string} - OK"
- end
- end
-end
-
diff --git a/lib/file_size_validator.rb b/lib/file_size_validator.rb
index 611e584f14f..42970c1be59 100644
--- a/lib/file_size_validator.rb
+++ b/lib/file_size_validator.rb
@@ -1,6 +1,6 @@
class FileSizeValidator < ActiveModel::EachValidator
- MESSAGES = { :is => :wrong_size, :minimum => :size_too_small, :maximum => :size_too_big }.freeze
- CHECKS = { :is => :==, :minimum => :>=, :maximum => :<= }.freeze
+ MESSAGES = { is: :wrong_size, minimum: :size_too_small, maximum: :size_too_big }.freeze
+ CHECKS = { is: :==, minimum: :>=, maximum: :<= }.freeze
DEFAULT_TOKENIZER = lambda { |value| value.split(//) }
RESERVED_OPTIONS = [:minimum, :maximum, :within, :is, :tokenizer, :too_short, :too_long]
diff --git a/lib/gitlab/encode.rb b/lib/gitlab/encode.rb
index 0787434b3af..7e37442ea32 100644
--- a/lib/gitlab/encode.rb
+++ b/lib/gitlab/encode.rb
@@ -19,7 +19,7 @@ module Gitlab
# if message is not utf-8 encoding, convert it
if detect[:encoding]
message.force_encoding(detect[:encoding])
- message.encode!("utf-8", detect[:encoding], :undef => :replace, :replace => "", :invalid => :replace)
+ message.encode!("utf-8", detect[:encoding], undef: :replace, replace: "", invalid: :replace)
end
# ensure message encoding is utf8
diff --git a/lib/gitlab/gitolite.rb b/lib/gitlab/gitolite.rb
index 7b80d4a836a..e82f9e62307 100644
--- a/lib/gitlab/gitolite.rb
+++ b/lib/gitlab/gitolite.rb
@@ -137,7 +137,7 @@ module Gitlab
owner_name = repo.permissions[0]["RW+"][""][0]
raise StandardError if owner_name.blank?
rescue => ex
- puts "Cant determine gitolite-admin owner".red
+ puts "Can't determine gitolite-admin owner".red
raise StandardError
end
diff --git a/lib/gitlab/graph_commit.rb b/lib/gitlab/graph_commit.rb
new file mode 100644
index 00000000000..b9859d79274
--- /dev/null
+++ b/lib/gitlab/graph_commit.rb
@@ -0,0 +1,183 @@
+require "grit"
+
+module Gitlab
+ class GraphCommit
+ attr_accessor :time, :space
+ attr_accessor :refs
+
+ def self.to_graph(project)
+ @repo = project.repo
+ commits = Grit::Commit.find_all(@repo, nil, {max_count: 650})
+
+ ref_cache = {}
+
+ commits.map! {|c| GraphCommit.new(Commit.new(c))}
+ commits.each { |commit| commit.add_refs(ref_cache, @repo) }
+
+ days = GraphCommit.index_commits(commits)
+ @days_json = days.compact.collect{|d| [d.day, d.strftime("%b")] }.to_json
+ @commits_json = commits.map(&:to_graph_hash).to_json
+
+ return @days_json, @commits_json
+ end
+
+ # Method is adding time and space on the
+ # list of commits. As well as returns date list
+ # corelated with time set on commits.
+ #
+ # @param [Array<GraphCommit>] comits to index
+ #
+ # @return [Array<TimeDate>] list of commit dates corelated with time on commits
+ def self.index_commits(commits)
+ days, heads = [], []
+ map = {}
+
+ commits.reverse.each_with_index do |c,i|
+ c.time = i
+ days[i] = c.committed_date
+ map[c.id] = c
+ heads += c.refs unless c.refs.nil?
+ end
+
+ heads.select!{|h| h.is_a? Grit::Head or h.is_a? Grit::Remote}
+ # sort heads so the master is top and current branches are closer
+ heads.sort! do |a,b|
+ if a.name == "master"
+ -1
+ elsif b.name == "master"
+ 1
+ else
+ b.commit.committed_date <=> a.commit.committed_date
+ end
+ end
+
+ @_reserved = {}
+ days.each_index do |i|
+ @_reserved[i] = []
+ end
+
+ heads.each do |h|
+ if map.include? h.commit.id then
+ place_chain(map[h.commit.id], map)
+ end
+ end
+ days
+ end
+
+ # Add space mark on commit and its parents
+ #
+ # @param [GraphCommit] the commit object.
+ # @param [Hash<String,GraphCommit>] map of commits
+ def self.place_chain(commit, map, parent_time = nil)
+ leaves = take_left_leaves(commit, map)
+ if leaves.empty? then
+ return
+ end
+ space = find_free_space(leaves.last.time..leaves.first.time)
+ leaves.each{|l| l.space = space}
+ # and mark it as reserved
+ min_time = leaves.last.time
+ parents = leaves.last.parents.collect
+ parents.each do |p|
+ if map.include? p.id then
+ parent = map[p.id]
+ if parent.time < min_time then
+ min_time = parent.time
+ end
+ end
+ end
+ if parent_time.nil? then
+ max_time = leaves.first.time
+ else
+ max_time = parent_time - 1
+ end
+ mark_reserved(min_time..max_time, space)
+ # Visit branching chains
+ leaves.each do |l|
+ parents = l.parents.collect
+ .select{|p| map.include? p.id and map[p.id].space == 0}
+ for p in parents
+ place_chain(map[p.id], map, l.time)
+ end
+ end
+ end
+
+ def self.mark_reserved(time_range, space)
+ for day in time_range
+ @_reserved[day].push(space)
+ end
+ end
+
+ def self.find_free_space(time_range)
+ reserved = []
+ for day in time_range
+ reserved += @_reserved[day]
+ end
+ space = 1
+ while reserved.include? space do
+ space += 1
+ end
+ space
+ end
+
+ # Takes most left subtree branch of commits
+ # which don't have space mark yet.
+ #
+ # @param [GraphCommit] the commit object.
+ # @param [Hash<String,GraphCommit>] map of commits
+ #
+ # @return [Array<GraphCommit>] list of branch commits
+ def self.take_left_leaves(commit, map)
+ leaves = []
+ leaves.push(commit) if commit.space == 0
+ while true
+ parent = commit.parents.collect
+ .select{|p| map.include? p.id and map[p.id].space == 0}
+ if parent.count == 0 then
+ return leaves
+ else
+ commit = map[parent.first.id]
+ leaves.push(commit)
+ end
+ end
+ end
+
+
+ def initialize(commit)
+ @_commit = commit
+ @time = -1
+ @space = 0
+ end
+
+ def method_missing(m, *args, &block)
+ @_commit.send(m, *args, &block)
+ end
+
+ def to_graph_hash
+ h = {}
+ h[:parents] = self.parents.collect do |p|
+ [p.id,0,0]
+ end
+ h[:author] = Gitlab::Encode.utf8(author.name)
+ h[:time] = time
+ h[:space] = space
+ h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil?
+ h[:id] = sha
+ h[:date] = date
+ h[:message] = Gitlab::Encode.utf8(message)
+ h[:login] = author.email
+ h
+ end
+
+ def add_refs(ref_cache, repo)
+ if ref_cache.empty?
+ repo.refs.each do |ref|
+ ref_cache[ref.commit.id] ||= []
+ ref_cache[ref.commit.id] << ref
+ end
+ end
+ @refs = ref_cache[@_commit.id] if ref_cache.include?(@_commit.id)
+ @refs ||= []
+ end
+ end
+end
diff --git a/lib/gitlab/logger.rb b/lib/gitlab/logger.rb
index aff13baf67b..c3a19e71c10 100644
--- a/lib/gitlab/logger.rb
+++ b/lib/gitlab/logger.rb
@@ -10,6 +10,7 @@ module Gitlab
def self.read_latest
path = Rails.root.join("log/githost.log")
+ self.build unless File.exist?(path)
logs = File.read(path).split("\n")
end
diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb
new file mode 100644
index 00000000000..75fa835d502
--- /dev/null
+++ b/lib/gitlab/markdown.rb
@@ -0,0 +1,107 @@
+module Gitlab
+ # Custom parser for Gitlab-flavored Markdown
+ #
+ # It replaces references in the text with links to the appropriate items in Gitlab.
+ #
+ # Supported reference formats are:
+ # * @foo for team members
+ # * #123 for issues
+ # * !123 for merge requests
+ # * $123 for snippets
+ # * 123456 for commits
+ #
+ # Examples
+ #
+ # >> m = Markdown.new(...)
+ #
+ # >> m.parse("Hey @david, can you fix this?")
+ # => "Hey <a href="/gitlab/team_members/1">@david</a>, can you fix this?"
+ #
+ # >> m.parse("Commit 35d5f7c closes #1234")
+ # => "Commit <a href="/gitlab/commits/35d5f7c">35d5f7c</a> closes <a href="/gitlab/issues/1234">#1234</a>"
+ class Markdown
+ include Rails.application.routes.url_helpers
+ include ActionView::Helpers
+
+ REFERENCE_PATTERN = %r{
+ ([^\w&;])? # Prefix (1)
+ ( # Reference (2)
+ @([\w\._]+) # User name (3)
+ |[#!$](\d+) # Issue/MR/Snippet ID (4)
+ |([\h]{6,40}) # Commit ID (5)
+ )
+ ([^\w&;])? # Suffix (6)
+ }x.freeze
+
+ attr_reader :html_options
+
+ def initialize(project, html_options = {})
+ @project = project
+ @html_options = html_options
+ end
+
+ def parse(text)
+ text.gsub(REFERENCE_PATTERN) do |match|
+ prefix = $1 || ''
+ reference = $2
+ identifier = $3 || $4 || $5
+ suffix = $6 || ''
+
+ if ref_link = reference_link(reference, identifier)
+ prefix + ref_link + suffix
+ else
+ match
+ end
+ end
+ end
+
+ private
+
+ # Private: Dispatches to a dedicated processing method based on reference
+ #
+ # reference - Object reference ("@1234", "!567", etc.)
+ # identifier - Object identifier (Issue ID, SHA hash, etc.)
+ #
+ # Returns string rendered by the processing method
+ def reference_link(reference, identifier)
+ case reference
+ when /^@/ then reference_user(identifier)
+ when /^#/ then reference_issue(identifier)
+ when /^!/ then reference_merge_request(identifier)
+ when /^\$/ then reference_snippet(identifier)
+ when /^\h/ then reference_commit(identifier)
+ end
+ end
+
+ def reference_user(identifier)
+ if user = @project.users.where(name: identifier).first
+ member = @project.users_projects.where(user_id: user).first
+ link_to("@#{identifier}", project_team_member_path(@project, member), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}")) if member
+ end
+ end
+
+ def reference_issue(identifier)
+ if issue = @project.issues.where(id: identifier).first
+ link_to("##{identifier}", project_issue_path(@project, issue), html_options.merge(title: "Issue: #{issue.title}", class: "gfm gfm-issue #{html_options[:class]}"))
+ end
+ end
+
+ def reference_merge_request(identifier)
+ if merge_request = @project.merge_requests.where(id: identifier).first
+ link_to("!#{identifier}", project_merge_request_path(@project, merge_request), html_options.merge(title: "Merge Request: #{merge_request.title}", class: "gfm gfm-merge_request #{html_options[:class]}"))
+ end
+ end
+
+ def reference_snippet(identifier)
+ if snippet = @project.snippets.where(id: identifier).first
+ link_to("$#{identifier}", project_snippet_path(@project, snippet), html_options.merge(title: "Snippet: #{snippet.title}", class: "gfm gfm-snippet #{html_options[:class]}"))
+ end
+ end
+
+ def reference_commit(identifier)
+ if commit = @project.commit(identifier)
+ link_to(identifier, project_commit_path(@project, id: commit.id), html_options.merge(title: "Commit: #{commit.author_name} - #{CommitDecorator.new(commit).title}", class: "gfm gfm-commit #{html_options[:class]}"))
+ end
+ end
+ end
+end
diff --git a/lib/graph_commit.rb b/lib/graph_commit.rb
deleted file mode 100644
index 269378e8acc..00000000000
--- a/lib/graph_commit.rb
+++ /dev/null
@@ -1,181 +0,0 @@
-require "grit"
-
-class GraphCommit
- attr_accessor :time, :space
- attr_accessor :refs
-
- def self.to_graph(project)
- @repo = project.repo
- commits = Grit::Commit.find_all(@repo, nil, {:max_count => 650})
-
- ref_cache = {}
-
- commits.map! {|c| GraphCommit.new(Commit.new(c))}
- commits.each { |commit| commit.add_refs(ref_cache, @repo) }
-
- days = GraphCommit.index_commits(commits)
- @days_json = days.compact.collect{|d| [d.day, d.strftime("%b")] }.to_json
- @commits_json = commits.map(&:to_graph_hash).to_json
-
- return @days_json, @commits_json
- end
-
- # Method is adding time and space on the
- # list of commits. As well as returns date list
- # corelated with time set on commits.
- #
- # @param [Array<GraphCommit>] comits to index
- #
- # @return [Array<TimeDate>] list of commit dates corelated with time on commits
- def self.index_commits(commits)
- days, heads = [], []
- map = {}
-
- commits.reverse.each_with_index do |c,i|
- c.time = i
- days[i] = c.committed_date
- map[c.id] = c
- heads += c.refs unless c.refs.nil?
- end
-
- heads.select!{|h| h.is_a? Grit::Head or h.is_a? Grit::Remote}
- # sort heads so the master is top and current branches are closer
- heads.sort! do |a,b|
- if a.name == "master"
- -1
- elsif b.name == "master"
- 1
- else
- b.commit.committed_date <=> a.commit.committed_date
- end
- end
-
- @_reserved = {}
- days.each_index do |i|
- @_reserved[i] = []
- end
-
- heads.each do |h|
- if map.include? h.commit.id then
- place_chain(map[h.commit.id], map)
- end
- end
- days
- end
-
- # Add space mark on commit and its parents
- #
- # @param [GraphCommit] the commit object.
- # @param [Hash<String,GraphCommit>] map of commits
- def self.place_chain(commit, map, parent_time = nil)
- leaves = take_left_leaves(commit, map)
- if leaves.empty? then
- return
- end
- space = find_free_space(leaves.last.time..leaves.first.time)
- leaves.each{|l| l.space = space}
- # and mark it as reserved
- min_time = leaves.last.time
- parents = leaves.last.parents.collect
- parents.each do |p|
- if map.include? p.id then
- parent = map[p.id]
- if parent.time < min_time then
- min_time = parent.time
- end
- end
- end
- if parent_time.nil? then
- max_time = leaves.first.time
- else
- max_time = parent_time - 1
- end
- mark_reserved(min_time..max_time, space)
- # Visit branching chains
- leaves.each do |l|
- parents = l.parents.collect
- .select{|p| map.include? p.id and map[p.id].space == 0}
- for p in parents
- place_chain(map[p.id], map, l.time)
- end
- end
- end
-
- def self.mark_reserved(time_range, space)
- for day in time_range
- @_reserved[day].push(space)
- end
- end
-
- def self.find_free_space(time_range)
- reserved = []
- for day in time_range
- reserved += @_reserved[day]
- end
- space = 1
- while reserved.include? space do
- space += 1
- end
- space
- end
-
- # Takes most left subtree branch of commits
- # which don't have space mark yet.
- #
- # @param [GraphCommit] the commit object.
- # @param [Hash<String,GraphCommit>] map of commits
- #
- # @return [Array<GraphCommit>] list of branch commits
- def self.take_left_leaves(commit, map)
- leaves = []
- leaves.push(commit) if commit.space == 0
- while true
- parent = commit.parents.collect
- .select{|p| map.include? p.id and map[p.id].space == 0}
- if parent.count == 0 then
- return leaves
- else
- commit = map[parent.first.id]
- leaves.push(commit)
- end
- end
- end
-
-
- def initialize(commit)
- @_commit = commit
- @time = -1
- @space = 0
- end
-
- def method_missing(m, *args, &block)
- @_commit.send(m, *args, &block)
- end
-
- def to_graph_hash
- h = {}
- h[:parents] = self.parents.collect do |p|
- [p.id,0,0]
- end
- h[:author] = Gitlab::Encode.utf8(author.name)
- h[:time] = time
- h[:space] = space
- h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil?
- h[:id] = sha
- h[:date] = date
- h[:message] = Gitlab::Encode.utf8(message)
- h[:login] = author.email
- h
- end
-
- def add_refs(ref_cache, repo)
- if ref_cache.empty?
- repo.refs.each do |ref|
- ref_cache[ref.commit.id] ||= []
- ref_cache[ref.commit.id] << ref
- end
- end
- @refs = ref_cache[@_commit.id] if ref_cache.include?(@_commit.id)
- @refs ||= []
- end
-end
diff --git a/lib/post-receive-hook b/lib/hooks/post-receive
index d38bd13e19d..d38bd13e19d 100755
--- a/lib/post-receive-hook
+++ b/lib/hooks/post-receive
diff --git a/lib/redcarpet/render/gitlab_html.rb b/lib/redcarpet/render/gitlab_html.rb
index 638c227cb20..30a807145ea 100644
--- a/lib/redcarpet/render/gitlab_html.rb
+++ b/lib/redcarpet/render/gitlab_html.rb
@@ -1,9 +1,23 @@
class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML
+
+ attr_reader :template
+ alias_method :h, :template
+
+ def initialize(template, options = {})
+ @template = template
+ @project = @template.instance_variable_get("@project")
+ super options
+ end
+
def block_code(code, language)
if Pygments::Lexer.find(language)
- Pygments.highlight(code, :lexer => language, :options => {:encoding => 'utf-8'})
+ Pygments.highlight(code, lexer: language, options: {encoding: 'utf-8'})
else
- Pygments.highlight(code, :options => {:encoding => 'utf-8'})
+ Pygments.highlight(code, options: {encoding: 'utf-8'})
end
end
+
+ def postprocess(full_document)
+ h.gfm(full_document)
+ end
end
diff --git a/lib/tasks/dev/repo.rake b/lib/tasks/dev/repo.rake
deleted file mode 100644
index 7b389a5535b..00000000000
--- a/lib/tasks/dev/repo.rake
+++ /dev/null
@@ -1,26 +0,0 @@
-namespace :dev do
- desc "Prepare for development (run dev_user.sh first)"
- task :repos => :environment do
- key = `sudo -u gitlabdev -H cat /home/gitlabdev/.ssh/id_rsa.pub`
- raise "\n *** Run ./lib/tasks/dev/user.sh first *** \n" if key.empty?
- Key.create(:user_id => User.first, :key => key, :title => "gitlabdev")
-
- puts "\n *** Clone diaspora from github"
- `sudo -u gitlabdev -H sh -c "cd /home/gitlabdev; git clone git://github.com/diaspora/diaspora.git /home/gitlabdev/diaspora"`
-
- puts "\n *** Push diaspora source to gitlab"
- `sudo -u gitlabdev -H sh -c "cd /home/gitlabdev/diaspora; git remote add local git@localhost:diaspora.git; git push local master; git push local --tags; git checkout -b api origin/api; git push local api; git checkout -b heroku origin/heroku; git push local heroku"`
-
- puts "\n *** Clone rails from github"
- `sudo -u gitlabdev -H sh -c "cd /home/gitlabdev; git clone git://github.com/rails/rails.git /home/gitlabdev/rails"`
-
- puts "\n *** Push rails source to gitlab"
- `sudo -u gitlabdev -H sh -c "cd /home/gitlabdev/rails; git remote add local git@localhost:ruby_on_rails.git; git push local master; git push local --tags"`
-
- puts "\n *** Clone rubinius from github"
- `sudo -u gitlabdev -H sh -c "cd /home/gitlabdev; git clone git://github.com/rubinius/rubinius.git /home/gitlabdev/rubinius"`
-
- puts "\n *** Push rubinius source to gitlab"
- `sudo -u gitlabdev -H sh -c "cd /home/gitlabdev/rubinius; git remote add local git@localhost:rubinius.git; git push local master; git push local --tags"`
- end
-end
diff --git a/lib/tasks/dev/user.sh b/lib/tasks/dev/user.sh
deleted file mode 100755
index d6b20df2ef2..00000000000
--- a/lib/tasks/dev/user.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-sudo adduser \
- --gecos 'gitlab dev user' \
- --disabled-password \
- --home /home/gitlabdev \
- gitlabdev
-
-sudo -i -u gitlabdev -H sh -c "ssh-keygen -t rsa"
diff --git a/lib/tasks/gitlab/backup.rake b/lib/tasks/gitlab/backup.rake
index 014483d4e8c..d9053c232cd 100644
--- a/lib/tasks/gitlab/backup.rake
+++ b/lib/tasks/gitlab/backup.rake
@@ -121,7 +121,7 @@ namespace :gitlab do
backup_path_repo = File.join(Gitlab.config.backup_path, "repositories")
FileUtils.mkdir_p(backup_path_repo) until Dir.exists?(backup_path_repo)
puts "Dumping repositories:"
- project = Project.all.map { |n| [n.name,n.path_to_repo] }
+ project = Project.all.map { |n| [n.path,n.path_to_repo] }
project << ["gitolite-admin.git", File.join(File.dirname(project.first.second), "gitolite-admin.git")]
project.each do |project|
print "- Dumping repository #{project.first}... "
@@ -136,12 +136,18 @@ namespace :gitlab do
task :repo_restore => :environment do
backup_path_repo = File.join(Gitlab.config.backup_path, "repositories")
puts "Restoring repositories:"
- project = Project.all.map { |n| [n.name,n.path_to_repo] }
+ project = Project.all.map { |n| [n.path,n.path_to_repo] }
project << ["gitolite-admin.git", File.join(File.dirname(project.first.second), "gitolite-admin.git")]
project.each do |project|
print "- Restoring repository #{project.first}... "
FileUtils.rm_rf(project.second) if File.dirname(project.second) # delet old stuff
if Kernel.system("cd #{File.dirname(project.second)} > /dev/null 2>&1 && git clone --bare #{backup_path_repo}/#{project.first}.bundle #{project.first}.git > /dev/null 2>&1")
+ permission_commands = [
+ "sudo chmod -R g+rwX #{Gitlab.config.git_base_path}",
+ "sudo chown -R #{Gitlab.config.ssh_user}:#{Gitlab.config.ssh_user} #{Gitlab.config.git_base_path}",
+ "sudo chown gitlab:gitlab /home/git/repositories/**/hooks/post-receive"
+ ]
+ permission_commands.each { |command| Kernel.system(command) }
puts "[DONE]".green
else
puts "[FAILED]".red
diff --git a/lib/tasks/gitlab/setup.rake b/lib/tasks/gitlab/setup.rake
index d60e73e9ac3..49c86461c0b 100644
--- a/lib/tasks/gitlab/setup.rake
+++ b/lib/tasks/gitlab/setup.rake
@@ -1,7 +1,11 @@
namespace :gitlab do
namespace :app do
desc "GITLAB | Setup production application"
- task :setup => ['db:setup', 'db:seed_fu', 'gitlab:app:enable_automerge']
+ task :setup => [
+ 'db:setup',
+ 'db:seed_fu',
+ 'gitlab:app:enable_automerge'
+ ]
end
end
diff --git a/lib/tasks/gitlab/status.rake b/lib/tasks/gitlab/status.rake
index ac712234b27..02d27d4bbcc 100644
--- a/lib/tasks/gitlab/status.rake
+++ b/lib/tasks/gitlab/status.rake
@@ -2,7 +2,7 @@ namespace :gitlab do
namespace :app do
desc "GITLAB | Check gitlab installation status"
task :status => :environment do
- puts "Starting diagnostic"
+ puts "Starting diagnostic".yellow
git_base_path = Gitlab.config.git_base_path
print "config/database.yml............"
@@ -49,14 +49,43 @@ namespace :gitlab do
end
print "UMASK for .gitolite.rc is 0007? ............"
- unless open("#{git_base_path}/../.gitolite.rc").grep(/REPO_UMASK = 0007/).empty?
+ unless open("#{git_base_path}/../.gitolite.rc").grep(/UMASK([ \t]*)=([ \t>]*)0007/).empty?
puts "YES".green
else
puts "NO".red
return
end
- puts "\nFinished"
+ gitolite_hooks_path = File.join("/home", Gitlab.config.ssh_user, "share", "gitolite", "hooks", "common")
+ gitlab_hook_files = ['post-receive']
+ gitlab_hook_files.each do |file_name|
+ dest = File.join(gitolite_hooks_path, file_name)
+ print "#{dest} exists? ............"
+ if File.exists?(dest)
+ puts "YES".green
+ else
+ puts "NO".red
+ return
+ end
+ end
+
+
+ if Project.count > 0
+ puts "Validating projects repositories:".yellow
+ Project.find_each(:batch_size => 100) do |project|
+ print "#{project.name}....."
+ hook_file = File.join(project.path_to_repo, 'hooks','post-receive')
+
+ unless File.exists?(hook_file)
+ puts "post-receive file missing".red
+ next
+ end
+
+ puts "post-reveice file ok".green
+ end
+ end
+
+ puts "\nFinished".blue
end
end
end
diff --git a/lib/tasks/gitlab/update_hooks.rake b/lib/tasks/gitlab/update_hooks.rake
deleted file mode 100644
index 44e1617e58f..00000000000
--- a/lib/tasks/gitlab/update_hooks.rake
+++ /dev/null
@@ -1,19 +0,0 @@
-namespace :gitlab do
- namespace :gitolite do
- desc "GITLAB | 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.write_hooks
- print ".".green
- end
- rescue Exception => e
- print e.message.red
- end
- end
- puts "\nDone with projects"
- end
- end
-end
diff --git a/lib/tasks/gitlab/write_hook.rake b/lib/tasks/gitlab/write_hook.rake
new file mode 100644
index 00000000000..098331b8cd7
--- /dev/null
+++ b/lib/tasks/gitlab/write_hook.rake
@@ -0,0 +1,23 @@
+namespace :gitlab do
+ namespace :gitolite do
+ desc "GITLAB | Write GITLAB hook for gitolite"
+ task :write_hooks => :environment do
+ gitolite_hooks_path = File.join("/home", Gitlab.config.ssh_user, "share", "gitolite", "hooks", "common")
+ gitlab_hooks_path = Rails.root.join("lib", "hooks")
+
+ gitlab_hook_files = ['post-receive']
+
+ gitlab_hook_files.each do |file_name|
+ source = File.join(gitlab_hooks_path, file_name)
+ dest = File.join(gitolite_hooks_path, file_name)
+
+ puts "sudo -u root cp #{source} #{dest}".yellow
+ `sudo -u root cp #{source} #{dest}`
+
+ puts "sudo -u root chown git:git #{dest}".yellow
+ `sudo -u root chown git:git #{dest}`
+ end
+ end
+ end
+end
+
diff --git a/public/404.html b/public/404.html
index d4b26fe439c..3e56e52cc18 100644
--- a/public/404.html
+++ b/public/404.html
@@ -7,7 +7,7 @@
<body>
<h1>404</h1>
- <div class="alert-message block-message error">
+ <div>
<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 a0a0a244105..b6c37ac5386 100644
--- a/public/422.html
+++ b/public/422.html
@@ -8,7 +8,7 @@
<body>
<!-- This file lives in public/422.html -->
<h1>422</h1>
- <div class="alert-message block-message error">
+ <div>
<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 2868de5e686..3be1cc259c0 100644
--- a/public/500.html
+++ b/public/500.html
@@ -8,7 +8,7 @@
<body>
<!-- This file lives in public/500.html -->
<h1>500</h1>
- <div class="alert-message block-message error">
+ <div>
<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/resque.sh b/resque.sh
index ce7c944b735..ab67c650805 100755
--- a/resque.sh
+++ b/resque.sh
@@ -1,2 +1,2 @@
mkdir -p tmp/pids
-bundle exec rake environment resque:work QUEUE=post_receive,mailer RAILS_ENV=production PIDFILE=tmp/pids/resque_worker.pid BACKGROUND=yes
+bundle exec rake environment resque:work QUEUE=post_receive,mailer,system_hook RAILS_ENV=production PIDFILE=tmp/pids/resque_worker.pid BACKGROUND=yes
diff --git a/resque_dev.sh b/resque_dev.sh
index 9df4dc1d087..b09cfd9e383 100755
--- a/resque_dev.sh
+++ b/resque_dev.sh
@@ -1 +1 @@
-bundle exec rake environment resque:work QUEUE=* VVERBOSE=1
+bundle exec rake environment resque:work QUEUE=post_receive,mailer,system_hook VVERBOSE=1
diff --git a/spec/api/projects_spec.rb b/spec/api/projects_spec.rb
deleted file mode 100644
index 9998ee509bf..00000000000
--- a/spec/api/projects_spec.rb
+++ /dev/null
@@ -1,94 +0,0 @@
-require 'spec_helper'
-
-describe Gitlab::API do
- let(:user) { Factory :user }
- let!(:project) { Factory :project, :owner => user }
- let!(:snippet) { Factory :snippet, :author => user, :project => project, :title => 'example' }
- before { project.add_access(user, :read) }
-
- describe "GET /projects" do
- it "should return authentication error" do
- get "#{api_prefix}/projects"
- response.status.should == 401
- end
-
- describe "authenticated GET /projects" do
- it "should return an array of projects" do
- get "#{api_prefix}/projects?private_token=#{user.private_token}"
- response.status.should == 200
- json_response.should be_an Array
- json_response.first['name'].should == project.name
- json_response.first['owner']['email'].should == user.email
- end
- end
- end
-
- describe "GET /projects/:id" do
- it "should return a project by id" do
- get "#{api_prefix}/projects/#{project.code}?private_token=#{user.private_token}"
- response.status.should == 200
- json_response['name'].should == project.name
- json_response['owner']['email'].should == user.email
- end
- end
-
- describe "GET /projects/:id/repository/branches" do
- it "should return an array of project branches" do
- get "#{api_prefix}/projects/#{project.code}/repository/branches?private_token=#{user.private_token}"
- response.status.should == 200
- json_response.should be_an Array
- json_response.first['name'].should == project.repo.heads.sort_by(&:name).first.name
- end
- end
-
- describe "GET /projects/:id/repository/tags" do
- it "should return an array of project tags" do
- get "#{api_prefix}/projects/#{project.code}/repository/tags?private_token=#{user.private_token}"
- response.status.should == 200
- json_response.should be_an Array
- json_response.first['name'].should == project.repo.tags.sort_by(&:name).reverse.first.name
- end
- end
-
- describe "GET /projects/:id/snippets/:snippet_id" do
- it "should return a project snippet" do
- get "#{api_prefix}/projects/#{project.code}/snippets/#{snippet.id}?private_token=#{user.private_token}"
- response.status.should == 200
- json_response['title'].should == snippet.title
- end
- end
-
- describe "POST /projects/:id/snippets" do
- it "should create a new project snippet" do
- post "#{api_prefix}/projects/#{project.code}/snippets?private_token=#{user.private_token}",
- :title => 'api test', :file_name => 'sample.rb', :code => 'test'
- response.status.should == 201
- json_response['title'].should == 'api test'
- end
- end
-
- describe "PUT /projects/:id/snippets" do
- it "should update an existing project snippet" do
- put "#{api_prefix}/projects/#{project.code}/snippets/#{snippet.id}?private_token=#{user.private_token}",
- :code => 'updated code'
- response.status.should == 200
- json_response['title'].should == 'example'
- snippet.reload.content.should == 'updated code'
- end
- end
-
- describe "DELETE /projects/:id/snippets/:snippet_id" do
- it "should delete existing project snippet" do
- expect {
- delete "#{api_prefix}/projects/#{project.code}/snippets/#{snippet.id}?private_token=#{user.private_token}"
- }.should change { Snippet.count }.by(-1)
- end
- end
-
- describe "GET /projects/:id/snippets/:snippet_id/raw" do
- it "should get a raw project snippet" do
- get "#{api_prefix}/projects/#{project.code}/snippets/#{snippet.id}/raw?private_token=#{user.private_token}"
- response.status.should == 200
- end
- end
-end
diff --git a/spec/factories.rb b/spec/factories.rb
index ea8c7aef0e2..ab2ca4687da 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -7,6 +7,12 @@ Factory.add(:project, Project) do |obj|
obj.code = 'LGT'
end
+Factory.add(:project_without_owner, Project) do |obj|
+ obj.name = Faker::Internet.user_name
+ obj.path = 'gitlabhq'
+ obj.code = 'LGT'
+end
+
Factory.add(:public_project, Project) do |obj|
obj.name = Faker::Internet.user_name
obj.path = 'gitlabhq'
@@ -60,7 +66,11 @@ Factory.add(:key, Key) do |obj|
obj.key = File.read(File.join(Rails.root, "db", "pkey.example"))
end
-Factory.add(:web_hook, WebHook) do |obj|
+Factory.add(:project_hook, ProjectHook) do |obj|
+ obj.url = Faker::Internet.uri("http")
+end
+
+Factory.add(:system_hook, SystemHook) do |obj|
obj.url = Faker::Internet.uri("http")
end
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
new file mode 100644
index 00000000000..9a2df31479c
--- /dev/null
+++ b/spec/helpers/application_helper_spec.rb
@@ -0,0 +1,26 @@
+require 'spec_helper'
+
+describe ApplicationHelper do
+ describe "gravatar_icon" do
+ let(:user_email) { 'user@email.com' }
+
+ it "should return a generic avatar path when Gravatar is disabled" do
+ Gitlab.config.stub(:disable_gravatar?).and_return(true)
+ gravatar_icon(user_email).should == 'no_avatar.png'
+ end
+
+ it "should return a generic avatar path when email is blank" do
+ gravatar_icon('').should == 'no_avatar.png'
+ end
+
+ it "should use SSL when appropriate" do
+ stub!(:request).and_return(double(:ssl? => true))
+ gravatar_icon(user_email).should match('https://secure.gravatar.com')
+ end
+
+ it "should accept a custom size" do
+ stub!(:request).and_return(double(:ssl? => false))
+ gravatar_icon(user_email, 64).should match(/\?s=64/)
+ end
+ end
+end
diff --git a/spec/helpers/commit_helper_spec.rb b/spec/helpers/commit_helper_spec.rb
deleted file mode 100644
index 747a28a35b9..00000000000
--- a/spec/helpers/commit_helper_spec.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-require "spec_helper"
-include Haml::Helpers
-
-describe CommitsHelper do
-
- before do
- @project = Factory :project
- @other_project = Factory :project, :path => "OtherPath", :code => "OtherCode"
- @fake_user = Factory :user
- @valid_issue = Factory :issue, :assignee => @fake_user, :author => @fake_user, :project => @project
- @invalid_issue = Factory :issue, :assignee => @fake_user, :author => @fake_user, :project => @other_project
- end
-
- it "should provides return message untouched if no issue number present" do
- message = "Dummy message without issue number"
-
- commit_msg_with_link_to_issues(@project, message).should eql message
- end
-
- it "should returns message handled by preserve" do
- message = "My brand new
- Commit on multiple
- lines !"
-
- #\n are converted to &#x000A as specified in preserve_rspec
- expected = "My brand new&#x000A; Commit on multiple&#x000A; lines !"
-
- commit_msg_with_link_to_issues(@project, message).should eql expected
- end
-
- it "should returns empty string if message undefined" do
- commit_msg_with_link_to_issues(@project, nil).should eql ''
- end
-
- it "should returns link_to issue for one valid issue in message" do
- issue_id = @valid_issue.id
- message = "One commit message ##{issue_id}"
- expected = "One commit message <a href=\"/#{@project.code}/issues/#{issue_id}\">##{issue_id}</a>"
-
- commit_msg_with_link_to_issues(@project, message).should eql expected
- end
-
- it "should returns message untouched for one invalid issue in message" do
- issue_id = @invalid_issue.id
- message = "One commit message ##{issue_id}"
-
- commit_msg_with_link_to_issues(@project, message).should eql message
- end
-
- it "should handle multiple issue references in commit message" do
- issue_id = @valid_issue.id
- invalid_issue_id = @invalid_issue.id
-
- message = "One big commit message with a valid issue ##{issue_id} and an invalid one ##{invalid_issue_id}.
- We reference valid ##{issue_id} multiple times (##{issue_id}) as the invalid ##{invalid_issue_id} is also
- referenced another time (##{invalid_issue_id})"
-
- expected = "One big commit message with a valid issue <a href=\"/#{@project.code}/issues/#{issue_id}\">##{issue_id}</a>"+
- " and an invalid one ##{invalid_issue_id}.&#x000A; "+
- "We reference valid <a href=\"/#{@project.code}/issues/#{issue_id}\">##{issue_id}</a> multiple times "+
- "(<a href=\"/#{@project.code}/issues/#{issue_id}\">##{issue_id}</a>) "+
- "as the invalid ##{invalid_issue_id} is also&#x000A; referenced another time (##{invalid_issue_id})"
-
- commit_msg_with_link_to_issues(@project, message).should eql expected
- end
-
-end \ No newline at end of file
diff --git a/spec/helpers/gitlab_flavored_markdown_spec.rb b/spec/helpers/gitlab_flavored_markdown_spec.rb
new file mode 100644
index 00000000000..e147cb39375
--- /dev/null
+++ b/spec/helpers/gitlab_flavored_markdown_spec.rb
@@ -0,0 +1,232 @@
+require "spec_helper"
+
+describe GitlabMarkdownHelper do
+ before do
+ @project = Project.find_by_path("gitlabhq") || Factory(:project)
+ @commit = @project.repo.commits.first.parents.first
+ @commit = CommitDecorator.decorate(Commit.new(@commit))
+ @other_project = Factory :project, path: "OtherPath", code: "OtherCode"
+ @fake_user = Factory :user, name: "fred"
+ end
+
+ describe "#gfm" do
+ it "should return text if @project is not set" do
+ @project = nil
+
+ gfm("foo").should == "foo"
+ end
+
+ describe "referencing a commit" do
+ it "should link using a full id" do
+ gfm("Reverts changes from #{@commit.id}").should == "Reverts changes from #{link_to @commit.id, project_commit_path(@project, id: @commit.id), title: "Commit: #{@commit.author_name} - #{@commit.title}", class: "gfm gfm-commit "}"
+ end
+
+ it "should link using a short id" do
+ gfm("Backported from #{@commit.id[0, 6]}").should == "Backported from #{link_to @commit.id[0, 6], project_commit_path(@project, id: @commit.id), title: "Commit: #{@commit.author_name} - #{@commit.title}", class: "gfm gfm-commit "}"
+ end
+
+ it "should link with adjecent text" do
+ gfm("Reverted (see #{@commit.id})").should == "Reverted (see #{link_to @commit.id, project_commit_path(@project, id: @commit.id), title: "Commit: #{@commit.author_name} - #{@commit.title}", class: "gfm gfm-commit "})"
+ end
+
+ it "should not link with an invalid id" do
+ gfm("What happened in 12345678?").should == "What happened in 12345678?"
+ end
+ end
+
+ describe "referencing a team member" do
+ it "should link using a simple name" do
+ user = Factory :user, name: "barry"
+ @project.users << user
+ member = @project.users_projects.where(user_id: user).first
+
+ gfm("@#{user.name} you are right").should == "#{link_to "@#{user.name}", project_team_member_path(@project, member), class: "gfm gfm-team_member "} you are right"
+ end
+
+ it "should link using a name with dots" do
+ user = Factory :user, name: "alphA.Beta"
+ @project.users << user
+ member = @project.users_projects.where(user_id: user).first
+
+ gfm("@#{user.name} you are right").should == "#{link_to "@#{user.name}", project_team_member_path(@project, member), class: "gfm gfm-team_member "} you are right"
+ end
+
+ it "should link using name with underscores" do
+ user = Factory :user, name: "ping_pong_king"
+ @project.users << user
+ member = @project.users_projects.where(user_id: user).first
+
+ gfm("@#{user.name} you are right").should == "#{link_to "@#{user.name}", project_team_member_path(@project, member), class: "gfm gfm-team_member "} you are right"
+ end
+
+ it "should link with adjecent text" do
+ user = Factory.create(:user, name: "ace")
+ @project.users << user
+ member = @project.users_projects.where(user_id: user).first
+
+ gfm("Mail the Admin (@#{user.name})").should == "Mail the Admin (#{link_to "@#{user.name}", project_team_member_path(@project, member), class: "gfm gfm-team_member "})"
+ end
+
+ it "should add styles" do
+ user = Factory :user, name: "barry"
+ @project.users << user
+ gfm("@#{user.name} you are right").should have_selector(".gfm.gfm-team_member")
+ end
+
+ it "should not link using a bogus name" do
+ gfm("What hapened to @foo?").should == "What hapened to @foo?"
+ end
+ end
+
+ describe "referencing an issue" do
+ before do
+ @issue = Factory :issue, assignee: @fake_user, author: @fake_user, project: @project
+ @invalid_issue = Factory :issue, assignee: @fake_user, author: @fake_user, project: @other_project
+ end
+
+ it "should link using a correct id" do
+ gfm("Fixes ##{@issue.id}").should == "Fixes #{link_to "##{@issue.id}", project_issue_path(@project, @issue), title: "Issue: #{@issue.title}", class: "gfm gfm-issue "}"
+ end
+
+ it "should link with adjecent text" do
+ gfm("This has already been discussed (see ##{@issue.id})").should == "This has already been discussed (see #{link_to "##{@issue.id}", project_issue_path(@project, @issue), title: "Issue: #{@issue.title}", class: "gfm gfm-issue "})"
+ end
+
+ it "should add styles" do
+ gfm("Fixes ##{@issue.id}").should have_selector(".gfm.gfm-issue")
+ end
+
+ it "should not link using an invalid id" do
+ gfm("##{@invalid_issue.id} has been marked duplicate of this").should == "##{@invalid_issue.id} has been marked duplicate of this"
+ end
+ end
+
+ describe "referencing a merge request" do
+ before do
+ @merge_request = Factory :merge_request, assignee: @fake_user, author: @fake_user, project: @project
+ @invalid_merge_request = Factory :merge_request, assignee: @fake_user, author: @fake_user, project: @other_project
+ end
+
+ it "should link using a correct id" do
+ gfm("Fixed in !#{@merge_request.id}").should == "Fixed in #{link_to "!#{@merge_request.id}", project_merge_request_path(@project, @merge_request), title: "Merge Request: #{@merge_request.title}", class: "gfm gfm-merge_request "}"
+ end
+
+ it "should link with adjecent text" do
+ gfm("This has been fixed already (see !#{@merge_request.id})").should == "This has been fixed already (see #{link_to "!#{@merge_request.id}", project_merge_request_path(@project, @merge_request), title: "Merge Request: #{@merge_request.title}", class: "gfm gfm-merge_request "})"
+ end
+
+ it "should add styles" do
+ gfm("Fixed in !#{@merge_request.id}").should have_selector(".gfm.gfm-merge_request")
+ end
+
+ it "should not link using an invalid id" do
+ gfm("!#{@invalid_merge_request.id} violates our coding guidelines")
+ end
+ end
+
+ describe "referencing a snippet" do
+ before do
+ @snippet = Factory.create(:snippet,
+ title: "Render asset to string",
+ author: @fake_user,
+ project: @project)
+ end
+
+ it "should link using a correct id" do
+ gfm("Check out $#{@snippet.id}").should == "Check out #{link_to "$#{@snippet.id}", project_snippet_path(@project, @snippet), title: "Snippet: #{@snippet.title}", class: "gfm gfm-snippet "}"
+ end
+
+ it "should link with adjecent text" do
+ gfm("I have created a snippet for that ($#{@snippet.id})").should == "I have created a snippet for that (#{link_to "$#{@snippet.id}", project_snippet_path(@project, @snippet), title: "Snippet: #{@snippet.title}", class: "gfm gfm-snippet "})"
+ end
+
+ it "should add styles" do
+ gfm("Check out $#{@snippet.id}").should have_selector(".gfm.gfm-snippet")
+ end
+
+ it "should not link using an invalid id" do
+ gfm("Don't use $1234").should == "Don't use $1234"
+ end
+ end
+
+ it "should link to multiple things" do
+ user = Factory :user, name: "barry"
+ @project.users << user
+ member = @project.users_projects.where(user_id: user).first
+
+ gfm("Let @#{user.name} fix the *mess* in #{@commit.id}").should == "Let #{link_to "@#{user.name}", project_team_member_path(@project, member), class: "gfm gfm-team_member "} fix the *mess* in #{link_to @commit.id, project_commit_path(@project, id: @commit.id), title: "Commit: #{@commit.author_name} - #{@commit.title}", class: "gfm gfm-commit "}"
+ end
+
+ it "should not trip over other stuff", focus: true do
+ gfm("_Please_ *stop* 'helping' and all the other b*$#%' you do.").should == "_Please_ *stop* 'helping' and all the other b*$#%' you do."
+ end
+
+ it "should not touch HTML entities" do
+ gfm("We&#39;ll accept good pull requests.").should == "We&#39;ll accept good pull requests."
+ end
+
+ it "should forward HTML options to links" do
+ gfm("fixed in #{@commit.id}", class: "foo").should have_selector("a.foo")
+ end
+ end
+
+ describe "#link_to_gfm" do
+ let(:issue1) { Factory :issue, assignee: @fake_user, author: @fake_user, project: @project }
+ let(:issue2) { Factory :issue, assignee: @fake_user, author: @fake_user, project: @project }
+
+ it "should handle references nested in links with all the text" do
+ link_to_gfm("This should finally fix ##{issue1.id} and ##{issue2.id} for real", project_commit_path(@project, id: @commit.id)).should == "#{link_to "This should finally fix ", project_commit_path(@project, id: @commit.id)}#{link_to "##{issue1.id}", project_issue_path(@project, issue1), title: "Issue: #{issue1.title}", class: "gfm gfm-issue "}#{link_to " and ", project_commit_path(@project, id: @commit.id)}#{link_to "##{issue2.id}", project_issue_path(@project, issue2), title: "Issue: #{issue2.title}", class: "gfm gfm-issue "}#{link_to " for real", project_commit_path(@project, id: @commit.id)}"
+ end
+
+ it "should forward HTML options" do
+ link_to_gfm("This should finally fix ##{issue1.id} for real", project_commit_path(@project, id: @commit.id), class: "foo").should have_selector(".foo")
+ end
+ end
+
+ describe "#markdown" do
+ before do
+ @issue = Factory :issue, assignee: @fake_user, author: @fake_user, project: @project
+ @merge_request = Factory :merge_request, assignee: @fake_user, author: @fake_user, project: @project
+ @note = Factory.create(:note,
+ note: "Screenshot of the new feature",
+ project: @project,
+ noteable_id: @commit.id,
+ noteable_type: "Commit",
+ attachment: "screenshot123.jpg")
+ @snippet = Factory.create(:snippet,
+ title: "Render asset to string",
+ author: @fake_user,
+ project: @project)
+
+ @other_user = Factory :user, name: "bill"
+ @project.users << @other_user
+ @member = @project.users_projects.where(user_id: @other_user).first
+ end
+
+ it "should handle references in paragraphs" do
+ markdown("\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. #{@commit.id} Nam pulvinar sapien eget odio adipiscing at faucibus orci vestibulum.\n").should == "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. #{link_to @commit.id, project_commit_path(@project, id: @commit.id), title: "Commit: #{@commit.author_name} - #{@commit.title}", class: "gfm gfm-commit "} Nam pulvinar sapien eget odio adipiscing at faucibus orci vestibulum.</p>\n"
+ end
+
+ it "should handle references in headers" do
+ markdown("\n# Working around ##{@issue.id} for now\n## Apply !#{@merge_request.id}").should == "<h1 id=\"toc_0\">Working around #{link_to "##{@issue.id}", project_issue_path(@project, @issue), title: "Issue: #{@issue.title}", class: "gfm gfm-issue "} for now</h1>\n\n<h2 id=\"toc_1\">Apply #{link_to "!#{@merge_request.id}", project_merge_request_path(@project, @merge_request), title: "Merge Request: #{@merge_request.title}", class: "gfm gfm-merge_request "}</h2>\n"
+ end
+
+ it "should handle references in lists" do
+ markdown("\n* dark: ##{@issue.id}\n* light by @#{@other_user.name}\n").should == "<ul>\n<li>dark: #{link_to "##{@issue.id}", project_issue_path(@project, @issue), title: "Issue: #{@issue.title}", class: "gfm gfm-issue "}</li>\n<li>light by #{link_to "@#{@other_user.name}", project_team_member_path(@project, @member), class: "gfm gfm-team_member "}</li>\n</ul>\n"
+ end
+
+ it "should handle references in <em>" do
+ markdown("Apply _!#{@merge_request.id}_ ASAP").should == "<p>Apply <em>#{link_to "!#{@merge_request.id}", project_merge_request_path(@project, @merge_request), title: "Merge Request: #{@merge_request.title}", class: "gfm gfm-merge_request "}</em> ASAP</p>\n"
+ end
+
+ it "should leave code blocks untouched" do
+ markdown("\n some code from $#{@snippet.id}\n here too\n").should == "<div class=\"highlight\"><pre><span class=\"n\">some</span> <span class=\"n\">code</span> <span class=\"n\">from</span> $#{@snippet.id}\n<span class=\"n\">here</span> <span class=\"n\">too</span>\n</pre>\n</div>\n"
+
+ markdown("\n```\nsome code from $#{@snippet.id}\nhere too\n```\n").should == "<div class=\"highlight\"><pre><span class=\"n\">some</span> <span class=\"n\">code</span> <span class=\"n\">from</span> $#{@snippet.id}\n<span class=\"n\">here</span> <span class=\"n\">too</span>\n</pre>\n</div>\n"
+ end
+
+ it "should leave inline code untouched" do
+ markdown("\nDon't use `$#{@snippet.id}` here.\n").should == "<p>Don&#39;t use <code>$#{@snippet.id}</code> here.</p>\n"
+ end
+ end
+end
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index 4df771b97fe..93427ebfacd 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -4,7 +4,7 @@ describe Notify do
include EmailSpec::Helpers
include EmailSpec::Matchers
- let(:recipient) { Factory.create(:user, :email => 'recipient@example.com') }
+ let(:recipient) { Factory.create(:user, email: 'recipient@example.com') }
let(:project) { Factory.create(:project) }
shared_examples 'a multiple recipients email' do
@@ -15,7 +15,7 @@ describe Notify do
describe 'for new users, the email' do
let(:example_site_path) { root_path }
- let(:new_user) { Factory.create(:user, :email => 'newguy@example.com') }
+ let(:new_user) { Factory.create(:user, email: 'newguy@example.com') }
subject { Notify.new_user_email(new_user.id, new_user.password) }
@@ -24,7 +24,7 @@ describe Notify do
end
it 'has the correct subject' do
- should have_subject /Account was created for you/
+ should have_subject /^gitlab \| Account was created for you$/
end
it 'contains the new user\'s login name' do
@@ -42,8 +42,8 @@ describe Notify do
context 'for a project' do
describe 'items that are assignable, the email' do
- let(:assignee) { Factory.create(:user, :email => 'assignee@example.com') }
- let(:previous_assignee) { Factory.create(:user, :name => 'Previous Assignee') }
+ let(:assignee) { Factory.create(:user, email: 'assignee@example.com') }
+ let(:previous_assignee) { Factory.create(:user, name: 'Previous Assignee') }
shared_examples 'an assignee email' do
it 'is sent to the assignee' do
@@ -52,7 +52,7 @@ describe Notify do
end
context 'for issues' do
- let(:issue) { Factory.create(:issue, :assignee => assignee, :project => project ) }
+ let(:issue) { Factory.create(:issue, assignee: assignee, project: project ) }
describe 'that are new' do
subject { Notify.new_issue_email(issue.id) }
@@ -60,7 +60,7 @@ describe Notify do
it_behaves_like 'an assignee email'
it 'has the correct subject' do
- should have_subject /New Issue was created/
+ should have_subject /new issue ##{issue.id} \| #{issue.title} \| #{project.name}/
end
it 'contains a link to the new issue' do
@@ -76,7 +76,7 @@ describe Notify do
it_behaves_like 'a multiple recipients email'
it 'has the correct subject' do
- should have_subject /changed issue/
+ should have_subject /changed issue ##{issue.id} \| #{issue.title}/
end
it 'contains the name of the previous assignee' do
@@ -94,7 +94,7 @@ describe Notify do
end
context 'for merge requests' do
- let(:merge_request) { Factory.create(:merge_request, :assignee => assignee, :project => project) }
+ let(:merge_request) { Factory.create(:merge_request, assignee: assignee, project: project) }
describe 'that are new' do
subject { Notify.new_merge_request_email(merge_request.id) }
@@ -102,7 +102,7 @@ describe Notify do
it_behaves_like 'an assignee email'
it 'has the correct subject' do
- should have_subject /new merge request/
+ should have_subject /new merge request !#{merge_request.id}/
end
it 'contains a link to the new merge request' do
@@ -126,7 +126,7 @@ describe Notify do
it_behaves_like 'a multiple recipients email'
it 'has the correct subject' do
- should have_subject /merge request changed/
+ should have_subject /changed merge request !#{merge_request.id}/
end
it 'contains the name of the previous assignee' do
@@ -146,8 +146,8 @@ describe Notify do
end
context 'items that are noteable, the email for a note' do
- let(:note_author) { Factory.create(:user, :name => 'author_name') }
- let(:note) { Factory.create(:note, :project => project, :author => note_author) }
+ let(:note_author) { Factory.create(:user, name: 'author_name') }
+ let(:note) { Factory.create(:note, project: project, author: note_author) }
before :each do
Note.stub(:find).with(note.id).and_return(note)
@@ -168,7 +168,7 @@ describe Notify do
end
describe 'on a project wall' do
- let(:note_on_the_wall_path) { wall_project_path(project, :anchor => "note_#{note.id}") }
+ let(:note_on_the_wall_path) { wall_project_path(project, anchor: "note_#{note.id}") }
subject { Notify.note_wall_email(recipient.id, note.id) }
@@ -188,6 +188,8 @@ describe Notify do
mock(:commit).tap do |commit|
commit.stub(:id).and_return('fauxsha1')
commit.stub(:project).and_return(project)
+ commit.stub(:short_id).and_return('fauxsha1')
+ commit.stub(:safe_message).and_return('some message')
end
end
before(:each) { note.stub(:target).and_return(commit) }
@@ -197,7 +199,7 @@ describe Notify do
it_behaves_like 'a note email'
it 'has the correct subject' do
- should have_subject /note for commit/
+ should have_subject /note for commit #{commit.short_id}/
end
it 'contains a link to the commit' do
@@ -206,8 +208,8 @@ describe Notify do
end
describe 'on a merge request' do
- let(:merge_request) { Factory.create(:merge_request, :project => project) }
- let(:note_on_merge_request_path) { project_merge_request_path(project, merge_request, :anchor => "note_#{note.id}") }
+ let(:merge_request) { Factory.create(:merge_request, project: project) }
+ let(:note_on_merge_request_path) { project_merge_request_path(project, merge_request, anchor: "note_#{note.id}") }
before(:each) { note.stub(:noteable).and_return(merge_request) }
subject { Notify.note_merge_request_email(recipient.id, note.id) }
@@ -215,7 +217,7 @@ describe Notify do
it_behaves_like 'a note email'
it 'has the correct subject' do
- should have_subject /note for merge request/
+ should have_subject /note for merge request !#{merge_request.id}/
end
it 'contains a link to the merge request note' do
@@ -224,8 +226,8 @@ describe Notify do
end
describe 'on an issue' do
- let(:issue) { Factory.create(:issue, :project => project) }
- let(:note_on_issue_path) { project_issue_path(project, issue, :anchor => "note_#{note.id}") }
+ let(:issue) { Factory.create(:issue, project: project) }
+ let(:note_on_issue_path) { project_issue_path(project, issue, anchor: "note_#{note.id}") }
before(:each) { note.stub(:noteable).and_return(issue) }
subject { Notify.note_issue_email(recipient.id, note.id) }
@@ -233,7 +235,7 @@ describe Notify do
it_behaves_like 'a note email'
it 'has the correct subject' do
- should have_subject /note for issue #{issue.id}/
+ should have_subject /note for issue ##{issue.id}/
end
it 'contains a link to the issue note' do
diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb
index a295e2860cc..188f09978a7 100644
--- a/spec/models/event_spec.rb
+++ b/spec/models/event_spec.rb
@@ -45,25 +45,25 @@ describe Event do
@user = project.owner
data = {
- :before => "0000000000000000000000000000000000000000",
- :after => "0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e",
- :ref => "refs/heads/master",
- :user_id => @user.id,
- :user_name => @user.name,
- :repository => {
- :name => project.name,
- :url => "localhost/rubinius",
- :description => "",
- :homepage => "localhost/rubinius",
- :private => true
+ before: "0000000000000000000000000000000000000000",
+ after: "0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e",
+ ref: "refs/heads/master",
+ user_id: @user.id,
+ user_name: @user.name,
+ repository: {
+ name: project.name,
+ url: "localhost/rubinius",
+ description: "",
+ homepage: "localhost/rubinius",
+ private: true
}
}
@event = Event.create(
- :project => project,
- :action => Event::Pushed,
- :data => data,
- :author_id => @user.id
+ project: project,
+ action: Event::Pushed,
+ data: data,
+ author_id: @user.id
)
end
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index fbd4031fa0b..e9cbd72589a 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -20,9 +20,9 @@ describe Issue do
end
subject { Factory.create(:issue,
- :author => Factory(:user),
- :assignee => Factory(:user),
- :project => Factory.create(:project)) }
+ author: Factory(:user),
+ assignee: Factory(:user),
+ project: Factory.create(:project)) }
it { should be_valid }
describe '#is_being_reassigned?' do
@@ -42,10 +42,10 @@ describe Issue do
end
it 'returns false if the closed attribute has changed and is now false' do
issue = Factory.create(:issue,
- :closed => true,
- :author => Factory(:user),
- :assignee => Factory(:user),
- :project => Factory.create(:project))
+ closed: true,
+ author: Factory(:user),
+ assignee: Factory(:user),
+ project: Factory.create(:project))
issue.closed = false
issue.is_being_closed?.should be_false
end
@@ -58,10 +58,10 @@ describe Issue do
describe '#is_being_reopened?' do
it 'returns true if the closed attribute has changed and is now false' do
issue = Factory.create(:issue,
- :closed => true,
- :author => Factory(:user),
- :assignee => Factory(:user),
- :project => Factory.create(:project))
+ closed: true,
+ author: Factory(:user),
+ assignee: Factory(:user),
+ project: Factory.create(:project))
issue.closed = false
issue.is_being_reopened?.should be_true
end
@@ -78,9 +78,9 @@ describe Issue do
let(:project) { Factory(:project) }
subject {
Factory.create(:issue,
- :author => Factory(:user),
- :assignee => Factory(:user),
- :project => project)
+ author: Factory(:user),
+ assignee: Factory(:user),
+ project: project)
}
it "with no notes has a 0/0 score" do
@@ -106,6 +106,14 @@ describe Issue do
end
end
+ describe ".search" do
+ let!(:issue) { Factory.create(:issue, title: "Searchable issue",
+ project: Factory.create(:project)) }
+
+ it "matches by title" do
+ Issue.search('able').all.should == [issue]
+ end
+ end
end
# == Schema Information
#
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index ac986ccebe3..c7ad08a1e06 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -21,17 +21,17 @@ describe MergeRequest do
end
it { Factory.create(:merge_request,
- :author => Factory(:user),
- :assignee => Factory(:user),
- :project => Factory.create(:project)).should be_valid }
+ author: Factory(:user),
+ assignee: Factory(:user),
+ project: Factory.create(:project)).should be_valid }
describe "plus 1" do
let(:project) { Factory(:project) }
subject {
Factory.create(:merge_request,
- :author => Factory(:user),
- :assignee => Factory(:user),
- :project => project)
+ author: Factory(:user),
+ assignee: Factory(:user),
+ project: project)
}
it "with no notes has a 0/0 score" do
@@ -56,6 +56,15 @@ describe MergeRequest do
subject.upvotes.should == 2
end
end
+
+ describe ".search" do
+ let!(:issue) { Factory.create(:issue, title: "Searchable issue",
+ project: Factory.create(:project)) }
+
+ it "matches by title" do
+ Issue.search('able').all.should == [issue]
+ end
+ end
end
# == Schema Information
#
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index bb71ca990f0..e9acc4e2815 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -26,29 +26,38 @@ describe Milestone do
end
let(:project) { Factory :project }
- let(:milestone) { Factory :milestone, :project => project }
- let(:issue) { Factory :issue, :project => project }
+ let(:milestone) { Factory :milestone, project: project }
+ let(:issue) { Factory :issue, project: project }
it { milestone.should be_valid }
- describe "Issues" do
- before do
+ describe "#percent_complete" do
+ it "should not count open issues" do
milestone.issues << issue
+ milestone.percent_complete.should == 0
end
- it { milestone.percent_complete.should == 0 }
+ it "should count closed issues" do
+ issue.update_attributes(closed: true)
+ milestone.issues << issue
+ milestone.percent_complete.should == 100
+ end
- it do
- issue.update_attributes :closed => true
+ it "should recover from dividing by zero" do
+ milestone.issues.should_receive(:count).and_return(0)
milestone.percent_complete.should == 100
end
end
- describe :expires_at do
- before do
- milestone.update_attributes :due_date => Date.today + 1.day
+ describe "#expires_at" do
+ it "should be nil when due_date is unset" do
+ milestone.update_attributes(due_date: nil)
+ milestone.expires_at.should be_nil
end
- it { milestone.expires_at.should_not be_nil }
+ it "should not be nil when due_date is set" do
+ milestone.update_attributes(due_date: Date.tomorrow)
+ milestone.expires_at.should be_present
+ end
end
end
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index f2dfcabcc87..c97b23cb4fa 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -14,7 +14,7 @@ describe Note do
end
it { Factory.create(:note,
- :project => project).should be_valid }
+ project: project).should be_valid }
describe "Scopes" do
it "should have a today named scope that returns ..." do
Note.today.where_values.should == ["created_at >= '#{Date.today}'"]
@@ -44,9 +44,9 @@ describe Note do
before do
@note = Factory :note,
- :project => project,
- :noteable_id => commit.id,
- :noteable_type => "Commit"
+ project: project,
+ noteable_id: commit.id,
+ noteable_type: "Commit"
end
it "should save a valid note" do
@@ -58,10 +58,10 @@ describe Note do
describe "Pre-line commit notes" do
before do
@note = Factory :note,
- :project => project,
- :noteable_id => commit.id,
- :noteable_type => "Commit",
- :line_code => "0_16_1"
+ project: project,
+ noteable_id: commit.id,
+ noteable_type: "Commit",
+ line_code: "0_16_1"
end
it "should save a valid note" do
@@ -72,7 +72,7 @@ describe Note do
describe '#create_status_change_note' do
let(:project) { Factory.create(:project) }
- let(:thing) { Factory.create(:issue, :project => project) }
+ let(:thing) { Factory.create(:issue, project: project) }
let(:author) { Factory(:user) }
let(:status) { 'new_status' }
@@ -92,7 +92,7 @@ describe Note do
describe :authorization do
before do
@p1 = project
- @p2 = Factory :project, :code => "alien", :path => "gitlabhq_1"
+ @p2 = Factory :project, code: "alien", path: "gitlabhq_1"
@u1 = Factory :user
@u2 = Factory :user
@u3 = Factory :user
@@ -102,8 +102,8 @@ describe Note do
describe :read do
before do
- @p1.users_projects.create(:user => @u2, :project_access => UsersProject::GUEST)
- @p2.users_projects.create(:user => @u3, :project_access => UsersProject::GUEST)
+ @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 }
@@ -113,8 +113,8 @@ describe Note do
describe :write do
before do
- @p1.users_projects.create(:user => @u2, :project_access => UsersProject::DEVELOPER)
- @p2.users_projects.create(:user => @u3, :project_access => UsersProject::DEVELOPER)
+ @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 }
@@ -124,9 +124,9 @@ describe Note do
describe :admin do
before do
- @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)
+ @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
index fcc969ceba5..129e3d61030 100644
--- a/spec/models/project_hooks_spec.rb
+++ b/spec/models/project_hooks_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Project, "Hooks" do
let(:project) { Factory :project }
before do
- @key = Factory :key, :user => project.owner
+ @key = Factory :key, user: project.owner
@user = @key.user
@key_id = @key.identifier
end
@@ -21,44 +21,44 @@ describe Project, "Hooks" do
end
end
- describe "Web hooks" do
+ describe "Project hooks" do
context "with no web hooks" do
it "raises no errors" do
lambda {
- project.execute_web_hooks('oldrev', 'newrev', 'ref', @user)
+ project.execute_hooks('oldrev', 'newrev', 'ref', @user)
}.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]
+ @project_hook = Factory(:project_hook)
+ @project_hook_2 = Factory(:project_hook)
+ project.hooks << [@project_hook, @project_hook_2]
end
it "executes multiple web hook" do
- @webhook.should_receive(:execute).once
- @webhook_2.should_receive(:execute).once
+ @project_hook.should_receive(:execute).once
+ @project_hook_2.should_receive(:execute).once
- project.execute_web_hooks('oldrev', 'newrev', 'refs/heads/master', @user)
+ project.execute_hooks('oldrev', 'newrev', 'refs/heads/master', @user)
end
end
context "does not execute web hooks" do
before do
- @webhook = Factory(:web_hook)
- project.web_hooks << [@webhook]
+ @project_hook = Factory(:project_hook)
+ project.hooks << [@project_hook]
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', @user)
+ @project_hook.should_not_receive(:execute)
+ project.execute_hooks('00000000000000000000000000000000', 'newrev', 'refs/heads/master', @user)
end
it "when pushing tags" do
- @webhook.should_not_receive(:execute)
- project.execute_web_hooks('oldrev', 'newrev', 'refs/tags/v1.0.0', @user)
+ @project_hook.should_not_receive(:execute)
+ project.execute_hooks('oldrev', 'newrev', 'refs/tags/v1.0.0', @user)
end
end
diff --git a/spec/models/project_security_spec.rb b/spec/models/project_security_spec.rb
index bd697af9652..baf6d4b68ea 100644
--- a/spec/models/project_security_spec.rb
+++ b/spec/models/project_security_spec.rb
@@ -12,7 +12,7 @@ describe Project do
describe "read access" do
before do
- @p1.users_projects.create(:project => @p1, :user => @u2, :project_access => UsersProject::REPORTER)
+ @p1.users_projects.create(project: @p1, user: @u2, project_access: UsersProject::REPORTER)
end
it { @abilities.allowed?(@u1, :read_project, @p1).should be_false }
@@ -21,7 +21,7 @@ describe Project do
describe "write access" do
before do
- @p1.users_projects.create(:project => @p1, :user => @u2, :project_access => UsersProject::DEVELOPER)
+ @p1.users_projects.create(project: @p1, user: @u2, project_access: UsersProject::DEVELOPER)
end
it { @abilities.allowed?(@u1, :write_project, @p1).should be_false }
@@ -30,8 +30,8 @@ describe Project do
describe "admin access" do
before do
- @p1.users_projects.create(:project => @p1, :user => @u1, :project_access => UsersProject::DEVELOPER)
- @p1.users_projects.create(:project => @p1, :user => @u2, :project_access => UsersProject::MASTER)
+ @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 381fe7592c9..af193295ee3 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -11,7 +11,7 @@ describe Project do
it { should have_many(:issues).dependent(:destroy) }
it { should have_many(:notes).dependent(:destroy) }
it { should have_many(:snippets).dependent(:destroy) }
- it { should have_many(:web_hooks).dependent(:destroy) }
+ it { should have_many(:hooks).dependent(:destroy) }
it { should have_many(:deploy_keys).dependent(:destroy) }
end
@@ -22,21 +22,55 @@ describe Project do
end
describe "Respond to" do
- it { should respond_to(:repository_writers) }
- it { should respond_to(:add_access) }
- it { should respond_to(:reset_access) }
- it { should respond_to(:update_repository) }
- it { should respond_to(:destroy_repository) }
it { should respond_to(:public?) }
it { should respond_to(:private?) }
it { should respond_to(:url_to_repo) }
it { should respond_to(:path_to_repo) }
it { should respond_to(:valid_repo?) }
it { should respond_to(:repo_exists?) }
+
+ # Repository Role
+ it { should respond_to(:tree) }
+ it { should respond_to(:root_ref) }
it { should respond_to(:repo) }
it { should respond_to(:tags) }
it { should respond_to(:commit) }
+ it { should respond_to(:commits) }
+ it { should respond_to(:commits_between) }
+ it { should respond_to(:commits_with_refs) }
+ it { should respond_to(:commits_since) }
it { should respond_to(:commits_between) }
+ it { should respond_to(:satellite) }
+ it { should respond_to(:update_repository) }
+ it { should respond_to(:destroy_repository) }
+ it { should respond_to(:archive_repo) }
+
+ # Authority Role
+ it { should respond_to(:add_access) }
+ it { should respond_to(:reset_access) }
+ it { should respond_to(:repository_writers) }
+ it { should respond_to(:repository_masters) }
+ it { should respond_to(:repository_readers) }
+ it { should respond_to(:allow_read_for?) }
+ it { should respond_to(:guest_access_for?) }
+ it { should respond_to(:report_access_for?) }
+ it { should respond_to(:dev_access_for?) }
+ it { should respond_to(:master_access_for?) }
+
+ # Team Role
+ it { should respond_to(:team_member_by_name_or_email) }
+ it { should respond_to(:team_member_by_id) }
+ it { should respond_to(:add_user_to_team) }
+ it { should respond_to(:add_users_to_team) }
+ it { should respond_to(:add_user_id_to_team) }
+ it { should respond_to(:add_users_ids_to_team) }
+
+ # Project Push Role
+ it { should respond_to(:observe_push) }
+ it { should respond_to(:update_merge_requests) }
+ it { should respond_to(:execute_hooks) }
+ it { should respond_to(:post_receive_data) }
+ it { should respond_to(:trigger_post_receive) }
end
it "should not allow 'gitolite-admin' as repo name" do
@@ -45,17 +79,17 @@ describe Project do
end
it "should return valid url to repo" do
- project = Project.new(:path => "somewhere")
+ project = Project.new(path: "somewhere")
project.url_to_repo.should == Gitlab.config.ssh_path + "somewhere.git"
end
it "should return path to repo" do
- project = Project.new(:path => "somewhere")
+ project = Project.new(path: "somewhere")
project.path_to_repo.should == File.join(Rails.root, "tmp", "tests", "somewhere")
end
it "returns the full web URL for this repo" do
- project = Project.new(:code => "somewhere")
+ project = Project.new(code: "somewhere")
project.web_url.should == "#{Gitlab.config.url}/somewhere"
end
@@ -66,7 +100,7 @@ describe Project do
end
it "should be invalid repo" do
- project = Project.new(:name => "ok_name", :path => "/INVALID_PATH/", :code => "NEOK")
+ project = Project.new(name: "ok_name", path: "/INVALID_PATH/", code: "NEOK")
project.valid_repo?.should be_false
end
end
@@ -86,7 +120,7 @@ describe Project do
let(:project) { Factory :project }
it 'returns the creation date of the project\'s last event if present' do
- last_event = double(:created_at => 'now')
+ last_event = double(created_at: 'now')
project.stub(:events).and_return( [double, double, last_event] )
project.last_activity_date.should == last_event.created_at
end
@@ -126,7 +160,7 @@ describe Project do
end
it "should return nil" do
- lambda { Project.new(:path => "invalid").repo }.should raise_error(Grit::NoSuchPathError)
+ lambda { Project.new(path: "invalid").repo }.should raise_error(Grit::NoSuchPathError)
end
it "should return nil" do
@@ -179,10 +213,10 @@ describe Project do
before do
@merge_request = Factory :merge_request,
- :project => project,
- :merged => false,
- :closed => false
- @key = Factory :key, :user_id => project.owner.id
+ project: project,
+ merged: false,
+ closed: false
+ @key = Factory :key, user_id: project.owner.id
end
it "should close merge request if last commit from source branch was pushed to target branch" do
diff --git a/spec/models/protected_branch_spec.rb b/spec/models/protected_branch_spec.rb
index becc1be4d76..1654e3b6f56 100644
--- a/spec/models/protected_branch_spec.rb
+++ b/spec/models/protected_branch_spec.rb
@@ -24,7 +24,7 @@ describe ProtectedBranch do
end
describe 'Callbacks' do
- subject { ProtectedBranch.new(:project => project, :name => 'branch_name') }
+ subject { ProtectedBranch.new(project: project, name: 'branch_name') }
it 'call update_repository after save' do
subject.should_receive(:update_repository)
@@ -37,21 +37,8 @@ describe ProtectedBranch do
end
end
- describe '#update_repository' do
- let(:gitolite) { mock }
-
- subject { ProtectedBranch.new(:project => project) }
-
- it "updates the branch's project repo permissions" do
- Gitlab::GitHost.should_receive(:system).and_return(gitolite)
- gitolite.should_receive(:update_project).with(project.path, project)
-
- subject.update_repository
- end
- end
-
describe '#commit' do
- subject { ProtectedBranch.new(:project => project, :name => 'cant_touch_this') }
+ subject { ProtectedBranch.new(project: project, name: 'cant_touch_this') }
it 'commits itself to its project' do
project.should_receive(:commit).with('cant_touch_this')
diff --git a/spec/models/system_hook_spec.rb b/spec/models/system_hook_spec.rb
new file mode 100644
index 00000000000..56d76ed08cf
--- /dev/null
+++ b/spec/models/system_hook_spec.rb
@@ -0,0 +1,63 @@
+require "spec_helper"
+
+describe SystemHook do
+ describe "execute" do
+ before(:each) { ActiveRecord::Base.observers.enable(:all) }
+
+ before(:each) do
+ @system_hook = Factory :system_hook
+ WebMock.stub_request(:post, @system_hook.url)
+ end
+
+ it "project_create hook" do
+ user = Factory :user
+ with_resque do
+ project = Factory :project_without_owner, owner: user
+ end
+ WebMock.should have_requested(:post, @system_hook.url).with(body: /project_create/).once
+ end
+
+ it "project_destroy hook" do
+ project = Factory :project
+ with_resque do
+ project.destroy
+ end
+ WebMock.should have_requested(:post, @system_hook.url).with(body: /project_destroy/).once
+ end
+
+ it "user_create hook" do
+ with_resque do
+ Factory :user
+ end
+ WebMock.should have_requested(:post, @system_hook.url).with(body: /user_create/).once
+ end
+
+ it "user_destroy hook" do
+ user = Factory :user
+ with_resque do
+ user.destroy
+ end
+ WebMock.should have_requested(:post, @system_hook.url).with(body: /user_destroy/).once
+ end
+
+ it "project_create hook" do
+ user = Factory :user
+ project = Factory :project
+ with_resque do
+ project.users << user
+ end
+ WebMock.should have_requested(:post, @system_hook.url).with(body: /user_add_to_team/).once
+ end
+
+ it "project_destroy hook" do
+ user = Factory :user
+ project = Factory :project
+ project.users << user
+ with_resque do
+ project.users_projects.clear
+ end
+ WebMock.should have_requested(:post, @system_hook.url).with(body: /user_remove_from_team/).once
+ end
+ end
+
+end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 91771ca903b..265dcef1e77 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -18,24 +18,29 @@ describe User do
end
it "should return valid identifier" do
- user = User.new(:email => "test@mail.com")
+ user = User.new(email: "test@mail.com")
user.identifier.should == "test_mail_com"
end
+ it "should return identifier without + sign" do
+ user = User.new(email: "test+foo@mail.com")
+ user.identifier.should == "test_foo_mail_com"
+ end
+
it "should execute callback when force_random_password specified" do
- user = User.new(:email => "test@mail.com", :force_random_password => true)
+ user = User.new(email: "test@mail.com", force_random_password: true)
user.should_receive(:generate_password)
user.save
end
it "should not generate password by default" do
- user = Factory(:user, :password => 'abcdefg', :password_confirmation => 'abcdefg')
+ user = Factory(:user, password: 'abcdefg', password_confirmation: 'abcdefg')
user.password.should == 'abcdefg'
end
it "should generate password when forcing random password" do
Devise.stub(:friendly_token).and_return('123456789')
- user = User.create(:email => "test1@mail.com", :force_random_password => true)
+ user = User.create(email: "test1@mail.com", force_random_password: true)
user.password.should == user.password_confirmation
user.password.should == '12345678'
end
@@ -49,8 +54,8 @@ describe User do
before do
@user = Factory :user
@note = Factory :note,
- :author => @user,
- :project => Factory(:project)
+ author: @user,
+ project: Factory(:project)
end
it "should destroy all notes with user" do
diff --git a/spec/models/web_hook_spec.rb b/spec/models/web_hook_spec.rb
index 9971bd5819d..885947614d7 100644
--- a/spec/models/web_hook_spec.rb
+++ b/spec/models/web_hook_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe WebHook do
+describe ProjectHook do
describe "Associations" do
it { should belong_to :project }
end
@@ -23,32 +23,32 @@ describe WebHook do
describe "execute" do
before(:each) do
- @webhook = Factory :web_hook
+ @project_hook = Factory :project_hook
@project = Factory :project
- @project.web_hooks << [@webhook]
+ @project.hooks << [@project_hook]
@data = { before: 'oldrev', after: 'newrev', ref: 'ref'}
- WebMock.stub_request(:post, @webhook.url)
+ WebMock.stub_request(:post, @project_hook.url)
end
it "POSTs to the web hook URL" do
- @webhook.execute(@data)
- WebMock.should have_requested(:post, @webhook.url).once
+ @project_hook.execute(@data)
+ WebMock.should have_requested(:post, @project_hook.url).once
end
it "POSTs the data as JSON" do
json = @data.to_json
- @webhook.execute(@data)
- WebMock.should have_requested(:post, @webhook.url).with(body: json).once
+ @project_hook.execute(@data)
+ WebMock.should have_requested(:post, @project_hook.url).with(body: json).once
end
it "catches exceptions" do
WebHook.should_receive(:post).and_raise("Some HTTP Post error")
lambda {
- @webhook.execute(@data)
- }.should_not raise_error
+ @project_hook.execute(@data)
+ }.should raise_error
end
end
end
diff --git a/spec/models/activity_observer_spec.rb b/spec/observers/activity_observer_spec.rb
index aed1b26d306..0db4a9985be 100644
--- a/spec/models/activity_observer_spec.rb
+++ b/spec/observers/activity_observer_spec.rb
@@ -11,7 +11,7 @@ describe ActivityObserver do
describe "Merge Request created" do
before do
MergeRequest.observers.enable :activity_observer do
- @merge_request = Factory :merge_request, :project => project
+ @merge_request = Factory :merge_request, project: project
@event = Event.last
end
end
@@ -24,7 +24,7 @@ describe ActivityObserver do
describe "Issue created" do
before do
Issue.observers.enable :activity_observer do
- @issue = Factory :issue, :project => project
+ @issue = Factory :issue, project: project
@event = Event.last
end
end
@@ -36,8 +36,8 @@ describe ActivityObserver do
#describe "Issue commented" do
#before do
- #@issue = Factory :issue, :project => project
- #@note = Factory :note, :noteable => @issue, :project => project
+ #@issue = Factory :issue, project: project
+ #@note = Factory :note, noteable: @issue, project: project
#@event = Event.last
#end
diff --git a/spec/models/issue_observer_spec.rb b/spec/observers/issue_observer_spec.rb
index 2b9798f7e53..c6a405f1c1b 100644
--- a/spec/models/issue_observer_spec.rb
+++ b/spec/observers/issue_observer_spec.rb
@@ -1,9 +1,9 @@
require 'spec_helper'
describe IssueObserver do
- let(:some_user) { double(:user, :id => 1) }
- let(:assignee) { double(:user, :id => 2) }
- let(:issue) { double(:issue, :id => 42, :assignee => assignee) }
+ let(:some_user) { double(:user, id: 1) }
+ let(:assignee) { double(:user, id: 2) }
+ let(:issue) { double(:issue, id: 42, assignee: assignee) }
before(:each) { subject.stub(:current_user).and_return(some_user) }
@@ -15,13 +15,13 @@ describe IssueObserver do
subject.should_receive(:after_create)
Issue.observers.enable :issue_observer do
- Factory.create(:issue, :project => Factory.create(:project))
+ Factory.create(:issue, project: Factory.create(:project))
end
end
it 'sends an email to the assignee' do
Notify.should_receive(:new_issue_email).with(issue.id).
- and_return(double(:deliver => true))
+ and_return(double(deliver: true))
subject.after_create(issue)
end
@@ -42,7 +42,7 @@ describe IssueObserver do
end
it 'is called when an issue is changed' do
- changed = Factory.create(:issue, :project => Factory.create(:project))
+ changed = Factory.create(:issue, project: Factory.create(:project))
subject.should_receive(:after_update)
Issue.observers.enable :issue_observer do
@@ -101,7 +101,7 @@ describe IssueObserver do
end
describe '#send_reassigned_email' do
- let(:previous_assignee) { double(:user, :id => 3) }
+ let(:previous_assignee) { double(:user, id: 3) }
before(:each) do
issue.stub(:assignee_id).and_return(assignee.id)
@@ -110,7 +110,7 @@ describe IssueObserver do
def it_sends_a_reassigned_email_to(recipient)
Notify.should_receive(:reassigned_issue_email).with(recipient, issue.id, previous_assignee.id).
- and_return(double(:deliver => true))
+ and_return(double(deliver: true))
end
def it_does_not_send_a_reassigned_email_to(recipient)
diff --git a/spec/models/user_observer_spec.rb b/spec/observers/user_observer_spec.rb
index 23dac98bb74..23dac98bb74 100644
--- a/spec/models/user_observer_spec.rb
+++ b/spec/observers/user_observer_spec.rb
diff --git a/spec/requests/admin/admin_hooks_spec.rb b/spec/requests/admin/admin_hooks_spec.rb
new file mode 100644
index 00000000000..2f026aabab8
--- /dev/null
+++ b/spec/requests/admin/admin_hooks_spec.rb
@@ -0,0 +1,53 @@
+require 'spec_helper'
+
+describe "Admin::Hooks" do
+ before do
+ @project = Factory :project,
+ name: "LeGiT",
+ code: "LGT"
+ login_as :admin
+
+ @system_hook = Factory :system_hook
+
+ end
+
+ describe "GET /admin/hooks" do
+ it "should be ok" do
+ visit admin_root_path
+ within ".main_menu" do
+ click_on "Hooks"
+ end
+ current_path.should == admin_hooks_path
+ end
+
+ it "should have hooks list" do
+ visit admin_hooks_path
+ page.should have_content(@system_hook.url)
+ end
+ end
+
+ describe "New Hook" do
+ before do
+ @url = Faker::Internet.uri("http")
+ visit admin_hooks_path
+ fill_in "hook_url", with: @url
+ expect { click_button "Add System Hook" }.to change(SystemHook, :count).by(1)
+ end
+
+ it "should open new hook popup" do
+ page.current_path.should == admin_hooks_path
+ page.should have_content(@url)
+ end
+ end
+
+ describe "Test" do
+ before do
+ WebMock.stub_request(:post, @system_hook.url)
+ visit admin_hooks_path
+ click_link "Test Hook"
+ end
+
+ it { page.current_path.should == admin_hooks_path }
+ end
+
+end
diff --git a/spec/requests/admin/admin_projects_spec.rb b/spec/requests/admin/admin_projects_spec.rb
index fb6577de326..0ce66f5f868 100644
--- a/spec/requests/admin/admin_projects_spec.rb
+++ b/spec/requests/admin/admin_projects_spec.rb
@@ -3,8 +3,8 @@ require 'spec_helper'
describe "Admin::Projects" do
before do
@project = Factory :project,
- :name => "LeGiT",
- :code => "LGT"
+ name: "LeGiT",
+ code: "LGT"
login_as :admin
end
@@ -41,15 +41,15 @@ describe "Admin::Projects" do
end
it "should have project edit page" do
- page.should have_content("Name")
- page.should have_content("Code")
+ page.should have_content("Project name")
+ page.should have_content("URL")
end
describe "Update project" do
before do
- fill_in "project_name", :with => "Big Bang"
- fill_in "project_code", :with => "BB1"
- click_button "Save"
+ fill_in "project_name", with: "Big Bang"
+ fill_in "project_code", with: "BB1"
+ click_button "Save Project"
@project.reload
end
@@ -76,20 +76,19 @@ describe "Admin::Projects" do
end
it "should have labels for new project" do
- page.should have_content("Name")
- page.should have_content("Path")
- page.should have_content("Description")
+ page.should have_content("Project name is")
+ page.should have_content("Git Clone")
+ page.should have_content("URL")
end
end
describe "POST /admin/projects" do
before do
visit new_admin_project_path
- fill_in 'Name', :with => 'NewProject'
- fill_in 'Code', :with => 'NPR'
- fill_in 'Path', :with => 'gitlabhq_1'
- fill_in 'Description', :with => 'New Project Description'
- expect { click_button "Save" }.to change { Project.count }.by(1)
+ fill_in 'project_name', with: 'NewProject'
+ fill_in 'project_code', with: 'NPR'
+ fill_in 'project_path', with: 'gitlabhq_1'
+ expect { click_button "Create project" }.to change { Project.count }.by(1)
@project = Project.last
end
@@ -100,7 +99,6 @@ describe "Admin::Projects" do
it "should show project" do
page.should have_content(@project.name)
page.should have_content(@project.path)
- page.should have_content(@project.description)
end
end
@@ -111,7 +109,7 @@ describe "Admin::Projects" do
end
it "should create new user" do
- select @new_user.name, :from => "user_ids"
+ 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)
diff --git a/spec/requests/admin/admin_users_spec.rb b/spec/requests/admin/admin_users_spec.rb
index ba6831e3d8b..68358bf0a0f 100644
--- a/spec/requests/admin/admin_users_spec.rb
+++ b/spec/requests/admin/admin_users_spec.rb
@@ -22,10 +22,10 @@ describe "Admin::Users" do
before do
@password = "123ABC"
visit new_admin_user_path
- fill_in "user_name", :with => "Big Bang"
- fill_in "user_email", :with => "bigbang@mail.com"
- fill_in "user_password", :with => @password
- fill_in "user_password_confirmation", :with => @password
+ fill_in "user_name", with: "Big Bang"
+ fill_in "user_email", with: "bigbang@mail.com"
+ fill_in "user_password", with: @password
+ fill_in "user_password_confirmation", with: @password
end
it "should create new user" do
@@ -40,7 +40,7 @@ describe "Admin::Users" do
end
it "should call send mail" do
- Notify.should_receive(:new_user_email).and_return(stub(:deliver => true))
+ Notify.should_receive(:new_user_email).and_return(stub(deliver: true))
User.observers.enable :user_observer do
click_button "Save"
@@ -88,8 +88,8 @@ describe "Admin::Users" do
describe "Update user" do
before do
- fill_in "user_name", :with => "Big Bang"
- fill_in "user_email", :with => "bigbang@mail.com"
+ fill_in "user_name", with: "Big Bang"
+ fill_in "user_email", with: "bigbang@mail.com"
check "user_admin"
click_button "Save"
end
@@ -114,7 +114,7 @@ describe "Admin::Users" do
end
it "should create new user" do
- select @new_project.name, :from => "project_ids"
+ 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)
diff --git a/spec/requests/admin/security_spec.rb b/spec/requests/admin/security_spec.rb
index 0b0edb85a37..6306832628b 100644
--- a/spec/requests/admin/security_spec.rb
+++ b/spec/requests/admin/security_spec.rb
@@ -2,20 +2,26 @@ require 'spec_helper'
describe "Admin::Projects" do
describe "GET /admin/projects" do
- it { admin_projects_path.should be_allowed_for :admin }
- it { admin_projects_path.should be_denied_for :user }
- it { admin_projects_path.should be_denied_for :visitor }
+ subject { admin_projects_path }
+
+ it { should be_allowed_for :admin }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
end
describe "GET /admin/users" do
- it { admin_users_path.should be_allowed_for :admin }
- it { admin_users_path.should be_denied_for :user }
- it { admin_users_path.should be_denied_for :visitor }
+ subject { admin_users_path }
+
+ it { should be_allowed_for :admin }
+ it { should be_denied_for :user }
+ it { 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 }
- it { admin_emails_path.should be_denied_for :visitor }
+ describe "GET /admin/hooks" do
+ subject { admin_hooks_path }
+
+ it { should be_allowed_for :admin }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
end
end
diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb
new file mode 100644
index 00000000000..c00a056d079
--- /dev/null
+++ b/spec/requests/api/issues_spec.rb
@@ -0,0 +1,73 @@
+require 'spec_helper'
+
+describe Gitlab::API do
+ include ApiHelpers
+
+ let(:user) { Factory :user }
+ let!(:project) { Factory :project, owner: user }
+ let!(:issue) { Factory :issue, author: user, assignee: user, project: project }
+ before { project.add_access(user, :read) }
+
+ describe "GET /issues" do
+ it "should return authentication error" do
+ get api("/issues")
+ response.status.should == 401
+ end
+
+ describe "authenticated GET /issues" do
+ it "should return an array of issues" do
+ get api("/issues", user)
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.first['title'].should == issue.title
+ end
+ end
+ end
+
+ describe "GET /projects/:id/issues" do
+ it "should return project issues" do
+ get api("/projects/#{project.code}/issues", user)
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.first['title'].should == issue.title
+ end
+ end
+
+ describe "GET /projects/:id/issues/:issue_id" do
+ it "should return a project issue by id" do
+ get api("/projects/#{project.code}/issues/#{issue.id}", user)
+ response.status.should == 200
+ json_response['title'].should == issue.title
+ end
+ end
+
+ describe "POST /projects/:id/issues" do
+ it "should create a new project issue" do
+ post api("/projects/#{project.code}/issues", user),
+ title: 'new issue', labels: 'label, label2'
+ response.status.should == 201
+ json_response['title'].should == 'new issue'
+ json_response['description'].should be_nil
+ json_response['labels'].should == ['label', 'label2']
+ end
+ end
+
+ describe "PUT /projects/:id/issues/:issue_id" do
+ it "should update a project issue" do
+ put api("/projects/#{project.code}/issues/#{issue.id}", user),
+ title: 'updated title', labels: 'label2', closed: 1
+ response.status.should == 200
+ json_response['title'].should == 'updated title'
+ json_response['labels'].should == ['label2']
+ json_response['closed'].should be_true
+ end
+ end
+
+ describe "DELETE /projects/:id/issues/:issue_id" do
+ it "should delete a project issue" do
+ expect {
+ delete api("/projects/#{project.code}/issues/#{issue.id}", user)
+ }.to change { Issue.count }.by(-1)
+ end
+ end
+end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
new file mode 100644
index 00000000000..0cbc12af53b
--- /dev/null
+++ b/spec/requests/api/projects_spec.rb
@@ -0,0 +1,135 @@
+require 'spec_helper'
+
+describe Gitlab::API do
+ include ApiHelpers
+
+ let(:user) { Factory :user }
+ let!(:project) { Factory :project, owner: user }
+ let!(:snippet) { Factory :snippet, author: user, project: project, title: 'example' }
+ before { project.add_access(user, :read) }
+
+ describe "GET /projects" do
+ it "should return authentication error" do
+ get api("/projects")
+ response.status.should == 401
+ end
+
+ describe "authenticated GET /projects" do
+ it "should return an array of projects" do
+ get api("/projects", user)
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.first['name'].should == project.name
+ json_response.first['owner']['email'].should == user.email
+ end
+ end
+ end
+
+ describe "GET /projects/:id" do
+ it "should return a project by id" do
+ get api("/projects/#{project.id}", user)
+ response.status.should == 200
+ json_response['name'].should == project.name
+ json_response['owner']['email'].should == user.email
+ end
+
+ it "should return a project by code name" do
+ get api("/projects/#{project.code}", user)
+ response.status.should == 200
+ json_response['name'].should == project.name
+ end
+
+ it "should return a 404 error if not found" do
+ get api("/projects/42", user)
+ response.status.should == 404
+ json_response['message'].should == '404 Not found'
+ end
+ end
+
+ describe "GET /projects/:id/repository/branches" do
+ it "should return an array of project branches" do
+ get api("/projects/#{project.code}/repository/branches", user)
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.first['name'].should == project.repo.heads.sort_by(&:name).first.name
+ end
+ end
+
+ describe "GET /projects/:id/repository/branches/:branch" do
+ it "should return the branch information for a single branch" do
+ get api("/projects/#{project.code}/repository/branches/new_design", user)
+ response.status.should == 200
+
+ json_response['name'].should == 'new_design'
+ json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1'
+ end
+ end
+
+ describe "GET /projects/:id/repository/tags" do
+ it "should return an array of project tags" do
+ get api("/projects/#{project.code}/repository/tags", user)
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.first['name'].should == project.repo.tags.sort_by(&:name).reverse.first.name
+ end
+ end
+
+ describe "GET /projects/:id/snippets/:snippet_id" do
+ it "should return a project snippet" do
+ get api("/projects/#{project.code}/snippets/#{snippet.id}", user)
+ response.status.should == 200
+ json_response['title'].should == snippet.title
+ end
+ end
+
+ describe "POST /projects/:id/snippets" do
+ it "should create a new project snippet" do
+ post api("/projects/#{project.code}/snippets", user),
+ title: 'api test', file_name: 'sample.rb', code: 'test'
+ response.status.should == 201
+ json_response['title'].should == 'api test'
+ end
+ end
+
+ describe "PUT /projects/:id/snippets" do
+ it "should update an existing project snippet" do
+ put api("/projects/#{project.code}/snippets/#{snippet.id}", user),
+ code: 'updated code'
+ response.status.should == 200
+ json_response['title'].should == 'example'
+ snippet.reload.content.should == 'updated code'
+ end
+ end
+
+ describe "DELETE /projects/:id/snippets/:snippet_id" do
+ it "should delete existing project snippet" do
+ expect {
+ delete api("/projects/#{project.code}/snippets/#{snippet.id}", user)
+ }.to change { Snippet.count }.by(-1)
+ end
+ end
+
+ describe "GET /projects/:id/snippets/:snippet_id/raw" do
+ it "should get a raw project snippet" do
+ get api("/projects/#{project.code}/snippets/#{snippet.id}/raw", user)
+ response.status.should == 200
+ end
+ end
+
+ describe "GET /projects/:id/:sha/blob" do
+ it "should get the raw file contents" do
+ get api("/projects/#{project.code}/repository/commits/master/blob?filepath=README.md", user)
+ response.status.should == 200
+ end
+
+ it "should return 404 for invalid branch_name" do
+ get api("/projects/#{project.code}/repository/commits/invalid_branch_name/blob?filepath=README.md", user)
+ response.status.should == 404
+ end
+
+ it "should return 404 for invalid file" do
+ get api("/projects/#{project.code}/repository/commits/master/blob?filepath=README.invalid", user)
+ response.status.should == 404
+ end
+ end
+end
diff --git a/spec/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 32b9379d212..d791962adc2 100644
--- a/spec/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -1,17 +1,19 @@
require 'spec_helper'
describe Gitlab::API do
+ include ApiHelpers
+
let(:user) { Factory :user }
describe "GET /users" do
it "should return authentication error" do
- get "#{api_prefix}/users"
+ get api("/users")
response.status.should == 401
end
describe "authenticated GET /users" do
it "should return an array of users" do
- get "#{api_prefix}/users?private_token=#{user.private_token}"
+ get api("/users", user)
response.status.should == 200
json_response.should be_an Array
json_response.first['email'].should == user.email
@@ -21,7 +23,7 @@ describe Gitlab::API do
describe "GET /users/:id" do
it "should return a user by id" do
- get "#{api_prefix}/users/#{user.id}?private_token=#{user.private_token}"
+ get api("/users/#{user.id}", user)
response.status.should == 200
json_response['email'].should == user.email
end
@@ -29,7 +31,7 @@ describe Gitlab::API do
describe "GET /user" do
it "should return current user" do
- get "#{api_prefix}/user?private_token=#{user.private_token}"
+ get api("/user", user)
response.status.should == 200
json_response['email'].should == user.email
end
diff --git a/spec/requests/atom/dashboard_issues_spec.rb b/spec/requests/atom/dashboard_issues_spec.rb
new file mode 100644
index 00000000000..1d208c70b12
--- /dev/null
+++ b/spec/requests/atom/dashboard_issues_spec.rb
@@ -0,0 +1,47 @@
+require 'spec_helper'
+
+describe "User Issues Dashboard" do
+ describe "GET /issues" do
+ before do
+
+ login_as :user
+
+ @project1 = Factory :project,
+ path: "gitlabhq_0",
+ code: "TEST1"
+
+ @project2 = Factory :project,
+ path: "gitlabhq_1",
+ code: "TEST2"
+
+ @project1.add_access(@user, :read, :write)
+ @project2.add_access(@user, :read, :write)
+
+ @issue1 = Factory :issue,
+ author: @user,
+ assignee: @user,
+ project: @project1
+
+ @issue2 = Factory :issue,
+ author: @user,
+ assignee: @user,
+ project: @project2
+
+ visit dashboard_issues_path
+ end
+
+ describe "atom feed", js: false do
+ it "should render atom feed via private token" do
+ logout
+ visit dashboard_issues_path(:atom, private_token: @user.private_token)
+
+ page.response_headers['Content-Type'].should have_content("application/atom+xml")
+ page.body.should have_selector("title", text: "#{@user.name} issues")
+ page.body.should have_selector("author email", text: @issue1.author_email)
+ page.body.should have_selector("entry summary", text: @issue1.title)
+ page.body.should have_selector("author email", text: @issue2.author_email)
+ page.body.should have_selector("entry summary", text: @issue2.title)
+ end
+ end
+ end
+end
diff --git a/spec/requests/dashboard_spec.rb b/spec/requests/atom/dashboard_spec.rb
index 16ededd02af..00c7a5255ca 100644
--- a/spec/requests/dashboard_spec.rb
+++ b/spec/requests/atom/dashboard_spec.rb
@@ -5,34 +5,22 @@ describe "User Dashboard" do
describe "GET /" do
before do
- @project = Factory :project, :owner => @user
+ @project = Factory :project, owner: @user
@project.add_access(@user, :read)
visit dashboard_path
end
- it "should be on projects page" do
- current_path.should == dashboard_path
- end
-
- it "should have link to new project" do
- page.should have_content("New Project")
- end
-
- it "should have project" do
- page.should have_content(@project.name)
- end
-
it "should render projects atom feed via private token" do
logout
- visit dashboard_path(:atom, :private_token => @user.private_token)
+ visit dashboard_path(:atom, private_token: @user.private_token)
page.body.should have_selector("feed title")
end
it "should not render projects page via private token" do
logout
- visit dashboard_path(:private_token => @user.private_token)
+ visit dashboard_path(private_token: @user.private_token)
current_path.should == new_user_session_path
end
end
diff --git a/spec/requests/atom/issues_spec.rb b/spec/requests/atom/issues_spec.rb
new file mode 100644
index 00000000000..468d1b2260a
--- /dev/null
+++ b/spec/requests/atom/issues_spec.rb
@@ -0,0 +1,40 @@
+require 'spec_helper'
+
+describe "Issues" do
+ let(:project) { Factory :project }
+
+ before do
+ login_as :user
+ project.add_access(@user, :read, :write)
+ end
+
+ describe "GET /issues" do
+ before do
+ @issue = Factory :issue,
+ author: @user,
+ assignee: @user,
+ project: project
+
+ visit project_issues_path(project)
+ end
+
+ it "should render atom feed" do
+ visit project_issues_path(project, :atom)
+
+ page.response_headers['Content-Type'].should have_content("application/atom+xml")
+ page.body.should have_selector("title", text: "#{project.name} issues")
+ page.body.should have_selector("author email", text: @issue.author_email)
+ page.body.should have_selector("entry summary", text: @issue.title)
+ end
+
+ it "should render atom feed via private token" do
+ logout
+ visit project_issues_path(project, :atom, private_token: @user.private_token)
+
+ page.response_headers['Content-Type'].should have_content("application/atom+xml")
+ page.body.should have_selector("title", text: "#{project.name} issues")
+ page.body.should have_selector("author email", text: @issue.author_email)
+ page.body.should have_selector("entry summary", text: @issue.title)
+ end
+ end
+end
diff --git a/spec/requests/commits_notes_spec.rb b/spec/requests/commits_notes_spec.rb
deleted file mode 100644
index fde42a8f55e..00000000000
--- a/spec/requests/commits_notes_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-require 'spec_helper'
-
-describe "Issues" do
- let(:project) { Factory :project }
- let!(:commit) { project.repo.commits.first }
-
- before do
- login_as :user
- project.add_access(@user, :read, :write)
- end
-
- describe "add new note", :js => true do
- before do
- visit project_commit_path(project, commit)
- fill_in "note_note", :with => "I commented this commit"
- click_button "Add Comment"
- end
-
- it "should conatin new note" do
- page.should have_content("I commented this commit")
- end
-
- it "should be displayed when i visit this commit again" do
- visit project_commit_path(project, commit)
- page.should have_content("I commented this commit")
- end
- end
-end
diff --git a/spec/requests/commits_spec.rb b/spec/requests/commits_spec.rb
deleted file mode 100644
index 00b69379848..00000000000
--- a/spec/requests/commits_spec.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-require 'spec_helper'
-
-describe "Commits" do
- let(:project) { Factory :project }
- let!(:commit) { project.commit }
- before do
- login_as :user
- project.add_access(@user, :read)
- end
-
- describe "GET /commits" do
- before do
- visit project_commits_path(project)
- end
-
- it "should have valid path" do
- current_path.should == project_commits_path(project)
- end
-
- it "should have project name" do
- page.should have_content(project.name)
- end
-
- it "should list commits" do
- page.should have_content(commit.message)
- page.should have_content(commit.id.to_s[0..5])
- end
-
- it "should render atom feed" do
- visit project_commits_path(project, :atom)
-
- page.response_headers['Content-Type'].should have_content("application/atom+xml")
- page.body.should have_selector("title", :text => "Recent commits to #{project.name}")
- page.body.should have_selector("author email", :text => commit.author_email)
- page.body.should have_selector("entry summary", :text => commit.message)
- end
-
- it "should render atom feed via private token" do
- logout
- visit project_commits_path(project, :atom, :private_token => @user.private_token)
-
- page.response_headers['Content-Type'].should have_content("application/atom+xml")
- page.body.should have_selector("title", :text => "Recent commits to #{project.name}")
- page.body.should have_selector("author email", :text => commit.author_email)
- page.body.should have_selector("entry summary", :text => commit.message)
- end
- end
-
- describe "GET /commits/:id" do
- before do
- visit project_commit_path(project, commit.id)
- end
-
- it "should have valid path" 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
deleted file mode 100644
index 29c79313f7e..00000000000
--- a/spec/requests/dashboard_issues_spec.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-require 'spec_helper'
-
-describe "User Issues Dashboard" do
- describe "GET /issues" do
- before do
-
- login_as :user
-
- @project1 = Factory :project,
- :path => "project1",
- :code => "TEST1"
-
- @project2 = Factory :project,
- :path => "project2",
- :code => "TEST2"
-
- @project1.add_access(@user, :read, :write)
- @project2.add_access(@user, :read, :write)
-
- @issue1 = Factory :issue,
- :author => @user,
- :assignee => @user,
- :project => @project1
-
- @issue2 = Factory :issue,
- :author => @user,
- :assignee => @user,
- :project => @project2
-
- visit dashboard_issues_path
- end
-
- subject { page }
-
- it { should have_content(@issue1.title[0..10]) }
- it { should have_content(@issue1.project.name) }
-
- it { should have_content(@issue2.title[0..10]) }
- it { should have_content(@issue2.project.name) }
-
- describe "atom feed", :js => false do
- it "should render atom feed via private token" do
- logout
- visit dashboard_issues_path(:atom, :private_token => @user.private_token)
-
- page.response_headers['Content-Type'].should have_content("application/atom+xml")
- page.body.should have_selector("title", :text => "#{@user.name} issues")
- page.body.should have_selector("author email", :text => @issue1.author_email)
- page.body.should have_selector("entry summary", :text => @issue1.title)
- page.body.should have_selector("author email", :text => @issue2.author_email)
- page.body.should have_selector("entry summary", :text => @issue2.title)
- end
- end
- end
-end
diff --git a/spec/requests/dashboard_merge_requests_spec.rb b/spec/requests/dashboard_merge_requests_spec.rb
deleted file mode 100644
index f345a858ac8..00000000000
--- a/spec/requests/dashboard_merge_requests_spec.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-require 'spec_helper'
-
-describe "User MergeRequests" do
- describe "GET /issues" do
- before do
-
- login_as :user
-
- @project1 = Factory :project,
- :path => "project1",
- :code => "TEST1"
-
- @project2 = Factory :project,
- :path => "project2",
- :code => "TEST2"
-
- @project1.add_access(@user, :read, :write)
- @project2.add_access(@user, :read, :write)
-
- @merge_request1 = Factory :merge_request,
- :author => @user,
- :assignee => @user,
- :project => @project1
-
- @merge_request2 = Factory :merge_request,
- :author => @user,
- :assignee => @user,
- :project => @project2
-
- visit dashboard_merge_requests_path
- end
-
- subject { page }
-
- it { should have_content(@merge_request1.title[0..10]) }
- it { should have_content(@merge_request1.project.name) }
- it { should have_content(@merge_request2.title[0..10]) }
- it { should have_content(@merge_request2.project.name) }
- end
-end
diff --git a/spec/requests/file_blame_spec.rb b/spec/requests/file_blame_spec.rb
deleted file mode 100644
index 511f340c1c8..00000000000
--- a/spec/requests/file_blame_spec.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-require 'spec_helper'
-
-describe "Blame file" do
- before { login_as :user }
-
- describe "GET /:projectname/:commit/blob/Gemfile" do
- before do
- @project = Factory :project
- @project.add_access(@user, :read)
-
- visit tree_project_ref_path(@project, @project.root_ref, :path => "Gemfile")
- click_link "blame"
- end
-
- it "should be correct path" do
- current_path.should == blame_file_project_ref_path(@project, @project.root_ref, :path => "Gemfile")
- end
-
- it "should contain file view" do
- page.should have_content("rubygems.org")
- page.should have_content("Dmitriy Zaporozhets")
- page.should have_content("bc3735004cb Moving to rails 3.2")
- end
- end
-end
diff --git a/spec/requests/gitlab_flavored_markdown_spec.rb b/spec/requests/gitlab_flavored_markdown_spec.rb
new file mode 100644
index 00000000000..1076e90c42b
--- /dev/null
+++ b/spec/requests/gitlab_flavored_markdown_spec.rb
@@ -0,0 +1,241 @@
+require 'spec_helper'
+
+describe "Gitlab Flavored Markdown" do
+ let(:project) { Factory :project }
+ let(:issue) { Factory :issue, project: project }
+ let(:merge_request) { Factory :merge_request, project: project }
+ let(:fred) do
+ u = Factory :user, name: "fred"
+ project.users << u
+ u
+ end
+
+ before do
+ # add test branch
+ @branch_name = "gfm-test"
+ r = project.repo
+ i = r.index
+ # add test file
+ @test_file = "gfm_test_file"
+ i.add(@test_file, "foo\nbar\n")
+ # add commit with gfm
+ i.commit("fix ##{issue.id}\n\nask @#{fred.name} for details", head: @branch_name)
+
+ # add test tag
+ @tag_name = "gfm-test-tag"
+ r.git.native(:tag, {}, @tag_name, commit.id)
+ end
+ after do
+ # delete test branch and tag
+ project.repo.git.native(:branch, {D: true}, @branch_name)
+ project.repo.git.native(:tag, {d: true}, @tag_name)
+ project.repo.gc_auto
+ end
+
+ let(:commit) { project.commits(@branch_name).first }
+
+ before do
+ login_as :user
+ project.add_access(@user, :read, :write)
+ end
+
+
+ describe "for commits" do
+ it "should render title in commits#index" do
+ visit project_commits_path(project, ref: @branch_name)
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render title in commits#show" do
+ visit project_commit_path(project, id: commit.id)
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render description in commits#show" do
+ visit project_commit_path(project, id: commit.id)
+
+ page.should have_link("@#{fred.name}")
+ end
+
+ it "should render title in refs#tree", js: true do
+ visit tree_project_ref_path(project, id: @branch_name)
+
+ within(".tree_commit") do
+ page.should have_link("##{issue.id}")
+ end
+ end
+
+ it "should render title in refs#blame" do
+ visit blame_file_project_ref_path(project, id: @branch_name, path: @test_file)
+
+ within(".blame_commit") do
+ page.should have_link("##{issue.id}")
+ end
+ end
+
+ it "should render title in repositories#branches" do
+ visit branches_project_repository_path(project)
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render title in repositories#tags" do
+ visit tags_project_repository_path(project)
+
+ page.should have_link("##{issue.id}")
+ end
+ end
+
+
+ describe "for issues" do
+ before do
+ @other_issue = Factory :issue,
+ author: @user,
+ assignee: @user,
+ project: project
+ @issue = Factory :issue,
+ author: @user,
+ assignee: @user,
+ project: project,
+ title: "fix ##{@other_issue.id}",
+ description: "ask @#{fred.name} for details"
+ end
+
+ it "should render subject in issues#index" do
+ visit project_issues_path(project)
+
+ page.should have_link("##{@other_issue.id}")
+ end
+
+ it "should render subject in issues#show" do
+ visit project_issue_path(project, @issue)
+
+ page.should have_link("##{@other_issue.id}")
+ end
+
+ it "should render details in issues#show" do
+ visit project_issue_path(project, @issue)
+
+ page.should have_link("@#{fred.name}")
+ end
+ end
+
+
+ describe "for merge requests" do
+ before do
+ @merge_request = Factory :merge_request,
+ project: project,
+ title: "fix ##{issue.id}"
+ end
+
+ it "should render title in merge_requests#index" do
+ visit project_merge_requests_path(project)
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render title in merge_requests#show" do
+ visit project_merge_request_path(project, @merge_request)
+
+ page.should have_link("##{issue.id}")
+ end
+ end
+
+
+ describe "for milestones" do
+ before do
+ @milestone = Factory :milestone,
+ project: project,
+ title: "fix ##{issue.id}",
+ description: "ask @#{fred.name} for details"
+ end
+
+ it "should render title in milestones#index" do
+ visit project_milestones_path(project)
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render title in milestones#show" do
+ visit project_milestone_path(project, @milestone)
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render description in milestones#show" do
+ visit project_milestone_path(project, @milestone)
+
+ page.should have_link("@#{fred.name}")
+ end
+ end
+
+
+ describe "for notes" do
+ it "should render in commits#show", js: true do
+ visit project_commit_path(project, id: commit.id)
+ fill_in "note_note", with: "see ##{issue.id}"
+ click_button "Add Comment"
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render in issue#show", js: true do
+ visit project_issue_path(project, issue)
+ fill_in "note_note", with: "see ##{issue.id}"
+ click_button "Add Comment"
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render in merge_request#show", js: true do
+ visit project_merge_request_path(project, merge_request)
+ fill_in "note_note", with: "see ##{issue.id}"
+ click_button "Add Comment"
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render in projects#wall", js: true do
+ visit wall_project_path(project)
+ fill_in "note_note", with: "see ##{issue.id}"
+ click_button "Add Comment"
+
+ page.should have_link("##{issue.id}")
+ end
+
+ it "should render in wikis#index", js: true do
+ visit project_wiki_path(project, :index)
+ fill_in "Title", with: 'Test title'
+ fill_in "Content", with: '[link test](test)'
+ click_on "Save"
+
+ fill_in "note_note", with: "see ##{issue.id}"
+ click_button "Add Comment"
+
+ page.should have_link("##{issue.id}")
+ end
+ end
+
+
+ describe "for wikis" do
+ before do
+ visit project_wiki_path(project, :index)
+ fill_in "Title", with: "Circumvent ##{issue.id}"
+ fill_in "Content", with: "# Other pages\n\n* [Foo](foo)\n* [Bar](bar)\n\nAlso look at ##{issue.id} :-)"
+ click_on "Save"
+ end
+
+ it "should NOT render title in wikis#show" do
+ within(".content h3") do # page title
+ page.should have_content("Circumvent ##{issue.id}")
+ page.should_not have_link("##{issue.id}")
+ end
+ end
+
+ it "should render content in wikis#show" do
+ page.should have_link("##{issue.id}")
+ end
+ end
+end
diff --git a/spec/requests/hooks_spec.rb b/spec/requests/hooks_spec.rb
index a508e5ea517..7cfe7cfe849 100644
--- a/spec/requests/hooks_spec.rb
+++ b/spec/requests/hooks_spec.rb
@@ -9,7 +9,7 @@ describe "Hooks" do
describe "GET index" do
it "should be available" do
- @hook = Factory :web_hook, :project => @project
+ @hook = Factory :project_hook, project: @project
visit project_hooks_path(@project)
page.should have_content "Hooks"
page.should have_content @hook.url
@@ -20,8 +20,8 @@ describe "Hooks" do
before do
@url = Faker::Internet.uri("http")
visit project_hooks_path(@project)
- fill_in "hook_url", :with => @url
- expect { click_button "Add Web Hook" }.to change(WebHook, :count).by(1)
+ fill_in "hook_url", with: @url
+ expect { click_button "Add Web Hook" }.to change(ProjectHook, :count).by(1)
end
it "should open new team member popup" do
@@ -32,7 +32,8 @@ describe "Hooks" do
describe "Test" do
before do
- @hook = Factory :web_hook, :project => @project
+ @hook = Factory :project_hook, project: @project
+ stub_request(:post, @hook.url)
visit project_hooks_path(@project)
click_link "Test Hook"
end
diff --git a/spec/requests/issues_notes_spec.rb b/spec/requests/issues_notes_spec.rb
deleted file mode 100644
index 538098e60bd..00000000000
--- a/spec/requests/issues_notes_spec.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-require 'spec_helper'
-
-describe "Issues" do
- let(:project) { Factory :project }
-
- before do
- login_as :user
- project.add_access(@user, :read, :write)
-
- @issue = Factory :issue,
- :author => @user,
- :assignee => @user,
- :project => project
- end
-
- describe "add new note", :js => true do
- before do
- visit project_issue_path(project, @issue)
- fill_in "note_note", :with => "I commented this issue"
- click_button "Add Comment"
- end
-
- it "should conatin new note" do
- page.should have_content("I commented this issue")
- end
- end
-end
diff --git a/spec/requests/issues_spec.rb b/spec/requests/issues_spec.rb
index 2c8650a8402..15ee5d174a0 100644
--- a/spec/requests/issues_spec.rb
+++ b/spec/requests/issues_spec.rb
@@ -11,167 +11,12 @@ describe "Issues" do
project.add_access(@user2, :read, :write)
end
- describe "GET /issues" do
+ describe "Edit issue", js: true do
before do
@issue = Factory :issue,
- :author => @user,
- :assignee => @user,
- :project => project
-
- visit project_issues_path(project)
- end
-
- subject { page }
-
- it { should have_content(@issue.title[0..20]) }
- it { should have_content(@issue.project.name) }
- it { should have_content(@issue.assignee.name) }
-
- it "should render atom feed" do
- visit project_issues_path(project, :atom)
-
- page.response_headers['Content-Type'].should have_content("application/atom+xml")
- page.body.should have_selector("title", :text => "#{project.name} issues")
- page.body.should have_selector("author email", :text => @issue.author_email)
- page.body.should have_selector("entry summary", :text => @issue.title)
- end
-
- it "should render atom feed via private token" do
- logout
- visit project_issues_path(project, :atom, :private_token => @user.private_token)
-
- page.response_headers['Content-Type'].should have_content("application/atom+xml")
- page.body.should have_selector("title", :text => "#{project.name} issues")
- page.body.should have_selector("author email", :text => @issue.author_email)
- page.body.should have_selector("entry summary", :text => @issue.title)
- end
-
- describe "statuses" do
- before do
- @closed_issue = Factory :issue,
- :author => @user,
- :assignee => @user,
- :project => project,
- :closed => true
- end
-
- it "should show only open" do
- should have_content(@issue.title[0..25])
- should have_no_content(@closed_issue.title)
- end
-
- it "should show only closed" do
- click_link "Closed"
- should have_no_content(@issue.title)
- should have_content(@closed_issue.title[0..25])
- end
-
- it "should show all" do
- click_link "All"
- should have_content(@issue.title[0..25])
- should have_content(@closed_issue.title[0..25])
- end
- end
- end
-
- describe "New issue", :js => true do
- before do
- visit project_issues_path(project)
- click_link "New Issue"
- end
-
- it "should open new issue form" do
- page.should have_content("New Issue")
- end
-
- describe "fill in" do
- describe 'assign to me' do
- before do
- fill_in "issue_title", :with => "bug 345"
- page.execute_script("$('#issue_assignee_id').show();")
- select @user.name, :from => "issue_assignee_id"
- end
-
- it { expect { click_button "Submit new issue" }.to change {Issue.count}.by(1) }
-
- it "should add new issue to table" do
- click_button "Submit new issue"
-
- page.should_not have_content("Add new issue")
- page.should have_content @user.name
- page.should have_content "bug 345"
- page.should have_content project.name
- end
-
- it "should call send mail" do
- Notify.should_not_receive(:new_issue_email)
- click_button "Submit new issue"
- end
- end
-
- describe 'assign to other' do
- before do
- fill_in "issue_title", :with => "bug 345"
- page.execute_script("$('#issue_assignee_id').show();")
- select @user2.name, :from => "issue_assignee_id"
- end
-
- it { expect { click_button "Submit new issue" }.to change {Issue.count}.by(1) }
-
- it "should add new issue to table" do
- click_button "Submit new issue"
-
- page.should_not have_content("Add new issue")
- page.should have_content @user2.name
- page.should have_content "bug 345"
- page.should have_content project.name
- end
-
- it "should call send mail" do
- Issue.observers.enable :issue_observer do
- Notify.should_receive(:new_issue_email).and_return(stub(:deliver => true))
- click_button "Submit new issue"
- end
- end
-
- it "should send valid email to user" do
- Issue.observers.enable :issue_observer do
- with_resque do
- click_button "Submit new issue"
- end
- issue = Issue.last
- email = ActionMailer::Base.deliveries.last
- email.subject.should have_content("New Issue was created")
- email.body.should have_content(issue.title)
- end
- end
-
- end
- end
- end
-
- describe "Show issue" do
- before do
- @issue = Factory :issue,
- :author => @user,
- :assignee => @user,
- :project => project
-
- visit project_issue_path(project, @issue)
- end
-
- it "should have valid show page for issue" do
- page.should have_content @issue.title
- page.should have_content @user.name
- end
- end
-
- describe "Edit issue", :js => true do
- before do
- @issue = Factory :issue,
- :author => @user,
- :assignee => @user,
- :project => project
+ author: @user,
+ assignee: @user,
+ project: project
visit project_issues_path(project)
click_link "Edit"
end
@@ -182,8 +27,8 @@ describe "Issues" do
describe "fill in" do
before do
- fill_in "issue_title", :with => "bug 345"
- fill_in "issue_description", :with => "bug description"
+ fill_in "issue_title", with: "bug 345"
+ fill_in "issue_description", with: "bug description"
end
it { expect { click_button "Save changes" }.to_not change {Issue.count} }
@@ -198,14 +43,14 @@ describe "Issues" do
end
end
- describe "Search issue", :js => true do
+ describe "Search issue", js: true do
before do
['foobar', 'foobar2', 'gitlab'].each do |title|
@issue = Factory :issue,
- :author => @user,
- :assignee => @user,
- :project => project,
- :title => title
+ author: @user,
+ assignee: @user,
+ project: project,
+ title: title
@issue.save
end
end
@@ -217,7 +62,7 @@ describe "Issues" do
visit project_issues_path(project)
click_link 'Closed'
- fill_in 'issue_search', :with => 'foobar'
+ fill_in 'issue_search', with: 'foobar'
page.should have_content 'foobar'
page.should_not have_content 'foobar2'
@@ -226,7 +71,7 @@ describe "Issues" do
it "should search for term and return the correct results" do
visit project_issues_path(project)
- fill_in 'issue_search', :with => 'foobar'
+ fill_in 'issue_search', with: 'foobar'
page.should have_content 'foobar'
page.should have_content 'foobar2'
@@ -235,8 +80,8 @@ describe "Issues" do
it "should return all results if term has been cleared" do
visit project_issues_path(project)
- fill_in "issue_search", :with => "foobar"
- # Because fill_in, :with => "" triggers nothing we need to trigger a keyup event
+ fill_in "issue_search", with: "foobar"
+ # Because fill_in, with: "" triggers nothing we need to trigger a keyup event
page.execute_script("$('.issue_search').val('').keyup();");
page.should have_content 'foobar'
@@ -244,4 +89,53 @@ describe "Issues" do
page.should have_content 'gitlab'
end
end
+
+ describe "Filter issue" do
+ before do
+ ['foobar', 'barbaz', 'gitlab'].each do |title|
+ @issue = Factory :issue,
+ author: @user,
+ assignee: @user,
+ project: project,
+ title: title
+ end
+
+ @issue = Issue.first
+ @issue.milestone = Factory(:milestone, project: project)
+ @issue.assignee = nil
+ @issue.save
+ end
+
+ it "should allow filtering by issues with no specified milestone" do
+ visit project_issues_path(project, milestone_id: '0')
+
+ page.should_not have_content 'foobar'
+ page.should have_content 'barbaz'
+ page.should have_content 'gitlab'
+ end
+
+ it "should allow filtering by a specified milestone" do
+ visit project_issues_path(project, milestone_id: @issue.milestone.id)
+
+ page.should have_content 'foobar'
+ page.should_not have_content 'barbaz'
+ page.should_not have_content 'gitlab'
+ end
+
+ it "should allow filtering by issues with no specified assignee" do
+ visit project_issues_path(project, assignee_id: '0')
+
+ page.should have_content 'foobar'
+ page.should_not have_content 'barbaz'
+ page.should_not have_content 'gitlab'
+ end
+
+ it "should allow filtering by a specified assignee" do
+ visit project_issues_path(project, assignee_id: @user.id)
+
+ page.should_not have_content 'foobar'
+ page.should have_content 'barbaz'
+ page.should have_content 'gitlab'
+ end
+ end
end
diff --git a/spec/requests/keys_spec.rb b/spec/requests/keys_spec.rb
deleted file mode 100644
index 2bc7c75ba0d..00000000000
--- a/spec/requests/keys_spec.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-require 'spec_helper'
-
-describe "Issues" do
- before do
- login_as :user
- end
-
- describe "GET /keys" do
- before do
- @key = Factory :key, :user => @user
- visit keys_path
- end
-
- subject { page }
-
- it { should have_content(@key.title) }
-
- describe "Destroy" do
- before { visit key_path(@key) }
-
- it "should remove entry" do
- expect {
- click_link "Remove"
- }.to change { @user.keys.count }.by(-1)
- end
- end
- end
-
- 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("New key")
- end
-
- describe "fill in" do
- before do
- fill_in "key_title", :with => "laptop"
- fill_in "key_key", :with => "publickey234="
- end
-
- it { expect { click_button "Save" }.to change {Key.count}.by(1) }
-
- it "should add new key to table" do
- click_button "Save"
-
- page.should_not have_content("New key")
- page.should have_content "laptop"
- end
- end
- end
-
- describe "Show page" do
- before do
- @key = Factory :key, :user => @user
- visit key_path(@key)
- end
-
- it { page.should have_content @key.title }
- it { page.should have_content @key.key[0..10] }
- end
-end
diff --git a/spec/requests/last_push_widget_spec.rb b/spec/requests/last_push_widget_spec.rb
deleted file mode 100644
index 0baa20c6e94..00000000000
--- a/spec/requests/last_push_widget_spec.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-require 'spec_helper'
-
-describe "Last Push widget" do
- before { login_as :user }
-
- before do
- @project = Factory :project, :owner => @user
- @project.add_access(@user, :read)
- create_push_event
- visit dashboard_path
- end
-
- it "should display last push widget with link to merge request page" do
- page.should have_content "Your pushed to branch new_design"
- page.should have_link "Create Merge Request"
- end
-
- describe "click create MR" do
- before { click_link "Create Merge Request" }
-
- it { current_path.should == new_project_merge_request_path(@project) }
- it { find("#merge_request_source_branch").value.should == "new_design" }
- it { find("#merge_request_target_branch").value.should == "master" }
- it { find("#merge_request_title").value.should == "New Design" }
- end
-
-
- def create_push_event
- data = {
- :before => "0000000000000000000000000000000000000000",
- :after => "0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e",
- :ref => "refs/heads/new_design",
- :user_id => @user.id,
- :user_name => @user.name,
- :repository => {
- :name => @project.name,
- :url => "localhost/rubinius",
- :description => "",
- :homepage => "localhost/rubinius",
- :private => true
- }
- }
-
- @event = Event.create(
- :project => @project,
- :action => Event::Pushed,
- :data => data,
- :author_id => @user.id
- )
- end
-end
-
diff --git a/spec/requests/merge_requests_spec.rb b/spec/requests/merge_requests_spec.rb
deleted file mode 100644
index f8b8725f56b..00000000000
--- a/spec/requests/merge_requests_spec.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-require 'spec_helper'
-
-describe "MergeRequests" do
- let(:project) { Factory :project }
-
- before do
- login_as :user
- project.add_access(@user, :read, :write)
- @merge_request = Factory :merge_request,
- :author => @user,
- :assignee => @user,
- :project => project
- end
-
- describe "GET /merge_requests" do
- before do
- visit project_merge_requests_path(project)
- end
-
- subject { page }
-
- it { should have_content(@merge_request.title[0..10]) }
- it { should have_content(@merge_request.target_branch) }
- it { should have_content(@merge_request.source_branch) }
- it { should have_content(@merge_request.assignee.name) }
- end
-
- describe "GET /merge_request/:id" do
- before do
- visit project_merge_request_path(project, @merge_request)
- end
-
- subject { page }
-
- it { should have_content(@merge_request.title[0..10]) }
- it { should have_content(@merge_request.target_branch) }
- it { should have_content(@merge_request.source_branch) }
- it { should have_content(@merge_request.assignee.name) }
-
- describe "Close merge request" do
- before { click_link "Close" }
-
- it { should have_content(@merge_request.title[0..10]) }
- it "Show page should inform user that merge request closed" do
- page.should have_content "Closed"
- end
- end
- end
-
- describe "GET /merge_requests/new" do
- before do
- visit new_project_merge_request_path(project)
- fill_in "merge_request_title", :with => "Merge Request Title"
- select "master", :from => "merge_request_source_branch"
- select "stable", :from => "merge_request_target_branch"
- select @user.name, :from => "merge_request_assignee_id"
- click_button "Save"
- end
-
- it { current_path.should == project_merge_request_path(project, project.merge_requests.last) }
-
- it "should create merge request" do
- page.should have_content "Close"
- page.should have_content @user.name
- end
- end
-end
diff --git a/spec/requests/milestones_spec.rb b/spec/requests/milestones_spec.rb
deleted file mode 100644
index f1d5023e6b4..00000000000
--- a/spec/requests/milestones_spec.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-require 'spec_helper'
-
-describe "Milestones" do
- let(:project) { Factory :project }
-
- before do
- login_as :user
- project.add_access(@user, :admin)
-
- @milestone = Factory :milestone, :project => project
- @issue = Factory :issue, :project => project
-
- @milestone.issues << @issue
- end
-
- describe "GET /milestones" do
- before do
- visit project_milestones_path(project)
- end
-
- subject { page }
-
- it { should have_content(@milestone.title[0..10]) }
- it { should have_content(@milestone.expires_at) }
- it { should have_content("Browse Issues") }
- end
-
- describe "GET /milestone/:id" do
- before do
- visit project_milestone_path(project, @milestone)
- end
-
- subject { page }
-
- it { should have_content(@milestone.title[0..10]) }
- it { should have_content(@milestone.expires_at) }
- it { should have_content("Browse Issues") }
- end
-
- describe "GET /milestones/new" do
- before do
- visit new_project_milestone_path(project)
- fill_in "milestone_title", :with => "v2.3"
- click_button "Create milestone"
- end
-
- it { current_path.should == project_milestone_path(project, project.milestones.last) }
- it { page.should have_content(project.milestones.last.title[0..10]) }
- it { page.should have_content(project.milestones.last.expires_at) }
- end
-end
diff --git a/spec/requests/profile_spec.rb b/spec/requests/profile_spec.rb
deleted file mode 100644
index 6f9af6085ab..00000000000
--- a/spec/requests/profile_spec.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-require 'spec_helper'
-
-describe "Profile" do
- before do
- login_as :user
- end
-
- describe "Show profile" do
- before do
- visit profile_path
- end
-
- it { page.should have_content(@user.name) }
- end
-
- describe "Profile update" do
- before do
- visit profile_path
- fill_in "user_skype", :with => "testskype"
- fill_in "user_linkedin", :with => "testlinkedin"
- fill_in "user_twitter", :with => "testtwitter"
- click_button "Save"
- @user.reload
- end
-
- it { @user.skype.should == 'testskype' }
- it { @user.linkedin.should == 'testlinkedin' }
- it { @user.twitter.should == 'testtwitter' }
- end
-
- describe "Reset private token" do
- before do
- visit profile_token_path
- end
-
- it "should reset private token" do
- user_first_token = @user.private_token
- click_button "Reset"
- @user.reload
- @user.private_token.should_not == user_first_token
- end
- end
-
- describe "Password update" do
- before do
- visit profile_password_path
- end
-
- it { page.should have_content("Password") }
- it { page.should have_content("Password confirmation") }
-
- describe "change password" do
- before do
- @old_pwd = @user.encrypted_password
- fill_in "user_password", :with => "777777"
- fill_in "user_password_confirmation", :with => "777777"
- click_button "Save"
- @user.reload
- end
-
- it "should redirect to signin page" do
- current_path.should == new_user_session_path
- end
-
- it "should change password" do
- @user.encrypted_password.should_not == @old_pwd
- end
-
- describe "login with new password" do
- before do
- fill_in "user_email", :with => @user.email
- fill_in "user_password", :with => "777777"
- click_button "Sign in"
- end
-
- it "should login user" do
- current_path.should == root_path
- end
- end
- end
- end
-end
diff --git a/spec/requests/projects_deploy_keys_spec.rb b/spec/requests/projects_deploy_keys_spec.rb
index 580e55229e1..0fea7b46ce2 100644
--- a/spec/requests/projects_deploy_keys_spec.rb
+++ b/spec/requests/projects_deploy_keys_spec.rb
@@ -10,7 +10,7 @@ describe "Projects", "DeployKeys" do
describe "GET /keys" do
before do
- @key = Factory :key, :project => project
+ @key = Factory :key, project: project
visit project_deploy_keys_path(project)
end
@@ -41,8 +41,8 @@ describe "Projects", "DeployKeys" do
describe "fill in" do
before do
- fill_in "key_title", :with => "laptop"
- fill_in "key_key", :with => "publickey234="
+ fill_in "key_title", with: "laptop"
+ fill_in "key_key", with: "publickey234="
end
it { expect { click_button "Save" }.to change {Key.count}.by(1) }
@@ -57,7 +57,7 @@ describe "Projects", "DeployKeys" do
describe "Show page" do
before do
- @key = Factory :key, :project => project
+ @key = Factory :key, project: project
visit project_deploy_key_path(project, @key)
end
diff --git a/spec/requests/projects_security_spec.rb b/spec/requests/projects_security_spec.rb
deleted file mode 100644
index df4d11221c3..00000000000
--- a/spec/requests/projects_security_spec.rb
+++ /dev/null
@@ -1,187 +0,0 @@
-require 'spec_helper'
-
-describe "Projects Security" do
- describe "GET /" do
- it { root_path.should be_allowed_for :admin }
- it { root_path.should be_allowed_for :user }
- it { root_path.should be_denied_for :visitor }
- end
-
- describe "GET /projects/new" do
- it { new_project_path.should be_allowed_for :admin }
- it { new_project_path.should be_allowed_for :user }
- it { new_project_path.should be_denied_for :visitor }
- end
-
- describe "Project" do
- before do
- @project = Factory :project
- @u1 = Factory :user
- @u2 = Factory :user
- @u3 = Factory :user
- # full access
- @project.users_projects.create(:user => @u1, :project_access => UsersProject::MASTER)
- # readonly
- @project.users_projects.create(:user => @u3, :project_access => UsersProject::REPORTER)
- end
-
- describe "GET /project_code" do
- it { project_path(@project).should be_allowed_for @u1 }
- it { project_path(@project).should be_allowed_for @u3 }
- it { project_path(@project).should be_denied_for :admin }
- it { project_path(@project).should be_denied_for @u2 }
- it { project_path(@project).should be_denied_for :user }
- it { project_path(@project).should be_denied_for :visitor }
- end
-
- describe "GET /project_code/master/tree" do
- it { tree_project_ref_path(@project, @project.root_ref).should be_allowed_for @u1 }
- it { tree_project_ref_path(@project, @project.root_ref).should be_allowed_for @u3 }
- it { tree_project_ref_path(@project, @project.root_ref).should be_denied_for :admin }
- it { tree_project_ref_path(@project, @project.root_ref).should be_denied_for @u2 }
- it { tree_project_ref_path(@project, @project.root_ref).should be_denied_for :user }
- it { tree_project_ref_path(@project, @project.root_ref).should be_denied_for :visitor }
- end
-
- describe "GET /project_code/commits" do
- it { project_commits_path(@project).should be_allowed_for @u1 }
- it { project_commits_path(@project).should be_allowed_for @u3 }
- it { project_commits_path(@project).should be_denied_for :admin }
- it { project_commits_path(@project).should be_denied_for @u2 }
- it { project_commits_path(@project).should be_denied_for :user }
- it { project_commits_path(@project).should be_denied_for :visitor }
- end
-
- describe "GET /project_code/commit" do
- it { project_commit_path(@project, @project.commit.id).should be_allowed_for @u1 }
- it { project_commit_path(@project, @project.commit.id).should be_allowed_for @u3 }
- it { project_commit_path(@project, @project.commit.id).should be_denied_for :admin }
- it { project_commit_path(@project, @project.commit.id).should be_denied_for @u2 }
- it { project_commit_path(@project, @project.commit.id).should be_denied_for :user }
- it { project_commit_path(@project, @project.commit.id).should be_denied_for :visitor }
- end
-
- describe "GET /project_code/team" do
- it { team_project_path(@project).should be_allowed_for @u1 }
- it { team_project_path(@project).should be_allowed_for @u3 }
- it { team_project_path(@project).should be_denied_for :admin }
- it { team_project_path(@project).should be_denied_for @u2 }
- it { team_project_path(@project).should be_denied_for :user }
- it { team_project_path(@project).should be_denied_for :visitor }
- end
-
- describe "GET /project_code/wall" do
- it { wall_project_path(@project).should be_allowed_for @u1 }
- it { wall_project_path(@project).should be_allowed_for @u3 }
- it { wall_project_path(@project).should be_denied_for :admin }
- it { wall_project_path(@project).should be_denied_for @u2 }
- it { wall_project_path(@project).should be_denied_for :user }
- it { wall_project_path(@project).should be_denied_for :visitor }
- end
-
- describe "GET /project_code/blob" do
- before do
- @commit = @project.commit
- @path = @commit.tree.contents.select { |i| i.is_a?(Grit::Blob)}.first.name
- @blob_path = blob_project_ref_path(@project, @commit.id, :path => @path)
- end
-
- it { @blob_path.should be_allowed_for @u1 }
- it { @blob_path.should be_allowed_for @u3 }
- it { @blob_path.should be_denied_for :admin }
- it { @blob_path.should be_denied_for @u2 }
- it { @blob_path.should be_denied_for :user }
- it { @blob_path.should be_denied_for :visitor }
- end
-
- describe "GET /project_code/edit" do
- it { edit_project_path(@project).should be_allowed_for @u1 }
- it { edit_project_path(@project).should be_denied_for @u3 }
- it { edit_project_path(@project).should be_denied_for :admin }
- it { edit_project_path(@project).should be_denied_for @u2 }
- it { edit_project_path(@project).should be_denied_for :user }
- it { edit_project_path(@project).should be_denied_for :visitor }
- end
-
- describe "GET /project_code/deploy_keys" do
- it { project_deploy_keys_path(@project).should be_allowed_for @u1 }
- it { project_deploy_keys_path(@project).should be_denied_for @u3 }
- it { project_deploy_keys_path(@project).should be_denied_for :admin }
- it { project_deploy_keys_path(@project).should be_denied_for @u2 }
- it { project_deploy_keys_path(@project).should be_denied_for :user }
- it { project_deploy_keys_path(@project).should be_denied_for :visitor }
- end
-
- describe "GET /project_code/issues" do
- it { project_issues_path(@project).should be_allowed_for @u1 }
- it { project_issues_path(@project).should be_allowed_for @u3 }
- it { project_issues_path(@project).should be_denied_for :admin }
- it { project_issues_path(@project).should be_denied_for @u2 }
- it { project_issues_path(@project).should be_denied_for :user }
- it { project_issues_path(@project).should be_denied_for :visitor }
- end
-
- describe "GET /project_code/snippets" do
- it { project_snippets_path(@project).should be_allowed_for @u1 }
- it { project_snippets_path(@project).should be_allowed_for @u3 }
- it { project_snippets_path(@project).should be_denied_for :admin }
- it { project_snippets_path(@project).should be_denied_for @u2 }
- it { project_snippets_path(@project).should be_denied_for :user }
- it { project_snippets_path(@project).should be_denied_for :visitor }
- end
-
- describe "GET /project_code/merge_requests" do
- it { project_merge_requests_path(@project).should be_allowed_for @u1 }
- it { project_merge_requests_path(@project).should be_allowed_for @u3 }
- it { project_merge_requests_path(@project).should be_denied_for :admin }
- it { project_merge_requests_path(@project).should be_denied_for @u2 }
- it { project_merge_requests_path(@project).should be_denied_for :user }
- it { project_merge_requests_path(@project).should be_denied_for :visitor }
- end
-
- describe "GET /project_code/repository" do
- it { project_repository_path(@project).should be_allowed_for @u1 }
- it { project_repository_path(@project).should be_allowed_for @u3 }
- it { project_repository_path(@project).should be_denied_for :admin }
- it { project_repository_path(@project).should be_denied_for @u2 }
- it { project_repository_path(@project).should be_denied_for :user }
- it { project_repository_path(@project).should be_denied_for :visitor }
- end
-
- describe "GET /project_code/repository/branches" do
- it { branches_project_repository_path(@project).should be_allowed_for @u1 }
- it { branches_project_repository_path(@project).should be_allowed_for @u3 }
- it { branches_project_repository_path(@project).should be_denied_for :admin }
- it { branches_project_repository_path(@project).should be_denied_for @u2 }
- it { branches_project_repository_path(@project).should be_denied_for :user }
- it { branches_project_repository_path(@project).should be_denied_for :visitor }
- end
-
- describe "GET /project_code/repository/tags" do
- it { tags_project_repository_path(@project).should be_allowed_for @u1 }
- it { tags_project_repository_path(@project).should be_allowed_for @u3 }
- it { tags_project_repository_path(@project).should be_denied_for :admin }
- it { tags_project_repository_path(@project).should be_denied_for @u2 }
- it { tags_project_repository_path(@project).should be_denied_for :user }
- it { tags_project_repository_path(@project).should be_denied_for :visitor }
- end
-
- describe "GET /project_code/hooks" do
- it { project_hooks_path(@project).should be_allowed_for @u1 }
- it { project_hooks_path(@project).should be_allowed_for @u3 }
- it { project_hooks_path(@project).should be_denied_for :admin }
- it { project_hooks_path(@project).should be_denied_for @u2 }
- it { project_hooks_path(@project).should be_denied_for :user }
- it { project_hooks_path(@project).should be_denied_for :visitor }
- end
-
- describe "GET /project_code/files" do
- it { files_project_path(@project).should be_allowed_for @u1 }
- it { files_project_path(@project).should be_allowed_for @u3 }
- it { files_project_path(@project).should be_denied_for :admin }
- it { files_project_path(@project).should be_denied_for @u2 }
- it { files_project_path(@project).should be_denied_for :user }
- it { files_project_path(@project).should be_denied_for :visitor }
- end
- end
-end
diff --git a/spec/requests/projects_spec.rb b/spec/requests/projects_spec.rb
index c9c348469cc..63f8a696754 100644
--- a/spec/requests/projects_spec.rb
+++ b/spec/requests/projects_spec.rb
@@ -3,50 +3,9 @@ require 'spec_helper'
describe "Projects" do
before { login_as :user }
- describe "GET /projects/new" do
- before do
- visit root_path
- click_link "New Project"
- end
-
- it "should be correct path" do
- current_path.should == new_project_path
- end
-
- it "should have labels for new project" do
- page.should have_content("Project name is")
- end
- end
-
- describe "POST /projects" do
- before do
- visit new_project_path
- fill_in 'project_name', :with => 'NewProject'
- fill_in 'project_code', :with => 'NPR'
- fill_in 'project_path', :with => 'newproject'
- expect { click_button "Create project" }.to change { Project.count }.by(1)
- @project = Project.last
- end
-
- it "should be correct path" do
- current_path.should == project_path(@project)
- end
-
- it "should show project" do
- page.should have_content(@project.name)
- page.should have_content(@project.path)
- page.should have_content(@project.description)
- end
-
- it "should init repo instructions" do
- page.should have_content("git remote")
- page.should have_content(@project.url_to_repo)
- end
- end
-
describe "GET /projects/show" do
before do
- @project = Factory :project, :owner => @user
+ @project = Factory :project, owner: @user
@project.add_access(@user, :read)
visit project_path(@project)
@@ -57,42 +16,6 @@ describe "Projects" do
end
end
- describe "GET /projects/graph" do
- before do
- @project = Factory :project
- @project.add_access(@user, :read)
-
- visit graph_project_path(@project)
- end
-
- it "should be correct path" do
- current_path.should == graph_project_path(@project)
- end
-
- it "should have as as team member" do
- page.should have_content("master")
- end
- end
-
- describe "GET /projects/team" do
- before do
- @project = Factory :project
- @project.add_access(@user, :read)
-
- visit team_project_path(@project,
- :path => ValidCommit::BLOB_FILE_PATH,
- :commit_id => ValidCommit::ID)
- end
-
- it "should be correct path" do
- current_path.should == team_project_path(@project)
- end
-
- it "should have as as team member" do
- page.should have_content(@user.name)
- end
- end
-
describe "GET /projects/:id/edit" do
before do
@project = Factory :project
@@ -114,13 +37,13 @@ describe "Projects" do
describe "PUT /projects/:id" do
before do
- @project = Factory :project, :owner => @user
+ @project = Factory :project, owner: @user
@project.add_access(@user, :admin, :read)
visit edit_project_path(@project)
- fill_in 'project_name', :with => 'Awesome'
- fill_in 'project_code', :with => 'gitlabhq'
+ fill_in 'project_name', with: 'Awesome'
+ fill_in 'project_code', with: 'gitlabhq'
click_button "Save"
@project = @project.reload
end
diff --git a/spec/requests/projects_tree_spec.rb b/spec/requests/projects_tree_spec.rb
deleted file mode 100644
index acc4f0b9674..00000000000
--- a/spec/requests/projects_tree_spec.rb
+++ /dev/null
@@ -1,90 +0,0 @@
-require 'spec_helper'
-
-describe "Projects" do
- before { login_as :user }
-
- describe "GET /projects/tree" do
- describe "head" do
- before do
- @project = Factory :project
- @project.add_access(@user, :read)
-
- visit tree_project_ref_path(@project, @project.root_ref)
- end
-
- it "should be correct path" do
- current_path.should == tree_project_ref_path(@project, @project.root_ref)
- end
-
- it_behaves_like :tree_view
- end
-
- describe ValidCommit::ID do
- before do
- @project = Factory :project
- @project.add_access(@user, :read)
-
- visit tree_project_ref_path(@project, ValidCommit::ID)
- end
-
- it "should be correct path" do
- current_path.should == tree_project_ref_path(@project, ValidCommit::ID)
- end
-
- it_behaves_like :tree_view
- it_behaves_like :project_side_pane
- end
-
- describe "branch passed" do
- before do
- @project = Factory :project
- @project.add_access(@user, :read)
-
- visit tree_project_ref_path(@project, @project.root_ref)
- end
-
- it "should be correct path" do
- current_path.should == tree_project_ref_path(@project, @project.root_ref)
- end
-
- it_behaves_like :tree_view
- it_behaves_like :project_side_pane
- end
-
- # TREE FILE PREVIEW
- describe "file preview" do
- before do
- @project = Factory :project
- @project.add_access(@user, :read)
-
- visit tree_project_ref_path(@project, @project.root_ref, :path => "Gemfile")
- end
-
- it "should be correct path" do
- current_path.should == tree_project_ref_path(@project, @project.root_ref)
- end
-
- it "should contain file view" do
- page.should have_content("rubygems.org")
- end
- end
- end
-
- # RAW FILE
- describe "GET /projects/blob" do
- before do
- @project = Factory :project
- @project.add_access(@user, :read)
-
- visit blob_project_ref_path(@project, ValidCommit::ID, :path => ValidCommit::BLOB_FILE_PATH)
- end
-
- it "should be correct path" do
- current_path.should == blob_project_ref_path(@project, ValidCommit::ID)
- end
-
- it "raw file response" do
- page.source.should == ValidCommit::BLOB_FILE
- end
- end
-end
diff --git a/spec/requests/projects_wall_spec.rb b/spec/requests/projects_wall_spec.rb
deleted file mode 100644
index b2708fd1a57..00000000000
--- a/spec/requests/projects_wall_spec.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-require 'spec_helper'
-
-describe "Projects", "Wall" do
- let(:project) { Factory :project }
-
- before do
- login_as :user
- project.add_access(@user, :read, :write)
- end
-
- describe "View notes on wall", :js => true do
- before do
- Factory :note, :project => project, :note => "Project specs", :author => @user
- visit wall_project_path(project)
- end
-
- it { page.should have_content("Project specs") }
- it { page.should have_content(@user.name) }
- it { page.should have_content("less than a minute ago") }
- end
-
- describe "add new note", :js => true do
- before do
- visit wall_project_path(project)
- fill_in "note_note", :with => "my post on wall"
- click_button "Add Comment"
- end
-
- it "should conatin new note" do
- page.should have_content("my post on wall")
- end
- end
-end
diff --git a/spec/requests/repositories_spec.rb b/spec/requests/repositories_spec.rb
deleted file mode 100644
index 1bf4c8d24b7..00000000000
--- a/spec/requests/repositories_spec.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require 'spec_helper'
-
-describe "Repository" do
-
- before do
- @user = Factory :user
- @project = Factory :project
- @project.add_access(@user, :read, :write)
- login_with @user
- end
-
- describe "GET /:project_name/repository" do
- before do
- visit project_repository_path(@project)
- end
-
- it "should be on projects page" do
- current_path.should == project_repository_path(@project)
- end
-
- it "should have link to last commit for activities tab" do
- page.should have_content(@project.commit.safe_message[0..20])
- end
- end
-
- describe "GET /:project_name/repository/branches" do
- before do
- visit branches_project_repository_path(@project)
- end
-
- it "should have link to repo activities" do
- page.should have_content("Branches")
- page.should have_content("master")
- end
- end
-
- # TODO: Add new repo to seeds with tags list
- describe "GET /:project_name/repository/tags" do
- before do
- visit tags_project_repository_path(@project)
- end
-
- it "should have link to repo activities" do
- page.should have_content("Tags")
- page.should have_content("v1.2.1")
- end
- end
-end
-
diff --git a/spec/requests/search_spec.rb b/spec/requests/search_spec.rb
index 377bc215a04..537c4d0c64c 100644
--- a/spec/requests/search_spec.rb
+++ b/spec/requests/search_spec.rb
@@ -6,7 +6,7 @@ describe "Search" do
@project = Factory :project
@project.add_access(@user, :read)
visit search_path
- fill_in "search", :with => @project.name[0..3]
+ fill_in "search", with: @project.name[0..3]
click_button "Search"
end
diff --git a/spec/requests/security/profile_access_spec.rb b/spec/requests/security/profile_access_spec.rb
new file mode 100644
index 00000000000..9f6fe6a2b50
--- /dev/null
+++ b/spec/requests/security/profile_access_spec.rb
@@ -0,0 +1,40 @@
+require 'spec_helper'
+
+describe "Users Security" do
+ describe "Project" do
+ before do
+ @u1 = Factory :user
+ end
+
+ describe "GET /login" do
+ it { new_user_session_path.should_not be_404_for :visitor }
+ end
+
+ describe "GET /keys" do
+ subject { keys_path }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /profile" do
+ subject { profile_path }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /profile/password" do
+ subject { profile_password_path }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for :admin }
+ it { should be_allowed_for :user }
+ it { should be_denied_for :visitor }
+ end
+ end
+end
diff --git a/spec/requests/security/project_access_spec.rb b/spec/requests/security/project_access_spec.rb
new file mode 100644
index 00000000000..0cdf43bf84e
--- /dev/null
+++ b/spec/requests/security/project_access_spec.rb
@@ -0,0 +1,219 @@
+require 'spec_helper'
+
+describe "Application access" do
+ describe "GET /" do
+ it { root_path.should be_allowed_for :admin }
+ it { root_path.should be_allowed_for :user }
+ it { root_path.should be_denied_for :visitor }
+ end
+
+ describe "GET /projects/new" do
+ it { new_project_path.should be_allowed_for :admin }
+ it { new_project_path.should be_allowed_for :user }
+ it { new_project_path.should be_denied_for :visitor }
+ end
+
+ describe "Project" do
+ before do
+ @project = Factory :project
+ @u1 = Factory :user
+ @u2 = Factory :user
+ @u3 = Factory :user
+ # full access
+ @project.users_projects.create(user: @u1, project_access: UsersProject::MASTER)
+ # readonly
+ @project.users_projects.create(user: @u3, project_access: UsersProject::REPORTER)
+ end
+
+ describe "GET /project_code" do
+ subject { project_path(@project) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/master/tree" do
+ subject { tree_project_ref_path(@project, @project.root_ref) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/commits" do
+ subject { project_commits_path(@project) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/commit" do
+ subject { project_commit_path(@project, @project.commit.id) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/team" do
+ subject { team_project_path(@project) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/wall" do
+ subject { wall_project_path(@project) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/blob" do
+ before do
+ commit = @project.commit
+ path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob)}.first.name
+ @blob_path = blob_project_ref_path(@project, commit.id, path: path)
+ end
+
+ it { @blob_path.should be_allowed_for @u1 }
+ it { @blob_path.should be_allowed_for @u3 }
+ it { @blob_path.should be_denied_for :admin }
+ it { @blob_path.should be_denied_for @u2 }
+ it { @blob_path.should be_denied_for :user }
+ it { @blob_path.should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/edit" do
+ subject { edit_project_path(@project) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_denied_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/deploy_keys" do
+ subject { project_deploy_keys_path(@project) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_denied_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/issues" do
+ subject { project_issues_path(@project) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/snippets" do
+ subject { project_snippets_path(@project) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/merge_requests" do
+ subject { project_merge_requests_path(@project) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/repository" do
+ subject { project_repository_path(@project) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/repository/branches" do
+ subject { branches_project_repository_path(@project) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/repository/tags" do
+ subject { tags_project_repository_path(@project) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/hooks" do
+ subject { project_hooks_path(@project) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/files" do
+ subject { files_project_path(@project) }
+
+ it { should be_allowed_for @u1 }
+ it { should be_allowed_for @u3 }
+ it { should be_denied_for :admin }
+ it { should be_denied_for @u2 }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+ end
+end
diff --git a/spec/requests/snippets_spec.rb b/spec/requests/snippets_spec.rb
index 9b9bb0e96c5..6b993660507 100644
--- a/spec/requests/snippets_spec.rb
+++ b/spec/requests/snippets_spec.rb
@@ -11,8 +11,8 @@ describe "Snippets" do
describe "GET /snippets" do
before do
@snippet = Factory :snippet,
- :author => @user,
- :project => project
+ author: @user,
+ project: project
visit project_snippets_path(project)
end
@@ -50,9 +50,9 @@ describe "Snippets" do
describe "fill in" do
before do
- fill_in "snippet_title", :with => "login function"
- fill_in "snippet_file_name", :with => "test.rb"
- fill_in "snippet_content", :with => "def login; end"
+ fill_in "snippet_title", with: "login function"
+ fill_in "snippet_file_name", with: "test.rb"
+ fill_in "snippet_content", with: "def login; end"
end
it { expect { click_button "Save" }.to change {Snippet.count}.by(1) }
@@ -69,8 +69,8 @@ describe "Snippets" do
describe "Edit snippet" do
before do
@snippet = Factory :snippet,
- :author => @user,
- :project => project
+ author: @user,
+ project: project
visit project_snippet_path(project, @snippet)
click_link "Edit"
end
@@ -81,9 +81,9 @@ describe "Snippets" do
describe "fill in" do
before do
- fill_in "snippet_title", :with => "login function"
- fill_in "snippet_file_name", :with => "test.rb"
- fill_in "snippet_content", :with => "def login; end"
+ fill_in "snippet_title", with: "login function"
+ fill_in "snippet_file_name", with: "test.rb"
+ fill_in "snippet_content", with: "def login; end"
end
it { expect { click_button "Save" }.to_not change {Snippet.count} }
diff --git a/spec/requests/team_members_spec.rb b/spec/requests/team_members_spec.rb
deleted file mode 100644
index 34e34f59bdb..00000000000
--- a/spec/requests/team_members_spec.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-require 'spec_helper'
-
-describe "TeamMembers" do
- before do
- login_as :user
- @project = Factory :project
- @project.add_access(@user, :read, :admin)
- end
-
- describe "Update profile", :js => true do
- it "should update user role" do
- @project.master_access_for?(@user).should be_true
- visit team_project_path(@project)
- select "Developer", :from => "team_member_project_access"
- @project.master_access_for?(@user).should be_false
- @project.dev_access_for?(@user).should be_true
- end
- end
-
- describe "View profile" do
- it "should be available" do
- visit(team_project_path(@project))
- click_link(@user.name)
- page.should have_content @user.skype
- page.should_not have_content 'Twitter'
- end
- end
-
- describe "New Team member" do
- before do
- @user_1 = Factory :user
- visit team_project_path(@project)
- click_link "New Team Member"
- end
-
- it "should open new team member popup" do
- page.should have_content("New Team member")
- end
-
- describe "fill in" do
- before do
- within "#new_team_member" do
- select @user_1.name, :from => "team_member_user_id"
- select "Reporter", :from => "team_member_project_access"
- end
- end
-
- it { expect { click_button "Save";sleep(1) }.to change {UsersProject.count}.by(1) }
-
- it "should add new member to table" do
- click_button "Save"
- @member = UsersProject.last
-
- page.should have_content @user_1.name
-
- @member.reload
- @member.project_access.should == UsersProject::REPORTER
- end
- end
- end
-
- describe "Cancel membership" do
- it "should cancel membership" do
- 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/user_security_spec.rb b/spec/requests/user_security_spec.rb
deleted file mode 100644
index b75a1779a8a..00000000000
--- a/spec/requests/user_security_spec.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-require 'spec_helper'
-
-describe "Users Security" do
- describe "Project" do
- before do
- @u1 = Factory :user
- end
-
- describe "GET /login" do
- #it { new_user_session_path.should be_denied_for @u1 }
- #it { new_user_session_path.should be_denied_for :admin }
- #it { new_user_session_path.should be_denied_for :user }
- it { new_user_session_path.should_not be_404_for :visitor }
- end
-
- describe "GET /keys" do
- it { keys_path.should be_allowed_for @u1 }
- it { keys_path.should be_allowed_for :admin }
- it { keys_path.should be_allowed_for :user }
- it { keys_path.should be_denied_for :visitor }
- end
-
- describe "GET /profile" do
- it { profile_path.should be_allowed_for @u1 }
- it { profile_path.should be_allowed_for :admin }
- it { profile_path.should be_allowed_for :user }
- it { profile_path.should be_denied_for :visitor }
- end
-
- describe "GET /profile/password" do
- it { profile_password_path.should be_allowed_for @u1 }
- it { profile_password_path.should be_allowed_for :admin }
- it { profile_password_path.should be_allowed_for :user }
- it { profile_password_path.should be_denied_for :visitor }
- end
- end
-end
diff --git a/spec/requests/wikis_spec.rb b/spec/requests/wikis_spec.rb
deleted file mode 100644
index fd66b5e4300..00000000000
--- a/spec/requests/wikis_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-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/spec_helper.rb b/spec/spec_helper.rb
index 65e7e529a5b..9fb0ad7e249 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,5 +1,7 @@
-require 'simplecov'
-SimpleCov.start 'rails'
+unless ENV['CI']
+ require 'simplecov'
+ SimpleCov.start 'rails'
+end
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
@@ -7,59 +9,38 @@ require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/rails'
require 'capybara/rspec'
-require 'capybara/dsl'
require 'webmock/rspec'
require 'factories'
-require 'monkeypatch'
require 'email_spec'
+require 'headless'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
+# Use capybara-webkit
+Capybara.javascript_driver = :webkit
+
+WebMock.disable_net_connect!(allow_localhost: true)
+
RSpec.configure do |config|
- # == Mock Framework
- #
- # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
- #
- # config.mock_with :mocha
- # config.mock_with :flexmock
- # config.mock_with :rr
config.mock_with :rspec
- config.include LoginMacros
-
- # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
- config.fixture_path = "#{::Rails.root}/spec/fixtures"
+ config.include LoginHelpers, type: :request
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = false
- config.before :each, :type => :integration do
- DeviseSessionMock.disable
+ config.before :all do
+ headless = Headless.new
+ headless.start
end
config.before do
- if example.metadata[:js]
- DatabaseCleaner.strategy = :truncation
- Capybara::Selenium::Driver::DEFAULT_OPTIONS[:resynchronize] = true
- else
- DatabaseCleaner.strategy = :transaction
- end
-
- DatabaseCleaner.start
-
- WebMock.disable_net_connect!(allow_localhost: true)
- ActiveRecord::Base.observers.disable :all
- end
-
- config.after do
- DatabaseCleaner.clean
+ # !!! Observers disabled by default in tests
+ ActiveRecord::Base.observers.disable(:all)
+ # ActiveRecord::Base.observers.enable(:all)
end
-
- config.include RSpec::Rails::RequestExampleGroup, :type => :request, :example_group => {
- :file_path => /spec\/api/
- }
end
diff --git a/spec/support/api.rb b/spec/support/api.rb
deleted file mode 100644
index d363d8b9a57..00000000000
--- a/spec/support/api.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-def api_prefix
- "/api/#{Gitlab::API::VERSION}"
-end
-
-def json_response
- JSON.parse(response.body)
-end
diff --git a/spec/support/api_helpers.rb b/spec/support/api_helpers.rb
new file mode 100644
index 00000000000..7d9011971dd
--- /dev/null
+++ b/spec/support/api_helpers.rb
@@ -0,0 +1,34 @@
+module ApiHelpers
+ # Public: Prepend a request path with the path to the API
+ #
+ # path - Path to append
+ # user - User object - If provided, automatically appends private_token query
+ # string for authenticated requests
+ #
+ # Examples
+ #
+ # >> api('/issues')
+ # => "/api/v2/issues"
+ #
+ # >> api('/issues', User.last)
+ # => "/api/v2/issues?private_token=..."
+ #
+ # >> api('/issues?foo=bar', User.last)
+ # => "/api/v2/issues?foo=bar&private_token=..."
+ #
+ # Returns the relative path to the requested API resource
+ def api(path, user = nil)
+ "/api/#{Gitlab::API::VERSION}#{path}" +
+
+ # Normalize query string
+ (path.index('?') ? '' : '?') +
+
+ # Append private_token if given a User object
+ (user.respond_to?(:private_token) ?
+ "&private_token=#{user.private_token}" : "")
+ end
+
+ def json_response
+ JSON.parse(response.body)
+ end
+end
diff --git a/spec/support/db_cleaner.rb b/spec/support/db_cleaner.rb
new file mode 100644
index 00000000000..f1e072aa15f
--- /dev/null
+++ b/spec/support/db_cleaner.rb
@@ -0,0 +1,18 @@
+require 'database_cleaner'
+
+RSpec.configure do |config|
+ config.before do
+ if example.metadata[:js]
+ DatabaseCleaner.strategy = :truncation
+ Capybara::Selenium::Driver::DEFAULT_OPTIONS[:resynchronize] = true
+ else
+ DatabaseCleaner.strategy = :transaction
+ end
+
+ DatabaseCleaner.start
+ end
+
+ config.after do
+ DatabaseCleaner.clean
+ end
+end
diff --git a/spec/support/js_patch.rb b/spec/support/js_patch.rb
deleted file mode 100644
index 0d4ab264e85..00000000000
--- a/spec/support/js_patch.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module JsPatch
- def confirm_js_popup
- page.evaluate_script("window.alert = function(msg) { return true; }")
- page.evaluate_script("window.confirm = function(msg) { return true; }")
- end
-end
diff --git a/spec/support/login.rb b/spec/support/login.rb
deleted file mode 100644
index 026e336df58..00000000000
--- a/spec/support/login.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-module LoginMacros
- def login_as role
- @user = User.create(:email => "user#{User.count}@mail.com",
- :name => "John Smith",
- :password => "123456",
- :password_confirmation => "123456",
- :skype => 'user_skype')
-
- if role == :admin
- @user.admin = true
- @user.save!
- end
-
- visit new_user_session_path
- fill_in "user_email", :with => @user.email
- fill_in "user_password", :with => "123456"
- click_button "Sign in"
- end
-
- def login_with(user)
- visit new_user_session_path
- fill_in "user_email", :with => user.email
- fill_in "user_password", :with => "123456"
- click_button "Sign in"
- end
-
- def logout
- click_link "Logout" rescue nil
- end
-end
diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb
new file mode 100644
index 00000000000..769034e2286
--- /dev/null
+++ b/spec/support/login_helpers.rb
@@ -0,0 +1,23 @@
+module LoginHelpers
+ # Internal: Create and log in as a user of the specified role
+ #
+ # role - User role (e.g., :admin, :user)
+ def login_as(role)
+ @user = Factory(role)
+ login_with(@user)
+ end
+
+ # Internal: Login as the specified user
+ #
+ # user - User instance to login with
+ def login_with(user)
+ visit new_user_session_path
+ fill_in "user_email", with: user.email
+ fill_in "user_password", with: "123456"
+ click_button "Sign in"
+ end
+
+ def logout
+ click_link "Logout" rescue nil
+ end
+end
diff --git a/spec/monkeypatch.rb b/spec/support/monkeypatch.rb
index 6133631c5de..855a31f06de 100644
--- a/spec/monkeypatch.rb
+++ b/spec/support/monkeypatch.rb
@@ -35,7 +35,7 @@ class UsersProject
end
class FakeSatellite
- def exists?
+ def exists?
true
end
@@ -44,4 +44,8 @@ class FakeSatellite
end
end
-
+class ProtectedBranch
+ def update_repository
+ true
+ end
+end
diff --git a/spec/support/shared_examples.rb b/spec/support/shared_examples.rb
deleted file mode 100644
index 9fd207d0db2..00000000000
--- a/spec/support/shared_examples.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-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("Files") }
-end
-
-shared_examples_for :tree_view do
- subject { page }
-
- it "should have Tree View of project" do
- should have_content("app")
- should have_content("History")
- should have_content("Gemfile")
- end
-end
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index c70b2f6cebb..6f4bcca2bf2 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -10,7 +10,7 @@ describe PostReceive do
context "web hook" do
let(:project) { Factory.create(:project) }
- let(:key) { Factory.create(:key, :user => project.owner) }
+ let(:key) { Factory.create(:key, user: project.owner) }
let(:key_id) { key.identifier }
it "fetches the correct project" do
@@ -22,14 +22,14 @@ describe PostReceive do
Key.stub(find_by_identifier: nil)
project.should_not_receive(:observe_push)
- project.should_not_receive(:execute_web_hooks)
+ project.should_not_receive(:execute_hooks)
PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id).should be_false
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.owner)
+ project.should_receive(:execute_hooks).with('sha-old', 'sha-new', 'refs/heads/master', project.owner)
PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id)
end
diff --git a/vendor/assets/images/bg_fallback.png b/vendor/assets/images/bg_fallback.png
new file mode 100644
index 00000000000..4b2754b8040
--- /dev/null
+++ b/vendor/assets/images/bg_fallback.png
Binary files differ
diff --git a/vendor/assets/images/icon_sprite.png b/vendor/assets/images/icon_sprite.png
new file mode 100644
index 00000000000..636c80f2216
--- /dev/null
+++ b/vendor/assets/images/icon_sprite.png
Binary files differ
diff --git a/vendor/assets/images/progress_bar.gif b/vendor/assets/images/progress_bar.gif
new file mode 100644
index 00000000000..156fbb53137
--- /dev/null
+++ b/vendor/assets/images/progress_bar.gif
Binary files differ
diff --git a/vendor/assets/images/slider_handles.png b/vendor/assets/images/slider_handles.png
new file mode 100644
index 00000000000..b95a46eca97
--- /dev/null
+++ b/vendor/assets/images/slider_handles.png
Binary files differ
diff --git a/vendor/assets/images/ui-icons_222222_256x240.png b/vendor/assets/images/ui-icons_222222_256x240.png
new file mode 100644
index 00000000000..b273ff111d2
--- /dev/null
+++ b/vendor/assets/images/ui-icons_222222_256x240.png
Binary files differ
diff --git a/vendor/assets/images/ui-icons_454545_256x240.png b/vendor/assets/images/ui-icons_454545_256x240.png
new file mode 100644
index 00000000000..59bd45b907c
--- /dev/null
+++ b/vendor/assets/images/ui-icons_454545_256x240.png
Binary files differ
diff --git a/vendor/assets/javascripts/jquery.tagify.js b/vendor/assets/javascripts/jquery.tagify.js
deleted file mode 100644
index f22d4c71191..00000000000
--- a/vendor/assets/javascripts/jquery.tagify.js
+++ /dev/null
@@ -1,143 +0,0 @@
-/* Author: Alicia Liu */
-
-(function ($) {
-
- $.widget("ui.tagify", {
- options: {
- delimiters: [13, 188], // what user can type to complete a tag in char codes: [enter], [comma]
- outputDelimiter: ',', // delimiter for tags in original input field
- cssClass: 'tagify-container', // CSS class to style the tagify div and tags, see stylesheet
- addTagPrompt: 'add tags' // placeholder text
- },
-
- _create: function() {
- var self = this,
- el = self.element,
- opts = self.options;
-
- this.tags = [];
-
- // hide text field and replace with a div that contains it's own input field for entering tags
- this.tagInput = $("<input type='text'>")
- .attr( 'placeholder', opts.addTagPrompt )
- .keypress( function(e) {
- var $this = $(this),
- pressed = e.which;
-
- for ( i in opts.delimiters ) {
-
- if (pressed == opts.delimiters[i]) {
- self.add( $this.val() );
- e.preventDefault();
- return false;
- }
- }
- })
- // for some reason, in Safari, backspace is only recognized on keyup
- .keyup( function(e) {
- var $this = $(this),
- pressed = e.which;
-
- // if backspace is hit with no input, remove the last tag
- if (pressed == 8) { // backspace
- if ( $this.val() == "" ) {
- self.remove();
- return false;
- }
- return;
- }
- });
-
- this.tagDiv = $("<div></div>")
- .addClass( opts.cssClass )
- .click( function() {
- $(this).children('input').focus();
- })
- .append( this.tagInput )
- .insertAfter( el.hide() );
-
- // if the field isn't empty, parse the field for tags, and prepopulate existing tags
- var initVal = $.trim( el.val() );
-
- if ( initVal ) {
- var initTags = initVal.split( opts.outputDelimiter );
- $.each( initTags, function(i, tag) {
- self.add( tag );
- });
- }
- },
-
- _setOption: function( key, value ) {
- options.key = value;
- },
-
- // add a tag, public function
- add: function(text) {
- var self = this;
- text = text || self.tagInput.val();
- if (text) {
- var tagIndex = self.tags.length;
-
- var removeButton = $("<a href='#'>x</a>")
- .click( function() {
- self.remove( tagIndex );
- return false;
- });
- var newTag = $("<span></span>")
- .text( text )
- .append( removeButton );
-
- self.tagInput.before( newTag );
- self.tags.push( text );
- self.tagInput.val('');
- }
- },
-
- // remove a tag by index, public function
- // if index is blank, remove the last tag
- remove: function( tagIndex ) {
- var self = this;
- if ( tagIndex == null || tagIndex === (self.tags.length - 1) ) {
- this.tagDiv.children("span").last().remove();
- self.tags.pop();
- }
- if ( typeof(tagIndex) == 'number' ) {
- // otherwise just hide this tag, and we don't mess up the index
- this.tagDiv.children( "span:eq(" + tagIndex + ")" ).hide();
- // we rely on the serialize function to remove null values
- delete( self.tags[tagIndex] );
- }
- },
-
- // serialize the tags with the given delimiter, and write it back into the tagified field
- serialize: function() {
- var self = this;
- var delim = self.options.outputDelimiter;
- var tagsStr = self.tags.join( delim );
-
- // our tags might have deleted entries, remove them here
- var dupes = new RegExp(delim + delim + '+', 'g'); // regex: /,,+/g
- var ends = new RegExp('^' + delim + '|' + delim + '$', 'g'); // regex: /^,|,$/g
- var outputStr = tagsStr.replace( dupes, delim ).replace(ends, '');
-
- self.element.val(outputStr);
- return outputStr;
- },
-
- inputField: function() {
- return this.tagInput;
- },
-
- containerDiv: function() {
- return this.tagDiv;
- },
-
- // remove the div, and show original input
- destroy: function() {
- $.Widget.prototype.destroy.apply(this);
- this.tagDiv.remove();
- this.element.show();
- }
- });
-
-})(jQuery); \ No newline at end of file
diff --git a/vendor/assets/javascripts/jquery.ui.selectmenu.js b/vendor/assets/javascripts/jquery.ui.selectmenu.js
deleted file mode 100644
index 957fe4d8887..00000000000
--- a/vendor/assets/javascripts/jquery.ui.selectmenu.js
+++ /dev/null
@@ -1,844 +0,0 @@
- /*
- * jQuery UI selectmenu dev version
- *
- * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
- *
- * http://docs.jquery.com/UI
- * https://github.com/fnagel/jquery-ui/wiki/Selectmenu
- */
-
-(function($) {
-
-$.widget("ui.selectmenu", {
- getter: "value",
- version: "1.8",
- eventPrefix: "selectmenu",
- options: {
- transferClasses: true,
- typeAhead: "sequential",
- style: 'dropdown',
- positionOptions: {
- my: "left top",
- at: "left bottom",
- offset: null
- },
- width: null,
- menuWidth: null,
- handleWidth: 26,
- maxHeight: null,
- icons: null,
- format: null,
- bgImage: function() {},
- wrapperElement: "<div />"
- },
-
- _create: function() {
- var self = this, o = this.options;
-
- // set a default id value, generate a new random one if not set by developer
- var selectmenuId = this.element.attr( 'id' ) || 'ui-selectmenu-' + Math.random().toString( 16 ).slice( 2, 10 );
-
- // quick array of button and menu id's
- this.ids = [ selectmenuId + '-button', selectmenuId + '-menu' ];
-
- // define safe mouseup for future toggling
- this._safemouseup = true;
-
- // create menu button wrapper
- this.newelement = $( '<a />', {
- 'class': this.widgetBaseClass + ' ui-widget ui-state-default ui-corner-all',
- 'id' : this.ids[ 0 ],
- 'role': 'button',
- 'href': '#nogo',
- 'tabindex': this.element.attr( 'disabled' ) ? 1 : 0,
- 'aria-haspopup': true,
- 'aria-owns': this.ids[ 1 ]
- });
- this.newelementWrap = $( o.wrapperElement )
- .append( this.newelement )
- .insertAfter( this.element );
-
- // transfer tabindex
- var tabindex = this.element.attr( 'tabindex' );
- if ( tabindex ) {
- this.newelement.attr( 'tabindex', tabindex );
- }
-
- // save reference to select in data for ease in calling methods
- this.newelement.data( 'selectelement', this.element );
-
- // menu icon
- this.selectmenuIcon = $( '<span class="' + this.widgetBaseClass + '-icon ui-icon"></span>' )
- .prependTo( this.newelement );
-
- // append status span to button
- this.newelement.prepend( '<span class="' + self.widgetBaseClass + '-status" />' );
-
- // make associated form label trigger focus
- $( 'label[for="' + selectmenuId + '"]' )
- .attr( 'for', this.ids[0] )
- .bind( 'click.selectmenu', function() {
- self.newelement[0].focus();
- return false;
- });
-
- // click toggle for menu visibility
- this.newelement
- .bind('mousedown.selectmenu', function(event) {
- self._toggle(event, true);
- // make sure a click won't open/close instantly
- if (o.style == "popup") {
- self._safemouseup = false;
- setTimeout(function() { self._safemouseup = true; }, 300);
- }
- return false;
- })
- .bind('click.selectmenu', function() {
- return false;
- })
- .bind("keydown.selectmenu", function(event) {
- var ret = false;
- switch (event.keyCode) {
- case $.ui.keyCode.ENTER:
- ret = true;
- break;
- case $.ui.keyCode.SPACE:
- self._toggle(event);
- break;
- case $.ui.keyCode.UP:
- if (event.altKey) {
- self.open(event);
- } else {
- self._moveSelection(-1);
- }
- break;
- case $.ui.keyCode.DOWN:
- if (event.altKey) {
- self.open(event);
- } else {
- self._moveSelection(1);
- }
- break;
- case $.ui.keyCode.LEFT:
- self._moveSelection(-1);
- break;
- case $.ui.keyCode.RIGHT:
- self._moveSelection(1);
- break;
- case $.ui.keyCode.TAB:
- ret = true;
- break;
- default:
- ret = true;
- }
- return ret;
- })
- .bind('keypress.selectmenu', function(event) {
- self._typeAhead(event.which, 'mouseup');
- return true;
- })
- .bind('mouseover.selectmenu focus.selectmenu', function() {
- if (!o.disabled) {
- $(this).addClass(self.widgetBaseClass + '-focus ui-state-hover');
- }
- })
- .bind('mouseout.selectmenu blur.selectmenu', function() {
- if (!o.disabled) {
- $(this).removeClass(self.widgetBaseClass + '-focus ui-state-hover');
- }
- });
-
- // document click closes menu
- $(document).bind("mousedown.selectmenu", function(event) {
- self.close(event);
- });
-
- // change event on original selectmenu
- this.element
- .bind("click.selectmenu", function() {
- self._refreshValue();
- })
- // FIXME: newelement can be null under unclear circumstances in IE8
- // TODO not sure if this is still a problem (fnagel 20.03.11)
- .bind("focus.selectmenu", function() {
- if (self.newelement) {
- self.newelement[0].focus();
- }
- });
-
- // set width when not set via options
- if (!o.width) {
- o.width = this.element.outerWidth();
- }
- // set menu button width
- this.newelement.width(o.width);
-
- // hide original selectmenu element
- this.element.hide();
-
- // create menu portion, append to body
- this.list = $( '<ul />', {
- 'class': 'ui-widget ui-widget-content',
- 'aria-hidden': true,
- 'role': 'listbox',
- 'aria-labelledby': this.ids[0],
- 'id': this.ids[1]
- });
- this.listWrap = $( o.wrapperElement )
- .addClass( self.widgetBaseClass + '-menu' )
- .append( this.list )
- .appendTo( 'body' );
-
- // transfer menu click to menu button
- this.list
- .bind("keydown.selectmenu", function(event) {
- var ret = false;
- switch (event.keyCode) {
- case $.ui.keyCode.UP:
- if (event.altKey) {
- self.close(event, true);
- } else {
- self._moveFocus(-1);
- }
- break;
- case $.ui.keyCode.DOWN:
- if (event.altKey) {
- self.close(event, true);
- } else {
- self._moveFocus(1);
- }
- break;
- case $.ui.keyCode.LEFT:
- self._moveFocus(-1);
- break;
- case $.ui.keyCode.RIGHT:
- self._moveFocus(1);
- break;
- case $.ui.keyCode.HOME:
- self._moveFocus(':first');
- break;
- case $.ui.keyCode.PAGE_UP:
- self._scrollPage('up');
- break;
- case $.ui.keyCode.PAGE_DOWN:
- self._scrollPage('down');
- break;
- case $.ui.keyCode.END:
- self._moveFocus(':last');
- break;
- case $.ui.keyCode.ENTER:
- case $.ui.keyCode.SPACE:
- self.close(event, true);
- $(event.target).parents('li:eq(0)').trigger('mouseup');
- break;
- case $.ui.keyCode.TAB:
- ret = true;
- self.close(event, true);
- $(event.target).parents('li:eq(0)').trigger('mouseup');
- break;
- case $.ui.keyCode.ESCAPE:
- self.close(event, true);
- break;
- default:
- ret = true;
- }
- return ret;
- })
- .bind('keypress.selectmenu', function(event) {
- self._typeAhead(event.which, 'focus');
- return true;
- })
- // this allows for using the scrollbar in an overflowed list
- .bind( 'mousedown.selectmenu mouseup.selectmenu', function() { return false; });
-
- // needed when window is resized
- // TODO seems to be useless, but causes errors (fnagel 01.08.11)
- // see: https://github.com/fnagel/jquery-ui/issues/147
- // $(window).bind( "resize.selectmenu", $.proxy( self._refreshPosition, this ) );
- },
-
- _init: function() {
- var self = this, o = this.options;
-
- // serialize selectmenu element options
- var selectOptionData = [];
- this.element
- .find('option')
- .each(function() {
- var opt = $(this);
- selectOptionData.push({
- value: opt.attr('value'),
- text: self._formatText(opt.text()),
- selected: opt.attr('selected'),
- disabled: opt.attr('disabled'),
- classes: opt.attr('class'),
- typeahead: opt.attr('typeahead'),
- parentOptGroup: opt.parent('optgroup'),
- bgImage: o.bgImage.call(opt)
- });
- });
-
- // active state class is only used in popup style
- var activeClass = (self.options.style == "popup") ? " ui-state-active" : "";
-
- // empty list so we can refresh the selectmenu via selectmenu()
- this.list.html("");
-
- // write li's
- if (selectOptionData.length) {
- for (var i = 0; i < selectOptionData.length; i++) {
- var thisLiAttr = { role : 'presentation' };
- if ( selectOptionData[ i ].disabled ) {
- thisLiAttr[ 'class' ] = this.namespace + '-state-disabled';
- }
- var thisAAttr = {
- html: selectOptionData[i].text,
- href : '#nogo',
- tabindex : -1,
- role : 'option',
- 'aria-selected' : false
- };
- if ( selectOptionData[ i ].disabled ) {
- thisAAttr[ 'aria-disabled' ] = selectOptionData[ i ].disabled;
- }
- if ( selectOptionData[ i ].typeahead ) {
- thisAAttr[ 'typeahead' ] = selectOptionData[ i ].typeahead;
- }
- var thisA = $('<a/>', thisAAttr);
- var thisLi = $('<li/>', thisLiAttr)
- .append(thisA)
- .data('index', i)
- .addClass(selectOptionData[i].classes)
- .data('optionClasses', selectOptionData[i].classes || '')
- .bind("mouseup.selectmenu", function(event) {
- if (self._safemouseup && !self._disabled(event.currentTarget) && !self._disabled($( event.currentTarget ).parents( "ul>li." + self.widgetBaseClass + "-group " )) ) {
- var changed = $(this).data('index') != self._selectedIndex();
- self.index($(this).data('index'));
- self.select(event);
- if (changed) {
- self.change(event);
- }
- self.close(event, true);
- }
- return false;
- })
- .bind("click.selectmenu", function() {
- return false;
- })
- .bind('mouseover.selectmenu focus.selectmenu', function(e) {
- // no hover if diabled
- if (!$(e.currentTarget).hasClass(self.namespace + '-state-disabled') && !$(e.currentTarget).parent("ul").parent("li").hasClass(self.namespace + '-state-disabled')) {
- self._selectedOptionLi().addClass(activeClass);
- self._focusedOptionLi().removeClass(self.widgetBaseClass + '-item-focus ui-state-hover');
- $(this).removeClass('ui-state-active').addClass(self.widgetBaseClass + '-item-focus ui-state-hover');
- }
- })
- .bind('mouseout.selectmenu blur.selectmenu', function() {
- if ($(this).is(self._selectedOptionLi().selector)) {
- $(this).addClass(activeClass);
- }
- $(this).removeClass(self.widgetBaseClass + '-item-focus ui-state-hover');
- });
-
- // optgroup or not...
- if ( selectOptionData[i].parentOptGroup.length ) {
- var optGroupName = self.widgetBaseClass + '-group-' + this.element.find( 'optgroup' ).index( selectOptionData[i].parentOptGroup );
- if (this.list.find( 'li.' + optGroupName ).length ) {
- this.list.find( 'li.' + optGroupName + ':last ul' ).append( thisLi );
- } else {
- $(' <li role="presentation" class="' + self.widgetBaseClass + '-group ' + optGroupName + (selectOptionData[i].parentOptGroup.attr("disabled") ? ' ' + this.namespace + '-state-disabled" aria-disabled="true"' : '"' ) + '><span class="' + self.widgetBaseClass + '-group-label">' + selectOptionData[i].parentOptGroup.attr('label') + '</span><ul></ul></li> ')
- .appendTo( this.list )
- .find( 'ul' )
- .append( thisLi );
- }
- } else {
- thisLi.appendTo(this.list);
- }
-
- // append icon if option is specified
- if (o.icons) {
- for (var j in o.icons) {
- if (thisLi.is(o.icons[j].find)) {
- thisLi
- .data('optionClasses', selectOptionData[i].classes + ' ' + self.widgetBaseClass + '-hasIcon')
- .addClass(self.widgetBaseClass + '-hasIcon');
- var iconClass = o.icons[j].icon || "";
- thisLi
- .find('a:eq(0)')
- .prepend('<span class="' + self.widgetBaseClass + '-item-icon ui-icon ' + iconClass + '"></span>');
- if (selectOptionData[i].bgImage) {
- thisLi.find('span').css('background-image', selectOptionData[i].bgImage);
- }
- }
- }
- }
- }
- } else {
- $('<li role="presentation"><a href="#nogo" tabindex="-1" role="option"></a></li>').appendTo(this.list);
- }
- // we need to set and unset the CSS classes for dropdown and popup style
- var isDropDown = ( o.style == 'dropdown' );
- this.newelement
- .toggleClass( self.widgetBaseClass + '-dropdown', isDropDown )
- .toggleClass( self.widgetBaseClass + '-popup', !isDropDown );
- this.list
- .toggleClass( self.widgetBaseClass + '-menu-dropdown ui-corner-bottom', isDropDown )
- .toggleClass( self.widgetBaseClass + '-menu-popup ui-corner-all', !isDropDown )
- // add corners to top and bottom menu items
- .find( 'li:first' )
- .toggleClass( 'ui-corner-top', !isDropDown )
- .end().find( 'li:last' )
- .addClass( 'ui-corner-bottom' );
- this.selectmenuIcon
- .toggleClass( 'ui-icon-triangle-1-s', isDropDown )
- .toggleClass( 'ui-icon-triangle-2-n-s', !isDropDown );
-
- // transfer classes to selectmenu and list
- if ( o.transferClasses ) {
- var transferClasses = this.element.attr( 'class' ) || '';
- this.newelement.add( this.list ).addClass( transferClasses );
- }
-
- // set menu width to either menuWidth option value, width option value, or select width
- if ( o.style == 'dropdown' ) {
- this.list.width( o.menuWidth ? o.menuWidth : o.width );
- } else {
- this.list.width( o.menuWidth ? o.menuWidth : o.width - o.handleWidth );
- }
-
- // reset height to auto
- this.list.css( 'height', 'auto' );
- var listH = this.listWrap.height();
- // calculate default max height
- if ( o.maxHeight && o.maxHeight < listH ) {
- this.list.height( o.maxHeight );
- } else {
- var winH = $( window ).height() / 3;
- if ( winH < listH ) this.list.height( winH );
- }
-
- // save reference to actionable li's (not group label li's)
- this._optionLis = this.list.find( 'li:not(.' + self.widgetBaseClass + '-group)' );
-
- // transfer disabled state
- if ( this.element.attr( 'disabled' ) ) {
- this.disable();
- } else {
- this.enable()
- }
-
- // update value
- this.index( this._selectedIndex() );
-
- // needed when selectmenu is placed at the very bottom / top of the page
- window.setTimeout( function() {
- self._refreshPosition();
- }, 200 );
- },
-
- destroy: function() {
- this.element.removeData( this.widgetName )
- .removeClass( this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled' )
- .removeAttr( 'aria-disabled' )
- .unbind( ".selectmenu" );
-
- // TODO unneded as event binding has been disabled
- // $( window ).unbind( ".selectmenu" );
- $( document ).unbind( ".selectmenu" );
-
- // unbind click on label, reset its for attr
- $( 'label[for=' + this.newelement.attr('id') + ']' )
- .attr( 'for', this.element.attr( 'id' ) )
- .unbind( '.selectmenu' );
-
- this.newelementWrap.remove();
- this.listWrap.remove();
-
- this.element.show();
-
- // call widget destroy function
- $.Widget.prototype.destroy.apply(this, arguments);
- },
-
- _typeAhead: function( code, eventType ){
- var self = this, focusFound = false, C = String.fromCharCode(code).toUpperCase();
- c = C.toLowerCase();
-
- if ( self.options.typeAhead == 'sequential' ) {
- // clear the timeout so we can use _prevChar
- window.clearTimeout('ui.selectmenu-' + self.selectmenuId);
-
- // define our find var
- var find = typeof( self._prevChar ) == 'undefined' ? '' : self._prevChar.join( '' );
-
- function focusOptSeq( elem, ind, c ){
- focusFound = true;
- $( elem ).trigger( eventType );
- typeof( self._prevChar ) == 'undefined' ? self._prevChar = [ c ] : self._prevChar[ self._prevChar.length ] = c;
- }
- this.list.find( 'li a' ).each( function( i ) {
- if ( !focusFound ) {
- // allow the typeahead attribute on the option tag for a more specific lookup
- var thisText = $( this ).attr( 'typeahead' ) || $(this).text();
- if ( thisText.indexOf( find + C ) === 0 ) {
- focusOptSeq( this, i, C );
- } else if (thisText.indexOf(find+c) === 0 ) {
- focusOptSeq( this, i, c );
- }
- }
- });
- // set a 1 second timeout for sequenctial typeahead
- // keep this set even if we have no matches so it doesnt typeahead somewhere else
- window.setTimeout( function( el ) {
- self._prevChar = undefined;
- }, 1000, self );
-
- } else {
- // define self._prevChar if needed
- if ( !self._prevChar ) { self._prevChar = [ '' , 0 ]; }
-
- focusFound = false;
- function focusOpt( elem, ind ){
- focusFound = true;
- $( elem ).trigger( eventType );
- self._prevChar[ 1 ] = ind;
- }
- this.list.find( 'li a' ).each(function( i ){
- if (!focusFound){
- var thisText = $(this).text();
- if ( thisText.indexOf( C ) === 0 || thisText.indexOf( c ) === 0 ) {
- if (self._prevChar[0] == C){
- if ( self._prevChar[ 1 ] < i ){ focusOpt( this, i ); }
- } else{
- focusOpt( this, i );
- }
- }
- }
- });
- this._prevChar[ 0 ] = C;
- }
- },
-
- // returns some usefull information, called by callbacks only
- _uiHash: function() {
- var index = this.index();
- return {
- index: index,
- option: $("option", this.element).get(index),
- value: this.element[0].value
- };
- },
-
- open: function(event) {
- var self = this, o = this.options;
- if ( self.newelement.attr("aria-disabled") != 'true' ) {
- self._closeOthers(event);
- self.newelement.addClass('ui-state-active');
-
- self.listWrap.appendTo( o.appendTo );
- self.list.attr('aria-hidden', false);
-
- if ( o.style == "dropdown" ) {
- self.newelement.removeClass('ui-corner-all').addClass('ui-corner-top');
- }
-
- self.listWrap.addClass( self.widgetBaseClass + '-open' );
- // positioning needed for IE7 (tested 01.08.11 on MS VPC Image)
- // see https://github.com/fnagel/jquery-ui/issues/147
- if ( $.browser.msie && $.browser.version.substr( 0,1 ) == 7 ) {
- self._refreshPosition();
- }
- var selected = self.list.attr('aria-hidden', false).find('li:not(.' + self.widgetBaseClass + '-group):eq(' + self._selectedIndex() + '):visible a');
- if (selected.length) selected[0].focus();
- // positioning needed for FF, Chrome, IE8, IE7, IE6 (tested 01.08.11 on MS VPC Image)
- self._refreshPosition();
-
- self._trigger("open", event, self._uiHash());
- }
- },
-
- close: function(event, retainFocus) {
- if ( this.newelement.is('.ui-state-active') ) {
- this.newelement
- .removeClass('ui-state-active');
- this.listWrap.removeClass(this.widgetBaseClass + '-open');
- this.list.attr('aria-hidden', true);
- if ( this.options.style == "dropdown" ) {
- this.newelement.removeClass('ui-corner-top').addClass('ui-corner-all');
- }
- if ( retainFocus ) {
- this.newelement.focus();
- }
- this._trigger("close", event, this._uiHash());
- }
- },
-
- change: function(event) {
- this.element.trigger("change");
- this._trigger("change", event, this._uiHash());
- },
-
- select: function(event) {
- if (this._disabled(event.currentTarget)) { return false; }
- this._trigger("select", event, this._uiHash());
- },
-
- _closeOthers: function(event) {
- $('.' + this.widgetBaseClass + '.ui-state-active').not(this.newelement).each(function() {
- $(this).data('selectelement').selectmenu('close', event);
- });
- $('.' + this.widgetBaseClass + '.ui-state-hover').trigger('mouseout');
- },
-
- _toggle: function(event, retainFocus) {
- if ( this.list.parent().is('.' + this.widgetBaseClass + '-open') ) {
- this.close(event, retainFocus);
- } else {
- this.open(event);
- }
- },
-
- _formatText: function(text) {
- return (this.options.format ? this.options.format(text) : text);
- },
-
- _selectedIndex: function() {
- return this.element[0].selectedIndex;
- },
-
- _selectedOptionLi: function() {
- return this._optionLis.eq(this._selectedIndex());
- },
-
- _focusedOptionLi: function() {
- return this.list.find('.' + this.widgetBaseClass + '-item-focus');
- },
-
- _moveSelection: function(amt, recIndex) {
- // do nothing if disabled
- if (!this.options.disabled) {
- var currIndex = parseInt(this._selectedOptionLi().data('index') || 0, 10);
- var newIndex = currIndex + amt;
- // do not loop when using up key
-
- if (newIndex < 0) {
- newIndex = 0;
- }
- if (newIndex > this._optionLis.size() - 1) {
- newIndex = this._optionLis.size() - 1;
- }
- // Occurs when a full loop has been made
- if (newIndex === recIndex) { return false; }
-
- if (this._optionLis.eq(newIndex).hasClass( this.namespace + '-state-disabled' )) {
- // if option at newIndex is disabled, call _moveFocus, incrementing amt by one
- (amt > 0) ? ++amt : --amt;
- this._moveSelection(amt, newIndex);
- } else {
- return this._optionLis.eq(newIndex).trigger('mouseup');
- }
- }
- },
-
- _moveFocus: function(amt, recIndex) {
- if (!isNaN(amt)) {
- var currIndex = parseInt(this._focusedOptionLi().data('index') || 0, 10);
- var newIndex = currIndex + amt;
- } else {
- var newIndex = parseInt(this._optionLis.filter(amt).data('index'), 10);
- }
-
- if (newIndex < 0) {
- newIndex = 0;
- }
- if (newIndex > this._optionLis.size() - 1) {
- newIndex = this._optionLis.size() - 1;
- }
-
- //Occurs when a full loop has been made
- if (newIndex === recIndex) { return false; }
-
- var activeID = this.widgetBaseClass + '-item-' + Math.round(Math.random() * 1000);
-
- this._focusedOptionLi().find('a:eq(0)').attr('id', '');
-
- if (this._optionLis.eq(newIndex).hasClass( this.namespace + '-state-disabled' )) {
- // if option at newIndex is disabled, call _moveFocus, incrementing amt by one
- (amt > 0) ? ++amt : --amt;
- this._moveFocus(amt, newIndex);
- } else {
- this._optionLis.eq(newIndex).find('a:eq(0)').attr('id',activeID).focus();
- }
-
- this.list.attr('aria-activedescendant', activeID);
- },
-
- _scrollPage: function(direction) {
- var numPerPage = Math.floor(this.list.outerHeight() / this.list.find('li:first').outerHeight());
- numPerPage = (direction == 'up' ? -numPerPage : numPerPage);
- this._moveFocus(numPerPage);
- },
-
- _setOption: function(key, value) {
- this.options[key] = value;
- // set
- if (key == 'disabled') {
- this.close();
- this.element
- .add(this.newelement)
- .add(this.list)[value ? 'addClass' : 'removeClass'](
- this.widgetBaseClass + '-disabled' + ' ' +
- this.namespace + '-state-disabled')
- .attr("aria-disabled", value);
- }
- },
-
- disable: function(index, type){
- // if options is not provided, call the parents disable function
- if ( typeof( index ) == 'undefined' ) {
- this._setOption( 'disabled', true );
- } else {
- if ( type == "optgroup" ) {
- this._disableOptgroup(index);
- } else {
- this._disableOption(index);
- }
- }
- },
-
- enable: function(index, type) {
- // if options is not provided, call the parents enable function
- if ( typeof( index ) == 'undefined' ) {
- this._setOption('disabled', false);
- } else {
- if ( type == "optgroup" ) {
- this._enableOptgroup(index);
- } else {
- this._enableOption(index);
- }
- }
- },
-
- _disabled: function(elem) {
- return $(elem).hasClass( this.namespace + '-state-disabled' );
- },
-
- _disableOption: function(index) {
- var optionElem = this._optionLis.eq(index);
- if (optionElem) {
- optionElem.addClass(this.namespace + '-state-disabled')
- .find("a").attr("aria-disabled", true);
- this.element.find("option").eq(index).attr("disabled", "disabled");
- }
- },
-
- _enableOption: function(index) {
- var optionElem = this._optionLis.eq(index);
- if (optionElem) {
- optionElem.removeClass( this.namespace + '-state-disabled' )
- .find("a").attr("aria-disabled", false);
- this.element.find("option").eq(index).removeAttr("disabled");
- }
- },
-
- _disableOptgroup: function(index) {
- var optGroupElem = this.list.find( 'li.' + this.widgetBaseClass + '-group-' + index );
- if (optGroupElem) {
- optGroupElem.addClass(this.namespace + '-state-disabled')
- .attr("aria-disabled", true);
- this.element.find("optgroup").eq(index).attr("disabled", "disabled");
- }
- },
-
- _enableOptgroup: function(index) {
- var optGroupElem = this.list.find( 'li.' + this.widgetBaseClass + '-group-' + index );
- if (optGroupElem) {
- optGroupElem.removeClass(this.namespace + '-state-disabled')
- .attr("aria-disabled", false);
- this.element.find("optgroup").eq(index).removeAttr("disabled");
- }
- },
-
- index: function(newValue) {
- if (arguments.length) {
- if (!this._disabled($(this._optionLis[newValue]))) {
- this.element[0].selectedIndex = newValue;
- this._refreshValue();
- } else {
- return false;
- }
- } else {
- return this._selectedIndex();
- }
- },
-
- value: function(newValue) {
- if (arguments.length) {
- this.element[0].value = newValue;
- this._refreshValue();
- } else {
- return this.element[0].value;
- }
- },
-
- _refreshValue: function() {
- var activeClass = (this.options.style == "popup") ? " ui-state-active" : "";
- var activeID = this.widgetBaseClass + '-item-' + Math.round(Math.random() * 1000);
- // deselect previous
- this.list
- .find('.' + this.widgetBaseClass + '-item-selected')
- .removeClass(this.widgetBaseClass + "-item-selected" + activeClass)
- .find('a')
- .attr('aria-selected', 'false')
- .attr('id', '');
- // select new
- this._selectedOptionLi()
- .addClass(this.widgetBaseClass + "-item-selected" + activeClass)
- .find('a')
- .attr('aria-selected', 'true')
- .attr('id', activeID);
-
- // toggle any class brought in from option
- var currentOptionClasses = (this.newelement.data('optionClasses') ? this.newelement.data('optionClasses') : "");
- var newOptionClasses = (this._selectedOptionLi().data('optionClasses') ? this._selectedOptionLi().data('optionClasses') : "");
- this.newelement
- .removeClass(currentOptionClasses)
- .data('optionClasses', newOptionClasses)
- .addClass( newOptionClasses )
- .find('.' + this.widgetBaseClass + '-status')
- .html(
- this._selectedOptionLi()
- .find('a:eq(0)')
- .html()
- );
-
- this.list.attr('aria-activedescendant', activeID);
- },
-
- _refreshPosition: function() {
- var o = this.options;
-
- // if its a native pop-up we need to calculate the position of the selected li
- if ( o.style == "popup" && !o.positionOptions.offset ) {
- var selected = this._selectedOptionLi();
- var _offset = "0 -" + ( selected.outerHeight() + selected.offset().top - this.list.offset().top );
- }
- // update zIndex if jQuery UI is able to process
- var zIndexElement = this.element.zIndex();
- if ( zIndexElement ) {
- this.listWrap.css( 'zIndex', zIndexElement );
- }
- this.listWrap.position({
- // set options for position plugin
- of: o.positionOptions.of || this.newelement,
- my: o.positionOptions.my,
- at: o.positionOptions.at,
- offset: o.positionOptions.offset || _offset,
- collision: o.positionOptions.collision || 'flip'
- });
- }
-});
-
-})(jQuery);
diff --git a/vendor/assets/stylesheets/jquery-ui/jquery.tagify.css b/vendor/assets/stylesheets/jquery-ui/jquery.tagify.css
deleted file mode 100644
index d6c178f7132..00000000000
--- a/vendor/assets/stylesheets/jquery-ui/jquery.tagify.css
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Tagify styles
-Author: Alicia Liu test
-*/
-
-.tagify-container {
-}
-
-.tagify-container > span {
- display: inline-block;
- padding: 8px 11px 8px 11px;
- margin: 1px 5px 0px 0px;
- border-radius: 4px;
- border: 1px solid #d0e1ff;
- background-color: #d0e1ff;
- color: #0f326d;
- font-weight: bold;
- font-size: 14px;
-}
-
-.tagify-container > span > a {
- padding-left: 5px !important;
- color: #83a5e1;
- text-decoration: none;
- font-weight: bold;
-}
-
-.tagify-container > input {
- border: 0 none;
- width: 100px !important;
-}
-
-.tagify-container > input:focus {
- outline: none;
-} \ No newline at end of file
diff --git a/vendor/assets/stylesheets/jquery-ui/jquery.ui.selectmenu.css b/vendor/assets/stylesheets/jquery-ui/jquery.ui.selectmenu.css
deleted file mode 100644
index 481adf5a2a8..00000000000
--- a/vendor/assets/stylesheets/jquery-ui/jquery.ui.selectmenu.css
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Selectmenu
-----------------------------------*/
-.ui-selectmenu { background:none; font-size:12px;display: block; display: inline-block; position: relative; height: 2.2em; vertical-align: middle; text-decoration: none; overflow: hidden; zoom: 1; }
-.ui-selectmenu-icon { position:absolute; right:6px; margin-top:-8px; top: 50%; }
-.ui-selectmenu-menu { padding:0; margin:0; position:absolute; top: 0; display: none; z-index: 1005;} /* z-index: 1005 to make selectmenu work with dialog */
-.ui-selectmenu-menu ul { padding:0; margin:0; list-style:none; position: relative; overflow: auto; overflow-y: auto ; overflow-x: hidden; }
-.ui-selectmenu-open { display: block; }
-.ui-selectmenu.ui-widget { background:none; }
-.ui-selectmenu-menu-popup { margin-top: -1px; }
-.ui-selectmenu-menu-dropdown { }
-.ui-selectmenu-menu li.ui-state-active { background:#F7FBFC; border:none; padding:1px 0;}
-.ui-selectmenu-menu li { padding:0; margin:0; display: block; border-top: 1px dotted transparent; border-bottom: 1px dotted transparent; border-right-width: 0 !important; border-left-width: 0 !important; font-weight: normal !important; }
-.ui-selectmenu-menu li a,.ui-selectmenu-status { line-height: 1.4em; display: block; padding: .405em 2.1em .405em 1em; outline:none; text-decoration:none; }
-.ui-selectmenu-menu li.ui-state-disabled a, .ui-state-disabled { cursor: default; }
-.ui-selectmenu-menu li.ui-selectmenu-hasIcon a,
-.ui-selectmenu-hasIcon .ui-selectmenu-status { padding-left: 20px; position: relative; margin-left: 5px; }
-.ui-selectmenu-menu li .ui-icon, .ui-selectmenu-status .ui-icon { position: absolute; top: 1em; margin-top: -8px; left: 0; }
-.ui-selectmenu-status { line-height: 1.4em; }
-.ui-selectmenu-open li.ui-selectmenu-item-focus { background: none repeat scroll 0 0 #FFF6BF; border:1px solid #eaeaea;}
-.ui-selectmenu-open li.ui-selectmenu-item-selected { }
-.ui-selectmenu-menu li span,.ui-selectmenu-status span { display:block; margin-bottom: .2em; }
-.ui-selectmenu-menu li .ui-selectmenu-item-header { font-weight: bold; }
-.ui-selectmenu-menu li .ui-selectmenu-item-content { }
-.ui-selectmenu-menu li .ui-selectmenu-item-footer { opacity: .8; }
-/* for optgroups */
-.ui-selectmenu-menu .ui-selectmenu-group { font-size: 1em; }
-.ui-selectmenu-menu .ui-selectmenu-group .ui-selectmenu-group-label { line-height: 1.4em; display:block; padding: .6em .5em 0; font-weight: bold; }
-.ui-selectmenu-menu .ui-selectmenu-group ul { margin: 0; padding: 0; }
-/* IE6 workaround (dotted transparent borders) */
-* html .ui-selectmenu-menu li { border-color: pink; filter:chroma(color=pink); width:100%; }
-* html .ui-selectmenu-menu li a { position: relative }
-/* IE7 workaround (opacity disabled) */
-*+html .ui-state-disabled, *+html .ui-state-disabled a { color: silver; }
diff --git a/vendor/assets/stylesheets/jquery.ui.aristo.css b/vendor/assets/stylesheets/jquery.ui.aristo.css
new file mode 100644
index 00000000000..8cc6e787730
--- /dev/null
+++ b/vendor/assets/stylesheets/jquery.ui.aristo.css
@@ -0,0 +1,738 @@
+/*
+ * jQuery UI CSS Framework 1.8.7
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+
+/*
+ * jQuery UI CSS Framework 1.8.7
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ *
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ctl=themeroller
+ */
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Arial,sans-serif; font-size: 1.1em; }
+.ui-widget .ui-widget { font-size: 1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Arial,sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #B6B6B6; background: #ffffff; color: #4F4F4F; }
+.ui-widget-content a { color: #4F4F4F; }
+.ui-widget-header { border: 1px solid #B6B6B6; color: #4F4F4F; font-weight: bold; }
+.ui-widget-header {
+ background: #ededed url(bg_fallback.png) 0 0 repeat-x; /* Old browsers */
+ background: -moz-linear-gradient(top, #ededed 0%, #c4c4c4 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ededed), color-stop(100%,#c4c4c4)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #ededed 0%,#c4c4c4 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #ededed 0%,#c4c4c4 100%); /* Opera11.10+ */
+ background: -ms-linear-gradient(top, #ededed 0%,#c4c4c4 100%); /* IE10+ */
+ background: linear-gradient(top, #ededed 0%,#c4c4c4 100%); /* W3C */
+}
+.ui-widget-header a { color: #4F4F4F; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #B6B6B6; font-weight: normal; color: #4F4F4F; }
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default {
+ background: #ededed url(bg_fallback.png) 0 0 repeat-x; /* Old browsers */
+ background: -moz-linear-gradient(top, #ededed 0%, #c4c4c4 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ededed), color-stop(100%,#c4c4c4)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #ededed 0%,#c4c4c4 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #ededed 0%,#c4c4c4 100%); /* Opera11.10+ */
+ background: -ms-linear-gradient(top, #ededed 0%,#c4c4c4 100%); /* IE10+ */
+ background: linear-gradient(top, #ededed 0%,#c4c4c4 100%); /* W3C */
+ -webkit-box-shadow: 0 1px 0 rgba(255,255,255,0.6) inset;
+ -moz-box-shadow: 0 1px 0 rgba(255,255,255,0.6) inset;
+ box-shadow: 0 1px 0 rgba(255,255,255,0.6) inset;
+}
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #4F4F4F; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #9D9D9D; font-weight: normal; color: #313131; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #313131; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active {
+ outline: none;
+ color: #1c4257; border: 1px solid #7096ab;
+ background: #ededed url(bg_fallback.png) 0 -50px repeat-x; /* Old browsers */
+ background: -moz-linear-gradient(top, #b9e0f5 0%, #92bdd6 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b9e0f5), color-stop(100%,#92bdd6)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #b9e0f5 0%,#92bdd6 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #b9e0f5 0%,#92bdd6 100%); /* Opera11.10+ */
+ background: -ms-linear-gradient(top, #b9e0f5 0%,#92bdd6 100%); /* IE10+ */
+ background: linear-gradient(top, #b9e0f5 0%,#92bdd6 100%); /* W3C */
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+}
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #313131; text-decoration: none; }
+.ui-widget :active { outline: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight { border: 1px solid #d2dbf4; background: #f4f8fd; color: #0d2054; -moz-border-radius: 0 !important; -webkit-border-radius: 0 !important; border-radius: 0 !important; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error { border: 1px solid #e2d0d0; background: #fcf0f0; color: #280b0b; -moz-border-radius: 0 !important; -webkit-border-radius: 0 !important; border-radius: 0 !important; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(ui-icons_222222_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(ui-icons_222222_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(ui-icons_222222_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(ui-icons_454545_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(ui-icons_454545_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(ui-icons_454545_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(ui-icons_454545_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon { background: url(icon_sprite.png) -16px 0 no-repeat !important; }
+.ui-state-highlight .ui-icon, .ui-state-error .ui-icon { margin-top: -1px; }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background: url(icon_sprite.png) 0 0 no-repeat !important; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-tl { -moz-border-radius-topleft: 3px; -webkit-border-top-left-radius: 3px; border-top-left-radius: 3px; }
+.ui-corner-tr { -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 3px; border-top-right-radius: 3px; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 3px; -webkit-border-bottom-left-radius: 3px; border-bottom-left-radius: 3px; }
+.ui-corner-br { -moz-border-radius-bottomright: 3px; -webkit-border-bottom-right-radius: 3px; border-bottom-right-radius: 3px; }
+.ui-corner-top { -moz-border-radius-topleft: 3px; -webkit-border-top-left-radius: 3px; border-top-left-radius: 3px; -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 3px; border-top-right-radius: 3px; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 3px; -webkit-border-bottom-left-radius: 3px; border-bottom-left-radius: 3px; -moz-border-radius-bottomright: 3px; -webkit-border-bottom-right-radius: 3px; border-bottom-right-radius: 3px; }
+.ui-corner-right { -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 3px; border-top-right-radius: 3px; -moz-border-radius-bottomright: 3px; -webkit-border-bottom-right-radius: 3px; border-bottom-right-radius: 3px; }
+.ui-corner-left { -moz-border-radius-topleft: 3px; -webkit-border-top-left-radius: 3px; border-top-left-radius: 3px; -moz-border-radius-bottomleft: 3px; -webkit-border-bottom-left-radius: 3px; border-bottom-left-radius: 3px; }
+.ui-corner-all { -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #262b33; opacity: .70;filter:Alpha(Opacity=70); }
+.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #000000; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*
+ * jQuery UI Resizable 1.8.7
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Resizable#theming
+ */
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute; font-size: 0.1px; z-index: 999; display: block;}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*
+ * jQuery UI Selectable 1.8.7
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Selectable#theming
+ */
+.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
+/*
+ * jQuery UI Accordion 1.8.7
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Accordion#theming
+ */
+/* IE/Win - Fix animation bug - #4615 */
+.ui-accordion { width: 100%; }
+.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
+.ui-accordion .ui-accordion-header, .ui-accordion .ui-accordion-content { -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; }
+.ui-accordion .ui-accordion-li-fix { display: inline; }
+.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
+.ui-accordion .ui-accordion-header a { display: block; font-size: 12px; font-weight: bold; padding: .5em .5em .5em .7em; }
+.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
+.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
+.ui-accordion .ui-accordion-content-active { display: block; }/*
+ * jQuery UI Autocomplete 1.8.7
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Autocomplete#theming
+ */
+.ui-autocomplete {
+ position: absolute; cursor: default; z-index: 3;
+ -moz-border-radius: 0;
+ -webkit-border-radius: 0;
+ border-radius: 0;
+ -moz-box-shadow: 0 1px 5px rgba(0,0,0,0.3);
+ -webkit-box-shadow: 0 1px 5px rgba(0,0,0,0.3);
+ box-shadow: 0 1px 5px rgba(0,0,0,0.3);
+}
+
+/* workarounds */
+* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
+
+/*
+ * jQuery UI Menu 1.8.7
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Menu#theming
+ */
+.ui-menu {
+ list-style:none;
+ padding: 2px;
+ margin: 0;
+ display:block;
+ float: left;
+}
+.ui-menu .ui-menu {
+ margin-top: -3px;
+}
+.ui-menu .ui-menu-item {
+ margin:0;
+ padding: 0;
+ zoom: 1;
+ float: left;
+ clear: left;
+ width: 100%;
+}
+.ui-menu .ui-menu-item a {
+ text-decoration:none;
+ display:block;
+ padding:.2em .4em;
+ line-height:1.5;
+ zoom:1;
+}
+.ui-menu .ui-menu-item a.ui-state-hover,
+.ui-menu .ui-menu-item a.ui-state-active {
+ font-weight: normal;
+ margin: -1px;
+ background: #5f83b9;
+ color: #FFFFFF;
+ text-shadow: 0px 1px 1px #234386;
+ border-color: #466086;
+ -moz-border-radius: 0;
+ -webkit-border-radius: 0;
+ border-radius: 0;
+}
+/*
+ * jQuery UI Button 1.8.7
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Button#theming
+ */
+.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; -webkit-user-select: none; -moz-user-select: none; user-select: none; } /* the overflow property removes extra width in IE */
+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
+.ui-button-icons-only { width: 3.4em; }
+button.ui-button-icons-only { width: 3.7em; }
+
+/* button animation properties */
+.ui-button {
+ -webkit-transition: all 250ms ease-in-out;
+ -moz-transition: all 250ms ease-in-out;
+ -o-transition: all 250ms ease-in-out;
+ transition: all 250ms ease-in-out;
+}
+
+/*states*/
+.ui-button.ui-state-hover {
+ -moz-box-shadow: 0 0 8px rgba(0, 0, 0, 0.15), 0 1px 0 rgba(255,255,255,0.8) inset;
+ -webkit-box-shadow: 0 0 8px rgba(0, 0, 0, 0.15), 0 1px 0 rgba(255,255,255,0.8) inset;
+ box-shadow: 0 0 8px rgba(0, 0, 0, 0.15), 0 1px 0 rgba(255,255,255,0.8) inset;
+}
+.ui-button.ui-state-focus {
+ outline: none;
+ color: #1c4257;
+ border-color: #7096ab;
+ background: #ededed url(bg_fallback.png) 0 -50px repeat-x; /* Old browsers */
+ background: -moz-linear-gradient(top, #b9e0f5 0%, #92bdd6 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b9e0f5), color-stop(100%,#92bdd6)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #b9e0f5 0%,#92bdd6 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #b9e0f5 0%,#92bdd6 100%); /* Opera11.10+ */
+ background: -ms-linear-gradient(top, #b9e0f5 0%,#92bdd6 100%); /* IE10+ */
+ background: linear-gradient(top, #b9e0f5 0%,#92bdd6 100%); /* W3C */
+ -moz-box-shadow: 0 0 8px rgba(0, 0, 0, 0.15), 0 1px 0 rgba(255,255,255,0.8) inset;
+ -webkit-box-shadow: 0 0 8px rgba(0, 0, 0, 0.15), 0 1px 0 rgba(255,255,255,0.8) inset;
+ box-shadow: 0 0 8px rgba(0, 0, 0, 0.15), 0 1px 0 rgba(255,255,255,0.8) inset;
+}
+
+/*button text element */
+.ui-button .ui-button-text { display: block; line-height: 1.4; font-size: 14px; font-weight: bold; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.6); }
+.ui-button-text-only .ui-button-text { padding: .4em 1em; }
+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
+.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
+.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
+/* no icon support for input elements, provide padding by default */
+input.ui-button, .ui-widget-content input.ui-button { font-size: 14px; font-weight: bold; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.6); padding: 0 1em !important; height: 33px; }
+/*remove submit button internal padding in Firefox*/
+input.ui-button::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+/* fix webkits handling of the box model */
+@media screen and (-webkit-min-device-pixel-ratio:0) {
+ input.ui-button {
+ height: 31px !important;
+ }
+}
+
+
+/*button icon element(s) */
+.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
+.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
+.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+
+/*button sets*/
+.ui-buttonset { margin-right: 7px; }
+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
+.ui-buttonset .ui-button.ui-state-active { color: #1c4257; border-color: #7096ab; }
+.ui-buttonset .ui-button.ui-state-active {
+ background: #ededed url(bg_fallback.png) 0 -50px repeat-x; /* Old browsers */
+ background: -moz-linear-gradient(top, #b9e0f5 0%, #92bdd6 100%); /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#b9e0f5), color-stop(100%,#92bdd6)); /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #b9e0f5 0%,#92bdd6 100%); /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #b9e0f5 0%,#92bdd6 100%); /* Opera11.10+ */
+ background: -ms-linear-gradient(top, #b9e0f5 0%,#92bdd6 100%); /* IE10+ */
+ background: linear-gradient(top, #b9e0f5 0%,#92bdd6 100%); /* W3C */
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+}
+
+/* workarounds */
+button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
+/*
+ * jQuery UI Dialog 1.8.7
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Dialog#theming
+ */
+.ui-dialog { position: absolute; padding: 0; width: 300px; overflow: hidden; }
+.ui-dialog {
+ -webkit-box-shadow: 0 2px 12px rgba(0,0,0,0.6);
+ -moz-box-shadow: 0 2px 12px rgba(0,0,0,0.6);
+ box-shadow: 0 2px 12px rgba(0,0,0,0.6);
+}
+.ui-dialog .ui-dialog-titlebar { padding: 0.7em 1em 0.6em 1em; position: relative; border: none; border-bottom: 1px solid #979797; -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; font-size: 14px; text-shadow: 0 1px 0 rgba(255,255,255,0.5); }
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .8em; top: 55%; width: 16px; margin: -10px 0 0 0; padding: 0; height: 16px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; background: url(icon_sprite.png) 0 -16px no-repeat; }
+.ui-dialog .ui-dialog-titlebar-close:hover span { background-position: -16px -16px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; border: 0; }
+.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
+.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
+/*
+ * jQuery UI Slider 1.8.7
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Slider#theming
+ */
+.ui-slider { position: relative; text-align: left; background: #d7d7d7; z-index: 1; }
+.ui-slider { -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; }
+.ui-slider .ui-slider-handle { background: url(slider_handles.png) 0px -23px no-repeat; position: absolute; z-index: 2; width: 23px; height: 23px; cursor: default; border: none; outline: none; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; }
+.ui-slider .ui-state-hover, .ui-slider .ui-state-active { background-position: 0 0; }
+.ui-slider .ui-slider-range { background: #a3cae0; position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
+.ui-slider .ui-slider-range { -moz-box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; -webkit-box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; }
+
+
+.ui-slider-horizontal { height: 5px; }
+.ui-slider-horizontal .ui-slider-handle { top: -8px; margin-left: -13px; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: 5px; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -8px; margin-left: 0; margin-bottom: -13px; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }/*
+ * jQuery UI Tabs 1.8.7
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Tabs#theming
+ */
+.ui-tabs { position: relative; zoom: 1; border: 0; background: transparent; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+.ui-tabs .ui-tabs-nav { margin: 0; padding: 0; background: transparent; border-width: 0 0 1px 0; }
+.ui-tabs .ui-tabs-nav {
+ -moz-border-radius: 0;
+ -webkit-border-radius: 0;
+ border-radius: 0;
+}
+.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
+.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; font-size: 12px; font-weight: bold; text-shadow: 0 1px 0 rgba(255,255,255,0.5); }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; background: #fff; border-color: #B6B6B6; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; outline: none; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { display: block; border-width: 0 1px 1px 1px; padding: 1em 1.4em; background: none; }
+.ui-tabs .ui-tabs-panel { background: #FFF;
+ -moz-border-radius: 0;
+ -webkit-border-radius: 0;
+ border-radius: 0;
+}
+.ui-tabs .ui-tabs-hide { display: none !important; }
+/*
+ * jQuery UI Datepicker 1.8.7
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Datepicker#theming
+ */
+.ui-datepicker { width: 17em; padding: 0; display: none; border-color: #DDDDDD; }
+.ui-datepicker {
+ -moz-box-shadow: 0 4px 8px rgba(0,0,0,0.5);
+ -webkit-box-shadow: 0 4px 8px rgba(0,0,0,0.5);
+ box-shadow: 0 4px 8px rgba(0,0,0,0.5);
+}
+.ui-datepicker .ui-datepicker-header { position:relative; padding:.35em 0; border: none; border-bottom: 1px solid #B6B6B6; -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; }
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 6px; width: 1.8em; height: 1.8em; }
+.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { border: 1px none; }
+.ui-datepicker .ui-datepicker-prev { left:2px; }
+.ui-datepicker .ui-datepicker-next { right:2px; }
+.ui-datepicker .ui-datepicker-prev span { background-position: 0px -32px !important; }
+.ui-datepicker .ui-datepicker-next span { background-position: -16px -32px !important; }
+.ui-datepicker .ui-datepicker-prev-hover span { background-position: 0px -48px !important; }
+.ui-datepicker .ui-datepicker-next-hover span { background-position: -16px -48px !important; }
+.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; background: url(icon_sprite.png) no-repeat; }
+.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; font-size: 12px; text-shadow: 0 1px 0 rgba(255,255,255,0.6); }
+.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year { width: 49%;}
+.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
+.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
+.ui-datepicker td { border: 0; padding: 1px; }
+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
+.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
+.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
+.ui-datepicker table .ui-state-highlight { border-color: #5F83B9; }
+.ui-datepicker table .ui-state-hover { background: #5F83B9; color: #FFF; font-weight: bold; text-shadow: 0 1px 1px #234386; -webkit-box-shadow: 0 0px 0 rgba(255,255,255,0.6) inset; -moz-box-shadow: 0 0px 0 rgba(255,255,255,0.6) inset; box-shadow: 0 0px 0 rgba(255,255,255,0.6) inset; border-color: #5F83B9; }
+.ui-datepicker-calendar .ui-state-default { background: transparent; border-color: #FFF; }
+.ui-datepicker-calendar .ui-state-active { background: #5F83B9; border-color: #5F83B9; color: #FFF; font-weight: bold; text-shadow: 0 1px 1px #234386; }
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi { width:auto; }
+.ui-datepicker-multi .ui-datepicker-group { float:left; }
+.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
+.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
+.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
+.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
+.ui-datepicker-row-break { clear:both; width:100%; }
+
+/* RTL support */
+.ui-datepicker-rtl { direction: rtl; }
+.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+
+/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
+.ui-datepicker-cover {
+ display: none; /*sorry for IE5*/
+ display/**/: block; /*sorry for IE5*/
+ position: absolute; /*must have*/
+ z-index: -1; /*must have*/
+ filter: mask(); /*must have*/
+ top: -4px; /*must have*/
+ left: -4px; /*must have*/
+ width: 200px; /*must have*/
+ height: 200px; /*must have*/
+}/*
+ * jQuery UI Progressbar 1.8.7
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Progressbar#theming
+ */
+.ui-progressbar { height: 12px; text-align: left; background: #FFF url(progress_bar.gif) 0 -14px repeat-x; }
+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; background: url(progress_bar.gif) 0 0 repeat-x; }
+
+/* Extra Input Field Styling */
+.ui-form textarea, .ui-form input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]) {
+ padding: 3px;
+ -webkit-border-radius: 2px;
+ -moz-border-radius: 2px;
+ border-radius: 2px;
+ border: 1px solid #cecece;
+ outline: none;
+ -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.1) inset, 0 1px 0 rgba(255,255,255,0.2);
+ -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.1) inset, 0 1px 0 rgba(255,255,255,0.2);
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1) inset, 0 1px 0 rgba(255,255,255,0.2);
+ -webkit-transition: all 250ms ease-in-out;
+ -moz-transition: all 250ms ease-in-out;
+ -o-transition: all 250ms ease-in-out;
+ transition: all 250ms ease-in-out;
+}
+.ui-form textarea:hover, .ui-form input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):hover {
+ border: 1px solid #bdbdbd;
+ -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.2) inset, 0 1px 0 rgba(255,255,255,0.2);
+ -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.2) inset, 0 1px 0 rgba(255,255,255,0.2);
+ box-shadow: 0 1px 3px rgba(0,0,0,0.2) inset, 0 1px 0 rgba(255,255,255,0.2);
+}
+.ui-form textarea:focus, .ui-form input:not([type="submit"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):focus {
+ border: 1px solid #95bdd4;
+ -webkit-box-shadow: 0 2px 3px rgba(161,202,226,0.5) inset, 0 1px 0 rgba(255,255,255,0.2);
+ -moz-box-shadow: 0 2px 3px rgba(161,202,226,0.5) inset, 0 1px 0 rgba(255,255,255,0.2);
+ box-shadow: 0 2px 3px rgba(161,202,226,0.5) inset, 0 1px 0 rgba(255,255,255,0.2);
+}