diff options
author | Raffael Schmid <raf@nine.ch> | 2014-01-23 10:55:26 +0100 |
---|---|---|
committer | Raffael Schmid <raf@nine.ch> | 2014-01-23 10:55:26 +0100 |
commit | 7863319b97498a7621815cfe5691794ecb86b8c5 (patch) | |
tree | 5ae991fe7543bcb91e9257242e87849538b33214 | |
parent | 568d1c27c5a1b4d6749943240cdba2625eee2b6e (diff) | |
parent | 68590fddd860c5d840d8f04314ed11f0d02ddd44 (diff) | |
download | gitlab-ce-7863319b97498a7621815cfe5691794ecb86b8c5.tar.gz |
Merge branch 'master' into dont-depend-on-appid-and-appsecret
* master: (238 commits)
Version 6.5.1
Fix selectbox when submit MR from fork to origin
Fix HELP layout
No need for code tag here.
Spelling mistake and add links.
Warn against RVM.
Remove GitHub mention because we also have a GitLab issue tracker now.
Replace 6.0-to-6.4.md with 6.0-to-6.5.md
Add public assets to gitignore
Version 6.5.0
Use 6-5 branch in installation docs
Remove deprecated twitter handle.
Further explain userPrincipalName settings
Update from 6.4 to 6.5 guide
Explain how to use AD userPrincipalName for logins
More entries to CHANGELOG. Version to rc1
Rephrase LDAP check script output
add O'Reilly sponsorship in CHANGELOG
Fix select2 css for drop above style
Rename "Website url" labels to "Website"
...
403 files changed, 3554 insertions, 3020 deletions
diff --git a/.gitignore b/.gitignore index 084edd30df7..4c25c8abf82 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ doc/code/* .secret *.log public/uploads.* +public/assets/ diff --git a/CHANGELOG b/CHANGELOG index 01dbcc3c688..2e5cd78c8a8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,13 +1,28 @@ +v 6.5.1 + - Fix branch selectbox when create merge request from fork + v 6.5.0 - Dropdown menus on issue#show page for assignee and milestone (Jason Blanchard) - Add color custimization and previewing to broadcast messages - Fixed notes anchors - Load new comments in issues dynamically - Added sort options to Public page - - Added new filters(assigned/authored/all) to Dashboard#issues, Dashboard#merge_request pages + - New filters (assigned/authored/all) for Dashboard#issues/merge_requests (sponsored by Say Media) - Add project visibility icons to dashboard - Enable secure cookies if https used - Protect users/confirmation with rack_attack + - Default HTTP headers to protect against MIME-sniffing, force https if enabled + - Bootstrap 3 with responsive UI + - New repository download formats: tar.bz2, zip, tar (Jason Hollingsworth) + - Restyled accept widgets for MR + - SCSS refactored + - Use jquery timeago plugin + - Fix 500 error for rdoc files + - Ability to customize merge commit message (sponsored by Say Media) + - Search autocomplete via ajax + - Add website url to user profile + - Files API supports base64 encoded content (sponsored by O'Reilly Media) + - Added support for Go's repository retrieval (Bruno Albuquerque) v6.4.3 - Don't use unicorn worker killer if PhusionPassenger is defined diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 778018d25ef..cb5c218920d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,11 +1,6 @@ # Contribute to GitLab -This guide details how to use issues and pull requests to improve GitLab. - -- [Closing policy for issues and pull requests](#closing-policy-for-issues-and-pull-requests) -- [Issue tracker](#issue-tracker) -- [Pull requests](#pull-requests) -- [Security vulnerabilities](#security-vulnerabilities) +This guide details how contribute to GitLab. If you want to know how the GitLab team handles contributions have a look at [the GitLab contributing process](PROCESS.md). @@ -17,30 +12,30 @@ By submitting code as an individual you agree to the [individual contributor lic Please report suspected security vulnerabilities in private to support@gitlab.com, also see the [disclosure section on the GitLab.com website](http://www.gitlab.com/disclosure/). Please do NOT create publicly viewable issues for suspected security vulnerabilities. -## Closing policy for issues and pull requests +## Closing policy for issues and merge requests -GitLab is a popular open source project and the capacity to deal with issues and pull requests is limited. Out of respect for our volunteers, issues and pull requests not in line with the guidelines listed in this document may be closed without notice. +GitLab is a popular open source project and the capacity to deal with issues and merge requests is limited. Out of respect for our volunteers, issues and merge requests not in line with the guidelines listed in this document may be closed without notice. Please treat our volunteers with courtesy and respect, it will go a long way towards getting your issue resolved. -Issues and pull requests should be in English and contain appropriate language for audiences of all ages. +Issues and merge requests should be in English and contain appropriate language for audiences of all ages. ## Issue tracker -To get support for your particular problem please use the channels as detailed in [the getting help section of the readme](https://github.com/gitlabhq/gitlabhq#getting-help). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/). +To get support for your particular problem please use the channels as detailed in the getting help section of [the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/). -The [issue tracker](https://github.com/gitlabhq/gitlabhq/issues) is only for obvious bugs or misbehavior in the latest [stable or development release of GitLab](MAINTENANCE.md). When submitting an issue please conform to the issue submission guidelines listed below. Not all issues will be addressed and your issue is more likely to be addressed if you submit a pull request which partially or fully addresses the issue. +The [issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues) is only for obvious bugs or misbehavior in the latest [stable or development release of GitLab](MAINTENANCE.md). When submitting an issue please conform to the issue submission guidelines listed below. Not all issues will be addressed and your issue is more likely to be addressed if you submit a merge request which partially or fully addresses the issue. Do not use the issue tracker for feature requests. We have a specific [feedback and suggestions forum](http://feedback.gitlab.com) for this purpose. -Please send a pull request with a tested solution or a pull request with a failing test instead of opening an issue if you can. If you're unsure where to post, post to the [mailing list](https://groups.google.com/forum/#!forum/gitlabhq) or [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) first. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there. +Please send a merge request with a tested solution or a merge request with a failing test instead of opening an issue if you can. If you're unsure where to post, post to the [mailing list](https://groups.google.com/forum/#!forum/gitlabhq) or [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) first. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there. ### Issue tracker guidelines -**[Search](https://github.com/gitlabhq/gitlabhq/search?q=&ref=cmdform&type=Issues)** for similar entries before submitting your own, there's a good chance somebody else had the same issue. Show your support with `:+1:` and/or join the discussion. Please submit issues in the following format (as the first post): +**[Search the issues](https://gitlab.com/gitlab-org/gitlab-ce/issues)** for similar entries before submitting your own, there's a good chance somebody else had the same issue. Show your support with `:+1:` and/or join the discussion. Please submit issues in the following format (as the first post): 1. **Summary:** Summarize your issue in one sentence (what goes wrong, what did you expect to happen) -2. **Steps to reproduce:** How can we reproduce the issue, preferably on the [GitLab Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm) (start with: `vagrant destroy && vagrant up && vagrant ssh`) +2. **Steps to reproduce:** How can we reproduce the issue, preferably on the [GitLab development virtual machine with vagrant](https://gitlab.com/gitlab-org/cookbook-gitlab/blob/master/doc/development.md) (start your issue with: `vagrant destroy && vagrant up && vagrant ssh`) 3. **Expected behavior:** Describe your issue in detail 4. **Observed behavior** 5. **Relevant logs and/or screenshots:** Please use code blocks (\`\`\`) to format console output, logs, and code as it's very hard to read otherwise. @@ -51,37 +46,39 @@ Please send a pull request with a tested solution or a pull request with a faili * Describe your setup (use relevant parts from `sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`) 7. **Possible fixes**: If you can, link to the line of code that might be responsible for the problem -## Pull requests +## Merge requests -We welcome pull requests with fixes and improvements to GitLab code, tests, and/or documentation. The features we would really like a pull request for are listed with the [status 'accepting merge/pull requests' on our feedback forum](http://feedback.gitlab.com/forums/176466-general/status/796455) but other improvements are also welcome. +We welcome merge requests with fixes and improvements to GitLab code, tests, and/or documentation. The features we would really like a merge request for are listed with the [status 'accepting merge/merge requests' on our feedback forum](http://feedback.gitlab.com/forums/176466-general/status/796455) but other improvements are also welcome. -### Pull request guidelines +### Merge request guidelines -If you can, please submit a pull request with the fix or improvements including tests. If you don't know how to fix the issue but can write a test that exposes the issue we will accept that as well. In general bug fixes that include a regression test are merged quickly while new features without proper tests are least likely to receive timely feedback. The workflow to make a pull request is as follows: +If you can, please submit a merge request with the fix or improvements including tests. If you don't know how to fix the issue but can write a test that exposes the issue we will accept that as well. In general bug fixes that include a regression test are merged quickly while new features without proper tests are least likely to receive timely feedback. The workflow to make a merge request is as follows: -1. Fork the project on GitHub +1. Fork the project on GitLab Cloud 1. Create a feature branch 1. Write [tests](README.md#run-the-tests) and code 1. Add your changes to the [CHANGELOG](CHANGELOG) 1. If you have multiple commits please combine them into one commit by [squashing them](http://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits) 1. Push the commit to your fork -1. Submit a pull request (PR) -1. The PR title should describes the change you want to make -1. The PR description should give a motive for your change and the method you used to achieve it -* If the PR changes the UI it should include before and after screenshots -1. [Search for issues](https://github.com/gitlabhq/gitlabhq/search?q=&ref=cmdform&type=Issues) related to your pull request and mention them in the pull request description - -Please keep the change in a single PR as small as possible. If you want to contribute a large feature think very hard what the minimum viable change is. Can you split functionality? Can you only submit the backend/API code? Can you start with a very simple UI? The smaller a PR is the more likely it is it will be merged, after that you can send more PR's to enhance it. - -We will accept pull requests if: - -* The code has proper tests and all tests pass (or it is a test exposing a failure in existing code) -* It can be merged without problems (if not please use: `git rebase master`) -* It does not break any existing functionality -* It's quality code that conforms to the [Ruby](https://github.com/bbatsov/ruby-style-guide) and [Rails](https://github.com/bbatsov/rails-style-guide) style guides and best practices -* It is not a catch all pull request but rather fixes a specific issue or implements a specific feature -* It keeps the GitLab code base clean and well structured -* We think other users will benefit from the same functionality -* It is a single commit (please use `git rebase -i` to squash commits) - -For examples of feedback on pull requests please look at already [closed pull requests](https://github.com/gitlabhq/gitlabhq/pulls?direction=desc&page=1&sort=created&state=closed). +1. Submit a merge request (MR) +1. The MR title should describes the change you want to make +1. The MR description should give a motive for your change and the method you used to achieve it +1. If the MR changes the UI it should include before and after screenshots +1. Link relevant [issues](https://gitlab.com/gitlab-org/gitlab-ce/issues) and/or [feedback items](http://feedback.gitlab.com/) from the merge request description and leave a comment on them with a link back to the MR +1. Be prepared to answer questions and incorporate feedback even if requests for this arrive weeks or months after your MR submittion + +Please keep the change in a single MR as small as possible. If you want to contribute a large feature think very hard what the minimum viable change is. Can you split functionality? Can you only submit the backend/API code? Can you start with a very simple UI? The smaller a MR is the more likely it is it will be merged, after that you can send more MR's to enhance it. + +We will accept a merge requests if it: + +* Includes proper tests and all tests pass (unless it contains a test exposing a bug in existing code) +* Can be merged without problems (if not please use: `git rebase master`) +* Do not break any existing functionality +* Conforms to the [Ruby](https://github.com/bbatsov/ruby-style-guide) and [Rails](https://github.com/bbatsov/rails-style-guide) style guides and best practices +* Fixes one specific issue or implements one specific feature (do not combine things, send separate merge requests if needed) +* Keeps the GitLab code base clean and well structured +* Contains functionality we think other users will benefit from too +* Doesn't add unnessecary configuration options since they complicate future changes +* Contains a single commit (please use `git rebase -i` to squash commits) + +For examples of feedback on merge requests please look at already [closed merge requests](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests?assignee_id=&label_name=&milestone_id=&scope=&sort=&state=closed). @@ -14,7 +14,6 @@ gem "protected_attributes" gem 'rails-observers' gem 'actionpack-page_caching' gem 'actionpack-action_caching' -gem 'activerecord-deprecated_finders' # Supported DBs gem "mysql2", group: :mysql @@ -52,6 +51,9 @@ gem "grape", "~> 0.6.1" gem "grape-entity", "~> 0.3.0" gem 'rack-cors', require: 'rack/cors' +# Email validation +gem "email_validator", "~> 1.4.0", :require => 'email_validator/strict' + # Format dates and times # based on human-friendly examples gem "stamp" @@ -60,7 +62,7 @@ gem "stamp" gem 'enumerize' # Pagination -gem "kaminari", "~> 0.14.1" +gem "kaminari", "~> 0.15.1" # HAML gem "haml-rails" @@ -120,7 +122,7 @@ gem "redis-rails" gem 'tinder', '~> 1.9.2' # HipChat integration -gem "hipchat", "~> 0.9.0" +gem "hipchat", "~> 0.14.0" # Flowdock integration gem "gitlab-flowdock-git-hook", "~> 0.4.2" @@ -144,17 +146,16 @@ gem "therubyracer" gem 'turbolinks' gem 'jquery-turbolinks' -gem 'chosen-rails', "1.0.1" gem 'select2-rails' gem 'jquery-atwho-rails', "~> 0.3.3" gem "jquery-rails", "2.1.3" gem "jquery-ui-rails", "2.0.2" gem "modernizr", "2.6.2" gem "raphael-rails", "~> 2.1.2" -gem 'bootstrap-sass', '~> 2.3' +gem 'bootstrap-sass', '~> 3.0' gem "font-awesome-rails", '~> 3.2' gem "gemoji", "~> 1.3.0" -gem "gon", git: "https://github.com/gitlabhq/gon.git", ref: '58ca8e17273051cb370182cabd3602d1da6783ab' +gem "gon", '~> 5.0.0' group :development do gem "annotate", "~> 2.6.0.beta2" diff --git a/Gemfile.lock b/Gemfile.lock index 7948f3fb5bc..2c821a9b907 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,13 +1,4 @@ GIT - remote: https://github.com/gitlabhq/gon.git - revision: 58ca8e17273051cb370182cabd3602d1da6783ab - ref: 58ca8e17273051cb370182cabd3602d1da6783ab - specs: - gon (4.1.1) - actionpack (>= 2.3.0) - json - -GIT remote: https://github.com/gitlabhq/markup.git revision: 61ade389c1e1c159359338f570d18464a44ddbc4 ref: 61ade389c1e1c159359338f570d18464a44ddbc4 @@ -64,7 +55,7 @@ GEM erubis (>= 2.6.6) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) - bootstrap-sass (2.3.2.2) + bootstrap-sass (3.0.3.0) sass (~> 3.2) builder (3.1.4) capybara (2.1.0) @@ -80,12 +71,6 @@ GEM celluloid (0.15.2) timers (~> 1.1.0) charlock_holmes (0.6.9.4) - chosen-rails (1.0.1) - coffee-rails (>= 3.2) - compass-rails (>= 1.0) - railties (>= 3.0) - sass-rails (>= 3.2) - chunky_png (1.2.9) cliver (0.2.2) code_analyzer (0.4.3) sexp_processor @@ -101,12 +86,6 @@ GEM coffee-script-source (1.6.3) colored (1.2) colorize (0.5.8) - compass (0.12.2) - chunky_png (~> 1.2) - fssm (>= 0.2.7) - sass (~> 3.1) - compass-rails (1.1.1) - compass (>= 0.12.2) connection_pool (1.2.0) coveralls (0.7.0) multi_json (~> 1.3) @@ -135,6 +114,8 @@ GEM email_spec (1.5.0) launchy (~> 2.1) mail (~> 2.2) + email_validator (1.4.0) + activemodel enumerize (0.7.0) activesupport (>= 3.2) equalizer (0.0.8) @@ -170,7 +151,6 @@ GEM dotenv (>= 0.7) thor (>= 0.13.6) formatador (0.2.4) - fssm (0.2.10) gemoji (1.3.1) gherkin-ruby (0.3.1) racc @@ -212,6 +192,9 @@ GEM omniauth (~> 1.0) pyu-ruby-sasl (~> 0.0.3.1) rubyntlm (~> 0.1.1) + gon (5.0.1) + actionpack (>= 2.3.0) + json grape (0.6.1) activesupport builder @@ -247,7 +230,7 @@ GEM railties (~> 4.0.0) hashie (2.0.5) hike (1.2.3) - hipchat (0.9.0) + hipchat (0.14.0) httparty httparty http_parser.rb (0.5.3) @@ -276,7 +259,7 @@ GEM json (1.8.1) jwt (0.1.8) multi_json (>= 1.5) - kaminari (0.14.1) + kaminari (0.15.1) actionpack (>= 3.0.0) activesupport (>= 3.0.0) kgio (2.8.1) @@ -298,7 +281,7 @@ GEM minitest (4.7.5) modernizr (2.6.2) sprockets (~> 2.0) - multi_json (1.8.2) + multi_json (1.8.4) multi_xml (0.5.5) multipart-post (1.2.0) mysql2 (0.3.11) @@ -568,17 +551,15 @@ PLATFORMS DEPENDENCIES actionpack-action_caching actionpack-page_caching - activerecord-deprecated_finders acts-as-taggable-on annotate (~> 2.6.0.beta2) asciidoctor awesome_print better_errors binding_of_caller - bootstrap-sass (~> 2.3) + bootstrap-sass (~> 3.0) capybara carrierwave - chosen-rails (= 1.0.1) coffee-rails colored coveralls @@ -587,6 +568,7 @@ DEPENDENCIES devise (= 3.0.4) devise-async (= 0.8.0) email_spec + email_validator (~> 1.4.0) enumerize factory_girl_rails ffaker @@ -603,21 +585,21 @@ DEPENDENCIES gitlab_git (~> 4.0.0) gitlab_meta (= 6.0) gitlab_omniauth-ldap (= 1.0.3) - gon! + gon (~> 5.0.0) grape (~> 0.6.1) grape-entity (~> 0.3.0) growl guard-rspec guard-spinach haml-rails - hipchat (~> 0.9.0) + hipchat (~> 0.14.0) httparty jasmine (= 2.0.0.rc5) jquery-atwho-rails (~> 0.3.3) jquery-rails (= 2.1.3) jquery-turbolinks jquery-ui-rails (= 2.0.2) - kaminari (~> 0.14.1) + kaminari (~> 0.15.1) launchy letter_opener minitest (~> 4.7.0) diff --git a/PROCESS.md b/PROCESS.md index 668cacc870a..bf757025c40 100644 --- a/PROCESS.md +++ b/PROCESS.md @@ -8,25 +8,25 @@ Below we describe the contributing process to GitLab for two reasons. So that co ### Issue team - Looks for issues without workflow labels and triages issue -- Monitors pull requests -- Closes invalid issues and pull requests with a comment (duplicates, [feature requests](#feature-requests), [fixed in newer version](#issue-fixed-in-newer-version), [issue report for old version](#issue-report-for-old-version), not a problem in GitLab, etc.) +- Monitors merge requests +- Closes invalid issues and merge requests with a comment (duplicates, [feature requests](#feature-requests), [fixed in newer version](#issue-fixed-in-newer-version), [issue report for old version](#issue-report-for-old-version), not a problem in GitLab, etc.) - Assigns appropriate [labels](#how-we-handle-issues) -- Asks for feedback from issue reporter/pull request initiator ([invalid issue reports](#improperly-formatted-issue), [format code](#code-format), etc.) +- Asks for feedback from issue reporter/merge request initiator ([invalid issue reports](#improperly-formatted-issue), [format code](#code-format), etc.) - Asks for feedback from the relevant developer(s) based on the [list of members and their specialities](http://gitlab.org/team/) -- Monitors all issues/pull requests for feedback (but especially ones commented on since automatically watching them): +- Monitors all issues/merge requests for feedback (but especially ones commented on since automatically watching them): - Closes issues with no feedback from the reporter for two weeks -- Closes stale pull requests +- Closes stale merge requests ### Development team -- Responds to issues and pull requests the issue team mentions them in +- Responds to issues and merge requests the issue team mentions them in - Monitors for new issues in _Awaiting developer action/feedback_ with no developer activity (once a week) -- Monitors for new pull requests (at least once a week) -- Manages their work queue by looking at issues and pull requests assigned to them +- Monitors for new merge requests (at least once a week) +- Manages their work queue by looking at issues and merge requests assigned to them - Close fixed issues (via commit messages or manually) - Codes [new features](http://feedback.gitlab.com/forums/176466-general/filters/top)! - Response guidelines -- Be kind to people trying to contribute. Be aware that people can be a non-native or a native English speaker, they might not understand thing or they might be very sensitive to how your word things. Use emoji to express your feelings (heart, star, smile, etc.). Some good tips about giving feedback to pull requests is in the [Thoughtbot code review guide](https://github.com/thoughtbot/guides/tree/master/code-review). +- Be kind to people trying to contribute. Be aware that people can be a non-native or a native English speaker, they might not understand thing or they might be very sensitive to how your word things. Use emoji to express your feelings (heart, star, smile, etc.). Some good tips about giving feedback to merge requests is in the [Thoughtbot code review guide](https://github.com/thoughtbot/guides/tree/master/code-review). ## Priorities of the issue team @@ -45,8 +45,8 @@ Workflow labels are purposely not very detailed since that would be hard to keep - _Awaiting feedback_: Feedback pending from the reporter - _Awaiting confirmation of fix_: The issue should already be solved in **master** (generally you can avoid this workflow item and just close the issue right away) -- _Attached PR_: There is a PR attached and the discussion should happen there - - We need to let issues stay in sync with the PR's. We can do this with a "Closing #XXXX" or "Fixes #XXXX" comment in the PR. We can't close the issue when there is a pull request because sometimes a PR is not good and we just close the PR, then the issue must stay. +- _Attached MR_: There is a MR attached and the discussion should happen there + - We need to let issues stay in sync with the MR's. We can do this with a "Closing #XXXX" or "Fixes #XXXX" comment in the MR. We can't close the issue when there is a merge request because sometimes a MR is not good and we just close the MR, then the issue must stay. - _Awaiting developer action/feedback_: Issue needs to be fixed or clarified by a developer ## Functional labels @@ -59,7 +59,7 @@ If an issue is complex and needs the attention of a specific person, assignment ## Label colors - Light orange `#fef2c0`: workflow labels for issue team members (awaiting feedback, awaiting confirmation of fix) -- Bright orange `#eb6420`: workflow labels for core team members (attached PR, awaiting developer action/feedback) +- Bright orange `#eb6420`: workflow labels for core team members (attached MR, awaiting developer action/feedback) - Light blue `#82C5FF`: functional labels - Green labels `#009800`: issues that can generally be ignored. For example, issues given the following labels normally can be closed immediately: - Feature request (see copy & paste response: [Feature requests](#feature-requests)) @@ -69,19 +69,19 @@ If an issue is complex and needs the attention of a specific person, assignment ### Improperly formatted issue -Thanks for the issue report. Please reformat your issue to conform to the issue tracker guidelines found in our \[contributing guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md#issue-tracker-guidelines). +Thanks for the issue report. Please reformat your issue to conform to the issue tracker guidelines found in our \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker-guidelines). ### Feature requests -Thanks for your interest in GitLab. We don't use the GitHub issue tracker for feature requests. Please use http://feedback.gitlab.com/ for this purpose or create a pull request implementing this feature. Have a look at the \[contribution guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) for more information. +Thanks for your interest in GitLab. We don't use the issue tracker for feature requests. Please use http://feedback.gitlab.com/ for this purpose or create a merge request implementing this feature. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information. ### Issue report for old version -Thanks for the issue report but we only support issues for the latest stable version of GitLab. I'm closing this issue but if you still experience this problem in the latest stable version, please open a new issue (but also reference the old issue(s)). Make sure to also include the necessary debugging information conforming to the issue tracker guidelines found in our \[contributing guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md#issue-tracker-guidelines). +Thanks for the issue report but we only support issues for the latest stable version of GitLab. I'm closing this issue but if you still experience this problem in the latest stable version, please open a new issue (but also reference the old issue(s)). Make sure to also include the necessary debugging information conforming to the issue tracker guidelines found in our \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker-guidelines). ### Support requests and configuration questions -Thanks for your interest in GitLab. We don't use the GitHub issue tracker for support requests and configuration questions. Please use the \[support forum\]\(https://groups.google.com/forum/#!forum/gitlabhq), \[Stack Overflow\]\(http://stackoverflow.com/questions/tagged/gitlab), the unofficial #gitlab IRC channel on Freenode or the http://www.gitlab.com paid services for this purpose. Have a look at the \[contribution guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) for more information. +Thanks for your interest in GitLab. We don't use the issue tracker for support requests and configuration questions. Please use the \[support forum\]\(https://groups.google.com/forum/#!forum/gitlabhq), \[Stack Overflow\]\(http://stackoverflow.com/questions/tagged/gitlab), the unofficial #gitlab IRC channel on Freenode or the http://www.gitlab.com paid services for this purpose. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information. ### Code format @@ -89,17 +89,17 @@ Please use ``` to format console output, logs, and code as it's very hard to rea ### Issue fixed in newer version -Thanks for the issue report. This issue has already been fixed in newer versions of GitLab. Due to the size of this project and our limited resources we are only able to support the latest stable release as outlined in our \[contributing guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md#issue-tracker). In order to get this bug fix and enjoy many new features please \[upgrade\]\(http://blog.gitlab.org/). If you still experience issues at that time please open a new issue following our issue tracker guidelines found in the \[contributing guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md#issue-tracker-guidelines). +Thanks for the issue report. This issue has already been fixed in newer versions of GitLab. Due to the size of this project and our limited resources we are only able to support the latest stable release as outlined in our \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker). In order to get this bug fix and enjoy many new features please \[upgrade\]\(http://blog.gitlab.org/). If you still experience issues at that time please open a new issue following our issue tracker guidelines found in the \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker-guidelines). -### Improperly formatted pull request +### Improperly formatted merge request -Thanks for your interest in improving the GitLab codebase! Please update your pull request according to the \[contributing guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md#pull-request-guidelines). +Thanks for your interest in improving the GitLab codebase! Please update your merge request according to the \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#pull-request-guidelines). ### Inactivity close of an issue -It's been at least 2 weeks (and a new release) since we heard from you. I'm closing this issue but if you still experience this problem, please open a new issue (but also reference the old issue(s)). Make sure to also include the necessary debugging information conforming to the issue tracker guidelines found in our \[contributing guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md#issue-tracker-guidelines). +It's been at least 2 weeks (and a new release) since we heard from you. I'm closing this issue but if you still experience this problem, please open a new issue (but also reference the old issue(s)). Make sure to also include the necessary debugging information conforming to the issue tracker guidelines found in our \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker-guidelines). -### Inactivity close of a pull request +### Inactivity close of a merge request -This pull request has been closed because a request for more information has not been reacted to for more than 2 weeks. If you respond and conform to the pull request guidelines in our \[contributing guidelines\]\(https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md#pull-requests) we will reopen this pull request. +This merge request has been closed because a request for more information has not been reacted to for more than 2 weeks. If you respond and conform to the merge request guidelines in our \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#pull-requests) we will reopen this merge request. diff --git a/README.md b/README.md index fcf5fdeea99..0d5dfa8540a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## GitLab: self hosted Git management software - +  @@ -34,7 +34,7 @@ * [GitLab Enterprise Edition](https://www.gitlab.com/features/) offers additional features that are useful for larger organizations (100+ users). -* [GitLab CI](https://github.com/gitlabhq/gitlab-ci/blob/master/README.md) is a continuous integration (CI) server that is easy to integrate with GitLab. +* [GitLab CI](https://gitlab.com/gitlab-org/gitlab-ci/blob/master/README.md) is a continuous integration (CI) server that is easy to integrate with GitLab. ### Requirements @@ -62,7 +62,7 @@ #### Unofficial installation methods -* [GitLab recipes](https://github.com/gitlabhq/gitlab-recipes) repository with unofficial guides for using GitLab with different software (operating systems, webservers, etc.) than the official version. +* [GitLab recipes](https://gitlab.com/gitlab-org/gitlab-recipes/) repository with unofficial guides for using GitLab with different software (operating systems, webservers, etc.) than the official version. * [Installation guides](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Unofficial-Installation-Guides) public wiki with unofficial guides to install GitLab on different operating systems. @@ -145,13 +145,13 @@ or start each component separately * [Feedback and suggestions forum](http://feedback.gitlab.com) is the place to propose and discuss new features for GitLab. -* [Contributing guide](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) describes how to submit pull requests and issues. Pull requests and issues not in line with the guidelines in this document will be closed. +* [Contributing guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) describes how to submit merge requests and issues. Pull requests and issues not in line with the guidelines in this document will be closed. * [Support subscription](http://www.gitlab.com/subscription/) connects you to the knowledge of GitLab experts that will resolve your issues and answer your questions. * [Consultancy](http://www.gitlab.com/consultancy/) from the GitLab experts for installations, upgrades and customizations. -* [#gitlab IRC channel](http://www.freenode.net/) on Freenode to get in touch with other GitLab users and get help, it's managed by James Newton, Drew Blessing and Sam Gleske +* [#gitlab IRC channel](http://www.freenode.net/) on Freenode to get in touch with other GitLab users and get help, it's managed by James Newton (newton), Drew Blessing (dblessing), and Sam Gleske (sag47). * [Book](http://www.packtpub.com/gitlab-repository-management/book) written by GitLab enthusiast Jonathan M. Hethey is unofficial but it offers a good overview. @@ -1 +1 @@ -6.5.0.pre +6.5.1 diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 0767b82032d..aa2db1fc93c 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -19,7 +19,6 @@ //= require jquery.turbolinks //= require bootstrap //= require modernizr -//= require chosen-jquery //= require select2 //= require raphael //= require g.raphael-min diff --git a/app/assets/javascripts/behaviors/toggler_behavior.coffee b/app/assets/javascripts/behaviors/toggler_behavior.coffee index 7e438c51c1c..5afb656e696 100644 --- a/app/assets/javascripts/behaviors/toggler_behavior.coffee +++ b/app/assets/javascripts/behaviors/toggler_behavior.coffee @@ -3,7 +3,7 @@ $ -> container = $(@).closest(".js-toggler-container") container.toggleClass("on") - + $("body").on "click", ".js-toggle-visibility-link", (e) -> $(@).find('i'). toggleClass('icon-chevron-down'). @@ -11,7 +11,7 @@ $ -> container = $(".js-toggle-visibility-container") container.toggleClass("hide") e.preventDefault() - + $("body").on "click", ".js-toggle-button", (e) -> $(@).closest(".js-toggle-container").find(".js-toggle-content").toggle() e.preventDefault() diff --git a/app/assets/javascripts/branch-graph.js.coffee b/app/assets/javascripts/branch-graph.js.coffee index 318538509a5..dd09ee51fe0 100644 --- a/app/assets/javascripts/branch-graph.js.coffee +++ b/app/assets/javascripts/branch-graph.js.coffee @@ -194,11 +194,14 @@ class BranchGraph fill: @colors[commit.space] stroke: "none" ) - r.rect(@offsetX + @unitSpace * @mspace + 10, y - 10, 20, 20).attr( - fill: "url(#{commit.author.icon})" + + avatar_box_x = @offsetX + @unitSpace * @mspace + 10 + avatar_box_y = y - 10 + r.rect(avatar_box_x, avatar_box_y, 20, 20).attr( stroke: @colors[commit.space] "stroke-width": 2 ) + r.image(commit.author.icon, avatar_box_x, avatar_box_y, 20, 20) r.text(@offsetX + @unitSpace * @mspace + 35, y, commit.message.split("\n")[0]).attr( "text-anchor": "start" font: "14px Monaco, monospace" diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index e264e281309..8ea302f256a 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -47,5 +47,9 @@ class Dispatcher initSearch: -> - autocomplete_json = $('.search-autocomplete-json').data('autocomplete-opts') - new SearchAutocomplete(autocomplete_json) + opts = $('.search-autocomplete-opts') + path = opts.data('autocomplete-path') + project_id = opts.data('autocomplete-project-id') + project_ref = opts.data('autocomplete-project-ref') + + new SearchAutocomplete(path, project_id, project_ref) diff --git a/app/assets/javascripts/issues.js.coffee b/app/assets/javascripts/issues.js.coffee index 43571409bc5..6c239c66c0a 100644 --- a/app/assets/javascripts/issues.js.coffee +++ b/app/assets/javascripts/issues.js.coffee @@ -29,12 +29,10 @@ $('#filter_issue_search').val($('#issue_search').val()) initSelects: -> - $("#update_status").chosen() - $("#update_assignee_id").chosen() - $("#update_milestone_id").chosen() - $("#label_name").chosen() - $("#assignee_id").chosen() - $("#milestone_id").chosen() + $("select#update_status").select2(width: 'resolve', dropdownAutoWidth: true) + $("select#update_assignee_id").select2(width: 'resolve', dropdownAutoWidth: true) + $("select#update_milestone_id").select2(width: 'resolve', dropdownAutoWidth: true) + $("select#label_name").select2(width: 'resolve', dropdownAutoWidth: true) $("#milestone_id, #assignee_id, #label_name").on "change", -> $(this).closest("form").submit() diff --git a/app/assets/javascripts/main.js.coffee b/app/assets/javascripts/main.js.coffee index 10c40dff5fd..9cf4dba815b 100644 --- a/app/assets/javascripts/main.js.coffee +++ b/app/assets/javascripts/main.js.coffee @@ -67,8 +67,8 @@ $ -> $('.appear-data').fadeIn() e.preventDefault() - # Initialize chosen selects - $('select.chosen').chosen() + # Initialize select2 selects + $('select.select2').select2(width: 'resolve', dropdownAutoWidth: true) # Initialize tooltips $('.has_tooltip').tooltip() @@ -81,6 +81,7 @@ $ -> $(@).parents('form').submit() $("abbr.timeago").timeago() + $('.js-timeago').timeago() # Flash if (flash = $(".flash-container")).length > 0 @@ -125,12 +126,6 @@ $ -> $(@).remove() (($) -> - _chosen = $.fn.chosen - $.fn.extend chosen: (options) -> - default_options = search_contains: "true" - $.extend default_options, options - _chosen.apply @, [default_options] - # Disable an element and add the 'disabled' Bootstrap class $.fn.extend disable: -> $(@).attr('disabled', 'disabled').addClass('disabled') diff --git a/app/assets/javascripts/merge_requests.js.coffee b/app/assets/javascripts/merge_requests.js.coffee index 2eef7df1c64..ff843c68d68 100644 --- a/app/assets/javascripts/merge_requests.js.coffee +++ b/app/assets/javascripts/merge_requests.js.coffee @@ -2,8 +2,8 @@ # * Filter merge requests # @merge_requestsPage = -> - $('#assignee_id').chosen() - $('#milestone_id').chosen() + $('#assignee_id').select2() + $('#milestone_id').select2() $('#milestone_id, #assignee_id').on 'change', -> $(this).closest('form').submit() @@ -24,6 +24,8 @@ class MergeRequest modal = $('#modal_merge_info').modal(show: false) + disableButtonIfEmptyField '#merge_commit_message', '.accept_merge_request' + # Local jQuery finder $: (selector) -> this.$el.find(selector) diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee index 6501cf38a89..69e9e67f712 100644 --- a/app/assets/javascripts/notes.js.coffee +++ b/app/assets/javascripts/notes.js.coffee @@ -37,6 +37,9 @@ class Notes # attachment button $(document).on "click", ".js-choose-note-attachment-button", @chooseNoteAttachment + # update the file name when an attachment is selected + $(document).on "change", ".js-note-attachment-input", @updateFormAttachment + # reply to diff/discussion notes $(document).on "click", ".js-discussion-reply-button", @replyToDiscussionNote @@ -429,4 +432,16 @@ class Notes updateVotes: -> (new NotesVotes).updateVotes() + ### + Called after an attachment file has been selected. + + Updates the file name for the selected attachment. + ### + updateFormAttachment: -> + form = $(this).closest("form") + + # get only the basename + filename = $(this).val().replace(/^.*[\\\/]/, "") + form.find(".js-attachment-filename").text filename + @Notes = Notes diff --git a/app/assets/javascripts/project.js.coffee b/app/assets/javascripts/project.js.coffee index 9a41ec7a0be..4262418fd5e 100644 --- a/app/assets/javascripts/project.js.coffee +++ b/app/assets/javascripts/project.js.coffee @@ -35,7 +35,7 @@ $ -> $('a, button', scope).removeClass 'active' $(@).addClass 'active' $('#project_clone', scope).val $(@).data 'clone' - $(".clone").text("").append 'git remote add origin ' + $(@).data 'clone' + $(".clone").text("").append $(@).data 'clone' # Ref switcher $('.project-refs-select').on 'change', -> diff --git a/app/assets/javascripts/search_autocomplete.js.coffee b/app/assets/javascripts/search_autocomplete.js.coffee index 3418690e109..e144dfa1d68 100644 --- a/app/assets/javascripts/search_autocomplete.js.coffee +++ b/app/assets/javascripts/search_autocomplete.js.coffee @@ -1,7 +1,12 @@ class SearchAutocomplete - constructor: (json) -> + constructor: (search_autocomplete_path, project_id, project_ref) -> + project_id = '' unless project_id + project_ref = '' unless project_ref + query = "?project_id=" + project_id + "&project_ref=" + project_ref + $("#search").autocomplete - source: json + source: search_autocomplete_path + query + minLength: 1 select: (event, ui) -> location.href = ui.item.url diff --git a/app/assets/javascripts/stat_graph_contributors_graph.js.coffee b/app/assets/javascripts/stat_graph_contributors_graph.js.coffee index 48443644169..834c7e5dab0 100644 --- a/app/assets/javascripts/stat_graph_contributors_graph.js.coffee +++ b/app/assets/javascripts/stat_graph_contributors_graph.js.coffee @@ -46,11 +46,7 @@ class window.ContributorsGraph class window.ContributorsMasterGraph extends ContributorsGraph constructor: (@data) -> - if $(window).width() > 1214 - @width = 1100 - else - @width = 870 - + @width = $('.container').width() - 70 @height = 200 @x = null @y = null @@ -88,7 +84,6 @@ class window.ContributorsMasterGraph extends ContributorsGraph x(d.date) ).y0(@height).y1((d) -> xa = d.commits = d.commits ? d.additions ? d.deletions - console.log(xa) y(xa) ).interpolate("basis") create_brush: -> @@ -124,11 +119,7 @@ class window.ContributorsMasterGraph extends ContributorsGraph class window.ContributorsAuthorGraph extends ContributorsGraph constructor: (@data) -> - if $(window).width() > 1214 - @width = 490 - else - @width = 380 - + @width = $('.container').width()/2 - 100 @height = 200 @x = null @y = null diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index b1a23427add..eb8bc0d63c0 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -4,19 +4,44 @@ * the top of the compiled file, but it's generally better to create a new file per style scope. *= require jquery.ui.gitlab *= require jquery.atwho - *= require chosen *= require select2 *= require_self */ +@import "main/variables.scss"; +@import "main/mixins.scss"; +@import "main/fonts.scss"; +@import "main/layout.scss"; + +/** + * Customized Twitter bootstrap + */ +@import 'gl_bootstrap'; + /** - * GitLab bootstrap: + * Font icons + * */ -@import "gitlab_bootstrap.scss"; +@import "font-awesome"; -@import "common.scss"; -@import "selects.scss"; +/** + * Generic css (forms, nav etc): + */ +@import "generic/avatar.scss"; +@import "generic/common.scss"; +@import "generic/typography.scss"; +@import "generic/buttons.scss"; +@import "generic/blocks.scss"; +@import "generic/ui_box.scss"; +@import "generic/issue_box.scss"; +@import "generic/files.scss"; +@import "generic/lists.scss"; +@import "generic/forms.scss"; +@import "generic/selects.scss"; +/** + * Page specific styles (issues, projects etc): + */ @import "sections/header.scss"; @import "sections/nav.scss"; @import "sections/commits.scss"; @@ -39,6 +64,9 @@ @import "sections/dashboard.scss"; @import "sections/stat_graph.scss"; +/** + * Code ighlight + */ @import "highlight/white.scss"; @import "highlight/dark.scss"; @import "highlight/solarized_dark.scss"; @@ -57,4 +85,3 @@ * Styles for JS behaviors. */ @import "behaviors.scss"; - diff --git a/app/assets/stylesheets/gitlab_bootstrap/avatar.scss b/app/assets/stylesheets/generic/avatar.scss index 4f038b977e2..4f038b977e2 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/avatar.scss +++ b/app/assets/stylesheets/generic/avatar.scss diff --git a/app/assets/stylesheets/gitlab_bootstrap/blocks.scss b/app/assets/stylesheets/generic/blocks.scss index 1cbd7439835..1cbd7439835 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/blocks.scss +++ b/app/assets/stylesheets/generic/blocks.scss diff --git a/app/assets/stylesheets/gitlab_bootstrap/buttons.scss b/app/assets/stylesheets/generic/buttons.scss index 347da1ad680..219e6ebd68b 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/buttons.scss +++ b/app/assets/stylesheets/generic/buttons.scss @@ -143,16 +143,27 @@ line-height: 16px; margin: 2px; } +} + +.btn-block { + width: 100%; + margin: 0; + margin-bottom: 15px; + &.btn { + padding: 6px 0; + } +} +.btn, +.btn-group { &.grouped { margin-right: 7px; float: left; - } - - &.btn-block { - width: 100%; - margin: 0; - padding: 6px 0; - margin-bottom: 15px; + &:last-child { + margin-right: 0px; + } } } + +.btn-group-small > .btn { @extend .btn.btn-small; } +.btn-group-tiny > .btn { @extend .btn.btn-tiny; } diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/generic/common.scss index c428d905de2..79a217186de 100644 --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/generic/common.scss @@ -1,48 +1,132 @@ -html { - overflow-y: scroll; +/** COLORS **/ +.cgray { color: gray } +.clgray { color: #BBB } +.cred { color: #D12F19 } +.cgreen { color: #4a2 } +.cblue { color: #29A } +.cblack { color: #111 } +.cdark { color: #444 } +.camber { color: #ffc000 } +.cwhite { color: #fff!important } +.bgred { background: #F2DEDE!important } + +/** COMMON CLASSES **/ +.left { float:left } + +.prepend-top-10 { margin-top:10px } +.prepend-top-20 { margin-top:20px } +.prepend-left-10 { margin-left:10px } +.prepend-left-20 { margin-left:20px } +.append-right-10 { margin-right:10px } +.append-right-20 { margin-right:20px } +.append-bottom-10 { margin-bottom:10px } +.append-bottom-15 { margin-bottom:15px } +.append-bottom-20 { margin-bottom:20px } +.inline { display: inline-block } + +.padded { padding:20px } +.ipadded { padding:20px!important } +.lborder { border-left:1px solid #eee } +.underlined_link { text-decoration: underline; } +.hint { font-style: italic; color: #999; } +.light { color: #888 } +.tiny { font-weight: normal } +.vtop { vertical-align: top !important; } + + +/** ALERT MESSAGES **/ +.alert.alert-disabled { + background: #EEE; + color: #777; + border-color: #DDD; +} + +/** HELPERS **/ +.nothing_here_message { + text-align: center; + padding: 20px; + color: #666; + font-weight: normal; + font-size: 16px; + line-height: 36px; } -/** LAYOUT **/ - -body { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - margin-bottom: 20px; +.slead { + color: #666; + font-size: 14px; + margin-bottom: 12px; + font-weight: normal; + line-height: 24px; } -.container { - padding-top: 0; - z-index: 5; + +.tab-content { + overflow: visible; } -.container .content { - margin: 0 0; +@media (max-width: 1200px) { + .only-wide { + display: none; + } } -.author_link { - color: $link_color; +pre.well-pre { + border: 1px solid #EEE; + background: #f9f9f9; + border-radius: 0; + color: #555; } -.help li { color:$style_color; } +.input-append .btn.active, .input-prepend .btn.active { + background: #CCC; + border-color: #BBB; + text-shadow: 0 1px 1px #fff; + font-weight: bold; + @include box-shadow(inset 0 2px 4px rgba(0,0,0,.15)); +} -.back-link { +/** Big Labels **/ +.state-label { font-size: 14px; + padding: 6px 25px; + text-align: center; + @include border-radius(4px); + text-shadow: none; + margin-left: 10px; + + &.state-label-green { + background: #4A4; + color: #FFF; + } + + &.state-label-red { + background: #DA4E49; + color: #FFF; + } } -table a code { - position: relative; - top: -2px; - margin-right: 3px; +.dropdown-menu > li > a { + text-shadow: none; } -.loading { - margin: 20px auto; - background: url(ajax_loader.gif) no-repeat center center; - width: 40px; - height: 40px; - &.loading-gray { - background: url(ajax_loader_gray.gif) no-repeat center center; - } +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background: #29b; +} + +.breadcrumb > li + li:before { + content: "/"; + padding: 0; + color: #666; +} + +.str-truncated { + display: inline-block; + overflow: hidden; + text-overflow: ellipsis; + vertical-align: top; + white-space: nowrap; + max-width: 82%; } /** FLASH message **/ @@ -71,6 +155,31 @@ table a code { padding: 10px; } } +.author_link { + color: $link_color; +} + +.help li { color:$style_color; } + +.back-link { + font-size: 14px; +} + +table a code { + position: relative; + top: -2px; + margin-right: 3px; +} + +.loading { + margin: 20px auto; + background: url(ajax_loader.gif) no-repeat center center; + width: 40px; + height: 40px; + &.loading-gray { + background: url(ajax_loader_gray.gif) no-repeat center center; + } +} span.update-author { display: block; @@ -92,19 +201,6 @@ span.update-author { display: inline; } -ul.breadcrumb { - background: white; - border: none; - li { - display: inline; - text-shadow: 0 1px 0 white - } - - a { - font-size: 16px; - } -} - .line_holder { &:hover { td { @@ -119,18 +215,6 @@ p.time { margin: 30px 3px 3px 2px; } -.search-holder { - label, input { - height: 30px; - padding: 0; - font-size: 14px; - } - label { - line-height: 30px; - color: #666; - } -} - .highlight { text-shadow: none; } @@ -209,7 +293,7 @@ li.note { } .git_error_tips { - @extend .span6; + @extend .col-md-6; text-align: left; margin-top: 40px; pre { @@ -236,6 +320,7 @@ li.note { background: #C67; margin: 0; color: #FFF; + margin-top: -1px; text-align: center; a { @@ -344,12 +429,6 @@ table { min-height: 100px; } -.navbar-gitlab .navbar-inner .nav > li .btn-sign-in { - @extend .btn-new; - padding: 5px 15px; - text-shadow: none; -} - .broadcast-message { padding: 10px; text-align: center; @@ -395,3 +474,14 @@ table { font-weight: bolder; } } + +.btn-sign-in { + margin-top: 7px; + text-shadow: none; +} + +.side-filters { + fieldset { + margin-bottom: 15px; + } +} diff --git a/app/assets/stylesheets/gitlab_bootstrap/files.scss b/app/assets/stylesheets/generic/files.scss index 3f9e4989a27..11bb715f7b5 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/files.scss +++ b/app/assets/stylesheets/generic/files.scss @@ -20,7 +20,6 @@ text-align: left; color: $style_color; padding: 9px 10px; - height: 18px; .options { float: right; @@ -46,7 +45,7 @@ text-align: center; img { padding: 100px; - max-width: 300px; + max-width: 50%; } } diff --git a/app/assets/stylesheets/generic/forms.scss b/app/assets/stylesheets/generic/forms.scss new file mode 100644 index 00000000000..931b75a3234 --- /dev/null +++ b/app/assets/stylesheets/generic/forms.scss @@ -0,0 +1,53 @@ +input[type='search'].search-text-input { + background-image: url("icon-search.png"); + background-repeat: no-repeat; + background-position: 10px; + padding-left: 25px; +} + +input[type='text'].danger { + background: #F2DEDE!important; + border-color: #D66; + text-shadow: 0 1px 1px #fff +} + +fieldset legend { + font-size: 16px; +} + +.datetime-controls { + select { + width: 100px; + } +} + +.form-actions { + padding: 17px 20px 18px; + margin-top: 18px; + margin-bottom: 18px; + background-color: whitesmoke; + border-top: 1px solid #e5e5e5; + padding-left: 17%; +} + +label { + &.control-label { + @extend .col-sm-2; + } + + &.inline-label { + margin: 0; + } +} + +.inline-input-group { + width: 250px; +} + +.input-mx-250 { + max-width: 250px; +} + +.input-mn-300 { + min-width: 300px; +} diff --git a/app/assets/stylesheets/gitlab_bootstrap/issue_box.scss b/app/assets/stylesheets/generic/issue_box.scss index 6330523ea22..6330523ea22 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/issue_box.scss +++ b/app/assets/stylesheets/generic/issue_box.scss diff --git a/app/assets/stylesheets/gitlab_bootstrap/lists.scss b/app/assets/stylesheets/generic/lists.scss index 83066b5beec..245cccf855d 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/lists.scss +++ b/app/assets/stylesheets/generic/lists.scss @@ -4,7 +4,9 @@ */ .well-list { margin: 0; + padding: 0; list-style: none; + li { padding: 10px; min-height: 20px; diff --git a/app/assets/stylesheets/generic/selects.scss b/app/assets/stylesheets/generic/selects.scss new file mode 100644 index 00000000000..c506bff8a74 --- /dev/null +++ b/app/assets/stylesheets/generic/selects.scss @@ -0,0 +1,80 @@ +/** Select2 selectbox style override **/ + +.select2-container, .select2-container.select2-drop-above { + .select2-choice { + background: #FFF; + border-color: #BBB; + + .select2-arrow { + background: #FFF; + } + } +} + +.select2-drop-active { + border: 1px solid #BBB; + margin-top: 4px; + + .select2-search input { + background: #fafafa; + border-color: #DDD; + } + + .select2-results { + max-height: 350px; + .select2-highlighted { + background: $bg_style_color; + } + } +} + +select { + &.select2 { + width: 100px; + } + + &.select2-sm { + width: 100px; + } +} + +@media (min-width: $screen-sm-min) { + select { + &.select2 { + width: 150px; + } + &.select2-sm { + width: 120px; + } + } +} + +/* Medium devices (desktops, 992px and up) */ +@media (min-width: $screen-md-min) { + select { + &.select2 { + width: 170px; + } + &.select2-sm { + width: 140px; + } + } +} + +/* Large devices (large desktops, 1200px and up) */ +@media (min-width: $screen-lg-min) { + select { + &.select2 { + width: 200px; + } + &.select2-sm { + width: 150px; + } + } +} + + +/** Branch/tag selector **/ +.project-refs-form .select2-container { + margin-right: 10px; +} diff --git a/app/assets/stylesheets/gitlab_bootstrap/typography.scss b/app/assets/stylesheets/generic/typography.scss index d3986556376..4490566d4e8 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/typography.scss +++ b/app/assets/stylesheets/generic/typography.scss @@ -2,11 +2,6 @@ * Headers * */ -h1, h2, h3, h4, h5, h6 { - font-weight: 500; - line-height: 1.1; -} - h1.page-title { @include page-title; font-size: 28px; @@ -99,6 +94,7 @@ a:focus { background: #f5f5f5; } ul { + padding: 0; margin: 0 0 9px 25px !important; } } diff --git a/app/assets/stylesheets/gitlab_bootstrap/ui_box.scss b/app/assets/stylesheets/generic/ui_box.scss index 056b4eeaaf4..7a977eae70d 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/ui_box.scss +++ b/app/assets/stylesheets/generic/ui_box.scss @@ -43,6 +43,7 @@ ul { margin: 0; + padding: 0; } .title { @@ -157,7 +158,8 @@ .title { background: #D65; color: #fff; - text-shadow: 0 1px 1px #900; + text-shadow: none; + font-weight: 500; } } diff --git a/app/assets/stylesheets/gitlab_bootstrap.scss b/app/assets/stylesheets/gitlab_bootstrap.scss deleted file mode 100644 index 322fab4b416..00000000000 --- a/app/assets/stylesheets/gitlab_bootstrap.scss +++ /dev/null @@ -1,68 +0,0 @@ -/** Override bootstrap variables **/ -$baseFontSize: 13px !default; -$baseLineHeight: 18px !default; - -/** - * BOOTSTRAP - */ -@import "bootstrap/variables"; -@import "bootstrap/mixins"; -@import "bootstrap/reset"; -@import "bootstrap/scaffolding"; -@import "bootstrap/grid"; -@import "bootstrap/layouts"; -@import "bootstrap/type"; -@import "bootstrap/code"; -@import "bootstrap/forms"; -@import "bootstrap/tables"; -@import "bootstrap/sprites"; -@import "bootstrap/dropdowns"; -@import "bootstrap/wells"; -@import "bootstrap/component-animations"; -@import "bootstrap/close"; -@import "bootstrap/button-groups"; -@import "bootstrap/alerts"; -@import "bootstrap/navs"; -@import "bootstrap/navbar"; -@import "bootstrap/breadcrumbs"; -@import "bootstrap/pagination"; -@import "bootstrap/pager"; -@import "bootstrap/modals"; -@import "bootstrap/tooltip"; -@import "bootstrap/popovers"; -@import "bootstrap/thumbnails"; -@import "bootstrap/media"; -@import "bootstrap/labels-badges"; -@import "bootstrap/progress-bars"; -@import "bootstrap/accordion"; -@import "bootstrap/carousel"; -@import "bootstrap/hero-unit"; -@import "bootstrap/utilities"; -@import "bootstrap/responsive-utilities"; -@import "bootstrap/responsive-1200px-min"; - -/** - * Font icons - * - */ -@import "font-awesome"; - -/** - * GitLab bootstrap. - * Overrides some styles of twitter bootstrap. - * Also give some common classes for GitLab app - */ -@import "gitlab_bootstrap/variables.scss"; -@import "gitlab_bootstrap/fonts.scss"; -@import "gitlab_bootstrap/mixins.scss"; -@import "gitlab_bootstrap/avatar.scss"; -@import "gitlab_bootstrap/nav.scss"; -@import "gitlab_bootstrap/common.scss"; -@import "gitlab_bootstrap/typography.scss"; -@import "gitlab_bootstrap/buttons.scss"; -@import "gitlab_bootstrap/blocks.scss"; -@import "gitlab_bootstrap/ui_box.scss"; -@import "gitlab_bootstrap/issue_box.scss"; -@import "gitlab_bootstrap/files.scss"; -@import "gitlab_bootstrap/lists.scss"; -@import "gitlab_bootstrap/forms.scss"; diff --git a/app/assets/stylesheets/gitlab_bootstrap/common.scss b/app/assets/stylesheets/gitlab_bootstrap/common.scss deleted file mode 100644 index d5426982428..00000000000 --- a/app/assets/stylesheets/gitlab_bootstrap/common.scss +++ /dev/null @@ -1,133 +0,0 @@ -/** COLORS **/ -.cgray { color: gray } -.clgray { color: #BBB } -.cred { color: #D12F19 } -.cgreen { color: #4a2 } -.cblue { color: #29A } -.cblack { color: #111 } -.cdark { color: #444 } -.camber { color: #ffc000 } -.cwhite { color: #fff!important } -.bgred { background: #F2DEDE!important } - -/** COMMON CLASSES **/ -.left { float:left } - -.prepend-top-10 { margin-top:10px } -.prepend-top-20 { margin-top:20px } -.prepend-left-10 { margin-left:10px } -.prepend-left-20 { margin-left:20px } -.append-right-10 { margin-right:10px } -.append-right-20 { margin-right:20px } -.append-bottom-10 { margin-bottom:10px } -.append-bottom-20 { margin-bottom:20px } -.inline { display: inline-block } - -.padded { padding:20px } -.ipadded { padding:20px!important } -.lborder { border-left:1px solid #eee } -.underlined_link { text-decoration: underline; } -.hint { font-style: italic; color: #999; } -.light { color: #888 } -.tiny { font-weight: normal } -.vtop { vertical-align: top !important; } - - -/** ALERT MESSAGES **/ -.alert.alert-disabled { - background: #EEE; - color: #777; - border-color: #DDD; -} - -/** HELPERS **/ -.nothing_here_message { - text-align: center; - padding: 20px; - color: #666; - font-weight: normal; - font-size: 16px; - line-height: 36px; -} - -.slead { - color: #666; - font-size: 14px; - margin-bottom: 12px; - font-weight: normal; - line-height: 24px; -} - - -.tab-content { - overflow: visible; -} - -@media (max-width: 1200px) { - .only-wide { - display: none; - } -} - -.pagination ul > li > a, .pagination ul > li >span { - @include linear-gradient(#f1f1f1, #e1e1e1); - color: #333; - text-shadow: 0 1px 1px #FFF; -} - -pre.well-pre { - border: 1px solid #EEE; - background: #f9f9f9; - border-radius: 0; - color: #555; -} - -.input-append .btn.active, .input-prepend .btn.active { - background: #CCC; - border-color: #BBB; - text-shadow: 0 1px 1px #fff; - font-weight: bold; - @include box-shadow(inset 0 2px 4px rgba(0,0,0,.15)); -} - -.label { - padding: 2px 4px; - font-size: 12px; - font-style: normal; - font-weight: normal; - - &.label-gray { - background-color: #eee; - color: #999; - text-shadow: none; - } -} - -/** Big Labels **/ -.state-label { - font-size: 14px; - padding: 6px 25px; - text-align: center; - @include border-radius(4px); - text-shadow: none; - margin-left: 10px; - - &.state-label-green { - background: #4A4; - color: #FFF; - } - - &.state-label-red { - background: #DA4E49; - color: #FFF; - } -} - -.dropdown-menu > li > a { - text-shadow: none; -} - -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus { - background: #29b; -} diff --git a/app/assets/stylesheets/gitlab_bootstrap/forms.scss b/app/assets/stylesheets/gitlab_bootstrap/forms.scss deleted file mode 100644 index 39dd1f6c747..00000000000 --- a/app/assets/stylesheets/gitlab_bootstrap/forms.scss +++ /dev/null @@ -1,78 +0,0 @@ -form { - @extend .form-horizontal; - - label { - @extend .control-label; - - &.radio-label { - text-align: left; - width: 100%; - margin-left: 0; - - input[type="radio"] { - margin-top: 1px !important; - } - } - - &.list-label { - float: none; - padding: 0 !important; - margin: 0; - text-align: left; - } - } - - &.form-tiny { - margin: 0; - } -} - -input.input-xpadding, -.add-on.input-xpadding { - padding: 6px 10px; -} - -.control-group { - .control-label { - padding-top: 6px; - } - .controls { - input, textarea { - padding: 6px 10px; - } - - input[type="radio"], input[type="checkbox"] { - margin-top: 6px; - } - - .add-on { - padding: 6px; - } - } -} - -input[type='search'].search-text-input { - background-image: url("icon-search.png"); - background-repeat: no-repeat; - background-position: 10px; - padding-left: 25px; - @include border-radius(4px); - border: 1px solid #ccc; -} - -input[type='text'].danger { - background: #F2DEDE!important; - border-color: #D66; - text-shadow: 0 1px 1px #fff -} - -fieldset legend { - font-size: 16px; - margin-bottom: 10px; -} - -.datetime-controls { - select { - width: 100px; - } -} diff --git a/app/assets/stylesheets/gitlab_bootstrap/nav.scss b/app/assets/stylesheets/gitlab_bootstrap/nav.scss deleted file mode 100644 index cc2bf0f912e..00000000000 --- a/app/assets/stylesheets/gitlab_bootstrap/nav.scss +++ /dev/null @@ -1,91 +0,0 @@ -/** - * nav-pills - * - */ -.nav-pills { - .active a { - background: $primary_color; - } - - > li > a { - @include border-radius(0); - } - - &.nav-stacked { - > li > a { - border-left: 4px solid #EEE; - padding: 12px; - color: #777; - } - > .active > a { - border-color: $primary_color; - background: none; - color: #333; - font-weight: bolder; - } - - &.nav-stacked-menu { - li > a { - padding: 16px; - } - } - } - - &.nav-pills-small { - > li > a { - padding: 8px 12px; - font-size: 12px; - } - } -} - -.nav-pills > .active > a > i[class^="icon-"] { background: inherit; } - - - -/** - * nav-tabs - * - */ -.nav-tabs > li > a, .nav-pills > li > a { color: $style_color; } -.nav.nav-tabs { - li { - > a { - padding: 8px 20px; - margin-right: 7px; - line-height: 20px; - border-color: #EEE; - color: #888; - border-bottom: 1px solid #ddd; - .badge { - background-color: #eee; - color: #888; - text-shadow: 0 1px 1px #fff; - } - i[class^="icon-"] { - line-height: 14px; - } - } - &.active { - > a { - border-color: #CCC; - border-bottom: 1px solid #fff; - color: #333; - font-weight: bold; - } - } - } - - &.nav-small-tabs > li > a { padding: 6px 9px; } -} - - - -/** - * fix to keep tooltips position in top navigation bar - * - */ -.navbar .nav > li { - position: relative; - white-space: nowrap; -} diff --git a/app/assets/stylesheets/gl_bootstrap.scss b/app/assets/stylesheets/gl_bootstrap.scss new file mode 100644 index 00000000000..7f45d64fb7c --- /dev/null +++ b/app/assets/stylesheets/gl_bootstrap.scss @@ -0,0 +1,220 @@ +/* + * Twitter bootstrap with GitLab customizations/additions + * + * Some unused bootstrap compontents like panels are not included. + * Other components like tabs are modified to GitLab style. + * + */ + +$font-size-base: 13px !default; +$nav-pills-active-link-hover-bg: $bg_style_color; +$pagination-active-bg: $bg_style_color; + +// Core variables and mixins +@import "bootstrap/variables"; +@import "bootstrap/mixins"; + +// Reset +@import "bootstrap/normalize"; +@import "bootstrap/print"; + +// Core CSS +@import "bootstrap/scaffolding"; +@import "bootstrap/type"; +@import "bootstrap/code"; +@import "bootstrap/grid"; +@import "bootstrap/tables"; +@import "bootstrap/forms"; + +// Components +@import "bootstrap/component-animations"; +@import "bootstrap/dropdowns"; +@import "bootstrap/button-groups"; +@import "bootstrap/input-groups"; +@import "bootstrap/navs"; +@import "bootstrap/navbar"; +@import "bootstrap/breadcrumbs"; +@import "bootstrap/pagination"; +@import "bootstrap/pager"; +@import "bootstrap/labels"; +@import "bootstrap/badges"; +@import "bootstrap/jumbotron"; +@import "bootstrap/thumbnails"; +@import "bootstrap/alerts"; +@import "bootstrap/progress-bars"; +@import "bootstrap/list-group"; +@import "bootstrap/wells"; +@import "bootstrap/close"; + +// Components w/ JavaScript +@import "bootstrap/modals"; +@import "bootstrap/tooltip"; +@import "bootstrap/popovers"; +@import "bootstrap/carousel"; + +// Utility classes +.clearfix { + @include clearfix(); +} +.center-block { + @include center-block(); +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + @include text-hide(); +} +.hidden { + display: none !important; + visibility: hidden !important; +} +.affix { + position: fixed; +} + +@import "bootstrap/responsive-utilities"; + +// Labels +.label { + padding: 2px 4px; + font-size: 12px; + font-style: normal; + font-weight: normal; + display: inline-block; + + &.label-gray { + background-color: #eee; + color: #999; + text-shadow: none; + } + + &.label-inverse { + background-color: #333333; + } +} + +// Nav tabs +.nav.nav-tabs { + li { + > a { + padding: 8px 20px; + margin-right: 7px; + line-height: 20px; + border-color: #EEE; + color: #888; + border-bottom: 1px solid #ddd; + .badge { + background-color: #eee; + color: #888; + text-shadow: 0 1px 1px #fff; + } + i[class^="icon-"] { + line-height: 14px; + } + } + &.active { + > a { + border-color: #CCC; + border-bottom: 1px solid #fff; + color: #333; + font-weight: bold; + } + } + } + + &.nav-small-tabs > li > a { + padding: 6px 9px; + } +} + +.nav-tabs > li > a, +.nav-pills > li > a { + color: #666; +} + +.nav-small > li > a { + padding: 3px 5px; + font-size: 12px; +} + + +/* + * Callouts from Bootstrap3 docs + * + * Not quite alerts, but custom and helpful notes for folks reading the docs. + * Requires a base and modifier class. + */ + +/* Common styles for all types */ +.bs-callout { + margin: 20px 0; + padding: 20px; + border-left: 3px solid #eee; + color: #666; + background: #f9f9f9; +} +.bs-callout h4 { + margin-top: 0; + margin-bottom: 5px; +} +.bs-callout p:last-child { + margin-bottom: 0; +} + +/* Variations */ +.bs-callout-danger { + background-color: #fdf7f7; + border-color: #eed3d7; + color: #b94a48; +} +.bs-callout-warning { + background-color: #faf8f0; + border-color: #faebcc; + color: #8a6d3b; +} +.bs-callout-info { + background-color: #f4f8fa; + border-color: #bce8f1; + color: #34789a; +} +.bs-callout-success { + background-color: #dff0d8; + border-color: #5cA64d; + color: #3c763d; +} + +// Breadcrumb +ul.breadcrumb { + background: white; + border: none; + li { + display: inline; + text-shadow: 0 1px 0 white + } + + a { + font-size: 16px; + } +} + +/** + * fix to keep tooltips position in top navigation bar + * + */ +.navbar .nav > li { + position: relative; + white-space: nowrap; +} diff --git a/app/assets/stylesheets/gitlab_bootstrap/fonts.scss b/app/assets/stylesheets/main/fonts.scss index 8cc9986415c..8cc9986415c 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/fonts.scss +++ b/app/assets/stylesheets/main/fonts.scss diff --git a/app/assets/stylesheets/main/layout.scss b/app/assets/stylesheets/main/layout.scss new file mode 100644 index 00000000000..a4d889f26dd --- /dev/null +++ b/app/assets/stylesheets/main/layout.scss @@ -0,0 +1,18 @@ +html { + overflow-y: scroll; +} + +body { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + margin-bottom: 20px; +} + +.container { + padding-top: 0; + z-index: 5; +} + +.container .content { + margin: 0 0; +} diff --git a/app/assets/stylesheets/gitlab_bootstrap/mixins.scss b/app/assets/stylesheets/main/mixins.scss index 5a6b5ac0efd..e637b645b55 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/mixins.scss +++ b/app/assets/stylesheets/main/mixins.scss @@ -79,11 +79,15 @@ color: $style_color; text-shadow: 0 1px 1px #FFF; font-size: 16px; - line-height: 40px; + line-height: 44px; font-weight: normal; } @mixin md-typography { + img { + max-width: 100%; + } + *:first-child { margin-top: 0; } diff --git a/app/assets/stylesheets/gitlab_bootstrap/variables.scss b/app/assets/stylesheets/main/variables.scss index aeabe7ad2e8..decc5f50469 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/variables.scss +++ b/app/assets/stylesheets/main/variables.scss @@ -4,6 +4,7 @@ $primary_color: #2FA0BB; $link_color: #3A89A3; $style_color: #474D57; +$bg_style_color: #2299BB; $hover: #D9EDF7; /** diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss index cd3e5d56c25..ff293bc4a00 100644 --- a/app/assets/stylesheets/sections/commits.scss +++ b/app/assets/stylesheets/sections/commits.scss @@ -80,7 +80,7 @@ border-right: 1px solid #ccc; text-align: right; min-width: 35px; - max-width: 35px; + max-width: 50px; width: 35px; @include user-select(none); a { @@ -399,8 +399,8 @@ .commits-compare-switch{ background: url("switch_icon.png") no-repeat center center; - width: 22px; - height: 22px; + width: 32px; + height: 32px; text-indent: -9999px; float: left; margin-right: 9px; @@ -481,6 +481,10 @@ li.commit { font-family: $monospace_font; } + .str-truncated { + max-width: 70%; + } + .commit-row-message { color: #333; font-weight: 500; diff --git a/app/assets/stylesheets/sections/dashboard.scss b/app/assets/stylesheets/sections/dashboard.scss index 720d3a8fbd5..1fd82c84fc9 100644 --- a/app/assets/stylesheets/sections/dashboard.scss +++ b/app/assets/stylesheets/sections/dashboard.scss @@ -1,11 +1,5 @@ .dashboard { - @extend .row; - .activities { - } - .side { - @extend .pull-right; - .ui-box { margin: 0px; box-shadow: none; @@ -20,7 +14,7 @@ .search-text-input { float:left; - @extend .span2; + @extend .col-md-2; } .btn { margin-left: 5px; @@ -32,14 +26,15 @@ .dash-filter { margin: 7px 0; padding: 4px 6px; - width: 202px; + width: 220px; float: left; + height: inherit; } } @media (max-width: 1200px) { .dashboard .dash-filter { - width: 132px; + width: 150px; } } @@ -107,7 +102,6 @@ padding: 8px 12px; border-radius: 50px; background: #f5f5f5; - width: 16px; text-align: center; i { diff --git a/app/assets/stylesheets/sections/editor.scss b/app/assets/stylesheets/sections/editor.scss index a71e5438936..057f7b7fd44 100644 --- a/app/assets/stylesheets/sections/editor.scss +++ b/app/assets/stylesheets/sections/editor.scss @@ -34,15 +34,4 @@ margin: 5px 8px 0 8px; } } - .commit_message-group { - margin-top: 20px; - - label { - font-size: 16px; - line-height: 20px; - } - textarea { - @extend .span8; - } - } } diff --git a/app/assets/stylesheets/sections/events.scss b/app/assets/stylesheets/sections/events.scss index 966282750d9..a576fefdea1 100644 --- a/app/assets/stylesheets/sections/events.scss +++ b/app/assets/stylesheets/sections/events.scss @@ -75,6 +75,7 @@ margin-top: 4px; margin-left: 0px; max-width: 200px; + float: none; } p:last-child { @@ -147,7 +148,7 @@ float: left; padding: 9px 6px; font-size: 18px; - width: 26px; + width: 40px; @include border-radius(3px); } diff --git a/app/assets/stylesheets/sections/header.scss b/app/assets/stylesheets/sections/header.scss index 157b9dd9e8a..b0dd0d08356 100644 --- a/app/assets/stylesheets/sections/header.scss +++ b/app/assets/stylesheets/sections/header.scss @@ -4,17 +4,24 @@ */ header { &.navbar-gitlab { + margin-bottom: 0; + min-height: 40px; + .navbar-inner { - height: 40px; - padding: 3px; background: #F1F1F1; + border-bottom: 1px solid #DDD; filter: none; .nav > li > a { color: $style_color; text-shadow: 0 1px 0 #fff; font-size: 14px; - padding: 10px; + line-height: 32px; + padding: 6px 10px; + + &:hover { + background: none; + } } /** NAV block with links and profile **/ @@ -35,9 +42,6 @@ header { .app_logo { float: left; margin-right: 9px; - position: relative; - top: -3px; - padding-top: 3px; a { float: left; @@ -49,7 +53,7 @@ header { background: url('logo-black.png') no-repeat center center; background-size: 32px; float: left; - height: 40px; + height: 46px; width: 40px; @include header-font; text-indent: -9999px; @@ -75,7 +79,7 @@ header { .profile-pic { position: relative; - top: -4px; + top: -1px; img { width: 26px; height: 26px; @@ -91,21 +95,25 @@ header { .search { margin-right: 10px; margin-left: 10px; + margin-top: 8px; + + form { + margin: 0; + padding: 0; + } .search-input { - @extend .span3; background-image: url("icon-search.png"); background-repeat: no-repeat; background-position: 10px; + height: inherit; + padding: 4px 6px; padding-left: 25px; font-size: 13px; @include border-radius(3px); border: 1px solid #c6c6c6; box-shadow: none; @include transition(all 0.15s ease-in 0s); - &:focus { - @extend .span4; - } } } @@ -181,12 +189,26 @@ header { .separator { float: left; height: 46px; - width: 1px; + width: 2px; background: white; border-left: 1px solid #DDD; - margin-top: -3px; margin-left: 10px; margin-right: 10px; } } +.search .search-input { + width: 300px; + &:focus { + width: 400px; + } +} + +@media (max-width: 1200px) { + .search .search-input { + width: 200px; + &:focus { + width: 300px; + } + } +} diff --git a/app/assets/stylesheets/sections/issues.scss b/app/assets/stylesheets/sections/issues.scss index c8e55775040..81d945a9b3c 100644 --- a/app/assets/stylesheets/sections/issues.scss +++ b/app/assets/stylesheets/sections/issues.scss @@ -77,8 +77,8 @@ input.check_all_issues { @media (min-width: 800px) { .issues_filters select { width: 160px; } } @media (min-width: 1200px) { .issues_filters select { width: 220px; } } -@media (min-width: 800px) { .issues_bulk_update .chosen-container { min-width: 120px; } } -@media (min-width: 1200px) { .issues_bulk_update .chosen-container { min-width: 160px; } } +@media (min-width: 800px) { .issues_bulk_update .select2-container { min-width: 120px; } } +@media (min-width: 1200px) { .issues_bulk_update .select2-container { min-width: 160px; } } .issues-holder { .issues_filters { @@ -105,7 +105,7 @@ input.check_all_issues { } .issues_bulk_update { - .chosen-container { + .select2-container { text-shadow: none; } } @@ -120,11 +120,6 @@ input.check_all_issues { } } -.edit-issue.inline-update select { - width: 100%; - max-width: 200px; -} - .issue-show-labels .label { padding: 6px 10px; } diff --git a/app/assets/stylesheets/sections/login.scss b/app/assets/stylesheets/sections/login.scss index 402b44fe7a5..186294424a2 100644 --- a/app/assets/stylesheets/sections/login.scss +++ b/app/assets/stylesheets/sections/login.scss @@ -1,55 +1,58 @@ /* Login Page */ -body.login-page{ - .container > .content { - padding-top: 20px; +.login-page { + h1 { + font-size: 3em; + font-weight: 200; } -} - -.login-box{ - width: 304px; - position: relative; - @include border-radius(5px); - margin: auto; - padding: 20px; - background: white; -} - -.login-box .login-logo{ - margin: 10px 0 30px 0; - display: block; -} - -.login-box input.text{background-color: #f1f1f1; font-size: 16px; @include border-radius(0); padding: 14px 10px; width: 280px} - -.login-box input.text.top{ - @include border-radius(5px 5px 0 0); - margin-bottom: 0px; -} -.login-box input.text.bottom{ - @include border-radius(0 0 5px 5px); - border-top: 0; - margin-bottom: 20px; -} - -.login-box input.text.middle{ - border-top: 0; - margin-bottom:0px; -} + .login-box{ + width: 304px; + position: relative; + @include border-radius(5px); + margin: auto; + padding: 20px; + background: white; + } -.login-box a.forgot{float: right; padding-top: 6px} + .login-logo{ + margin: 10px 0 30px 0; + display: block; + } -.remember_me { - text-align: left; + .form-control { + background-color: #f1f1f1; + font-size: 16px; + padding: 14px 10px; + width: 280px; + height: auto; + + &.top { + @include border-radius(5px 5px 0 0); + margin-bottom: 0px; + } + + &.bottom { + @include border-radius(0 0 5px 5px); + border-top: 0; + margin-bottom: 20px; + } + + &.middle { + border-top: 0; + margin-bottom:0px; + @include border-radius(0); + } + } - input { - margin: 2px; + .login-box a.forgot { + float: right; + padding-top: 6px } -} -.devise-errors { - h2 { - font-size: 14px; - color: #a00; + .devise-errors { + h2 { + font-size: 14px; + color: #a00; + } } } diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss index 0f0f8c858d1..d3462d6aaa7 100644 --- a/app/assets/stylesheets/sections/merge_requests.scss +++ b/app/assets/stylesheets/sections/merge_requests.scss @@ -4,10 +4,6 @@ * */ .automerge_widget { - &.can_be_merged { - background: #DFF0D8; - } - form { margin-bottom: 0; .clearfix { @@ -15,32 +11,12 @@ } } - .accept_group { - float: left; - border: 1px solid #ADA; - padding: 2px; - @include border-radius(5px); - background: #CEB; - - .accept_merge_request { - font-size: 13px; - float: left; - } - .remove_branch_holder { - margin-left: 20px; - margin-right: 10px; - float: left; - } + .accept-group { label { - color: #444; - text-align: left + margin: 5px; + margin-left: 20px; } } - - - .how_to_merge_link { - @extend .primary; - } } .merge-request .nav-tabs{ @@ -53,11 +29,6 @@ } } -.merge-in-progress { - @extend .padded; - @extend .append-bottom-10; -} - .mr_source_commit, .mr_target_commit { .commit { @@ -111,12 +82,8 @@ .merge-request-angle { text-align: center; margin: 0 auto; - background: #eee; - border-radius: 100px; - width: 60px; - line-height: 60px; - color: #777; - text-shadow: 0 1px 2px #FFF; + font-size: 2em; + line-height: 1.1; } .merge-request-form-info { @@ -128,8 +95,7 @@ font-weight: normal !important; } - .chosen-container .chosen-single { - padding: 2px 0 2px 10px; + .select2-container .select2-single { span { font-weight: bold; color: #555; diff --git a/app/assets/stylesheets/sections/nav.scss b/app/assets/stylesheets/sections/nav.scss index 54263523e85..f706854b4fe 100644 --- a/app/assets/stylesheets/sections/nav.scss +++ b/app/assets/stylesheets/sections/nav.scss @@ -6,6 +6,7 @@ border-bottom: 1px solid #E1E1E1; ul { + padding: 0; margin: auto; height: 40px; overflow: hidden; diff --git a/app/assets/stylesheets/sections/notes.scss b/app/assets/stylesheets/sections/notes.scss index 724b8d414a8..1ae0e161aa2 100644 --- a/app/assets/stylesheets/sections/notes.scss +++ b/app/assets/stylesheets/sections/notes.scss @@ -2,7 +2,7 @@ * Notes */ -@-webkit-keyframes target-note { +@-webkit-keyframes targe3-note { from { background:#fffff0; } 50% { background:#ffffd3; } to { background:#fffff0; } @@ -119,9 +119,9 @@ ul.notes { } .file .notes_holder { - font-family: $sansFontFamily; font-size: 13px; line-height: 18px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; td { border: 1px solid #ddd; @@ -138,7 +138,7 @@ ul.notes { border-left: 1px solid #ddd !important; } &.notes_content { - background-color: $white; + background-color: #fff; border-width: 1px 0; padding-top: 0; @@ -303,7 +303,7 @@ ul.notes { } .note-image-attach { - @extend .span4; + @extend .col-md-4; @extend .thumbnail; margin-left: 45px; } diff --git a/app/assets/stylesheets/sections/profile.scss b/app/assets/stylesheets/sections/profile.scss index 7e5668ae8a7..3a3bf7cdf2a 100644 --- a/app/assets/stylesheets/sections/profile.scss +++ b/app/assets/stylesheets/sections/profile.scss @@ -1,7 +1,6 @@ .update-notifications { - margin-bottom: 0; - label { - margin-bottom: 0; + .radio-inline { + margin-right: 9%; } } @@ -17,7 +16,7 @@ legend { border: none; - margin: 0; + margin-bottom: 10px; } } } @@ -47,3 +46,62 @@ margin: 10px 0; } } + +.user-show-username { + font-weight: 200; + color: #666; +} + +/* + * Appearance settings + * + */ +.themes_opts { + label { + margin-right: 20px; + text-align: center; + + .prev { + @extend .thumbnail; + height: 30px; + width: 175px; + margin-bottom: 10px; + + &.classic { + background: #31363e; + } + + &.default { + background: #f1f1f1; + } + + &.modern { + background: #345; + } + + &.gray { + background: #373737; + } + + &.violet { + background: #547; + } + } + } +} + +.code_highlight_opts { + margin-top: 10px; + + label { + margin-right: 20px; + text-align: center; + + .prev { + @extend .thumbnail; + height: 151px; + width: 220px; + margin-bottom: 10px; + } + } +} diff --git a/app/assets/stylesheets/sections/projects.scss b/app/assets/stylesheets/sections/projects.scss index d55e40914b2..178364835ae 100644 --- a/app/assets/stylesheets/sections/projects.scss +++ b/app/assets/stylesheets/sections/projects.scss @@ -16,7 +16,7 @@ .project-home-panel { border-bottom: 1px solid #DDD; - padding-bottom: 25px; + padding-bottom: 15px; margin-bottom: 30px; &.empty-project { @@ -41,24 +41,29 @@ .project-home-desc { float: left; color: #777; + margin-bottom: 10px; } .project-home-links { float: right; a { margin-left: 10px; + font-weight: 500; } } } .visibility-level-label { - font-size: 14px; + font-size: 17px; background: #f1f1f1; - padding: 8px 10px; border-radius: 4px; - margin-left: 10px; color: #888; + position: absolute; + margin-left: -55px; text-shadow: 0 1px 1px #FFF; + width: 40px; + text-align: center; + padding: 6px; i { color: inherit; @@ -67,76 +72,53 @@ } .git-clone-holder { - float: right; - border: 1px solid #E1E1E1; - @include border-radius(4px); + .project-home-dropdown + & { + margin-right: 45px; + } - input[type="text"], - .btn { - border: none; - @include border-radius(0px); - border-left: 1px solid #E1E1E1; + .btn, + .form-control { + border: 1px solid #E1E1E1; box-shadow: none; padding: 6px 9px; } .btn { - float: left; background: none; color: #29b; - &:first-child { - @include border-radius-left(4px); - border-left: 0px; - } - &.active { color: #333; font-weight: bold; } } - input[type="text"] { + .form-control { cursor: auto; @extend .monospace; background: #FAFAFA; + width: 100%; } } .project-visibility-level-holder { - .controls { - padding-bottom: 9px; - } + .radio { + margin-bottom: 10px; - .controls { - input { - float: left; + i { + margin: 0 3px; + font-size: 20px; } - .descr { - display: block; - margin-left: 1.5em; - &.restricted { - color: #888; - } - label { - float: none; - padding: 0; - margin: 0; - text-align: left; - } - } - .info { - display: block; - margin-top: 5px; - } - strong { + .option-title { + font-weight: bold; display: inline-block; - width: 4em; } - } - i { - color: inherit; + + .option-descr { + margin-left: 24px; + color: #666; + } } } @@ -218,11 +200,26 @@ ul.nav.nav-projects-tabs { .project-side { .btn-block { background-image: none; - background-color: #F1f1f1; - border-color: #EEE; - &:hover { - background-color: #eee; - border-color: #DDD; + .btn, + &.btn, + &.btn-group ul.dropdown-menu { + background-color: #F1f1f1; + border-color: #EEE; + &:hover { + background-color: #eee; + border-color: #DDD; + } + } + &.btn-group-justified { + .btn { + width: 100%; + } + .dropdown-toggle { + width: 26px; + } + } + ul { + width: 100%; } } .project-fork-icon { @@ -233,46 +230,10 @@ ul.nav.nav-projects-tabs { } } -.transfer-project .chosen-container { +.transfer-project .select2-container { min-width: 200px; } -/** Branch/tag selector **/ -.project-refs-form { - margin: 0; - span { - background:none !important; - position:static !important; - width:auto !important; - height:auto !important; - } -} -.project-refs-select { - width: 120px; -} - -.project-refs-form .chosen-container { - position: relative; - top: 0; - left: 0; - margin-right: 10px; - - .chosen-single span { - font-weight: bold; - color: #555; - } - - &.chosen-container-active { - .chosen-drop { - min-width: 400px; - } - - .chosen-results { - max-height: 400px; - } - } -} - .deploy-project-label { margin: 1px; } diff --git a/app/assets/stylesheets/sections/snippets.scss b/app/assets/stylesheets/sections/snippets.scss index e67ca794f25..84404b6ee36 100644 --- a/app/assets/stylesheets/sections/snippets.scss +++ b/app/assets/stylesheets/sections/snippets.scss @@ -1,14 +1,3 @@ -.snippet.file-holder { - .file-title { - .snippet-file-name { - padding: 4px 10px; - position: relative; - top: -4px; - left: -4px; - } - } -} - .my-snippets li:first-child { h4 { margin-top: 0; } padding-top: 0; diff --git a/app/assets/stylesheets/sections/themes.scss b/app/assets/stylesheets/sections/themes.scss index cd1aa2b011a..e69de29bb2d 100644 --- a/app/assets/stylesheets/sections/themes.scss +++ b/app/assets/stylesheets/sections/themes.scss @@ -1,53 +0,0 @@ -.themes_opts { - padding-left: 20px; - - label { - width: 175px; - margin-right: 40px; - - .prev { - @extend .thumbnail; - height: 30px; - width: 175px; - margin-bottom: 10px; - - &.classic { - background: #31363e; - } - - &.default { - background: #f1f1f1; - } - - &.modern { - background: #345; - } - - &.gray { - background: #373737; - } - - &.violet { - background: #547; - } - } - } -} - -.code_highlight_opts { - padding-left: 20px; - - label { - width: 220px; - margin-right: 40px; - - .prev { - @extend .thumbnail; - height: 151px; - width: 220px; - margin-bottom: 10px; - } - } -} - - diff --git a/app/assets/stylesheets/sections/tree.scss b/app/assets/stylesheets/sections/tree.scss index efa95e66742..dfdcbb59b6b 100644 --- a/app/assets/stylesheets/sections/tree.scss +++ b/app/assets/stylesheets/sections/tree.scss @@ -24,10 +24,10 @@ th { font-weight: normal; font-size: 15px; - border-bottom: 1px solid #CCC; + border-bottom: 1px solid #CCC !important; } td { - border-color: #F1F1F1; + border-color: #F1F1F1 !important; } &:hover { td { @@ -49,6 +49,7 @@ .tree-item { .tree-item-file-name { + max-width: 320px; vertical-align: middle; a { &:hover { @@ -61,6 +62,14 @@ top:-1px; } } + + .tree_commit { + max-width: 320px; + } + + .tree_time_ago { + min-width: 135px; + } } .tree_author { @@ -111,7 +120,7 @@ .tree-ref-holder { float: left; - margin-top: 5px; + margin-top: 8px; } .readme-holder { diff --git a/app/assets/stylesheets/sections/votes.scss b/app/assets/stylesheets/sections/votes.scss index 49489babab7..13f811e01a1 100644 --- a/app/assets/stylesheets/sections/votes.scss +++ b/app/assets/stylesheets/sections/votes.scss @@ -36,3 +36,8 @@ display: inline-block; margin: 0 8px; } + +.votes-holder { + float: right; + width: 250px; +} diff --git a/app/assets/stylesheets/sections/wall.scss b/app/assets/stylesheets/sections/wall.scss index d6ac08fcf6f..3705afdb87c 100644 --- a/app/assets/stylesheets/sections/wall.scss +++ b/app/assets/stylesheets/sections/wall.scss @@ -1,6 +1,6 @@ .wall-page { .wall-note-form { - @extend .span12; + @extend .col-md-12; margin: 0; height: 140px; diff --git a/app/assets/stylesheets/selects.scss b/app/assets/stylesheets/selects.scss deleted file mode 100644 index 7259c7d7e49..00000000000 --- a/app/assets/stylesheets/selects.scss +++ /dev/null @@ -1,57 +0,0 @@ -/** Chosen.js selectbox style override **/ -.chosen-container { - min-width: 100px; - - .chosen-single { - background: #EEE !important; - border: 1px solid #DDD !important; - @include box-shadow(none !important); - @include border-radius(4px !important); - } - - .chosen-results li.highlighted { - background: #29b; - } - - .chosen-drop { - margin-top: 10px; - border: 1px solid #DDD !important; - @include border-radius(4px !important); - } - - .chosen-search input { - border: 1px solid #CCC !important; - @include box-shadow(none !important); - } -} - -/** Select2 styling **/ -.select2-container .select2-choice { - @include bg-light-gray-gradient; -} - -.select2-container .select2-choice div { - border: none; - background: none; -} - -.select2-drop { - padding-top: 8px; -} - -.select2-no-results, .select2-searching { - padding: 7px; - color: #666; -} - -.chosen-container .chosen-single div b { - background-position-y: 0px !important; -} - -.chosen-container .chosen-drop .chosen-search input { - background-position-y: -24px !important; -} - -.chosen-compact { - max-width: 170px !important; -} diff --git a/app/contexts/commit_load_context.rb b/app/contexts/commit_load_context.rb deleted file mode 100644 index 0c684976b64..00000000000 --- a/app/contexts/commit_load_context.rb +++ /dev/null @@ -1,34 +0,0 @@ -class CommitLoadContext < BaseContext - def execute - result = { - commit: nil, - suppress_diff: false, - line_notes: [], - notes_count: 0, - note: nil, - status: :ok - } - - commit = project.repository.commit(params[:id]) - - if commit - line_notes = project.notes.for_commit_id(commit.id).inline - - result[:commit] = commit - result[:note] = project.build_commit_note(commit) - result[:line_notes] = line_notes - result[:notes_count] = project.notes.for_commit_id(commit.id).count - result[:branches] = project.repository.branch_names_contains(commit.id) - - begin - result[:suppress_diff] = true if commit.diff_suppress? && !params[:force_show_diff] - result[:force_suppress_diff] = commit.diff_force_suppress? - rescue Grit::Git::GitTimeout - result[:suppress_diff] = true - result[:status] = :huge_commit - end - end - - result - end -end diff --git a/app/contexts/filter_context.rb b/app/contexts/filter_context.rb deleted file mode 100644 index fb0d42cf87d..00000000000 --- a/app/contexts/filter_context.rb +++ /dev/null @@ -1,58 +0,0 @@ -class FilterContext - attr_accessor :klass, :current_user, :params - - def initialize(klass, current_user, params) - @klass = klass - @current_user = current_user - @params = params - end - - def execute - items = by_scope - items = by_state(items) - items = by_project(items) - items = by_search(items) - end - - private - - def by_scope - table_name = klass.table_name - - case params[:scope] - when 'authored' then - current_user.send(table_name) - when 'all' then - klass.of_projects(current_user.authorized_projects.pluck(:id)) - else - current_user.send("assigned_#{table_name}") - end - end - - def by_state(items) - case params[:status] - when 'closed' - items.closed - when 'all' - items - else - items.opened - end - end - - def by_project(items) - if params[:project_id].present? - items = items.of_projects(params[:project_id]) - end - - items - end - - def by_search(items) - if params[:search].present? - items = items.search(params[:search]) - end - - items - end -end diff --git a/app/contexts/issues/list_context.rb b/app/contexts/issues/list_context.rb deleted file mode 100644 index b256fd4c732..00000000000 --- a/app/contexts/issues/list_context.rb +++ /dev/null @@ -1,53 +0,0 @@ -module Issues - class ListContext < BaseContext - attr_accessor :issues - - def execute - @issues = @project.issues - - @issues = case params[:state] - when 'all' then @issues - when 'closed' then @issues.closed - else @issues.opened - end - - @issues = case params[:scope] - when 'assigned-to-me' then @issues.assigned_to(current_user) - when 'created-by-me' then @issues.authored(current_user) - else @issues - end - - @issues = @issues.tagged_with(params[:label_name]) if params[:label_name].present? - @issues = @issues.includes(:author, :project) - - # 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 - - # Sort by :sort param - @issues = sort(@issues, params[:sort]) - - @issues - end - - private - - def sort(issues, condition) - case condition - when 'newest' then issues.except(:order).order('created_at DESC') - when 'oldest' then issues.except(:order).order('created_at ASC') - when 'recently_updated' then issues.except(:order).order('updated_at DESC') - when 'last_updated' then issues.except(:order).order('updated_at ASC') - when 'milestone_due_soon' then issues.except(:order).joins(:milestone).order("milestones.due_date ASC") - when 'milestone_due_later' then issues.except(:order).joins(:milestone).order("milestones.due_date DESC") - else issues - end - end - end -end diff --git a/app/contexts/merge_requests_load_context.rb b/app/contexts/merge_requests_load_context.rb deleted file mode 100644 index c3408db6e11..00000000000 --- a/app/contexts/merge_requests_load_context.rb +++ /dev/null @@ -1,35 +0,0 @@ -# Build collection of Merge Requests -# based on filtering passed via params for @project -class MergeRequestsLoadContext < BaseContext - def execute - merge_requests = @project.merge_requests - - merge_requests = case params[:state] - when 'all' then merge_requests - when 'closed' then merge_requests.closed - else merge_requests.opened - end - - merge_requests = case params[:scope] - when 'assigned-to-me' then merge_requests.assigned_to(current_user) - when 'created-by-me' then merge_requests.authored(current_user) - else merge_requests - end - - - merge_requests = merge_requests.page(params[:page]).per(20) - merge_requests = merge_requests.includes(:author, :source_project, :target_project).order("created_at desc") - - # Filter by specific assignee_id (or lack thereof)? - if params[:assignee_id].present? - merge_requests = merge_requests.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? - merge_requests = merge_requests.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id])) - end - - merge_requests - end -end diff --git a/app/contexts/search_context.rb b/app/contexts/search_context.rb deleted file mode 100644 index 5985ab1fb0c..00000000000 --- a/app/contexts/search_context.rb +++ /dev/null @@ -1,42 +0,0 @@ -class SearchContext - attr_accessor :project_ids, :current_user, :params - - def initialize(project_ids, user, params) - @project_ids, @current_user, @params = project_ids, user, params.dup - end - - def execute - query = params[:search] - query = Shellwords.shellescape(query) if query.present? - - return result unless query.present? - visibility_levels = @current_user ? [ Gitlab::VisibilityLevel::INTERNAL, Gitlab::VisibilityLevel::PUBLIC ] : [ Gitlab::VisibilityLevel::PUBLIC ] - result[:projects] = Project.where("projects.id in (?) OR projects.visibility_level in (?)", project_ids, visibility_levels).search(query).limit(20) - - # Search inside single project - single_project_search(Project.where(id: project_ids), query) - result - end - - def single_project_search(projects, query) - project = projects.first if projects.length == 1 - - if params[:search_code].present? - result[:blobs] = project.repository.search_files(query, params[:repository_ref]) unless project.empty_repo? - else - result[:merge_requests] = MergeRequest.in_projects(project_ids).search(query).order('updated_at DESC').limit(20) - result[:issues] = Issue.where(project_id: project_ids).search(query).order('updated_at DESC').limit(20) - result[:wiki_pages] = [] - end - end - - def result - @result ||= { - projects: [], - merge_requests: [], - issues: [], - wiki_pages: [], - blobs: [] - } - end -end diff --git a/app/contexts/test_hook_context.rb b/app/contexts/test_hook_context.rb deleted file mode 100644 index 63eda6c7d06..00000000000 --- a/app/contexts/test_hook_context.rb +++ /dev/null @@ -1,7 +0,0 @@ -class TestHookContext < BaseContext - def execute - hook = project.hooks.find(params[:id]) - data = GitPushService.new.sample_data(project, current_user) - hook.execute(data) - end -end diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index 89b395786b3..4bb3cf07da0 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -52,6 +52,6 @@ class Admin::GroupsController < Admin::ApplicationController private def group - @group = Group.find_by_path(params[:id]) + @group = Group.find_by(path: params[:id]) end end diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb index 7e3e29f59fb..13a7bdcf34a 100644 --- a/app/controllers/admin/projects_controller.rb +++ b/app/controllers/admin/projects_controller.rb @@ -5,7 +5,7 @@ class Admin::ProjectsController < Admin::ApplicationController def index owner_id = params[:owner_id] - user = User.find_by_id(owner_id) + user = User.find_by(id: owner_id) @projects = user ? user.owned_projects : Project.all @projects = @projects.where("visibility_level IN (?)", params[:visibility_levels]) if params[:visibility_levels].present? @@ -19,7 +19,7 @@ class Admin::ProjectsController < Admin::ApplicationController end def transfer - result = ::Projects::TransferContext.new(@project, current_user, project: params).execute(:admin) + result = ::Projects::TransferService.new(@project, current_user, project: params).execute(:admin) if result redirect_to [:admin, @project] diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 2f981627137..bdbb9a354b4 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -100,6 +100,6 @@ class Admin::UsersController < Admin::ApplicationController protected def user - @user ||= User.find_by_username!(params[:id]) + @user ||= User.find_by!(username: params[:id]) end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 0e714dbfcdf..442b1b65ce8 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -161,6 +161,8 @@ class ApplicationController < ActionController::Base headers['X-Frame-Options'] = 'DENY' headers['X-XSS-Protection'] = '1; mode=block' headers['X-UA-Compatible'] = 'IE=edge' + headers['X-Content-Type-Options'] = 'nosniff' + headers['Strict-Transport-Security'] = 'max-age=31536000' if Gitlab.config.gitlab.https end def add_gon_variables @@ -205,7 +207,7 @@ class ApplicationController < ActionController::Base end def configure_permitted_parameters - devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :email, :password) } + devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :email, :password, :login, :remember_me) } devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :name, :password, :password_confirmation) } end end diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 27955c62488..656eda9dec2 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -3,6 +3,8 @@ class DashboardController < ApplicationController before_filter :load_projects, except: [:projects] before_filter :event_filter, only: :show + before_filter :default_filter, only: [:issues, :merge_requests] + def show # Fetch only 30 projects. @@ -39,7 +41,7 @@ class DashboardController < ApplicationController current_user.authorized_projects end - @projects = @projects.where(namespace_id: Group.find_by_name(params[:group])) if params[:group].present? + @projects = @projects.where(namespace_id: Group.find_by(name: params[:group])) if params[:group].present? @projects = @projects.where(visibility_level: params[:visibility_level]) if params[:visibility_level].present? @projects = @projects.includes(:namespace) @projects = @projects.tagged_with(params[:label]) if params[:label].present? @@ -51,12 +53,12 @@ class DashboardController < ApplicationController end def merge_requests - @merge_requests = FilterContext.new(MergeRequest, current_user, params).execute + @merge_requests = FilteringService.new.execute(MergeRequest, current_user, params) @merge_requests = @merge_requests.recent.page(params[:page]).per(20) end def issues - @issues = FilterContext.new(Issue, current_user, params).execute + @issues = FilteringService.new.execute(Issue, current_user, params) @issues = @issues.recent.page(params[:page]).per(20) @issues = @issues.includes(:author, :project) @@ -71,4 +73,9 @@ class DashboardController < ApplicationController def load_projects @projects = current_user.authorized_projects.sorted_by_activity.non_archived end + + def default_filter + params[:scope] = 'assigned-to-me' if params[:scope].blank? + params[:state] = 'opened' if params[:state].blank? + end end diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 5e8efe35a46..7b418ec98f5 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -10,6 +10,8 @@ class GroupsController < ApplicationController # Load group projects before_filter :projects, except: [:new, :create] + before_filter :default_filter, only: [:issues, :merge_requests] + layout :determine_layout before_filter :set_title, only: [:new, :create] @@ -43,18 +45,14 @@ class GroupsController < ApplicationController end end - # Get authored or assigned open merge requests def merge_requests - @merge_requests = FilterContext.new(MergeRequest, current_user, params).execute - @merge_requests = @merge_requests.of_group(@group) - @merge_requests = @merge_requests.recent.page(params[:page]).per(20) + @merge_requests = FilteringService.new.execute(MergeRequest, current_user, params) + @merge_requests = @merge_requests.page(params[:page]).per(20) end - # Get only assigned issues def issues - @issues = FilterContext.new(Issue, current_user, params).execute - @issues = @issues.of_group(@group) - @issues = @issues.recent.page(params[:page]).per(20) + @issues = FilteringService.new.execute(Issue, current_user, params) + @issues = @issues.page(params[:page]).per(20) @issues = @issues.includes(:author, :project) respond_to do |format| @@ -89,7 +87,7 @@ class GroupsController < ApplicationController protected def group - @group ||= Group.find_by_path(params[:id]) + @group ||= Group.find_by(path: params[:id]) end def projects @@ -130,4 +128,10 @@ class GroupsController < ApplicationController 'group' end end + + def default_filter + params[:scope] = 'assigned-to-me' if params[:scope].blank? + params[:state] = 'opened' if params[:state].blank? + params[:group_id] = @group.id + end end diff --git a/app/controllers/profiles/groups_controller.rb b/app/controllers/profiles/groups_controller.rb index 378ff6bcf34..bdd991bec06 100644 --- a/app/controllers/profiles/groups_controller.rb +++ b/app/controllers/profiles/groups_controller.rb @@ -19,6 +19,6 @@ class Profiles::GroupsController < ApplicationController private def group - @group ||= Group.find_by_path(params[:id]) + @group ||= Group.find_by(path: params[:id]) end end diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index fc9807e3c47..2aa73471e2b 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -13,7 +13,7 @@ class Projects::BlobController < Projects::ApplicationController end def destroy - result = Files::DeleteContext.new(@project, current_user, params, @ref, @path).execute + result = Files::DeleteService.new(@project, current_user, params, @ref, @path).execute if result[:status] == :success flash[:notice] = "Your changes have been successfully committed" diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index 65b8a7283a7..c56df65dcba 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -6,34 +6,35 @@ class Projects::CommitController < Projects::ApplicationController before_filter :authorize_read_project! before_filter :authorize_code_access! before_filter :require_non_empty_project + before_filter :commit def show - result = CommitLoadContext.new(project, current_user, params).execute + return git_not_found! unless @commit - @commit = result[:commit] + @line_notes = project.notes.for_commit_id(commit.id).inline + @branches = project.repository.branch_names_contains(commit.id) - if @commit.nil? - git_not_found! - return + begin + @suppress_diff = true if commit.diff_suppress? && !params[:force_show_diff] + @force_suppress_diff = commit.diff_force_suppress? + rescue Grit::Git::GitTimeout + @suppress_diff = true + @status = :huge_commit end - @suppress_diff = result[:suppress_diff] - @force_suppress_diff = result[:force_suppress_diff] - - @note = result[:note] - @line_notes = result[:line_notes] - @branches = result[:branches] - @notes_count = result[:notes_count] + @note = project.build_commit_note(commit) + @notes_count = project.notes.for_commit_id(commit.id).count @notes = project.notes.for_commit_id(@commit.id).not_inline.fresh @noteable = @commit - @comments_allowed = @reply_allowed = true - @comments_target = { noteable_type: 'Commit', - commit_id: @commit.id } + @comments_target = { + noteable_type: 'Commit', + commit_id: @commit.id + } respond_to do |format| format.html do - if result[:status] == :huge_commit + if @status == :huge_commit render "huge_commit" and return end end @@ -42,4 +43,8 @@ class Projects::CommitController < Projects::ApplicationController format.patch { render text: @commit.to_patch } end end + + def commit + @commit ||= project.repository.commit(params[:id]) + end end diff --git a/app/controllers/projects/edit_tree_controller.rb b/app/controllers/projects/edit_tree_controller.rb index 3921273620c..aa4631300e0 100644 --- a/app/controllers/projects/edit_tree_controller.rb +++ b/app/controllers/projects/edit_tree_controller.rb @@ -7,7 +7,7 @@ class Projects::EditTreeController < Projects::BaseTreeController end def update - result = Files::UpdateContext.new(@project, current_user, params, @ref, @path).execute + result = Files::UpdateService.new(@project, current_user, params, @ref, @path).execute if result[:status] == :success flash[:notice] = "Your changes have been successfully committed" diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb index 314d87df034..a863b318324 100644 --- a/app/controllers/projects/hooks_controller.rb +++ b/app/controllers/projects/hooks_controller.rb @@ -24,15 +24,20 @@ class Projects::HooksController < Projects::ApplicationController end def test - TestHookContext.new(project, current_user, params).execute + TestHookService.new.execute(hook, current_user) redirect_to :back end def destroy - @hook = @project.hooks.find(params[:id]) - @hook.destroy + hook.destroy redirect_to project_hooks_path(@project) end + + private + + def hook + @hook ||= @project.hooks.find(params[:id]) + end end diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index c58ac71277e..2ec270b3159 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -89,7 +89,7 @@ class Projects::IssuesController < Projects::ApplicationController end def bulk_update - result = Issues::BulkUpdateContext.new(project, current_user, params).execute + result = Issues::BulkUpdateService.new(project, current_user, params).execute redirect_to :back, notice: "#{result[:count]} issues updated" end @@ -97,7 +97,7 @@ class Projects::IssuesController < Projects::ApplicationController def issue @issue ||= begin - @project.issues.find_by_iid!(params[:id]) + @project.issues.find_by!(iid: params[:id]) rescue ActiveRecord::RecordNotFound redirect_old end @@ -116,7 +116,9 @@ class Projects::IssuesController < Projects::ApplicationController end def issues_filtered - @issues = Issues::ListContext.new(project, current_user, params).execute + params[:scope] = 'all' if params[:scope].blank? + params[:state] = 'opened' if params[:state].blank? + @issues = FilteringService.new.execute(Issue, current_user, params.merge(project_id: @project.id)) end # Since iids are implemented only in 6.1 @@ -125,7 +127,7 @@ class Projects::IssuesController < Projects::ApplicationController # To prevent 404 errors we provide a redirect to correct iids until 7.0 release # def redirect_old - issue = @project.issues.find_by_id(params[:id]) + issue = @project.issues.find_by(id: params[:id]) if issue redirect_to project_issue_path(@project, issue) diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index bba08bdd782..7d56f091575 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -17,7 +17,14 @@ class Projects::MergeRequestsController < Projects::ApplicationController before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort] def index - @merge_requests = MergeRequestsLoadContext.new(project, current_user, params).execute + params[:sort] ||= 'newest' + params[:scope] = 'all' if params[:scope].blank? + params[:state] = 'opened' if params[:state].blank? + + @merge_requests = FilteringService.new.execute(MergeRequest, current_user, params.merge(project_id: @project.id)) + @merge_requests = @merge_requests.page(params[:page]).per(20) + + @sort = params[:sort].humanize assignee_id, milestone_id = params[:assignee_id], params[:milestone_id] @assignee = @project.team.find(assignee_id) if assignee_id.present? && !assignee_id.to_i.zero? @milestone = @project.milestones.find(milestone_id) if milestone_id.present? && !milestone_id.to_i.zero? @@ -123,7 +130,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController if @merge_request.opened? && @merge_request.can_be_merged? @merge_request.should_remove_source_branch = params[:should_remove_source_branch] - @merge_request.automerge!(current_user) + @merge_request.automerge!(current_user, params[:merge_commit_message]) @status = true else @status = false @@ -145,6 +152,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController @target_project = selected_target_project @target_branches = @target_project.repository.branch_names @target_branches + + respond_to do |format| + format.js + end end def ci_status @@ -161,7 +172,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController end def merge_request - @merge_request ||= @project.merge_requests.find_by_iid!(params[:id]) + @merge_request ||= @project.merge_requests.find_by!(iid: params[:id]) end def closes_issues diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index ecb1fc1d566..aea92a19f34 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -76,7 +76,7 @@ class Projects::MilestonesController < Projects::ApplicationController protected def milestone - @milestone ||= @project.milestones.find_by_iid!(params[:id]) + @milestone ||= @project.milestones.find_by!(iid: params[:id]) end def authorize_admin_milestone! diff --git a/app/controllers/projects/new_tree_controller.rb b/app/controllers/projects/new_tree_controller.rb index 933a0cb876e..2f3647ab071 100644 --- a/app/controllers/projects/new_tree_controller.rb +++ b/app/controllers/projects/new_tree_controller.rb @@ -6,7 +6,7 @@ class Projects::NewTreeController < Projects::BaseTreeController def update file_path = File.join(@path, File.basename(params[:file_name])) - result = Files::CreateContext.new(@project, current_user, params, @ref, file_path).execute + result = Files::CreateService.new(@project, current_user, params, @ref, file_path).execute if result[:status] == :success flash[:notice] = "Your changes have been successfully committed" diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb index 261841f1ea2..9c9c2decc78 100644 --- a/app/controllers/projects/notes_controller.rb +++ b/app/controllers/projects/notes_controller.rb @@ -5,7 +5,7 @@ class Projects::NotesController < Projects::ApplicationController before_filter :authorize_admin_note!, only: [:update, :destroy] def index - @notes = Notes::LoadContext.new(project, current_user, params).execute + @notes = Notes::LoadService.new(project, current_user, params).execute notes_json = { notes: [] } @@ -20,7 +20,7 @@ class Projects::NotesController < Projects::ApplicationController end def create - @note = Notes::CreateContext.new(project, current_user, params).execute + @note = Notes::CreateService.new(project, current_user, params).execute respond_to do |format| format.json { render_note_json(@note) } diff --git a/app/controllers/projects/repositories_controller.rb b/app/controllers/projects/repositories_controller.rb index 20e2a9311ee..f686db70bd4 100644 --- a/app/controllers/projects/repositories_controller.rb +++ b/app/controllers/projects/repositories_controller.rb @@ -16,7 +16,7 @@ class Projects::RepositoriesController < Projects::ApplicationController storage_path = Rails.root.join("tmp", "repositories") - file_path = @repository.archive_repo(params[:ref], storage_path) + file_path = @repository.archive_repo(params[:ref], storage_path, params[:format].downcase) if file_path # Send file to user diff --git a/app/controllers/projects/team_members_controller.rb b/app/controllers/projects/team_members_controller.rb index 2c40b3c75f2..44068878cd1 100644 --- a/app/controllers/projects/team_members_controller.rb +++ b/app/controllers/projects/team_members_controller.rb @@ -26,7 +26,7 @@ class Projects::TeamMembersController < Projects::ApplicationController end def update - @user_project_relation = project.users_projects.find_by_user_id(member) + @user_project_relation = project.users_projects.find_by(user_id: member) @user_project_relation.update_attributes(params[:team_member]) unless @user_project_relation.valid? @@ -36,7 +36,7 @@ class Projects::TeamMembersController < Projects::ApplicationController end def destroy - @user_project_relation = project.users_projects.find_by_user_id(member) + @user_project_relation = project.users_projects.find_by(user_id: member) @user_project_relation.destroy respond_to do |format| @@ -46,7 +46,7 @@ class Projects::TeamMembersController < Projects::ApplicationController end def leave - project.users_projects.find_by_user_id(current_user).destroy + project.users_projects.find_by(user_id: current_user).destroy respond_to do |format| format.html { redirect_to :back } @@ -65,6 +65,6 @@ class Projects::TeamMembersController < Projects::ApplicationController protected def member - @member ||= User.find_by_username(params[:id]) + @member ||= User.find_by(username: params[:id]) end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index e1c55e7d913..6ec109b9145 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -20,7 +20,7 @@ class ProjectsController < ApplicationController end def create - @project = ::Projects::CreateContext.new(current_user, params[:project]).execute + @project = ::Projects::CreateService.new(current_user, params[:project]).execute respond_to do |format| flash[:notice] = 'Project was successfully created.' if @project.saved? @@ -36,7 +36,7 @@ class ProjectsController < ApplicationController end def update - status = ::Projects::UpdateContext.new(@project, current_user, params).execute + status = ::Projects::UpdateService.new(@project, current_user, params).execute respond_to do |format| if status @@ -51,7 +51,7 @@ class ProjectsController < ApplicationController end def transfer - ::Projects::TransferContext.new(project, current_user, params).execute + ::Projects::TransferService.new(project, current_user, params).execute end def show @@ -89,7 +89,7 @@ class ProjectsController < ApplicationController end def fork - @forked_project = ::Projects::ForkContext.new(project, current_user).execute + @forked_project = ::Projects::ForkService.new(project, current_user).execute respond_to do |format| format.html do diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 2a2748dc1fb..c1648d6c387 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -1,26 +1,23 @@ class SearchController < ApplicationController - def show - project_id = params[:project_id] - group_id = params[:group_id] + include SearchHelper - project_ids = current_user.authorized_projects.map(&:id) + def show + @project = Project.find_by(id: params[:project_id]) if params[:project_id].present? + @group = Group.find_by(id: params[:group_id]) if params[:group_id].present? - if group_id.present? - @group = Group.find(group_id) - group_project_ids = @group.projects.map(&:id) - project_ids.select! { |id| group_project_ids.include?(id)} - elsif project_id.present? - @project = Project.find(params[:project_id]) - project_ids.select! { |id| id == project_id.to_i} + if @project + return access_denied! unless can?(current_user, :download_code, @project) + @search_results = Search::ProjectService.new(@project, current_user, params).execute + else + @search_results = Search::GlobalService.new(current_user, params).execute end + end - result = SearchContext.new(project_ids, current_user, params).execute + def autocomplete + term = params[:term] + @project = Project.find(params[:project_id]) if params[:project_id].present? + @ref = params[:project_ref] if params[:project_ref].present? - @projects = result[:projects] - @merge_requests = result[:merge_requests] - @issues = result[:issues] - @wiki_pages = result[:wiki_pages] - @blobs = Kaminari.paginate_array(result[:blobs]).page(params[:page]).per(20) - @total_results = @projects.count + @merge_requests.count + @issues.count + @wiki_pages.count + @blobs.total_count + render json: search_autocomplete_opts(term).to_json end end diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index b91f68aab5e..e54a968326f 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -18,7 +18,7 @@ class SnippetsController < ApplicationController end def user_index - @user = User.find_by_username(params[:username]) + @user = User.find_by(username: params[:username]) @snippets = @user.snippets.fresh.non_expired if @user == current_user diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 4947c33f959..6a5ce62909e 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -2,8 +2,8 @@ class UsersController < ApplicationController layout 'navless' def show - @user = User.find_by_username!(params[:username]) - @projects = @user.authorized_projects.where('projects.id in (?)', current_user.authorized_projects.map(&:id)) + @user = User.find_by!(username: params[:username]) + @projects = @user.authorized_projects.where(id: current_user.authorized_projects.pluck(:id)).includes(:namespace) @events = @user.recent_events.where(project_id: @projects.map(&:id)).limit(20) @title = @user.name diff --git a/app/controllers/users_groups_controller.rb b/app/controllers/users_groups_controller.rb index 749da1e1413..bc5db445528 100644 --- a/app/controllers/users_groups_controller.rb +++ b/app/controllers/users_groups_controller.rb @@ -30,7 +30,7 @@ class UsersGroupsController < ApplicationController protected def group - @group ||= Group.find_by_path(params[:group_id]) + @group ||= Group.find_by(path: params[:group_id]) end def authorize_admin_group! diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 7ca52598cfb..e60cba2bb2b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -50,7 +50,7 @@ module ApplicationHelper end def avatar_icon(user_email = '', size = nil) - user = User.find_by_email(user_email) + user = User.find_by(email: user_email) if user && user.avatar.present? user.avatar.url else @@ -72,7 +72,7 @@ module ApplicationHelper def last_commit(project) if project.repo_exists? - time_ago_with_tooltip(project.repository.commit.committed_date) + " ago" + time_ago_with_tooltip(project.repository.commit.committed_date) else "Never" end @@ -210,11 +210,15 @@ module ApplicationHelper def time_ago_with_tooltip(date, placement = 'top', html_class = 'time_ago') capture_haml do - haml_tag :time, time_ago_in_words(date), - class: html_class, datetime: date, title: date.stamp("Aug 21, 2011 9:23pm"), + haml_tag :time, date.to_s, + class: html_class, datetime: date.getutc.iso8601, title: date.stamp("Aug 21, 2011 9:23pm"), data: { toggle: 'tooltip', placement: placement } - haml_tag :script, "$('." + html_class + "').tooltip()" + haml_tag :script, "$('." + html_class + "').timeago().tooltip()" end.html_safe end + + def render_markup(file_name, file_content) + GitHub::Markup.render(file_name, file_content).html_safe + end end diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb index 7f86a833cb0..d5712ab3374 100644 --- a/app/helpers/dashboard_helper.rb +++ b/app/helpers/dashboard_helper.rb @@ -1,7 +1,7 @@ module DashboardHelper def filter_path(entity, options={}) exist_opts = { - status: params[:status], + state: params[:state], scope: params[:scope], project_id: params[:project_id], } diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb index 9a6aea85ee9..d1eb3808f9e 100644 --- a/app/helpers/labels_helper.rb +++ b/app/helpers/labels_helper.rb @@ -16,11 +16,11 @@ module LabelsHelper when *klass.warning_labels 'label-warning' when *klass.neutral_labels - 'label-inverse' + 'label-primary' when *klass.positive_labels 'label-success' when *klass.important_labels - 'label-important' + 'label-danger' else 'label-info' end diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb index ec5f8a6ded4..695147cd6db 100644 --- a/app/helpers/notes_helper.rb +++ b/app/helpers/notes_helper.rb @@ -23,11 +23,11 @@ module NotesHelper def note_timestamp(note) # Shows the created at time and the updated at time if different - ts = "#{time_ago_with_tooltip(note.created_at, 'bottom', 'note_created_ago')} ago" + ts = "#{time_ago_with_tooltip(note.created_at, 'bottom', 'note_created_ago')}" if note.updated_at != note.created_at ts << capture_haml do haml_tag :small do - haml_concat " (Edited #{time_ago_with_tooltip(note.updated_at, 'bottom', 'note_edited_ago')} ago)" + haml_concat " (Edited #{time_ago_with_tooltip(note.updated_at, 'bottom', 'note_edited_ago')})" end end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 33ae4134306..a6a507360bd 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -153,7 +153,7 @@ module ProjectsHelper "#{@project.path}\/#{@path} at #{@ref} - " + title elsif current_controller?(:issues) if current_action?(:show) - "Issue ##{@issue.iid} - " + title + "Issue ##{@issue.iid} - #{@issue.title} - " + title else "Issues - " + title end @@ -180,8 +180,9 @@ module ProjectsHelper title end - def default_url_to_repo - current_user ? @project.url_to_repo : @project.http_url_to_repo + def default_url_to_repo(project = nil) + project = project || @project + current_user ? project.url_to_repo : project.http_url_to_repo end def default_clone_protocol @@ -190,7 +191,7 @@ module ProjectsHelper def project_last_activity(project) if project.last_activity_at - time_ago_with_tooltip(project.last_activity_at, 'bottom', 'last_activity_time_ago') + " ago" + time_ago_with_tooltip(project.last_activity_at, 'bottom', 'last_activity_time_ago') else "Never" end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index f24156e4d85..470a495f036 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -1,16 +1,22 @@ module SearchHelper - def search_autocomplete_source + def search_autocomplete_opts(term) return unless current_user + + resources_results = [ + groups_autocomplete(term), + projects_autocomplete(term), + public_projects_autocomplete(term), + ].flatten + + generic_results = project_autocomplete + default_autocomplete + help_autocomplete + generic_results.select! { |result| result[:label] =~ Regexp.new(term, "i") } + [ - groups_autocomplete, - projects_autocomplete, - public_projects_autocomplete, - default_autocomplete, - project_autocomplete, - help_autocomplete + resources_results, + generic_results ].flatten.uniq do |item| item[:label] - end.to_json + end end private @@ -43,7 +49,7 @@ module SearchHelper # Autocomplete results for the current project, if it's defined def project_autocomplete if @project && @project.repository.exists? && @project.repository.root_ref - prefix = simple_sanitize(@project.name_with_namespace) + prefix = search_result_sanitize(@project.name_with_namespace) ref = @ref || @project.repository.root_ref [ @@ -65,23 +71,36 @@ module SearchHelper end # Autocomplete results for the current user's groups - def groups_autocomplete - current_user.authorized_groups.map do |group| - { label: "group: #{simple_sanitize(group.name)}", url: group_path(group) } + def groups_autocomplete(term, limit = 5) + current_user.authorized_groups.search(term).limit(limit).map do |group| + { + label: "group: #{search_result_sanitize(group.name)}", + url: group_path(group) + } end end # Autocomplete results for the current user's projects - def projects_autocomplete - current_user.authorized_projects.non_archived.map do |p| - { label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) } + def projects_autocomplete(term, limit = 5) + current_user.authorized_projects.search_by_title(term).non_archived.limit(limit).map do |p| + { + label: "project: #{search_result_sanitize(p.name_with_namespace)}", + url: project_path(p) + } end end # Autocomplete results for the current user's projects - def public_projects_autocomplete - Project.public_or_internal_only(current_user).non_archived.map do |p| - { label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) } + def public_projects_autocomplete(term, limit = 5) + Project.public_or_internal_only(current_user).search_by_title(term).non_archived.limit(limit).map do |p| + { + label: "project: #{search_result_sanitize(p.name_with_namespace)}", + url: project_path(p) + } end end + + def search_result_sanitize(str) + Sanitize.clean(str) + end end diff --git a/app/mailers/emails/issues.rb b/app/mailers/emails/issues.rb index 5abdf99529c..b2b4b83d6c3 100644 --- a/app/mailers/emails/issues.rb +++ b/app/mailers/emails/issues.rb @@ -8,7 +8,7 @@ module Emails def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id) @issue = Issue.find(issue_id) - @previous_assignee = User.find_by_id(previous_assignee_id) if previous_assignee_id + @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id @project = @issue.project mail(to: recipient(recipient_id), subject: subject("Changed issue ##{@issue.iid}", @issue.title)) end diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb index 25b8bf755e2..e60887d525a 100644 --- a/app/mailers/emails/merge_requests.rb +++ b/app/mailers/emails/merge_requests.rb @@ -8,7 +8,7 @@ module Emails def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id) @merge_request = MergeRequest.find(merge_request_id) - @previous_assignee = User.find_by_id(previous_assignee_id) if previous_assignee_id + @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id @project = @merge_request.project mail(to: recipient(recipient_id), subject: subject("Changed merge request ##{@merge_request.iid}", @merge_request.title)) end diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 58bf621f91b..0f1dad4ef16 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -45,6 +45,18 @@ module Issuable def search(query) where("title like :query", query: "%#{query}%") end + + def sort(method) + case method.to_s + when 'newest' then reorder('created_at DESC') + when 'oldest' then reorder('created_at ASC') + when 'recently_updated' then reorder('updated_at DESC') + when 'last_updated' then reorder('updated_at ASC') + when 'milestone_due_soon' then joins(:milestone).reorder("milestones.due_date ASC") + when 'milestone_due_later' then joins(:milestone).reorder("milestones.due_date DESC") + else reorder('created_at DESC') + end + end end def today? diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index e59aee8b445..da7aebd944f 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -214,8 +214,8 @@ class MergeRequest < ActiveRecord::Base self.merge end - def automerge!(current_user) - if Gitlab::Satellite::MergeAction.new(current_user, self).merge! && self.unmerged_commits.empty? + def automerge!(current_user, commit_message = nil) + if Gitlab::Satellite::MergeAction.new(current_user, self).merge!(commit_message) && self.unmerged_commits.empty? self.merge!(current_user.id) true end @@ -319,6 +319,15 @@ class MergeRequest < ActiveRecord::Base update_all(updated_at: Time.now) end + def merge_commit_message + message = "Merge branch '#{source_branch}' into '#{target_branch}'" + message << "\n\n" + message << title.to_s + message << "\n\n" + message << description.to_s + message + end + private def dump_commits(commits) diff --git a/app/models/note.rb b/app/models/note.rb index 48b36bcafdf..f4c0be3307f 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -82,6 +82,18 @@ class Note < ActiveRecord::Base }, without_protection: true) end + def create_assignee_change_note(noteable, project, author, assignee) + body = assignee.nil? ? '_Assignee removed_' : "_Reassigned to @#{assignee.username}_" + + create({ + noteable: noteable, + project: project, + author: author, + note: body, + system: true + }, without_protection: true) + end + def discussions_from_notes(notes) discussion_ids = [] discussions = [] @@ -111,8 +123,8 @@ class Note < ActiveRecord::Base def commit_author @commit_author ||= - project.users.find_by_email(noteable.author_email) || - project.users.find_by_name(noteable.author_name) + project.users.find_by(email: noteable.author_email) || + project.users.find_by(name: noteable.author_name) rescue nil end diff --git a/app/models/project.rb b/app/models/project.rb index a55f7a65b0b..579644d1119 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -138,13 +138,17 @@ class Project < ActiveRecord::Base joins(:namespace).where("projects.archived = ?", false).where("projects.name LIKE :query OR projects.path LIKE :query OR namespaces.name LIKE :query OR projects.description LIKE :query", query: "%#{query}%") end + def search_by_title query + where("projects.archived = ?", false).where("LOWER(projects.name) LIKE :query", query: "%#{query.downcase}%") + end + def find_with_namespace(id) if id.include?("/") id = id.split("/") - namespace = Namespace.find_by_path(id.first) + namespace = Namespace.find_by(path: id.first) return nil unless namespace - where(namespace_id: namespace.id).find_by_path(id.second) + where(namespace_id: namespace.id).find_by(path: id.second) else where(path: id, namespace_id: nil).last end @@ -201,6 +205,10 @@ class Project < ActiveRecord::Base [Gitlab.config.gitlab.url, path_with_namespace].join("/") end + def web_url_without_protocol + web_url.split("://")[1] + end + def build_commit_note(commit) notes.new(commit_id: commit.id, noteable_type: "Commit") end @@ -270,9 +278,7 @@ class Project < ActiveRecord::Base end def send_move_instructions - team.members.each do |user| - Notify.delay.project_was_moved_email(self.id, user.id) - end + NotificationService.new.project_was_moved(self) end def owner @@ -290,7 +296,7 @@ class Project < ActiveRecord::Base # Get Team Member record by user id def team_member_by_id(user_id) - users_projects.find_by_user_id(user_id) + users_projects.find_by(user_id: user_id) end def name_with_namespace diff --git a/app/models/project_team.rb b/app/models/project_team.rb index 5630f280aea..eca13e56061 100644 --- a/app/models/project_team.rb +++ b/app/models/project_team.rb @@ -22,22 +22,22 @@ class ProjectTeam end def find(user_id) - user = project.users.find_by_id(user_id) + user = project.users.find_by(id: user_id) if group - user ||= group.users.find_by_id(user_id) + user ||= group.users.find_by(id: user_id) end user end def find_tm(user_id) - tm = project.users_projects.find_by_user_id(user_id) + tm = project.users_projects.find_by(user_id: user_id) # If user is not in project members # we should check for group membership if group && !tm - tm = group.users_groups.find_by_user_id(user_id) + tm = group.users_groups.find_by(user_id: user_id) end tm diff --git a/app/models/user.rb b/app/models/user.rb index f2cd554f9c3..1acf330cabe 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -41,7 +41,8 @@ # confirmed_at :datetime # confirmation_sent_at :datetime # unconfirmed_email :string(255) -# hide_no_ssh_key :boolean default(FALSE), not null +# hide_no_ssh_key :boolean default(FALSE) +# website_url :string(255) default(""), not null # require 'carrierwave/orm/activerecord' @@ -52,7 +53,7 @@ class User < ActiveRecord::Base :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :confirmable, :registerable attr_accessible :email, :password, :password_confirmation, :remember_me, :bio, :name, :username, - :skype, :linkedin, :twitter, :color_scheme_id, :theme_id, :force_random_password, + :skype, :linkedin, :twitter, :website_url, :color_scheme_id, :theme_id, :force_random_password, :extern_uid, :provider, :password_expires_at, :avatar, :hide_no_ssh_key, as: [:default, :admin] @@ -103,7 +104,7 @@ class User < ActiveRecord::Base # Validations # validates :name, presence: true - validates :email, presence: true, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ }, uniqueness: true + validates :email, presence: true, email: {strict_mode: true}, uniqueness: true validates :bio, length: { maximum: 255 }, allow_blank: true validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider} validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0} @@ -238,7 +239,7 @@ class User < ActiveRecord::Base def namespace_uniq namespace_name = self.username - if Namespace.find_by_path(namespace_name) + if Namespace.find_by(path: namespace_name) self.errors.add :username, "already exist" end end @@ -382,7 +383,7 @@ class User < ActiveRecord::Base end def created_by - User.find_by_id(created_by_id) if created_by_id + User.find_by(id: created_by_id) if created_by_id end def sanitize_attrs @@ -424,4 +425,14 @@ class User < ActiveRecord::Base order('id DESC').limit(1000). update_all(updated_at: Time.now) end + + def full_website_url + return "http://#{website_url}" if website_url !~ /^https?:\/\// + + website_url + end + + def short_website_url + website_url.gsub(/https?:\/\//, '') + end end diff --git a/app/models/web_hook.rb b/app/models/web_hook.rb index c0aa3734917..8a5c4b6cd47 100644 --- a/app/models/web_hook.rb +++ b/app/models/web_hook.rb @@ -28,7 +28,7 @@ class WebHook < ActiveRecord::Base def execute(data) parsed_url = URI.parse(url) if parsed_url.userinfo.blank? - WebHook.post(url, body: data.to_json, headers: { "Content-Type" => "application/json" }) + WebHook.post(url, body: data.to_json, headers: { "Content-Type" => "application/json" }, verify: false) else post_url = url.gsub("#{parsed_url.userinfo}@", "") auth = { @@ -38,6 +38,7 @@ class WebHook < ActiveRecord::Base WebHook.post(post_url, body: data.to_json, headers: {"Content-Type" => "application/json"}, + verify: false, basic_auth: auth) end end diff --git a/app/observers/issue_observer.rb b/app/observers/issue_observer.rb index 1575cf0f19f..6ef13eb5d5e 100644 --- a/app/observers/issue_observer.rb +++ b/app/observers/issue_observer.rb @@ -19,6 +19,7 @@ class IssueObserver < BaseObserver def after_update(issue) if issue.is_being_reassigned? notification.reassigned_issue(issue, current_user) + create_assignee_note(issue) end issue.notice_added_references(issue.project, current_user) @@ -32,6 +33,10 @@ class IssueObserver < BaseObserver Note.create_status_change_note(issue, issue.project, current_user, issue.state, current_commit) end + def create_assignee_note(issue) + Note.create_assignee_change_note(issue, issue.project, current_user, issue.assignee) + end + def execute_hooks(issue) issue.project.execute_hooks(issue.to_hook_data, :issue_hooks) end diff --git a/app/observers/system_hook_observer.rb b/app/observers/system_hook_observer.rb index 3a649fd590d..80de177b9a2 100644 --- a/app/observers/system_hook_observer.rb +++ b/app/observers/system_hook_observer.rb @@ -2,10 +2,16 @@ class SystemHookObserver < BaseObserver observe :user, :project, :users_project def after_create(model) - SystemHooksService.execute_hooks_for(model, :create) + system_hook_service.execute_hooks_for(model, :create) end def after_destroy(model) - SystemHooksService.execute_hooks_for(model, :destroy) + system_hook_service.execute_hooks_for(model, :destroy) + end + + private + + def system_hook_service + SystemHooksService.new end end diff --git a/app/contexts/base_context.rb b/app/services/base_service.rb index 6accd9b2457..610f0474872 100644 --- a/app/contexts/base_context.rb +++ b/app/services/base_service.rb @@ -1,4 +1,4 @@ -class BaseContext +class BaseService attr_accessor :project, :current_user, :params def initialize(project, user, params) diff --git a/app/contexts/files/base_context.rb b/app/services/files/base_service.rb index 44f9826652c..f1765d38976 100644 --- a/app/contexts/files/base_context.rb +++ b/app/services/files/base_service.rb @@ -1,5 +1,5 @@ module Files - class BaseContext < ::BaseContext + class BaseService < ::BaseService attr_reader :ref, :path def initialize(project, user, params, ref, path = nil) diff --git a/app/contexts/files/create_context.rb b/app/services/files/create_service.rb index b3d62a028c7..185ab26d96b 100644 --- a/app/contexts/files/create_context.rb +++ b/app/services/files/create_service.rb @@ -1,7 +1,7 @@ -require_relative "base_context" +require_relative "base_service" module Files - class CreateContext < BaseContext + class CreateService < BaseService def execute allowed = if project.protected_branch?(ref) can?(current_user, :push_code_to_protected_branches, project) @@ -33,7 +33,8 @@ module Files new_file_action = Gitlab::Satellite::NewFileAction.new(current_user, project, ref, file_path) created_successfully = new_file_action.commit!( params[:content], - params[:commit_message] + params[:commit_message], + params[:encoding] ) if created_successfully diff --git a/app/contexts/files/delete_context.rb b/app/services/files/delete_service.rb index 39ff7c2a4b1..30e512d0912 100644 --- a/app/contexts/files/delete_context.rb +++ b/app/services/files/delete_service.rb @@ -1,7 +1,7 @@ -require_relative "base_context" +require_relative "base_service" module Files - class DeleteContext < BaseContext + class DeleteService < BaseService def execute allowed = if project.protected_branch?(ref) can?(current_user, :push_code_to_protected_branches, project) diff --git a/app/contexts/files/update_context.rb b/app/services/files/update_service.rb index 556027a3256..d59802ae485 100644 --- a/app/contexts/files/update_context.rb +++ b/app/services/files/update_service.rb @@ -1,7 +1,7 @@ -require_relative "base_context" +require_relative "base_service" module Files - class UpdateContext < BaseContext + class UpdateService < BaseService def execute allowed = if project.protected_branch?(ref) can?(current_user, :push_code_to_protected_branches, project) @@ -23,10 +23,11 @@ module Files return error("You can only edit text files") end - new_file_action = Gitlab::Satellite::EditFileAction.new(current_user, project, ref, path) - created_successfully = new_file_action.commit!( + edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, project, ref, path) + created_successfully = edit_file_action.commit!( params[:content], - params[:commit_message] + params[:commit_message], + params[:encoding] ) if created_successfully diff --git a/app/services/filtering_service.rb b/app/services/filtering_service.rb new file mode 100644 index 00000000000..b339065890b --- /dev/null +++ b/app/services/filtering_service.rb @@ -0,0 +1,123 @@ +# FilteringService class +# +# Used to filter Issues and MergeRequests collections by set of params +# +# Arguments: +# klass - actual class like Issue or MergeRequest +# current_user - which user use +# params: +# scope: 'created-by-me' or 'assigned-to-me' or 'all' +# state: 'open' or 'closed' or 'all' +# group_id: integer +# project_id: integer +# milestone_id: integer +# assignee_id: integer +# search: string +# label_name: string +# sort: string +# +class FilteringService + attr_accessor :klass, :current_user, :params + + def execute(klass, current_user, params) + @klass = klass + @current_user = current_user + @params = params + + items = by_scope + items = by_state(items) + items = by_group(items) + items = by_project(items) + items = by_search(items) + items = by_milestone(items) + items = by_assignee(items) + items = by_label(items) + items = sort(items) + end + + private + + def by_scope + table_name = klass.table_name + + case params[:scope] + when 'created-by-me', 'authored' then + current_user.send(table_name) + when 'all' then + if current_user + klass.of_projects(current_user.authorized_projects.pluck(:id)) + else + klass.of_projects(Project.public_only) + end + when 'assigned-to-me' then + current_user.send("assigned_#{table_name}") + else + raise 'You must specify default scope' + end + end + + def by_state(items) + case params[:state] + when 'closed' + items.closed + when 'all' + items + when 'opened' + items.opened + else + raise 'You must specify default state' + end + end + + def by_group(items) + if params[:group_id].present? + items = items.of_group(Group.find(params[:group_id])) + end + + items + end + + def by_project(items) + if params[:project_id].present? + items = items.of_projects(params[:project_id]) + end + + items + end + + def by_search(items) + if params[:search].present? + items = items.search(params[:search]) + end + + items + end + + def sort(items) + items.sort(params[:sort]) + end + + def by_milestone(items) + if params[:milestone_id].present? + items = items.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id])) + end + + items + end + + def by_assignee(items) + if params[:assignee_id].present? + items = items.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id])) + end + + items + end + + def by_label(items) + if params[:label_name].present? + items = items.tagged_with(params[:label_name]) + end + + items + end +end diff --git a/app/contexts/issues/bulk_update_context.rb b/app/services/issues/bulk_update_service.rb index ab38a4f8ab5..f72a346af6f 100644 --- a/app/contexts/issues/bulk_update_context.rb +++ b/app/services/issues/bulk_update_service.rb @@ -1,5 +1,5 @@ module Issues - class BulkUpdateContext < BaseContext + class BulkUpdateService < BaseService def execute update_data = params[:update] diff --git a/app/contexts/notes/create_context.rb b/app/services/notes/create_service.rb index 36ea76ff949..fb87e175933 100644 --- a/app/contexts/notes/create_context.rb +++ b/app/services/notes/create_service.rb @@ -1,5 +1,5 @@ module Notes - class CreateContext < BaseContext + class CreateService < BaseService def execute note = project.notes.new(params[:note]) note.author = current_user diff --git a/app/contexts/notes/load_context.rb b/app/services/notes/load_service.rb index 234e9ac3cdd..f7ad7d60a3a 100644 --- a/app/contexts/notes/load_context.rb +++ b/app/services/notes/load_service.rb @@ -1,5 +1,5 @@ module Notes - class LoadContext < BaseContext + class LoadService < BaseService def execute target_type = params[:target_type] target_id = params[:target_id] diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index eb42cac3f83..7c02777e914 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -157,6 +157,15 @@ class NotificationService mailer.group_access_granted_email(users_group.id) end + def project_was_moved(project) + recipients = project.team.members + recipients = reject_muted_users(recipients, project) + + recipients.each do |recipient| + mailer.project_was_moved_email(project.id, recipient.id) + end + end + protected # Get project users with WATCH notification level @@ -186,10 +195,10 @@ class NotificationService users.reject do |user| next user.notification.disabled? unless project - tm = project.users_projects.find_by_user_id(user.id) + tm = project.users_projects.find_by(user_id: user.id) if !tm && project.group - tm = project.group.users_groups.find_by_user_id(user.id) + tm = project.group.users_groups.find_by(user_id: user.id) end # reject users who globally disabled notification and has no membership diff --git a/app/contexts/projects/create_context.rb b/app/services/projects/create_service.rb index 2acb9fbfe14..ba131d8ffbe 100644 --- a/app/contexts/projects/create_context.rb +++ b/app/services/projects/create_service.rb @@ -1,5 +1,5 @@ module Projects - class CreateContext < BaseContext + class CreateService < BaseService def initialize(user, params) @current_user, @params = user, params.dup end @@ -73,7 +73,7 @@ module Projects end def allowed_namespace?(user, namespace_id) - namespace = Namespace.find_by_id(namespace_id) + namespace = Namespace.find_by(id: namespace_id) current_user.can?(:manage_namespace, namespace) end end diff --git a/app/contexts/projects/fork_context.rb b/app/services/projects/fork_service.rb index fbc67220d5d..2f1c7b18aa0 100644 --- a/app/contexts/projects/fork_context.rb +++ b/app/services/projects/fork_service.rb @@ -1,5 +1,5 @@ module Projects - class ForkContext < BaseContext + class ForkService < BaseService include Gitlab::ShellAdapter def initialize(project, user) diff --git a/app/contexts/projects/transfer_context.rb b/app/services/projects/transfer_service.rb index 3011984e3f8..f8e27f6f1c6 100644 --- a/app/contexts/projects/transfer_context.rb +++ b/app/services/projects/transfer_service.rb @@ -1,5 +1,5 @@ module Projects - class TransferContext < BaseContext + class TransferService < BaseService def execute(role = :default) namespace_id = params[:project].delete(:namespace_id) allowed_transfer = can?(current_user, :change_namespace, project) || role == :admin diff --git a/app/contexts/projects/update_context.rb b/app/services/projects/update_service.rb index 94de10de0f6..d9d371da5c4 100644 --- a/app/contexts/projects/update_context.rb +++ b/app/services/projects/update_service.rb @@ -1,5 +1,5 @@ module Projects - class UpdateContext < BaseContext + class UpdateService < BaseService def execute(role = :default) params[:project].delete(:namespace_id) # check that user is allowed to set specified visibility_level diff --git a/app/services/search/global_service.rb b/app/services/search/global_service.rb new file mode 100644 index 00000000000..c1130401578 --- /dev/null +++ b/app/services/search/global_service.rb @@ -0,0 +1,40 @@ +module Search + class GlobalService + attr_accessor :current_user, :params + + def initialize(user, params) + @current_user, @params = user, params.dup + end + + def execute + query = params[:search] + query = Shellwords.shellescape(query) if query.present? + return result unless query.present? + + authorized_projects_ids = [] + authorized_projects_ids += current_user.authorized_projects.pluck(:id) if current_user + authorized_projects_ids += Project.public_or_internal_only(current_user).pluck(:id) + + group = Group.find_by(id: params[:group_id]) if params[:group_id].present? + projects = Project.where(id: authorized_projects_ids) + projects = projects.where(namespace_id: group.id) if group + projects = projects.search(query) + project_ids = projects.pluck(:id) + + result[:projects] = projects.limit(20) + result[:merge_requests] = MergeRequest.in_projects(project_ids).search(query).order('updated_at DESC').limit(20) + result[:issues] = Issue.where(project_id: project_ids).search(query).order('updated_at DESC').limit(20) + result[:total_results] = %w(projects issues merge_requests).sum { |items| result[items.to_sym].size } + result + end + + def result + @result ||= { + projects: [], + merge_requests: [], + issues: [], + total_results: 0, + } + end + end +end diff --git a/app/services/search/project_service.rb b/app/services/search/project_service.rb new file mode 100644 index 00000000000..3ebaafc752c --- /dev/null +++ b/app/services/search/project_service.rb @@ -0,0 +1,37 @@ +module Search + class ProjectService + attr_accessor :project, :current_user, :params + + def initialize(project, user, params) + @project, @current_user, @params = project, user, params.dup + end + + def execute + query = params[:search] + query = Shellwords.shellescape(query) if query.present? + return result unless query.present? + + if params[:search_code].present? + blobs = project.repository.search_files(query, params[:repository_ref]) unless project.empty_repo? + blobs = Kaminari.paginate_array(blobs).page(params[:page]).per(20) + result[:blobs] = blobs + result[:total_results] = blobs.total_count + else + result[:merge_requests] = project.merge_requests.search(query).order('updated_at DESC').limit(20) + result[:issues] = project.issues.search(query).order('updated_at DESC').limit(20) + result[:total_results] = %w(issues merge_requests).sum { |items| result[items.to_sym].size } + end + + result + end + + def result + @result ||= { + merge_requests: [], + issues: [], + blobs: [], + total_results: 0, + } + end + end +end diff --git a/app/services/system_hooks_service.rb b/app/services/system_hooks_service.rb index de4fa9b79e7..4969198b8c2 100644 --- a/app/services/system_hooks_service.rb +++ b/app/services/system_hooks_service.rb @@ -1,21 +1,21 @@ class SystemHooksService - def self.execute_hooks_for(model, event) + def execute_hooks_for(model, event) execute_hooks(build_event_data(model, event)) end private - def self.execute_hooks(data) + def execute_hooks(data) SystemHook.all.each do |sh| async_execute_hook sh, data end end - def self.async_execute_hook(hook, data) + def async_execute_hook(hook, data) Sidekiq::Client.enqueue(SystemHookWorker, hook.id, data) end - def self.build_event_data(model, event) + def build_event_data(model, event) data = { event_name: build_event_name(model, event), created_at: model.created_at @@ -51,7 +51,7 @@ class SystemHooksService end end - def self.build_event_name(model, event) + def build_event_name(model, event) case model when UsersProject return "user_add_to_team" if event == :create diff --git a/app/services/test_hook_service.rb b/app/services/test_hook_service.rb new file mode 100644 index 00000000000..17d86a7a274 --- /dev/null +++ b/app/services/test_hook_service.rb @@ -0,0 +1,6 @@ +class TestHookService + def execute(hook, current_user) + data = GitPushService.new.sample_data(hook.project, current_user) + hook.execute(data) + end +end diff --git a/app/views/admin/broadcast_messages/index.html.haml b/app/views/admin/broadcast_messages/index.html.haml index d7c78950b95..f28dadfb659 100644 --- a/app/views/admin/broadcast_messages/index.html.haml +++ b/app/views/admin/broadcast_messages/index.html.haml @@ -6,35 +6,35 @@ %i.icon-bullhorn %span Your message here -= form_for [:admin, @broadcast_message] do |f| += form_for [:admin, @broadcast_message], html: { class: 'broadcast-message-form form-horizontal'} do |f| -if @broadcast_message.errors.any? - .alert.alert-error + .alert.alert-danger - @broadcast_message.errors.full_messages.each do |msg| %p= msg - .control-group - = f.label :message - .controls - = f.text_area :message, class: "input-xxlarge", rows: 2, required: true + .form-group + = f.label :message, class: 'control-label' + .col-sm-10 + = f.text_area :message, class: "form-control", rows: 2, required: true %div = link_to '#', class: 'js-toggle-colors-link' do Customize colors - .control-group.js-toggle-colors-container.hide - = f.label :color, "Background Color" - .controls - = f.text_field :color, placeholder: "#AA33EE" + .form-group.js-toggle-colors-container.hide + = f.label :color, "Background Color", class: 'control-label' + .col-sm-10 + = f.text_field :color, placeholder: "#AA33EE", class: "form-control" .light Hex values as 3 double digit numbers, starting with a # sign. - .control-group.js-toggle-colors-container.hide - = f.label :font, "Font Color" - .controls - = f.text_field :font, placeholder: "#224466" + .form-group.js-toggle-colors-container.hide + = f.label :font, "Font Color", class: 'control-label' + .col-sm-10 + = f.text_field :font, placeholder: "#224466", class: "form-control" .light Hex values as 3 double digit numbers, starting with a # sign. - .control-group - = f.label :starts_at - .controls.datetime-controls + .form-group + = f.label :starts_at, class: 'control-label' + .col-sm-10.datetime-controls = f.datetime_select :starts_at - .control-group - = f.label :ends_at - .controls.datetime-controls + .form-group + = f.label :ends_at, class: 'control-label' + .col-sm-10.datetime-controls = f.datetime_select :ends_at .form-actions = f.submit "Add broadcast message", class: "btn btn-create" diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index cc8e0c88efe..dd663945ea9 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -4,7 +4,7 @@ You can manage projects, users and other GitLab data from here. %hr .admin_dash.row - .span4 + .col-sm-4 .light-well %h4 Projects .data @@ -12,7 +12,7 @@ %h1= Project.count %hr = link_to 'New Project', new_project_path, class: "btn btn-new" - .span4 + .col-sm-4 .light-well %h4 Users .data @@ -20,7 +20,7 @@ %h1= User.count %hr = link_to 'New User', new_admin_user_path, class: "btn btn-new" - .span4 + .col-sm-4 .light-well %h4 Groups .data @@ -30,16 +30,16 @@ = link_to 'New Group', new_admin_group_path, class: "btn btn-new" .row.prepend-top-10 - .span4 + .col-md-4 %h4 Latest projects %hr - @projects.each do |project| %p = link_to project.name_with_namespace, [:admin, project] %span.light.pull-right - #{time_ago_with_tooltip(project.created_at)} ago + #{time_ago_with_tooltip(project.created_at)} - .span4 + .col-md-4 %h4 Latest users %hr - @users.each do |user| @@ -47,9 +47,9 @@ = link_to [:admin, user] do = user.name %span.light.pull-right - #{time_ago_with_tooltip(user.created_at)} ago + #{time_ago_with_tooltip(user.created_at)} - .span4 + .col-md-4 %h4 Latest groups %hr - @groups.each do |group| @@ -57,11 +57,11 @@ = link_to [:admin, group] do = group.name %span.light.pull-right - #{time_ago_with_tooltip(group.created_at)} ago + #{time_ago_with_tooltip(group.created_at)} %br .row - .span4 + .col-md-4 %h4 Stats %hr %p @@ -92,7 +92,7 @@ Milestones %span.light.pull-right = Milestone.count - .span4 + .col-md-4 %h4 Features %hr @@ -112,7 +112,7 @@ OmniAuth %span.light.pull-right = boolean_to_icon Gitlab.config.omniauth.enabled - .span4 + .col-md-4 %h4 Components %hr %p diff --git a/app/views/admin/groups/edit.html.haml b/app/views/admin/groups/edit.html.haml index 3918bf981a2..eb5c91050af 100644 --- a/app/views/admin/groups/edit.html.haml +++ b/app/views/admin/groups/edit.html.haml @@ -1,25 +1,25 @@ %h3.page-title Edit Group %hr -= form_for [:admin, @group] do |f| += form_for [:admin, @group], html: { class: "form-horizontal" } do |f| - if @group.errors.any? - .alert.alert-error + .alert.alert-danger %span= @group.errors.full_messages.first - .control-group.group_name_holder - = f.label :name do + .form-group.group_name_holder + = f.label :name, class: 'control-label' do Group name - .controls - = f.text_field :name, placeholder: "Example Group", class: "input-xxlarge" + .col-sm-10 + = f.text_field :name, placeholder: "Example Group", class: "form-control" - .control-group.group-description-holder - = f.label :description, "Details" - .controls - = f.text_area :description, maxlength: 250, class: "input-xxlarge js-gfm-input", rows: 4 + .form-group.group-description-holder + = f.label :description, "Details", class: 'control-label' + .col-sm-10 + = f.text_area :description, maxlength: 250, class: "form-control js-gfm-input", rows: 4 - .control-group.group_name_holder - = f.label :path do + .form-group.group_name_holder + = f.label :path, class: 'control-label' do %span.cred Group path - .controls - = f.text_field :path, placeholder: "example-group", class: "input-xxlarge danger" + .col-sm-10 + = f.text_field :path, placeholder: "example-group", class: "form-control danger" %ul.cred %li Changing group path can have unintended side effects. %li Renaming group path will rename directory for all related projects diff --git a/app/views/admin/groups/index.html.haml b/app/views/admin/groups/index.html.haml index 70098a442d5..7a373ee586c 100644 --- a/app/views/admin/groups/index.html.haml +++ b/app/views/admin/groups/index.html.haml @@ -7,7 +7,8 @@ = link_to 'New Group', new_admin_group_path, class: "btn btn-new pull-right" %br = form_tag admin_groups_path, method: :get, class: 'form-inline' do - = text_field_tag :name, params[:name], class: "span6 input-xpadding" + .form-group + = text_field_tag :name, params[:name], class: "form-control input-mn-300" = submit_tag "Search", class: "btn submit btn-primary" %hr diff --git a/app/views/admin/groups/new.html.haml b/app/views/admin/groups/new.html.haml index cfbe6b5ee5a..ae0604cf984 100644 --- a/app/views/admin/groups/new.html.haml +++ b/app/views/admin/groups/new.html.haml @@ -1,27 +1,31 @@ %h3.page-title New Group %hr -= form_for [:admin, @group] do |f| += form_for [:admin, @group], html: { class: 'group-form form-horizontal' } do |f| - if @group.errors.any? - .alert.alert-error + .alert.alert-danger %span= @group.errors.full_messages.first - .control-group - = f.label :name do + .form-group + = f.label :name, class: 'control-label' do Group name - .controls - = f.text_field :name, placeholder: "Ex. OpenSource", class: "input-xxlarge left" - .control-group.group-description-holder - = f.label :description, "Details" - .controls - = f.text_area :description, maxlength: 250, class: "input-xxlarge js-gfm-input", rows: 4 + .col-sm-10 + = f.text_field :name, placeholder: "Ex. OpenSource", class: "form-control" + + .form-group.group-description-holder + = f.label :description, "Details", class: 'control-label' + .col-sm-10 + = f.text_area :description, maxlength: 250, class: "form-control js-gfm-input", rows: 4 + + .form-group + .col-sm-2 + .col-sm-10 + %ul + %li A group is a collection of several projects + %li Groups are private by default + %li Members of a group may only view projects they have permission to access + %li Group project URLs are prefixed with the group namespace + %li Existing projects may be moved into a group .form-actions = f.submit 'Create group', class: "btn btn-create" - %hr - .padded - %ul - %li Group is kind of directory for several projects - %li All created groups are private - %li People within a group see only projects they have access to - %li All projects of group will be stored in a group directory - %li You will be able to move existing projects into group + diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index 4d0522393dd..252111875fa 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -6,7 +6,7 @@ Edit %hr .row - .span6 + .col-md-6 .ui-box .title Group info: @@ -44,7 +44,7 @@ %span.pull-right.light %span.monospace= project.path_with_namespace + ".git" - .span6 + .col-md-6 .ui-box .title Add user(s) to the group: @@ -57,7 +57,7 @@ %div = users_select_tag(:user_ids, multiple: true) %div.prepend-top-10 - = select_tag :group_access, options_for_select(UsersGroup.group_access_roles), class: "project-access-select chosen" + = select_tag :group_access, options_for_select(UsersGroup.group_access_roles), class: "project-access-select select2" %hr = submit_tag 'Add users into group', class: "btn btn-create" .ui-box diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml index 84546a75142..ff90d513ca1 100644 --- a/app/views/admin/hooks/index.html.haml +++ b/app/views/admin/hooks/index.html.haml @@ -8,17 +8,17 @@ %hr -= form_for @hook, as: :hook, url: admin_hooks_path, html: { class: 'form-inline' } do |f| += form_for @hook, as: :hook, url: admin_hooks_path, html: { class: 'form-horizontal' } do |f| -if @hook.errors.any? - .alert.alert-error + .alert.alert-danger - @hook.errors.full_messages.each do |msg| %p= msg - .control-group - = f.label :url, "URL:" - .controls - = f.text_field :url, class: "text_field input-xxlarge input-xpadding" - - = f.submit "Add System Hook", class: "btn btn-create" + .form-group + = f.label :url, "URL:", class: 'control-label' + .col-sm-10 + = f.text_field :url, class: "form-control" + .form-actions + = f.submit "Add System Hook", class: "btn btn-create" %hr -if @hooks.any? diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml index d2f827e083c..940a539d5e1 100644 --- a/app/views/admin/projects/index.html.haml +++ b/app/views/admin/projects/index.html.haml @@ -1,43 +1,41 @@ .row - .span4 + .col-md-4 .admin-filter - = form_tag admin_projects_path, method: :get, class: 'form-inline' do - .control-group - = label_tag :name, 'Name:', class: 'control-label' - .controls - = text_field_tag :name, params[:name], class: "span2" + = form_tag admin_projects_path, method: :get, class: '' do + .form-group + = label_tag :name, 'Name:' + = text_field_tag :name, params[:name], class: "form-control" - .control-group - = label_tag :owner_id, 'Owner:', class: 'control-label' - .controls + .form-group + = label_tag :owner_id, 'Owner:' + %div = users_select_tag :owner_id, selected: params[:owner_id], class: 'input-large input-clamp' - .control-group.visibility-levels - = label_tag :visibility_level, 'Visibility Levels', class: 'control-label' - - Project.visibility_levels.each do |label, level| - .controls - = check_box_tag 'visibility_levels[]', level, params[:visibility_levels].present? && params[:visibility_levels].include?(level.to_s) - %span.descr - = visibility_level_icon(level) - = label - .control-group - = label_tag :with_push, 'Not empty', class: 'control-label' - .controls - = check_box_tag :with_push, 1, params[:with_push] - - %span.light Projects with push events - .control-group - = label_tag :abandoned, 'Abandoned', class: 'control-label' - .controls - = check_box_tag :abandoned, 1, params[:abandoned] - - %span.light No activity over 6 month - - + .checkbox + = label_tag :with_push, 'Not empty' + = check_box_tag :with_push, 1, params[:with_push] + + %span.light Projects with push events + .checkbox + = label_tag :abandoned, 'Abandoned' + = check_box_tag :abandoned, 1, params[:abandoned] + + %span.light No activity over 6 month + %fieldset + %strong Visibility level: + .visibility-levels + - Project.visibility_levels.each do |label, level| + .checkbox + %label + = check_box_tag 'visibility_levels[]', level, params[:visibility_levels].present? && params[:visibility_levels].include?(level.to_s) + %span.descr + = visibility_level_icon(level) + = label .form-actions = submit_tag "Search", class: "btn submit btn-primary" = link_to "Reset", admin_projects_path, class: "btn" - .span8 + + .col-md-8 .ui-box .title Projects (#{@projects.total_count}) diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index 74c2d63c828..34a91cce163 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -5,7 +5,7 @@ Edit %hr .row - .span6 + .col-md-6 .ui-box .title Project info: @@ -79,17 +79,18 @@ .title Transfer project .body - = form_for @project, url: transfer_admin_project_path(@project), method: :put do |f| - .control-group - = f.label :namespace_id, "Namespace" - .controls + = form_for @project, url: transfer_admin_project_path(@project), method: :put, html: { class: 'form-horizontal' } do |f| + .form-group + = f.label :namespace_id, "Namespace", class: 'control-label' + .col-sm-10 = namespace_select_tag :namespace_id, selected: params[:namespace_id], class: 'input-large' - .control-group - .controls + .form-group + .col-sm-2 + .col-sm-10 = f.submit 'Transfer', class: 'btn btn-primary' - .span6 + .col-md-6 - if @group .ui-box .title diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index 9ccbcd868c0..881a043f36f 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -1,35 +1,35 @@ .user_new - = form_for [:admin, @user] do |f| + = form_for [:admin, @user], html: { class: 'form-horizontal' } do |f| -if @user.errors.any? #error_explanation - %ul.unstyled.alert.alert-error + %ul.unstyled.alert.alert-danger - @user.errors.full_messages.each do |msg| %li= msg %fieldset %legend Account - .control-group - = f.label :name - .controls - = f.text_field :name, required: true, autocomplete: "off" + .form-group + = f.label :name, class: 'control-label' + .col-sm-10 + = f.text_field :name, required: true, autocomplete: "off", class: 'form-control' %span.help-inline * required - .control-group - = f.label :username - .controls - = f.text_field :username, required: true, autocomplete: "off" + .form-group + = f.label :username, class: 'control-label' + .col-sm-10 + = f.text_field :username, required: true, autocomplete: "off", class: 'form-control' %span.help-inline * required - .control-group - = f.label :email - .controls - = f.text_field :email, required: true, autocomplete: "off" + .form-group + = f.label :email, class: 'control-label' + .col-sm-10 + = f.text_field :email, required: true, autocomplete: "off", class: 'form-control' %span.help-inline * required - if @user.new_record? %fieldset %legend Password - .control-group - = f.label :password - .controls + .form-group + = f.label :password, class: 'control-label' + .col-sm-10 %strong A temporary password will be generated and sent to user. %br @@ -37,49 +37,52 @@ - else %fieldset %legend Password - .control-group - = f.label :password - .controls= f.password_field :password, disabled: f.object.force_random_password - .control-group - = f.label :password_confirmation - .controls= f.password_field :password_confirmation, disabled: f.object.force_random_password + .form-group + = f.label :password, class: 'control-label' + .col-sm-10= f.password_field :password, disabled: f.object.force_random_password, class: 'form-control' + .form-group + = f.label :password_confirmation, class: 'control-label' + .col-sm-10= f.password_field :password_confirmation, disabled: f.object.force_random_password, class: 'form-control' %fieldset %legend Access - .row - .span8 - .control-group - = f.label :projects_limit - .controls= f.number_field :projects_limit + .form-group + = f.label :projects_limit, class: 'control-label' + .col-sm-10= f.number_field :projects_limit, class: 'form-control' - .control-group - = f.label :can_create_group - .controls= f.check_box :can_create_group + .form-group + = f.label :can_create_group, class: 'control-label' + .col-sm-10= f.check_box :can_create_group - .control-group - = f.label :admin do - %strong.cred Administrator - .controls= f.check_box :admin - .span4 - - unless @user.new_record? - .alert.alert-error - - if @user.blocked? - %p This user is blocked and is not able to login to GitLab - = link_to 'Unblock User', unblock_admin_user_path(@user), method: :put, class: "btn btn-small" - - else - %p Blocked users will be removed from all projects & will not be able to login to GitLab. - = link_to 'Block User', block_admin_user_path(@user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-small btn-remove" + .form-group + = f.label :admin, class: 'control-label' + - if current_user == @user + .col-sm-10= f.check_box :admin, disabled: true + .col-sm-10 You cannot remove your own admin rights + - else + .col-sm-10= f.check_box :admin + - unless @user.new_record? || current_user == @user + .alert.alert-danger + - if @user.blocked? + %p This user is blocked and is not able to login to GitLab + = link_to 'Unblock User', unblock_admin_user_path(@user), method: :put, class: "btn btn-small" + - else + %p Blocked users will be removed from all projects & will not be able to login to GitLab. + = link_to 'Block User', block_admin_user_path(@user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-small btn-remove" %fieldset %legend Profile - .control-group - = f.label :skype - .controls= f.text_field :skype - .control-group - = f.label :linkedin - .controls= f.text_field :linkedin - .control-group - = f.label :twitter - .controls= f.text_field :twitter + .form-group + = f.label :skype, class: 'control-label' + .col-sm-10= f.text_field :skype, class: 'form-control' + .form-group + = f.label :linkedin, class: 'control-label' + .col-sm-10= f.text_field :linkedin, class: 'form-control' + .form-group + = f.label :twitter, class: 'control-label' + .col-sm-10= f.text_field :twitter, class: 'form-control' + .form-group + = f.label :website_url, 'Website', class: 'control-label' + .col-sm-10= f.text_field :website_url, class: 'form-control' .form-actions - if @user.new_record? diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml index 5bc73d11f31..1fa6fdfaff1 100644 --- a/app/views/admin/users/index.html.haml +++ b/app/views/admin/users/index.html.haml @@ -1,10 +1,12 @@ .row - .span3 + .col-md-3 .admin-filter = form_tag admin_users_path, method: :get, class: 'form-inline' do - = search_field_tag :name, params[:name], placeholder: 'Name, email or username', class: 'input-xpadding span2' - = button_tag type: 'submit', class: 'btn btn-primary' do - %i.icon-search + .append-bottom-10 + .form-group + = search_field_tag :name, params[:name], placeholder: 'Name, email or username', class: 'form-control' + = button_tag type: 'submit', class: 'btn btn-primary' do + %i.icon-search %ul.nav.nav-pills.nav-stacked %li{class: "#{'active' unless params[:filter]}"} = link_to admin_users_path do @@ -25,7 +27,7 @@ %hr = link_to 'Reset', admin_users_path, class: "btn btn-cancel" - .span9 + .col-md-9 .ui-box .title Users (#{@users.total_count}) diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index e79cdbb978b..bd276f22221 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -13,7 +13,7 @@ %hr .row - .span6 + .col-md-6 .ui-box .title Account: @@ -100,7 +100,7 @@ %li Owned groups will be left = link_to 'Block user', block_admin_user_path(@user), data: { confirm: 'USER WILL BE BLOCKED! Are you sure?' }, method: :put, class: "btn btn-remove" - .alert.alert-error + .alert.alert-danger %h4 Remove user %br @@ -116,7 +116,7 @@ %strong #{@user.solo_owned_groups.map(&:name).join(', ')} = link_to 'Remove user', [:admin, @user], data: { confirm: "USER #{@user.name} WILL BE REMOVED! Are you sure?" }, method: :delete, class: "btn btn-remove" - .span6 + .col-md-6 - if @user.users_groups.present? .ui-box .title Groups: diff --git a/app/views/dashboard/_groups.html.haml b/app/views/dashboard/_groups.html.haml index b4f3866228d..d6937ca4813 100644 --- a/app/views/dashboard/_groups.html.haml +++ b/app/views/dashboard/_groups.html.haml @@ -1,6 +1,6 @@ .ui-box .title.clearfix - = search_field_tag :filter_group, nil, placeholder: 'Filter by name', class: 'dash-filter' + = search_field_tag :filter_group, nil, placeholder: 'Filter by name', class: 'dash-filter form-control' - if current_user.can_create_group? %span.pull-right = link_to new_group_path, class: "btn btn-new" do diff --git a/app/views/dashboard/_project.html.haml b/app/views/dashboard/_project.html.haml index db445eed233..e326bee53ab 100644 --- a/app/views/dashboard/_project.html.haml +++ b/app/views/dashboard/_project.html.haml @@ -1,11 +1,12 @@ = link_to project_path(project), class: dom_class(project) do .dash-project-access-icon = visibility_level_icon(project.visibility_level) - %span.namespace-name - - if project.namespace - = project.namespace.human_name - \/ - %span.project-name.filter-title - = truncate(project.name, length: 25) + %span.str-truncated + %span.namespace-name + - if project.namespace + = project.namespace.human_name + \/ + %span.project-name.filter-title + = project.name %span.arrow %i.icon-angle-right diff --git a/app/views/dashboard/_projects.html.haml b/app/views/dashboard/_projects.html.haml index b79b27fc95a..8313cc07b5e 100644 --- a/app/views/dashboard/_projects.html.haml +++ b/app/views/dashboard/_projects.html.haml @@ -1,6 +1,6 @@ .ui-box .title.clearfix - = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'dash-filter' + = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'dash-filter form-control' - if current_user.can_create_project? %span.pull-right = link_to new_project_path, class: "btn btn-new" do diff --git a/app/views/dashboard/_projects_filter.html.haml b/app/views/dashboard/_projects_filter.html.haml new file mode 100644 index 00000000000..8c9893ba84f --- /dev/null +++ b/app/views/dashboard/_projects_filter.html.haml @@ -0,0 +1,55 @@ +%fieldset + %ul.nav.nav-pills.nav-stacked + = nav_tab :scope, nil do + = link_to projects_dashboard_filter_path(scope: nil) do + All + %span.pull-right + = current_user.authorized_projects.count + = nav_tab :scope, 'personal' do + = link_to projects_dashboard_filter_path(scope: 'personal') do + Personal + %span.pull-right + = current_user.personal_projects.count + = nav_tab :scope, 'joined' do + = link_to projects_dashboard_filter_path(scope: 'joined') do + Joined + %span.pull-right + = current_user.authorized_projects.joined(current_user).count + = nav_tab :scope, 'owned' do + = link_to projects_dashboard_filter_path(scope: 'owned') do + Owned + %span.pull-right + = current_user.owned_projects.count + +%fieldset + %legend Visibility + %ul.nav.nav-pills.nav-stacked.nav-small.visibility-filter + - Gitlab::VisibilityLevel.values.each do |level| + %li{ class: (level.to_s == params[:visibility_level]) ? 'active' : 'light' } + = link_to projects_dashboard_filter_path(visibility_level: level) do + = visibility_level_icon(level) + = visibility_level_label(level) + +- if @groups.present? + %fieldset + %legend Groups + %ul.nav.nav-pills.nav-stacked.nav-small + - @groups.each do |group| + %li{ class: (group.name == params[:group]) ? 'active' : 'light' } + = link_to projects_dashboard_filter_path(group: group.name) do + %i.icon-folder-close-alt + = group.name + %small.pull-right + = group.projects.count + + + +- if @labels.present? + %fieldset + %legend Labels + %ul.nav.nav-pills.nav-stacked.nav-small + - @labels.each do |label| + %li{ class: (label.name == params[:label]) ? 'active' : 'light' } + = link_to projects_dashboard_filter_path(scope: params[:scope], label: label.name) do + %i.icon-tag + = label.name diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml index bda5b7c9147..19bd4e7bd54 100644 --- a/app/views/dashboard/issues.html.haml +++ b/app/views/dashboard/issues.html.haml @@ -7,7 +7,7 @@ %hr .row - .span3 + .col-md-3 = render 'shared/filter', entity: 'issue' - .span9 + .col-md-9 = render 'shared/issues' diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml index 74d02336bb8..b487a4d6666 100644 --- a/app/views/dashboard/merge_requests.html.haml +++ b/app/views/dashboard/merge_requests.html.haml @@ -7,7 +7,7 @@ List all merge requests from all project's you have access to. %hr .row - .span3 + .col-md-3 = render 'shared/filter', entity: 'merge_request' - .span9 + .col-md-9 = render 'shared/merge_requests' diff --git a/app/views/dashboard/projects.html.haml b/app/views/dashboard/projects.html.haml index c59d5aee0ac..8feef97c732 100644 --- a/app/views/dashboard/projects.html.haml +++ b/app/views/dashboard/projects.html.haml @@ -25,63 +25,9 @@ All projects you have access to are listed here. Public projects are not included here unless you are a member %hr .row - .span3 - %ul.nav.nav-pills.nav-stacked - = nav_tab :scope, nil do - = link_to projects_dashboard_filter_path(scope: nil) do - All - %span.pull-right - = current_user.authorized_projects.count - = nav_tab :scope, 'personal' do - = link_to projects_dashboard_filter_path(scope: 'personal') do - Personal - %span.pull-right - = current_user.personal_projects.count - = nav_tab :scope, 'joined' do - = link_to projects_dashboard_filter_path(scope: 'joined') do - Joined - %span.pull-right - = current_user.authorized_projects.joined(current_user).count - = nav_tab :scope, 'owned' do - = link_to projects_dashboard_filter_path(scope: 'owned') do - Owned - %span.pull-right - = current_user.owned_projects.count - - %fieldset - %legend Visibility - %ul.bordered-list.visibility-filter - - Gitlab::VisibilityLevel.values.each do |level| - %li{ class: (level.to_s == params[:visibility_level]) ? 'active' : 'light' } - = link_to projects_dashboard_filter_path(visibility_level: level) do - = visibility_level_icon(level) - = visibility_level_label(level) - - - if @groups.present? - %fieldset - %legend Groups - %ul.bordered-list - - @groups.each do |group| - %li{ class: (group.name == params[:group]) ? 'active' : 'light' } - = link_to projects_dashboard_filter_path(group: group.name) do - %i.icon-folder-close-alt - = group.name - %small.pull-right - = group.projects.count - - - - - if @labels.present? - %fieldset - %legend Labels - %ul.bordered-list - - @labels.each do |label| - %li{ class: (label.name == params[:label]) ? 'active' : 'light' } - = link_to projects_dashboard_filter_path(scope: params[:scope], label: label.name) do - %i.icon-tag - = label.name - - .span9 + .col-md-3.hidden-sm.hidden-xs.side-filters + = render "projects_filter" + .col-md-9 %ul.bordered-list.my-projects.top-list - @projects.each do |project| %li.my-project-row diff --git a/app/views/dashboard/show.html.haml b/app/views/dashboard/show.html.haml index 2305eae1f71..c4018d4b6d8 100644 --- a/app/views/dashboard/show.html.haml +++ b/app/views/dashboard/show.html.haml @@ -1,8 +1,8 @@ - if @has_authorized_projects - .dashboard - .activities.span8 + .dashboard.row + .activities.col-md-8 = render 'activities' - .side.span4 + .side.col-md-4.hidden-sm = render 'sidebar' - else diff --git a/app/views/devise/confirmations/new.html.haml b/app/views/devise/confirmations/new.html.haml index cf111e1f02b..dd63a232fe2 100644 --- a/app/views/devise/confirmations/new.html.haml +++ b/app/views/devise/confirmations/new.html.haml @@ -3,7 +3,7 @@ = form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| .devise-errors = devise_error_messages! - = f.email_field :email, placeholder: 'Email', class: "text", required: true + = f.email_field :email, placeholder: 'Email', class: "form-control", required: true .clearfix.append-bottom-10 = f.submit "Resend confirmation instructions", class: 'btn btn-success' %hr diff --git a/app/views/devise/passwords/edit.html.haml b/app/views/devise/passwords/edit.html.haml index fb519e7d654..95c52608e1f 100644 --- a/app/views/devise/passwords/edit.html.haml +++ b/app/views/devise/passwords/edit.html.haml @@ -4,9 +4,9 @@ = devise_error_messages! = f.hidden_field :reset_password_token %div - = f.password_field :password, class: "text top", placeholder: "New password", required: true + = f.password_field :password, class: "form-control top", placeholder: "New password", required: true %div - = f.password_field :password_confirmation, class: "text bottom", placeholder: "Confirm new password", required: true + = f.password_field :password_confirmation, class: "form-control bottom", placeholder: "Confirm new password", required: true %div .clearfix.append-bottom-10 = f.submit "Change my password", class: "btn btn-primary" diff --git a/app/views/devise/passwords/new.html.haml b/app/views/devise/passwords/new.html.haml index 5d6df7d8925..a14ef2995c8 100644 --- a/app/views/devise/passwords/new.html.haml +++ b/app/views/devise/passwords/new.html.haml @@ -2,7 +2,7 @@ %h3.page-title Reset password .devise-errors = devise_error_messages! - = f.email_field :email, placeholder: "Email", class: "text", required: true + = f.email_field :email, placeholder: "Email", class: "form-control", required: true .clearfix.append-bottom-10 = f.submit "Reset password", class: "btn-primary btn" %hr diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index a3ac3e43565..24bc0406544 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -3,15 +3,15 @@ .devise-errors = devise_error_messages! %div - = f.text_field :name, class: "text top", placeholder: "Name", required: true + = f.text_field :name, class: "form-control top", placeholder: "Name", required: true %div - = f.text_field :username, class: "text middle", placeholder: "Username", required: true + = f.text_field :username, class: "form-control middle", placeholder: "Username", required: true %div - = f.email_field :email, class: "text middle", placeholder: "Email", required: true + = f.email_field :email, class: "form-control middle", placeholder: "Email", required: true %div - = f.password_field :password, class: "text middle", placeholder: "Password", required: true + = f.password_field :password, class: "form-control middle", placeholder: "Password", required: true %div - = f.password_field :password_confirmation, class: "text bottom", placeholder: "Confirm password", required: true + = f.password_field :password_confirmation, class: "form-control bottom", placeholder: "Confirm password", required: true %div = f.submit "Sign up", class: "btn-create btn" %hr diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml index 0c8be9d5c48..a2f85fa3fe2 100644 --- a/app/views/devise/sessions/_new_base.html.haml +++ b/app/views/devise/sessions/_new_base.html.haml @@ -1,6 +1,6 @@ = form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| - = f.text_field :login, class: "text top", placeholder: "Username or Email", autofocus: "autofocus" - = f.password_field :password, class: "text bottom", placeholder: "Password" + = f.text_field :login, class: "form-control top", placeholder: "Username or Email", autofocus: "autofocus" + = f.password_field :password, class: "form-control bottom", placeholder: "Password" - if devise_mapping.rememberable? .clearfix.append-bottom-10 %label.checkbox.remember_me{for: "user_remember_me"} diff --git a/app/views/devise/sessions/_new_ldap.html.haml b/app/views/devise/sessions/_new_ldap.html.haml index 575d33949b6..bb1d0a4001f 100644 --- a/app/views/devise/sessions/_new_ldap.html.haml +++ b/app/views/devise/sessions/_new_ldap.html.haml @@ -1,5 +1,5 @@ = form_tag(user_omniauth_callback_path(:ldap), id: 'new_ldap_user' ) do - = text_field_tag :username, nil, {class: "text top", placeholder: "LDAP Login", autofocus: "autofocus"} - = password_field_tag :password, nil, {class: "text bottom", placeholder: "Password"} + = text_field_tag :username, nil, {class: "form-control top", placeholder: "LDAP Login", autofocus: "autofocus"} + = password_field_tag :password, nil, {class: "form-control bottom", placeholder: "Password"} %br/ = submit_tag "LDAP Sign in", class: "btn-create btn" diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml index bb87d9ecb4a..938f61d2093 100644 --- a/app/views/devise/sessions/new.html.haml +++ b/app/views/devise/sessions/new.html.haml @@ -1,7 +1,7 @@ .login-box %h3.page-title Sign in - if ldap_enabled? - %ul.nav.nav-tabs + %ul.nav.nav-tabs.append-bottom-20 %li.active = link_to 'LDAP', '#tab-ldap', 'data-toggle' => 'tab' %li diff --git a/app/views/events/_event.html.haml b/app/views/events/_event.html.haml index daed9116789..8cf26671e3b 100644 --- a/app/views/events/_event.html.haml +++ b/app/views/events/_event.html.haml @@ -1,7 +1,7 @@ - if event.proper? .event-item{class: "#{event.body? ? "event-block" : "event-inline" }"} %span.cgray.pull-right - #{time_ago_with_tooltip(event.created_at)} ago + #{time_ago_with_tooltip(event.created_at)} = cache event do = image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:'' diff --git a/app/views/events/_event_last_push.html.haml b/app/views/events/_event_last_push.html.haml index adb331c2b22..6db05a1a5a6 100644 --- a/app/views/events/_event_last_push.html.haml +++ b/app/views/events/_event_last_push.html.haml @@ -5,7 +5,7 @@ %strong= truncate(event.ref_name, length: 28) at %strong= link_to_project event.project - #{time_ago_with_tooltip(event.created_at)} ago + #{time_ago_with_tooltip(event.created_at)} .pull-right = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-create btn-small" do diff --git a/app/views/groups/_new_group_member.html.haml b/app/views/groups/_new_group_member.html.haml index 234392c03e1..5801139a9f2 100644 --- a/app/views/groups/_new_group_member.html.haml +++ b/app/views/groups/_new_group_member.html.haml @@ -1,20 +1,18 @@ -= form_for @users_group, url: group_users_groups_path(@group) do |f| - %fieldset - %legend - New member(s) for - %strong #{@group.name} - group += form_for @users_group, url: group_users_groups_path(@group), html: { class: 'form-horizontal users-group-form' } do |f| + %h4.append-bottom-20 + New member(s) for + %strong #{@group.name} + group - %p 1. Choose users you want in the group - .control-group - = f.label :user_ids, "People" - .controls= users_select_tag(:user_ids, multiple: true, class: 'input-large') + %p 1. Choose users you want in the group + .form-group + = f.label :user_ids, "People", class: 'control-label' + .col-sm-10= users_select_tag(:user_ids, multiple: true, class: 'input-large') - %p 2. Set access level for them - .control-group - = f.label :group_access, "Group Access" - .controls= select_tag :group_access, options_for_select(UsersGroup.group_access_roles, @users_group.group_access), class: "project-access-select chosen" - - .form-actions - = f.submit 'Add users into group', class: "btn btn-create" + %p 2. Set access level for them + .form-group + = f.label :group_access, "Group Access", class: 'control-label' + .col-sm-10= select_tag :group_access, options_for_select(UsersGroup.group_access_roles, @users_group.group_access), class: "project-access-select select2" + .form-actions + = f.submit 'Add users into group', class: "btn btn-create" diff --git a/app/views/groups/_projects.html.haml b/app/views/groups/_projects.html.haml index 98b7b88865b..029d6cb0efa 100644 --- a/app/views/groups/_projects.html.haml +++ b/app/views/groups/_projects.html.haml @@ -14,7 +14,8 @@ = link_to project_path(project), class: dom_class(project) do .dash-project-access-icon = visibility_level_icon(project.visibility_level) - %span.project-name - = truncate(project.name, length: 25) + %span.str-truncated + %span.project-name + = truncate(project.name, length: 25) %span.arrow %i.icon-angle-right diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml index 7a204d89cd1..77734815b8a 100644 --- a/app/views/groups/edit.html.haml +++ b/app/views/groups/edit.html.haml @@ -1,5 +1,5 @@ .row - .span2 + .col-md-2 %ul.nav.nav-pills.nav-stacked.nav-stacked-menu %li.active = link_to '#tab-edit', 'data-toggle' => 'tab' do @@ -12,7 +12,7 @@ %li = link_to 'Remove', '#tab-remove', 'data-toggle' => 'tab' - .span10 + .col-md-10 .tab-content .tab-pane.active#tab-edit .ui-box @@ -20,20 +20,20 @@ %strong= @group.name group settings: %div.form-holder - = form_for @group do |f| + = form_for @group, html: { class: "form-horizontal" } do |f| - if @group.errors.any? - .alert.alert-error + .alert.alert-danger %span= @group.errors.full_messages.first - .control-group - = f.label :name do + .form-group + = f.label :name, class: 'control-label' do Group name - .controls - = f.text_field :name, placeholder: "Ex. OpenSource", class: "input-xxlarge left" + .col-sm-10 + = f.text_field :name, placeholder: "Ex. OpenSource", class: "form-control left" - .control-group.group-description-holder - = f.label :description, "Details" - .controls - = f.text_area :description, maxlength: 250, class: "input-xxlarge js-gfm-input", rows: 4 + .form-group.group-description-holder + = f.label :description, "Details", class: 'control-label' + .col-sm-10 + = f.text_area :description, maxlength: 250, class: "form-control js-gfm-input", rows: 4 .form-actions = f.submit 'Save group', class: "btn btn-save" diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml index 482613f172d..e24df310910 100644 --- a/app/views/groups/issues.html.haml +++ b/app/views/groups/issues.html.haml @@ -1,5 +1,5 @@ %h3.page-title - Issues assigned to me + Issues %span.pull-right #{@issues.total_count} issues %p.light @@ -9,7 +9,7 @@ %hr .row - .span3 + .col-md-3 = render 'shared/filter', entity: 'issue' - .span9 + .col-md-9 = render 'shared/issues' diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml index 8a9b03535bc..eaf85bbdbc8 100644 --- a/app/views/groups/merge_requests.html.haml +++ b/app/views/groups/merge_requests.html.haml @@ -3,12 +3,12 @@ %span.pull-right #{@merge_requests.total_count} merge requests %p.light - Authored or assigned to you from + Only merge requests from %strong #{@group.name} - group. To see all merge requests you should visit #{link_to 'dashboard', merge_requests_dashboard_path} page. + group are listed here. To see all merge requests you should visit #{link_to 'dashboard', merge_requests_dashboard_path} page. %hr .row - .span3 + .col-md-3 = render 'shared/filter', entity: 'merge_request' - .span9 + .col-md-9 = render 'shared/merge_requests' diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml index d6d514e9b18..955a107e542 100644 --- a/app/views/groups/new.html.haml +++ b/app/views/groups/new.html.haml @@ -1,20 +1,21 @@ -= form_for @group do |f| += form_for @group, html: { class: 'group-form form-horizontal' } do |f| - if @group.errors.any? - .alert.alert-error + .alert.alert-danger %span= @group.errors.full_messages.first - .control-group - = f.label :name do + .form-group + = f.label :name, class: 'control-label' do Group name - .controls - = f.text_field :name, placeholder: "Ex. OpenSource", class: "input-xxlarge left" + .col-sm-10 + = f.text_field :name, placeholder: "Ex. OpenSource", class: "form-control" - .control-group.group-description-holder - = f.label :description, "Details" - .controls - = f.text_area :description, maxlength: 250, class: "input-xxlarge js-gfm-input", rows: 4 + .form-group.group-description-holder + = f.label :description, "Details", class: 'control-label' + .col-sm-10 + = f.text_area :description, maxlength: 250, class: "form-control js-gfm-input", rows: 4 - .control-group - .controls + .form-group + .col-sm-2 + .col-sm-10 %ul %li A group is a collection of several projects %li Groups are private by default diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index e613ed3eaa3..5332d383c4c 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -1,5 +1,5 @@ .dashboard - .activities.span8 + .activities.col-md-8.hidden-sm = render "events/event_last_push", event: @last_push = link_to dashboard_path, class: 'btn btn-tiny' do ← To dashboard @@ -12,7 +12,7 @@ - else %p.nothing_here_message Project activity will be displayed here .loading.hide - .side.span4 + .side.col-md-4 - if @group.description.present? .description-block = @group.description diff --git a/app/views/help/_api_layout.html.haml b/app/views/help/_api_layout.html.haml index 502cc31a80c..c211b658410 100644 --- a/app/views/help/_api_layout.html.haml +++ b/app/views/help/_api_layout.html.haml @@ -1,5 +1,5 @@ .row - .span3 + .col-md-3 .append-bottom-20 = link_to help_path, class: 'btn btn-small' do %i.icon-angle-left @@ -9,5 +9,5 @@ %li{class: file == @category ? 'active' : nil} = link_to file.titleize, help_api_file_path(file) - .span9.pull-right + .col-md-9.pull-right = yield diff --git a/app/views/help/_layout.html.haml b/app/views/help/_layout.html.haml index 7928937c60a..a413616bad0 100644 --- a/app/views/help/_layout.html.haml +++ b/app/views/help/_layout.html.haml @@ -1,5 +1,5 @@ .row - .span3{:"data-spy" => 'affix'} + .col-md-3 %h3.page-title Help %ul.nav.nav-pills.nav-stacked - links = {:"Workflow" => help_workflow_path, :"SSH Keys" => help_ssh_path, :"GitLab Markdown" => help_markdown_path, :"Permissions" => help_permissions_path, :"API" => help_api_path, :"Web Hooks" => help_web_hooks_path, :"Rake Tasks" => help_raketasks_path, :"System Hooks" => help_system_hooks_path, :"Public Access" => help_public_access_path, :"Security" => help_security_path} @@ -7,5 +7,5 @@ %li{class: current_page?(path) ? 'active' : nil} = link_to title, path - .span9.pull-right + .col-md-9 = yield diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml index e979e7c0d07..500e5dc65e1 100644 --- a/app/views/help/_shortcuts.html.haml +++ b/app/views/help/_shortcuts.html.haml @@ -1,30 +1,32 @@ -#modal-shortcuts.modal.hide - .modal-header - %a.close{href: "#", "data-dismiss" => "modal"} × - %h3 Keyboard Shortcuts - .modal-body - %h5 Global Shortcuts - %p - %span.label.label-inverse s - – - Focus Search - %p - %span.label.label-inverse ? - – - Show this dialog +#modal-shortcuts.modal.hide{tabindex: -1} + .modal-dialog + .modal-content + .modal-header + %a.close{href: "#", "data-dismiss" => "modal"} × + %h3 Keyboard Shortcuts + .modal-body + %h5 Global Shortcuts + %p + %span.label.label-inverse s + – + Focus Search + %p + %span.label.label-inverse ? + – + Show this dialog - %h5 Project Files browsing - %p - %span.label.label-inverse - %i.icon-arrow-up - – - Move selection up - %p - %span.label.label-inverse - %i.icon-arrow-down - – - Move selection down - %p - %span.label.label-inverse Enter - – - Open selection + %h5 Project Files browsing + %p + %span.label.label-inverse + %i.icon-arrow-up + – + Move selection up + %p + %span.label.label-inverse + %i.icon-arrow-down + – + Move selection down + %p + %span.label.label-inverse Enter + – + Open selection diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml index 869f87df4db..f1cb723ebac 100644 --- a/app/views/help/index.html.haml +++ b/app/views/help/index.html.haml @@ -1,4 +1,4 @@ -.hero-unit +.jumbotron %h2 GitLab %span= Gitlab::VERSION @@ -11,7 +11,7 @@ Read more about GitLab at #{link_to "gitlab.org", "http://gitlab.org/", target: "_blank"}. .row - .span4 + .col-md-4 .ui-box .title Quick help @@ -33,9 +33,9 @@ = link_to "Stack Overflow", "http://stackoverflow.com/questions/tagged/gitlab" %li Browse our - = link_to "issue tracker", "https://github.com/gitlabhq/gitlabhq/issues" + = link_to "issue tracker", "https://gitlab.com/gitlab-org/gitlab-ce/issues" - .span4 + .col-md-4 .ui-box .title User documentation @@ -64,7 +64,7 @@ %strong= link_to "Web Hooks", help_web_hooks_path %p Let GitLab notify you when new code has been pushed to your project. - .span4 + .col-md-4 .ui-box .title Admin documentation diff --git a/app/views/kaminari/gitlab/_paginator.html.haml b/app/views/kaminari/gitlab/_paginator.html.haml index 6f9fb332261..4f7996e4996 100644 --- a/app/views/kaminari/gitlab/_paginator.html.haml +++ b/app/views/kaminari/gitlab/_paginator.html.haml @@ -6,8 +6,8 @@ -# remote: data-remote -# paginator: the paginator that renders the pagination tags inside = paginator.render do - %div.pagination - %ul + %div.gl-pagination + %ul.pagination = prev_page_tag unless current_page.first? - each_page do |page| - if page.left_outer? || page.right_outer? || page.inside_window? diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml index 0775abea3dd..5723250151a 100644 --- a/app/views/layouts/_head.html.haml +++ b/app/views/layouts/_head.html.haml @@ -8,6 +8,8 @@ = javascript_include_tag "application" = csrf_meta_tags = include_gon + :erb + <meta name="viewport" content="width=device-width, initial-scale=1.0"> = render 'layouts/google_analytics' if extra_config.has_key?('google_analytics_id') @@ -20,3 +22,8 @@ = auto_discovery_link_tag(:atom, project_commits_url(@project, @ref, format: :atom, private_token: current_user.private_token), title: "Recent commits to #{@project.name}:#{@ref}") - if current_controller?(:issues) = auto_discovery_link_tag(:atom, project_issues_url(@project, :atom, private_token: current_user.private_token), title: "#{@project.name} issues") + + -# Go repository retrieval support. + - if controller_name == 'projects' && action_name == 'show' + %meta{name: "go-import", content: "#{@project.web_url_without_protocol} git #{@project.web_url}.git"} + diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml index 80c42fe6387..58b216f2e98 100644 --- a/app/views/layouts/_head_panel.html.haml +++ b/app/views/layouts/_head_panel.html.haml @@ -7,34 +7,43 @@ %h1 GITLAB %span.separator %h1.project_name= title - %ul.nav - %li - %a - %div.hide.turbolink-spinner - %i.icon-refresh.icon-spin - Loading... - %li - = render "layouts/search" - %li - = link_to public_root_path, title: "Public area", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do - %i.icon-globe - %li - = link_to user_snippets_path(current_user), title: "My snippets", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do - %i.icon-paste - - if current_user.is_admin? + + %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"} + %span.sr-only Toggle navigation + %i.icon-reorder + + .navbar-collapse.collapse + %ul.nav.navbar-nav %li - = link_to admin_root_path, title: "Admin area", class: 'has_bottom_tooltip', 'data-original-title' => 'Admin area' do - %i.icon-cogs - - if current_user.can_create_project? + %a + %div.hide.turbolink-spinner + %i.icon-refresh.icon-spin + Loading... + %li.hidden-sm + = render "layouts/search" + %li.visible-sm + = link_to search_path, title: "Search", class: 'has_bottom_tooltip', 'data-original-title' => 'Search area' do + %i.icon-search %li - = link_to new_project_path, title: "New project", class: 'has_bottom_tooltip', 'data-original-title' => 'New project' do - %i.icon-plus - %li - = link_to profile_path, title: "Profile settings", class: 'has_bottom_tooltip', 'data-original-title' => 'Profile settings"' do - %i.icon-user - %li - = link_to destroy_user_session_path, class: "logout", method: :delete, title: "Logout", class: 'has_bottom_tooltip', 'data-original-title' => 'Logout' do - %i.icon-signout - %li - = link_to current_user, class: "profile-pic", id: 'profile-pic' do - = image_tag avatar_icon(current_user.email, 26), alt: 'User activity' + = link_to public_root_path, title: "Public area", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do + %i.icon-globe + %li + = link_to user_snippets_path(current_user), title: "My snippets", class: 'has_bottom_tooltip', 'data-original-title' => 'My snippets' do + %i.icon-paste + - if current_user.is_admin? + %li + = link_to admin_root_path, title: "Admin area", class: 'has_bottom_tooltip', 'data-original-title' => 'Admin area' do + %i.icon-cogs + - if current_user.can_create_project? + %li + = link_to new_project_path, title: "New project", class: 'has_bottom_tooltip', 'data-original-title' => 'New project' do + %i.icon-plus + %li + = link_to profile_path, title: "Profile settings", class: 'has_bottom_tooltip', 'data-original-title' => 'Profile settings"' do + %i.icon-user + %li + = link_to destroy_user_session_path, class: "logout", method: :delete, title: "Logout", class: 'has_bottom_tooltip', 'data-original-title' => 'Logout' do + %i.icon-signout + %li + = link_to current_user, class: "profile-pic", id: 'profile-pic' do + = image_tag avatar_icon(current_user.email, 26), alt: 'User activity' diff --git a/app/views/layouts/_public_head_panel.html.haml b/app/views/layouts/_public_head_panel.html.haml index 3c4bd857c22..7d188fb28e4 100644 --- a/app/views/layouts/_public_head_panel.html.haml +++ b/app/views/layouts/_public_head_panel.html.haml @@ -12,11 +12,12 @@ - else Public Projects - %ul.nav + .pull-right + = link_to "Sign in", new_session_path(:user), class: 'btn btn-sign-in btn-new' + + %ul.nav.navbar-nav %li %a %div.hide.turbolink-spinner %i.icon-refresh.icon-spin Loading... - %li - = link_to "Sign in", new_session_path(:user), class: 'btn btn-sign-in' diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml index 9a0db99332a..a0e55b21c32 100644 --- a/app/views/layouts/_search.html.haml +++ b/app/views/layouts/_search.html.haml @@ -7,4 +7,4 @@ = hidden_field_tag :search_code, true = hidden_field_tag :repository_ref, @ref = submit_tag 'Go' if ENV['RAILS_ENV'] == 'test' - .search-autocomplete-json.hide{:'data-autocomplete-opts' => search_autocomplete_source } + .search-autocomplete-opts.hide{:'data-autocomplete-path' => search_autocomplete_path, :'data-autocomplete-project-id' => @project.try(:id), :'data-autocomplete-project-ref' => @ref } diff --git a/app/views/layouts/project_settings.html.haml b/app/views/layouts/project_settings.html.haml index 6a10d6cf9e1..a55f043f2cf 100644 --- a/app/views/layouts/project_settings.html.haml +++ b/app/views/layouts/project_settings.html.haml @@ -15,7 +15,7 @@ .container .content .row - .span2 + .col-md-2 = render "projects/settings_nav" - .span10 + .col-md-10 = yield diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml index 0b1ccee9c39..3220736b078 100644 --- a/app/views/profiles/accounts/show.html.haml +++ b/app/views/profiles/accounts/show.html.haml @@ -23,8 +23,9 @@ %p.cgray - if current_user.private_token - = text_field_tag "token", current_user.private_token, class: "input-xlarge input-xpadding pull-left" - = f.submit 'Reset', data: { confirm: "Are you sure?" }, class: "btn btn-primary btn-build-token prepend-left-10" + = text_field_tag "token", current_user.private_token, class: "form-control" + %div + = f.submit 'Reset', data: { confirm: "Are you sure?" }, class: "btn btn-primary btn-build-token" - else %span You don`t have one yet. Click generate to fix it. = f.submit 'Generate', class: "btn success btn-build-token" @@ -47,7 +48,7 @@ %p Changing your username will change path to all personal projects! %div - = f.text_field :username, required: true, class: 'input-xlarge input-xpadding' + = f.text_field :username, required: true, class: 'form-control' %span.loading-gif.hide= image_tag "ajax_loader.gif" %p.light diff --git a/app/views/profiles/keys/_form.html.haml b/app/views/profiles/keys/_form.html.haml index 158979c0ee5..f905417f0e2 100644 --- a/app/views/profiles/keys/_form.html.haml +++ b/app/views/profiles/keys/_form.html.haml @@ -1,20 +1,18 @@ %div - = form_for [:profile, @key] do |f| + = form_for [:profile, @key], html: { class: 'form-horizontal' } do |f| - if @key.errors.any? - .alert.alert-error + .alert.alert-danger %ul - @key.errors.full_messages.each do |msg| %li= msg - .control-group - = f.label :title - .controls= f.text_field :title, class: "input-xlarge" - .control-group - = f.label :key - .controls - %p.light - Paste your public key here. Read more about how to generate a key on #{link_to "the SSH help page", help_ssh_path}. - = f.text_area :key, class: "input-xxlarge thin_area" + .form-group + = f.label :title, class: 'control-label' + .col-sm-10= f.text_field :title, class: "form-control" + .form-group + = f.label :key, class: 'control-label' + .col-sm-10 + = f.text_area :key, class: "form-control", rows: 8 .form-actions diff --git a/app/views/profiles/keys/_key.html.haml b/app/views/profiles/keys/_key.html.haml index 23f8de1dffb..81411a7565e 100644 --- a/app/views/profiles/keys/_key.html.haml +++ b/app/views/profiles/keys/_key.html.haml @@ -4,6 +4,6 @@ %span (#{key.fingerprint}) %span.cgray - added #{time_ago_with_tooltip(key.created_at)} ago + added #{time_ago_with_tooltip(key.created_at)} = link_to 'Remove', profile_key_path(key), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-small btn-remove delete-key pull-right" diff --git a/app/views/profiles/keys/new.html.haml b/app/views/profiles/keys/new.html.haml index f1b8fe08d5c..3d5a947948d 100644 --- a/app/views/profiles/keys/new.html.haml +++ b/app/views/profiles/keys/new.html.haml @@ -1,4 +1,6 @@ %h3.page-title Add an SSH Key +%p.light + Paste your public key here. Read more about how to generate a key on #{link_to "the SSH help page", help_ssh_path}. %hr = render 'form' diff --git a/app/views/profiles/keys/show.html.haml b/app/views/profiles/keys/show.html.haml index a0a315a5b75..b6724a7cb5d 100644 --- a/app/views/profiles/keys/show.html.haml +++ b/app/views/profiles/keys/show.html.haml @@ -1,5 +1,5 @@ .row - .span4 + .col-md-4 .ui-box .title SSH Key @@ -11,7 +11,7 @@ %span.light Created on: %strong= @key.created_at.stamp("Aug 21, 2011") - .span8 + .col-md-8 %p %span.light Fingerprint: %strong= @key.fingerprint diff --git a/app/views/profiles/notifications/_settings.html.haml b/app/views/profiles/notifications/_settings.html.haml index 5f62c8099d0..d123b8f9407 100644 --- a/app/views/profiles/notifications/_settings.html.haml +++ b/app/views/profiles/notifications/_settings.html.haml @@ -1,6 +1,6 @@ %li .row - .span4 + .col-sm-4 %span = notification_icon(notification) @@ -8,24 +8,24 @@ = link_to membership.group.name, membership.group - else = link_to_project(membership.project) - .span7 + .col-sm-8 = form_tag profile_notifications_path, method: :put, remote: true, class: 'update-notifications' do = hidden_field_tag :notification_type, type, id: dom_id(membership, 'notification_type') = hidden_field_tag :notification_id, membership.id, id: dom_id(membership, 'notification_id') - = label_tag do + = label_tag nil, class: 'radio-inline' do = radio_button_tag :notification_level, Notification::N_GLOBAL, notification.global?, id: dom_id(membership, 'notification_level'), class: 'trigger-submit' %span Use global setting - = label_tag do + = label_tag nil, class: 'radio-inline' do = radio_button_tag :notification_level, Notification::N_DISABLED, notification.disabled?, id: dom_id(membership, 'notification_level'), class: 'trigger-submit' %span Disabled - = label_tag do + = label_tag nil, class: 'radio-inline' do = radio_button_tag :notification_level, Notification::N_PARTICIPATING, notification.participating?, id: dom_id(membership, 'notification_level'), class: 'trigger-submit' %span Participating - = label_tag do + = label_tag nil, class: 'radio-inline' do = radio_button_tag :notification_level, Notification::N_WATCH, notification.watch?, id: dom_id(membership, 'notification_level'), class: 'trigger-submit' %span Watch diff --git a/app/views/profiles/notifications/show.html.haml b/app/views/profiles/notifications/show.html.haml index 8353b2f5f23..878d7f77430 100644 --- a/app/views/profiles/notifications/show.html.haml +++ b/app/views/profiles/notifications/show.html.haml @@ -18,23 +18,23 @@ – You will receive all notifications from projects in which you participate .row - .span4 + .col-sm-4 %h4 = notification_icon(@notification) Global setting - .span7 + .col-sm-8 = form_tag profile_notifications_path, method: :put, remote: true, class: 'update-notifications' do = hidden_field_tag :notification_type, 'global' - = label_tag do + = label_tag nil, class: 'radio-inline' do = radio_button_tag :notification_level, Notification::N_DISABLED, @notification.disabled?, class: 'trigger-submit' %span Disabled - = label_tag do + = label_tag nil, class: 'radio-inline' do = radio_button_tag :notification_level, Notification::N_PARTICIPATING, @notification.participating?, class: 'trigger-submit' %span Participating - = label_tag do + = label_tag nil, class: 'radio-inline' do = radio_button_tag :notification_level, Notification::N_WATCH, @notification.watch?, class: 'trigger-submit' %span Watch diff --git a/app/views/profiles/passwords/edit.html.haml b/app/views/profiles/passwords/edit.html.haml index a5fa6e7f186..2a7d317aa3e 100644 --- a/app/views/profiles/passwords/edit.html.haml +++ b/app/views/profiles/passwords/edit.html.haml @@ -3,30 +3,31 @@ Change your password or recover your current one. %hr .update-password - = form_for @user, url: profile_password_path, method: :put do |f| + = form_for @user, url: profile_password_path, method: :put, html: { class: 'form-horizontal' } do |f| %div %p.slead You must provide current password in order to change it. %br After a successful password update you will be redirected to login page where you should login with your new password -if @user.errors.any? - .alert.alert-error + .alert.alert-danger %ul - @user.errors.full_messages.each do |msg| %li= msg - .control-group - = f.label :current_password - .controls - = f.password_field :current_password, required: true + .form-group + = f.label :current_password, class: 'control-label' + .col-sm-10 + = f.password_field :current_password, required: true, class: 'form-control' %div = link_to "Forgot your password?", reset_profile_password_path, method: :put - .control-group - = f.label :password, 'New password' - .controls= f.password_field :password, required: true - .control-group - = f.label :password_confirmation - .controls - = f.password_field :password_confirmation, required: true + .form-group + = f.label :password, 'New password', class: 'control-label' + .col-sm-10 + = f.password_field :password, required: true, class: 'form-control' + .form-group + = f.label :password_confirmation, class: 'control-label' + .col-sm-10 + = f.password_field :password_confirmation, required: true, class: 'form-control' .form-actions = f.submit 'Save password', class: "btn btn-save" diff --git a/app/views/profiles/passwords/new.html.haml b/app/views/profiles/passwords/new.html.haml index a4e7dadd16a..f333879cf6c 100644 --- a/app/views/profiles/passwords/new.html.haml +++ b/app/views/profiles/passwords/new.html.haml @@ -5,18 +5,18 @@ %br After successful password update you will be redirected to login screen -if @user.errors.any? - .alert.alert-error + .alert.alert-danger %ul - @user.errors.full_messages.each do |msg| %li= msg - .control-group + .form-group = f.label :password - .controls= f.password_field :password, required: true - .control-group + .col-sm-10= f.password_field :password, required: true + .form-group = f.label :password_confirmation - .controls + .col-sm-10 = f.password_field :password_confirmation, required: true - .control-group - .controls + .form-group + .col-sm-10 = f.submit 'Set new password', class: "btn btn-create" diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index ca3f8247223..523a07db400 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -10,49 +10,52 @@ = form_for @user, url: profile_path, method: :put, html: { multipart: true, class: "edit_user form-horizontal" }, authenticity_token: true do |f| -if @user.errors.any? - %div.alert.alert-error + %div.alert.alert-danger %ul - @user.errors.full_messages.each do |msg| %li= msg .row - .span7 - .control-group + .col-md-7 + .form-group = f.label :name, class: "control-label" - .controls - = f.text_field :name, class: "input-xlarge", required: true + .col-sm-10 + = f.text_field :name, class: "form-control", required: true %span.help-block Enter your name, so people you know can recognize you. - .control-group + .form-group = f.label :email, class: "control-label" - .controls + .col-sm-10 - if @user.ldap_user? - = f.text_field :email, class: "input-xlarge", required: true, readonly: true + = f.text_field :email, class: "form-control", required: true, readonly: true %span.help-block.light Email is read-only for LDAP user - else - = f.text_field :email, class: "input-xlarge", required: true + = f.text_field :email, class: "form-control", required: true - if @user.unconfirmed_email.present? %span.help-block We sent confirmation email to %strong #{@user.unconfirmed_email} - else %span.help-block We also use email for avatar detection if no avatar is uploaded. - .control-group + .form-group = f.label :skype, class: "control-label" - .controls= f.text_field :skype, class: "input-xlarge" - .control-group + .col-sm-10= f.text_field :skype, class: "form-control" + .form-group = f.label :linkedin, class: "control-label" - .controls= f.text_field :linkedin, class: "input-xlarge" - .control-group + .col-sm-10= f.text_field :linkedin, class: "form-control" + .form-group = f.label :twitter, class: "control-label" - .controls= f.text_field :twitter, class: "input-xlarge" - .control-group + .col-sm-10= f.text_field :twitter, class: "form-control" + .form-group + = f.label :website_url, 'Website', class: "control-label" + .col-sm-10= f.text_field :website_url, class: "form-control" + .form-group = f.label :bio, class: "control-label" - .controls - = f.text_area :bio, rows: 6, class: "input-xlarge", maxlength: 250 + .col-sm-10 + = f.text_area :bio, rows: 6, class: "form-control", maxlength: 250 %span.help-block Tell us about yourself in fewer than 250 characters. - .span5.pull-right + .col-md-5 .light-well = image_tag avatar_icon(@user.email, 160), alt: '', class: 'avatar s160' @@ -73,7 +76,7 @@ %span Choose File ... %span.file_name.js-avatar-filename File name... - = f.file_field :avatar, class: "js-user-avatar-input hide" + = f.file_field :avatar, class: "js-user-avatar-input hidden" .light The maximum file size allowed is 100KB. - if @user.avatar? %hr diff --git a/app/views/projects/_errors.html.haml b/app/views/projects/_errors.html.haml index bb9759353a3..7c8bb33ed7e 100644 --- a/app/views/projects/_errors.html.haml +++ b/app/views/projects/_errors.html.haml @@ -1,4 +1,4 @@ - if @project.errors.any? - .alert.alert-error + .alert.alert-danger %button{ type: "button", class: "close", "data-dismiss" => "alert"} × = @project.errors.full_messages.first diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index acb85fa0fd9..48e6ea91d94 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -1,31 +1,31 @@ - empty_repo = @project.empty_repo? .project-home-panel{:class => ("empty-project" if empty_repo)} + .visibility-level-label.has_tooltip{'data-title' => "#{visibility_level_label(@project.visibility_level)} project" } + = visibility_level_icon(@project.visibility_level) .row - .span6 + .col-sm-6 %h4.project-home-title = @project.name_with_namespace - %span.visibility-level-label - = visibility_level_icon(@project.visibility_level) - = visibility_level_label(@project.visibility_level) - .span6 + .col-sm-6 - unless empty_repo .project-home-dropdown = render "dropdown" - .form-horizontal - = render "shared/clone_panel" + = render "shared/clone_panel" - .project-home-extra.clearfix.row - .project-home-desc.span8 - - if @project.description.present? - = @project.description - - if can?(current_user, :admin_project, @project) - – - %strong= link_to 'Edit', edit_project_path + .project-home-extra.row + .col-md-8 + .project-home-desc + - if @project.description.present? + = @project.description + - if can?(current_user, :admin_project, @project) + – + %strong= link_to 'Edit', edit_project_path - unless empty_repo - .project-home-links - = link_to pluralize(@repository.round_commit_count, 'commit'), project_commits_path(@project, @ref || @repository.root_ref) - = link_to pluralize(@repository.branch_names.count, 'branch'), project_branches_path(@project) - = link_to pluralize(@repository.tag_names.count, 'tag'), project_tags_path(@project) - %span.light.prepend-left-20= repository_size + .col-md-4 + .project-home-links + = link_to pluralize(@repository.round_commit_count, 'commit'), project_commits_path(@project, @ref || @repository.root_ref) + = link_to pluralize(@repository.branch_names.count, 'branch'), project_branches_path(@project) + = link_to pluralize(@repository.tag_names.count, 'tag'), project_tags_path(@project) + %span.light.prepend-left-20= repository_size diff --git a/app/views/projects/_settings_nav.html.haml b/app/views/projects/_settings_nav.html.haml index f59e2871aa3..e4cfabc3100 100644 --- a/app/views/projects/_settings_nav.html.haml +++ b/app/views/projects/_settings_nav.html.haml @@ -1,11 +1,9 @@ -%ul.nav.nav-pills.nav-stacked.nav-stacked-menu +%ul.nav.nav-pills.nav-stacked.nav-stacked-menu.append-bottom-20 = nav_link(path: 'projects#edit') do = link_to edit_project_path(@project), class: "stat-tab tab " do - %i.icon-edit Edit Project = nav_link(controller: [:team_members, :teams]) do = link_to project_team_index_path(@project), class: "team-tab tab" do - %i.icon-group Members = nav_link(controller: :deploy_keys) do = link_to project_deploy_keys_path(@project) do diff --git a/app/views/projects/_visibility_level.html.haml b/app/views/projects/_visibility_level.html.haml index 7fc257811ca..eb38fce0ecf 100644 --- a/app/views/projects/_visibility_level.html.haml +++ b/app/views/projects/_visibility_level.html.haml @@ -1,26 +1,27 @@ -.control-group.project-visibility-level-holder - = f.label :visibility_level do +.form-group.project-visibility-level-holder + = f.label :visibility_level, class: 'control-label' do Visibility Level = link_to "(?)", help_public_access_path - - if can_change_visibility_level - - Gitlab::VisibilityLevel.values.each do |level| - - restricted = restricted_visibility_levels.include?(level) - .controls - = f.radio_button :visibility_level, level, checked: (visibility_level == level), disabled: restricted - %span.descr{:class => ("restricted" if restricted)} + .col-sm-10 + - if can_change_visibility_level + - Gitlab::VisibilityLevel.values.each do |level| + .radio + - restricted = restricted_visibility_levels.include?(level) + = f.radio_button :visibility_level, level, checked: (visibility_level == level), disabled: restricted = label :project_visibility_level, level do = visibility_level_icon(level) - %strong + .option-title = visibility_level_label(level) - .light= visibility_level_description(level) - - unless restricted_visibility_levels.empty? - .controls + .option-descr + = visibility_level_description(level) + - unless restricted_visibility_levels.empty? + .col-sm-10 + %span.info + Some visibility level settings have been restricted by the administrator. + - else + .col-sm-10 %span.info - Some visibility level settings have been restricted by the administrator. - - else - .controls - %span.info - = visibility_level_icon(visibility_level) - %strong - = visibility_level_label(visibility_level) - .light= visibility_level_description(visibility_level) + = visibility_level_icon(visibility_level) + %strong + = visibility_level_label(visibility_level) + .light= visibility_level_description(visibility_level) diff --git a/app/views/projects/blob/_blob.html.haml b/app/views/projects/blob/_blob.html.haml index 6524aaeef4c..32ea967105a 100644 --- a/app/views/projects/blob/_blob.html.haml +++ b/app/views/projects/blob/_blob.html.haml @@ -4,7 +4,6 @@ = link_to project_tree_path(@project, @ref) do = @project.path - tree_breadcrumbs(@tree, 6) do |title, path| - \/ %li - if path - if path.end_with?(@path) diff --git a/app/views/projects/blob/_remove.html.haml b/app/views/projects/blob/_remove.html.haml index 1c097330c44..6384703671a 100644 --- a/app/views/projects/blob/_remove.html.haml +++ b/app/views/projects/blob/_remove.html.haml @@ -1,19 +1,22 @@ -%div#modal-remove-blob.modal.hide - .modal-header - %a.close{href: "#", "data-dismiss" => "modal"} × - %h3.page-title Remove #{@blob.name} - %p.light - From branch - %strong= @ref +#modal-remove-blob.modal.hide + .modal-dialog + .modal-content + .modal-header + %a.close{href: "#", "data-dismiss" => "modal"} × + %h3.page-title Remove #{@blob.name} + %p.light + From branch + %strong= @ref - .modal-body - = form_tag project_blob_path(@project, @id), method: :delete do - .control-group.commit_message-group - = label_tag 'commit_message', class: "control-label" do - Commit message - .controls - = text_area_tag 'commit_message', params[:commit_message], placeholder: "Removed this file because...", required: true, rows: 3 - .control-group - .controls - = submit_tag 'Remove file', class: 'btn btn-remove' - = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal" + .modal-body + = form_tag project_blob_path(@project, @id), method: :delete, class: 'form-horizontal' do + .form-group.commit_message-group + = label_tag 'commit_message', class: "control-label" do + Commit message + .col-sm-10 + = text_area_tag 'commit_message', params[:commit_message], placeholder: "Removed this file because...", required: true, rows: 3, class: 'form-control' + .form-group + .col-sm-2 + .col-sm-10 + = submit_tag 'Remove file', class: 'btn btn-remove' + = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal" diff --git a/app/views/projects/blob/_text.html.haml b/app/views/projects/blob/_text.html.haml index bed493d6d8c..d03b53888ae 100644 --- a/app/views/projects/blob/_text.html.haml +++ b/app/views/projects/blob/_text.html.haml @@ -4,7 +4,7 @@ = markdown(blob.data) - elsif markup?(blob.name) .file-content.wiki - = raw GitHub::Markup.render(blob.name, blob.data) + = render_markup(blob.name, blob.data) - else .file-content.code - unless blob.empty? diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml index b41942baf40..4fd708517fc 100644 --- a/app/views/projects/branches/_branch.html.haml +++ b/app/views/projects/branches/_branch.html.haml @@ -10,9 +10,7 @@ %i.icon-lock .pull-right - if can?(current_user, :download_code, @project) - = link_to archive_project_repository_path(@project, ref: branch.name), class: 'btn grouped btn-small' do - %i.icon-download-alt - Download + = render 'projects/repositories/download_archive', ref: branch.name, btn_class: 'grouped btn-group-small' = link_to project_compare_index_path(@project, from: branch.name, to: branch.name), class: 'btn grouped btn-small', title: "Compare" do %i.icon-copy Compare @@ -27,4 +25,4 @@ = image_tag avatar_icon(commit.author_email), class: "avatar s16", alt: '' %span.light = gfm escape_once(truncate(commit.title, length: 40)) - #{time_ago_with_tooltip(commit.committed_date)} ago + #{time_ago_with_tooltip(commit.committed_date)} diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml index 45b9c6c8521..690df98a2ab 100644 --- a/app/views/projects/branches/index.html.haml +++ b/app/views/projects/branches/index.html.haml @@ -1,10 +1,10 @@ = render "projects/commits/head" .row - .span3 + .col-md-3 = render "filter" - .span9 + .col-md-9 - unless @branches.empty? %ul.bordered-list.top-list - @branches.each do |branch| = render "projects/branches/branch", branch: branch - = paginate @branches, theme: 'gitlab'
\ No newline at end of file + = paginate @branches, theme: 'gitlab' diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml index 37612d3fd7b..5da2ede2937 100644 --- a/app/views/projects/branches/new.html.haml +++ b/app/views/projects/branches/new.html.haml @@ -1,16 +1,15 @@ %h3.page-title %i.icon-code-fork New branch -= form_tag project_branches_path, method: :post do - .control-group += form_tag project_branches_path, method: :post, class: "form-horizontal" do + .form-group = label_tag :branch_name, 'Name for new branch', class: 'control-label' - .controls - = text_field_tag :branch_name, nil, placeholder: 'feature/dashboard', required: true, tabindex: 1 - .control-group + .col-sm-10 + = text_field_tag :branch_name, nil, placeholder: 'enter new branch name', required: true, tabindex: 1, class: 'form-control' + .form-group = label_tag :ref, 'Create from', class: 'control-label' - .controls - = text_field_tag :ref, nil, placeholder: 'master', required: true, tabindex: 2 - .light branch name or commit SHA + .col-sm-10 + = text_field_tag :ref, nil, placeholder: 'existing branch name, tag or commit SHA', required: true, tabindex: 2, class: 'form-control' .form-actions = submit_tag 'Create branch', class: 'btn btn-create', tabindex: 3 = link_to 'Cancel', project_branches_path(@project), class: 'btn btn-cancel' diff --git a/app/views/projects/branches/recent.html.haml b/app/views/projects/branches/recent.html.haml index 25f416c78f2..37d7919121e 100644 --- a/app/views/projects/branches/recent.html.haml +++ b/app/views/projects/branches/recent.html.haml @@ -1,8 +1,8 @@ = render "projects/commits/head" .row - .span3 + .col-md-3 = render "filter" - .span9 + .col-md-9 %ul.bordered-list.top-list - @branches.each do |branch| - = render "projects/branches/branch", branch: branch
\ No newline at end of file + = render "projects/branches/branch", branch: branch diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index 1dff75f51cc..3d666807cf9 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -23,14 +23,14 @@ %span.light Authored by %strong = commit_author_link(@commit, avatar: true, size: 24) - #{time_ago_with_tooltip(@commit.authored_date)} ago + #{time_ago_with_tooltip(@commit.authored_date)} - if @commit.different_committer? .commit-info-row %span.light Committed by %strong = commit_committer_link(@commit, avatar: true, size: 24) - #{time_ago_with_tooltip(@commit.committed_date)} ago + #{time_ago_with_tooltip(@commit.committed_date)} .commit-info-row %span.cgray= pluralize(@commit.parents.count, "parent") diff --git a/app/views/projects/commit/huge_commit.html.haml b/app/views/projects/commit/huge_commit.html.haml index 210d8d9e207..398ce771426 100644 --- a/app/views/projects/commit/huge_commit.html.haml +++ b/app/views/projects/commit/huge_commit.html.haml @@ -1,3 +1,3 @@ = render "projects/commit/commit_box" -.alert.alert-error +.alert.alert-danger %h4 Commit diffs are too big to be displayed diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index 658b23fbcfa..9772d3ef2ef 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -2,7 +2,8 @@ .commit-row-title = link_to commit.short_id(8), project_commit_path(project, commit), class: "commit_short_id" - = link_to_gfm truncate(commit.title, length: 70), project_commit_path(project, commit.id), class: "commit-row-message" + %span.str-truncated + = link_to_gfm commit.title, project_commit_path(project, commit.id), class: "commit-row-message" = link_to "Browse Code »", project_tree_path(project, commit), class: "pull-right" .notes_count - notes = project.notes.for_commit_id(commit.id) @@ -14,4 +15,4 @@ .commit-row-info = commit_author_link(commit, avatar: true, size: 16) .committed_ago - #{time_ago_with_tooltip(commit.committed_date)} ago + #{time_ago_with_tooltip(commit.committed_date)} diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml index b6404778073..e3411b62eb6 100644 --- a/app/views/projects/commits/_commits.html.haml +++ b/app/views/projects/commits/_commits.html.haml @@ -1,11 +1,11 @@ - @commits.group_by { |c| c.committed_date.to_date }.sort.reverse.each do |day, commits| .row.commits-row - .span2 + .col-md-2 %h4 %i.icon-calendar %span= day.stamp("28 Aug, 2010") %p= pluralize(commits.count, 'commit') - .span10 + .col-md-10 %ul.well-list = render commits, project: @project %hr.lists-separator diff --git a/app/views/projects/commits/_diffs.html.haml b/app/views/projects/commits/_diffs.html.haml index 2a32f56e8f0..a41a89bb972 100644 --- a/app/views/projects/commits/_diffs.html.haml +++ b/app/views/projects/commits/_diffs.html.haml @@ -1,6 +1,6 @@ - @suppress_diff ||= @suppress_diff || @force_suppress_diff - if @suppress_diff - .alert.alert-block + .alert.alert-warning %p %strong Warning! This is a large diff. %p @@ -67,7 +67,7 @@ - next unless file.respond_to?('text?') - if file.text? - if params[:view] == 'parallel' - = render "projects/commits/parallel_view", diff: diff, project: project, file: file, index: i + = render "projects/commits/parallel_view", diff: diff, project: project, file: file, index: i - else = render "projects/commits/text_file", diff: diff, index: i - elsif file.image? diff --git a/app/views/projects/commits/_head.html.haml b/app/views/projects/commits/_head.html.haml index c2da9f273b3..b9ab27d212c 100644 --- a/app/views/projects/commits/_head.html.haml +++ b/app/views/projects/commits/_head.html.haml @@ -1,4 +1,4 @@ -%ul.nav.nav-tabs +%ul.nav.nav-tabs.append-bottom-15 %li= render partial: 'shared/ref_switcher', locals: {destination: 'commits'} = nav_link(controller: [:commit, :commits]) do @@ -22,6 +22,6 @@ - if current_user && current_controller?(:commits) && current_user.private_token - %li.pull-right + %li.pull-right.hidden-sm = link_to project_commits_path(@project, @ref, {format: :atom, private_token: current_user.private_token}), title: "Feed" do %i.icon-rss diff --git a/app/views/projects/commits/_image.html.haml b/app/views/projects/commits/_image.html.haml index 73f87289d3d..9a8b7c857e5 100644 --- a/app/views/projects/commits/_image.html.haml +++ b/app/views/projects/commits/_image.html.haml @@ -49,7 +49,7 @@ %img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"} .frame.added %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} - .controls + .col-sm-10 .transparent .drag-track .dragger{:style => "left: 0px;"} @@ -60,4 +60,4 @@ %ul.view-modes-menu %li.two-up{data: {mode: 'two-up'}} 2-up %li.swipe{data: {mode: 'swipe'}} Swipe - %li.onion-skin{data: {mode: 'onion-skin'}} Onion skin
\ No newline at end of file + %li.onion-skin{data: {mode: 'onion-skin'}} Onion skin diff --git a/app/views/projects/commits/_inline_commit.html.haml b/app/views/projects/commits/_inline_commit.html.haml index 2129a45b9a5..f5863463fee 100644 --- a/app/views/projects/commits/_inline_commit.html.haml +++ b/app/views/projects/commits/_inline_commit.html.haml @@ -3,4 +3,4 @@ = link_to commit.short_id(8), project_commit_path(project, commit), class: "commit_short_id" = link_to_gfm truncate(commit.title, length: 40), project_commit_path(project, commit.id), class: "commit-row-message" - #{time_ago_with_tooltip(commit.committed_date)} ago + #{time_ago_with_tooltip(commit.committed_date)} diff --git a/app/views/projects/compare/_form.html.haml b/app/views/projects/compare/_form.html.haml index ca1ea4073e6..0762655fb93 100644 --- a/app/views/projects/compare/_form.html.haml +++ b/app/views/projects/compare/_form.html.haml @@ -1,21 +1,21 @@ -= form_tag project_compare_index_path(@project), method: :post do - .clearfix - .pull-left - - if params[:to] && params[:from] - = link_to 'switch', {from: params[:to], to: params[:from]}, {class: 'commits-compare-switch has_tooltip', title: 'Switch base of comparison'} - .input-prepend - %span.add-on.input-xpadding from - = text_field_tag :from, params[:from], class: "span3 input-xpadding" - = "..." - .input-prepend - %span.add-on.input-xpadding to - = text_field_tag :to, params[:to], class: "span3 input-xpadding" - .pull-left - - = submit_tag "Compare", class: "btn btn-create commits-compare-btn" - - if compare_to_mr_button? - = link_to compare_mr_path, class: 'prepend-left-10' do - %strong Make a merge request += form_tag project_compare_index_path(@project), method: :post, class: 'form-inline' do + .clearfix.append-bottom-20 + - if params[:to] && params[:from] + = link_to 'switch', {from: params[:to], to: params[:from]}, {class: 'commits-compare-switch has_tooltip', title: 'Switch base of comparison'} + .form-group + .input-group.inline-input-group + %span.input-group-addon from + = text_field_tag :from, params[:from], class: "form-control" + = "..." + .form-group + .input-group.inline-input-group + %span.input-group-addon to + = text_field_tag :to, params[:to], class: "form-control" + + = submit_tag "Compare", class: "btn btn-create commits-compare-btn" + - if compare_to_mr_button? + = link_to compare_mr_path, class: 'prepend-left-10' do + %strong Make a merge request :javascript diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml index 4be62d36917..e9456c24960 100644 --- a/app/views/projects/compare/show.html.haml +++ b/app/views/projects/compare/show.html.haml @@ -6,7 +6,7 @@ = render "form" - if @commits.size > 100 - .alert.alert-block + .alert.alert-warning %p %strong Warning! This comparison includes more than 100 commits. %p To preserve performance the line diff is not shown. diff --git a/app/views/projects/deploy_keys/_deploy_key.html.haml b/app/views/projects/deploy_keys/_deploy_key.html.haml index 72bca7156a2..2b4f36fb4b8 100644 --- a/app/views/projects/deploy_keys/_deploy_key.html.haml +++ b/app/views/projects/deploy_keys/_deploy_key.html.haml @@ -21,4 +21,4 @@ - deploy_key.projects.map(&:name_with_namespace).each do |project_name| %span.label.label-gray.deploy-project-label= project_name %small.pull-right - Created #{time_ago_with_tooltip(deploy_key.created_at)} ago + Created #{time_ago_with_tooltip(deploy_key.created_at)} diff --git a/app/views/projects/deploy_keys/_form.html.haml b/app/views/projects/deploy_keys/_form.html.haml index d49b2204537..ebb92b36b47 100644 --- a/app/views/projects/deploy_keys/_form.html.haml +++ b/app/views/projects/deploy_keys/_form.html.haml @@ -1,21 +1,21 @@ %div - = form_for [@project, @key], url: project_deploy_keys_path do |f| + = form_for [@project, @key], url: project_deploy_keys_path, html: { class: 'deploy-key-form form-horizontal' } do |f| -if @key.errors.any? - .alert.alert-error + .alert.alert-danger %ul - @key.errors.full_messages.each do |msg| %li= msg - .control-group - = f.label :title - .controls= f.text_field :title, class: 'input-xlarge' - .control-group - = f.label :key - .controls + .form-group + = f.label :title, class: "control-label" + .col-sm-10= f.text_field :title, class: 'form-control' + .form-group + = f.label :key, class: "control-label" + .col-sm-10 %p.light Paste a machine public key here. Read more about how to generate it = link_to "here", help_ssh_path - = f.text_area :key, class: "input-xxlarge thin_area" + = f.text_area :key, class: "form-control thin_area", rows: 5 .form-actions = f.submit 'Create', class: "btn-create btn" diff --git a/app/views/projects/deploy_keys/index.html.haml b/app/views/projects/deploy_keys/index.html.haml index 53d6e36c62c..90d86102aca 100644 --- a/app/views/projects/deploy_keys/index.html.haml +++ b/app/views/projects/deploy_keys/index.html.haml @@ -12,7 +12,7 @@ %hr.clearfix .row - .span5.enabled-keys + .col-md-6.enabled-keys %h5 %strong.cgreen Enabled deploy keys for this project @@ -21,7 +21,7 @@ - if @enabled_keys.blank? .light-well %p.nothing_here_message Create a #{link_to 'new deploy key', new_project_deploy_key_path(@project)} or add an existing one - .span5.available-keys + .col-md-6.available-keys %h5 %strong Deploy keys from projects available to you diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 20656d297e5..79234fe4fa9 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -7,26 +7,26 @@ %p.light Some settings, such as "Transfer Project", are hidden inside the danger area below %hr .form-holder - = form_for(@project, remote: true) do |f| + = form_for @project, remote: true, html: { class: "edit_project form-horizontal" } do |f| %fieldset - .control-group.project_name_holder - = f.label :name do + .form-group.project_name_holder + = f.label :name, class: 'control-label' do Project name - .controls - = f.text_field :name, placeholder: "Example Project", class: "span5" + .col-sm-10 + = f.text_field :name, placeholder: "Example Project", class: "form-control" - .control-group - = f.label :description do + .form-group + = f.label :description, class: 'control-label' do Project description %span.light (optional) - .controls - = f.text_area :description, placeholder: "Awesome project", class: "span5", rows: 3, maxlength: 250 + .col-sm-10 + = f.text_area :description, placeholder: "Awesome project", class: "form-control", rows: 3, maxlength: 250 - if @project.repository.exists? && @project.repository.branch_names.any? - .control-group - = f.label :default_branch, "Default Branch" - .controls= f.select(:default_branch, @repository.branch_names, {}, {class: 'chosen'}) + .form-group + = f.label :default_branch, "Default Branch", class: 'control-label' + .col-sm-10= f.select(:default_branch, @repository.branch_names, {}, {class: 'select2 select-wide'}) = render "visibility_level", f: f, visibility_level: @project.visibility_level, can_change_visibility_level: can?(current_user, :change_visibility_level, @project) @@ -34,53 +34,58 @@ %fieldset.features %legend Labels: - .control-group + .form-group = f.label :label_list, "Labels", class: 'control-label' - .controls - = f.text_field :label_list, maxlength: 2000, class: "span5" + .col-sm-10 + = f.text_field :label_list, maxlength: 2000, class: "form-control" %p.hint Separate labels with commas. %fieldset.features %legend Features: - .control-group + .form-group = f.label :issues_enabled, "Issues", class: 'control-label' - .controls - = f.check_box :issues_enabled - %span.descr Lightweight issue tracking system for this project + .col-sm-10 + .checkbox + = f.check_box :issues_enabled + %span.descr Lightweight issue tracking system for this project - if Project.issues_tracker.values.count > 1 - .control-group + .form-group = f.label :issues_tracker, "Issues tracker", class: 'control-label' - .controls= f.select(:issues_tracker, project_issues_trackers(@project.issues_tracker), {}, { disabled: !@project.issues_enabled }) + .col-sm-10= f.select(:issues_tracker, project_issues_trackers(@project.issues_tracker), {}, { disabled: !@project.issues_enabled }) - .control-group + .form-group = f.label :issues_tracker_id, "Project name or id in issues tracker", class: 'control-label' - .controls= f.text_field :issues_tracker_id, disabled: !@project.can_have_issues_tracker_id? + .col-sm-10= f.text_field :issues_tracker_id, disabled: !@project.can_have_issues_tracker_id?, class: 'form-control' - .control-group + .form-group = f.label :merge_requests_enabled, "Merge Requests", class: 'control-label' - .controls - = f.check_box :merge_requests_enabled - %span.descr Submit changes to be merged upstream. + .col-sm-10 + .checkbox + = f.check_box :merge_requests_enabled + %span.descr Submit changes to be merged upstream. - .control-group + .form-group = f.label :wiki_enabled, "Wiki", class: 'control-label' - .controls - = f.check_box :wiki_enabled - %span.descr Pages for project documentation + .col-sm-10 + .checkbox + = f.check_box :wiki_enabled + %span.descr Pages for project documentation - .control-group + .form-group = f.label :wall_enabled, "Wall", class: 'control-label' - .controls - = f.check_box :wall_enabled - %span.descr Simple chat system for broadcasting inside project + .col-sm-10 + .checkbox + = f.check_box :wall_enabled + %span.descr Simple chat system for broadcasting inside project - .control-group + .form-group = f.label :snippets_enabled, "Snippets", class: 'control-label' - .controls - = f.check_box :snippets_enabled - %span.descr Share code pastes with others out of git repository + .col-sm-10 + .checkbox + = f.check_box :snippets_enabled + %span.descr Share code pastes with others out of git repository .form-actions @@ -134,13 +139,13 @@ .title Transfer project .errors-holder .form-holder - = form_for(@project, url: transfer_project_path(@project), method: :put, remote: true, html: { class: 'transfer-project' }) do |f| - .control-group - = f.label :namespace_id do + = form_for(@project, url: transfer_project_path(@project), method: :put, remote: true, html: { class: 'transfer-project form-horizontal' }) do |f| + .form-group + = f.label :namespace_id, class: 'control-label' do %span Namespace - .controls - .control-group - = f.select :namespace_id, namespaces_options(@project.namespace_id), { prompt: 'Choose a project namespace' }, { class: 'chosen' } + .col-sm-10 + .form-group + = f.select :namespace_id, namespaces_options(@project.namespace_id), { prompt: 'Choose a project namespace' }, { class: 'select2' } %ul %li Be careful. Changing the project's namespace can have unintended side effects. %li You can only transfer the project to namespaces you manage. @@ -154,15 +159,15 @@ .title Rename repository .errors-holder .form-holder - = form_for(@project) do |f| - .control-group - = f.label :path do + = form_for(@project, html: { class: 'form-horizontal' }) do |f| + .form-group + = f.label :path, class: 'control-label' do %span Path - .controls - .control-group - .input-append - = f.text_field :path - %span.add-on .git + .col-sm-9 + .form-group + .input-group + = f.text_field :path, class: 'form-control' + %span.input-group-addon .git %ul %li Be careful. Renaming a project's repository can have unintended side effects. %li You will need to update your local repositories to point to the new location. diff --git a/app/views/projects/edit_tree/show.html.haml b/app/views/projects/edit_tree/show.html.haml index 9bb3eefe0cf..10dae3c8ff0 100644 --- a/app/views/projects/edit_tree/show.html.haml +++ b/app/views/projects/edit_tree/show.html.haml @@ -15,11 +15,11 @@ .file-content.code %pre#editor= @blob.data - .control-group.commit_message-group + .form-group.commit_message-group = label_tag 'commit_message', class: "control-label" do Commit message - .controls - = text_area_tag 'commit_message', '', placeholder: "Update #{@blob.name}", required: true, rows: 3 + .col-sm-10 + = text_area_tag 'commit_message', '', placeholder: "Update #{@blob.name}", required: true, rows: 3, class: 'form-control' .form-actions = hidden_field_tag 'last_commit', @last_commit = hidden_field_tag 'content', '', id: "file-content" diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml index 15cf150460f..eae4949fcd3 100644 --- a/app/views/projects/empty.html.haml +++ b/app/views/projects/empty.html.haml @@ -29,8 +29,7 @@ touch README git add README git commit -m 'first commit' - %span.clone= "git remote add origin #{default_url_to_repo}" - :preserve + git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'clone')} git push -u origin master %fieldset @@ -38,8 +37,7 @@ %pre.dark :preserve cd existing_git_repo - %span.clone= "git remote add origin #{default_url_to_repo}" - :preserve + git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'clone')} git push -u origin master - if can? current_user, :remove_project, @project diff --git a/app/views/projects/fork.html.haml b/app/views/projects/fork.html.haml index 227fde8a735..bdd75de447a 100644 --- a/app/views/projects/fork.html.haml +++ b/app/views/projects/fork.html.haml @@ -1,4 +1,4 @@ -.alert.alert-error.alert-block +.alert.alert-danger.alert-block %h4 %i.icon-code-fork Fork Error! diff --git a/app/views/projects/graphs/show.js.haml b/app/views/projects/graphs/show.js.haml index 43e776e5330..dcf6cacdceb 100644 --- a/app/views/projects/graphs/show.js.haml +++ b/app/views/projects/graphs/show.js.haml @@ -16,4 +16,4 @@ }) - else :plain - $('.stat-graph').replaceWith('<div class="alert alert-error">Failed to load graph</div>') + $('.stat-graph').replaceWith('<div class="alert alert-danger">Failed to load graph</div>') diff --git a/app/views/projects/hooks/index.html.haml b/app/views/projects/hooks/index.html.haml index 2ac67140bd7..a095fd06d2f 100644 --- a/app/views/projects/hooks/index.html.haml +++ b/app/views/projects/hooks/index.html.haml @@ -3,46 +3,45 @@ %p.light #{link_to "Web hooks ", help_web_hooks_path, class: "vlink"} can be - used for binding events when something happends to the the project. + used for binding events when something is happening within the project. %hr.clearfix -= form_for [@project, @hook], as: :hook, url: project_hooks_path(@project), html: { class: 'form-inline' } do |f| += form_for [@project, @hook], as: :hook, url: project_hooks_path(@project), html: { class: 'form-horizontal' } do |f| -if @hook.errors.any? - .alert.alert-error + .alert.alert-danger - @hook.errors.full_messages.each do |msg| %p= msg - .control-group - = f.label :url, "URL" - .controls - = f.text_field :url, class: "text_field input-xxlarge input-xpadding", placeholder: 'http://example.com/trigger-ci.json' - - = f.submit "Add Web Hook", class: "btn btn-create" - .control-group - = f.label :url, "Trigger" - .controls + .form-group + = f.label :url, "URL", class: 'control-label' + .col-sm-10 + = f.text_field :url, class: "form-control", placeholder: 'http://example.com/trigger-ci.json' + .form-group + = f.label :url, "Trigger", class: 'control-label' + .col-sm-10 %div = f.check_box :push_events, class: 'pull-left' .prepend-left-20 = f.label :push_events, class: 'list-label' do %strong Push events %p.light - This url will be triggered in case of push to repository + This url will be triggered by a push to the repository %div = f.check_box :issues_events, class: 'pull-left' .prepend-left-20 = f.label :issues_events, class: 'list-label' do %strong Issues events %p.light - This url will be triggered for created issues + This url will be triggered when an issue is created %div = f.check_box :merge_requests_events, class: 'pull-left' .prepend-left-20 = f.label :merge_requests_events, class: 'list-label' do %strong Merge Request events %p.light - This url will be triggered for created merge requests -%hr + This url will be triggered when a merge request is created + .form-actions + = f.submit "Add Web Hook", class: "btn btn-create" -if @hooks.any? .ui-box diff --git a/app/views/projects/issues/_form.html.haml b/app/views/projects/issues/_form.html.haml index 80d1aac6d3e..c95e8178594 100644 --- a/app/views/projects/issues/_form.html.haml +++ b/app/views/projects/issues/_form.html.haml @@ -1,50 +1,47 @@ %div.issue-form-holder %h3.page-title= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.iid}" - = form_for [@project, @issue] do |f| + %hr + = form_for [@project, @issue], html: { class: 'form-horizontal issue-form' } do |f| -if @issue.errors.any? - .alert.alert-error + .alert.alert-danger - @issue.errors.full_messages.each do |msg| %span= msg %br - .issue-box - .title - .control-group - = f.label :title do - %strong= "Subject *" - .controls - = f.text_field :title, maxlength: 255, class: "input-xxlarge js-gfm-input", autofocus: true, required: true - .context - .control-group - .issue_assignee.pull-left - = f.label :assignee_id do - %i.icon-user - Assign to - .controls - .pull-left - = f.select(:assignee_id, assignee_options(@issue), { include_blank: "Select a user" }, {class: 'chosen'}) - .pull-right - - = link_to 'Assign to me', '#', class: 'btn btn-small assign-to-me-link' - .issue_milestone.pull-left - = f.label :milestone_id do - %i.icon-time - Milestone - .controls= f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'chosen'}) + .form-group + = f.label :title, class: 'control-label' do + %strong= "Subject *" + .col-sm-10 + = f.text_field :title, maxlength: 255, class: "form-control js-gfm-input", autofocus: true, required: true + .form-group + = f.label :description, "Details", class: 'control-label' + .col-sm-10 + = f.text_area :description, class: "form-control js-gfm-input", rows: 14 + %p.hint Issues are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + %hr + .form-group + .issue-assignee + = f.label :assignee_id, class: 'control-label' do + %i.icon-user + Assign to + .col-sm-10 + = f.select(:assignee_id, assignee_options(@issue), { include_blank: "Select a user" }, {class: 'select2'}) + + = link_to 'Assign to me', '#', class: 'btn btn-small assign-to-me-link' + .form-group + .issue-milestone + = f.label :milestone_id, class: 'control-label' do + %i.icon-time + Milestone + .col-sm-10= f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'select2'}) - .description - .control-group - = f.label :label_list do - %i.icon-tag - Labels - .controls - = f.text_field :label_list, maxlength: 2000, class: "input-xxlarge" - %p.hint Separate labels with commas. + .form-group + = f.label :label_list, class: 'control-label' do + %i.icon-tag + Labels + .col-sm-10 + = f.text_field :label_list, maxlength: 2000, class: "form-control" + %p.hint Separate labels with commas. - .control-group - = f.label :description, "Details" - .controls - = f.text_area :description, class: "input-xxlarge js-gfm-input", rows: 14 - %p.hint Issues are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. .form-actions @@ -90,6 +87,6 @@ }); $('.assign-to-me-link').on('click', function(e){ - $('#issue_assignee_id').val("#{current_user.id}").trigger("chosen:updated"); + $('#issue_assignee_id').val("#{current_user.id}").trigger("change"); e.preventDefault(); }); diff --git a/app/views/projects/issues/_head.html.haml b/app/views/projects/issues/_head.html.haml index a44db78a92b..61213e752f8 100644 --- a/app/views/projects/issues/_head.html.haml +++ b/app/views/projects/issues/_head.html.haml @@ -1,4 +1,4 @@ -%ul.nav.nav-tabs +%ul.nav.nav-tabs.append-bottom-15 = nav_link(controller: :issues) do = link_to project_issues_path(@project), class: "tab" do Browse Issues @@ -17,9 +17,10 @@ %li.pull-right .pull-right + = form_tag project_issues_path(@project), method: :get, id: "issue_search_form", class: 'inline issue-search-form' do + .append-right-10.hidden-xs.hidden-sm + = search_field_tag :issue_search, nil, { placeholder: 'Filter by title or description', class: 'form-control issue_search search-text-input input-mn-300' } - if can? current_user, :write_issue, @project - = link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-new pull-right", title: "New Issue", id: "new_issue_link" do + = link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-new", title: "New Issue", id: "new_issue_link" do %i.icon-plus New Issue - = form_tag project_issues_path(@project), method: :get, id: "issue_search_form", class: 'pull-right issue-search-form' do - = search_field_tag :issue_search, nil, { placeholder: 'Filter by title or description', class: 'input-xpadding issue_search input-xlarge append-right-10 search-text-input' } diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml index 57a05ee7303..1bd93b774f1 100644 --- a/app/views/projects/issues/_issue.html.haml +++ b/app/views/projects/issues/_issue.html.haml @@ -5,7 +5,8 @@ .issue-title %span.light= "##{issue.iid}" - = link_to_gfm truncate(issue.title, length: 100), project_issue_path(issue.project, issue), class: "row_title" + %span.str-truncated + = link_to_gfm issue.title, project_issue_path(issue.project, issue), class: "row_title" - if issue.closed? %small.pull-right = "CLOSED" @@ -26,7 +27,7 @@ %i.icon-time = issue.milestone.title .pull-right - %small updated #{time_ago_with_tooltip(issue.updated_at, 'bottom', 'issue_update_ago')} ago + %small updated #{time_ago_with_tooltip(issue.updated_at, 'bottom', 'issue_update_ago')} .issue-labels - issue.labels.each do |label| diff --git a/app/views/projects/issues/_issue_context.html.haml b/app/views/projects/issues/_issue_context.html.haml index 1e6c04d2b93..7ddf470b6a0 100644 --- a/app/views/projects/issues/_issue_context.html.haml +++ b/app/views/projects/issues/_issue_context.html.haml @@ -1,5 +1,4 @@ = form_for [@project, @issue], remote: true, html: {class: 'edit-issue inline-update'} do |f| - .pull-right Created by #{link_to_member(@project, issue.author)} - if issue.assignee \ and currently assigned to @@ -7,18 +6,18 @@ - if can?(current_user, :modify_issue, @issue) = link_to profile_path(issue.assignee) do = image_tag(avatar_icon(issue.assignee.email), class: 'avatar avatar-inline s16 assignee') if issue.assignee - = f.select(:assignee_id, assignee_options(@issue), { include_blank: "Assign to user (none):" }, {class: 'chosen'}) + = f.select(:assignee_id, assignee_options(@issue), { include_blank: "Assign to user (none):" }, {class: 'select2'}) - elsif issue.assignee = link_to_member(@project, @issue.assignee) - .pull-right + .pull-right.hidden-sm - if issue.milestone - milestone = issue.milestone %cite.cgray Attached to milestone - if can?(current_user, :modify_issue, @issue) - = f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone (none):" }, {class: 'chosen chosen-compact'}) + = f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone (none):" }, {class: 'select2 select2-compact'}) = hidden_field_tag :issue_context = f.submit class: 'btn' diff --git a/app/views/projects/issues/_issues.html.haml b/app/views/projects/issues/_issues.html.haml index e2ce26feac3..87d30a4a163 100644 --- a/app/views/projects/issues/_issues.html.haml +++ b/app/views/projects/issues/_issues.html.haml @@ -78,28 +78,8 @@ %strong= milestone.title %small.light= milestone.expires_at - .dropdown.inline.prepend-left-10 - %a.dropdown-toggle.btn.btn-small{href: '#', "data-toggle" => "dropdown"} - %span.light sort: - - if @sort.present? - = @sort - - else - Newest - %b.caret - %ul.dropdown-menu - %li - = link_to project_filter_path(sort: 'newest') do - Newest - = link_to project_filter_path(sort: 'oldest') do - Oldest - = link_to project_filter_path(sort: 'recently_updated') do - Recently updated - = link_to project_filter_path(sort: 'last_updated') do - Last updated - = link_to project_filter_path(sort: 'milestone_due_soon') do - Milestone due soon - = link_to project_filter_path(sort: 'milestone_due_later') do - Milestone due later + .pull-right + = render 'shared/sort_dropdown' %ul.well-list.issues-list diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml index 3694798a749..71a89af61a2 100644 --- a/app/views/projects/issues/index.html.haml +++ b/app/views/projects/issues/index.html.haml @@ -1,6 +1,6 @@ = render "head" .row - .span3 + .col-md-3 = render 'shared/project_filter', project_entities_path: project_issues_path(@project) - .span9.issues-holder + .col-md-9.issues-holder = render "issues" diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index b21874c8d56..cd4a158e427 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -2,7 +2,7 @@ Issue ##{@issue.iid} %small - created #{time_ago_with_tooltip(@issue.created_at)} ago + created #{time_ago_with_tooltip(@issue.created_at)} - if @issue.closed? %span.state-label.state-label-red Closed @@ -24,8 +24,8 @@ %i.icon-edit Edit -.pull-right - .span3#votes= render 'votes/votes_block', votable: @issue +.votes-holder + #votes= render 'votes/votes_block', votable: @issue .back-link = link_to project_issues_path(@project) do @@ -33,8 +33,8 @@ %span.milestone-nav-link - if @issue.milestone | + %span.light Milestone = link_to project_milestone_path(@project, @issue.milestone) do - %span.light Milestone = @issue.milestone.title .issue-box diff --git a/app/views/projects/issues/update.js.haml b/app/views/projects/issues/update.js.haml index 2be1d0f0db0..59524e0f224 100644 --- a/app/views/projects/issues/update.js.haml +++ b/app/views/projects/issues/update.js.haml @@ -5,9 +5,9 @@ - elsif params[:issue_context] $('.issue-box .context').html("#{escape_javascript(render partial: 'issue_context', locals: { issue: @issue })}"); $('.issue-box .context').effect('highlight'); - $('.chosen').chosen(); + $('.select2').select2(); $('.edit-issue.inline-update input[type="submit"]').hide(); - if @issue.milestone - $('.milestone-nav-link').replaceWith("#{escape_javascript(link_to "| #{@issue.milestone.title}", project_milestone_path(@issue.project, @issue.milestone), :class => 'milestone-nav-link')}") + $('.milestone-nav-link').replaceWith("<span class='milestone-nav-link'>| <span class='light'>Milestone</span> #{escape_javascript(link_to @issue.milestone.title, project_milestone_path(@issue.project, @issue.milestone))}</span>") - else $('.milestone-nav-link').html('') diff --git a/app/views/projects/merge_requests/_form.html.haml b/app/views/projects/merge_requests/_form.html.haml index 3b94bbd690b..63ebaadaa80 100644 --- a/app/views/projects/merge_requests/_form.html.haml +++ b/app/views/projects/merge_requests/_form.html.haml @@ -1,55 +1,61 @@ -= form_for [@project, @merge_request], html: { class: "#{controller.action_name}-merge-request form-horizontal" } do |f| += form_for [@project, @merge_request], html: { class: "merge-request-form form-horizontal" } do |f| -if @merge_request.errors.any? - .alert.alert-error + .alert.alert-danger %ul - @merge_request.errors.full_messages.each do |msg| %li= msg .merge-request-branches .row - .span5 + .col-md-5 .clearfix .pull-left - = f.select(:source_project_id, [[@merge_request.source_project_path,@merge_request.source_project.id]] , {}, { class: 'source_project chosen span3', disabled: @merge_request.persisted? }) + = f.select(:source_project_id, [[@merge_request.source_project_path,@merge_request.source_project.id]] , {}, { class: 'source_project select2 span3', disabled: @merge_request.persisted? }) .pull-left - = f.select(:source_branch, @merge_request.source_project.repository.branch_names, { include_blank: "Select branch" }, {class: 'source_branch chosen span2'}) + = f.select(:source_branch, @merge_request.source_project.repository.branch_names, { include_blank: "Select branch" }, {class: 'source_branch select2 span2'}) .mr_source_commit.prepend-top-10 - .span2 - %h2.merge-request-angle.light + .col-md-2 + .merge-request-angle %i.icon-long-arrow-right - .span5 + .col-md-5 .clearfix .pull-left - projects = @project.forked_from_project.nil? ? [@project] : [ @project,@project.forked_from_project] - = f.select(:target_project_id, options_from_collection_for_select(projects, 'id', 'path_with_namespace'), {}, { class: 'target_project chosen span3', disabled: @merge_request.persisted? }) + = f.select(:target_project_id, options_from_collection_for_select(projects, 'id', 'path_with_namespace'), {}, { class: 'target_project select2 span3', disabled: @merge_request.persisted? }) .pull-left - = f.select(:target_branch, @target_branches, { include_blank: "Select branch" }, {class: 'target_branch chosen span2'}) + = f.select(:target_branch, @target_branches, { include_blank: "Select branch" }, {class: 'target_branch select2 span2'}) .mr_target_commit.prepend-top-10 %hr .merge-request-form-info - .control-group - = f.label :title do + .form-group + = f.label :title, class: 'control-label' do %strong= "Title *" - .controls= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5, required: true - .control-group - .left - = f.label :assignee_id do + .col-sm-10= f.text_field :title, class: "form-control pad js-gfm-input", maxlength: 255, rows: 5, required: true + .form-group + = f.label :description, "Description", class: 'control-label' + .col-sm-10 + = f.text_area :description, class: "form-control js-gfm-input", rows: 14 + %p.hint Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + + %hr + .form-group + .merge-request-assignee + = f.label :assignee_id, class: 'control-label' do %i.icon-user Assign to - .controls= f.select(:assignee_id, assignee_options(@merge_request), { include_blank: "Select user" }, {class: 'chosen span3'}) - .left - = f.label :milestone_id do + .col-sm-10 + = f.select(:assignee_id, assignee_options(@merge_request), { include_blank: "Select a user" }, {class: 'select2'}) + + = link_to 'Assign to me', '#', class: 'btn btn-small assign-to-me-link' + .form-group + .merge-request-milestone + = f.label :milestone_id, class: 'control-label' do %i.icon-time Milestone - .controls= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'chosen'}) - .control-group - = f.label :description, "Description" - .controls - = f.text_area :description, class: "input-xxlarge js-gfm-input", rows: 14 - %p.hint Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + .col-sm-10= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2'}) .form-actions @@ -83,3 +89,7 @@ target_branch.on("change", function() { $.get("#{branch_to_project_merge_requests_path(@source_project)}", {target_project_id: target_project.val(),ref: $(this).val() }); }); + $('.assign-to-me-link').on('click', function(e){ + $('#merge_request_assignee_id').val("#{current_user.id}").trigger("change"); + e.preventDefault(); + }); diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml index 648d0ed07f5..ff763bca307 100644 --- a/app/views/projects/merge_requests/_merge_request.html.haml +++ b/app/views/projects/merge_requests/_merge_request.html.haml @@ -34,4 +34,4 @@ .pull-right - %small updated #{time_ago_with_tooltip(merge_request.updated_at, 'bottom', 'merge_request_updated_ago')} ago + %small updated #{time_ago_with_tooltip(merge_request.updated_at, 'bottom', 'merge_request_updated_ago')} diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index 0b9e4df3fd3..42641765c5c 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -12,7 +12,7 @@ = render "projects/merge_requests/show/commits" - if @commits.present? - %ul.nav.nav-tabs + %ul.nav.nav-tabs.append-bottom-10 %li.notes-tab{data: {action: 'notes'}} = link_to project_merge_request_path(@project, @merge_request) do %i.icon-comment diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml index e256ee2153c..a525a49015f 100644 --- a/app/views/projects/merge_requests/index.html.haml +++ b/app/views/projects/merge_requests/index.html.haml @@ -5,12 +5,11 @@ %h3.page-title Merge Requests %span (#{@merge_requests.total_count}) - - +%hr .row - .span3 + .col-md-3 = render 'shared/project_filter', project_entities_path: project_merge_requests_path(@project) - .span9 + .col-md-9 .ui-box .title .mr-filters @@ -61,6 +60,9 @@ %strong= milestone.title %small.light= milestone.expires_at + .pull-right + = render 'shared/sort_dropdown' + %ul.well-list.mr-list = render @merge_requests - if @merge_requests.blank? diff --git a/app/views/projects/merge_requests/invalid.html.haml b/app/views/projects/merge_requests/invalid.html.haml index 16e9fee42a2..b9c466657de 100644 --- a/app/views/projects/merge_requests/invalid.html.haml +++ b/app/views/projects/merge_requests/invalid.html.haml @@ -2,7 +2,7 @@ = render "projects/merge_requests/show/mr_title" = render "projects/merge_requests/show/mr_box" - .alert.alert-error + .alert.alert-danger %p We cannot render this merge request properly because - if @merge_request.for_fork? && !@merge_request.source_project diff --git a/app/views/projects/merge_requests/show/_how_to_merge.html.haml b/app/views/projects/merge_requests/show/_how_to_merge.html.haml index 98d373e8ad4..9540453ce3e 100644 --- a/app/views/projects/merge_requests/show/_how_to_merge.html.haml +++ b/app/views/projects/merge_requests/show/_how_to_merge.html.haml @@ -1,42 +1,44 @@ %div#modal_merge_info.modal.hide - .modal-header - %a.close{href: "#", "data-dismiss" => "modal"} × - %h3 How to merge - .modal-body - - if @merge_request.for_fork? - - source_remote = @merge_request.source_project.namespace.nil? ? "source" :@merge_request.source_project.namespace.path - - target_remote = @merge_request.target_project.namespace.nil? ? "target" :@merge_request.target_project.namespace.path - %p - %strong Step 1. - Checkout target branch and get recent objects from GitLab - Assuming remote for #{@merge_request.target_project.path_with_namespace} is called #{target_remote} - remote for #{@merge_request.source_project_path} is called #{source_remote} - %pre.dark - :preserve - git checkout #{target_remote} #{@merge_request.target_branch} - git fetch #{source_remote} - %p - %strong Step 2. - Merge source branch into target branch and push changes to GitLab - %pre.dark - :preserve - git merge #{source_remote}/#{@merge_request.source_branch} - git push #{target_remote} #{@merge_request.target_branch} - - else - %p - %strong Step 1. - Checkout target branch and get recent objects from GitLab - %pre.dark - :preserve - git checkout #{@merge_request.target_branch} - git fetch origin - %p - %strong Step 2. - Merge source branch into target branch and push changes to GitLab - %pre.dark - :preserve - git merge origin/#{@merge_request.source_branch} - git push origin #{@merge_request.target_branch} + .modal-dialog + .modal-content + .modal-header + %a.close{href: "#", "data-dismiss" => "modal"} × + %h3 How to merge + .modal-body + - if @merge_request.for_fork? + - source_remote = @merge_request.source_project.namespace.nil? ? "source" :@merge_request.source_project.namespace.path + - target_remote = @merge_request.target_project.namespace.nil? ? "target" :@merge_request.target_project.namespace.path + %p + %strong Step 1. + Checkout the branch we are going to merge and pull in the code + %pre.dark + :preserve + git checkout -b #{@merge_request.source_project_path}-#{@merge_request.source_branch} #{@merge_request.target_branch} + git pull #{@merge_request.source_project.http_url_to_repo} #{@merge_request.source_branch} + %p + %strong Step 2. + Merge the branch and push the changes to GitLab + %pre.dark + :preserve + git checkout #{@merge_request.target_branch} + git merge --no-ff #{@merge_request.source_project_path}-#{@merge_request.source_branch} + git push origin #{@merge_request.target_branch} + - else + %p + %strong Step 1. + Update the repo and checkout the branch we are going to merge + %pre.dark + :preserve + git fetch origin + git checkout -b #{@merge_request.source_branch} origin/#{@merge_request.source_branch} + %p + %strong Step 2. + Merge the branch and push the changes to GitLab + %pre.dark + :preserve + git checkout #{@merge_request.target_branch} + git merge --no-ff #{@merge_request.source_branch} + git push origin #{@merge_request.target_branch} :javascript diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml index 299e1bc1e08..352d843f49f 100644 --- a/app/views/projects/merge_requests/show/_mr_accept.html.haml +++ b/app/views/projects/merge_requests/show/_mr_accept.html.haml @@ -1,53 +1,69 @@ - unless @allowed_to_merge - .alert + .bs-callout %strong You don't have permission to merge this MR - if @show_merge_controls - .automerge_widget.can_be_merged{style: "display:none"} - .alert.alert-success - %span - = 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", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" - for instructions - .accept_group + .automerge_widget.can_be_merged.hide + .bs-callout.bs-callout-success.clearfix + = form_for [:automerge, @project, @merge_request], remote: true, method: :get do |f| + %h4 + You can accept this request automatically. + %p + If you still want to do it manually - + %strong + = link_to "click here", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" + for instructions. + + %br + If you want to modify merge commit message - + %strong + = link_to "click here", "#", class: "modify-merge-commit-link js-toggle-visibility-link", title: "Modify merge commit message" + + .js-toggle-visibility-container.hide + .form-group + = label_tag :merge_commit_message, "Commit message", class: 'control-label' + .col-sm-10 + = text_area_tag :merge_commit_message, @merge_request.merge_commit_message, class: "form-control js-gfm-input", rows: 14, required: true + %p.hint + The recommended maximum line length is 52 characters for the first line and 72 characters for all following lines. + + .accept-group + .pull-left = f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request" - - unless @merge_request.disallow_source_branch_removal? - .remove_branch_holder - = label_tag :should_remove_source_branch, class: "checkbox" do - = check_box_tag :should_remove_source_branch - Remove source-branch - .clearfix + - unless @merge_request.disallow_source_branch_removal? + .remove_branch_holder.pull-left + = label_tag :should_remove_source_branch, class: "checkbox" do + = check_box_tag :should_remove_source_branch + Remove source-branch - .automerge_widget.no_satellite{style: "display:none"} - .alert.alert-error + .automerge_widget.no_satellite.hide + .bs-callout.bs-callout-danger %span %strong This repository does not have satellite. Ask an administrator to fix this issue - .automerge_widget.cannot_be_merged{style: "display:none"} - .alert.alert-disabled + .automerge_widget.cannot_be_merged.hide + .bs-callout.bs-callout-disabled + %h4 + This request can't be merged with GitLab. %span - = link_to "Show how to merge", "#modal_merge_info", class: "how_to_merge_link btn padded", title: "How To Merge", "data-toggle" => "modal" - - %strong This request can't be merged with GitLab. You should do it manually + You should do it manually with + %strong + = link_to "command line", "#modal_merge_info", class: "how_to_merge_link", title: "How To Merge", "data-toggle" => "modal" .automerge_widget.unchecked - .alert + .bs-callout.bs-callout-warning %strong - %i.icon-refresh + %i.icon-refresh.icon-spin Checking for ability to automatically merge… - .automerge_widget.already_cannot_be_merged{style: "display:none"} - .alert.alert-info + .automerge_widget.already_cannot_be_merged.hide + .bs-callout.bs-callout-info %strong This merge request already can not be merged. Try to reload page. .merge-in-progress.hide - %span.cgray + .bs-callout.bs-callout-success %i.icon-refresh.icon-spin Merge is in progress. Please wait. Page will be automatically reloaded. diff --git a/app/views/projects/merge_requests/show/_mr_box.html.haml b/app/views/projects/merge_requests/show/_mr_box.html.haml index 83ac2a58d80..b4f648ab197 100644 --- a/app/views/projects/merge_requests/show/_mr_box.html.haml +++ b/app/views/projects/merge_requests/show/_mr_box.html.haml @@ -21,17 +21,17 @@ = markdown @merge_request.description - if @merge_request.closed? - .description.alert-error + .description.alert-danger %span %i.icon-remove Closed by #{link_to_member(@project, @merge_request.closed_event.author)} - #{time_ago_with_tooltip(@merge_request.closed_event.created_at)} ago. + #{time_ago_with_tooltip(@merge_request.closed_event.created_at)}. - if @merge_request.merged? .description.alert-success %span %i.icon-ok Merged by #{link_to_member(@project, @merge_request.merge_event.author)} - #{time_ago_with_tooltip(@merge_request.merge_event.created_at)} ago. + #{time_ago_with_tooltip(@merge_request.merge_event.created_at)}. - if !@closes_issues.empty? && @merge_request.opened? .description.alert-info %span diff --git a/app/views/projects/merge_requests/show/_mr_ci.html.haml b/app/views/projects/merge_requests/show/_mr_ci.html.haml index 9b15c4526e9..2e923ec5f35 100644 --- a/app/views/projects/merge_requests/show/_mr_ci.html.haml +++ b/app/views/projects/merge_requests/show/_mr_ci.html.haml @@ -8,7 +8,7 @@ .ci_widget.ci-failed{style: "display:none"} - .alert.alert-error + .alert.alert-danger %i.icon-remove %strong CI build failed for #{@merge_request.last_commit_short_sha}. @@ -16,20 +16,20 @@ - [:running, :pending].each do |status| .ci_widget{class: "ci-#{status}", style: "display:none"} - .alert + .alert.alert-warning %i.icon-time %strong CI build #{status} for #{@merge_request.last_commit_short_sha}. = link_to "Build page", ci_build_details_path(@merge_request) .ci_widget - .alert + .alert.alert-warning %strong %i.icon-refresh Checking for CI status for #{@merge_request.last_commit_short_sha} .ci_widget.ci-error{style: "display:none"} - .alert.alert-error + .alert.alert-danger %i.icon-remove %strong Cannot connect to CI server. Please check your setting diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml index b649a189c93..08a3fdf869a 100644 --- a/app/views/projects/merge_requests/show/_mr_title.html.haml +++ b/app/views/projects/merge_requests/show/_mr_title.html.haml @@ -1,7 +1,7 @@ %h3.page-title = "Merge Request ##{@merge_request.iid}" %small - created #{time_ago_with_tooltip(@merge_request.created_at)} ago + created #{time_ago_with_tooltip(@merge_request.created_at)} - if @merge_request.merged? %span.state-label.state-label-green @@ -34,8 +34,8 @@ %i.icon-edit Edit -.pull-right - .span3#votes= render 'votes/votes_block', votable: @merge_request +.votes-holder + #votes= render 'votes/votes_block', votable: @merge_request .back-link = link_to project_merge_requests_path(@project) do diff --git a/app/views/projects/merge_requests/show/_no_accept.html.haml b/app/views/projects/merge_requests/show/_no_accept.html.haml index a0507b24ad8..203e2612de4 100644 --- a/app/views/projects/merge_requests/show/_no_accept.html.haml +++ b/app/views/projects/merge_requests/show/_no_accept.html.haml @@ -1,4 +1,4 @@ -.alert.alert-error +.alert.alert-danger %p This merge request can not be accepted because branch - unless @merge_request.source_branch_exists? diff --git a/app/views/projects/merge_requests/update_branches.js.haml b/app/views/projects/merge_requests/update_branches.js.haml index dfccb586ec7..ca21b3bc0de 100644 --- a/app/views/projects/merge_requests/update_branches.js.haml +++ b/app/views/projects/merge_requests/update_branches.js.haml @@ -1,5 +1,9 @@ :plain $(".target_branch").html("#{escape_javascript(options_for_select(@target_branches))}"); - $(".target_branch").trigger("chosen:updated"); + + $('select.target_branch').select2({ + width: 'resolve', + dropdownAutoWidth: true + }); + $(".mr_target_commit").html(""); - $(".target_branch").trigger("change"); diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml index b2fd1a9284d..d770bb5b371 100644 --- a/app/views/projects/milestones/_form.html.haml +++ b/app/views/projects/milestones/_form.html.haml @@ -7,27 +7,27 @@ = form_for [@project, @milestone], html: {class: "new_milestone form-horizontal"} do |f| -if @milestone.errors.any? - .alert.alert-error + .alert.alert-danger %ul - @milestone.errors.full_messages.each do |msg| %li= msg .row - .span6 - .control-group + .col-md-6 + .form-group = f.label :title, "Title", class: "control-label" - .controls - = f.text_field :title, maxlength: 255, class: "input-xlarge" + .col-sm-10 + = f.text_field :title, maxlength: 255, class: "form-control" %p.hint Required - .control-group + .form-group = f.label :description, "Description", class: "control-label" - .controls - = f.text_area :description, maxlength: 2000, class: "input-xlarge", rows: 10 + .col-sm-10 + = f.text_area :description, maxlength: 2000, class: "form-control", rows: 10 %p.hint Milestones are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. - .span6 - .control-group + .col-md-6 + .form-group = f.label :due_date, "Due Date", class: "control-label" - .controls= f.hidden_field :due_date - .controls + .col-sm-10= f.hidden_field :due_date + .col-sm-10 .datepicker .form-actions diff --git a/app/views/projects/milestones/_milestone.html.haml b/app/views/projects/milestones/_milestone.html.haml index bc3368b765c..4dec3838d97 100644 --- a/app/views/projects/milestones/_milestone.html.haml +++ b/app/views/projects/milestones/_milestone.html.haml @@ -24,4 +24,4 @@ %span.light #{milestone.percent_complete}% complete .progress.progress-info - .bar{style: "width: #{milestone.percent_complete}%;"} + .progress-bar{style: "width: #{milestone.percent_complete}%;"} diff --git a/app/views/projects/milestones/index.html.haml b/app/views/projects/milestones/index.html.haml index ddb46bcb5cb..6cfe4d28778 100644 --- a/app/views/projects/milestones/index.html.haml +++ b/app/views/projects/milestones/index.html.haml @@ -8,7 +8,7 @@ New Milestone .row - .span3 + .col-md-3.hidden-sm %ul.nav.nav-pills.nav-stacked %li{class: ("active" if (params[:f] == "active" || !params[:f]))} = link_to project_milestones_path(@project, f: "active") do @@ -19,7 +19,7 @@ %li{class: ("active" if params[:f] == "all")} = link_to project_milestones_path(@project, f: "all") do All - .span9 + .col-md-9 .ui-box %ul.well-list = render @milestones diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml index 74a32832388..e7c3785c056 100644 --- a/app/views/projects/milestones/show.html.haml +++ b/app/views/projects/milestones/show.html.haml @@ -40,7 +40,7 @@ #{@milestone.open_items_count} open %span.pull-right= @milestone.expires_at .progress.progress-info - .bar{style: "width: #{@milestone.percent_complete}%;"} + .progress-bar{style: "width: #{@milestone.percent_complete}%;"} - if @milestone.description.present? @@ -49,7 +49,7 @@ = markdown @milestone.description -%ul.nav.nav-tabs +%ul.nav.nav-tabs.append-bottom-10 %li.active = link_to '#tab-issues', 'data-toggle' => 'tab' do Issues @@ -72,22 +72,22 @@ .tab-content .tab-pane.active#tab-issues .row - .span4 + .col-md-4 = render('issues', title: 'Unstarted Issues (open and unassigned)', issues: @issues.opened.unassigned) - .span4 + .col-md-4 = render('issues', title: 'Ongoing Issues (open and assigned)', issues: @issues.opened.assigned) - .span4 + .col-md-4 = render('issues', title: 'Completed Issues (closed)', issues: @issues.closed) .tab-pane#tab-merge-requests .row - .span6 + .col-md-6 .ui-box .title Open %ul.well-list - @merge_requests.opened.each do |merge_request| = render 'merge_request', merge_request: merge_request - .span6 + .col-md-6 .ui-box .title Closed %ul.well-list diff --git a/app/views/projects/network/_head.html.haml b/app/views/projects/network/_head.html.haml index 2790ed6f594..d61ff789b65 100644 --- a/app/views/projects/network/_head.html.haml +++ b/app/views/projects/network/_head.html.haml @@ -1,23 +1,15 @@ -.clearfix - .pull-left +.row.append-bottom-20 + .col-md-2.append-bottom-10 = render partial: 'shared/ref_switcher', locals: {destination: 'graph'} - .pull-left - = form_tag project_network_path(@project, @id), method: :get do |f| - .control-group - = label_tag :filter_ref, "Begin with the selected commit", class: 'control-label light' - .controls - = check_box_tag :filter_ref, 1, @options[:filter_ref] - - @options.each do |key, value| - = hidden_field_tag(key, value, id: nil) unless key == "filter_ref" - - .search.pull-right - = form_tag project_network_path(@project, @id), method: :get do |f| - .control-group - = label_tag :search , "Looking for commit:", class: 'control-label light' - .controls - = text_field_tag :extended_sha1, @options[:extended_sha1], placeholder: "Input an extended SHA1 syntax", class: "search-input input-xlarge" - = button_tag type: 'submit', class: 'btn vtop' do - %i.icon-search - - @options.each do |key, value| - = hidden_field_tag(key, value, id: nil) unless key == "extended_sha1" + .col-md-10 + = form_tag project_network_path(@project, @id), method: :get, class: 'form-inline network-form' do |f| + = label_tag :extended_sha1 , "Looking for", class: 'light inline-label' + = text_field_tag :extended_sha1, @options[:extended_sha1], placeholder: "Input an extended SHA1 syntax", class: "search-input form-control input-mx-250" + = button_tag type: 'submit', class: 'btn btn-success' do + %i.icon-search + .inline.prepend-left-20 + .checkbox.light + = label_tag :filter_ref do + = check_box_tag :filter_ref, 1, @options[:filter_ref] + %span Begin with the selected commit diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index ee6c42b6ea8..f21cef6f2e3 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -3,50 +3,51 @@ = render 'projects/errors' .project-edit-content - = form_for @project, remote: true do |f| - .control-group.project-name-holder - = f.label :name do + = form_for @project, remote: true, html: { class: 'new_project form-horizontal' } do |f| + .form-group.project-name-holder + = f.label :name, class: 'control-label' do %strong Project name - .controls - = f.text_field :name, placeholder: "Example Project", class: "input-xlarge", tabindex: 1, autofocus: true - %span.help-inline + .col-sm-10 + = f.text_field :name, placeholder: "Example Project", class: "form-control", tabindex: 1, autofocus: true + .help-inline = link_to "#", class: 'js-toggle-visibility-link' do %span Customize repository name? - .control-group.js-toggle-visibility-container.hide - = f.label :path do + .form-group.js-toggle-visibility-container.hide + = f.label :path, class: 'control-label' do %span Repository name - .controls - .input-append - = f.text_field :path - %span.add-on .git + .col-sm-10 + .input-group + = f.text_field :path, class: 'form-control' + %span.input-group-addon .git - if current_user.can_select_namespace? - .control-group - = f.label :namespace_id do + .form-group + = f.label :namespace_id, class: 'control-label' do %span Namespace - .controls - = f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'chosen', tabindex: 2} + .col-sm-10 + = f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'select2', tabindex: 2} - .control-group - .controls + .form-group + .col-sm-2 + .col-sm-10 = link_to "#", class: 'appear-link' do %i.icon-upload-alt %span Import existing repository? - .control-group.appear-data.import-url-data - = f.label :import_url do + .form-group.appear-data.import-url-data + = f.label :import_url, class: 'control-label' do %span Import existing repo - .controls - = f.text_field :import_url, class: 'input-xlarge', placeholder: 'https://github.com/randx/six.git' + .col-sm-10 + = f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git' .light URL must be cloneable - .control-group - = f.label :description do + .form-group + = f.label :description, class: 'control-label' do Description %span.light (optional) - .controls - = f.text_area :description, placeholder: "Awesome project", class: "input-xlarge", rows: 3, maxlength: 250, tabindex: 3 + .col-sm-10 + = f.text_area :description, placeholder: "Awesome project", class: "form-control", rows: 3, maxlength: 250, tabindex: 3 = render "visibility_level", f: f, visibility_level: gitlab_config.default_projects_features.visibility_level, can_change_visibility_level: true .form-actions @@ -54,7 +55,7 @@ - if current_user.can_create_group? .pull-right - .controls.light + .light Need a group for several dependent projects? = link_to new_group_path, class: "btn btn-tiny" do Create a group diff --git a/app/views/projects/new_tree/show.html.haml b/app/views/projects/new_tree/show.html.haml index 327aac0d71a..9d7c7afbeac 100644 --- a/app/views/projects/new_tree/show.html.haml +++ b/app/views/projects/new_tree/show.html.haml @@ -2,23 +2,29 @@ %hr .file-editor = form_tag(project_new_tree_path(@project, @id), method: :put, class: "form-horizontal") do - .control-group.commit_message-group + .form-group.commit_message-group = label_tag 'file_name', class: "control-label" do File name - .controls - %span.monospace= @path[-1] == "/" ? @path : @path + "/" - - = text_field_tag 'file_name', params[:file_name], placeholder: "sample.rb", required: true - %span - - on - %span.label-branch= @ref + .col-sm-10 + .input-group + %span.input-group-addon + = @path[-1] == "/" ? @path : @path + "/" + = text_field_tag 'file_name', params[:file_name], placeholder: "sample.rb", required: true, class: 'form-control' + %span.input-group-addon + on + %span= @ref - .control-group.commit_message-group + .form-group.commit_message-group + = label_tag :encoding, class: "control-label" do + Encoding + .col-sm-10 + = select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'form-control' + + .form-group.commit_message-group = label_tag 'commit_message', class: "control-label" do Commit message - .controls - = text_area_tag 'commit_message', params[:commit_message], placeholder: "Added new file", required: true, rows: 3 + .col-sm-10 + = text_area_tag 'commit_message', params[:commit_message], placeholder: "Added new file", required: true, rows: 3, class: 'form-control' .file-holder .file-title diff --git a/app/views/projects/notes/_discussion.html.haml b/app/views/projects/notes/_discussion.html.haml index 527dd8b7fc4..ee65ae1e2f5 100644 --- a/app/views/projects/notes/_discussion.html.haml +++ b/app/views/projects/notes/_discussion.html.haml @@ -32,7 +32,7 @@ last updated by = link_to_member(@project, last_note.author, avatar: false) %span.discussion-last-update - #{time_ago_with_tooltip(last_note.updated_at, 'bottom', 'discussion_updated_ago')} ago + #{time_ago_with_tooltip(last_note.updated_at, 'bottom', 'discussion_updated_ago')} .discussion-body - if note.for_diff_line? - if note.active? diff --git a/app/views/projects/notes/_form.html.haml b/app/views/projects/notes/_form.html.haml index 33667d3f46d..bcaedc8bd7c 100644 --- a/app/views/projects/notes/_form.html.haml +++ b/app/views/projects/notes/_form.html.haml @@ -33,6 +33,6 @@ %span Choose File ... %span.file_name.js-attachment-filename File name... - = f.file_field :attachment, class: "js-note-attachment-input hide" + = f.file_field :attachment, class: "js-note-attachment-input hidden" .clearfix diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml index 1c3bd614bae..fd2a3f43674 100644 --- a/app/views/projects/notes/_note.html.haml +++ b/app/views/projects/notes/_note.html.haml @@ -37,7 +37,7 @@ = form_for note, url: project_note_path(@project, note), method: :put, remote: true, authenticity_token: true do |f| = f.text_area :note, class: 'note_text js-note-text js-gfm-input turn-on' - .form-actions + .form-actions.clearfix = f.submit 'Save changes', class: "btn btn-primary btn-save" .note-form-option @@ -46,7 +46,7 @@ %span Choose File ... %span.file_name.js-attachment-filename File name... - = f.file_field :attachment, class: "js-note-attachment-input hide" + = f.file_field :attachment, class: "js-note-attachment-input hidden" = link_to 'Cancel', "#", class: "btn btn-cancel note-edit-cancel" diff --git a/app/views/projects/protected_branches/index.html.haml b/app/views/projects/protected_branches/index.html.haml index 31ef281ab88..e0d058de79e 100644 --- a/app/views/projects/protected_branches/index.html.haml +++ b/app/views/projects/protected_branches/index.html.haml @@ -1,8 +1,8 @@ = render "projects/commits/head" .row - .span3 + .col-md-3 = render "projects/branches/filter" - .span9 + .col-md-9 .alert.alert-info %p Protected branches designed to prevent push for all except #{link_to "masters", help_permissions_path, class: "vlink"}. %p This ability allows: @@ -14,15 +14,15 @@ - if can? current_user, :admin_project, @project = form_for [@project, @protected_branch] do |f| -if @protected_branch.errors.any? - .alert.alert-error + .alert.alert-danger %ul - @protected_branch.errors.full_messages.each do |msg| %li= msg .entry.clearfix = f.label :name, "Branch" - .span3 - = f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , {include_blank: "Select branch"}, {class: "chosen span3"}) + .col-md-3 + = f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , {include_blank: "Select branch"}, {class: "select2 span3"}) = f.submit 'Protect', class: "btn-create btn" - unless @branches.empty? @@ -46,6 +46,6 @@ = commit.short_id %span.light = gfm escape_once(truncate(commit.title, length: 40)) - #{time_ago_with_tooltip(commit.committed_date)} ago + #{time_ago_with_tooltip(commit.committed_date)} - else (branch was removed from repository) diff --git a/app/views/projects/refs/logs_tree.js.haml b/app/views/projects/refs/logs_tree.js.haml index 2c8fc4dff29..e7343e0997f 100644 --- a/app/views/projects/refs/logs_tree.js.haml +++ b/app/views/projects/refs/logs_tree.js.haml @@ -5,5 +5,5 @@ :plain var row = $("table.table_#{@hex_path} tr.file_#{hexdigest(file_name)}"); - row.find("td.tree_time_ago").html('#{escape_javascript time_ago_with_tooltip(commit.committed_date)} ago'); + row.find("td.tree_time_ago").html('#{escape_javascript time_ago_with_tooltip(commit.committed_date)}'); row.find("td.tree_commit").html('#{escape_javascript render("projects/tree/tree_commit_column", commit: commit)}'); diff --git a/app/views/projects/repositories/_download_archive.html.haml b/app/views/projects/repositories/_download_archive.html.haml new file mode 100644 index 00000000000..b03feded0a7 --- /dev/null +++ b/app/views/projects/repositories/_download_archive.html.haml @@ -0,0 +1,37 @@ +- ref = ref || nil +- btn_class = btn_class || '' +- split_button = split_button || false +- if split_button == true + %span.btn-group{class: btn_class} + = link_to archive_project_repository_path(@project, ref: ref, format: 'zip'), class: 'btn' do + %i.icon-download-alt + %span Download zip + %a.btn.dropdown-toggle{ 'data-toggle' => 'dropdown' } + %span.caret + %span.sr-only + Select Archive Format + %ul.dropdown-menu{ role: 'menu' } + %li + = link_to archive_project_repository_path(@project, ref: ref, format: 'zip') do + %i.icon-download-alt + %span Download zip + %li + = link_to archive_project_repository_path(@project, ref: ref, format: 'tar.gz') do + %i.icon-download-alt + %span Download tar.gz + %li + = link_to archive_project_repository_path(@project, ref: ref, format: 'tar.bz2') do + %i.icon-download-alt + %span Download tar.bz2 + %li + = link_to archive_project_repository_path(@project, ref: ref, format: 'tar') do + %i.icon-download-alt + %span Download tar +- else + %span.btn-group{class: btn_class} + = link_to archive_project_repository_path(@project, ref: ref, format: 'zip'), class: 'btn' do + %i.icon-download-alt + %span zip + = link_to archive_project_repository_path(@project, ref: ref, format: 'tar.gz'), class: 'btn' do + %i.icon-download-alt + %span tar.gz
\ No newline at end of file diff --git a/app/views/projects/repositories/_feed.html.haml b/app/views/projects/repositories/_feed.html.haml index 6e537d2959b..c77ffff43fe 100644 --- a/app/views/projects/repositories/_feed.html.haml +++ b/app/views/projects/repositories/_feed.html.haml @@ -15,5 +15,4 @@ = gfm escape_once(truncate(commit.title, length: 40)) %td %span.pull-right.cgray - = time_ago_in_words(commit.committed_date) - ago + = time_ago_with_tooltip(commit.committed_date) diff --git a/app/views/projects/repositories/stats.html.haml b/app/views/projects/repositories/stats.html.haml index 679b4211cde..fd353978572 100644 --- a/app/views/projects/repositories/stats.html.haml +++ b/app/views/projects/repositories/stats.html.haml @@ -1,6 +1,6 @@ = render "projects/commits/head" .row - .span6 + .col-md-6 %div#activity-chart.chart %hr %p @@ -14,7 +14,7 @@ %span= @stats.authors_count - .span6 + .col-md-6 %h4 Top 50 Committers: %ol.styled - @stats.authors[0...50].each do |author| diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml index 34ba55fc4cd..a3b5296ed1e 100644 --- a/app/views/projects/services/_form.html.haml +++ b/app/views/projects/services/_form.html.haml @@ -10,17 +10,17 @@ %hr -= form_for(@service, as: :service, url: project_service_path(@project, @service.to_param), method: :put) do |f| += form_for(@service, as: :service, url: project_service_path(@project, @service.to_param), method: :put, html: { class: 'form-horizontal' }) do |f| - if @service.errors.any? - .alert.alert-error + .alert.alert-danger %ul - @service.errors.full_messages.each do |msg| %li= msg - .control-group + .form-group = f.label :active, "Active", class: "control-label" - .controls + .col-sm-10 = f.check_box :active - @service.fields.each do |field| @@ -28,13 +28,13 @@ - type = field[:type] - placeholder = field[:placeholder] - .control-group + .form-group = f.label name, class: "control-label" - .controls + .col-sm-10 - if type == 'text' - = f.text_field name, class: "input-xlarge", placeholder: placeholder + = f.text_field name, class: "form-control", placeholder: placeholder - elsif type == 'textarea' - = f.text_area name, rows: 5, class: "input-xxlarge", placeholder: placeholder + = f.text_area name, rows: 5, class: "form-control", placeholder: placeholder - elsif type == 'checkbox' = f.check_box name diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index d2ced59f2c6..59075abf984 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -1,12 +1,12 @@ = render "home_panel" .row - .span9 + .col-md-9 = render "events/event_last_push", event: @last_push = render 'shared/event_filter' .content_list .loading.hide - .span3.project-side + .col-md-3.project-side.hidden-sm .clearfix - if @project.archived? .alert @@ -34,11 +34,10 @@ Fork repository - if can? current_user, :download_code, @project - = link_to archive_project_repository_path(@project), class: "btn btn-block" do - %i.icon-download-alt - %span Download - = link_to project_compare_index_path(@project, from: @repository.root_ref, to: @ref || @repository.root_ref), class: 'btn btn-block' do - Compare code + = render 'projects/repositories/download_archive', btn_class: 'btn-block btn-group-justified', split_button: true + + = link_to project_compare_index_path(@project, from: @repository.root_ref, to: @ref || @repository.root_ref), class: 'btn btn-block' do + Compare code - if @repository.readme - readme = @repository.readme diff --git a/app/views/projects/snippets/_form.html.haml b/app/views/projects/snippets/_form.html.haml index 198ec2170c7..866346990d3 100644 --- a/app/views/projects/snippets/_form.html.haml +++ b/app/views/projects/snippets/_form.html.haml @@ -2,26 +2,23 @@ = @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}" %hr .snippet-form-holder - = form_for [@project, @snippet], as: :project_snippet, url: url do |f| + = form_for [@project, @snippet], as: :project_snippet, url: url, html: {class: "form-horizontal snippet-form"} do |f| -if @snippet.errors.any? - .alert.alert-error + .alert.alert-danger %ul - @snippet.errors.full_messages.each do |msg| %li= msg - .control-group - = f.label :title - .controls= f.text_field :title, placeholder: "Example Snippet", class: 'input-xlarge', required: true - .control-group - = f.label "Lifetime" - .controls= f.select :expires_at, lifetime_select_options, {}, {class: 'chosen span2'} - .control-group + .form-group + = f.label :title, class: 'control-label' + .col-sm-10= f.text_field :title, placeholder: "Example Snippet", class: 'form-control', required: true + .form-group .file-editor - = f.label :file_name, "File" - .controls + = f.label :file_name, "File", class: 'control-label' + .col-sm-10 .file-holder.snippet .file-title - = f.text_field :file_name, placeholder: "example.rb", class: 'snippet-file-name', required: true + = f.text_field :file_name, placeholder: "example.rb", class: 'form-control snippet-file-name', required: true .file-content.code %pre#editor= @snippet.content = f.hidden_field :content, class: 'snippet-file-content' @@ -31,10 +28,11 @@ = f.submit 'Create snippet', class: "btn-create btn" - else = f.submit 'Save', class: "btn-save btn" - = link_to "Cancel", project_snippets_path(@project), class: "btn btn-cancel" - - unless @snippet.new_record? - = link_to 'Remove snippet', project_snippet_path(@project, @snippet), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn pull-right btn-remove delete-snippet prepend-left-10", id: "destroy_snippet_#{@snippet.id}" + - unless @snippet.new_record? + .pull-right.prepend-left-20 + = link_to 'Remove snippet', project_snippet_path(@project, @snippet), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn pull-right btn-remove delete-snippet prepend-left-10", id: "destroy_snippet_#{@snippet.id}" + = link_to "Cancel", project_snippets_path(@project), class: "btn btn-cancel" :javascript var editor = ace.edit("editor"); diff --git a/app/views/projects/snippets/_snippet.html.haml b/app/views/projects/snippets/_snippet.html.haml index 79de35d0b1a..ddd9645ee51 100644 --- a/app/views/projects/snippets/_snippet.html.haml +++ b/app/views/projects/snippets/_snippet.html.haml @@ -19,4 +19,4 @@ = image_tag avatar_icon(snippet.author_email), class: "avatar avatar-inline s16" = snippet.author_name %span.light - #{time_ago_with_tooltip(snippet.created_at)} ago + #{time_ago_with_tooltip(snippet.created_at)} diff --git a/app/views/projects/tags/index.html.haml b/app/views/projects/tags/index.html.haml index 21d4c546850..c88e42a1073 100644 --- a/app/views/projects/tags/index.html.haml +++ b/app/views/projects/tags/index.html.haml @@ -24,7 +24,7 @@ .pull-right %small.cdark %i.icon-calendar - #{time_ago_with_tooltip(commit.committed_date)} ago + #{time_ago_with_tooltip(commit.committed_date)} %p.prepend-left-20 = link_to commit.short_id(8), project_commit_path(@project, commit), class: "monospace" – @@ -32,11 +32,9 @@ %span.pull-right - if can? current_user, :download_code, @project - = link_to archive_project_repository_path(@project, ref: tag.name), class: 'btn grouped btn-small' do - %i.icon-download-alt - Download + = render 'projects/repositories/download_archive', ref: tag.name, btn_class: 'grouped btn-group-small' - if can?(current_user, :admin_project, @project) - = link_to project_tag_path(@project, tag.name), class: 'btn btn-small remove-row', method: :delete, data: { confirm: 'Removed tag cannot be restored. Are you sure?'}, remote: true do + = link_to project_tag_path(@project, tag.name), class: 'btn btn-small remove-row grouped', method: :delete, data: { confirm: 'Removed tag cannot be restored. Are you sure?'}, remote: true do %i.icon-trash = paginate @tags, theme: 'gitlab' diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml index 67030785e06..a9fd97f8915 100644 --- a/app/views/projects/tags/new.html.haml +++ b/app/views/projects/tags/new.html.haml @@ -1,15 +1,15 @@ %h3.page-title %i.icon-code-fork New tag -= form_tag project_tags_path, method: :post do - .control-group += form_tag project_tags_path, method: :post, class: "form-horizontal" do + .form-group = label_tag :tag_name, 'Name for new tag', class: 'control-label' - .controls - = text_field_tag :tag_name, nil, placeholder: 'v3.0.1', required: true, tabindex: 1 - .control-group + .col-sm-10 + = text_field_tag :tag_name, nil, placeholder: 'v3.0.1', required: true, tabindex: 1, class: 'form-control' + .form-group = label_tag :ref, 'Create from', class: 'control-label' - .controls - = text_field_tag :ref, nil, placeholder: 'master', required: true, tabindex: 2 + .col-sm-10 + = text_field_tag :ref, nil, placeholder: 'master', required: true, tabindex: 2, class: 'form-control' .light Branch name or commit SHA .form-actions = submit_tag 'Create tag', class: 'btn btn-create', tabindex: 3 diff --git a/app/views/projects/team_members/_form.html.haml b/app/views/projects/team_members/_form.html.haml index 5214a54e909..dd059fb99d3 100644 --- a/app/views/projects/team_members/_form.html.haml +++ b/app/views/projects/team_members/_form.html.haml @@ -1,23 +1,23 @@ %h3.page-title = "New project member(s)" -= form_for @user_project_relation, as: :team_member, url: project_team_members_path(@project) do |f| += form_for @user_project_relation, as: :team_member, url: project_team_members_path(@project), html: { class: "form-horizontal users-project-form" } do |f| -if @user_project_relation.errors.any? - .alert.alert-error + .alert.alert-danger %ul - @user_project_relation.errors.full_messages.each do |msg| %li= msg %p 1. Choose people you want in the project - .control-group - = f.label :user_ids, "People" - .controls + .form-group + = f.label :user_ids, "People", class: 'control-label' + .col-sm-10 = users_select_tag(:user_ids, multiple: true) %p 2. Set access level for them - .control-group - = f.label :project_access, "Project Access" - .controls= select_tag :project_access, options_for_select(Gitlab::Access.options, @user_project_relation.project_access), class: "project-access-select chosen" + .form-group + = f.label :project_access, "Project Access", class: 'control-label' + .col-sm-10= select_tag :project_access, options_for_select(Gitlab::Access.options, @user_project_relation.project_access), class: "project-access-select select2" .form-actions = f.submit 'Add users', class: "btn btn-create" diff --git a/app/views/projects/team_members/import.html.haml b/app/views/projects/team_members/import.html.haml index 1d98b986210..d3e4a762018 100644 --- a/app/views/projects/team_members/import.html.haml +++ b/app/views/projects/team_members/import.html.haml @@ -3,10 +3,10 @@ %p.light Only project members will be imported. Group members will be skipped. %hr -= form_tag apply_import_project_team_members_path(@project), method: 'post' do - .padded - = label_tag :source_project_id, "Project" - .controls= select_tag(:source_project_id, options_from_collection_for_select(current_user.authorized_projects, :id, :name_with_namespace), prompt: "Select project", class: "chosen xxlarge", required: true) += form_tag apply_import_project_team_members_path(@project), method: 'post', class: 'form-horizontal' do + .form-group + = label_tag :source_project_id, "Project", class: 'control-label' + .col-sm-10= select_tag(:source_project_id, options_from_collection_for_select(current_user.authorized_projects, :id, :name_with_namespace), prompt: "Select project", class: "select2 lg", required: true) .form-actions = submit_tag 'Import project members', class: "btn btn-create" diff --git a/app/views/projects/tree/_blob_item.html.haml b/app/views/projects/tree/_blob_item.html.haml index b179ad7d245..92dfd7537ca 100644 --- a/app/views/projects/tree/_blob_item.html.haml +++ b/app/views/projects/tree/_blob_item.html.haml @@ -1,7 +1,8 @@ %tr{ class: "tree-item #{tree_hex_class(blob_item)}" } %td.tree-item-file-name = tree_icon(type) - %span= link_to truncate(blob_item.name, length: 40), project_blob_path(@project, tree_join(@id || @commit.id, blob_item.name)) + %span.str-truncated + = link_to blob_item.name, project_blob_path(@project, tree_join(@id || @commit.id, blob_item.name)) %td.tree_time_ago.cgray %span.log_loading.hide Loading commit data... diff --git a/app/views/projects/tree/_readme.html.haml b/app/views/projects/tree/_readme.html.haml index 1fccfbc1645..ab572f2e97b 100644 --- a/app/views/projects/tree/_readme.html.haml +++ b/app/views/projects/tree/_readme.html.haml @@ -9,5 +9,5 @@ - elsif plain_text_readme?(readme.name) %pre.clean = readme.data - - else - = raw GitHub::Markup.render(readme.name, readme.data) + - elsif markup?(readme.name) + = render_markup(readme.name, readme.data) diff --git a/app/views/projects/tree/_tree.html.haml b/app/views/projects/tree/_tree.html.haml index 6b5b84f83b0..4e80872df48 100644 --- a/app/views/projects/tree/_tree.html.haml +++ b/app/views/projects/tree/_tree.html.haml @@ -4,14 +4,12 @@ = link_to project_tree_path(@project, @ref) do = @project.path - tree_breadcrumbs(tree, 6) do |title, path| - \/ %li - if path = link_to truncate(title, length: 40), project_tree_path(@project, path) - else = link_to title, '#' - if @repository.branch_names.include?(@ref) - \/ %li = link_to project_new_tree_path(@project, @id), title: 'New file', id: 'new-file-link' do %small @@ -23,15 +21,16 @@ %tr %th Name %th Last Update - %th + %th.hidden-sm Last Commit - - %i.icon-angle-right - - %small.light - = link_to @commit.short_id, project_commit_path(@project, @commit) - – - = truncate(@commit.title, length: 50) + %span.last-commit + + %i.icon-angle-right + + %small.light + = link_to @commit.short_id, project_commit_path(@project, @commit) + – + = truncate(@commit.title, length: 50) %th= link_to "history", project_commits_path(@project, @id), class: "pull-right" - if @path.present? diff --git a/app/views/projects/tree/_tree_commit_column.html.haml b/app/views/projects/tree/_tree_commit_column.html.haml index 67b5b2b96e2..bd50dd4d9a2 100644 --- a/app/views/projects/tree/_tree_commit_column.html.haml +++ b/app/views/projects/tree/_tree_commit_column.html.haml @@ -1,2 +1,3 @@ -%span.tree_author= commit_author_link(commit, avatar: true, size: 16) -= link_to_gfm truncate(commit.title, length: 80), project_commit_path(@project, commit.id), class: "tree-commit-link" +%span.str-truncated + %span.tree_author= commit_author_link(commit, avatar: true, size: 16) + = link_to_gfm commit.title, project_commit_path(@project, commit.id), class: "tree-commit-link" diff --git a/app/views/projects/tree/_tree_item.html.haml b/app/views/projects/tree/_tree_item.html.haml index f8856afc866..b4dd6f48b62 100644 --- a/app/views/projects/tree/_tree_item.html.haml +++ b/app/views/projects/tree/_tree_item.html.haml @@ -1,7 +1,8 @@ %tr{ class: "tree-item #{tree_hex_class(tree_item)}" } %td.tree-item-file-name = tree_icon(type) - %span= link_to truncate(tree_item.name, length: 40), project_tree_path(@project, tree_join(@id || @commit.id, tree_item.name)) + %span.str-truncated + = link_to tree_item.name, project_tree_path(@project, tree_join(@id || @commit.id, tree_item.name)) %td.tree_time_ago.cgray %span.log_loading.hide Loading commit data... diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml index 0f7692aba7f..6b33493b7d2 100644 --- a/app/views/projects/tree/show.html.haml +++ b/app/views/projects/tree/show.html.haml @@ -1,4 +1,6 @@ %div.tree-ref-holder = render 'shared/ref_switcher', destination: 'tree', path: @path +- if can? current_user, :download_code, @project + = render 'projects/repositories/download_archive', ref: @ref, btn_class: 'btn-group-small tree-ref-holder pull-right', split_button: true %div#tree-holder.tree-holder = render "tree", tree: @tree diff --git a/app/views/projects/walls/show.html.haml b/app/views/projects/walls/show.html.haml index 4fe3e6bccf4..c6afec443f4 100644 --- a/app/views/projects/walls/show.html.haml +++ b/app/views/projects/walls/show.html.haml @@ -17,7 +17,7 @@ %span Choose File ... %span.file_name.js-attachment-filename File name... - = f.file_field :attachment, class: "js-note-attachment-input hide" + = f.file_field :attachment, class: "js-note-attachment-input hidden" .hint.pull-right CTRL + Enter to send message .clearfix diff --git a/app/views/projects/wikis/_form.html.haml b/app/views/projects/wikis/_form.html.haml index 0420e026c69..06d8660630d 100644 --- a/app/views/projects/wikis/_form.html.haml +++ b/app/views/projects/wikis/_form.html.haml @@ -1,4 +1,4 @@ -= form_for [@project, @wiki], method: @wiki.persisted? ? :put : :post do |f| += form_for [@project, @wiki], method: @wiki.persisted? ? :put : :post, html: { class: 'form-horizontal' } do |f| -if @wiki.errors.any? #error_explanation %h2= "#{pluralize(@wiki.errors.count, "error")} prohibited this wiki from being saved:" @@ -6,29 +6,30 @@ - @wiki.errors.full_messages.each do |msg| %li= msg - .issue-box - %h3.title - .edit-wiki-header - = @wiki.title.titleize - = f.hidden_field :title, value: @wiki.title - = f.select :format, options_for_select(GollumWiki::MARKUPS, {selected: @wiki.format}), {}, class: "pull-right input-medium" - = f.label :format, class: "pull-right", style: "padding-right: 20px;" - .context - .controls - %span.cgray - Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. - To link to a (new) page you can just type - %code [Link Title](page-slug) - \. + = f.hidden_field :title, value: @wiki.title + .form-group + = f.label :format, class: 'control-label' + .col-sm-10 + = f.select :format, options_for_select(GollumWiki::MARKUPS, {selected: @wiki.format}), {}, class: "form-control" + + .row + .col-sm-2 + .col-sm-10 + %p.cgray + Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. + To link to a (new) page you can just type + %code [Link Title](page-slug) + \. + + .form-group + = f.label :content, class: 'control-label' + .col-sm-10 + = f.text_area :content, class: 'form-control js-gfm-input', rows: 18 + + .form-group + = f.label :commit_message, class: 'control-label' + .col-sm-10= f.text_field :message, class: 'form-control', rows: 18 - .description - .control-group - = f.label :content - .controls= f.text_area :content, class: 'span8 js-gfm-input', rows: 18 - .description - .control-group - = f.label :commit_message - .controls= f.text_field :message, class: 'span8', rows: 18 .form-actions - if @wiki && @wiki.persisted? = f.submit 'Save changes', class: "btn-save btn" diff --git a/app/views/projects/wikis/_nav.html.haml b/app/views/projects/wikis/_nav.html.haml index 0a7e51e974c..5e5aa5170d6 100644 --- a/app/views/projects/wikis/_nav.html.haml +++ b/app/views/projects/wikis/_nav.html.haml @@ -1,4 +1,4 @@ -%ul.nav.nav-tabs +%ul.nav.nav-tabs.append-bottom-20 = nav_link(html_options: {class: params[:id] == 'home' ? 'active' : '' }) do = link_to 'Home', project_wiki_path(@project, :home) diff --git a/app/views/projects/wikis/_new.html.haml b/app/views/projects/wikis/_new.html.haml index f64772b2001..8cb7fa8aa0b 100644 --- a/app/views/projects/wikis/_new.html.haml +++ b/app/views/projects/wikis/_new.html.haml @@ -1,12 +1,14 @@ %div#modal-new-wiki.modal.hide - .modal-header - %a.close{href: "#", "data-dismiss" => "modal"} × - %h3.page-title New Wiki Page - .modal-body - = label_tag :new_wiki_path do - %span Page slug - = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'input-xlarge', required: true, :'data-wikis-path' => project_wikis_path(@project) - %p.hint - Please don't use spaces and slashes - .modal-footer - = link_to 'Build', '#', class: 'build-new-wiki btn btn-create' + .modal-dialog + .modal-content + .modal-header + %a.close{href: "#", "data-dismiss" => "modal"} × + %h3.page-title New Wiki Page + .modal-body + = label_tag :new_wiki_path do + %span Page slug + = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'form-control', required: true, :'data-wikis-path' => project_wikis_path(@project) + %p.hint + Please don't use spaces and slashes + .modal-footer + = link_to 'Build', '#', class: 'build-new-wiki btn btn-create' diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml index 1400f2ec787..47b236083b3 100644 --- a/app/views/projects/wikis/edit.html.haml +++ b/app/views/projects/wikis/edit.html.haml @@ -1,7 +1,10 @@ = render 'nav' -%h3.page-title - Editing page +.pull-right = render 'main_links' +%h3.page-title + Editing - + %span.light #{@wiki.title.titleize} +%hr = render 'form' .pull-right diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml index 692eda4e535..b62c4975416 100644 --- a/app/views/projects/wikis/git_access.html.haml +++ b/app/views/projects/wikis/git_access.html.haml @@ -1,13 +1,12 @@ = render 'nav' -%h3.page-title - Git access for - %strong= @gollum_wiki.path_with_namespace +.row + .col-sm-6 + %h3.page-title + Git access for + %strong= @gollum_wiki.path_with_namespace - .form-horizontal.pull-right - .git-clone-holder - %button{class: "btn active", :"data-clone" => @gollum_wiki.ssh_url_to_repo} SSH - %button{class: "btn", :"data-clone" => @gollum_wiki.http_url_to_repo}= gitlab_config.protocol.upcase - = text_field_tag :project_clone, @gollum_wiki.url_to_repo, class: "one_click_select input-xxlarge", readonly: true + .col-sm-6 + = render "shared/clone_panel", project: @gollum_wiki .git-empty %fieldset @@ -19,7 +18,7 @@ %legend Clone Your Wiki: %pre.dark :preserve - git clone #{@gollum_wiki.ssh_url_to_repo} + git clone #{ content_tag(:span, default_url_to_repo(@gollum_wiki), class: 'clone')} cd #{@gollum_wiki.path} %legend Start Gollum And Edit Locally: diff --git a/app/views/projects/wikis/history.html.haml b/app/views/projects/wikis/history.html.haml index c9c61329ace..55efb624e23 100644 --- a/app/views/projects/wikis/history.html.haml +++ b/app/views/projects/wikis/history.html.haml @@ -23,7 +23,7 @@ %td = commit.title %td - #{time_ago_with_tooltip(version.date)} ago + #{time_ago_with_tooltip(version.date)} %td %strong = @wiki.page.wiki.page(@wiki.page.name, commit.id).try(:format) diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml index 4df406c4210..7a890816568 100644 --- a/app/views/projects/wikis/pages.html.haml +++ b/app/views/projects/wikis/pages.html.haml @@ -8,4 +8,4 @@ = link_to wiki_page.title.titleize, project_wiki_path(@project, wiki_page) %small (#{wiki_page.format}) .pull-right - %small Last edited #{time_ago_with_tooltip(wiki_page.commit.created_at)} ago + %small Last edited #{time_ago_with_tooltip(wiki_page.commit.created_at)} diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml index 3d00940414b..f7d4fe42b57 100644 --- a/app/views/projects/wikis/show.html.haml +++ b/app/views/projects/wikis/show.html.haml @@ -17,4 +17,4 @@ %hr .wiki-last-edit-by - Last edited by #{commit_author_link(@wiki.commit, avatar: true, size: 16)} #{time_ago_with_tooltip(@wiki.commit.created_at)} ago + Last edited by #{commit_author_link(@wiki.commit, avatar: true, size: 16)} #{time_ago_with_tooltip(@wiki.commit.created_at)} diff --git a/app/views/public/projects/index.html.haml b/app/views/public/projects/index.html.haml index 002ffa916b5..2fc93c5b742 100644 --- a/app/views/public/projects/index.html.haml +++ b/app/views/public/projects/index.html.haml @@ -6,8 +6,9 @@ .clearfix .pull-left = form_tag public_projects_path, method: :get, class: 'form-inline form-tiny' do |f| - .search-holder - = search_field_tag :search, params[:search], placeholder: "Filter by name", class: "span4 search-text-input", id: "projects_search" + .form-group + = search_field_tag :search, params[:search], placeholder: "Filter by name", class: "form-control search-text-input input-mn-300", id: "projects_search" + .form-group = submit_tag 'Search', class: "btn btn-primary wide" .pull-right diff --git a/app/views/search/_filter.html.haml b/app/views/search/_filter.html.haml index f7a00b23480..979b18e3856 100644 --- a/app/views/search/_filter.html.haml +++ b/app/views/search/_filter.html.haml @@ -9,7 +9,7 @@ %b.caret %ul.dropdown-menu %li - = link_to search_path(group_id: nil) do + = link_to search_path(group_id: nil, search: params[:search]) do Any - current_user.authorized_groups.sort_by(&:name).each do |group| %li @@ -27,7 +27,7 @@ %b.caret %ul.dropdown-menu %li - = link_to search_path(project_id: nil) do + = link_to search_path(project_id: nil, search: params[:search]) do Any - current_user.authorized_projects.sort_by(&:name_with_namespace).each do |project| %li diff --git a/app/views/search/_global_results.html.haml b/app/views/search/_global_results.html.haml index 6e6feeb6c5a..7f4f0e5e000 100644 --- a/app/views/search/_global_results.html.haml +++ b/app/views/search/_global_results.html.haml @@ -1,5 +1,5 @@ .search_results %ul.bordered-list - = render partial: "search/results/project", collection: @projects - = render partial: "search/results/merge_request", collection: @merge_requests - = render partial: "search/results/issue", collection: @issues + = render partial: "search/results/project", collection: @search_results[:projects] + = render partial: "search/results/merge_request", collection: @search_results[:merge_requests] + = render partial: "search/results/issue", collection: @search_results[:issues] diff --git a/app/views/search/_project_results.html.haml b/app/views/search/_project_results.html.haml index 8d04dd27cca..ea324b3a9aa 100644 --- a/app/views/search/_project_results.html.haml +++ b/app/views/search/_project_results.html.haml @@ -1,17 +1,17 @@ -%ul.nav.nav-pills +%ul.nav.nav-tabs.append-bottom-10 %li{class: ("active" if params[:search_code].present?)} = link_to search_path(params.merge(search_code: true)) do Repository Code %li{class: ("active" if params[:search_code].blank?)} = link_to search_path(params.merge(search_code: nil)) do - Everything else + Issues and Merge requests .search_results - if params[:search_code].present? .blob-results - = render partial: "search/results/blob", collection: @blobs - = paginate @blobs, theme: 'gitlab' + = render partial: "search/results/blob", collection: @search_results[:blobs] + = paginate @search_results[:blobs], theme: 'gitlab' - else %ul.bordered-list - = render partial: "search/results/merge_request", collection: @merge_requests - = render partial: "search/results/issue", collection: @issues + = render partial: "search/results/merge_request", collection: @search_results[:merge_requests] + = render partial: "search/results/issue", collection: @search_results[:issues] diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml index 75f134aae66..2336d0f71d5 100644 --- a/app/views/search/_results.html.haml +++ b/app/views/search/_results.html.haml @@ -1,7 +1,11 @@ -%fieldset - %legend - Search results - %span.cgray (#{@total_results}) +%h4 + #{@search_results[:total_results]} results found + - if @project + for #{link_to @project.name_with_namespace, @project} + - elsif @group + for #{link_to @group.name, @group} + +%hr - if @project = render "project_results" diff --git a/app/views/search/show.html.haml b/app/views/search/show.html.haml index 25e8c00888a..3b6f10d4d9c 100644 --- a/app/views/search/show.html.haml +++ b/app/views/search/show.html.haml @@ -1,15 +1,19 @@ -= form_tag search_path, method: :get, class: 'form-inline' do |f| - .search-holder - = label_tag :search do - %span Looking for - .controls - = search_field_tag :search, params[:search], placeholder: "issue 143", class: "input-xxlarge search-text-input", id: "dashboard_search" += form_tag search_path, method: :get, class: 'form-horizontal' do |f| + .search-holder.clearfix + .form-group + = label_tag :search, class: 'control-label' do + %span Looking for + .col-sm-6 + = search_field_tag :search, params[:search], placeholder: "issue 143", class: "form-control search-text-input", id: "dashboard_search" + .col-sm-4 + = submit_tag 'Search', class: "btn btn-create" + .form-group + .col-sm-2 + .col-sm-10 + = render 'filter', f: f = hidden_field_tag :project_id, params[:project_id] = hidden_field_tag :group_id, params[:group_id] = hidden_field_tag :search_code, params[:search_code] - = submit_tag 'Search', class: "btn btn-create" - .prepend-top-10 - = render 'filter', f: f .results.prepend-top-10 - if params[:search].present? diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml index 48d6c97ee43..8cd426c71e6 100644 --- a/app/views/shared/_clone_panel.html.haml +++ b/app/views/shared/_clone_panel.html.haml @@ -1,4 +1,6 @@ -.git-clone-holder - %button{class: "btn #{ 'active' if default_clone_protocol == 'ssh' }", :"data-clone" => @project.ssh_url_to_repo} SSH - %button{class: "btn #{ 'active' if default_clone_protocol == 'http' }", :"data-clone" => @project.http_url_to_repo}= gitlab_config.protocol.upcase - = text_field_tag :project_clone, default_url_to_repo, class: "one_click_select span4", readonly: true +- project = project || @project +.git-clone-holder.input-group + .input-group-btn + %button{class: "btn #{ 'active' if default_clone_protocol == 'ssh' }", :"data-clone" => project.ssh_url_to_repo} SSH + %button{class: "btn #{ 'active' if default_clone_protocol == 'http' }", :"data-clone" => project.http_url_to_repo}= gitlab_config.protocol.upcase + = text_field_tag :project_clone, default_url_to_repo(project), class: "one_click_select form-control", readonly: true diff --git a/app/views/shared/_filter.html.haml b/app/views/shared/_filter.html.haml index 13bda305d77..6063b4a0732 100644 --- a/app/views/shared/_filter.html.haml +++ b/app/views/shared/_filter.html.haml @@ -1,41 +1,43 @@ -= form_tag filter_path(entity), method: 'get' do - %fieldset.scope-filter - %ul.nav.nav-pills.nav-stacked - %li{class: ("active" if params[:scope].blank?)} - = link_to filter_path(entity, scope: nil) do - Assigned to me - %li{class: ("active" if params[:scope] == 'authored')} - = link_to filter_path(entity, scope: 'authored') do - Created by me - %li{class: ("active" if params[:scope] == 'all')} - = link_to filter_path(entity, scope: 'all') do - All +.side-filters.hidden-xs.hidden-sm + = form_tag filter_path(entity), method: 'get' do + %fieldset.scope-filter + %ul.nav.nav-pills.nav-stacked + %li{class: ("active" if params[:scope] == 'assigned-to-me')} + = link_to filter_path(entity, scope: 'assigned-to-me') do + Assigned to me + %li{class: ("active" if params[:scope] == 'authored')} + = link_to filter_path(entity, scope: 'authored') do + Created by me + %li{class: ("active" if params[:scope] == 'all')} + = link_to filter_path(entity, scope: 'all') do + Everyone's - %fieldset.status-filter - %ul.nav.nav-pills.nav-stacked - %li{class: ("active" if params[:status].blank?)} - = link_to filter_path(entity, status: nil) do - Open - %li{class: ("active" if params[:status] == 'closed')} - = link_to filter_path(entity, status: 'closed') do - Closed - %li{class: ("active" if params[:status] == 'all')} - = link_to filter_path(entity, status: 'all') do - All + %fieldset.status-filter + %legend State + %ul.nav.nav-pills + %li{class: ("active" if params[:state] == 'opened')} + = link_to filter_path(entity, state: 'opened') do + Open + %li{class: ("active" if params[:state] == 'closed')} + = link_to filter_path(entity, state: 'closed') do + Closed + %li{class: ("active" if params[:state] == 'all')} + = link_to filter_path(entity, state: 'all') do + All - %fieldset - %legend Projects - %ul.nav.nav-pills.nav-pills-small.nav-stacked - - @projects.each do |project| - - unless entities_per_project(project, entity).zero? - %li{class: ("active" if params[:project_id] == project.id.to_s)} - = link_to filter_path(entity, project_id: project.id) do - = project.name_with_namespace - %small.pull-right= entities_per_project(project, entity) + %fieldset + %legend Projects + %ul.nav.nav-pills.nav-stacked.nav-small + - @projects.each do |project| + - unless entities_per_project(project, entity).zero? + %li{class: ("active" if params[:project_id] == project.id.to_s)} + = link_to filter_path(entity, project_id: project.id) do + = project.name_with_namespace + %small.pull-right= entities_per_project(project, entity) - %fieldset - - if params[:status].present? || params[:project_id].present? - = link_to filter_path(entity, status: nil, project_id: nil), class: 'pull-right cgray' do - %i.icon-remove - %strong Clear filter + %fieldset + - if params[:state].present? || params[:project_id].present? + = link_to filter_path(entity, state: nil, project_id: nil), class: 'pull-right cgray' do + %i.icon-remove + %strong Clear filter diff --git a/app/views/shared/_project_filter.html.haml b/app/views/shared/_project_filter.html.haml index f3d032ef986..9b89c5c8007 100644 --- a/app/views/shared/_project_filter.html.haml +++ b/app/views/shared/_project_filter.html.haml @@ -1,32 +1,35 @@ -= form_tag project_entities_path, method: 'get' do - %fieldset +.side-filters.hidden-xs.hidden-sm + = form_tag project_entities_path, method: 'get' do - if current_user - %ul.nav.nav-pills.nav-stacked - %li{class: ("active" if params[:scope].blank?)} - = link_to project_filter_path(scope: nil) do - Everyone's - %li{class: ("active" if params[:scope] == 'assigned-to-me')} - = link_to project_filter_path(scope: 'assigned-to-me') do - Assigned to me - %li{class: ("active" if params[:scope] == 'created-by-me')} - = link_to project_filter_path(scope: 'created-by-me') do - Created by me + %fieldset + %ul.nav.nav-pills.nav-stacked + %li{class: ("active" if params[:scope] == 'all')} + = link_to project_filter_path(scope: 'all') do + Everyone's + %li{class: ("active" if params[:scope] == 'assigned-to-me')} + = link_to project_filter_path(scope: 'assigned-to-me') do + Assigned to me + %li{class: ("active" if params[:scope] == 'created-by-me')} + = link_to project_filter_path(scope: 'created-by-me') do + Created by me - %ul.nav.nav-pills.nav-stacked - %li{class: ("active" if params[:state].blank?)} - = link_to project_filter_path(state: nil) do - Open - %li{class: ("active" if params[:state] == 'closed')} - = link_to project_filter_path(state: 'closed') do - Closed - %li{class: ("active" if params[:state] == 'all')} - = link_to project_filter_path(state: 'all') do - All + %fieldset + %legend State + %ul.nav.nav-pills + %li{class: ("active" if params[:state] == 'opened')} + = link_to project_filter_path(state: 'opened') do + Open + %li{class: ("active" if params[:state] == 'closed')} + = link_to project_filter_path(state: 'closed') do + Closed + %li{class: ("active" if params[:state] == 'all')} + = link_to project_filter_path(state: 'all') do + All - %fieldset - - if %w(state scope milestone_id assignee_id label_name).select { |k| params[k].present? }.any? - = link_to project_entities_path, class: 'cgray pull-right' do - %i.icon-remove - %strong Clear filter + %fieldset + - if %w(state scope milestone_id assignee_id label_name).select { |k| params[k].present? }.any? + = link_to project_entities_path, class: 'cgray pull-right' do + %i.icon-remove + %strong Clear filter diff --git a/app/views/shared/_ref_switcher.html.haml b/app/views/shared/_ref_switcher.html.haml index dc8c656e12e..4d9534f49b1 100644 --- a/app/views/shared/_ref_switcher.html.haml +++ b/app/views/shared/_ref_switcher.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, class: "project-refs-select chosen" + = select_tag "ref", grouped_options_refs, class: "project-refs-select select2 select2-sm" = hidden_field_tag :destination, destination - if defined?(path) = hidden_field_tag :path, path diff --git a/app/views/shared/_sort_dropdown.html.haml b/app/views/shared/_sort_dropdown.html.haml new file mode 100644 index 00000000000..2e875669967 --- /dev/null +++ b/app/views/shared/_sort_dropdown.html.haml @@ -0,0 +1,22 @@ +.dropdown.inline.prepend-left-10 + %a.dropdown-toggle.btn.btn-small{href: '#', "data-toggle" => "dropdown"} + %span.light sort: + - if @sort.present? + = @sort + - else + Newest + %b.caret + %ul.dropdown-menu + %li + = link_to project_filter_path(sort: 'newest') do + Newest + = link_to project_filter_path(sort: 'oldest') do + Oldest + = link_to project_filter_path(sort: 'recently_updated') do + Recently updated + = link_to project_filter_path(sort: 'last_updated') do + Last updated + = link_to project_filter_path(sort: 'milestone_due_soon') do + Milestone due soon + = link_to project_filter_path(sort: 'milestone_due_later') do + Milestone due later diff --git a/app/views/snippets/_blob.html.haml b/app/views/snippets/_blob.html.haml index e0152143a95..e6ae33f38f3 100644 --- a/app/views/snippets/_blob.html.haml +++ b/app/views/snippets/_blob.html.haml @@ -15,7 +15,7 @@ = markdown(@snippet.data) - elsif markup?(@snippet.file_name) .file-content.wiki - = raw GitHub::Markup.render(@snippet.file_name, @snippet.data) + = render_markup(@snippet.file_name, @snippet.data) - else .file-content.code %div{class: user_color_scheme_class} diff --git a/app/views/snippets/_form.html.haml b/app/views/snippets/_form.html.haml index 0541ed4d633..d466dc1af14 100644 --- a/app/views/snippets/_form.html.haml +++ b/app/views/snippets/_form.html.haml @@ -2,19 +2,19 @@ = @snippet.new_record? ? "New Snippet" : "Edit Snippet ##{@snippet.id}" %hr .snippet-form-holder - = form_for @snippet, as: :personal_snippet, url: url do |f| + = form_for @snippet, as: :personal_snippet, url: url, html: { class: "form-horizontal snippet-form" } do |f| -if @snippet.errors.any? - .alert.alert-error + .alert.alert-danger %ul - @snippet.errors.full_messages.each do |msg| %li= msg - .control-group - = f.label :title - .controls= f.text_field :title, placeholder: "Example Snippet", class: 'input-xlarge', required: true - .control-group - = f.label "Access" - .controls + .form-group + = f.label :title, class: 'control-label' + .col-sm-10= f.text_field :title, placeholder: "Example Snippet", class: 'form-control', required: true + .form-group + = f.label "Access", class: 'control-label' + .col-sm-10 = f.label :private_true, class: 'radio-label' do = f.radio_button :private, true %span @@ -27,13 +27,13 @@ %strong Public (GitLab users can see this snippet) - .control-group + .form-group .file-editor - = f.label :file_name, "File" - .controls + = f.label :file_name, "File", class: 'control-label' + .col-sm-10 .file-holder.snippet .file-title - = f.text_field :file_name, placeholder: "example.rb", class: 'snippet-file-name', required: true + = f.text_field :file_name, placeholder: "example.rb", class: 'form-control snippet-file-name', required: true .file-content.code %pre#editor= @snippet.content = f.hidden_field :content, class: 'snippet-file-content' diff --git a/app/views/snippets/_snippet.html.haml b/app/views/snippets/_snippet.html.haml index 4c9ef3f9f34..e6f83167330 100644 --- a/app/views/snippets/_snippet.html.haml +++ b/app/views/snippets/_snippet.html.haml @@ -20,4 +20,4 @@ = link_to user_snippets_path(snippet.author) do = image_tag avatar_icon(snippet.author_email), class: "avatar avatar-inline s16", alt: '' = snippet.author_name - %span.light #{time_ago_with_tooltip(snippet.created_at)} ago + %span.light #{time_ago_with_tooltip(snippet.created_at)} diff --git a/app/views/snippets/current_user_index.html.haml b/app/views/snippets/current_user_index.html.haml index 51030f965a1..bf712b2c7e7 100644 --- a/app/views/snippets/current_user_index.html.haml +++ b/app/views/snippets/current_user_index.html.haml @@ -11,7 +11,7 @@ %hr .row - .span3 + .col-md-3 %ul.nav.nav-pills.nav-stacked = nav_tab :scope, nil do = link_to user_snippets_path(@user) do @@ -29,6 +29,6 @@ %span.pull-right = @user.snippets.public.count - .span9.my-snippets + .col-md-9.my-snippets = render 'snippets' diff --git a/app/views/users/_profile.html.haml b/app/views/users/_profile.html.haml index 4cd1eebdf91..7ffd43e837d 100644 --- a/app/views/users/_profile.html.haml +++ b/app/views/users/_profile.html.haml @@ -8,7 +8,7 @@ - unless user.skype.blank? %li %span.light Skype: - %strong= user.skype + %strong= link_to user.skype, "skype:#{user.skype}" - unless user.linkedin.blank? %li %span.light LinkedIn: @@ -16,7 +16,11 @@ - unless user.twitter.blank? %li %span.light Twitter: - %strong= user.twitter + %strong= link_to user.twitter, "http://www.twitter.com/#{user.twitter}" + - unless user.website_url.blank? + %li + %span.light Website: + %strong= link_to user.short_website_url, user.full_website_url - unless user.bio.blank? %li %span.light Bio: diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 53a0a9232a4..65f46500a89 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -1,5 +1,5 @@ .row - .span8 + .col-md-8 %h3.page-title = image_tag avatar_icon(@user.email, 90), class: "avatar s90", alt: '' = @user.name @@ -9,13 +9,13 @@ %i.icon-edit Edit Profile settings %br - %small #{@user.username} + %span.user-show-username #{@user.username} %br %small member since #{@user.created_at.stamp("Nov 12, 2031")} .clearfix %hr %h4 User Activity: = render @events - .span4 + .col-md-4 = render 'profile', user: @user = render 'projects', user: @user diff --git a/app/views/votes/_votes_block.html.haml b/app/views/votes/_votes_block.html.haml index bded53b2f21..788d9065a7b 100644 --- a/app/views/votes/_votes_block.html.haml +++ b/app/views/votes/_votes_block.html.haml @@ -1,6 +1,6 @@ .votes.votes-block .progress - .bar.bar-success{style: "width: #{votable.upvotes_in_percent}%;"} - .bar.bar-danger{style: "width: #{votable.downvotes_in_percent}%;"} + .progress-bar.progress-bar-success{style: "width: #{votable.upvotes_in_percent}%;"} + .progress-bar.progress-bar-danger{style: "width: #{votable.downvotes_in_percent}%;"} .upvotes= "#{votable.upvotes} up" .downvotes= "#{votable.downvotes} down" diff --git a/config/application.rb b/config/application.rb index 1c91134f524..88759ce7cf3 100644 --- a/config/application.rb +++ b/config/application.rb @@ -38,6 +38,7 @@ module Gitlab # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.default_locale = :de + config.i18n.enforce_available_locales = false # Configure the default encoding used in templates for Ruby 1.9. config.encoding = "utf-8" diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 2bc984c9294..c63e8cb7ded 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -65,7 +65,7 @@ production: &base # If a commit message matches this regular expression, all issues referenced from the matched text will be closed. # This happens when the commit is pushed or merged into the default branch of a project. # When not specified the default issue_closing_pattern as specified below will be used. - # issue_closing_pattern: ([Cc]lose[sd]|[Ff]ixe[sd]) +#\d+ + # issue_closing_pattern: '([Cc]lose[sd]|[Ff]ixe[sd]) +#\d+' ## Default project features settings default_projects_features: @@ -116,8 +116,8 @@ production: &base # ========================== ## LDAP settings - # You can inspect the first 100 LDAP users with login access by running: - # bundle exec rake gitlab:ldap:check[100] RAILS_ENV=production + # You can inspect a sample of the LDAP users with login access by running: + # bundle exec rake gitlab:ldap:check RAILS_ENV=production ldap: enabled: false host: '_your_ldap_server' @@ -127,6 +127,15 @@ production: &base method: 'ssl' # "ssl" or "plain" bind_dn: '_the_full_dn_of_the_user_you_will_bind_with' password: '_the_password_of_the_bind_user' + # If allow_username_or_email_login is enabled, GitLab will ignore everything + # after the first '@' in the LDAP username submitted by the user on login. + # + # Example: + # - the user enters 'jane.doe@example.com' and 'p@ssw0rd' as LDAP credentials; + # - GitLab queries the LDAP server with 'jane.doe' and 'p@ssw0rd'. + # + # If you are using "uid: 'userPrincipalName'" on ActiveDirectory you need to + # disable this setting, because the userPrincipalName contains an '@'. allow_username_or_email_login: true ## OmniAuth settings @@ -154,7 +163,8 @@ production: &base # - { name: 'twitter', app_id: 'YOUR APP ID', # app_secret: 'YOUR APP SECRET'} # - { name: 'github', app_id: 'YOUR APP ID', - # app_secret: 'YOUR APP SECRET' } + # app_secret: 'YOUR APP SECRET', + # args: { scope: 'user:email' } } diff --git a/config/initializers/devise_password_length.rb.example b/config/initializers/devise_password_length.rb.example new file mode 100644 index 00000000000..97305825e07 --- /dev/null +++ b/config/initializers/devise_password_length.rb.example @@ -0,0 +1,6 @@ +Devise.setup do |config| + # The following line changes the password length limits for new users. In the + # example below the minimum length is 12 characters, and the maximum length + # is 128 characters. + config.password_length = 12..128 +end diff --git a/config/routes.rb b/config/routes.rb index 8322d6a9d4e..315c339016b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -6,6 +6,7 @@ Gitlab::Application.routes.draw do # Search # get 'search' => "search#show" + get 'search/autocomplete' => "search#autocomplete", as: :search_autocomplete # API API::API.logger Rails.logger @@ -217,7 +218,7 @@ Gitlab::Application.routes.draw do resource :repository, only: [:show] do member do get "stats" - get "archive" + get "archive", constraints: { format: Gitlab::Regex.archive_formats_regex } end end diff --git a/db/fixtures/development/04_project.rb b/db/fixtures/development/04_project.rb index 6fdb163c27d..990575306c3 100644 --- a/db/fixtures/development/04_project.rb +++ b/db/fixtures/development/04_project.rb @@ -19,7 +19,7 @@ project_urls = [ project_urls.each_with_index do |url, i| group_path, project_path = url.split('/')[-2..-1] - group = Group.find_by_path(group_path) + group = Group.find_by(path: group_path) unless group group = Group.new( diff --git a/db/migrate/20130506095501_remove_project_id_from_key.rb b/db/migrate/20130506095501_remove_project_id_from_key.rb index 4214fd45d14..6b794cfb5c1 100644 --- a/db/migrate/20130506095501_remove_project_id_from_key.rb +++ b/db/migrate/20130506095501_remove_project_id_from_key.rb @@ -4,7 +4,7 @@ class RemoveProjectIdFromKey < ActiveRecord::Migration Key.where('project_id IS NOT NULL').update_all(type: 'DeployKey') DeployKey.all.each do |key| - project = Project.find_by_id(key.project_id) + project = Project.find_by(id: key.project_id) if project project.deploy_keys << key print '.' diff --git a/db/migrate/20140116231608_add_website_url_to_users.rb b/db/migrate/20140116231608_add_website_url_to_users.rb new file mode 100644 index 00000000000..0996fdcad73 --- /dev/null +++ b/db/migrate/20140116231608_add_website_url_to_users.rb @@ -0,0 +1,5 @@ +class AddWebsiteUrlToUsers < ActiveRecord::Migration + def change + add_column :users, :website_url, :string, {:null => false, :default => ''} + end +end diff --git a/db/schema.rb b/db/schema.rb index e02799e0dbc..73d0a92e1cc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20131217102743) do +ActiveRecord::Schema.define(version: 20140116231608) do create_table "broadcast_messages", force: true do |t| t.text "message", null: false @@ -301,6 +301,7 @@ ActiveRecord::Schema.define(version: 20131217102743) do t.datetime "confirmation_sent_at" t.string "unconfirmed_email" t.boolean "hide_no_ssh_key", default: false + t.string "website_url", default: "", null: false end add_index "users", ["admin"], name: "index_users_on_admin", using: :btree diff --git a/doc/api/project_snippets.md b/doc/api/project_snippets.md index f7b7fc8fbb5..e16e1e84596 100644 --- a/doc/api/project_snippets.md +++ b/doc/api/project_snippets.md @@ -57,7 +57,6 @@ Parameters: + `id` (required) - The ID 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 @@ -75,7 +74,6 @@ Parameters: + `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 diff --git a/doc/api/projects.md b/doc/api/projects.md index 53acc4a025e..559553a1108 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -239,6 +239,7 @@ Parameters: + `snippets_enabled` (optional) + `public` (optional) - if `true` same as setting visibility_level = 20 + `visibility_level` (optional) +* `import_url` (optional) ### Create project for user diff --git a/doc/api/repositories.md b/doc/api/repositories.md index 6b3a43b869e..01607263008 100644 --- a/doc/api/repositories.md +++ b/doc/api/repositories.md @@ -259,7 +259,12 @@ Parameters: "title": "Sanitize for network graph", "author_name": "randx", "author_email": "dmitriy.zaporozhets@gmail.com", - "created_at": "2012-09-20T09:06:12+03:00" + "created_at": "2012-09-20T09:06:12+03:00", + "committed_date": "2012-09-20T09:06:12+03:00", + "authored_date": "2012-09-20T09:06:12+03:00", + "parent_ids" : [ + "ae1d9fb46aa2b07ee9836d49862ec4e2c46fbbba" + ] } ``` @@ -395,6 +400,7 @@ Parameters: + `file_path` (optional) - Full path to new file. Ex. lib/class.rb + `branch_name` (required) - The name of branch ++ `encoding` (optional) - 'text' or 'base64'. Text is default. + `content` (required) - File content + `commit_message` (required) - Commit message @@ -408,6 +414,7 @@ Parameters: + `file_path` (required) - Full path to file. Ex. lib/class.rb + `branch_name` (required) - The name of branch ++ `encoding` (optional) - 'text' or 'base64'. Text is default. + `content` (required) - New file content + `commit_message` (required) - Commit message diff --git a/doc/api/session.md b/doc/api/session.md index 162d4c8bf78..fd18d5c5e97 100644 --- a/doc/api/session.md +++ b/doc/api/session.md @@ -26,6 +26,7 @@ __You can login with both GitLab and LDAP credentials now__ "skype": "", "linkedin": "", "twitter": "", + "website_url": "", "dark_scheme": false, "theme_id": 1, "is_admin": false, diff --git a/doc/api/users.md b/doc/api/users.md index 16479ea6e0d..4098da72b30 100644 --- a/doc/api/users.md +++ b/doc/api/users.md @@ -20,6 +20,7 @@ GET /users "skype": "", "linkedin": "", "twitter": "", + "website_url": "", "extern_uid": "john.smith", "provider": "provider_name", "theme_id": 1, @@ -38,6 +39,7 @@ GET /users "skype": "", "linkedin": "", "twitter": "", + "website_url": "", "extern_uid": "jack.smith", "provider": "provider_name", "theme_id": 1, @@ -74,6 +76,7 @@ Parameters: "skype": "", "linkedin": "", "twitter": "", + "website_url": "", "extern_uid": "john.smith", "provider": "provider_name", "theme_id": 1, @@ -102,6 +105,7 @@ Parameters: + `skype` (optional) - Skype ID + `linkedin` (optional) - Linkedin + `twitter` (optional) - Twitter account ++ `website_url` (optional) - Website url + `projects_limit` (optional) - Number of projects user can create + `extern_uid` (optional) - External UID + `provider` (optional) - External provider name @@ -127,6 +131,7 @@ Parameters: + `skype` - Skype ID + `linkedin` - Linkedin + `twitter` - Twitter account ++ `website_url` - Website url + `projects_limit` - Limit projects each user can create + `extern_uid` - External UID + `provider` - External provider name @@ -174,6 +179,7 @@ GET /user "skype": "", "linkedin": "", "twitter": "", + "website_url": "", "theme_id": 1, "color_scheme_id": 2, "is_admin": false, diff --git a/doc/install/databases.md b/doc/install/databases.md index 6016e97ede5..1d9405dfa96 100644 --- a/doc/install/databases.md +++ b/doc/install/databases.md @@ -52,7 +52,7 @@ GitLab supports the following databases: ## PostgreSQL # Install the database packages - sudo apt-get install -y postgresql-9.1 libpq-dev + sudo apt-get install -y postgresql-9.1 postgresql-client libpq-dev # Login to PostgreSQL sudo -u postgres psql -d template1 diff --git a/doc/install/installation.md b/doc/install/installation.md index 02f713e7611..0d7f126167b 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -2,19 +2,21 @@ Make sure you view this installation guide from the branch (version) of GitLab you would like to install. In most cases this should be the highest numbered stable branch (example shown below). - + If this is unclear check the [GitLab Blog](http://blog.gitlab.org/) for installation guide links by version. # Important notes -This installation guide was created for and tested on **Debian/Ubuntu** operating systems. Please read [`doc/install/requirements.md`](./requirements.md) for hardware and operating system requirements. +This guide is long because it covers many cases and includes all commands you need, this is [one of the few installation scripts that actually works out of the box](https://twitter.com/robinvdvleuten/status/424163226532986880). + +This installation guide was created for and tested on **Debian/Ubuntu** operating systems. Please read [doc/install/requirements.md](./requirements.md) for hardware and operating system requirements. This is the official installation guide to set up a production server. To set up a **development installation** or for many other installation options please consult [the installation section in the readme](https://github.com/gitlabhq/gitlabhq#installation). The following steps have been known to work. Please **use caution when you deviate** from this guide. Make sure you don't violate any assumptions GitLab makes about its environment. For example many people run into permission problems because they changed the location of directories or run services as the wrong user. -If you find a bug/error in this guide please **submit a pull request** following the [contributing guide](../../CONTRIBUTING.md). +If you find a bug/error in this guide please **submit a merge request** following the [contributing guide](../../CONTRIBUTING.md). - - - @@ -111,6 +113,8 @@ Then select 'Internet Site' and press enter to confirm the hostname. # 2. Ruby +The use of ruby version managers such as [RVM](http://rvm.io/), [rbenv](https://github.com/sstephenson/rbenv) or [chruby](https://github.com/postmodern/chruby) with GitLab in production frequently leads to hard to diagnose problems. Version managers are not supported and we stronly advise everyone to follow the instructions below to use a system ruby. + Remove the old Ruby 1.8 if present sudo apt-get remove ruby1.8 @@ -144,7 +148,7 @@ GitLab Shell is an ssh access and repository management software developed speci cd /home/git # Clone gitlab shell - sudo -u git -H git clone https://github.com/gitlabhq/gitlab-shell.git -b v1.8.0 + sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-shell.git -b v1.8.0 cd gitlab-shell @@ -171,13 +175,13 @@ To setup the MySQL/PostgreSQL database and dependencies please see [`doc/install ## Clone the Source # Clone GitLab repository - sudo -u git -H git clone https://github.com/gitlabhq/gitlabhq.git -b 6-4-stable gitlab + sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 6-5-stable gitlab # Go to gitlab dir cd /home/git/gitlab **Note:** -You can change `6-4-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! +You can change `6-5-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! ## Configure it @@ -313,7 +317,7 @@ Check if GitLab and its environment are configured correctly: **Note:** Nginx is the officially supported web server for GitLab. If you cannot or do not want to use Nginx as your web server, have a look at the -[GitLab recipes](https://github.com/gitlabhq/gitlab-recipes). +[GitLab recipes](https://gitlab.com/gitlab-org/gitlab-recipes/). ## Installation sudo apt-get install -y nginx @@ -408,9 +412,9 @@ These steps are fairly general and you will need to figure out the exact details * Stop GitLab `sudo service gitlab stop` -* Add provider specific configuration options to your `config/gitlab.yml` (you can use the [auth providers section of the example config](https://github.com/gitlabhq/gitlabhq/blob/master/config/gitlab.yml.example) as a reference) +* Add provider specific configuration options to your `config/gitlab.yml` (you can use the [auth providers section of the example config](https://gitlab.com/gitlab-org/gitlab-ce/blob/masterconfig/gitlab.yml.example) as a reference) -* Add the gem to your [Gemfile](https://github.com/gitlabhq/gitlabhq/blob/master/Gemfile) +* Add the gem to your [Gemfile](https://gitlab.com/gitlab-org/gitlab-ce/blob/masterGemfile) `gem "omniauth-your-auth-provider"` * If you're using MySQL, install the new Omniauth provider gem by running the following command: `sudo -u git -H bundle install --without development test postgres --path vendor/bundle --no-deployment` diff --git a/doc/install/requirements.md b/doc/install/requirements.md index e9c95ba2ef9..0a1539fb0d6 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -55,7 +55,7 @@ it might require some work since GitLab uses several Gems that have native exten - 512MB is too little memory, GitLab will be very slow and you will need 250MB of swap - 768MB is the minimal memory size but we advise against this -- 1GB supports up to 100 users if you do not have individual repo's over 250MB +- 1GB supports up to 100 users (with individual repositories under 250MB, otherwise git memory usage necessitates using swap space) - **2GB** is the **recommended** memory size and supports up to 1,000 users - 4GB supports up to 10,000 users @@ -76,3 +76,11 @@ If you have enough RAM memory and a recent CPU the speed of GitLab is mainly lim If you have troubles installing GitLab following the [official installation guide](installation.md) or want to share your experience installing GitLab on a not officially supported platform, please follow the the [contribution guide](/CONTRIBUTING.md). + +# Supported webbrowsers + +- Chrome (Latest stable version) +- Firefox (Latest released version) +- Safari 7+ (Know problem: required fields in html5 do not work) +- Opera (Latest released version) +- IE 10+ diff --git a/doc/release/monthly.md b/doc/release/monthly.md index b96ae211812..bad7794d421 100644 --- a/doc/release/monthly.md +++ b/doc/release/monthly.md @@ -27,16 +27,16 @@ NOTE: This is a guide for GitLab developers. If you are trying to install GitLab Check if any of these changed since last release (~22nd of last month depending on when last release branch was created): -* https://github.com/gitlabhq/gitlabhq/commits/master/lib/support/nginx/gitlab -* https://github.com/gitlabhq/gitlab-shell/commits/master/config.yml.example -* https://github.com/gitlabhq/gitlabhq/commits/master/config/gitlab.yml.example -* https://github.com/gitlabhq/gitlabhq/commits/master/config/unicorn.rb.example -* https://github.com/gitlabhq/gitlabhq/commits/master/config/database.yml.mysql -* https://github.com/gitlabhq/gitlabhq/commits/master/config/database.yml.postgresql +* https://gitlab.com/gitlab-org/gitlab-ce/commits/master/lib/support/nginx/gitlab +* https://gitlab.com/gitlab-org/gitlab-shell/commits/master/config.yml.example +* https://gitlab.com/gitlab-org/gitlab-ce/commits/master/config/gitlab.yml.example +* https://gitlab.com/gitlab-org/gitlab-ce/commits/master/config/unicorn.rb.example +* https://gitlab.com/gitlab-org/gitlab-ce/commits/master/config/database.yml.mysql +* https://gitlab.com/gitlab-org/gitlab-ce/commits/master/config/database.yml.postgresql #### 8. Need to update init script? -Check if changed since last release (~22nd of last month depending on when last release branch was created): https://github.com/gitlabhq/gitlabhq/commits/master/lib/support/init.d/gitlab +Check if changed since last release (~22nd of last month depending on when last release branch was created): https://gitlab.com/gitlab-org/gitlab-ce/commits/master/lib/support/init.d/gitlab #### 9. Start application @@ -56,23 +56,17 @@ Check if changed since last release (~22nd of last month depending on when last ## Make a release branch -After making the release branch new commits are cherry-picked from master. When the release gets closer we get more selective what is cherry-picked. +After making the release branch new commits are cherry-picked from master. When the release gets closer we get more selective what is cherry-picked. The days of the month are approximately as follows: -* 5 days before release: feature freeze (stop merging new features) -* 4 days before release: UI freeze (stop merging changes to the user interface) -* 3 days before release: code freeze (stop merging non-essential code improvements) -* 2 days before release: release candidate 1 (tag and tweet about x.x.rc1) -* 1 day before release: release candidate 2 (optional, only if rc1 had problems) +* 17th: feature freeze (branch and stop merging new features) +* 18th: UI freeze (stop cherry-picking changes to the user interface) +* 19th: code freeze (stop cherry-picking non-essential code improvements) +* 20th: release candidate 1 (tag and tweet about x.x.rc1) +* 21st: release candidate 2 (optional, only if rc1 had problems) +* 22nd: release (update VERSION and CHANGELOG, tag, blog and tweet) # Write a blog post * Mention what GitLab is on the second line: GitLab is open source software to collaborate on code. * Select and thank the the Most Valuable Person (MVP) of this release. -* Note if there are security fixes: This release fixes an important security issue and we advise everyone to upgrade as soon as possible. - -## Last actions - -1. Update VERSION and CHANGELOG -1. Create a git tag vX.X.X -1. Publish the blog post -1. Tweet about the release
\ No newline at end of file +* Add a note if there are security fixes: This release fixes an important security issue and we advise everyone to upgrade as soon as possible. diff --git a/doc/release/security.md b/doc/release/security.md index a77cbae3eaa..7ec3991de85 100644 --- a/doc/release/security.md +++ b/doc/release/security.md @@ -22,7 +22,7 @@ Please report suspected security vulnerabilities in private to support@gitlab.co 1. Push the code and the tags to all the CE and EE repositories 1. Apply the patch to GitLab Cloud and the private GitLab development server 1. Merge and publish the blog posts -1. Send tweets about the release from @gitlabhq and @git_lab +1. Send tweets about the release from @gitlabhq 1. Send out an email to the subscribers mailing list on MailChimp 1. Send out an email to [the community google mailing list](https://groups.google.com/forum/#!forum/gitlabhq) 1. Send out an email to [the GitLab newsletter list](http://gitlab.us5.list-manage.com/subscribe?u=498dccd07cf3e9482bee33ba4&id=98a9a4992c) diff --git a/doc/security/password_length_limits.md b/doc/security/password_length_limits.md new file mode 100644 index 00000000000..c8d66e9636c --- /dev/null +++ b/doc/security/password_length_limits.md @@ -0,0 +1,10 @@ +# Custom password length limits + +If you want to enforce longer user passwords you can create an extra Devise initializer with the steps below. +If you do not use the `devise_password_length.rb` initializer the password length is set to a minimum of 8 characters in `config/initializers/devise.rb`. + +```bash +cd /home/git/gitlab +sudo -u git -H cp config/initializers/devise_password_length.rb.example config/initializers/devise_password_length.rb +sudo -u git -H editor config/initializers/devise_password_length.rb # inspect and edit the new password length limits +``` diff --git a/doc/update/5.1-to-5.2.md b/doc/update/5.1-to-5.2.md index a25df58a9ba..e4eaee91b8e 100644 --- a/doc/update/5.1-to-5.2.md +++ b/doc/update/5.1-to-5.2.md @@ -51,8 +51,8 @@ sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production ### 5. Update config files -* Make `/home/git/gitlab/config/gitlab.yml` same as https://github.com/gitlabhq/gitlabhq/blob/5-2-stable/config/gitlab.yml.example but with your settings. -* Make `/home/git/gitlab/config/puma.rb` same as https://github.com/gitlabhq/gitlabhq/blob/5-2-stable/config/puma.rb.example but with your settings. +* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-2-stable/config/gitlab.yml.example but with your settings. +* Make `/home/git/gitlab/config/puma.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-2-stable/config/puma.rb.example but with your settings. ### 6. Update Init script diff --git a/doc/update/5.1-to-5.4.md b/doc/update/5.1-to-5.4.md index 3061507f6a6..39cacd381a3 100644 --- a/doc/update/5.1-to-5.4.md +++ b/doc/update/5.1-to-5.4.md @@ -52,8 +52,8 @@ sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production ### 5. Update config files -* Make `/home/git/gitlab/config/gitlab.yml` same as https://github.com/gitlabhq/gitlabhq/blob/5-4-stable/config/gitlab.yml.example but with your settings. -* Make `/home/git/gitlab/config/puma.rb` same as https://github.com/gitlabhq/gitlabhq/blob/5-4-stable/config/puma.rb.example but with your settings. +* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-4-stable/config/gitlab.yml.example but with your settings. +* Make `/home/git/gitlab/config/puma.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-4-stable/config/puma.rb.example but with your settings. ### 6. Update Init script diff --git a/doc/update/5.1-to-6.0.md b/doc/update/5.1-to-6.0.md index 53a3c645241..fa0f9ce54b6 100644 --- a/doc/update/5.1-to-6.0.md +++ b/doc/update/5.1-to-6.0.md @@ -87,8 +87,8 @@ sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production Note: We switched from Puma in GitLab 5.x to unicorn in GitLab 6.0. -* Make `/home/git/gitlab/config/gitlab.yml` the same as https://github.com/gitlabhq/gitlabhq/blob/master/config/gitlab.yml.example but with your settings. -* Make `/home/git/gitlab/config/unicorn.rb` the same as https://github.com/gitlabhq/gitlabhq/blob/master/config/unicorn.rb.example but with your settings. +* Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/masterconfig/gitlab.yml.example but with your settings. +* Make `/home/git/gitlab/config/unicorn.rb` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/masterconfig/unicorn.rb.example but with your settings. ### 7. Update Init script diff --git a/doc/update/5.2-to-5.3.md b/doc/update/5.2-to-5.3.md index 67517b23d37..7f89f6bf887 100644 --- a/doc/update/5.2-to-5.3.md +++ b/doc/update/5.2-to-5.3.md @@ -43,8 +43,8 @@ sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production ### 4. Update config files -* Make `/home/git/gitlab/config/gitlab.yml` same as https://github.com/gitlabhq/gitlabhq/blob/5-3-stable/config/gitlab.yml.example but with your settings. -* Make `/home/git/gitlab/config/puma.rb` same as https://github.com/gitlabhq/gitlabhq/blob/5-3-stable/config/puma.rb.example but with your settings. +* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-3-stable/config/gitlab.yml.example but with your settings. +* Make `/home/git/gitlab/config/puma.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-3-stable/config/puma.rb.example but with your settings. ### 5. Update Init script diff --git a/doc/update/5.3-to-5.4.md b/doc/update/5.3-to-5.4.md index 11c0f7c627f..7a24c11c223 100644 --- a/doc/update/5.3-to-5.4.md +++ b/doc/update/5.3-to-5.4.md @@ -51,8 +51,8 @@ sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production ### 5. Update config files -* Make `/home/git/gitlab/config/gitlab.yml` same as https://github.com/gitlabhq/gitlabhq/blob/5-4-stable/config/gitlab.yml.example but with your settings. -* Make `/home/git/gitlab/config/puma.rb` same as https://github.com/gitlabhq/gitlabhq/blob/5-4-stable/config/puma.rb.example but with your settings. +* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-4-stable/config/gitlab.yml.example but with your settings. +* Make `/home/git/gitlab/config/puma.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-4-stable/config/puma.rb.example but with your settings. ### 6. Update Init script diff --git a/doc/update/5.4-to-6.0.md b/doc/update/5.4-to-6.0.md index 8990f8d034f..bcba3ee4d05 100644 --- a/doc/update/5.4-to-6.0.md +++ b/doc/update/5.4-to-6.0.md @@ -87,8 +87,8 @@ sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production Note: We switched from Puma in GitLab 5.4 to unicorn in GitLab 6.0. -* Make `/home/git/gitlab/config/gitlab.yml` the same as https://github.com/gitlabhq/gitlabhq/blob/master/config/gitlab.yml.example but with your settings. -* Make `/home/git/gitlab/config/unicorn.rb` the same as https://github.com/gitlabhq/gitlabhq/blob/master/config/unicorn.rb.example but with your settings. +* Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/masterconfig/gitlab.yml.example but with your settings. +* Make `/home/git/gitlab/config/unicorn.rb` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/masterconfig/unicorn.rb.example but with your settings. ### 7. Update Init script diff --git a/doc/update/6.0-to-6.1.md b/doc/update/6.0-to-6.1.md index f02f054fda8..ac8f0a77efd 100644 --- a/doc/update/6.0-to-6.1.md +++ b/doc/update/6.0-to-6.1.md @@ -30,8 +30,9 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ```bash cd /home/git/gitlab -sudo -u git -H git fetch +sudo -u git -H git fetch --all sudo -u git -H git checkout 6-1-stable +# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-1-stable-ee ``` ### 3. Update gitlab-shell @@ -63,8 +64,8 @@ sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production ### 5. Update config files -* Make `/home/git/gitlab/config/gitlab.yml` same as https://github.com/gitlabhq/gitlabhq/blob/6-1-stable/config/gitlab.yml.example but with your settings. -* Make `/home/git/gitlab/config/unicorn.rb` same as https://github.com/gitlabhq/gitlabhq/blob/6-1-stable/config/unicorn.rb.example but with your settings. +* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-1-stable/config/gitlab.yml.example but with your settings. +* Make `/home/git/gitlab/config/unicorn.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-1-stable/config/unicorn.rb.example but with your settings. ### 6. Update Init script diff --git a/doc/update/6.0-to-6.2.md b/doc/update/6.0-to-6.5.md index 03d7e96effe..8b2fcd4854b 100644 --- a/doc/update/6.0-to-6.2.md +++ b/doc/update/6.0-to-6.5.md @@ -1,7 +1,4 @@ -# From 6.0 to 6.2 - -## Notice -Security vulnerabilities CVE-2013-4490 and CVE-2013-4489 have been patched in the latest version of GitLab 6.2. +# From 6.0 to 6.5 # In 6.1 we remove a lot of deprecated code. # You should update to 6.0 before installing 6.1 or higher so all the necessary conversions are run. @@ -30,8 +27,9 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ```bash cd /home/git/gitlab -sudo -u git -H git fetch -sudo -u git -H git checkout 6-2-stable # Latest version of 6-2-stable addresses CVE-2013-4489 +sudo -u git -H git fetch --all +sudo -u git -H git checkout 6-5-stable +# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-5-stable-ee ``` @@ -47,7 +45,7 @@ sudo apt-get install logrotate ```bash cd /home/git/gitlab-shell sudo -u git -H git fetch -sudo -u git -H git checkout v1.7.9 # Addresses multiple critical security vulnerabilities +sudo -u git -H git checkout v1.8.0 # Addresses multiple critical security vulnerabilities ``` ### 5. Install libs, migrations, etc. @@ -74,17 +72,17 @@ sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production TIP: to see what changed in gitlab.yml.example in this release use next command: ``` -git diff 6-0-stable:config/gitlab.yml.example 6-2-stable:config/gitlab.yml.example +git diff 6-0-stable:config/gitlab.yml.example 6-5-stable:config/gitlab.yml.example ``` -* Make `/home/git/gitlab/config/gitlab.yml` same as https://github.com/gitlabhq/gitlabhq/blob/6-2-stable/config/gitlab.yml.example but with your settings. -* Make `/home/git/gitlab/config/unicorn.rb` same as https://github.com/gitlabhq/gitlabhq/blob/6-2-stable/config/unicorn.rb.example but with your settings. +* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-5-stable/config/gitlab.yml.example but with your settings. +* Make `/home/git/gitlab/config/unicorn.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-5-stable/config/unicorn.rb.example but with your settings. * Copy rack attack middleware config ```bash sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb ``` -* Uncomment `config.middleware.use Rack::Attack` in `/home/git/gitlab/config/application.rb` + * Set up logrotate ```bash @@ -94,9 +92,7 @@ sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab ### 7. Update Init script ```bash -sudo rm /etc/init.d/gitlab -sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/6-2-stable/lib/support/init.d/gitlab -sudo chmod +x /etc/init.d/gitlab +sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab ``` ### 8. Start application diff --git a/doc/update/6.1-to-6.2.md b/doc/update/6.1-to-6.2.md index 767ad80641c..7342a9117c6 100644 --- a/doc/update/6.1-to-6.2.md +++ b/doc/update/6.1-to-6.2.md @@ -23,8 +23,9 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ```bash cd /home/git/gitlab -sudo -u git -H git fetch +sudo -u git -H git fetch --all sudo -u git -H git checkout 6-2-stable # Latest version of 6-2-stable addresses CVE-2013-4489 +# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-2-stable-ee ``` ### 3. Update gitlab-shell @@ -68,8 +69,8 @@ TIP: to see what changed in gitlab.yml.example in this release use next command: git diff 6-1-stable:config/gitlab.yml.example 6-2-stable:config/gitlab.yml.example ``` -* Make `/home/git/gitlab/config/gitlab.yml` same as https://github.com/gitlabhq/gitlabhq/blob/6-2-stable/config/gitlab.yml.example but with your settings. -* Make `/home/git/gitlab/config/unicorn.rb` same as https://github.com/gitlabhq/gitlabhq/blob/6-2-stable/config/unicorn.rb.example but with your settings. +* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-2-stable/config/gitlab.yml.example but with your settings. +* Make `/home/git/gitlab/config/unicorn.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-2-stable/config/unicorn.rb.example but with your settings. * Copy rack attack middleware config ```bash diff --git a/doc/update/6.2-to-6.3.md b/doc/update/6.2-to-6.3.md index b7740a538e2..7f916047369 100644 --- a/doc/update/6.2-to-6.3.md +++ b/doc/update/6.2-to-6.3.md @@ -20,8 +20,9 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ```bash cd /home/git/gitlab -sudo -u git -H git fetch +sudo -u git -H git fetch --all sudo -u git -H git checkout 6-3-stable +# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-3-stable-ee ``` ### 3. Update gitlab-shell (and its config) @@ -61,8 +62,8 @@ TIP: to see what changed in gitlab.yml.example in this release use next command: git diff 6-2-stable:config/gitlab.yml.example 6-3-stable:config/gitlab.yml.example ``` -* Make `/home/git/gitlab/config/gitlab.yml` same as https://github.com/gitlabhq/gitlabhq/blob/6-3-stable/config/gitlab.yml.example but with your settings. -* Make `/home/git/gitlab/config/unicorn.rb` same as https://github.com/gitlabhq/gitlabhq/blob/6-3-stable/config/unicorn.rb.example but with your settings. +* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-3-stable/config/gitlab.yml.example but with your settings. +* Make `/home/git/gitlab/config/unicorn.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-3-stable/config/unicorn.rb.example but with your settings. ```bash # Copy rack attack middleware config diff --git a/doc/update/6.3-to-6.4.md b/doc/update/6.3-to-6.4.md index 69d184722cb..6874056498b 100644 --- a/doc/update/6.3-to-6.4.md +++ b/doc/update/6.3-to-6.4.md @@ -15,8 +15,9 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production ```bash cd /home/git/gitlab -sudo -u git -H git fetch +sudo -u git -H git fetch --all sudo -u git -H git checkout 6-4-stable +# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-4-stable-ee ``` ### 3. Update gitlab-shell (and its config) diff --git a/doc/update/6.4-to-6.5.md b/doc/update/6.4-to-6.5.md new file mode 100644 index 00000000000..43bc20ec6b0 --- /dev/null +++ b/doc/update/6.4-to-6.5.md @@ -0,0 +1,81 @@ +# From 6.4 to 6.5 + +### 0. Backup + +```bash +cd /home/git/gitlab +sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production +``` + +### 1. Stop server + + sudo service gitlab stop + +### 2. Get latest code + +```bash +cd /home/git/gitlab +sudo -u git -H git fetch --all +sudo -u git -H git checkout 6-5-stable +# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-5-stable-ee +``` + +### 3. Update gitlab-shell (and its config) + +```bash +cd /home/git/gitlab-shell +sudo -u git -H git fetch +sudo -u git -H git checkout v1.8.0 +``` + +### 4. Install libs, migrations, etc. + +```bash +cd /home/git/gitlab + +# MySQL +sudo -u git -H bundle install --without development test postgres --deployment + +# PostgreSQL +sudo -u git -H bundle install --without development test mysql --deployment + + +# Run database migrations +sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production + +# Clean up assets and cache +sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production + +# Update init.d script +sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab +``` + +### 5. Start application + + sudo service gitlab start + sudo service nginx restart + +### 8. Check application status + +Check if GitLab and its environment are configured correctly: + + sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production + +To make sure you didn't miss anything run a more thorough check with: + + sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production + +If all items are green, then congratulations upgrade complete! + +## Things went south? Revert to previous version (6.4) + +### 1. Revert the code to the previous version +Follow the [`upgrade guide from 6.3 to 6.4`](6.3-to-6.4.md), except for the database migration +(The backup is already migrated to the previous version) + +### 2. Restore from the backup: + +```bash +cd /home/git/gitlab +sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production +``` diff --git a/doc/update/ruby.md b/doc/update/ruby.md index f6f2fd5856b..3fc068c0ae2 100644 --- a/doc/update/ruby.md +++ b/doc/update/ruby.md @@ -1,6 +1,6 @@ # Updating Ruby from source -This guide explains how to update Ruby in case you installed it from source according to the instructions in https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md#2-ruby . +This guide explains how to update Ruby in case you installed it from source according to the instructions in https://gitlab.com/gitlab-org/gitlab-ce/blob/masterdoc/install/installation.md#2-ruby . ### 1. Look for Ruby versions This guide will only update `/usr/local/bin/ruby`. You can see which Ruby binaries are installed on your system by running: @@ -36,7 +36,7 @@ sudo gem install bundler ``` ### 5. Reinstall GitLab gem bundle -Just to be sure we will reinstall the gems used by GitLab. Note that the `bundle install` command [depends on your choice of database](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md#install-gems). +Just to be sure we will reinstall the gems used by GitLab. Note that the `bundle install` command [depends on your choice of database](https://gitlab.com/gitlab-org/gitlab-ce/blob/masterdoc/install/installation.md#install-gems). ```bash cd /home/git/gitlab diff --git a/features/profile/profile.feature b/features/profile/profile.feature index 6b0421a20b3..8b6ee6fd67f 100644 --- a/features/profile/profile.feature +++ b/features/profile/profile.feature @@ -8,8 +8,8 @@ Feature: Profile Scenario: I edit profile Given I visit profile page - Then I change my contact info - And I should see new contact info + Then I change my profile info + And I should see new profile info Scenario: I change my password without old one Given I visit profile password page diff --git a/features/project/merge_requests.feature b/features/project/merge_requests.feature index 63f27c3acc3..4e4ac1a68e4 100644 --- a/features/project/merge_requests.feature +++ b/features/project/merge_requests.feature @@ -67,3 +67,13 @@ Feature: Project Merge Requests And I leave a comment on the diff page And I switch to the merge request's comments tab Then I should see a discussion has started on commit bcf03b5de6c + + @javascript + Scenario: I accept merge request with custom commit message + Given project "Shop" have "Bug NS-05" open merge request with diffs inside + And merge request "Bug NS-05" is mergeable + And I visit merge request page "Bug NS-05" + And merge request is mergeable + Then I modify merge commit message + And I accept this merge request + Then I should see merged request diff --git a/features/steps/admin/admin_groups.rb b/features/steps/admin/admin_groups.rb index b4591f227e3..013fa6da8b4 100644 --- a/features/steps/admin/admin_groups.rb +++ b/features/steps/admin/admin_groups.rb @@ -40,7 +40,7 @@ class AdminGroups < Spinach::FeatureSteps end When 'I select user "John" from user list as "Reporter"' do - user = User.find_by_name("John") + user = User.find_by(name: "John") select2(user.id, from: "#user_ids", multiple: true) within "#new_team_member" do select "Reporter", from: "group_access" diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb index bde32128b92..3526006c94a 100644 --- a/features/steps/dashboard/dashboard.rb +++ b/features/steps/dashboard/dashboard.rb @@ -43,7 +43,7 @@ class Dashboard < Spinach::FeatureSteps end And 'user with name "John Doe" left project "Shop"' do - user = User.find_by_name "John Doe" + user = User.find_by(name: "John Doe") Event.create( project: project, author_id: user.id, @@ -85,6 +85,6 @@ class Dashboard < Spinach::FeatureSteps end def project - @project ||= Project.find_by_name "Shop" + @project ||= Project.find_by(name: "Shop") end end diff --git a/features/steps/dashboard/dashboard_issues.rb b/features/steps/dashboard/dashboard_issues.rb index 9d486bd8156..a458acdae07 100644 --- a/features/steps/dashboard/dashboard_issues.rb +++ b/features/steps/dashboard/dashboard_issues.rb @@ -40,7 +40,7 @@ class DashboardIssues < Spinach::FeatureSteps step 'I click "All" link' do within ".scope-filter" do - click_link 'All' + click_link "Everyone's" end end diff --git a/features/steps/dashboard/dashboard_merge_requests.rb b/features/steps/dashboard/dashboard_merge_requests.rb index f6fe47470b3..73286532b93 100644 --- a/features/steps/dashboard/dashboard_merge_requests.rb +++ b/features/steps/dashboard/dashboard_merge_requests.rb @@ -40,7 +40,7 @@ class DashboardMergeRequests < Spinach::FeatureSteps step 'I click "All" link' do within ".scope-filter" do - click_link 'All' + click_link "Everyone's" end end diff --git a/features/steps/dashboard/dashboard_with_archived_projects.rb b/features/steps/dashboard/dashboard_with_archived_projects.rb index 700f4b426c3..1bc69555b56 100644 --- a/features/steps/dashboard/dashboard_with_archived_projects.rb +++ b/features/steps/dashboard/dashboard_with_archived_projects.rb @@ -4,7 +4,7 @@ class DashboardWithArchivedProjects < Spinach::FeatureSteps include SharedProject When 'project "Forum" is archived' do - project = Project.find_by_name "Forum" + project = Project.find_by(name: "Forum") project.update_attribute(:archived, true) end diff --git a/features/steps/group/group.rb b/features/steps/group/group.rb index 99ec77a7613..15d7c46c694 100644 --- a/features/steps/group/group.rb +++ b/features/steps/group/group.rb @@ -39,8 +39,8 @@ class Groups < Spinach::FeatureSteps end And 'I select user "John" from list with role "Reporter"' do - user = User.find_by_name("John") - within ".new_users_group" do + user = User.find_by(name: "John") + within ".users-group-form" do select2(user.id, from: "#user_ids", multiple: true) select "Reporter", from: "group_access" end diff --git a/features/steps/profile/profile.rb b/features/steps/profile/profile.rb index 7bb4aebde28..33ae6c72998 100644 --- a/features/steps/profile/profile.rb +++ b/features/steps/profile/profile.rb @@ -6,18 +6,20 @@ class Profile < Spinach::FeatureSteps page.should have_content "Profile settings" end - step 'I change my contact info' do + step 'I change my profile info' do fill_in "user_skype", with: "testskype" fill_in "user_linkedin", with: "testlinkedin" fill_in "user_twitter", with: "testtwitter" + fill_in "user_website_url", with: "testurl" click_button "Save changes" @user.reload end - step 'I should see new contact info' do + step 'I should see new profile info' do @user.skype.should == 'testskype' @user.linkedin.should == 'testlinkedin' @user.twitter.should == 'testtwitter' + @user.website_url.should == 'testurl' end step 'I change my avatar' do diff --git a/features/steps/profile/profile_ssh_keys.rb b/features/steps/profile/profile_ssh_keys.rb index 65bfc505d85..65ca824bb5b 100644 --- a/features/steps/profile/profile_ssh_keys.rb +++ b/features/steps/profile/profile_ssh_keys.rb @@ -18,7 +18,7 @@ class ProfileSshKeys < Spinach::FeatureSteps end Then 'I should see new ssh key "Laptop"' do - key = Key.find_by_title("Laptop") + key = Key.find_by(title: "Laptop") page.should have_content(key.title) page.should have_content(key.key) current_path.should == profile_key_path(key) diff --git a/features/steps/project/project_archived.rb b/features/steps/project/project_archived.rb index 149d293cd08..dfbe762c438 100644 --- a/features/steps/project/project_archived.rb +++ b/features/steps/project/project_archived.rb @@ -4,17 +4,17 @@ class ProjectArchived < Spinach::FeatureSteps include SharedPaths When 'project "Forum" is archived' do - project = Project.find_by_name "Forum" + project = Project.find_by(name: "Forum") project.update_attribute(:archived, true) end When 'project "Shop" is archived' do - project = Project.find_by_name "Shop" + project = Project.find_by(name: "Shop") project.update_attribute(:archived, true) end When 'I visit project "Forum" page' do - project = Project.find_by_name "Forum" + project = Project.find_by(name: "Forum") visit project_path(project) end diff --git a/features/steps/project/project_browse_branches.rb b/features/steps/project/project_browse_branches.rb index e77825411f3..ef29cc67a4e 100644 --- a/features/steps/project/project_browse_branches.rb +++ b/features/steps/project/project_browse_branches.rb @@ -29,7 +29,7 @@ class ProjectBrowseBranches < Spinach::FeatureSteps end And 'project "Shop" has protected branches' do - project = Project.find_by_name("Shop") + project = Project.find_by(name: "Shop") project.protected_branches.create(name: "stable") end end diff --git a/features/steps/project/project_fork.rb b/features/steps/project/project_fork.rb index 858c7d11b32..128687ca286 100644 --- a/features/steps/project/project_fork.rb +++ b/features/steps/project/project_fork.rb @@ -11,7 +11,7 @@ class ForkProject < Spinach::FeatureSteps end step 'I am a member of project "Shop"' do - @project = Project.find_by_name "Shop" + @project = Project.find_by(name: "Shop") @project ||= create(:project_with_code, name: "Shop", group: create(:group)) @project.team << [@user, :reporter] end @@ -19,7 +19,7 @@ class ForkProject < Spinach::FeatureSteps step 'I should see the forked project page' do page.should have_content "Project was successfully forked." current_path.should include current_user.namespace.path - @forked_project = Project.find_by_namespace_id(current_user.namespace.path) + @forked_project = Project.find_by(namespace_id: current_user.namespace.path) end step 'I already have a project named "Shop" in my namespace' do diff --git a/features/steps/project/project_forked_merge_requests.rb b/features/steps/project/project_forked_merge_requests.rb index f7bf085a423..a8198532ae8 100644 --- a/features/steps/project/project_forked_merge_requests.rb +++ b/features/steps/project/project_forked_merge_requests.rb @@ -3,10 +3,10 @@ class ProjectForkedMergeRequests < Spinach::FeatureSteps include SharedProject include SharedNote include SharedPaths - include ChosenHelper + include Select2Helper step 'I am a member of project "Shop"' do - @project = Project.find_by_name "Shop" + @project = Project.find_by(name: "Shop") @project ||= create(:project_with_code, name: "Shop") @project.team << [@user, :reporter] end @@ -14,7 +14,7 @@ class ProjectForkedMergeRequests < Spinach::FeatureSteps step 'I have a project forked off of "Shop" called "Forked Shop"' do @forking_user = @user forked_project_link = build(:forked_project_link) - @forked_project = Project.find_by_name "Forked Shop" + @forked_project = Project.find_by(name: "Forked Shop") @forked_project ||= create(:source_project_with_code, name: "Forked Shop", forked_project_link: forked_project_link, creator_id: @forking_user.id , namespace: @forking_user.namespace) forked_project_link.forked_from_project = @project @@ -42,14 +42,14 @@ class ProjectForkedMergeRequests < Spinach::FeatureSteps end step 'I fill out a "Merge Request On Forked Project" merge request' do - chosen @forked_project.id, from: "#merge_request_source_project_id" - chosen @project.id, from: "#merge_request_target_project_id" + select2 @forked_project.id, from: "#merge_request_source_project_id" + select2 @project.id, from: "#merge_request_target_project_id" find(:select, "merge_request_source_project_id", {}).value.should == @forked_project.id.to_s find(:select, "merge_request_target_project_id", {}).value.should == @project.id.to_s - chosen "master", from: "#merge_request_source_branch" - chosen "stable", from: "#merge_request_target_branch" + select2 "master", from: "#merge_request_source_branch" + select2 "stable", from: "#merge_request_target_branch" find(:select, "merge_request_source_branch", {}).value.should == 'master' find(:select, "merge_request_target_branch", {}).value.should == 'stable' @@ -114,7 +114,7 @@ class ProjectForkedMergeRequests < Spinach::FeatureSteps end step 'project "Forked Shop" has push event' do - @forked_project = Project.find_by_name("Forked Shop") + @forked_project = Project.find_by(name: "Forked Shop") data = { before: "0000000000000000000000000000000000000000", @@ -172,7 +172,7 @@ class ProjectForkedMergeRequests < Spinach::FeatureSteps end def project - @project ||= Project.find_by_name!("Shop") + @project ||= Project.find_by!(name: "Shop") end # Verify a link is generated against the correct project diff --git a/features/steps/project/project_graph.rb b/features/steps/project/project_graph.rb index 50942b3cbb3..89fe5fdeadf 100644 --- a/features/steps/project/project_graph.rb +++ b/features/steps/project/project_graph.rb @@ -7,7 +7,7 @@ class ProjectGraph < Spinach::FeatureSteps end When 'I visit project "Shop" graph page' do - project = Project.find_by_name("Shop") + project = Project.find_by(name: "Shop") visit project_graph_path(project, "master") end end diff --git a/features/steps/project/project_hooks.rb b/features/steps/project/project_hooks.rb index 36555fb8e8c..19ff3244543 100644 --- a/features/steps/project/project_hooks.rb +++ b/features/steps/project/project_hooks.rb @@ -1,9 +1,12 @@ +require 'webmock' + class ProjectHooks < Spinach::FeatureSteps include SharedAuthentication include SharedProject include SharedPaths include RSpec::Matchers include RSpec::Mocks::ExampleMethods + include WebMock::API Given 'project has hook' do @hook = create(:project_hook, project: current_project) @@ -25,8 +28,7 @@ class ProjectHooks < Spinach::FeatureSteps end When 'I click test hook button' do - test_hook_context = double(execute: true) - TestHookContext.should_receive(:new).and_return(test_hook_context) + stub_request(:post, @hook.url).to_return(status: 200) click_link 'Test Hook' end diff --git a/features/steps/project/project_issue_tracker.rb b/features/steps/project/project_issue_tracker.rb index a05d7a0bc37..fe41a900a90 100644 --- a/features/steps/project/project_issue_tracker.rb +++ b/features/steps/project/project_issue_tracker.rb @@ -4,7 +4,7 @@ class ProjectIssueTracker < Spinach::FeatureSteps include SharedPaths step 'project "Shop" has issues enabled' do - @project = Project.find_by_name "Shop" + @project = Project.find_by(name: "Shop") @project ||= create(:project_with_code, name: "Shop", namespace: @user.namespace) @project.issues_enabled = true end diff --git a/features/steps/project/project_issues.rb b/features/steps/project/project_issues.rb index 801fff78a52..4a503dfaf4f 100644 --- a/features/steps/project/project_issues.rb +++ b/features/steps/project/project_issues.rb @@ -54,7 +54,7 @@ class ProjectIssues < Spinach::FeatureSteps end Then 'I should see issue "500 error on profile"' do - issue = Issue.find_by_title("500 error on profile") + issue = Issue.find_by(title: "500 error on profile") page.should have_content issue.title page.should have_content issue.author_name page.should have_content issue.project.name @@ -81,14 +81,14 @@ class ProjectIssues < Spinach::FeatureSteps end Given 'project "Shop" has milestone "v2.2"' do - project = Project.find_by_name("Shop") + project = Project.find_by(name: "Shop") milestone = create(:milestone, title: "v2.2", project: project) 3.times { create(:issue, project: project, milestone: milestone) } end And 'project "Shop" has milestone "v3.0"' do - project = Project.find_by_name("Shop") + project = Project.find_by(name: "Shop") milestone = create(:milestone, title: "v3.0", project: project) 3.times { create(:issue, project: project, milestone: milestone) } @@ -104,20 +104,20 @@ class ProjectIssues < Spinach::FeatureSteps end When 'I select first assignee from "Shop" project' do - project = Project.find_by_name "Shop" + project = Project.find_by(name: "Shop") first_assignee = project.users.first select first_assignee.name, from: "assignee_id" end Then 'I should see first assignee from "Shop" as selected assignee' do issues_assignee_selector = "#issue_assignee_id_chzn > a" - project = Project.find_by_name "Shop" + project = Project.find_by(name: "Shop") assignee_name = project.users.first.name page.find(issues_assignee_selector).should have_content(assignee_name) end And 'project "Shop" have "Release 0.4" open issue' do - project = Project.find_by_name("Shop") + project = Project.find_by(name: "Shop") create(:issue, title: "Release 0.4", project: project, @@ -125,7 +125,7 @@ class ProjectIssues < Spinach::FeatureSteps end And 'project "Shop" have "Tweet control" open issue' do - project = Project.find_by_name("Shop") + project = Project.find_by(name: "Shop") create(:issue, title: "Tweet control", project: project, @@ -133,7 +133,7 @@ class ProjectIssues < Spinach::FeatureSteps end And 'project "Shop" have "Release 0.3" closed issue' do - project = Project.find_by_name("Shop") + project = Project.find_by(name: "Shop") create(:closed_issue, title: "Release 0.3", project: project, diff --git a/features/steps/project/project_labels.rb b/features/steps/project/project_labels.rb index 915190f3dae..0907cdb526f 100644 --- a/features/steps/project/project_labels.rb +++ b/features/steps/project/project_labels.rb @@ -16,7 +16,7 @@ class ProjectLabels < Spinach::FeatureSteps end And 'project "Shop" have issues tags: "bug", "feature"' do - project = Project.find_by_name("Shop") + project = Project.find_by(name: "Shop") ['bug', 'feature'].each do |label| create(:issue, project: project, label_list: label) end diff --git a/features/steps/project/project_markdown_render.rb b/features/steps/project/project_markdown_render.rb index 95d73c93621..3c5c3e09da9 100644 --- a/features/steps/project/project_markdown_render.rb +++ b/features/steps/project/project_markdown_render.rb @@ -3,7 +3,7 @@ class Spinach::Features::ProjectMarkdownRender < Spinach::FeatureSteps include SharedPaths And 'I own project "Delta"' do - @project = Project.find_by_name "Delta" + @project = Project.find_by(name: "Delta") @project ||= create(:project_with_code, name: "Delta", namespace: @user.namespace) @project.team << [@user, :master] end @@ -124,7 +124,7 @@ class Spinach::Features::ProjectMarkdownRender < Spinach::FeatureSteps Then 'I see new wiki page named test' do current_path.should == project_wiki_path(@project, "test") - page.should have_content "Editing page" + page.should have_content "Editing" end When 'I go back to wiki page home' do diff --git a/features/steps/project/project_merge_requests.rb b/features/steps/project/project_merge_requests.rb index 7b0f8cc7ad2..b771c8d1392 100644 --- a/features/steps/project/project_merge_requests.rb +++ b/features/steps/project/project_merge_requests.rb @@ -4,60 +4,60 @@ class ProjectMergeRequests < Spinach::FeatureSteps include SharedNote include SharedPaths - Given 'I click link "New Merge Request"' do + step 'I click link "New Merge Request"' do click_link "New Merge Request" end - Given 'I click link "Bug NS-04"' do + step 'I click link "Bug NS-04"' do click_link "Bug NS-04" end - Given 'I click link "All"' do + step 'I click link "All"' do click_link "All" end - Given 'I click link "Closed"' do + step 'I click link "Closed"' do click_link "Closed" end - Then 'I should see merge request "Wiki Feature"' do + step 'I should see merge request "Wiki Feature"' do within '.merge-request' do page.should have_content "Wiki Feature" end end - Then 'I should see closed merge request "Bug NS-04"' do - merge_request = MergeRequest.find_by_title!("Bug NS-04") + step 'I should see closed merge request "Bug NS-04"' do + merge_request = MergeRequest.find_by!(title: "Bug NS-04") merge_request.closed?.should be_true page.should have_content "Closed by" end - Then 'I should see merge request "Bug NS-04"' do + step 'I should see merge request "Bug NS-04"' do page.should have_content "Bug NS-04" end - Then 'I should see "Bug NS-04" in merge requests' do + step 'I should see "Bug NS-04" in merge requests' do page.should have_content "Bug NS-04" end - Then 'I should see "Feature NS-03" in merge requests' do + step 'I should see "Feature NS-03" in merge requests' do page.should have_content "Feature NS-03" end - And 'I should not see "Feature NS-03" in merge requests' do + step 'I should not see "Feature NS-03" in merge requests' do page.should_not have_content "Feature NS-03" end - And 'I should not see "Bug NS-04" in merge requests' do + step 'I should not see "Bug NS-04" in merge requests' do page.should_not have_content "Bug NS-04" end - And 'I click link "Close"' do + step 'I click link "Close"' do click_link "Close" end - And 'I submit new merge request "Wiki Feature"' do + step 'I submit new merge request "Wiki Feature"' do fill_in "merge_request_title", with: "Wiki Feature" # this must come first, so that the target branch is set @@ -76,7 +76,7 @@ class ProjectMergeRequests < Spinach::FeatureSteps click_button "Submit merge request" end - And 'project "Shop" have "Bug NS-04" open merge request' do + step 'project "Shop" have "Bug NS-04" open merge request' do create(:merge_request, title: "Bug NS-04", source_project: project, @@ -84,7 +84,7 @@ class ProjectMergeRequests < Spinach::FeatureSteps author: project.users.first) end - And 'project "Shop" have "Bug NS-05" open merge request with diffs inside' do + step 'project "Shop" have "Bug NS-05" open merge request with diffs inside' do create(:merge_request_with_diffs, title: "Bug NS-05", source_project: project, @@ -92,7 +92,7 @@ class ProjectMergeRequests < Spinach::FeatureSteps author: project.users.first) end - And 'project "Shop" have "Feature NS-03" closed merge request' do + step 'project "Shop" have "Feature NS-03" closed merge request' do create(:closed_merge_request, title: "Feature NS-03", source_project: project, @@ -100,19 +100,19 @@ class ProjectMergeRequests < Spinach::FeatureSteps author: project.users.first) end - And 'I switch to the diff tab' do + step 'I switch to the diff tab' do visit diffs_project_merge_request_path(project, merge_request) end - And 'I switch to the merge request\'s comments tab' do + step 'I switch to the merge request\'s comments tab' do visit project_merge_request_path(project, merge_request) end - And 'I click on the first commit in the merge request' do + step 'I click on the first commit in the merge request' do click_link merge_request.commits.first.short_id(8) end - And 'I leave a comment on the diff page' do + step 'I leave a comment on the diff page' do init_diff_note within('.js-discussion-note-form') do @@ -125,7 +125,7 @@ class ProjectMergeRequests < Spinach::FeatureSteps end end - And 'I leave a comment like "Line is wrong" on line 185 of the first file' do + step 'I leave a comment like "Line is wrong" on line 185 of the first file' do init_diff_note within(".js-discussion-note-form") do @@ -138,30 +138,53 @@ class ProjectMergeRequests < Spinach::FeatureSteps end end - Then 'I should see a discussion has started on line 185' do + step 'I should see a discussion has started on line 185' do page.should have_content "#{current_user.name} started a discussion on this merge request diff" page.should have_content "app/assets/stylesheets/tree.scss:L185" page.should have_content "Line is wrong" end - Then 'I should see a discussion has started on commit bcf03b5de6c:L185' do + step 'I should see a discussion has started on commit bcf03b5de6c:L185' do page.should have_content "#{current_user.name} started a discussion on commit" page.should have_content "app/assets/stylesheets/tree.scss:L185" page.should have_content "Line is wrong" end - Then 'I should see a discussion has started on commit bcf03b5de6c' do + step 'I should see a discussion has started on commit bcf03b5de6c' do page.should have_content "#{current_user.name} started a discussion on commit bcf03b5de6c" page.should have_content "One comment to rule them all" page.should have_content "app/assets/stylesheets/tree.scss:L185" end + step 'merge request is mergeable' do + page.should have_content 'You can accept this request automatically' + end + + step 'I modify merge commit message' do + find('.modify-merge-commit-link').click + fill_in 'merge_commit_message', with: "wow such merge" + end + + step 'merge request "Bug NS-05" is mergeable' do + merge_request.mark_as_mergeable + end + + step 'I accept this merge request' do + click_button "Accept Merge Request" + end + + step 'I should see merged request' do + within '.page-title' do + page.should have_content "Merged" + end + end + def project - @project ||= Project.find_by_name!("Shop") + @project ||= Project.find_by!(name: "Shop") end def merge_request - @merge_request ||= MergeRequest.find_by_title!("Bug NS-05") + @merge_request ||= MergeRequest.find_by!(title: "Bug NS-05") end def init_diff_note diff --git a/features/steps/project/project_milestones.rb b/features/steps/project/project_milestones.rb index c4d0d176f3a..85962221c0f 100644 --- a/features/steps/project/project_milestones.rb +++ b/features/steps/project/project_milestones.rb @@ -4,7 +4,7 @@ class ProjectMilestones < Spinach::FeatureSteps include SharedPaths Then 'I should see milestone "v2.2"' do - milestone = @project.milestones.find_by_title("v2.2") + milestone = @project.milestones.find_by(title: "v2.2") page.should have_content(milestone.title[0..10]) page.should have_content(milestone.expires_at) page.should have_content("Browse Issues") @@ -24,22 +24,22 @@ class ProjectMilestones < Spinach::FeatureSteps end Then 'I should see milestone "v2.3"' do - milestone = @project.milestones.find_by_title("v2.3") + milestone = @project.milestones.find_by(title: "v2.3") page.should have_content(milestone.title[0..10]) page.should have_content(milestone.expires_at) page.should have_content("Browse Issues") end And 'project "Shop" has milestone "v2.2"' do - project = Project.find_by_name("Shop") + project = Project.find_by(name: "Shop") milestone = create(:milestone, title: "v2.2", project: project) 3.times { create(:issue, project: project, milestone: milestone) } end Given 'the milestone has open and closed issues' do - project = Project.find_by_name("Shop") - milestone = project.milestones.find_by_title('v2.2') + project = Project.find_by(name: "Shop") + milestone = project.milestones.find_by(title: 'v2.2') # 3 Open issues created above; create one closed issue create(:closed_issue, project: project, milestone: milestone) diff --git a/features/steps/project/project_network_graph.rb b/features/steps/project/project_network_graph.rb index 4954db2d7b1..c7d9ece6feb 100644 --- a/features/steps/project/project_network_graph.rb +++ b/features/steps/project/project_network_graph.rb @@ -10,16 +10,16 @@ class ProjectNetworkGraph < Spinach::FeatureSteps # Stub Graph max_size to speed up test (10 commits vs. 650) Network::Graph.stub(max_count: 10) - project = Project.find_by_name("Shop") + project = Project.find_by(name: "Shop") visit project_network_path(project, "master") end And 'page should select "master" in select box' do - page.should have_selector '.chosen-single span', text: "master" + page.should have_selector '.select2-chosen', text: "master" end And 'page should select "v2.1.0" in select box' do - page.should have_selector '.chosen-single span', text: "v2.1.0" + page.should have_selector '.select2-chosen', text: "v2.1.0" end And 'page should have "master" on graph' do @@ -56,11 +56,11 @@ class ProjectNetworkGraph < Spinach::FeatureSteps end And 'page should select "stable" in select box' do - page.should have_selector '.chosen-single span', text: "stable" + page.should have_selector '.select2-chosen', text: "stable" end And 'page should select "v2.1.0" in select box' do - page.should have_selector '.chosen-single span', text: "v2.1.0" + page.should have_selector '.select2-chosen', text: "v2.1.0" end And 'page should have "stable" on graph' do @@ -70,7 +70,7 @@ class ProjectNetworkGraph < Spinach::FeatureSteps end When 'I looking for a commit by SHA of "v2.1.0"' do - within ".content .search" do + within ".network-form" do fill_in 'extended_sha1', with: '98d6492' find('button').click end @@ -84,7 +84,7 @@ class ProjectNetworkGraph < Spinach::FeatureSteps end When 'I look for a commit by ";"' do - within ".content .search" do + within ".network-form" do fill_in 'extended_sha1', with: ';' find('button').click end diff --git a/features/steps/project/project_snippets.rb b/features/steps/project/project_snippets.rb index 5082b31198a..c3a76bea269 100644 --- a/features/steps/project/project_snippets.rb +++ b/features/steps/project/project_snippets.rb @@ -53,7 +53,6 @@ class ProjectSnippets < Spinach::FeatureSteps And 'I submit new snippet "Snippet three"' do fill_in "project_snippet_title", :with => "Snippet three" - select "forever", :from => "project_snippet_expires_at" fill_in "project_snippet_file_name", :with => "my_snippet.rb" within('.file-editor') do find(:xpath, "//input[@id='project_snippet_content']").set 'Content of snippet three' @@ -91,10 +90,10 @@ class ProjectSnippets < Spinach::FeatureSteps end def project - @project ||= Project.find_by_name!("Shop") + @project ||= Project.find_by!(name: "Shop") end def project_snippet - @project_snippet ||= ProjectSnippet.find_by_title!("Snippet One") + @project_snippet ||= ProjectSnippet.find_by!(title: "Snippet one") end end diff --git a/features/steps/project/project_team_management.rb b/features/steps/project/project_team_management.rb index efebba1be24..cde06cadda3 100644 --- a/features/steps/project/project_team_management.rb +++ b/features/steps/project/project_team_management.rb @@ -10,7 +10,7 @@ class ProjectTeamManagement < Spinach::FeatureSteps end And 'I should see "Sam" in team list' do - user = User.find_by_name("Sam") + user = User.find_by(name: "Sam") page.should have_content(user.name) page.should have_content(user.username) end @@ -20,7 +20,7 @@ class ProjectTeamManagement < Spinach::FeatureSteps end And 'I select "Mike" as "Reporter"' do - user = User.find_by_name("Mike") + user = User.find_by(name: "Mike") select2(user.id, from: "#user_ids", multiple: true) within "#new_team_member" do @@ -42,7 +42,7 @@ class ProjectTeamManagement < Spinach::FeatureSteps end And 'I change "Sam" role to "Reporter"' do - user = User.find_by_name("Sam") + user = User.find_by(name: "Sam") within "#user_#{user.id}" do select "Reporter", from: "team_member_project_access" end @@ -59,7 +59,7 @@ class ProjectTeamManagement < Spinach::FeatureSteps end And 'I should not see "Sam" in team list' do - user = User.find_by_name("Sam") + user = User.find_by(name: "Sam") page.should_not have_content(user.name) page.should_not have_content(user.username) end @@ -73,8 +73,8 @@ class ProjectTeamManagement < Spinach::FeatureSteps end And '"Sam" is "Shop" developer' do - user = User.find_by_name("Sam") - project = Project.find_by_name("Shop") + user = User.find_by(name: "Sam") + project = Project.find_by(name: "Shop") project.team << [user, :developer] end @@ -84,8 +84,8 @@ class ProjectTeamManagement < Spinach::FeatureSteps end And '"Mike" is "Website" reporter' do - user = User.find_by_name("Mike") - project = Project.find_by_name("Website") + user = User.find_by(name: "Mike") + project = Project.find_by(name: "Website") project.team << [user, :reporter] end @@ -94,13 +94,13 @@ class ProjectTeamManagement < Spinach::FeatureSteps end When 'I submit "Website" project for import team' do - project = Project.find_by_name("Website") + project = Project.find_by(name: "Website") select project.name_with_namespace, from: 'source_project_id' click_button 'Import' end step 'I click cancel link for "Sam"' do - within "#user_#{User.find_by_name('Sam').id}" do + within "#user_#{User.find_by(name: 'Sam').id}" do click_link('Remove user from team') end end diff --git a/features/steps/project/project_wiki.rb b/features/steps/project/project_wiki.rb index 7aba412d751..6146599cc4a 100644 --- a/features/steps/project/project_wiki.rb +++ b/features/steps/project/project_wiki.rb @@ -25,7 +25,7 @@ class ProjectWiki < Spinach::FeatureSteps page.should have_content "link test" click_link "link test" - page.should have_content "Editing page" + page.should have_content "Editing" end Given 'I have an existing Wiki page' do diff --git a/features/steps/project/redirects.rb b/features/steps/project/redirects.rb index 4ac53075704..896f7180f95 100644 --- a/features/steps/project/redirects.rb +++ b/features/steps/project/redirects.rb @@ -12,7 +12,7 @@ class Spinach::Features::ProjectRedirects < Spinach::FeatureSteps end step 'I visit project "Community" page' do - project = Project.find_by_name('Community') + project = Project.find_by(name: 'Community') visit project_path(project) end @@ -23,12 +23,12 @@ class Spinach::Features::ProjectRedirects < Spinach::FeatureSteps end step 'I visit project "Enterprise" page' do - project = Project.find_by_name('Enterprise') + project = Project.find_by(name: 'Enterprise') visit project_path(project) end step 'I visit project "CommunityDoesNotExist" page' do - project = Project.find_by_name('Community') + project = Project.find_by(name: 'Community') visit project_path(project) + 'DoesNotExist' end end diff --git a/features/steps/public/projects_feature.rb b/features/steps/public/projects_feature.rb index 47e52f47d07..49db9b316be 100644 --- a/features/steps/public/projects_feature.rb +++ b/features/steps/public/projects_feature.rb @@ -33,12 +33,12 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps end step 'I visit empty project page' do - project = Project.find_by_name('Empty Public Project') + project = Project.find_by(name: 'Empty Public Project') visit project_path(project) end step 'I visit project "Community" page' do - project = Project.find_by_name('Community') + project = Project.find_by(name: 'Community') visit project_path(project) end @@ -47,14 +47,14 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps end step 'I should see empty public project details with http clone info' do - project = Project.find_by_name('Empty Public Project') + project = Project.find_by(name: 'Empty Public Project') page.all(:css, '.git-empty .clone').each do |element| element.text.should include(project.http_url_to_repo) end end step 'I should see empty public project details with ssh clone info' do - project = Project.find_by_name('Empty Public Project') + project = Project.find_by(name: 'Empty Public Project') page.all(:css, '.git-empty .clone').each do |element| element.text.should include(project.url_to_repo) end @@ -65,7 +65,7 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps end step 'I visit project "Enterprise" page' do - project = Project.find_by_name('Enterprise') + project = Project.find_by(name: 'Enterprise') visit project_path(project) end @@ -88,7 +88,7 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps end step 'I visit project "Internal" page' do - project = Project.find_by_name('Internal') + project = Project.find_by(name: 'Internal') visit project_path(project) end @@ -99,12 +99,12 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps end step 'I should see an http link to the repository' do - project = Project.find_by_name 'Community' + project = Project.find_by(name: 'Community') page.should have_field('project_clone', with: project.http_url_to_repo) end step 'I should see an ssh link to the repository' do - project = Project.find_by_name 'Community' + project = Project.find_by(name: 'Community') page.should have_field('project_clone', with: project.url_to_repo) end end diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index 987cd3120c9..d287121bb84 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -241,7 +241,7 @@ module SharedPaths end step 'I visit issue page "Release 0.4"' do - issue = Issue.find_by_title("Release 0.4") + issue = Issue.find_by(title: "Release 0.4") visit project_issue_path(issue.project, issue) end @@ -250,12 +250,12 @@ module SharedPaths end step 'I visit merge request page "Bug NS-04"' do - mr = MergeRequest.find_by_title("Bug NS-04") + mr = MergeRequest.find_by(title: "Bug NS-04") visit project_merge_request_path(mr.target_project, mr) end step 'I visit merge request page "Bug NS-05"' do - mr = MergeRequest.find_by_title("Bug NS-05") + mr = MergeRequest.find_by(title: "Bug NS-05") visit project_merge_request_path(mr.target_project, mr) end @@ -292,7 +292,7 @@ module SharedPaths end step 'I visit public page for "Community" project' do - visit public_project_path(Project.find_by_name("Community")) + visit public_project_path(Project.find_by(name: "Community")) end # ---------------------------------------- @@ -316,6 +316,6 @@ module SharedPaths end def project - project = Project.find_by_name!("Shop") + project = Project.find_by!(name: "Shop") end end diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb index 3dc4932a09a..00c289c2329 100644 --- a/features/steps/shared/project.rb +++ b/features/steps/shared/project.rb @@ -9,20 +9,20 @@ module SharedProject # Create a specific project called "Shop" And 'I own project "Shop"' do - @project = Project.find_by_name "Shop" + @project = Project.find_by(name: "Shop") @project ||= create(:project_with_code, name: "Shop", namespace: @user.namespace) @project.team << [@user, :master] end # Create another specific project called "Forum" And 'I own project "Forum"' do - @project = Project.find_by_name "Forum" + @project = Project.find_by(name: "Forum") @project ||= create(:project_with_code, name: "Forum", namespace: @user.namespace, path: 'forum_project') @project.team << [@user, :master] end And 'project "Shop" has push event' do - @project = Project.find_by_name("Shop") + @project = Project.find_by(name: "Shop") data = { before: "0000000000000000000000000000000000000000", @@ -48,7 +48,7 @@ module SharedProject end Then 'I should see project "Shop" activity feed' do - project = Project.find_by_name("Shop") + project = Project.find_by(name: "Shop") page.should have_content "#{@user.name} pushed new branch new_design at #{project.name_with_namespace}" end diff --git a/features/steps/snippets/discover_snippets.rb b/features/steps/snippets/discover_snippets.rb index 3afe019adf6..09337937002 100644 --- a/features/steps/snippets/discover_snippets.rb +++ b/features/steps/snippets/discover_snippets.rb @@ -12,6 +12,6 @@ class DiscoverSnippets < Spinach::FeatureSteps end def snippet - @snippet ||= PersonalSnippet.find_by_title!("Personal snippet one") + @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one") end end diff --git a/features/steps/snippets/snippets.rb b/features/steps/snippets/snippets.rb index 1aea01f6cdf..fed54659ebc 100644 --- a/features/steps/snippets/snippets.rb +++ b/features/steps/snippets/snippets.rb @@ -59,6 +59,6 @@ class SnippetsFeature < Spinach::FeatureSteps end def snippet - @snippet ||= PersonalSnippet.find_by_title!("Personal snippet one") + @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one") end end diff --git a/features/steps/snippets/user_snippets.rb b/features/steps/snippets/user_snippets.rb index 15d6da6db3d..2d7ffc866e7 100644 --- a/features/steps/snippets/user_snippets.rb +++ b/features/steps/snippets/user_snippets.rb @@ -36,6 +36,6 @@ class UserSnippets < Spinach::FeatureSteps end def snippet - @snippet ||= PersonalSnippet.find_by_title!("Personal snippet one") + @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one") end end diff --git a/features/support/env.rb b/features/support/env.rb index 64cdc7f5bf1..0186002c559 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -15,7 +15,7 @@ require 'spinach/capybara' require 'sidekiq/testing/inline' -%w(valid_commit big_commits select2_helper chosen_helper test_env).each do |f| +%w(valid_commit big_commits select2_helper test_env).each do |f| require Rails.root.join('spec', 'support', f) end diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb index b5997608997..7f5a125038c 100644 --- a/lib/api/deploy_keys.rb +++ b/lib/api/deploy_keys.rb @@ -38,14 +38,14 @@ module API attrs[:key].strip! # check if key already exist in project - key = user_project.deploy_keys.find_by_key(attrs[:key]) + key = user_project.deploy_keys.find_by(key: attrs[:key]) if key present key, with: Entities::SSHKey return end # Check for available deploy keys in other projects - key = current_user.accessible_deploy_keys.find_by_key(attrs[:key]) + key = current_user.accessible_deploy_keys.find_by(key: attrs[:key]) if key user_project.deploy_keys << key present key, with: Entities::SSHKey diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 7daf8ace242..4f636fc54a3 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -1,7 +1,7 @@ module API module Entities class User < Grape::Entity - expose :id, :username, :email, :name, :bio, :skype, :linkedin, :twitter, + expose :id, :username, :email, :name, :bio, :skype, :linkedin, :twitter, :website_url, :theme_id, :color_scheme_id, :state, :created_at, :extern_uid, :provider expose :is_admin?, as: :is_admin expose :can_create_group?, as: :can_create_group @@ -48,19 +48,19 @@ module API class ProjectMember < UserBasic expose :project_access, as: :access_level do |user, options| - options[:project].users_projects.find_by_user_id(user.id).project_access + options[:project].users_projects.find_by(user_id: user.id).project_access end end class TeamMember < UserBasic expose :permission, as: :access_level do |user, options| - options[:user_team].user_team_user_relationships.find_by_user_id(user.id).permission + options[:user_team].user_team_user_relationships.find_by(user_id: user.id).permission end end class TeamProject < Project expose :greatest_access, as: :greatest_access_level do |project, options| - options[:user_team].user_team_project_relationships.find_by_project_id(project.id).greatest_access + options[:user_team].user_team_project_relationships.find_by(project_id: project.id).greatest_access end end @@ -74,7 +74,7 @@ module API class GroupMember < UserBasic expose :group_access, as: :access_level do |user, options| - options[:group].users_groups.find_by_user_id(user.id).group_access + options[:group].users_groups.find_by(user_id: user.id).group_access end end @@ -91,6 +91,10 @@ module API expose :id, :short_id, :title, :author_name, :author_email, :created_at end + class RepoCommitDetail < RepoCommit + expose :parent_ids, :committed_date, :authored_date + end + class ProjectSnippet < Grape::Entity expose :id, :title, :file_name expose :author, using: Entities::UserBasic diff --git a/lib/api/files.rb b/lib/api/files.rb index 6a5419a580f..213604915a6 100644 --- a/lib/api/files.rb +++ b/lib/api/files.rb @@ -18,10 +18,10 @@ module API # post ":id/repository/files" do required_attributes! [:file_path, :branch_name, :content, :commit_message] - attrs = attributes_for_keys [:file_path, :branch_name, :content, :commit_message] + attrs = attributes_for_keys [:file_path, :branch_name, :content, :commit_message, :encoding] branch_name = attrs.delete(:branch_name) file_path = attrs.delete(:file_path) - result = ::Files::CreateContext.new(user_project, current_user, attrs, branch_name, file_path).execute + result = ::Files::CreateService.new(user_project, current_user, attrs, branch_name, file_path).execute if result[:status] == :success status(201) @@ -48,10 +48,10 @@ module API # put ":id/repository/files" do required_attributes! [:file_path, :branch_name, :content, :commit_message] - attrs = attributes_for_keys [:file_path, :branch_name, :content, :commit_message] + attrs = attributes_for_keys [:file_path, :branch_name, :content, :commit_message, :encoding] branch_name = attrs.delete(:branch_name) file_path = attrs.delete(:file_path) - result = ::Files::UpdateContext.new(user_project, current_user, attrs, branch_name, file_path).execute + result = ::Files::UpdateService.new(user_project, current_user, attrs, branch_name, file_path).execute if result[:status] == :success status(200) @@ -81,7 +81,7 @@ module API attrs = attributes_for_keys [:file_path, :branch_name, :commit_message] branch_name = attrs.delete(:branch_name) file_path = attrs.delete(:file_path) - result = ::Files::DeleteContext.new(user_project, current_user, attrs, branch_name, file_path).execute + result = ::Files::DeleteService.new(user_project, current_user, attrs, branch_name, file_path).execute if result[:status] == :success status(200) diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 290b78d8017..03f027706de 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -121,11 +121,11 @@ module API render_api_error!("Wrong access level", 422) end group = find_group(params[:id]) - if group.users_groups.find_by_user_id(params[:user_id]) + if group.users_groups.find_by(user_id: params[:user_id]) render_api_error!("Already exists", 409) end group.add_users([params[:user_id]], params[:access_level]) - member = group.users_groups.find_by_user_id(params[:user_id]) + member = group.users_groups.find_by(user_id: params[:user_id]) present member.user, with: Entities::GroupMember, group: group end @@ -139,7 +139,7 @@ module API # DELETE /groups/:id/members/:user_id delete ":id/members/:user_id" do group = find_group(params[:id]) - member = group.users_groups.find_by_user_id(params[:user_id]) + member = group.users_groups.find_by(user_id: params[:user_id]) if member.nil? render_api_error!("404 Not Found - user_id:#{params[:user_id]} not a member of group #{group.name}",404) else diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index b0f8d5a6da9..f8c48e2f3b2 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -7,7 +7,7 @@ module API def current_user private_token = (params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]).to_s - @current_user ||= User.find_by_authentication_token(private_token) + @current_user ||= User.find_by(authentication_token: private_token) identifier = sudo_identifier() # If the sudo is the current user do nothing @@ -47,7 +47,7 @@ module API end def find_project(id) - project = Project.find_by_id(id) || Project.find_with_namespace(id) + project = Project.find_by(id: id) || Project.find_with_namespace(id) if project && can?(current_user, :read_project, project) project diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 3f4bec895bf..cbaf22f265d 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -81,7 +81,7 @@ module API merge_request.target_project = user_project else if target_matches_fork(target_project_id,user_project) - merge_request.target_project = Project.find_by_id(attrs[:target_project_id]) + merge_request.target_project = Project.find_by(id: attrs[:target_project_id]) else render_api_error!('(Bad Request) Specified target project that is not the source project, or the source fork of the project.', 400) end diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb index bee6544ea3d..8e09fff6843 100644 --- a/lib/api/project_snippets.rb +++ b/lib/api/project_snippets.rb @@ -41,7 +41,6 @@ module API # id (required) - The ID 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 # Example Request: # POST /projects/:id/snippets @@ -50,7 +49,6 @@ module API required_attributes! [:title, :file_name, :code] attrs = attributes_for_keys [:title, :file_name] - attrs[:expires_at] = params[:lifetime] if params[:lifetime].present? attrs[:content] = params[:code] if params[:code].present? @snippet = user_project.snippets.new attrs @snippet.author = current_user @@ -69,7 +67,6 @@ module API # 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 - # lifetime (optional) - The expiration date of a snippet # code (optional) - The content of a snippet # Example Request: # PUT /projects/:id/snippets/:snippet_id @@ -78,7 +75,6 @@ module API authorize! :modify_project_snippet, @snippet attrs = attributes_for_keys [:title, :file_name] - attrs[:expires_at] = params[:lifetime] if params[:lifetime].present? attrs[:content] = params[:code] if params[:code].present? if @snippet.update_attributes attrs diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 003533fb59a..888aa7e77d2 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -99,9 +99,10 @@ module API :snippets_enabled, :namespace_id, :public, - :visibility_level] + :visibility_level, + :import_url] attrs = map_public_to_visibility_level(attrs) - @project = ::Projects::CreateContext.new(current_user, attrs).execute + @project = ::Projects::CreateService.new(current_user, attrs).execute if @project.saved? present @project, with: Entities::Project else @@ -142,7 +143,7 @@ module API :public, :visibility_level] attrs = map_public_to_visibility_level(attrs) - @project = ::Projects::CreateContext.new(user, attrs).execute + @project = ::Projects::CreateService.new(user, attrs).execute if @project.saved? present @project, with: Entities::Project else @@ -265,7 +266,7 @@ module API authorize! :admin_project, user_project required_attributes! [:access_level] - team_member = user_project.users_projects.find_by_user_id(params[:user_id]) + team_member = user_project.users_projects.find_by(user_id: params[:user_id]) not_found!("User can not be found") if team_member.nil? if team_member.update_attributes(project_access: params[:access_level]) @@ -285,7 +286,7 @@ module API # DELETE /projects/:id/members/:user_id delete ":id/members/:user_id" do authorize! :admin_project, user_project - team_member = user_project.users_projects.find_by_user_id(params[:user_id]) + team_member = user_project.users_projects.find_by(user_id: params[:user_id]) unless team_member.nil? team_member.destroy else diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb index 6a9dc9a39f1..878929b8032 100644 --- a/lib/api/repositories.rb +++ b/lib/api/repositories.rb @@ -1,3 +1,5 @@ +require 'mime/types' + module API # Projects API class Repositories < Grape::API @@ -49,7 +51,7 @@ module API @branch = user_project.repository.find_branch(params[:branch]) not_found! unless @branch - protected_branch = user_project.protected_branches.find_by_name(@branch.name) + protected_branch = user_project.protected_branches.find_by(name: @branch.name) user_project.protected_branches.create(name: @branch.name) unless protected_branch present @branch, with: Entities::RepoObject, project: user_project @@ -67,7 +69,7 @@ module API @branch = user_project.repository.find_branch(params[:branch]) not_found! unless @branch - protected_branch = user_project.protected_branches.find_by_name(@branch.name) + protected_branch = user_project.protected_branches.find_by(name: @branch.name) protected_branch.destroy if protected_branch present @branch, with: Entities::RepoObject, project: user_project @@ -110,7 +112,7 @@ module API sha = params[:sha] commit = user_project.repository.commit(sha) not_found! "Commit" unless commit - present commit, with: Entities::RepoCommit + present commit, with: Entities::RepoCommitDetail end # Get the diff for a specific commit of a project @@ -122,9 +124,9 @@ module API # GET /projects/:id/repository/commits/:sha/diff get ":id/repository/commits/:sha/diff" do sha = params[:sha] - result = CommitLoadContext.new(user_project, current_user, {id: sha}).execute - not_found! "Commit" unless result[:commit] - result[:commit].diffs + commit = user_project.repository.commit(sha) + not_found! "Commit" unless commit + commit.diffs end # Get a project repository tree @@ -206,18 +208,20 @@ module API # sha (optional) - the commit sha to download defaults to the tip of the default branch # Example Request: # GET /projects/:id/repository/archive - get ":id/repository/archive" do + get ":id/repository/archive", requirements: { format: Gitlab::Regex.archive_formats_regex } do authorize! :download_code, user_project repo = user_project.repository ref = params[:sha] + format = params[:format] storage_path = Rails.root.join("tmp", "repositories") - file_path = repo.archive_repo(ref, storage_path) + file_path = repo.archive_repo(ref, storage_path, format) if file_path && File.exists?(file_path) data = File.open(file_path, 'rb').read - header "Content-Disposition:", " infile; filename=\"#{File.basename(file_path)}\"" - content_type 'application/x-gzip' + header["Content-Disposition"] = "attachment; filename=\"#{File.basename(file_path)}\"" + + content_type MIME::Types.type_for(file_path).first.content_type env['api.format'] = :binary diff --git a/lib/api/users.rb b/lib/api/users.rb index 475343a3edf..ae808b6272b 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -36,6 +36,7 @@ module API # skype - Skype ID # linkedin - Linkedin # twitter - Twitter account + # website_url - Website url # projects_limit - Number of projects user can create # extern_uid - External authentication provider UID # provider - External provider @@ -67,6 +68,7 @@ module API # skype - Skype ID # linkedin - Linkedin # twitter - Twitter account + # website_url - Website url # projects_limit - Limit projects each user can create # extern_uid - External authentication provider UID # provider - External provider @@ -78,7 +80,7 @@ module API put ":id" do authenticated_as_admin! - attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :extern_uid, :provider, :bio, :can_create_group, :admin] + attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :website_url, :projects_limit, :username, :extern_uid, :provider, :bio, :can_create_group, :admin] user = User.find(params[:id]) not_found!("User not found") unless user @@ -117,7 +119,7 @@ module API # DELETE /users/:id delete ":id" do authenticated_as_admin! - user = User.find_by_id(params[:id]) + user = User.find_by(id: params[:id]) if user user.destroy diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb index 0f196297477..955abc1bedd 100644 --- a/lib/gitlab/auth.rb +++ b/lib/gitlab/auth.rb @@ -1,7 +1,7 @@ module Gitlab class Auth def find(login, password) - user = User.find_by_email(login) || User.find_by_username(login) + user = User.find_by(email: login) || User.find_by(username: login) if user.nil? || user.ldap_user? # Second chance - try LDAP authentication diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index c629144118c..60c03ce1c04 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -92,6 +92,9 @@ module Grack return false unless can?(user, action, project) end + # Never let git-receive-pack trough unauthenticated; it's + # harmless but git < 1.8 doesn't like it + return false if user.nil? true else false diff --git a/lib/gitlab/identifier.rb b/lib/gitlab/identifier.rb index a1ff248a77f..6e4de197eeb 100644 --- a/lib/gitlab/identifier.rb +++ b/lib/gitlab/identifier.rb @@ -6,17 +6,17 @@ module Gitlab if identifier.blank? # Local push from gitlab email = project.repository.commit(newrev).author_email rescue nil - User.find_by_email(email) if email + User.find_by(email: email) if email elsif identifier =~ /\Auser-\d+\Z/ # git push over http user_id = identifier.gsub("user-", "") - User.find_by_id(user_id) + User.find_by(id: user_id) elsif identifier =~ /\Akey-\d+\Z/ # git push over ssh key_id = identifier.gsub("key-", "") - Key.find_by_id(key_id).try(:user) + Key.find_by(id: key_id).try(:user) end end end diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb index 59f0fa64a6a..fd36dda7d22 100644 --- a/lib/gitlab/ldap/user.rb +++ b/lib/gitlab/ldap/user.rb @@ -44,13 +44,13 @@ module Gitlab end def find_user(email) - user = model.find_by_email(email) + user = model.find_by(email: email) # If no user found and allow_username_or_email_login is true # we look for user by extracting part of their email if !user && email && ldap_conf['allow_username_or_email_login'] uname = email.partition('@').first - user = model.find_by_username(uname) + user = model.find_by(username: uname) end user diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb index 93e013ab1b3..d18fc8bf2ce 100644 --- a/lib/gitlab/regex.rb +++ b/lib/gitlab/regex.rb @@ -18,6 +18,11 @@ module Gitlab default_regex end + def archive_formats_regex + #|zip|tar| tar.gz | tar.bz2 | + /(zip|tar|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)/ + end + def git_reference_regex # Valid git ref regex, see: # https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html @@ -44,7 +49,7 @@ module Gitlab protected def default_regex - /\A[a-zA-Z0-9][a-zA-Z0-9_\-\.]*(?<!\.git)\z/ + /\A[.?]?[a-zA-Z0-9][a-zA-Z0-9_\-\.]*(?<!\.git)\z/ end end end diff --git a/lib/gitlab/satellite/files/edit_file_action.rb b/lib/gitlab/satellite/files/edit_file_action.rb index f410ecb7984..cbdf70f7d12 100644 --- a/lib/gitlab/satellite/files/edit_file_action.rb +++ b/lib/gitlab/satellite/files/edit_file_action.rb @@ -10,7 +10,7 @@ module Gitlab # Returns false if committing the change fails # Returns false if pushing from the satellite to bare repo failed or was rejected # Returns true otherwise - def commit!(content, commit_message) + def commit!(content, commit_message, encoding) in_locked_and_timed_satellite do |repo| prepare_satellite!(repo) @@ -26,7 +26,8 @@ module Gitlab return false end - File.open(file_path_in_satellite, 'w') { |f| f.write(content) } + # Write file + write_file(file_path_in_satellite, content, encoding) # commit the changes # will raise CommandFailed when commit fails diff --git a/lib/gitlab/satellite/files/file_action.rb b/lib/gitlab/satellite/files/file_action.rb index 0f7afde647d..7701a6d5d60 100644 --- a/lib/gitlab/satellite/files/file_action.rb +++ b/lib/gitlab/satellite/files/file_action.rb @@ -12,6 +12,14 @@ module Gitlab def safe_path?(path) File.absolute_path(path) == path end + + def write_file(abs_file_path, content, file_encoding = 'text') + if file_encoding == 'base64' + File.open(abs_file_path, 'wb') { |f| f.write(Base64.decode64(content)) } + else + File.open(abs_file_path, 'w') { |f| f.write(content) } + end + end end end end diff --git a/lib/gitlab/satellite/files/new_file_action.rb b/lib/gitlab/satellite/files/new_file_action.rb index 57d101ff535..15e9b7a6f77 100644 --- a/lib/gitlab/satellite/files/new_file_action.rb +++ b/lib/gitlab/satellite/files/new_file_action.rb @@ -9,7 +9,7 @@ module Gitlab # Returns false if committing the change fails # Returns false if pushing from the satellite to bare repo failed or was rejected # Returns true otherwise - def commit!(content, commit_message) + def commit!(content, commit_message, encoding) in_locked_and_timed_satellite do |repo| prepare_satellite!(repo) @@ -29,7 +29,7 @@ module Gitlab FileUtils.mkdir_p(dir_name_in_satellite) # Write file - File.open(file_path_in_satellite, 'w') { |f| f.write(content) } + write_file(file_path_in_satellite, content, encoding) # add new file repo.add(file_path_in_satellite) diff --git a/lib/gitlab/satellite/merge_action.rb b/lib/gitlab/satellite/merge_action.rb index 54afd6ab95c..85615f282c4 100644 --- a/lib/gitlab/satellite/merge_action.rb +++ b/lib/gitlab/satellite/merge_action.rb @@ -24,10 +24,10 @@ module Gitlab # Returns false if the merge produced conflicts # Returns false if pushing from the satellite to the repository failed or was rejected # Returns true otherwise - def merge! + def merge!(merge_commit_message = nil) in_locked_and_timed_satellite do |merge_repo| prepare_satellite!(merge_repo) - if merge_in_satellite!(merge_repo) + if merge_in_satellite!(merge_repo, merge_commit_message) # push merge back to bare repo # will raise CommandFailed when push fails merge_repo.git.push(default_options, :origin, merge_request.target_branch) @@ -49,14 +49,7 @@ module Gitlab in_locked_and_timed_satellite do |merge_repo| prepare_satellite!(merge_repo) update_satellite_source_and_target!(merge_repo) - - if merge_request.for_fork? - diff = merge_repo.git.native(:diff, default_options, "origin/#{merge_request.target_branch}", "source/#{merge_request.source_branch}") - else - diff = merge_repo.git.native(:diff, default_options, "#{merge_request.target_branch}", "#{merge_request.source_branch}") - end - - return diff + diff = merge_repo.git.native(:diff, default_options, "origin/#{merge_request.target_branch}", "source/#{merge_request.source_branch}") end rescue Grit::Git::CommandFailed => ex handle_exception(ex) @@ -88,14 +81,7 @@ module Gitlab in_locked_and_timed_satellite do |merge_repo| prepare_satellite!(merge_repo) update_satellite_source_and_target!(merge_repo) - - if (merge_request.for_fork?) - patch = merge_repo.git.format_patch(default_options({stdout: true}), "origin/#{merge_request.target_branch}..source/#{merge_request.source_branch}") - else - patch = merge_repo.git.format_patch(default_options({stdout: true}), "#{merge_request.target_branch}..#{merge_request.source_branch}") - end - - return patch + patch = merge_repo.git.format_patch(default_options({stdout: true}), "origin/#{merge_request.target_branch}..source/#{merge_request.source_branch}") end rescue Grit::Git::CommandFailed => ex handle_exception(ex) @@ -125,34 +111,26 @@ module Gitlab # # Returns false if the merge produced conflicts # Returns true otherwise - def merge_in_satellite!(repo) + def merge_in_satellite!(repo, message = nil) update_satellite_source_and_target!(repo) + message ||= "Merge branch '#{merge_request.source_branch}' into '#{merge_request.target_branch}'" + # merge the source branch into the satellite # will raise CommandFailed when merge fails - if merge_request.for_fork? - repo.git.pull(default_options({no_ff: true}), 'source', merge_request.source_branch) - else - repo.git.pull(default_options({no_ff: true}), 'origin', merge_request.source_branch) - end + repo.git.merge(default_options({no_ff: true}), "-m #{message}", "source/#{merge_request.source_branch}") rescue Grit::Git::CommandFailed => ex handle_exception(ex) end # Assumes a satellite exists that is a fresh clone of the projects repo, prepares satellite for merges, diffs etc def update_satellite_source_and_target!(repo) - if merge_request.for_fork? - repo.remote_add('source', merge_request.source_project.repository.path_to_repo) - repo.remote_fetch('source') - repo.git.checkout(default_options({b: true}), merge_request.target_branch, "origin/#{merge_request.target_branch}") - else - repo.git.checkout(default_options, "#{merge_request.source_branch}") - repo.git.checkout(default_options({t: true}), "origin/#{merge_request.target_branch}") - end + repo.remote_add('source', merge_request.source_project.repository.path_to_repo) + repo.remote_fetch('source') + repo.git.checkout(default_options({b: true}), merge_request.target_branch, "origin/#{merge_request.target_branch}") rescue Grit::Git::CommandFailed => ex handle_exception(ex) end - end end end diff --git a/lib/gitlab/theme.rb b/lib/gitlab/theme.rb index 89604162304..44237a062fc 100644 --- a/lib/gitlab/theme.rb +++ b/lib/gitlab/theme.rb @@ -15,7 +15,7 @@ module Gitlab COLOR => "ui_color" } - id ||= 1 + id ||= Gitlab.config.gitlab.default_theme return themes[id] end diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab index f1b94087b6a..cb2db44c97c 100755 --- a/lib/support/init.d/gitlab +++ b/lib/support/init.d/gitlab @@ -20,7 +20,7 @@ # DO NOT EDIT THIS FILE! # This file will be overwritten on update. # Instead add/change your variables in /etc/default/gitlab -# An example defaults file can be found in lib/support/default/gitlab +# An example defaults file can be found in lib/support/init.d/gitlab.default.example ### diff --git a/lib/support/init.d/gitlab.default.example b/lib/support/init.d/gitlab.default.example index 4230783a9d7..9951bacedf5 100755 --- a/lib/support/init.d/gitlab.default.example +++ b/lib/support/init.d/gitlab.default.example @@ -12,3 +12,20 @@ app_user="git" # app_root defines the folder in which gitlab and it's components are installed. # The default is "/home/$app_user/gitlab" app_root="/home/$app_user/gitlab" + +# pid_path defines a folder in which the gitlab and it's components place their pids. +# This variable is also used below to define the relevant pids for the gitlab components. +# The default is "$app_root/tmp/pids" +pid_path="$app_root/tmp/pids" + +# socket_path defines the folder in which gitlab places the sockets +#The default is "$app_root/tmp/sockets" +socket_path="$app_root/tmp/sockets" + +# web_server_pid_path defines the path in which to create the pid file fo the web_server +# The default is "$pid_path/unicorn.pid" +web_server_pid_path="$pid_path/unicorn.pid" + +# sidekiq_pid_path defines the path in which to create the pid file for sidekiq +# The default is "$pid_path/sidekiq.pid" +sidekiq_pid_path="$pid_path/sidekiq.pid" diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index 9f5155b3916..d1d959e152e 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -28,8 +28,8 @@ server { # if a file, which is not found in the root folder is requested, # then the proxy pass the request to the upsteam (gitlab unicorn) location @gitlab { - proxy_read_timeout 300; # https://github.com/gitlabhq/gitlabhq/issues/694 - proxy_connect_timeout 300; # https://github.com/gitlabhq/gitlabhq/issues/694 + proxy_read_timeout 300; # Some requests take more than 30 seconds. + proxy_connect_timeout 300; # Some requests take more than 30 seconds. proxy_redirect off; proxy_set_header X-Forwarded-Proto $scheme; diff --git a/lib/tasks/gitlab/bulk_add_permission.rake b/lib/tasks/gitlab/bulk_add_permission.rake index c270232edba..612a9ba93a8 100644 --- a/lib/tasks/gitlab/bulk_add_permission.rake +++ b/lib/tasks/gitlab/bulk_add_permission.rake @@ -15,7 +15,7 @@ namespace :gitlab do desc "GITLAB | Add a specific user to all projects (as a developer)" task :user_to_projects, [:email] => :environment do |t, args| - user = User.find_by_email args.email + user = User.find_by(email: args.email) project_ids = Project.pluck(:id) puts "Importing #{user.email} users into #{project_ids.size} projects" UsersProject.add_users_into_projects(project_ids, Array.wrap(user.id), UsersProject::DEVELOPER) diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake index 20d5f03d6ef..f48d26433c0 100644 --- a/lib/tasks/gitlab/check.rake +++ b/lib/tasks/gitlab/check.rake @@ -682,6 +682,8 @@ namespace :gitlab do namespace :ldap do task :check, [:limit] => :environment do |t, args| + # Only show up to 100 results because LDAP directories can be very big. + # This setting only affects the `rake gitlab:check` script. args.with_defaults(limit: 100) warn_user_is_not_gitlab start_checking "LDAP" @@ -696,7 +698,7 @@ namespace :gitlab do end def print_users(limit) - puts "LDAP users with access to your GitLab server (limit: #{limit}):" + puts "LDAP users with access to your GitLab server (only showing the first #{limit} results)" ldap.search(attributes: attributes, filter: filter, size: limit, return_result: false) do |entry| puts "DN: #{entry.dn}\t#{ldap_config.uid}: #{entry[ldap_config.uid]}" end diff --git a/lib/tasks/gitlab/enable_namespaces.rake b/lib/tasks/gitlab/enable_namespaces.rake index 927748c0fd5..201f34ab546 100644 --- a/lib/tasks/gitlab/enable_namespaces.rake +++ b/lib/tasks/gitlab/enable_namespaces.rake @@ -43,13 +43,13 @@ namespace :gitlab do username.gsub!("+", ".") # return username if no matches - return username unless User.find_by_username(username) + return username unless User.find_by(username: username) # look for same username (1..10).each do |i| suffixed_username = "#{username}#{i}" - return suffixed_username unless User.find_by_username(suffixed_username) + return suffixed_username unless User.find_by(username: suffixed_username) end end diff --git a/lib/tasks/gitlab/import.rake b/lib/tasks/gitlab/import.rake index 8fa89270854..cbfa736c84c 100644 --- a/lib/tasks/gitlab/import.rake +++ b/lib/tasks/gitlab/import.rake @@ -2,12 +2,12 @@ namespace :gitlab do namespace :import do # How to use: # - # 1. copy your bare repos under git repos_path - # 2. run bundle exec rake gitlab:import:repos RAILS_ENV=production + # 1. copy the bare repos under the repos_path (commonly /home/git/repositories) + # 2. run: bundle exec rake gitlab:import:repos RAILS_ENV=production # # Notes: - # * project owner will be a first admin - # * existing projects will be skipped + # * The project owner will set to the first administator of the system + # * Existing projects will be skipped # desc "GITLAB | Import bare repositories from gitlab_shell -> repos_path into GitLab project instance" task repos: :environment do @@ -50,7 +50,7 @@ namespace :gitlab do # find group namespace if group_name - group = Group.find_by_path(group_name) + group = Group.find_by(path: group_name) # create group namespace if !group group = Group.new(:name => group_name) @@ -66,7 +66,7 @@ namespace :gitlab do project_params[:namespace_id] = group.id end - project = Projects::CreateContext.new(user, project_params).execute + project = Projects::CreateService.new(user, project_params).execute if project.valid? puts " * Created #{project.name} (#{repo_path})".green diff --git a/spec/contexts/issues/list_context_spec.rb b/spec/contexts/issues/list_context_spec.rb deleted file mode 100644 index 70ce956499c..00000000000 --- a/spec/contexts/issues/list_context_spec.rb +++ /dev/null @@ -1,73 +0,0 @@ -require 'spec_helper' - -describe Issues::ListContext do - - let(:user) { create(:user) } - let(:project) { create(:project, creator: user) } - - titles = ['foo','bar','baz'] - titles.each_with_index do |title, index| - let!(title.to_sym) { create(:issue, title: title, project: project, created_at: Time.now - (index * 60)) } - end - - describe 'sorting' do - it 'sorts by newest' do - params = {sort: 'newest'} - - issues = Issues::ListContext.new(project, user, params).execute - issues.first.should eq foo - end - - it 'sorts by oldest' do - params = {sort: 'oldest'} - - issues = Issues::ListContext.new(project, user, params).execute - issues.first.should eq baz - end - - it 'sorts by recently updated' do - params = {sort: 'recently_updated'} - baz.updated_at = Time.now + 10 - baz.save - - issues = Issues::ListContext.new(project, user, params).execute - issues.first.should eq baz - end - - it 'sorts by least recently updated' do - params = {sort: 'last_updated'} - bar.updated_at = Time.now - 10 - bar.save - - issues = Issues::ListContext.new(project, user, params).execute - issues.first.should eq bar - end - - describe 'sorting by milestone' do - let(:newer_due_milestone) { create(:milestone, due_date: '2013-12-11') } - let(:later_due_milestone) { create(:milestone, due_date: '2013-12-12') } - - before :each do - foo.milestone = newer_due_milestone - foo.save - bar.milestone = later_due_milestone - bar.save - end - - it 'sorts by most recently due milestone' do - params = {sort: 'milestone_due_soon'} - - issues = Issues::ListContext.new(project, user, params).execute - issues.first.should eq foo - - end - - it 'sorts by least recently due milestone' do - params = {sort: 'milestone_due_later'} - - issues = Issues::ListContext.new(project, user, params).execute - issues.first.should eq bar - end - end - end -end diff --git a/spec/controllers/merge_requests_controller_spec.rb b/spec/controllers/merge_requests_controller_spec.rb index 69708edd8b1..f237f358452 100644 --- a/spec/controllers/merge_requests_controller_spec.rb +++ b/spec/controllers/merge_requests_controller_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Projects::MergeRequestsController do let(:project) { create(:project_with_code) } let(:user) { create(:user) } - let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project, target_branch: "bcf03b5d~3", source_branch: "bcf03b5d") } + let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project, target_branch: "stable", source_branch: "master") } before do sign_in(user) @@ -61,7 +61,7 @@ describe Projects::MergeRequestsController do it "should really be a git email patch with commit" do get :show, project_id: project.to_param, id: merge_request.iid, format: format - expect(response.body[0..100]).to start_with("From #{merge_request.commits.last.id}") + expect(response.body[0..100]).to start_with("From 6ea87c47f0f8a24ae031c3fff17bc913889ecd00") end it "should contain git diffs" do diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index 538a6ee9fc9..1d225e8bad0 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -222,8 +222,6 @@ describe "Issues" do it 'with dropdown menu' do visit project_issue_path(project, issue) - p find('.edit-issue.inline-update').text - find('.edit-issue.inline-update').select(milestone.title, from: 'issue_milestone_id') click_button 'Update Issue' diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb index f92d479d02f..b534548a122 100644 --- a/spec/features/notes_on_merge_requests_spec.rb +++ b/spec/features/notes_on_merge_requests_spec.rb @@ -159,13 +159,14 @@ describe "On a merge request diff", js: true, focus: true do end describe "the note form" do - it 'should be valid' do - within(".js-temp-notes-holder") { find("#note_noteable_type").value.should == "MergeRequest" } - within(".js-temp-notes-holder") { find("#note_noteable_id").value.should == merge_request.id.to_s } - within(".js-temp-notes-holder") { find("#note_commit_id").value.should == "" } - within(".js-temp-notes-holder") { find("#note_line_code").value.should == "4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185" } - should have_css(".js-close-discussion-note-form", text: "Cancel") - end + # FIXME + #it 'should be valid' do + #within(".js-temp-notes-holder") { find("#note_noteable_type").value.should == "MergeRequest" } + #within(".js-temp-notes-holder") { find("#note_noteable_id").value.should == merge_request.id.to_s } + #within(".js-temp-notes-holder") { find("#note_commit_id").value.should == "" } + #within(".js-temp-notes-holder") { find("#note_line_code").value.should == "4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185" } + #should have_css(".js-close-discussion-note-form", text: "Cancel") + #end it "shouldn't add a second form for same row" do find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185"]').click diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb index 33ecb980202..d04945dfe35 100644 --- a/spec/helpers/search_helper_spec.rb +++ b/spec/helpers/search_helper_spec.rb @@ -13,52 +13,41 @@ describe SearchHelper do end it "it returns nil" do - search_autocomplete_source.should be_nil + search_autocomplete_opts("q").should be_nil end end context "with a user" do let(:user) { create(:user) } - let(:result) { JSON.parse(search_autocomplete_source) } before do allow(self).to receive(:current_user).and_return(user) end it "includes Help sections" do - result.select { |h| h['label'] =~ /^help:/ }.length.should == 9 + search_autocomplete_opts("hel").size.should == 9 end it "includes default sections" do - result.count { |h| h['label'] =~ /^(My|Admin)\s/ }.should == 4 + search_autocomplete_opts("adm").size.should == 1 end it "includes the user's groups" do create(:group).add_owner(user) - result.count { |h| h['label'] =~ /^group:/ }.should == 1 + search_autocomplete_opts("gro").size.should == 1 end it "includes the user's projects" do - create(:project, namespace: create(:namespace, owner: user)) - result.count { |h| h['label'] =~ /^project:/ }.should == 1 + project = create(:project, namespace: create(:namespace, owner: user)) + search_autocomplete_opts(project.name).size.should == 1 end context "with a current project" do before { @project = create(:project_with_code) } it "includes project-specific sections" do - result.count { |h| h['label'] =~ /^#{@project.name_with_namespace} - / }.should == 11 - end - - it "uses @ref in urls if defined" do - @ref = "foo_bar" - result.count { |h| h['url'] == project_tree_path(@project, @ref) }.should == 1 - end - end - - context "with no current project" do - it "does not include project-specific sections" do - result.count { |h| h['label'] =~ /Files$/ }.should == 0 + search_autocomplete_opts("Files").size.should == 1 + search_autocomplete_opts("Commits").size.should == 1 end end end diff --git a/spec/lib/gitlab/ldap/ldap_user_auth_spec.rb b/spec/lib/gitlab/ldap/ldap_user_auth_spec.rb index b7d7bbaad2e..a0e74c49631 100644 --- a/spec/lib/gitlab/ldap/ldap_user_auth_spec.rb +++ b/spec/lib/gitlab/ldap/ldap_user_auth_spec.rb @@ -25,7 +25,7 @@ describe Gitlab::LDAP do it "should update credentials by email if missing uid" do user = double('User') User.stub find_by_extern_uid_and_provider: nil - User.stub find_by_email: user + User.stub(:find_by).with(hash_including(email: anything())) { user } user.should_receive :update_attributes gl_auth.find_or_create(@auth) end @@ -35,8 +35,8 @@ describe Gitlab::LDAP do value = Gitlab.config.ldap.allow_username_or_email_login Gitlab.config.ldap['allow_username_or_email_login'] = true User.stub find_by_extern_uid_and_provider: nil - User.stub find_by_email: nil - User.stub find_by_username: user + User.stub(:find_by).with(hash_including(email: anything())) { nil } + User.stub(:find_by).with(hash_including(username: anything())) { user } user.should_receive :update_attributes gl_auth.find_or_create(@auth) Gitlab.config.ldap['allow_username_or_email_login'] = value @@ -47,8 +47,8 @@ describe Gitlab::LDAP do value = Gitlab.config.ldap.allow_username_or_email_login Gitlab.config.ldap['allow_username_or_email_login'] = false User.stub find_by_extern_uid_and_provider: nil - User.stub find_by_email: nil - User.stub find_by_username: user + User.stub(:find_by).with(hash_including(email: anything())) { nil } + User.stub(:find_by).with(hash_including(username: anything())) { user } user.should_not_receive :update_attributes gl_auth.find_or_create(@auth) Gitlab.config.ldap['allow_username_or_email_login'] = value diff --git a/spec/lib/gitlab/satellite/merge_action_spec.rb b/spec/lib/gitlab/satellite/merge_action_spec.rb index e40ff73b7f0..d2f026f96e8 100644 --- a/spec/lib/gitlab/satellite/merge_action_spec.rb +++ b/spec/lib/gitlab/satellite/merge_action_spec.rb @@ -2,13 +2,12 @@ require 'spec_helper' describe 'Gitlab::Satellite::MergeAction' do before(:each) do -# TestEnv.init(mailer: false, init_repos: true, repos: true) @master = ['master', 'b1e6a9dbf1c85e6616497a5e7bad9143a4bd0828'] @one_after_stable = ['stable', '6ea87c47f0f8a24ae031c3fff17bc913889ecd00'] #this commit sha is one after stable @wiki_branch = ['wiki', '635d3e09b72232b6e92a38de6cc184147e5bcb41'] #this is the commit sha where the wiki branch goes off from master @conflicting_metior = ['metior', '313d96e42b313a0af5ab50fa233bf43e27118b3f'] #this branch conflicts with the wiki branch - #these commits are quite close together, itended to make string diffs/format patches small + # these commits are quite close together, itended to make string diffs/format patches small @close_commit1 = ['2_3_notes_fix', '8470d70da67355c9c009e4401746b1d5410af2e3'] @close_commit2 = ['scss_refactoring', 'f0f14c8eaba69ebddd766498a9d0b0e79becd633'] end @@ -16,6 +15,7 @@ describe 'Gitlab::Satellite::MergeAction' do let(:project) { create(:project_with_code) } let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } let(:merge_request_fork) { create(:merge_request) } + describe '#commits_between' do def verify_commits(commits, first_commit_sha, last_commit_sha) commits.each { |commit| commit.class.should == Gitlab::Git::Commit } @@ -145,4 +145,4 @@ describe 'Gitlab::Satellite::MergeAction' do end end end -end
\ No newline at end of file +end diff --git a/spec/models/forked_project_link_spec.rb b/spec/models/forked_project_link_spec.rb index 472ddf1b59d..e719e3bfcc8 100644 --- a/spec/models/forked_project_link_spec.rb +++ b/spec/models/forked_project_link_spec.rb @@ -58,7 +58,7 @@ describe :forked_from_project do end def fork_project(from_project, user) - context = Projects::ForkContext.new(from_project, user) + context = Projects::ForkService.new(from_project, user) shell = double("gitlab_shell") shell.stub(fork_repository: true) context.stub(gitlab_shell: shell) diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index 55b264ce8cf..b86603dd4ac 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -180,6 +180,31 @@ describe Note do end end + describe '#create_assignee_change_note' do + let(:project) { create(:project) } + let(:thing) { create(:issue, project: project) } + let(:author) { create(:user) } + let(:assignee) { create(:user) } + + subject { Note.create_assignee_change_note(thing, project, author, assignee) } + + context 'creates and saves a Note' do + it { should be_a Note } + its(:id) { should_not be_nil } + end + + its(:noteable) { should == thing } + its(:project) { should == thing.project } + its(:author) { should == author } + its(:note) { should =~ /Reassigned to @#{assignee.username}/ } + + context 'assignee is removed' do + let(:assignee) { nil } + + its(:note) { should =~ /Assignee removed/ } + end + end + describe '#create_cross_reference_note' do let(:project) { create(:project_with_code) } let(:author) { create(:user) } @@ -252,6 +277,7 @@ describe Note do let(:issue) { create(:issue, project: project) } let(:other) { create(:issue, project: project) } let(:author) { create(:user) } + let(:assignee) { create(:user) } it 'should recognize user-supplied notes as non-system' do @note = create(:note_on_issue) @@ -267,6 +293,11 @@ describe Note do @note = Note.create_cross_reference_note(issue, other, author, project) @note.should be_system end + + it 'should identify assignee-change notes as system notes' do + @note = Note.create_assignee_change_note(issue, project, author, assignee) + @note.should be_system + end end describe :authorization do diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 8aa4c7fed1a..373accfe412 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -99,6 +99,11 @@ describe Project do project.web_url.should == "#{Gitlab.config.gitlab.url}/somewhere" end + it "returns the web URL without the protocol for this repo" do + project = Project.new(path: "somewhere") + project.web_url_without_protocol.should == "#{Gitlab.config.gitlab.host}/somewhere" + end + describe "last_activity methods" do let(:project) { create(:project) } let(:last_event) { double(created_at: Time.now) } diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 94bd19f5900..5e53ed09b58 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -41,6 +41,8 @@ # confirmed_at :datetime # confirmation_sent_at :datetime # unconfirmed_email :string(255) +# hide_no_ssh_key :boolean default(FALSE) +# website_url :string(255) default(""), not null # require 'spec_helper' @@ -74,6 +76,27 @@ describe User do it { should_not allow_value(-1).for(:projects_limit) } it { should ensure_length_of(:bio).is_within(0..255) } + + describe 'email' do + it 'accepts info@example.com' do + user = build(:user, email: 'info@example.com') + expect(user).to be_valid + end + it 'accepts info+test@example.com' do + user = build(:user, email: 'info+test@example.com') + expect(user).to be_valid + end + + it 'rejects test@test@example.com' do + user = build(:user, email: 'test@test@example.com') + expect(user).to be_invalid + end + + it 'rejects mailto:test@example.com' do + user = build(:user, email: 'mailto:test@example.com') + expect(user).to be_invalid + end + end end describe "Respond to" do @@ -293,4 +316,48 @@ describe User do user.avatar_type.should == ["only images allowed"] end end + + describe '#full_website_url' do + let(:user) { create(:user) } + + it 'begins with http if website url omits it' do + user.website_url = 'test.com' + + expect(user.full_website_url).to eq 'http://test.com' + end + + it 'begins with http if website url begins with http' do + user.website_url = 'http://test.com' + + expect(user.full_website_url).to eq 'http://test.com' + end + + it 'begins with https if website url begins with https' do + user.website_url = 'https://test.com' + + expect(user.full_website_url).to eq 'https://test.com' + end + end + + describe '#short_website_url' do + let(:user) { create(:user) } + + it 'does not begin with http if website url omits it' do + user.website_url = 'test.com' + + expect(user.short_website_url).to eq 'test.com' + end + + it 'does not begin with http if website url begins with http' do + user.website_url = 'http://test.com' + + expect(user.short_website_url).to eq 'test.com' + end + + it 'does not begin with https if website url begins with https' do + user.website_url = 'https://test.com' + + expect(user.short_website_url).to eq 'test.com' + end + end end diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb index e078efcc50a..f73ac4372b2 100644 --- a/spec/requests/api/repositories_spec.rb +++ b/spec/requests/api/repositories_spec.rb @@ -1,4 +1,5 @@ require 'spec_helper' +require 'mime/types' describe API::API do include ApiHelpers @@ -232,11 +233,29 @@ describe API::API do end end - describe "GET /projects/:id/repository/archive/:sha" do + describe "GET /projects/:id/repository/archive(.:format)?:sha" do it "should get the archive" do get api("/projects/#{project.id}/repository/archive", user) + repo_name = project.repository.name.gsub("\.git", "") response.status.should == 200 - response.content_type.should == 'application/x-gzip' + response.headers['Content-Disposition'].should =~ /filename\=\"#{repo_name}\-[^\.]+\.tar.gz\"/ + response.content_type.should == MIME::Types.type_for('file.tar.gz').first.content_type + end + + it "should get the archive.zip" do + get api("/projects/#{project.id}/repository/archive.zip", user) + repo_name = project.repository.name.gsub("\.git", "") + response.status.should == 200 + response.headers['Content-Disposition'].should =~ /filename\=\"#{repo_name}\-[^\.]+\.zip\"/ + response.content_type.should == MIME::Types.type_for('file.zip').first.content_type + end + + it "should get the archive.tar.bz2" do + get api("/projects/#{project.id}/repository/archive.tar.bz2", user) + repo_name = project.repository.name.gsub("\.git", "") + response.status.should == 200 + response.headers['Content-Disposition'].should =~ /filename\=\"#{repo_name}\-[^\.]+\.tar.bz2\"/ + response.content_type.should == MIME::Types.type_for('file.tar.bz2').first.content_type end it "should return 404 for invalid sha" do diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index 4ef78b8e5d0..c4be5102002 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -93,7 +93,7 @@ describe API::API do expect { post api("/users", admin), attr }.to change { User.count }.by(1) - user = User.find_by_username(attr[:username]) + user = User.find_by(username: attr[:username]) user.projects_limit.should == limit user.theme_id.should == Gitlab::Theme::MARS Gitlab.config.gitlab.unstub(:default_projects_limit) diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index 5597f08d186..97f7392e50a 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -130,6 +130,14 @@ describe Projects::RepositoriesController, "routing" do get("/gitlab/gitlabhq/repository/archive").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq') end + it "to #archive format:zip" do + get("/gitlab/gitlabhq/repository/archive.zip").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq', format: 'zip') + end + + it "to #archive format:tar.bz2" do + get("/gitlab/gitlabhq/repository/archive.tar.bz2").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq', format: 'tar.bz2') + end + it "to #show" do get("/gitlab/gitlabhq/repository").should route_to('projects/repositories#show', project_id: 'gitlab/gitlabhq') end diff --git a/spec/contexts/filter_context_spec.rb b/spec/services/filtering_service_spec.rb index 06aef5d7ed1..596601264b3 100644 --- a/spec/contexts/filter_context_spec.rb +++ b/spec/services/filtering_service_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe FilterContext do +describe FilteringService do let(:user) { create :user } let(:user2) { create :user } let(:project1) { create(:project) } @@ -25,14 +25,14 @@ describe FilterContext do end it 'should filter by scope' do - params = { scope: 'authored' } - merge_requests = FilterContext.new(MergeRequest, user, params).execute + params = { scope: 'authored', state: 'opened' } + merge_requests = FilteringService.new.execute(MergeRequest, user, params) merge_requests.size.should == 3 end it 'should filter by project' do - params = { project_id: project1.id, scope: 'authored' } - merge_requests = FilterContext.new(MergeRequest, user, params).execute + params = { project_id: project1.id, scope: 'authored', state: 'opened' } + merge_requests = FilteringService.new.execute(MergeRequest, user, params) merge_requests.size.should == 1 end end @@ -45,20 +45,20 @@ describe FilterContext do end it 'should filter by all' do - params = { scope: "all" } - issues = FilterContext.new(Issue, user, params).execute + params = { scope: "all", state: 'opened' } + issues = FilteringService.new.execute(Issue, user, params) issues.size.should == 3 end it 'should filter by assignee' do - params = {} - issues = FilterContext.new(Issue, user, params).execute + params = { scope: "assigned-to-me", state: 'opened' } + issues = FilteringService.new.execute(Issue, user, params) issues.size.should == 2 end it 'should filter by project' do - params = { project_id: project1.id } - issues = FilterContext.new(Issue, user, params).execute + params = { scope: "assigned-to-me", state: 'opened', project_id: project1.id } + issues = FilteringService.new.execute(Issue, user, params) issues.size.should == 1 end end diff --git a/spec/contexts/fork_context_spec.rb b/spec/services/fork_service_spec.rb index 70f650bc83d..b6573095dbd 100644 --- a/spec/contexts/fork_context_spec.rb +++ b/spec/services/fork_service_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Projects::ForkContext do +describe Projects::ForkService do describe :fork_by_user do before do @from_namespace = create(:namespace) @@ -47,7 +47,7 @@ describe Projects::ForkContext do end def fork_project(from_project, user, fork_success = true) - context = Projects::ForkContext.new(from_project, user) + context = Projects::ForkService.new(from_project, user) shell = double("gitlab_shell") shell.stub(fork_repository: fork_success) context.stub(gitlab_shell: shell) diff --git a/spec/contexts/issues/bulk_update_context_spec.rb b/spec/services/issues/bulk_update_context_spec.rb index 058e43ba090..548109a8450 100644 --- a/spec/contexts/issues/bulk_update_context_spec.rb +++ b/spec/services/issues/bulk_update_context_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Issues::BulkUpdateContext do +describe Issues::BulkUpdateService do before(:each) { ActiveRecord::Base.observers.enable(:user_observer) } after(:each) { ActiveRecord::Base.observers.disable(:user_observer) } @@ -14,7 +14,7 @@ describe Issues::BulkUpdateContext do name: "GitLab", namespace: @user.namespace } - @project = Projects::CreateContext.new(@user, opts).execute + @project = Projects::CreateService.new(@user, opts).execute end describe :close_issue do @@ -32,7 +32,7 @@ describe Issues::BulkUpdateContext do end it { - result = Issues::BulkUpdateContext.new(@project, @user, @params).execute + result = Issues::BulkUpdateService.new(@project, @user, @params).execute result[:success].should be_true result[:count].should == @issues.count @@ -57,7 +57,7 @@ describe Issues::BulkUpdateContext do end it { - result = Issues::BulkUpdateContext.new(@project, @user, @params).execute + result = Issues::BulkUpdateService.new(@project, @user, @params).execute result[:success].should be_true result[:count].should == @issues.count @@ -80,7 +80,7 @@ describe Issues::BulkUpdateContext do end it { - result = Issues::BulkUpdateContext.new(@project, @user, @params).execute + result = Issues::BulkUpdateService.new(@project, @user, @params).execute result[:success].should be_true result[:count].should == 1 @@ -102,7 +102,7 @@ describe Issues::BulkUpdateContext do end it { - result = Issues::BulkUpdateContext.new(@project, @user, @params).execute + result = Issues::BulkUpdateService.new(@project, @user, @params).execute result[:success].should be_true result[:count].should == 1 diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index a112835d4d0..09a5debe1dc 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -233,6 +233,31 @@ describe NotificationService do end end + describe 'Projects' do + let(:project) { create :project } + + before do + build_team(project) + end + + describe :project_was_moved do + it do + should_email(@u_watcher.id) + should_email(@u_participating.id) + should_not_email(@u_disabled.id) + notification.project_was_moved(project) + end + + def should_email(user_id) + Notify.should_receive(:project_was_moved_email).with(project.id, user_id) + end + + def should_not_email(user_id) + Notify.should_not_receive(:project_was_moved_email).with(project.id, user_id) + end + end + end + def build_team(project) @u_watcher = create(:user, notification_level: Notification::N_WATCH) @u_participating = create(:user, notification_level: Notification::N_PARTICIPATING) diff --git a/spec/contexts/projects_create_context_spec.rb b/spec/services/projects_create_service_spec.rb index d5b1cb83510..0a41832a211 100644 --- a/spec/contexts/projects_create_context_spec.rb +++ b/spec/services/projects_create_service_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Projects::CreateContext do +describe Projects::CreateService do before(:each) { ActiveRecord::Base.observers.enable(:user_observer) } after(:each) { ActiveRecord::Base.observers.disable(:user_observer) } @@ -136,7 +136,7 @@ describe Projects::CreateContext do end def create_project(user, opts) - Projects::CreateContext.new(user, opts).execute + Projects::CreateService.new(user, opts).execute end end diff --git a/spec/contexts/projects_update_context_spec.rb b/spec/services/projects_update_service_spec.rb index edcaf844e5d..1854c0d8233 100644 --- a/spec/contexts/projects_update_context_spec.rb +++ b/spec/services/projects_update_service_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Projects::UpdateContext do +describe Projects::UpdateService do before(:each) { ActiveRecord::Base.observers.enable(:user_observer) } after(:each) { ActiveRecord::Base.observers.disable(:user_observer) } @@ -106,6 +106,6 @@ describe Projects::UpdateContext do end def update_project(project, user, opts) - Projects::UpdateContext.new(project, user, opts).execute + Projects::UpdateService.new(project, user, opts).execute end -end
\ No newline at end of file +end diff --git a/spec/contexts/search_context_spec.rb b/spec/services/search_service_spec.rb index c25743e0032..457cb3c0ca3 100644 --- a/spec/contexts/search_context_spec.rb +++ b/spec/services/search_service_spec.rb @@ -1,43 +1,54 @@ require 'spec_helper' -describe SearchContext do +describe 'Search::GlobalService' do let(:found_namespace) { create(:namespace, name: 'searchable namespace', path:'another_thing') } let(:user) { create(:user, namespace: found_namespace) } let!(:found_project) { create(:project, name: 'searchable_project', creator_id: user.id, namespace: found_namespace, visibility_level: Gitlab::VisibilityLevel::PRIVATE) } let(:unfound_namespace) { create(:namespace, name: 'unfound namespace', path: 'yet_something_else') } let!(:unfound_project) { create(:project, name: 'unfound_project', creator_id: user.id, namespace: unfound_namespace, visibility_level: Gitlab::VisibilityLevel::PRIVATE) } - + let(:internal_namespace) { create(:namespace, path: 'something_internal',name: 'searchable internal namespace') } let(:internal_user) { create(:user, namespace: internal_namespace) } let!(:internal_project) { create(:project, name: 'searchable_internal_project', creator_id: internal_user.id, namespace: internal_namespace, visibility_level: Gitlab::VisibilityLevel::INTERNAL) } - + let(:public_namespace) { create(:namespace, path: 'something_public',name: 'searchable public namespace') } let(:public_user) { create(:user, namespace: public_namespace) } let!(:public_project) { create(:project, name: 'searchable_public_project', creator_id: public_user.id, namespace: public_namespace, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } describe '#execute' do - it 'public projects should be searchable' do - context = SearchContext.new([found_project.id], nil, {search_code: false, search: "searchable"}) - results = context.execute - results[:projects].should == [found_project, public_project] + context 'unauthenticated' do + it 'should return public projects only' do + context = Search::GlobalService.new(nil, search: "searchable") + results = context.execute + results[:projects].should have(1).items + results[:projects].should include(public_project) + end end - it 'internal projects should be searchable' do - context = SearchContext.new([found_project.id], user, {search_code: false, search: "searchable"}) - results = context.execute - # can't seem to rely on the return order, so check this way - #subject { results[:projects] } - results[:projects].should have(3).items - results[:projects].should include(found_project) - results[:projects].should include(internal_project) - results[:projects].should include(public_project) - end + context 'authenticated' do + it 'should return public, internal and private projects' do + context = Search::GlobalService.new(user, search: "searchable") + results = context.execute + results[:projects].should have(3).items + results[:projects].should include(public_project) + results[:projects].should include(found_project) + results[:projects].should include(internal_project) + end + + it 'should return only public & internal projects' do + context = Search::GlobalService.new(internal_user, search: "searchable") + results = context.execute + results[:projects].should have(2).items + results[:projects].should include(internal_project) + results[:projects].should include(public_project) + end - it 'namespace name should be searchable' do - context = SearchContext.new([found_project.id], user, {search_code: false, search: "searchable namespace"}) - results = context.execute - results[:projects].should == [found_project] + it 'namespace name should be searchable' do + context = Search::GlobalService.new(user, search: "searchable namespace") + results = context.execute + results[:projects].should == [found_project] + end end end end diff --git a/spec/services/system_hooks_service_spec.rb b/spec/services/system_hooks_service_spec.rb index ebc1ed51d2e..f1df7e55dd0 100644 --- a/spec/services/system_hooks_service_spec.rb +++ b/spec/services/system_hooks_service_spec.rb @@ -24,10 +24,10 @@ describe SystemHooksService do end def event_data(*args) - SystemHooksService.build_event_data(*args) + SystemHooksService.new.send :build_event_data, *args end def event_name(*args) - SystemHooksService.build_event_name(*args) + SystemHooksService.new.send :build_event_name, *args end end diff --git a/spec/services/test_hook_service_spec.rb b/spec/services/test_hook_service_spec.rb new file mode 100644 index 00000000000..fbe9066096d --- /dev/null +++ b/spec/services/test_hook_service_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe TestHookService do + let (:user) { create :user } + let (:project) { create :project_with_code } + let (:hook) { create :project_hook, project: project } + + describe :execute do + it "should execute successfully" do + stub_request(:post, hook.url).to_return(status: 200) + TestHookService.new.execute(hook, user).should be_true + end + end +end diff --git a/spec/support/chosen_helper.rb b/spec/support/chosen_helper.rb deleted file mode 100644 index 42c9342c77a..00000000000 --- a/spec/support/chosen_helper.rb +++ /dev/null @@ -1,21 +0,0 @@ -# Chosen programmatic helper -# It allows you to select value from chosen select -# -# Params -# value - real value of selected item -# opts - options containing css selector -# -# Usage: -# -# chosen(2, from: '#user_ids') -# - -module ChosenHelper - def chosen(value, options={}) - raise "Must pass a hash containing 'from'" if not options.is_a?(Hash) or not options.has_key?(:from) - - selector = options[:from] - - page.execute_script("$('#{selector}').val('#{value}').trigger('chosen:updated');") - end -end diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb index cba243226db..a5541bee876 100644 --- a/spec/tasks/gitlab/backup_rake_spec.rb +++ b/spec/tasks/gitlab/backup_rake_spec.rb @@ -5,6 +5,7 @@ describe 'gitlab:app namespace rake task' do before :all do Rake.application.rake_require "tasks/gitlab/task_helpers" Rake.application.rake_require "tasks/gitlab/backup" + Rake.application.rake_require "tasks/gitlab/shell" # empty task as env is already loaded Rake::Task.define_task :environment end @@ -26,6 +27,9 @@ describe 'gitlab:app namespace rake task' do Dir.stub :chdir File.stub exists?: true Kernel.stub system: true + FileUtils.stub cp_r: true + FileUtils.stub mv: true + Rake::Task["gitlab:shell:setup"].stub invoke: true end let(:gitlab_version) { %x{git rev-parse HEAD}.gsub(/\n/,"") } @@ -39,7 +43,8 @@ describe 'gitlab:app namespace rake task' do YAML.stub load_file: {gitlab_version: gitlab_version} Rake::Task["gitlab:backup:db:restore"].should_receive :invoke Rake::Task["gitlab:backup:repo:restore"].should_receive :invoke - expect { run_rake_task }.to_not raise_error SystemExit + Rake::Task["gitlab:shell:setup"].should_receive :invoke + expect { run_rake_task }.to_not raise_error end end diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb index 46e86dbe00a..0850734f136 100644 --- a/spec/workers/post_receive_spec.rb +++ b/spec/workers/post_receive_spec.rb @@ -19,7 +19,7 @@ describe PostReceive do end it "does not run if the author is not in the project" do - Key.stub(find_by_id: nil) + Key.stub(:find_by).with(hash_including(id: anything())) { nil } project.should_not_receive(:execute_hooks) |