Commit 50f3d0d4 authored by tiagonbotelho's avatar tiagonbotelho

Merge branch 'master' into rename-repo-files

parents c6097f24 017ae313
# Prefer single quotes
StringLiterals:
EnforcedStyle: single_quotes
Enabled: true
This diff is collapsed.
This diff is collapsed.
stage:
before:
- cp config/gitlab.teatro.yml config/gitlab.yml
- mkdir /apps/gitlab-satellites
- mkdir /apps/repositories
database:
- RAILS_ENV=development force=yes bundle exec rake db:create gitlab:setup
\ No newline at end of file
...@@ -3,40 +3,54 @@ Please view this file on the master branch, on stable branches it's out of date. ...@@ -3,40 +3,54 @@ Please view this file on the master branch, on stable branches it's out of date.
v 8.10.0 (unreleased) v 8.10.0 (unreleased)
- Expose {should,force}_remove_source_branch (Ben Boeckel) - Expose {should,force}_remove_source_branch (Ben Boeckel)
- Add the functionality to be able to rename a file. !5049 (tiagonbotelho) - Add the functionality to be able to rename a file. !5049 (tiagonbotelho)
- Disable PostgreSQL statement timeout during migrations
- Fix projects dropdown loading performance with a simplified api cal. !5113 (tiagonbotelho)
- Fix commit builds API, return all builds for all pipelines for given commit. !4849 - Fix commit builds API, return all builds for all pipelines for given commit. !4849
- Replace Haml with Hamlit to make view rendering faster. !3666 - Replace Haml with Hamlit to make view rendering faster. !3666
- Expire the branch cache after `git gc` runs - Refresh the branch cache after `git gc` runs
- Refactor repository paths handling to allow multiple git mount points - Refactor repository paths handling to allow multiple git mount points
- Optimize system note visibility checking by memoizing the visible reference count !5070 - Optimize system note visibility checking by memoizing the visible reference count !5070
- Add Application Setting to configure default Repository Path for new projects - Add Application Setting to configure default Repository Path for new projects
- Delete award emoji when deleting a user
- Remove pinTo from Flash and make inline flash messages look nicer !4854 (winniehell) - Remove pinTo from Flash and make inline flash messages look nicer !4854 (winniehell)
- Wrap code blocks on Activies and Todos page. !4783 (winniehell) - Wrap code blocks on Activies and Todos page. !4783 (winniehell)
- Align flash messages with left side of page content !4959 (winniehell) - Align flash messages with left side of page content !4959 (winniehell)
- Display tooltip for "Copy to Clipboard" button !5164 (winniehell) - Display tooltip for "Copy to Clipboard" button !5164 (winniehell)
- Use default cursor for table header of project files !5165 (winniehell)
- Store when and yaml variables in builds table
- Display last commit of deleted branch in push events !4699 (winniehell) - Display last commit of deleted branch in push events !4699 (winniehell)
- Escape file extension when parsing search results !5141 (winniehell) - Escape file extension when parsing search results !5141 (winniehell)
- Apply the trusted_proxies config to the rack request object for use with rack_attack - Apply the trusted_proxies config to the rack request object for use with rack_attack
- Upgrade to Rails 4.2.7. !5236
- Add Sidekiq queue duration to transaction metrics. - Add Sidekiq queue duration to transaction metrics.
- Add a new column `artifacts_size` to table `ci_builds` !4964 - Add a new column `artifacts_size` to table `ci_builds` !4964
- Let Workhorse serve format-patch diffs - Let Workhorse serve format-patch diffs
- Display tooltip for mentioned users and groups !5261 (winniehell)
- Added day name to contribution calendar tooltips - Added day name to contribution calendar tooltips
- Make images fit to the size of the viewport !4810 - Make images fit to the size of the viewport !4810
- Fix check for New Branch button on Issue page !4630 (winniehell) - Fix check for New Branch button on Issue page !4630 (winniehell)
- Fix MR-auto-close text added to description. !4836 - Fix MR-auto-close text added to description. !4836
- Support U2F devices in Firefox. !5177
- Fix issue, preventing users w/o push access to sort tags !5105 (redetection) - Fix issue, preventing users w/o push access to sort tags !5105 (redetection)
- Add Spring EmojiOne updates. - Add Spring EmojiOne updates.
- Fix fetching LFS objects for private CI projects
- Add syntax for multiline blockquote using `>>>` fence !3954 - Add syntax for multiline blockquote using `>>>` fence !3954
- Fix viewing notification settings when a project is pending deletion - Fix viewing notification settings when a project is pending deletion
- Updated compare dropdown menus to use GL dropdown
- Eager load award emoji on notes
- Fix pagination when sorting by columns with lots of ties (like priority) - Fix pagination when sorting by columns with lots of ties (like priority)
- The Markdown reference parsers now re-use query results to prevent running the same queries multiple times !5020 - The Markdown reference parsers now re-use query results to prevent running the same queries multiple times !5020
- Updated project header design - Updated project header design
- Issuable collapsed assignee tooltip is now the users name
- Exclude email check from the standard health check - Exclude email check from the standard health check
- Updated layout for Projects, Groups, Users on Admin area !4424 - Updated layout for Projects, Groups, Users on Admin area !4424
- Fix changing issue state columns in milestone view - Fix changing issue state columns in milestone view
- Update health_check gem to version 2.1.0 - Update health_check gem to version 2.1.0
- Add notification settings dropdown for groups - Add notification settings dropdown for groups
- Render inline diffs for multiple changed lines following eachother
- Wildcards for protected branches. !4665 - Wildcards for protected branches. !4665
- Allow importing from Github using Personal Access Tokens. (Eric K Idema) - Allow importing from Github using Personal Access Tokens. (Eric K Idema)
- API: Expose `due_date` for issues (Robert Schilling)
- API: Todos !3188 (Robert Schilling) - API: Todos !3188 (Robert Schilling)
- API: Expose shared groups for projects and shared projects for groups !5050 (Robert Schilling) - API: Expose shared groups for projects and shared projects for groups !5050 (Robert Schilling)
- Add "Enabled Git access protocols" to Application Settings - Add "Enabled Git access protocols" to Application Settings
...@@ -45,14 +59,22 @@ v 8.10.0 (unreleased) ...@@ -45,14 +59,22 @@ v 8.10.0 (unreleased)
- Fix user creation with stronger minimum password requirements !4054 (nathan-pmt) - Fix user creation with stronger minimum password requirements !4054 (nathan-pmt)
- Only show New Snippet button to users that can create snippets. - Only show New Snippet button to users that can create snippets.
- PipelinesFinder uses git cache data - PipelinesFinder uses git cache data
- Track a user who created a pipeline
- Actually render old and new sections of parallel diff next to each other
- Throttle the update of `project.pushes_since_gc` to 1 minute. - Throttle the update of `project.pushes_since_gc` to 1 minute.
- Allow expanding and collapsing files in diff view (!4990) - Allow expanding and collapsing files in diff view (!4990)
- Collapse large diffs by default (!4990) - Collapse large diffs by default (!4990)
- Fix mentioned users list on diff notes
- Fix creation of deployment on build that is retried, redeployed or rollback
- Don't parse Rinku returned value to DocFragment when it didn't change the original html string.
- Check for conflicts with existing Project's wiki path when creating a new project. - Check for conflicts with existing Project's wiki path when creating a new project.
- Show last push widget in upstream after push to fork - Show last push widget in upstream after push to fork
- Fix stage status shown for pipelines
- Cache todos pending/done dashboard query counts.
- Don't instantiate a git tree on Projects show default view - Don't instantiate a git tree on Projects show default view
- Bump Rinku to 2.0.0 - Bump Rinku to 2.0.0
- Remove unused front-end variable -> default_issues_tracker - Remove unused front-end variable -> default_issues_tracker
- ObjectRenderer retrieve renderer content using Rails.cache.read_multi
- Better caching of git calls on ProjectsController#show. - Better caching of git calls on ProjectsController#show.
- Avoid to retrieve MR closes_issues as much as possible. - Avoid to retrieve MR closes_issues as much as possible.
- Add API endpoint for a group issues !4520 (mahcsig) - Add API endpoint for a group issues !4520 (mahcsig)
...@@ -68,19 +90,46 @@ v 8.10.0 (unreleased) ...@@ -68,19 +90,46 @@ v 8.10.0 (unreleased)
- Add basic system information like memory and disk usage to the admin panel - Add basic system information like memory and disk usage to the admin panel
- Don't garbage collect commits that have related DB records like comments - Don't garbage collect commits that have related DB records like comments
- More descriptive message for git hooks and file locks - More descriptive message for git hooks and file locks
- Aliases of award emoji should be stored as original name. !5060 (dixpac)
- Handle custom Git hook result in GitLab UI - Handle custom Git hook result in GitLab UI
- Allow to access Container Registry for Public and Internal projects
- Allow '?', or '&' for label names - Allow '?', or '&' for label names
- Support redirected blobs for Container Registry integration
- Fix importer for GitHub Pull Requests when a branch was reused across Pull Requests - Fix importer for GitHub Pull Requests when a branch was reused across Pull Requests
- Add date when user joined the team on the member page - Add date when user joined the team on the member page
- Fix 404 redirect after validation fails importing a GitLab project - Fix 404 redirect after validation fails importing a GitLab project
- Fix 404 redirect after validation fails importing a GitLab project
- Added setting to set new users by default as external !4545 (Dravere) - Added setting to set new users by default as external !4545 (Dravere)
- Add min value for project limit field on user's form !3622 (jastkand) - Add min value for project limit field on user's form !3622 (jastkand)
- Reset project pushes_since_gc when we enqueue the git gc call
- Add reminder to not paste private SSH keys !4399 (Ingo Blechschmidt) - Add reminder to not paste private SSH keys !4399 (Ingo Blechschmidt)
- Remove duplicate `description` field in `MergeRequest` entities (Ben Boeckel) - Remove duplicate `description` field in `MergeRequest` entities (Ben Boeckel)
- Style of import project buttons were fixed in the new project page. !5183 (rdemirbay) - Style of import project buttons were fixed in the new project page. !5183 (rdemirbay)
- Fix GitHub client requests when rate limit is disabled
v 8.9.6 (unreleased) - Optimistic locking for Issues and Merge Requests (Title and description overriding prevention)
- Redesign Builds and Pipelines pages
- Change status color and icon for running builds
- Fix markdown rendering for: consecutive labels references, label references that begin with a digit or contains `.`
- Project export filename now includes the project and namespace path
- Fix last update timestamp on issues not preserved on gitlab.com and project imports
- Fix issues importing projects from EE to CE
- Fix creating group with space in group path
- Create Todos for Issue author when assign or mention himself (Katarzyna Kobierska)
- Limit the number of retries on error to 3 for exporting projects
- Allow empty repositories on project import/export
v 8.9.6
- Fix importing of events under notes for GitLab projects. !5154
- Fix log statements in import/export. !5129
- Fix commit avatar alignment in compare view. !5128
- Fix broken migration in MySQL. !5005
- Overwrite Host and X-Forwarded-Host headers in NGINX !5213
- Keeps issue number when importing from Gitlab.com
- Add Pending tab for Builds (Katarzyna Kobierska, Urszula Budziszewska)
v 8.9.7 (unreleased)
- Fix import_data wrongly saved as a result of an invalid import_url
v 8.9.6
- Fix importing of events under notes for GitLab projects - Fix importing of events under notes for GitLab projects
v 8.9.5 v 8.9.5
...@@ -242,6 +291,7 @@ v 8.9.0 ...@@ -242,6 +291,7 @@ v 8.9.0
- Add rake task 'gitlab:db:configure' for conditionally seeding or migrating the database - Add rake task 'gitlab:db:configure' for conditionally seeding or migrating the database
- Changed the Slack build message to use the singular duration if necessary (Aran Koning) - Changed the Slack build message to use the singular duration if necessary (Aran Koning)
- Fix race condition on merge when build succeeds - Fix race condition on merge when build succeeds
- Added shortcut to focus filter search fields and added documentation #18120
- Links from a wiki page to other wiki pages should be rewritten as expected - Links from a wiki page to other wiki pages should be rewritten as expected
- Add option to project to only allow merge requests to be merged if the build succeeds (Rui Santos) - Add option to project to only allow merge requests to be merged if the build succeeds (Rui Santos)
- Added navigation shortcuts to the project pipelines, milestones, builds and forks page. !4393 - Added navigation shortcuts to the project pipelines, milestones, builds and forks page. !4393
...@@ -2203,8 +2253,6 @@ v 7.7.0 ...@@ -2203,8 +2253,6 @@ v 7.7.0
- Fixes for edit comments: drag-n-drop images, preview mode, selecting images, save & update - Fixes for edit comments: drag-n-drop images, preview mode, selecting images, save & update
- Remove password strength indicator - Remove password strength indicator
v 7.6.0 v 7.6.0
- Fork repository to groups - Fork repository to groups
- New rugged version - New rugged version
......
...@@ -145,7 +145,8 @@ might be edited to make them small and simple. ...@@ -145,7 +145,8 @@ might be edited to make them small and simple.
You are encouraged to use the template below for feature proposals. You are encouraged to use the template below for feature proposals.
``` ```
## Description including problem, use cases, benefits, and/or goals ## Description
Include problem, use cases, benefits, and/or goals
## Proposal ## Proposal
......
source 'https://rubygems.org' source 'https://rubygems.org'
gem 'rails', '4.2.6' gem 'rails', '4.2.7'
gem 'rails-deprecated_sanitizer', '~> 1.0.3' gem 'rails-deprecated_sanitizer', '~> 1.0.3'
# Responders respond_to and respond_with # Responders respond_to and respond_with
...@@ -61,7 +61,7 @@ gem 'gitlab_omniauth-ldap', '~> 1.2.1', require: 'omniauth-ldap' ...@@ -61,7 +61,7 @@ gem 'gitlab_omniauth-ldap', '~> 1.2.1', require: 'omniauth-ldap'
# Git Wiki # Git Wiki
# Required manually in config/initializers/gollum.rb to control load order # Required manually in config/initializers/gollum.rb to control load order
gem 'gollum-lib', '~> 4.1.0', require: false gem 'gollum-lib', '~> 4.2', require: false
gem 'gollum-rugged_adapter', '~> 0.4.2', require: false gem 'gollum-rugged_adapter', '~> 0.4.2', require: false
# Language detection # Language detection
...@@ -105,7 +105,7 @@ gem 'seed-fu', '~> 2.3.5' ...@@ -105,7 +105,7 @@ gem 'seed-fu', '~> 2.3.5'
# Markdown and HTML processing # Markdown and HTML processing
gem 'html-pipeline', '~> 1.11.0' gem 'html-pipeline', '~> 1.11.0'
gem 'task_list', '~> 1.0.2', require: 'task_list/railtie' gem 'task_list', '~> 1.0.2', require: 'task_list/railtie'
gem 'github-markup', '~> 1.3.1' gem 'github-markup', '~> 1.4'
gem 'redcarpet', '~> 3.3.3' gem 'redcarpet', '~> 3.3.3'
gem 'RedCloth', '~> 4.3.2' gem 'RedCloth', '~> 4.3.2'
gem 'rdoc', '~>3.6' gem 'rdoc', '~>3.6'
...@@ -113,7 +113,7 @@ gem 'org-ruby', '~> 0.9.12' ...@@ -113,7 +113,7 @@ gem 'org-ruby', '~> 0.9.12'
gem 'creole', '~> 0.5.0' gem 'creole', '~> 0.5.0'
gem 'wikicloth', '0.8.1' gem 'wikicloth', '0.8.1'
gem 'asciidoctor', '~> 1.5.2' gem 'asciidoctor', '~> 1.5.2'
gem 'rouge', '~> 1.11' gem 'rouge', '~> 2.0'
# See https://groups.google.com/forum/#!topic/ruby-security-ann/aSbgDiwb24s # See https://groups.google.com/forum/#!topic/ruby-security-ann/aSbgDiwb24s
# and https://groups.google.com/forum/#!topic/ruby-security-ann/Dy7YiKb_pMM # and https://groups.google.com/forum/#!topic/ruby-security-ann/Dy7YiKb_pMM
...@@ -299,7 +299,7 @@ group :development, :test do ...@@ -299,7 +299,7 @@ group :development, :test do
gem 'spring-commands-spinach', '~> 1.1.0' gem 'spring-commands-spinach', '~> 1.1.0'
gem 'spring-commands-teaspoon', '~> 0.0.2' gem 'spring-commands-teaspoon', '~> 0.0.2'
gem 'rubocop', '~> 0.40.0', require: false gem 'rubocop', '~> 0.41.2', require: false
gem 'rubocop-rspec', '~> 1.5.0', require: false gem 'rubocop-rspec', '~> 1.5.0', require: false
gem 'scss_lint', '~> 0.47.0', require: false gem 'scss_lint', '~> 0.47.0', require: false
gem 'simplecov', '~> 0.11.0', require: false gem 'simplecov', '~> 0.11.0', require: false
......
...@@ -3,34 +3,34 @@ GEM ...@@ -3,34 +3,34 @@ GEM
specs: specs:
RedCloth (4.3.2) RedCloth (4.3.2)
ace-rails-ap (4.0.2) ace-rails-ap (4.0.2)
actionmailer (4.2.6) actionmailer (4.2.7)
actionpack (= 4.2.6) actionpack (= 4.2.7)
actionview (= 4.2.6) actionview (= 4.2.7)
activejob (= 4.2.6) activejob (= 4.2.7)
mail (~> 2.5, >= 2.5.4) mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 1.0, >= 1.0.5)
actionpack (4.2.6) actionpack (4.2.7)
actionview (= 4.2.6) actionview (= 4.2.7)
activesupport (= 4.2.6) activesupport (= 4.2.7)
rack (~> 1.6) rack (~> 1.6)
rack-test (~> 0.6.2) rack-test (~> 0.6.2)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (4.2.6) actionview (4.2.7)
activesupport (= 4.2.6) activesupport (= 4.2.7)
builder (~> 3.1) builder (~> 3.1)
erubis (~> 2.7.0) erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.2)
activejob (4.2.6) activejob (4.2.7)
activesupport (= 4.2.6) activesupport (= 4.2.7)
globalid (>= 0.3.0) globalid (>= 0.3.0)
activemodel (4.2.6) activemodel (4.2.7)
activesupport (= 4.2.6) activesupport (= 4.2.7)
builder (~> 3.1) builder (~> 3.1)
activerecord (4.2.6) activerecord (4.2.7)
activemodel (= 4.2.6) activemodel (= 4.2.7)
activesupport (= 4.2.6) activesupport (= 4.2.7)
arel (~> 6.0) arel (~> 6.0)
activerecord-session_store (1.0.0) activerecord-session_store (1.0.0)
actionpack (>= 4.0, < 5.1) actionpack (>= 4.0, < 5.1)
...@@ -38,7 +38,7 @@ GEM ...@@ -38,7 +38,7 @@ GEM
multi_json (~> 1.11, >= 1.11.2) multi_json (~> 1.11, >= 1.11.2)
rack (>= 1.5.2, < 3) rack (>= 1.5.2, < 3)
railties (>= 4.0, < 5.1) railties (>= 4.0, < 5.1)
activesupport (4.2.6) activesupport (4.2.7)
i18n (~> 0.7) i18n (~> 0.7)
json (~> 1.7, >= 1.7.7) json (~> 1.7, >= 1.7.7)
minitest (~> 5.1) minitest (~> 5.1)
...@@ -58,7 +58,7 @@ GEM ...@@ -58,7 +58,7 @@ GEM
faraday_middleware-multi_json (~> 0.0) faraday_middleware-multi_json (~> 0.0)
oauth2 (~> 1.0) oauth2 (~> 1.0)
asciidoctor (1.5.3) asciidoctor (1.5.3)
ast (2.2.0) ast (2.3.0)
attr_encrypted (3.0.1) attr_encrypted (3.0.1)
encryptor (~> 3.0.0) encryptor (~> 3.0.0)
attr_required (1.0.0) attr_required (1.0.0)
...@@ -264,7 +264,7 @@ GEM ...@@ -264,7 +264,7 @@ GEM
escape_utils (~> 1.1.0) escape_utils (~> 1.1.0)
mime-types (>= 1.19) mime-types (>= 1.19)
rugged (>= 0.23.0b) rugged (>= 0.23.0b)
github-markup (1.3.3) github-markup (1.4.0)
gitlab-flowdock-git-hook (1.0.1) gitlab-flowdock-git-hook (1.0.1)
flowdock (~> 0.7) flowdock (~> 0.7)
gitlab-grit (>= 2.4.1) gitlab-grit (>= 2.4.1)
...@@ -287,13 +287,13 @@ GEM ...@@ -287,13 +287,13 @@ GEM
rubyntlm (~> 0.3) rubyntlm (~> 0.3)
globalid (0.3.6) globalid (0.3.6)
activesupport (>= 4.1.0) activesupport (>= 4.1.0)
gollum-grit_adapter (1.0.0) gollum-grit_adapter (1.0.1)
gitlab-grit (~> 2.7, >= 2.7.1) gitlab-grit (~> 2.7, >= 2.7.1)
gollum-lib (4.1.0) gollum-lib (4.2.1)
github-markup (~> 1.3.3) github-markup (~> 1.4.0)
gollum-grit_adapter (~> 1.0) gollum-grit_adapter (~> 1.0)
nokogiri (~> 1.6.4) nokogiri (~> 1.6.4)
rouge (~> 1.9) rouge (~> 2.0)
sanitize (~> 2.1.0) sanitize (~> 2.1.0)
stringex (~> 2.5.1) stringex (~> 2.5.1)
gollum-rugged_adapter (0.4.2) gollum-rugged_adapter (0.4.2)
...@@ -474,7 +474,7 @@ GEM ...@@ -474,7 +474,7 @@ GEM
orm_adapter (0.5.0) orm_adapter (0.5.0)
paranoia (2.1.4) paranoia (2.1.4)
activerecord (~> 4.0) activerecord (~> 4.0)
parser (2.3.1.0) parser (2.3.1.2)
ast (~> 2.2) ast (~> 2.2)
pg (0.18.4) pg (0.18.4)
pkg-config (1.1.7) pkg-config (1.1.7)
...@@ -516,16 +516,16 @@ GEM ...@@ -516,16 +516,16 @@ GEM
rack rack
rack-test (0.6.3) rack-test (0.6.3)
rack (>= 1.0) rack (>= 1.0)
rails (4.2.6) rails (4.2.7)
actionmailer (= 4.2.6) actionmailer (= 4.2.7)
actionpack (= 4.2.6) actionpack (= 4.2.7)
actionview (= 4.2.6) actionview (= 4.2.7)
activejob (= 4.2.6) activejob (= 4.2.7)
activemodel (= 4.2.6) activemodel (= 4.2.7)
activerecord (= 4.2.6) activerecord (= 4.2.7)
activesupport (= 4.2.6) activesupport (= 4.2.7)
bundler (>= 1.3.0, < 2.0) bundler (>= 1.3.0, < 2.0)
railties (= 4.2.6) railties (= 4.2.7)
sprockets-rails sprockets-rails
rails-deprecated_sanitizer (1.0.3) rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha) activesupport (>= 4.2.0.alpha)
...@@ -535,9 +535,9 @@ GEM ...@@ -535,9 +535,9 @@ GEM
rails-deprecated_sanitizer (>= 1.0.1) rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.3) rails-html-sanitizer (1.0.3)
loofah (~> 2.0) loofah (~> 2.0)
railties (4.2.6) railties (4.2.7)
actionpack (= 4.2.6) actionpack (= 4.2.7)
activesupport (= 4.2.6) activesupport (= 4.2.7)
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.18.1, < 2.0)
rainbow (2.1.0) rainbow (2.1.0)
...@@ -579,7 +579,7 @@ GEM ...@@ -579,7 +579,7 @@ GEM
railties (>= 4.2.0, < 5.1) railties (>= 4.2.0, < 5.1)
rinku (2.0.0) rinku (2.0.0)
rotp (2.1.2) rotp (2.1.2)
rouge (1.11.0) rouge (2.0.3)
rqrcode (0.7.0) rqrcode (0.7.0)
chunky_png chunky_png
rqrcode-rails3 (0.1.7) rqrcode-rails3 (0.1.7)
...@@ -607,8 +607,8 @@ GEM ...@@ -607,8 +607,8 @@ GEM
rspec-retry (0.4.5) rspec-retry (0.4.5)
rspec-core rspec-core
rspec-support (3.5.0) rspec-support (3.5.0)
rubocop (0.40.0) rubocop (0.41.2)
parser (>= 2.3.1.0, < 3.0) parser (>= 2.3.1.1, < 3.0)
powerpack (~> 0.1) powerpack (~> 0.1)
rainbow (>= 1.99.1, < 3.0) rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
...@@ -698,7 +698,7 @@ GEM ...@@ -698,7 +698,7 @@ GEM
spring (>= 0.9.1) spring (>= 0.9.1)
spring-commands-teaspoon (0.0.2) spring-commands-teaspoon (0.0.2)
spring (>= 0.9.1) spring (>= 0.9.1)
sprockets (3.6.2) sprockets (3.6.3)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
rack (> 1, < 3) rack (> 1, < 3)
sprockets-rails (3.1.1) sprockets-rails (3.1.1)
...@@ -759,7 +759,7 @@ GEM ...@@ -759,7 +759,7 @@ GEM
unf (0.1.4) unf (0.1.4)
unf_ext unf_ext
unf_ext (0.0.7.2) unf_ext (0.0.7.2)
unicode-display_width (1.0.5) unicode-display_width (1.1.0)
unicorn (4.9.0) unicorn (4.9.0)
kgio (~> 2.6) kgio (~> 2.6)
rack rack
...@@ -860,12 +860,12 @@ DEPENDENCIES ...@@ -860,12 +860,12 @@ DEPENDENCIES
gemnasium-gitlab-service (~> 0.2) gemnasium-gitlab-service (~> 0.2)
gemojione (~> 2.6) gemojione (~> 2.6)
github-linguist (~> 4.7.0) github-linguist (~> 4.7.0)
github-markup (~> 1.3.1) github-markup (~> 1.4)
gitlab-flowdock-git-hook (~> 1.0.1) gitlab-flowdock-git-hook (~> 1.0.1)
gitlab_git (~> 10.2) gitlab_git (~> 10.2)
gitlab_meta (= 7.0) gitlab_meta (= 7.0)
gitlab_omniauth-ldap (~> 1.2.1) gitlab_omniauth-ldap (~> 1.2.1)
gollum-lib (~> 4.1.0) gollum-lib (~> 4.2)
gollum-rugged_adapter (~> 0.4.2) gollum-rugged_adapter (~> 0.4.2)
gon (~> 6.0.1) gon (~> 6.0.1)
grape (~> 0.13.0) grape (~> 0.13.0)
...@@ -921,7 +921,7 @@ DEPENDENCIES ...@@ -921,7 +921,7 @@ DEPENDENCIES
rack-attack (~> 4.3.1) rack-attack (~> 4.3.1)
rack-cors (~> 0.4.0) rack-cors (~> 0.4.0)
rack-oauth2 (~> 1.2.1) rack-oauth2 (~> 1.2.1)
rails (= 4.2.6) rails (= 4.2.7)
rails-deprecated_sanitizer (~> 1.0.3) rails-deprecated_sanitizer (~> 1.0.3)
rainbow (~> 2.1.0) rainbow (~> 2.1.0)
rblineprof (~> 0.3.6) rblineprof (~> 0.3.6)
...@@ -934,11 +934,11 @@ DEPENDENCIES ...@@ -934,11 +934,11 @@ DEPENDENCIES
request_store (~> 1.3.0) request_store (~> 1.3.0)
rerun (~> 0.11.0) rerun (~> 0.11.0)
responders (~> 2.0) responders (~> 2.0)
rouge (~> 1.11) rouge (~> 2.0)
rqrcode-rails3 (~> 0.1.7) rqrcode-rails3 (~> 0.1.7)
rspec-rails (~> 3.5.0) rspec-rails (~> 3.5.0)
rspec-retry (~> 0.4.5) rspec-retry (~> 0.4.5)
rubocop (~> 0.40.0) rubocop (~> 0.41.2)
rubocop-rspec (~> 1.5.0) rubocop-rspec (~> 1.5.0)
ruby-fogbugz (~> 0.2.1) ruby-fogbugz (~> 0.2.1)
sanitize (~> 2.0) sanitize (~> 2.0)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
groupPath: "/api/:version/groups/:id.json" groupPath: "/api/:version/groups/:id.json"
namespacesPath: "/api/:version/namespaces.json" namespacesPath: "/api/:version/namespaces.json"
groupProjectsPath: "/api/:version/groups/:id/projects.json" groupProjectsPath: "/api/:version/groups/:id/projects.json"
projectsPath: "/api/:version/projects.json" projectsPath: "/api/:version/projects.json?simple=true"
labelsPath: "/api/:version/projects/:id/labels" labelsPath: "/api/:version/projects/:id/labels"
licensePath: "/api/:version/licenses/:key" licensePath: "/api/:version/licenses/:key"
gitignorePath: "/api/:version/gitignores/:key" gitignorePath: "/api/:version/gitignores/:key"
......
...@@ -53,7 +53,6 @@ ...@@ -53,7 +53,6 @@
#= require_directory ./u2f #= require_directory ./u2f
#= require_directory . #= require_directory .
#= require fuzzaldrin-plus #= require fuzzaldrin-plus
#= require u2f
window.slugify = (text) -> window.slugify = (text) ->
text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase() text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase()
......
class @CompareAutocomplete
constructor: ->
@initDropdown()
initDropdown: ->
$('.js-compare-dropdown').each ->
$dropdown = $(@)
selected = $dropdown.data('selected')
$dropdown.glDropdown(
data: (term, callback) ->
$.ajax(
url: $dropdown.data('refs-url')
data:
ref: $dropdown.data('ref')
).done (refs) ->
callback(refs)
selectable: true
filterable: true
filterByText: true
fieldName: $dropdown.attr('name')
filterInput: 'input[type="text"]'
renderRow: (ref) ->
if ref.header?
$('<li />')
.addClass('dropdown-header')
.text(ref.header)
else
link = $('<a />')
.attr('href', '#')
.addClass(if ref is selected then 'is-active' else '')
.text(ref)
.attr('data-ref', escape(ref))
$('<li />')
.append(link)
id: (obj, $el) ->
$el.attr('data-ref')
toggleLabel: (obj, $el) ->
$el.text().trim()
)
...@@ -137,6 +137,8 @@ class Dispatcher ...@@ -137,6 +137,8 @@ class Dispatcher
new Project() new Project()
new ProjectAvatar() new ProjectAvatar()
switch path[1] switch path[1]
when 'compare'
new CompareAutocomplete()
when 'edit' when 'edit'
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
new ProjectNew() new ProjectNew()
......
...@@ -456,6 +456,8 @@ class GitLabDropdown ...@@ -456,6 +456,8 @@ class GitLabDropdown
rowClicked: (el) -> rowClicked: (el) ->
fieldName = @options.fieldName fieldName = @options.fieldName
isInput = $(@el).is('input')
if @renderedData if @renderedData
groupName = el.data('group') groupName = el.data('group')
if groupName if groupName
...@@ -466,9 +468,18 @@ class GitLabDropdown ...@@ -466,9 +468,18 @@ class GitLabDropdown
selectedObject = @renderedData[selectedIndex] selectedObject = @renderedData[selectedIndex]
value = if @options.id then @options.id(selectedObject, el) else selectedObject.id value = if @options.id then @options.id(selectedObject, el) else selectedObject.id
if isInput
field = $(@el)
else
field = @dropdown.parent().find("input[name='#{fieldName}'][value='#{value}']") field = @dropdown.parent().find("input[name='#{fieldName}'][value='#{value}']")
if el.hasClass(ACTIVE_CLASS) if el.hasClass(ACTIVE_CLASS)
el.removeClass(ACTIVE_CLASS) el.removeClass(ACTIVE_CLASS)
if isInput
field.val('')
else
field.remove() field.remove()
# Toggle the dropdown label # Toggle the dropdown label
...@@ -490,6 +501,8 @@ class GitLabDropdown ...@@ -490,6 +501,8 @@ class GitLabDropdown
else else
if not @options.multiSelect or el.hasClass('dropdown-clear-active') if not @options.multiSelect or el.hasClass('dropdown-clear-active')
@dropdown.find(".#{ACTIVE_CLASS}").removeClass ACTIVE_CLASS @dropdown.find(".#{ACTIVE_CLASS}").removeClass ACTIVE_CLASS
unless isInput
@dropdown.parent().find("input[name='#{fieldName}']").remove() @dropdown.parent().find("input[name='#{fieldName}']").remove()
if !value? if !value?
...@@ -505,7 +518,9 @@ class GitLabDropdown ...@@ -505,7 +518,9 @@ class GitLabDropdown
if !field.length and fieldName if !field.length and fieldName
@addInput(fieldName, value) @addInput(fieldName, value)
else else
field.val value field
.val value
.trigger 'change'
return selectedObject return selectedObject
......
...@@ -32,13 +32,11 @@ issuable_created = false ...@@ -32,13 +32,11 @@ issuable_created = false
$search = $('#issue_search') $search = $('#issue_search')
$form = $('.js-filter-form') $form = $('.js-filter-form')
$input = $("input[name='#{$search.attr('name')}']", $form) $input = $("input[name='#{$search.attr('name')}']", $form)
if $input.length is 0 if $input.length is 0
$form.append "<input type='hidden' name='#{$search.attr('name')}' value='#{_.escape($search.val())}'/>" $form.append "<input type='hidden' name='#{$search.attr('name')}' value='#{_.escape($search.val())}'/>"
else else
$input.val $search.val() $input.val $search.val()
Issuable.filterResults $form if $search.val() isnt ''
Issuable.filterResults $form
, 500) , 500)
initLabelFilterRemove: -> initLabelFilterRemove: ->
......
...@@ -5,13 +5,12 @@ ...@@ -5,13 +5,12 @@
this.initPagination() this.initPagination()
initSearch: -> initSearch: ->
@timer = null projectsListFilter = $('.projects-list-filter')
$(".projects-list-filter").on('keyup', -> debounceFilter = _.debounce ProjectsList.filterResults, 500
clearTimeout(@timer) projectsListFilter.on 'keyup', (e) ->
@timer = setTimeout(ProjectsList.filterResults, 500) debounceFilter() if projectsListFilter.val() isnt ''
)
filterResults: => filterResults: ->
$('.projects-list-holder').fadeTo(250, 0.5) $('.projects-list-holder').fadeTo(250, 0.5)
form = null form = null
......
...@@ -2,9 +2,10 @@ class @Shortcuts ...@@ -2,9 +2,10 @@ class @Shortcuts
constructor: (skipResetBindings) -> constructor: (skipResetBindings) ->
@enabledHelp = [] @enabledHelp = []
Mousetrap.reset() if not skipResetBindings Mousetrap.reset() if not skipResetBindings
Mousetrap.bind('?', @onToggleHelp) Mousetrap.bind '?', @onToggleHelp
Mousetrap.bind('s', Shortcuts.focusSearch) Mousetrap.bind 's', Shortcuts.focusSearch
Mousetrap.bind(['ctrl+shift+p', 'command+shift+p'], @toggleMarkdownPreview) Mousetrap.bind 'f', (e) => @focusFilter e
Mousetrap.bind ['ctrl+shift+p', 'command+shift+p'], @toggleMarkdownPreview
Mousetrap.bind('t', -> Turbolinks.visit(findFileURL)) if findFileURL? Mousetrap.bind('t', -> Turbolinks.visit(findFileURL)) if findFileURL?
onToggleHelp: (e) => onToggleHelp: (e) =>
...@@ -32,10 +33,16 @@ class @Shortcuts ...@@ -32,10 +33,16 @@ class @Shortcuts
$('.js-more-help-button').remove() $('.js-more-help-button').remove()
) )
focusFilter: (e) ->
@filterInput ?= $('input[type=search]', '.nav-controls')
@filterInput.focus()
e.preventDefault()
@focusSearch: (e) -> @focusSearch: (e) ->
$('#search').focus() $('#search').focus()
e.preventDefault() e.preventDefault()
$(document).on 'click.more_help', '.js-more-help-button', (e) -> $(document).on 'click.more_help', '.js-more-help-button', (e) ->
$(@).remove() $(@).remove()
$('.hidden-shortcut').show() $('.hidden-shortcut').show()
......
...@@ -6,8 +6,20 @@ ...@@ -6,8 +6,20 @@
class @U2FAuthenticate class @U2FAuthenticate
constructor: (@container, u2fParams) -> constructor: (@container, u2fParams) ->
@appId = u2fParams.app_id @appId = u2fParams.app_id
@challenges = u2fParams.challenges @challenge = u2fParams.challenge
@signRequests = u2fParams.sign_requests
# The U2F Javascript API v1.1 requires a single challenge, with
# _no challenges per-request_. The U2F Javascript API v1.0 requires a
# challenge per-request, which is done by copying the single challenge
# into every request.
#
# In either case, we don't need the per-request challenges that the server
# has generated, so we can remove them.
#
# Note: The server library fixes this behaviour in (unreleased) version 1.0.0.
# This can be removed once we upgrade.
# https://github.com/castle/ruby-u2f/commit/103f428071a81cd3d5f80c2e77d522d5029946a4
@signRequests = u2fParams.sign_requests.map (request) -> _(request).omit('challenge')
start: () => start: () =>
if U2FUtil.isU2FSupported() if U2FUtil.isU2FSupported()
...@@ -16,7 +28,7 @@ class @U2FAuthenticate ...@@ -16,7 +28,7 @@ class @U2FAuthenticate
@renderNotSupported() @renderNotSupported()
authenticate: () => authenticate: () =>
u2f.sign(@appId, @challenges, @signRequests, (response) => u2f.sign(@appId, @challenge, @signRequests, (response) =>
if response.errorCode if response.errorCode
error = new U2FError(response.errorCode) error = new U2FError(response.errorCode)
@renderError(error); @renderError(error);
......
class @U2FUtil
@isU2FSupported: ->
window.u2f
# Helper class for U2F (universal 2nd factor) device registration and authentication.
class @U2FUtil
@isU2FSupported: ->
if @testMode
true
else
gon.u2f.browser_supports_u2f
@enableTestMode: ->
@testMode = true
<% if Rails.env.test? %>
U2FUtil.enableTestMode();
<% end %>
...@@ -56,6 +56,11 @@ class @UsersSelect ...@@ -56,6 +56,11 @@ class @UsersSelect
username: '' username: ''
avatar: '' avatar: ''
$value.html(assigneeTemplate(user)) $value.html(assigneeTemplate(user))
$collapsedSidebar
.attr('title', user.name)
.tooltip('fixTitle')
$collapsedSidebar.html(collapsedAssigneeTemplate(user)) $collapsedSidebar.html(collapsedAssigneeTemplate(user))
...@@ -63,7 +68,6 @@ class @UsersSelect ...@@ -63,7 +68,6 @@ class @UsersSelect
'<% if( avatar ) { %> '<% if( avatar ) { %>
<a class="author_link" href="/u/<%- username %>"> <a class="author_link" href="/u/<%- username %>">
<img width="24" class="avatar avatar-inline s24" alt="" src="<%- avatar %>"> <img width="24" class="avatar avatar-inline s24" alt="" src="<%- avatar %>">
<span class="author">Toni Boehm</span>
</a> </a>
<% } else { %> <% } else { %>
<i class="fa fa-user"></i> <i class="fa fa-user"></i>
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
} }
&.s16 { width: 16px; height: 16px; margin-right: 6px; } &.s16 { width: 16px; height: 16px; margin-right: 6px; }
&.s20 { width: 20px; height: 20px; margin-right: 7px; }
&.s24 { width: 24px; height: 24px; margin-right: 8px; } &.s24 { width: 24px; height: 24px; margin-right: 8px; }
&.s26 { width: 26px; height: 26px; margin-right: 8px; } &.s26 { width: 26px; height: 26px; margin-right: 8px; }
&.s32 { width: 32px; height: 32px; margin-right: 10px; } &.s32 { width: 32px; height: 32px; margin-right: 10px; }
......
...@@ -20,9 +20,12 @@ ...@@ -20,9 +20,12 @@
.blank-state-icon { .blank-state-icon {
padding-bottom: 20px; padding-bottom: 20px;
color: $gray-darkest;
font-size: 56px;
path { path,
fill: $gray-darkest; polygon {
fill: currentColor;
} }
} }
...@@ -37,6 +40,10 @@ ...@@ -37,6 +40,10 @@
margin-top: 0; margin-top: 0;
margin-bottom: $gl-padding; margin-bottom: $gl-padding;
font-size: 15px; font-size: 15px;
> strong {
font-weight: 600;
}
} }
.blank-state-welcome-title { .blank-state-welcome-title {
......
...@@ -16,8 +16,14 @@ ...@@ -16,8 +16,14 @@
font-weight: normal; font-weight: normal;
font-size: 16px; font-size: 16px;
line-height: 36px; line-height: 36px;
&.diff-collapsed { &.diff-collapsed {
padding: 5px;
cursor: pointer; cursor: pointer;
&:hover {
background-color: $row-hover;
}
} }
} }
......
...@@ -270,21 +270,6 @@ table { ...@@ -270,21 +270,6 @@ table {
} }
} }
.dashboard-intro-icon {
float: left;
text-align: center;
font-size: 32px;
color: #aaa;
width: 60px;
}
.dashboard-intro-text {
display: inline-block;
margin-left: -60px;
padding-left: 60px;
width: 100%;
}
.btn-sign-in { .btn-sign-in {
text-shadow: none; text-shadow: none;
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
.toggle-nav-collapse, .toggle-nav-collapse,
.pin-nav-btn { .pin-nav-btn {
color: $color-light; color: $color-light;
background: $color;
&:hover { &:hover {
color: $white-light; color: $white-light;
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
transition: width $sidebar-transition-duration; transition: width $sidebar-transition-duration;
@include box-shadow(2px 0 16px 0 #bbb); @include box-shadow(2px 0 16px 0 $black-transparent);
} }
} }
...@@ -55,10 +55,6 @@ ...@@ -55,10 +55,6 @@
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
@media (min-width: $sidebar-breakpoint) {
bottom: 50px;
}
&.navbar-collapse { &.navbar-collapse {
padding: 0 !important; padding: 0 !important;
} }
...@@ -76,7 +72,7 @@ ...@@ -76,7 +72,7 @@
} }
a { a {
padding: 7px 15px 7px 12px; padding: 7px $gl-sidebar-padding;
font-size: $gl-font-size; font-size: $gl-font-size;
line-height: 24px; line-height: 24px;
display: block; display: block;
...@@ -108,7 +104,7 @@ ...@@ -108,7 +104,7 @@
} }
} }
.toggle-nav-collapse { .sidebar-action-buttons {
width: $sidebar_width; width: $sidebar_width;
position: absolute; position: absolute;
top: 0; top: 0;
...@@ -117,28 +113,14 @@ ...@@ -117,28 +113,14 @@
padding: 5px 0; padding: 5px 0;
font-size: 18px; font-size: 18px;
line-height: 30px; line-height: 30px;
}
.nav-header-btn { .toggle-nav-collapse {
padding: 10px 5px; left: 0;
color: inherit;
transition-duration: .3s;
&:hover,
&:focus {
color: $white-light;
text-decoration: none;
} }
}
.pin-nav-btn { .pin-nav-btn {
right: 0;
display: none; display: none;
position: absolute;
left: 0;
bottom: 0;
height: 50px;
width: $sidebar_width;
line-height: 30px;
@media (min-width: $sidebar-breakpoint) { @media (min-width: $sidebar-breakpoint) {
display: block; display: block;
...@@ -153,6 +135,21 @@ ...@@ -153,6 +135,21 @@
transform: rotate(90deg); transform: rotate(90deg);
} }
} }
}
}
.nav-header-btn {
padding: 10px $gl-sidebar-padding;
color: inherit;
transition-duration: .3s;
position: absolute;
top: 0;
&:hover,
&:focus {
color: $white-light;
text-decoration: none;
}
} }
.page-sidebar-collapsed { .page-sidebar-collapsed {
......
...@@ -17,6 +17,7 @@ $focus-border-color: #3aabf0; ...@@ -17,6 +17,7 @@ $focus-border-color: #3aabf0;
$table-border-color: #f0f0f0; $table-border-color: #f0f0f0;
$background-color: #fafafa; $background-color: #fafafa;
$dark-background-color: #f7f7f7; $dark-background-color: #f7f7f7;
$table-text-gray: #8f8f8f;
/* /*
* Text * Text
...@@ -63,6 +64,7 @@ $gl-btn-padding: 10px; ...@@ -63,6 +64,7 @@ $gl-btn-padding: 10px;
$gl-input-padding: 10px; $gl-input-padding: 10px;
$gl-vert-padding: 6px; $gl-vert-padding: 6px;
$gl-padding-top: 10px; $gl-padding-top: 10px;
$gl-sidebar-padding: 22px;
/* /*
* Misc * Misc
......
...@@ -88,13 +88,7 @@ ...@@ -88,13 +88,7 @@
.user-name { .user-name {
display: inline-block; display: inline-block;
font-weight: bold; font-weight: 600;
}
.controls {
> .btn, > .dropdown {
margin-left: 5px;
}
} }
.dropdown { .dropdown {
......
...@@ -83,14 +83,6 @@ ...@@ -83,14 +83,6 @@
} }
} }
table.builds {
.build-link {
a {
color: $gl-dark-link-color;
}
}
}
.build-trace { .build-trace {
background: $ci-output-bg; background: $ci-output-bg;
color: $ci-text-color; color: $ci-text-color;
......
...@@ -38,33 +38,6 @@ ...@@ -38,33 +38,6 @@
margin-right: 15px; margin-right: 15px;
} }
} }
&.group-admin {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
.group-avatar, .group-details, .group-controls {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
.group-details {
flex: 1 1 auto;
flex-direction: column;
min-width: 0;
}
.group-controls {
align-items: center;
a {
margin-left: 5px;
}
}
}
} }
.ldap-group-links { .ldap-group-links {
......
...@@ -162,9 +162,15 @@ ...@@ -162,9 +162,15 @@
} }
.filtered-labels { .filtered-labels {
font-size: 0;
padding: 12px 16px;
.label-row { .label-row {
margin-top: 4px;
margin-bottom: 4px;
&:not(:last-child) { &:not(:last-child) {
margin-right: 5px; margin-right: 8px;
} }
} }
......
...@@ -73,11 +73,14 @@ ...@@ -73,11 +73,14 @@
color: #888; color: #888;
} }
&.ci-pending, &.ci-pending {
&.ci-running {
color: $gl-warning; color: $gl-warning;
} }
&.ci-running {
color: $blue-normal;
}
&.ci-failed, &.ci-failed,
&.ci-error { &.ci-error {
color: $gl-danger; color: $gl-danger;
......
.pipelines { .pipelines {
.stage { .stage {
max-width: 100px; max-width: 80px;
width: 80px;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.duration, .finished_at {
margin: 4px 0;
}
.commit-title { .commit-title {
margin: 0; margin: 0;
} }
...@@ -22,3 +19,156 @@ ...@@ -22,3 +19,156 @@
margin: 4px; margin: 4px;
} }
} }
.content-list {
&.pipelines,
&.builds-content-list {
width: 100%;
overflow: auto;
}
}
.table.builds {
min-width: 1100px;
tr {
th {
padding: 16px;
border: none;
}
}
tbody {
border-top-width: 1px;
}
.commit-link {
a:hover {
text-decoration: none;
}
}
.branch-commit {
.branch-name {
margin-left: 8px;
font-weight: bold;
max-width: 180px;
overflow: hidden;
display: inline-block;
white-space: nowrap;
vertical-align: top;
text-overflow: ellipsis;
}
svg {
margin: 0 6px;
height: 14px;
width: auto;
vertical-align: middle;
}
.commit-id {
color: $gl-link-color;
margin-right: 8px;
}
.commit-title {
margin-top: 4px;
max-width: 320px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.avatar {
margin-left: 0;
}
.label {
margin-right: 4px;
}
.label-container {
font-size: 0;
.label {
margin-top: 5px;
}
}
}
.duration,
.finished-at {
color: $table-text-gray;
margin: 4px 0;
.fa {
font-size: 12px;
}
svg {
height: 12px;
width: auto;
vertical-align: middle;
}
.fa,
svg {
margin-right: 5px;
}
}
.pipeline-actions {
.btn {
margin: 0;
color: $table-text-gray;
}
.cancel-retry-btns {
vertical-align: middle;
.btn:not(:first-child) {
margin-left: 8px;
}
}
.dropdown-toggle,
.dropdown-menu {
color: $table-text-gray;
.fa {
color: $table-text-gray;
margin-right: 6px;
font-size: 14px;
}
}
.btn-remove {
color: $white-light;
}
.btn-group {
&.open {
.btn-default {
background-color: $white-normal;
border-color: $border-white-normal;
}
}
}
}
.build-link {
a {
color: $gl-dark-link-color;
}
}
.btn-group.open .dropdown-toggle {
box-shadow: none;
}
}
...@@ -482,6 +482,10 @@ pre.light-well { ...@@ -482,6 +482,10 @@ pre.light-well {
a:hover { a:hover {
text-decoration: none; text-decoration: none;
} }
> span {
margin-left: 10px;
}
} }
} }
...@@ -639,3 +643,9 @@ pre.light-well { ...@@ -639,3 +643,9 @@ pre.light-well {
width: 300px; width: 300px;
} }
} }
.compare-form-group {
.dropdown-menu {
width: 300px;
}
}
...@@ -185,7 +185,7 @@ ...@@ -185,7 +185,7 @@
padding-right: $gl-padding + 15px; padding-right: $gl-padding + 15px;
} }
.btn-search { .btn-search, .btn-new {
width: 100%; width: 100%;
margin-top: 5px; margin-top: 5px;
......
...@@ -32,11 +32,15 @@ ...@@ -32,11 +32,15 @@
border-color: $gl-gray; border-color: $gl-gray;
} }
&.ci-pending, &.ci-pending {
&.ci-running {
color: $gl-warning; color: $gl-warning;
border-color: $gl-warning; border-color: $gl-warning;
} }
&.ci-running {
color: $blue-normal;
border-color: $blue-normal;
}
} }
.ci-status-icon-success { .ci-status-icon-success {
...@@ -45,10 +49,12 @@ ...@@ -45,10 +49,12 @@
.ci-status-icon-failed { .ci-status-icon-failed {
color: $gl-danger; color: $gl-danger;
} }
.ci-status-icon-running,
.ci-status-icon-pending { .ci-status-icon-pending {
color: $gl-warning; color: $gl-warning;
} }
.ci-status-icon-running {
color: $blue-normal;
}
.ci-status-icon-canceled, .ci-status-icon-canceled,
.ci-status-icon-disabled, .ci-status-icon-disabled,
.ci-status-icon-not-found, .ci-status-icon-not-found,
......
...@@ -23,12 +23,11 @@ ...@@ -23,12 +23,11 @@
} }
&:hover { &:hover {
cursor: pointer;
td { td {
background-color: $row-hover; background-color: $row-hover;
border-top: 1px solid $row-hover-border; border-top: 1px solid $row-hover-border;
border-bottom: 1px solid $row-hover-border; border-bottom: 1px solid $row-hover-border;
cursor: pointer;
} }
} }
......
...@@ -5,8 +5,10 @@ class Admin::BuildsController < Admin::ApplicationController ...@@ -5,8 +5,10 @@ class Admin::BuildsController < Admin::ApplicationController
@builds = @all_builds.order('created_at DESC') @builds = @all_builds.order('created_at DESC')
@builds = @builds =
case @scope case @scope
when 'pending'
@builds.pending.reverse_order
when 'running' when 'running'
@builds.running_or_pending.reverse_order @builds.running.reverse_order
when 'finished' when 'finished'
@builds.finished @builds.finished
else else
......
...@@ -344,10 +344,6 @@ class ApplicationController < ActionController::Base ...@@ -344,10 +344,6 @@ class ApplicationController < ActionController::Base
session[:skip_tfa] && session[:skip_tfa] > Time.current session[:skip_tfa] && session[:skip_tfa] > Time.current
end end
def browser_supports_u2f?
browser.chrome? && browser.version.to_i >= 41 && !browser.device.mobile?
end
def redirect_to_home_page_url? def redirect_to_home_page_url?
# If user is not signed-in and tries to access root_path - redirect him to landing page # If user is not signed-in and tries to access root_path - redirect him to landing page
# Don't redirect to the default URL to prevent endless redirections # Don't redirect to the default URL to prevent endless redirections
......
...@@ -57,7 +57,7 @@ module AuthenticatesWithTwoFactor ...@@ -57,7 +57,7 @@ module AuthenticatesWithTwoFactor
# Authenticate using the response from a U2F (universal 2nd factor) device # Authenticate using the response from a U2F (universal 2nd factor) device
def authenticate_with_two_factor_via_u2f(user) def authenticate_with_two_factor_via_u2f(user)
if U2fRegistration.authenticate(user, u2f_app_id, user_params[:device_response], session[:challenges]) if U2fRegistration.authenticate(user, u2f_app_id, user_params[:device_response], session[:challenge])
# Remove any lingering user data from login # Remove any lingering user data from login
session.delete(:otp_user_id) session.delete(:otp_user_id)
session.delete(:challenges) session.delete(:challenges)
...@@ -77,11 +77,9 @@ module AuthenticatesWithTwoFactor ...@@ -77,11 +77,9 @@ module AuthenticatesWithTwoFactor
if key_handles.present? if key_handles.present?
sign_requests = u2f.authentication_requests(key_handles) sign_requests = u2f.authentication_requests(key_handles)
challenges = sign_requests.map(&:challenge) session[:challenge] ||= u2f.challenge
session[:challenges] = challenges gon.push(u2f: { challenge: session[:challenge], app_id: u2f_app_id,
gon.push(u2f: { challenges: challenges, app_id: u2f_app_id, sign_requests: sign_requests })
sign_requests: sign_requests,
browser_supports_u2f: browser_supports_u2f? })
end end
end end
end end
class Dashboard::TodosController < Dashboard::ApplicationController class Dashboard::TodosController < Dashboard::ApplicationController
include TodosHelper
before_action :find_todos, only: [:index, :destroy_all] before_action :find_todos, only: [:index, :destroy_all]
def index def index
...@@ -13,7 +11,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController ...@@ -13,7 +11,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
respond_to do |format| respond_to do |format|
format.html { redirect_to dashboard_todos_path, notice: 'Todo was successfully marked as done.' } format.html { redirect_to dashboard_todos_path, notice: 'Todo was successfully marked as done.' }
format.js { head :ok } format.js { head :ok }
format.json { render json: { count: todos_pending_count, done_count: todos_done_count } } format.json { render json: todos_counts }
end end
end end
...@@ -23,7 +21,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController ...@@ -23,7 +21,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
respond_to do |format| respond_to do |format|
format.html { redirect_to dashboard_todos_path, notice: 'All todos were marked as done.' } format.html { redirect_to dashboard_todos_path, notice: 'All todos were marked as done.' }
format.js { head :ok } format.js { head :ok }
format.json { render json: { count: todos_pending_count, done_count: todos_done_count } } format.json { render json: todos_counts }
end end
end end
...@@ -36,4 +34,11 @@ class Dashboard::TodosController < Dashboard::ApplicationController ...@@ -36,4 +34,11 @@ class Dashboard::TodosController < Dashboard::ApplicationController
def find_todos def find_todos
@todos ||= TodosFinder.new(current_user, params).execute @todos ||= TodosFinder.new(current_user, params).execute
end end
def todos_counts
{
count: TodosFinder.new(current_user, state: :pending).execute.count,
done_count: TodosFinder.new(current_user, state: :done).execute.count
}
end
end end
...@@ -107,7 +107,11 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController ...@@ -107,7 +107,11 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
# Only allow properly saved users to login. # Only allow properly saved users to login.
if @user.persisted? && @user.valid? if @user.persisted? && @user.valid?
log_audit_event(@user, with: oauth['provider']) log_audit_event(@user, with: oauth['provider'])
if @user.two_factor_enabled?
prompt_for_two_factor(@user)
else
sign_in_and_redirect(@user) sign_in_and_redirect(@user)
end
else else
error_message = @user.errors.full_messages.to_sentence error_message = @user.errors.full_messages.to_sentence
......
...@@ -100,7 +100,6 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController ...@@ -100,7 +100,6 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
gon.push(u2f: { challenges: session[:challenges], app_id: u2f_app_id, gon.push(u2f: { challenges: session[:challenges], app_id: u2f_app_id,
register_requests: registration_requests, register_requests: registration_requests,
sign_requests: sign_requests, sign_requests: sign_requests })
browser_supports_u2f: browser_supports_u2f? })
end end
end end
...@@ -10,8 +10,10 @@ class Projects::BuildsController < Projects::ApplicationController ...@@ -10,8 +10,10 @@ class Projects::BuildsController < Projects::ApplicationController
@builds = @all_builds.order('created_at DESC') @builds = @all_builds.order('created_at DESC')
@builds = @builds =
case @scope case @scope
when 'pending'
@builds.pending.reverse_order
when 'running' when 'running'
@builds.running_or_pending.reverse_order @builds.running.reverse_order
when 'finished' when 'finished'
@builds.finished @builds.finished
else else
......
...@@ -5,7 +5,7 @@ class Projects::TodosController < Projects::ApplicationController ...@@ -5,7 +5,7 @@ class Projects::TodosController < Projects::ApplicationController
todo = TodoService.new.mark_todo(issuable, current_user) todo = TodoService.new.mark_todo(issuable, current_user)
render json: { render json: {
count: current_user.todos_pending_count, count: TodosFinder.new(current_user, state: :pending).execute.count,
delete_path: dashboard_todo_path(todo) delete_path: dashboard_todo_path(todo)
} }
end end
......
...@@ -5,7 +5,7 @@ class ProjectsController < Projects::ApplicationController ...@@ -5,7 +5,7 @@ class ProjectsController < Projects::ApplicationController
before_action :project, except: [:new, :create] before_action :project, except: [:new, :create]
before_action :repository, except: [:new, :create] before_action :repository, except: [:new, :create]
before_action :assign_ref_vars, only: [:show], if: :repo_exists? before_action :assign_ref_vars, only: [:show], if: :repo_exists?
before_action :tree, only: [:show], if: :project_view_files? before_action :tree, only: [:show], if: [:repo_exists?, :project_view_files?]
# Authorize # Authorize
before_action :authorize_admin_project!, only: [:edit, :update, :housekeeping, :download_export, :export, :remove_export, :generate_new_export] before_action :authorize_admin_project!, only: [:edit, :update, :housekeeping, :download_export, :export, :remove_export, :generate_new_export]
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
# action_id: integer # action_id: integer
# author_id: integer # author_id: integer
# project_id; integer # project_id; integer
# state: 'pending' or 'done' # state: 'pending' (default) or 'done'
# type: 'Issue' or 'MergeRequest' # type: 'Issue' or 'MergeRequest'
# #
...@@ -37,7 +37,7 @@ class TodosFinder ...@@ -37,7 +37,7 @@ class TodosFinder
private private
def action_id? def action_id?
action_id.present? && [Todo::ASSIGNED, Todo::MENTIONED, Todo::BUILD_FAILED, Todo::MARKED].include?(action_id.to_i) action_id.present? && Todo::ACTION_NAMES.has_key?(action_id.to_i)
end end
def action_id def action_id
......
...@@ -31,7 +31,7 @@ module AppearancesHelper ...@@ -31,7 +31,7 @@ module AppearancesHelper
end end
end end
def navbar_icon(icon_name, size: 16) def custom_icon(icon_name, size: 16)
render "shared/icons/#{icon_name}.svg", size: size render "shared/icons/#{icon_name}.svg", size: size
end end
end end
module BlobHelper module BlobHelper
def highlighter(blob_name, blob_content, repository: nil, nowrap: false) def highlight(blob_name, blob_content, repository: nil, plain: false)
Gitlab::Highlight.new(blob_name, blob_content, nowrap: nowrap, repository: repository) highlighted = Gitlab::Highlight.highlight(blob_name, blob_content, plain: plain, repository: repository)
end raw %(<pre class="code highlight"><code>#{highlighted}</code></pre>)
def highlight(blob_name, blob_content, repository: nil, nowrap: false, plain: false)
Gitlab::Highlight.highlight(blob_name, blob_content, nowrap: nowrap, plain: plain, repository: repository)
end end
def no_highlight_files def no_highlight_files
......
...@@ -29,8 +29,10 @@ module CiStatusHelper ...@@ -29,8 +29,10 @@ module CiStatusHelper
'check' 'check'
when 'failed' when 'failed'
'close' 'close'
when 'running', 'pending' when 'pending'
'clock-o' 'clock-o'
when 'running'
'spinner'
else else
'circle' 'circle'
end end
......
...@@ -61,7 +61,7 @@ module IssuablesHelper ...@@ -61,7 +61,7 @@ module IssuablesHelper
output = content_tag :strong, "#{text} #{issuable.to_reference}", class: "identifier" output = content_tag :strong, "#{text} #{issuable.to_reference}", class: "identifier"
output << " opened #{time_ago_with_tooltip(issuable.created_at)} by ".html_safe output << " opened #{time_ago_with_tooltip(issuable.created_at)} by ".html_safe
output << content_tag(:strong) do output << content_tag(:strong) do
author_output = link_to_member(project, issuable.author, size: 24, mobile_classes: "hidden-xs") author_output = link_to_member(project, issuable.author, size: 24, mobile_classes: "hidden-xs", tooltip: true)
author_output << link_to_member(project, issuable.author, size: 24, by_username: true, avatar: false, mobile_classes: "hidden-sm hidden-md hidden-lg") author_output << link_to_member(project, issuable.author, size: 24, by_username: true, avatar: false, mobile_classes: "hidden-sm hidden-md hidden-lg")
end end
end end
......
...@@ -19,7 +19,7 @@ module ProjectsHelper ...@@ -19,7 +19,7 @@ module ProjectsHelper
end end
def link_to_member(project, author, opts = {}, &block) def link_to_member(project, author, opts = {}, &block)
default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name" } default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name", tooltip: false }
opts = default_opts.merge(opts) opts = default_opts.merge(opts)
return "(deleted)" unless author return "(deleted)" unless author
...@@ -33,7 +33,8 @@ module ProjectsHelper ...@@ -33,7 +33,8 @@ module ProjectsHelper
if opts[:by_username] if opts[:by_username]
author_html << content_tag(:span, sanitize("@#{author.username}"), class: opts[:author_class]) if opts[:name] author_html << content_tag(:span, sanitize("@#{author.username}"), class: opts[:author_class]) if opts[:name]
else else
author_html << content_tag(:span, sanitize(author.name), class: opts[:author_class]) if opts[:name] tooltip_data = { placement: 'top' }
author_html << content_tag(:span, sanitize(author.name), class: [opts[:author_class], ('has-tooltip' if opts[:tooltip])], title: (author.to_reference if opts[:tooltip]), data: (tooltip_data if opts[:tooltip])) if opts[:name]
end end
author_html << capture(&block) if block author_html << capture(&block) if block
...@@ -60,7 +61,7 @@ module ProjectsHelper ...@@ -60,7 +61,7 @@ module ProjectsHelper
project_link = link_to simple_sanitize(project.name), project_path(project), { class: "project-item-select-holder" } project_link = link_to simple_sanitize(project.name), project_path(project), { class: "project-item-select-holder" }
if current_user if current_user
project_link << icon("chevron-down", class: "dropdown-toggle-caret js-projects-dropdown-toggle", data: { target: ".js-dropdown-menu-projects", toggle: "dropdown" }) project_link << icon("chevron-down", class: "dropdown-toggle-caret js-projects-dropdown-toggle", aria: { label: "Toggle switch project dropdown" }, data: { target: ".js-dropdown-menu-projects", toggle: "dropdown" })
end end
full_title = "#{namespace_link} / #{project_link}".html_safe full_title = "#{namespace_link} / #{project_link}".html_safe
......
...@@ -45,7 +45,7 @@ module SearchHelper ...@@ -45,7 +45,7 @@ module SearchHelper
[ [
{ category: "Help", label: "API Help", url: help_page_path("api/README") }, { category: "Help", label: "API Help", url: help_page_path("api/README") },
{ category: "Help", label: "Markdown Help", url: help_page_path("markdown/markdown") }, { category: "Help", label: "Markdown Help", url: help_page_path("markdown/markdown") },
{ category: "Help", label: "Permissions Help", url: help_page_path("permissions/permissions") }, { category: "Help", label: "Permissions Help", url: help_page_path("user/permissions") },
{ category: "Help", label: "Public Access Help", url: help_page_path("public_access/public_access") }, { category: "Help", label: "Public Access Help", url: help_page_path("public_access/public_access") },
{ category: "Help", label: "Rake Tasks Help", url: help_page_path("raketasks/README") }, { category: "Help", label: "Rake Tasks Help", url: help_page_path("raketasks/README") },
{ category: "Help", label: "SSH Keys Help", url: help_page_path("ssh/README") }, { category: "Help", label: "SSH Keys Help", url: help_page_path("ssh/README") },
......
module TodosHelper module TodosHelper
def todos_pending_count def todos_pending_count
TodosFinder.new(current_user, state: :pending).execute.count @todos_pending_count ||= TodosFinder.new(current_user, state: :pending).execute.count
end end
def todos_done_count def todos_done_count
TodosFinder.new(current_user, state: :done).execute.count @todos_done_count ||= TodosFinder.new(current_user, state: :done).execute.count
end end
def todo_action_name(todo) def todo_action_name(todo)
...@@ -13,6 +13,7 @@ module TodosHelper ...@@ -13,6 +13,7 @@ module TodosHelper
when Todo::MENTIONED then 'mentioned you on' when Todo::MENTIONED then 'mentioned you on'
when Todo::BUILD_FAILED then 'The build failed for your' when Todo::BUILD_FAILED then 'The build failed for your'
when Todo::MARKED then 'added a todo for' when Todo::MARKED then 'added a todo for'
when Todo::APPROVAL_REQUIRED then 'set you as an approver for'
end end
end end
......
module U2fHelper
def inject_u2f_api?
browser.chrome? && browser.version.to_i >= 41 && !browser.device.mobile?
end
end
...@@ -204,7 +204,8 @@ class Ability ...@@ -204,7 +204,8 @@ class Ability
:download_code, :download_code,
:fork_project, :fork_project,
:read_commit_status, :read_commit_status,
:read_pipeline :read_pipeline,
:read_container_image
] ]
end end
......
...@@ -5,6 +5,7 @@ module Ci ...@@ -5,6 +5,7 @@ module Ci
belongs_to :erased_by, class_name: 'User' belongs_to :erased_by, class_name: 'User'
serialize :options serialize :options
serialize :yaml_variables
validates :coverage, numericality: true, allow_blank: true validates :coverage, numericality: true, allow_blank: true
validates_presence_of :ref validates_presence_of :ref
...@@ -52,7 +53,10 @@ module Ci ...@@ -52,7 +53,10 @@ module Ci
new_build.stage = build.stage new_build.stage = build.stage
new_build.stage_idx = build.stage_idx new_build.stage_idx = build.stage_idx
new_build.trigger_request = build.trigger_request new_build.trigger_request = build.trigger_request
new_build.yaml_variables = build.yaml_variables
new_build.when = build.when
new_build.user = user new_build.user = user
new_build.environment = build.environment
new_build.save new_build.save
MergeRequests::AddTodoWhenBuildFailsService.new(build.project, nil).close(new_build) MergeRequests::AddTodoWhenBuildFailsService.new(build.project, nil).close(new_build)
new_build new_build
...@@ -117,7 +121,12 @@ module Ci ...@@ -117,7 +121,12 @@ module Ci
end end
def variables def variables
predefined_variables + yaml_variables + project_variables + trigger_variables variables = []
variables += predefined_variables
variables += yaml_variables if yaml_variables
variables += project_variables
variables += trigger_variables
variables
end end
def merge_request def merge_request
...@@ -394,30 +403,6 @@ module Ci ...@@ -394,30 +403,6 @@ module Ci
self.update(erased_by: user, erased_at: Time.now, artifacts_expire_at: nil) self.update(erased_by: user, erased_at: Time.now, artifacts_expire_at: nil)
end end
def yaml_variables
global_yaml_variables + job_yaml_variables
end
def global_yaml_variables
if pipeline.config_processor
pipeline.config_processor.global_variables.map do |key, value|
{ key: key, value: value, public: true }
end
else
[]
end
end
def job_yaml_variables
if pipeline.config_processor
pipeline.config_processor.job_variables(name).map do |key, value|
{ key: key, value: value, public: true }
end
else
[]
end
end
def project_variables def project_variables
project.variables.map do |variable| project.variables.map do |variable|
{ key: variable.key, value: variable.value, public: false } { key: variable.key, value: variable.value, public: false }
......
...@@ -6,6 +6,8 @@ module Ci ...@@ -6,6 +6,8 @@ module Ci
self.table_name = 'ci_commits' self.table_name = 'ci_commits'
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
belongs_to :user
has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id
has_many :builds, class_name: 'Ci::Build', foreign_key: :commit_id has_many :builds, class_name: 'Ci::Build', foreign_key: :commit_id
has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest', foreign_key: :commit_id has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest', foreign_key: :commit_id
...@@ -215,6 +217,8 @@ module Ci ...@@ -215,6 +217,8 @@ module Ci
end end
def keep_around_commits def keep_around_commits
return unless project
project.repository.keep_around(self.sha) project.repository.keep_around(self.sha)
project.repository.keep_around(self.before_sha) project.repository.keep_around(self.before_sha)
end end
......
...@@ -65,8 +65,7 @@ module Awardable ...@@ -65,8 +65,7 @@ module Awardable
def create_award_emoji(name, current_user) def create_award_emoji(name, current_user)
return unless emoji_awardable? return unless emoji_awardable?
award_emoji.create(name: normalize_name(name), user: current_user)
award_emoji.create(name: name, user: current_user)
end end
def remove_award_emoji(name, current_user) def remove_award_emoji(name, current_user)
...@@ -80,4 +79,10 @@ module Awardable ...@@ -80,4 +79,10 @@ module Awardable
create_award_emoji(emoji_name, current_user) create_award_emoji(emoji_name, current_user)
end end
end end
private
def normalize_name(name)
Gitlab::AwardEmoji.normalize_emoji_name(name)
end
end end
...@@ -14,14 +14,14 @@ module Mentionable ...@@ -14,14 +14,14 @@ module Mentionable
attr = attr.to_s attr = attr.to_s
mentionable_attrs << [attr, options] mentionable_attrs << [attr, options]
end end
end
included do
# Accessor for attributes marked mentionable. # Accessor for attributes marked mentionable.
def mentionable_attrs cattr_accessor :mentionable_attrs, instance_accessor: false do
@mentionable_attrs ||= [] []
end
end end
included do
if self < Participable if self < Participable
participant -> (user, ext) { all_references(user, extractor: ext) } participant -> (user, ext) { all_references(user, extractor: ext) }
end end
......
...@@ -41,9 +41,12 @@ module Participable ...@@ -41,9 +41,12 @@ module Participable
def participant(attr) def participant(attr)
participant_attrs << attr participant_attrs << attr
end end
end
def participant_attrs included do
@participant_attrs ||= [] # Accessor for participant attributes.
cattr_accessor :participant_attrs, instance_accessor: false do
[]
end end
end end
......
...@@ -52,14 +52,17 @@ class Label < ActiveRecord::Base ...@@ -52,14 +52,17 @@ class Label < ActiveRecord::Base
# This pattern supports cross-project references. # This pattern supports cross-project references.
# #
def self.reference_pattern def self.reference_pattern
# NOTE: The id pattern only matches when all characters on the expression
# are digits, so it will match ~2 but not ~2fa because that's probably a
# label name and we want it to be matched as such.
@reference_pattern ||= %r{ @reference_pattern ||= %r{
(#{Project.reference_pattern})? (#{Project.reference_pattern})?
#{Regexp.escape(reference_prefix)} #{Regexp.escape(reference_prefix)}
(?: (?:
(?<label_id>\d+) | # Integer-based label ID, or (?<label_id>\d+(?!\S\w)\b) | # Integer-based label ID, or
(?<label_name> (?<label_name>
[A-Za-z0-9_\-\?&]+ | # String-based single-word label title, or [A-Za-z0-9_\-\?\.&]+ | # String-based single-word label title, or
"[^,]+" # String-based multi-word label surrounded in quotes ".+?" # String-based multi-word label surrounded in quotes
) )
) )
}x }x
......
...@@ -38,7 +38,7 @@ class LegacyDiffNote < Note ...@@ -38,7 +38,7 @@ class LegacyDiffNote < Note
end end
def diff_line def diff_line
@diff_line ||= diff_file.line_for_line_code(self.line_code) @diff_line ||= diff_file.line_for_line_code(self.line_code) if diff_file
end end
def for_line?(line) def for_line?(line)
...@@ -55,7 +55,7 @@ class LegacyDiffNote < Note ...@@ -55,7 +55,7 @@ class LegacyDiffNote < Note
def active? def active?
return @active if defined?(@active) return @active if defined?(@active)
return true if for_commit? return true if for_commit?
return true unless self.diff return true unless diff_line
return false unless noteable return false unless noteable
noteable_diff = find_noteable_diff noteable_diff = find_noteable_diff
......
...@@ -229,8 +229,7 @@ class Note < ActiveRecord::Base ...@@ -229,8 +229,7 @@ class Note < ActiveRecord::Base
end end
def award_emoji_name def award_emoji_name
original_name = note.match(Banzai::Filter::EmojiFilter.emoji_pattern)[1] note.match(Banzai::Filter::EmojiFilter.emoji_pattern)[1]
Gitlab::AwardEmoji.normalize_emoji_name(original_name)
end end
private private
......
...@@ -464,8 +464,8 @@ class Project < ActiveRecord::Base ...@@ -464,8 +464,8 @@ class Project < ActiveRecord::Base
return super(value) unless Gitlab::UrlSanitizer.valid?(value) return super(value) unless Gitlab::UrlSanitizer.valid?(value)
import_url = Gitlab::UrlSanitizer.new(value) import_url = Gitlab::UrlSanitizer.new(value)
create_or_update_import_data(credentials: import_url.credentials)
super(import_url.sanitized_url) super(import_url.sanitized_url)
create_or_update_import_data(credentials: import_url.credentials)
end end
def import_url def import_url
...@@ -477,7 +477,13 @@ class Project < ActiveRecord::Base ...@@ -477,7 +477,13 @@ class Project < ActiveRecord::Base
end end
end end
def valid_import_url?
valid? || errors.messages[:import_url].nil?
end
def create_or_update_import_data(data: nil, credentials: nil) def create_or_update_import_data(data: nil, credentials: nil)
return unless import_url.present? && valid_import_url?
project_import_data = import_data || build_import_data project_import_data = import_data || build_import_data
if data if data
project_import_data.data ||= {} project_import_data.data ||= {}
...@@ -1032,8 +1038,8 @@ class Project < ActiveRecord::Base ...@@ -1032,8 +1038,8 @@ class Project < ActiveRecord::Base
pipelines.order(id: :desc).find_by(sha: sha, ref: ref) pipelines.order(id: :desc).find_by(sha: sha, ref: ref)
end end
def ensure_pipeline(sha, ref) def ensure_pipeline(sha, ref, current_user = nil)
pipeline(sha, ref) || pipelines.create(sha: sha, ref: ref) pipeline(sha, ref) || pipelines.create(sha: sha, ref: ref, user: current_user)
end end
def enable_ci def enable_ci
......
...@@ -3,12 +3,14 @@ class Todo < ActiveRecord::Base ...@@ -3,12 +3,14 @@ class Todo < ActiveRecord::Base
MENTIONED = 2 MENTIONED = 2
BUILD_FAILED = 3 BUILD_FAILED = 3
MARKED = 4 MARKED = 4
APPROVAL_REQUIRED = 5 # This is an EE-only feature
ACTION_NAMES = { ACTION_NAMES = {
ASSIGNED => :assigned, ASSIGNED => :assigned,
MENTIONED => :mentioned, MENTIONED => :mentioned,
BUILD_FAILED => :build_failed, BUILD_FAILED => :build_failed,
MARKED => :marked MARKED => :marked,
APPROVAL_REQUIRED => :approval_required
} }
belongs_to :author, class_name: "User" belongs_to :author, class_name: "User"
......
...@@ -85,9 +85,10 @@ class User < ActiveRecord::Base ...@@ -85,9 +85,10 @@ class User < ActiveRecord::Base
has_one :abuse_report, dependent: :destroy has_one :abuse_report, dependent: :destroy
has_many :spam_logs, dependent: :destroy has_many :spam_logs, dependent: :destroy
has_many :builds, dependent: :nullify, class_name: 'Ci::Build' has_many :builds, dependent: :nullify, class_name: 'Ci::Build'
has_many :pipelines, dependent: :nullify, class_name: 'Ci::Pipeline'
has_many :todos, dependent: :destroy has_many :todos, dependent: :destroy
has_many :notification_settings, dependent: :destroy has_many :notification_settings, dependent: :destroy
has_many :award_emoji, as: :awardable, dependent: :destroy has_many :award_emoji, dependent: :destroy
# #
# Validations # Validations
......
...@@ -36,7 +36,9 @@ module Ci ...@@ -36,7 +36,9 @@ module Ci
:allow_failure, :allow_failure,
:stage, :stage,
:stage_idx, :stage_idx,
:environment) :environment,
:when,
:yaml_variables)
build_attrs.merge!(pipeline: @pipeline, build_attrs.merge!(pipeline: @pipeline,
ref: @pipeline.ref, ref: @pipeline.ref,
......
...@@ -2,6 +2,7 @@ module Ci ...@@ -2,6 +2,7 @@ module Ci
class CreatePipelineService < BaseService class CreatePipelineService < BaseService
def execute def execute
pipeline = project.pipelines.new(params) pipeline = project.pipelines.new(params)
pipeline.user = current_user
unless ref_names.include?(params[:ref]) unless ref_names.include?(params[:ref])
pipeline.errors.add(:base, 'Reference not found') pipeline.errors.add(:base, 'Reference not found')
......
...@@ -14,7 +14,13 @@ class CreateCommitBuildsService ...@@ -14,7 +14,13 @@ class CreateCommitBuildsService
return false return false
end end
@pipeline = Ci::Pipeline.new(project: project, sha: sha, ref: ref, before_sha: before_sha, tag: tag) @pipeline = Ci::Pipeline.new(
project: project,
sha: sha,
ref: ref,
before_sha: before_sha,
tag: tag,
user: user)
## ##
# Skip creating pipeline if no gitlab-ci.yml is found # Skip creating pipeline if no gitlab-ci.yml is found
......
...@@ -8,7 +8,6 @@ module Notes ...@@ -8,7 +8,6 @@ module Notes
if note.award_emoji? if note.award_emoji?
noteable = note.noteable noteable = note.noteable
todo_service.new_award_emoji(noteable, current_user) todo_service.new_award_emoji(noteable, current_user)
return noteable.create_award_emoji(note.award_emoji_name, current_user) return noteable.create_award_emoji(note.award_emoji_name, current_user)
end end
......
...@@ -22,11 +22,7 @@ module Projects ...@@ -22,11 +22,7 @@ module Projects
def execute def execute
raise LeaseTaken unless try_obtain_lease raise LeaseTaken unless try_obtain_lease
GitGarbageCollectWorker.perform_async(@project.id) execute_gitlab_shell_gc
ensure
Gitlab::Metrics.measure(:reset_pushes_since_gc) do
update_pushes_since_gc(0)
end
end end
def needed? def needed?
...@@ -34,18 +30,26 @@ module Projects ...@@ -34,18 +30,26 @@ module Projects
end end
def increment! def increment!
if Gitlab::ExclusiveLease.new("project_housekeeping:increment!:#{@project.id}", timeout: 60).try_obtain
Gitlab::Metrics.measure(:increment_pushes_since_gc) do Gitlab::Metrics.measure(:increment_pushes_since_gc) do
update_pushes_since_gc(@project.pushes_since_gc + 1) update_pushes_since_gc(@project.pushes_since_gc + 1)
end end
end end
end
private private
def execute_gitlab_shell_gc
GitGarbageCollectWorker.perform_async(@project.id)
ensure
Gitlab::Metrics.measure(:reset_pushes_since_gc) do
update_pushes_since_gc(0)
end
end
def update_pushes_since_gc(new_value) def update_pushes_since_gc(new_value)
if Gitlab::ExclusiveLease.new("project_housekeeping:update_pushes_since_gc:#{project.id}", timeout: 60).try_obtain
@project.update_column(:pushes_since_gc, new_value) @project.update_column(:pushes_since_gc, new_value)
end end
end
def try_obtain_lease def try_obtain_lease
Gitlab::Metrics.measure(:obtain_housekeeping_lease) do Gitlab::Metrics.measure(:obtain_housekeeping_lease) do
......
...@@ -10,7 +10,7 @@ module Projects ...@@ -10,7 +10,7 @@ module Projects
def save_all def save_all
if [version_saver, project_tree_saver, uploads_saver, repo_saver, wiki_repo_saver].all?(&:save) if [version_saver, project_tree_saver, uploads_saver, repo_saver, wiki_repo_saver].all?(&:save)
Gitlab::ImportExport::Saver.save(shared: @shared) Gitlab::ImportExport::Saver.save(project: project, shared: @shared)
notify_success notify_success
else else
cleanup_and_notify cleanup_and_notify
......
...@@ -43,7 +43,7 @@ module Projects ...@@ -43,7 +43,7 @@ module Projects
def import_repository def import_repository
begin begin
gitlab_shell.import_repository(project.repository_storage_path, project.path_with_namespace, project.import_url) gitlab_shell.import_repository(project.repository_storage_path, project.path_with_namespace, project.import_url)
rescue Gitlab::Shell::Error => e rescue => e
raise Error, "Error importing repository #{project.import_url} into #{project.path_with_namespace} - #{e.message}" raise Error, "Error importing repository #{project.import_url} into #{project.path_with_namespace} - #{e.message}"
end end
end end
......
...@@ -194,7 +194,7 @@ class TodoService ...@@ -194,7 +194,7 @@ class TodoService
end end
def create_assignment_todo(issuable, author) def create_assignment_todo(issuable, author)
if issuable.assignee && issuable.assignee != author if issuable.assignee
attributes = attributes_for_todo(issuable.project, issuable, author, Todo::ASSIGNED) attributes = attributes_for_todo(issuable.project, issuable, author, Todo::ASSIGNED)
create_todos(issuable.assignee, attributes) create_todos(issuable.assignee, attributes)
end end
...@@ -239,7 +239,6 @@ class TodoService ...@@ -239,7 +239,6 @@ class TodoService
def filter_mentioned_users(project, target, author) def filter_mentioned_users(project, target, author)
mentioned_users = target.mentioned_users(author) mentioned_users = target.mentioned_users(author)
mentioned_users = reject_users_without_access(mentioned_users, project, target) mentioned_users = reject_users_without_access(mentioned_users, project, target)
mentioned_users.delete(author)
mentioned_users.uniq mentioned_users.uniq
end end
......
- project = build.project - project = build.project
%tr.build %tr.build.commit
%td.status %td.status
= ci_status_with_icon(build.status) = ci_status_with_icon(build.status)
%td.build-link %td
.branch-commit
- if can?(current_user, :read_build, build.project) - if can?(current_user, :read_build, build.project)
= link_to namespace_project_build_url(build.project.namespace, build.project, build) do = link_to namespace_project_build_url(build.project.namespace, build.project, build) do
%strong Build ##{build.id} %span.build-link ##{build.id}
- else - else
%strong Build ##{build.id} %span.build-link ##{build.id}
- if build.stuck? - if build.stuck?
%i.fa.fa-warning.text-warning %i.fa.fa-warning.text-warning
%td
- if project
= link_to project.name_with_namespace, admin_namespace_project_path(project.namespace, project)
%td
= link_to build.short_sha, namespace_project_commit_path(build.project.namespace, build.project, build.sha), class: "monospace"
%td
- if build.ref - if build.ref
= link_to build.ref, namespace_project_commits_path(build.project.namespace, build.project, build.ref) = link_to build.ref, namespace_project_commits_path(build.project.namespace, build.project, build.ref), class: "monospace branch-name"
- else - else
.light none .light none
= custom_icon("icon_commit")
%td = link_to build.short_sha, namespace_project_commit_path(build.project.namespace, build.project, build.sha), class: "monospace commit-id"
- if build.try(:runner)
= runner_link(build.runner)
- else
.light none
%td
#{build.stage} / #{build.name}
%td .label-container
- if build.tags.any? - if build.tags.any?
- build.tags.each do |tag| - build.tags.each do |tag|
%span.label.label-primary %span.label.label-primary
...@@ -45,12 +32,28 @@ ...@@ -45,12 +32,28 @@
- if build.try(:allow_failure) - if build.try(:allow_failure)
%span.label.label-danger allowed to fail %span.label.label-danger allowed to fail
%td.duration %td
- if project
= link_to project.name_with_namespace, admin_namespace_project_path(project.namespace, project)
%td
- if build.try(:runner)
= runner_link(build.runner)
- else
.light none
%td
#{build.stage} / #{build.name}
%td
- if build.duration - if build.duration
#{duration_in_words(build.finished_at, build.started_at)} %p.duration
= custom_icon("icon_timer")
= duration_in_numbers(build.finished_at, build.started_at)
%td.timestamp
- if build.finished_at - if build.finished_at
%p.finished-at
= icon("calendar")
%span #{time_ago_with_tooltip(build.finished_at)} %span #{time_ago_with_tooltip(build.finished_at)}
- if defined?(coverage) && coverage - if defined?(coverage) && coverage
......
...@@ -10,15 +10,20 @@ ...@@ -10,15 +10,20 @@
All All
%span.badge.js-totalbuilds-count= @all_builds.count(:id) %span.badge.js-totalbuilds-count= @all_builds.count(:id)
%li{class: ('active' if @scope == 'pending')}
= link_to admin_builds_path(scope: :pending) do
Pending
%span.badge= number_with_delimiter(@all_builds.pending.count(:id))
%li{class: ('active' if @scope == 'running')} %li{class: ('active' if @scope == 'running')}
= link_to admin_builds_path(scope: :running) do = link_to admin_builds_path(scope: :running) do
Running Running
%span.badge.js-running-count= number_with_delimiter(@all_builds.running_or_pending.count(:id)) %span.badge= number_with_delimiter(@all_builds.running.count(:id))
%li{class: ('active' if @scope == 'finished')} %li{class: ('active' if @scope == 'finished')}
= link_to admin_builds_path(scope: :finished) do = link_to admin_builds_path(scope: :finished) do
Finished Finished
%span.badge.js-running-count= number_with_delimiter(@all_builds.finished.count(:id)) %span.badge= number_with_delimiter(@all_builds.finished.count(:id))
.nav-controls .nav-controls
- if @all_builds.running_or_pending.any? - if @all_builds.running_or_pending.any?
...@@ -27,7 +32,7 @@ ...@@ -27,7 +32,7 @@
.row-content-block.second-block .row-content-block.second-block
#{(@scope || 'all').capitalize} builds #{(@scope || 'all').capitalize} builds
%ul.content-list %ul.content-list.builds-content-list
- if @builds.blank? - if @builds.blank?
%li %li
.nothing-here-block No builds to show .nothing-here-block No builds to show
...@@ -37,15 +42,11 @@ ...@@ -37,15 +42,11 @@
%thead %thead
%tr %tr
%th Status %th Status
%th Build ID
%th Project
%th Commit %th Commit
%th Ref %th Project
%th Runner %th Runner
%th Name %th Name
%th Tags %th
%th Duration
%th Finished at
%th %th
- @builds.each do |build| - @builds.each do |build|
......
- css_class = '' unless local_assigns[:css_class] - css_class = 'no-description' if group.description.blank?
%li.group-row.group-admin{ class: css_class } %li.group-row{ class: css_class }
.group-avatar .controls
= image_tag group_icon(group), class: 'avatar hidden-xs' = link_to 'Edit', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: 'btn'
.group-details = link_to 'Delete', [:admin, group], data: { confirm: "Are you sure you want to remove #{group.name}?" }, method: :delete, class: 'btn btn-remove'
.stats
%span
= icon('bookmark')
= number_with_delimiter(group.projects.count)
%span
= icon('users')
= number_with_delimiter(group.users.count)
%span.visibility-icon.has-tooltip{data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group)}
= visibility_level_icon(group.visibility_level, fw: false)
= image_tag group_icon(group), class: "avatar s40 hidden-xs"
.title .title
= link_to [:admin, group], class: 'group-name' do = link_to [:admin, group], class: 'group-name' do
= group.name = group.name
.group-stats
%span>= pluralize(number_with_delimiter(group.projects.count), 'project')
,
%span= pluralize(number_with_delimiter(group.users.count), 'member')
- if group.description.present? - if group.description.present?
.description .description
= markdown(group.description, pipeline: :description) = markdown(group.description, pipeline: :description)
.group-controls.hidden-xs
= link_to 'Edit', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: 'btn'
= link_to 'Delete', [:admin, group], data: { confirm: "Are you sure you want to remove #{group.name}?" }, method: :delete, class: 'btn btn-remove'
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
.panel-body.form-holder .panel-body.form-holder
%p.light %p.light
Read more about project permissions Read more about project permissions
%strong= link_to "here", help_page_path("permissions/permissions"), class: "vlink" %strong= link_to "here", help_page_path("user/permissions"), class: "vlink"
= form_tag members_update_admin_group_path(@group), id: "new_project_member", class: "bulk_import", method: :put do = form_tag members_update_admin_group_path(@group), id: "new_project_member", class: "bulk_import", method: :put do
%div %div
......
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
%ul.projects-list.content-list %ul.projects-list.content-list
- @projects.each_with_index do |project| - @projects.each_with_index do |project|
%li.project-row %li.project-row
.controls.pull-right .controls
- if project.archived - if project.archived
%span.label.label-warning archived %span.label.label-warning archived
%span.label.label-gray %span.label.label-gray
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
%span It's you! %span It's you!
.user-email .user-email
= mail_to user.email, user.email = mail_to user.email, user.email
.controls.pull-right .controls
= link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: 'btn' = link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: 'btn'
- unless user == current_user - unless user == current_user
.dropdown.inline .dropdown.inline
......
- publicish_project_count = ProjectsFinder.new.execute(current_user).count - publicish_project_count = ProjectsFinder.new.execute(current_user).count
%h3.page-title Welcome to GitLab! .blank-state.blank-state-welcome
%p.light Self hosted Git management application. %h2.blank-state-welcome-title
%hr Welcome to GitLab
%div %p.blank-state-text
.dashboard-intro-icon Code, test, and deploy together
%i.fa.fa-bookmark-o .blank-state
.dashboard-intro-text .blank-state-icon
%p.slead = custom_icon("project", size: 50)
You don't have access to any projects right now. %h3.blank-state-title
%br You don't have access to any projects right now
%p.blank-state-text
- if current_user.can_create_project? - if current_user.can_create_project?
You can create up to You can create up to
%strong= pluralize(number_with_delimiter(current_user.projects_limit), "project") + "." %strong= number_with_delimiter(current_user.projects_limit)
= succeed "." do
= "project".pluralize(current_user.projects_limit)
- else - else
If you are added to a project, it will be displayed here. If you are added to a project, it will be displayed here.
- if current_user.can_create_project? - if current_user.can_create_project?
.link_holder
= link_to new_project_path, class: "btn btn-new" do = link_to new_project_path, class: "btn btn-new" do
= icon('plus') New project
New Project
- if current_user.can_create_group? - if current_user.can_create_group?
%hr .blank-state
%div .blank-state-icon
.dashboard-intro-icon = custom_icon("group", size: 50)
%i.fa.fa-users %h3.blank-state-title
.dashboard-intro-text
%p.slead
You can create a group for several dependent projects. You can create a group for several dependent projects.
%br %p.blank-state-text
Groups are the best way to manage projects and members. Groups are the best way to manage projects and members.
.link_holder
= link_to new_group_path, class: "btn btn-new" do = link_to new_group_path, class: "btn btn-new" do
%i.fa.fa-plus New group
New Group
-if publicish_project_count > 0 -if publicish_project_count > 0
%hr .blank-state
%div .blank-state-icon
.dashboard-intro-icon = icon("globe")
%i.fa.fa-globe %h3.blank-state-title
.dashboard-intro-text
%p.slead
There are There are
%strong= number_with_delimiter(publicish_project_count) = number_with_delimiter(publicish_project_count)
public projects on this server. public projects on this server.
%br %p.blank-state-text
Public projects are an easy way to allow everyone to have read-only access. Public projects are an easy way to allow everyone to have read-only access.
.link_holder
= link_to trending_explore_projects_path, class: "btn btn-new" do = link_to trending_explore_projects_path, class: "btn btn-new" do
Browse public projects Browse projects
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
- page_title "Projects" - page_title "Projects"
- header_title "Projects", dashboard_projects_path - header_title "Projects", dashboard_projects_path
= render 'dashboard/projects_head' - if @projects.any? || params[:filter_projects]
= render 'dashboard/projects_head'
- if @last_push - if @last_push
= render "events/event_last_push", event: @last_push = render "events/event_last_push", event: @last_push
......
...@@ -9,14 +9,14 @@ ...@@ -9,14 +9,14 @@
%span %span
To do To do
%span.badge %span.badge
= todos_pending_count = number_with_delimiter(todos_pending_count)
- todo_done_active = ('active' if params[:state] == 'done') - todo_done_active = ('active' if params[:state] == 'done')
%li{class: "todos-done #{todo_done_active}"} %li{class: "todos-done #{todo_done_active}"}
= link_to todos_filter_path(state: 'done') do = link_to todos_filter_path(state: 'done') do
%span %span
Done Done
%span.badge %span.badge
= todos_done_count = number_with_delimiter(todos_done_count)
.nav-controls .nav-controls
- if @todos.any?(&:pending?) - if @todos.any?(&:pending?)
......
- if inject_u2f_api?
- content_for :page_specific_javascripts do
= page_specific_javascript_tag('u2f.js')
%div %div
.login-box .login-box
.login-heading .login-heading
......
...@@ -3,4 +3,4 @@ ...@@ -3,4 +3,4 @@
%h3 Access Denied %h3 Access Denied
%hr %hr
%p You are not allowed to access this page. %p You are not allowed to access this page.
%p Read more about project permissions #{link_to "here", help_page_path("permissions/permissions"), class: "vlink"} %p Read more about project permissions #{link_to "here", help_page_path("user/permissions"), class: "vlink"}
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
= select_tag :access_level, options_for_select(GroupMember.access_level_roles, @group_member.access_level), class: "project-access-select select2" = select_tag :access_level, options_for_select(GroupMember.access_level_roles, @group_member.access_level), class: "project-access-select select2"
.help-block .help-block
Read more about role permissions Read more about role permissions
%strong= link_to "here", help_page_path("permissions/permissions"), class: "vlink" %strong= link_to "here", help_page_path("user/permissions"), class: "vlink"
.form-actions .form-actions
= f.submit 'Add users to group', class: "btn btn-create" = f.submit 'Add users to group', class: "btn btn-create"
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
.cover-block.groups-cover-block .cover-block.groups-cover-block
%div{ class: container_class } %div{ class: container_class }
= link_to group_icon(@group), target: '_blank' do
= image_tag group_icon(@group), class: "avatar group-avatar s70" = image_tag group_icon(@group), class: "avatar group-avatar s70"
.group-info .group-info
.cover-title .cover-title
......
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
%td.shortcut %td.shortcut
.key s .key s
%td Focus Search %td Focus Search
%tr
%td.shortcut
.key f
%td Focus Filter
%tr %tr
%td.shortcut %td.shortcut
.key ? .key ?
......
= link_to '#', class: 'nav-header-btn text-center toggle-nav-collapse', title: "Open/Close" do
%span.sr-only Toggle navigation
= icon('bars')
.page-with-sidebar{ class: "#{page_sidebar_class} #{page_gutter_class}" } .page-with-sidebar{ class: "#{page_sidebar_class} #{page_gutter_class}" }
.sidebar-wrapper.nicescroll{ class: nav_sidebar_class } .sidebar-wrapper.nicescroll{ class: nav_sidebar_class }
= render partial: 'layouts/collapse_button' .sidebar-action-buttons
= link_to '#', class: 'nav-header-btn toggle-nav-collapse', title: "Open/Close" do
%span.sr-only Toggle navigation
= icon('bars')
= link_to '#', class: "nav-header-btn pin-nav-btn has-tooltip #{'is-active' if pinned_nav?} js-nav-pin", title: pinned_nav? ? "Unpin navigation" : "Pin Navigation", data: {placement: 'right', container: 'body'} do
%span.sr-only Toggle navigation pinning
= icon('fw thumb-tack')
- if defined?(sidebar) && sidebar - if defined?(sidebar) && sidebar
= render "layouts/nav/#{sidebar}" = render "layouts/nav/#{sidebar}"
- elsif current_user - elsif current_user
...@@ -8,9 +15,6 @@ ...@@ -8,9 +15,6 @@
- else - else
= render 'layouts/nav/explore' = render 'layouts/nav/explore'
= link_to '#', class: "nav-header-btn text-center pin-nav-btn has-tooltip #{'is-active' if pinned_nav?} js-nav-pin", title: pinned_nav? ? "Unpin navigation" : "Pin Navigation", data: {placement: 'right', container: 'body'} do
%span.sr-only Toggle navigation pinning
= icon('thumb-tack')
- if defined?(nav) && nav - if defined?(nav) && nav
.layout-nav .layout-nav
.container-fluid .container-fluid
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
name: "#{j(@project.name)}" name: "#{j(@project.name)}"
}; };
- if @group and @group.path - if @group && @group.persisted? && @group.path
:javascript :javascript
gl.groupOptions = gl.groupOptions || {}; gl.groupOptions = gl.groupOptions || {};
gl.groupOptions["#{j(@group.path)}"] = { gl.groupOptions["#{j(@group.path)}"] = {
......
%header.navbar.navbar-fixed-top.navbar-gitlab{ class: nav_header_class } %header.navbar.navbar-fixed-top.navbar-gitlab{ class: nav_header_class }
%div{ class: fluid_layout ? "container-fluid" : "container-fluid" } %div{ class: fluid_layout ? "container-fluid" : "container-fluid" }
.header-content .header-content
%button.side-nav-toggle{type: 'button'} %button.side-nav-toggle{ type: 'button', "aria-label" => "Toggle global navigation" }
%span.sr-only Toggle navigation %span.sr-only Toggle navigation
= icon('bars') = icon('bars')
%button.navbar-toggle{type: 'button'} %button.navbar-toggle{type: 'button'}
...@@ -13,25 +13,25 @@ ...@@ -13,25 +13,25 @@
%li.hidden-sm.hidden-xs %li.hidden-sm.hidden-xs
= render 'layouts/search' unless current_controller?(:search) = render 'layouts/search' unless current_controller?(:search)
%li.visible-sm.visible-xs %li.visible-sm.visible-xs
= link_to search_path, title: 'Search', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = link_to search_path, title: 'Search', aria: { label: "Search" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('search') = icon('search')
- if current_user - if current_user
- if session[:impersonator_id] - if session[:impersonator_id]
%li.impersonation %li.impersonation
= link_to admin_impersonation_path, method: :delete, title: 'Stop Impersonation', data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do = link_to admin_impersonation_path, method: :delete, title: "Stop Impersonation", aria: { label: 'Stop Impersonation' }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
= icon('user-secret fw') = icon('user-secret fw')
- if current_user.is_admin? - if current_user.is_admin?
%li %li
= link_to admin_root_path, title: 'Admin Area', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = link_to admin_root_path, title: 'Admin Area', aria: { label: "Admin Area" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('wrench fw') = icon('wrench fw')
%li %li
= link_to dashboard_todos_path, title: 'Todos', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = link_to dashboard_todos_path, title: 'Todos', aria: { label: "Todos" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('bell fw') = icon('bell fw')
%span.badge.todos-pending-count{ class: ("hidden" if todos_pending_count == 0) } %span.badge.todos-pending-count{ class: ("hidden" if todos_pending_count == 0) }
= todos_pending_count = todos_pending_count
- if current_user.can_create_project? - if current_user.can_create_project?
%li %li
= link_to new_project_path, title: 'New project', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = link_to new_project_path, title: 'New project', aria: { label: "New project" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('plus fw') = icon('plus fw')
- if Gitlab::Sherlock.enabled? - if Gitlab::Sherlock.enabled?
%li %li
...@@ -45,12 +45,12 @@ ...@@ -45,12 +45,12 @@
.dropdown-menu-nav.dropdown-menu-align-right .dropdown-menu-nav.dropdown-menu-align-right
%ul %ul
%li %li
= link_to "Profile", current_user, class: 'profile-link', data: { user: current_user.username } = link_to "Profile", current_user, class: 'profile-link', aria: { label: "Profile" }, data: { user: current_user.username }
%li %li
= link_to "Profile Settings", profile_path = link_to "Profile Settings", profile_path, aria: { label: "Profile Settings" }
%li.divider %li.divider
%li %li
= link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link", title: 'Sign out' = link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link", aria: { label: "Sign out" }
- else - else
%li %li
%div %div
......
%ul.nav.nav-sidebar %ul.nav.nav-sidebar
= nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: {class: "#{project_tab_class} home"}) do = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: {class: "#{project_tab_class} home"}) do
= link_to dashboard_projects_path, title: 'Projects', class: 'dashboard-shortcuts-projects' do = link_to dashboard_projects_path, title: 'Projects', class: 'dashboard-shortcuts-projects' do
.icon-container
= navbar_icon('project')
%span %span
Projects Projects
= nav_link(controller: :todos) do = nav_link(controller: :todos) do
= link_to dashboard_todos_path, title: 'Todos' do = link_to dashboard_todos_path, title: 'Todos' do
.icon-container
= icon('bell fw')
%span %span
Todos Todos
%span.count= number_with_delimiter(todos_pending_count) %span.count= number_with_delimiter(todos_pending_count)
= nav_link(path: 'dashboard#activity') do = nav_link(path: 'dashboard#activity') do
= link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity', title: 'Activity' do = link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity', title: 'Activity' do
.icon-container
= navbar_icon('activity')
%span %span
Activity Activity
= nav_link(controller: [:groups, 'groups/milestones', 'groups/group_members']) do = nav_link(controller: [:groups, 'groups/milestones', 'groups/group_members']) do
= link_to dashboard_groups_path, title: 'Groups' do = link_to dashboard_groups_path, title: 'Groups' do
.icon-container
= navbar_icon('group')
%span %span
Groups Groups
= nav_link(controller: 'dashboard/milestones') do = nav_link(controller: 'dashboard/milestones') do
= link_to dashboard_milestones_path, title: 'Milestones' do = link_to dashboard_milestones_path, title: 'Milestones' do
.icon-container
= navbar_icon('milestones')
%span %span
Milestones Milestones
= nav_link(path: 'dashboard#issues') do = nav_link(path: 'dashboard#issues') do
= link_to assigned_issues_dashboard_path, title: 'Issues', class: 'dashboard-shortcuts-issues' do = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'dashboard-shortcuts-issues' do
.icon-container
= navbar_icon('issues')
%span %span
Issues Issues
%span.count= number_with_delimiter(current_user.assigned_issues.opened.count) %span.count= number_with_delimiter(current_user.assigned_issues.opened.count)
= nav_link(path: 'dashboard#merge_requests') do = nav_link(path: 'dashboard#merge_requests') do
= link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'dashboard-shortcuts-merge_requests' do = link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'dashboard-shortcuts-merge_requests' do
.icon-container
= navbar_icon('mr')
%span %span
Merge Requests Merge Requests
%span.count= number_with_delimiter(current_user.assigned_merge_requests.opened.count) %span.count= number_with_delimiter(current_user.assigned_merge_requests.opened.count)
= nav_link(controller: :snippets) do = nav_link(controller: :snippets) do
= link_to dashboard_snippets_path, title: 'Snippets' do = link_to dashboard_snippets_path, title: 'Snippets' do
.icon-container
= icon('clipboard fw')
%span %span
Snippets Snippets
= nav_link(controller: :help) do = nav_link(controller: :help) do
= link_to help_path, title: 'Help' do = link_to help_path, title: 'Help' do
.icon-container
= icon('question-circle fw')
%span %span
Help Help
= nav_link(html_options: {class: profile_tab_class}) do = nav_link(html_options: {class: profile_tab_class}) do
= link_to profile_path, title: 'Profile Settings', data: {placement: 'bottom'} do = link_to profile_path, title: 'Profile Settings', data: {placement: 'bottom'} do
.icon-container
= icon('user fw')
%span %span
Profile Settings Profile Settings
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
%span %span
Applications Applications
= nav_link(controller: :personal_access_tokens) do = nav_link(controller: :personal_access_tokens) do
= link_to profile_personal_access_tokens_path, title: 'Personal Access Tokens' do = link_to profile_personal_access_tokens_path, title: 'Access Tokens' do
%span %span
Personal Access Tokens Access Tokens
= nav_link(controller: :emails) do = nav_link(controller: :emails) do
= link_to profile_emails_path, title: 'Emails' do = link_to profile_emails_path, title: 'Emails' do
%span %span
......
- if @note.diff_note? - if @note.diff_note? && @note.diff_file
%p.details %p.details
New comment on diff for New comment on diff for
= link_to @note.diff_file.file_path, @target_url = link_to @note.diff_file.file_path, @target_url
......
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
- header_title "Two-Factor Authentication", profile_two_factor_auth_path - header_title "Two-Factor Authentication", profile_two_factor_auth_path
= render 'profiles/head' = render 'profiles/head'
- if inject_u2f_api?
- content_for :page_specific_javascripts do
= page_specific_javascript_tag('u2f.js')
.row.prepend-top-default .row.prepend-top-default
.col-lg-3 .col-lg-3
%h4.prepend-top-0 %h4.prepend-top-0
......
...@@ -11,17 +11,22 @@ ...@@ -11,17 +11,22 @@
%span.badge.js-totalbuilds-count %span.badge.js-totalbuilds-count
= number_with_delimiter(@all_builds.count(:id)) = number_with_delimiter(@all_builds.count(:id))
%li{class: ('active' if @scope == 'pending')}
= link_to project_builds_path(@project, scope: :pending) do
Pending
%span.badge
= number_with_delimiter(@all_builds.pending.count(:id))
%li{class: ('active' if @scope == 'running')} %li{class: ('active' if @scope == 'running')}
= link_to project_builds_path(@project, scope: :running) do = link_to project_builds_path(@project, scope: :running) do
Running Running
%span.badge.js-running-count %span.badge
= number_with_delimiter(@all_builds.running_or_pending.count(:id)) = number_with_delimiter(@all_builds.running.count(:id))
%li{class: ('active' if @scope == 'finished')} %li{class: ('active' if @scope == 'finished')}
= link_to project_builds_path(@project, scope: :finished) do = link_to project_builds_path(@project, scope: :finished) do
Finished Finished
%span.badge.js-running-count %span.badge
= number_with_delimiter(@all_builds.finished.count(:id)) = number_with_delimiter(@all_builds.finished.count(:id))
.nav-controls .nav-controls
...@@ -36,7 +41,7 @@ ...@@ -36,7 +41,7 @@
= link_to ci_lint_path, class: 'btn btn-default' do = link_to ci_lint_path, class: 'btn btn-default' do
%span CI Lint %span CI Lint
%ul.content-list %ul.content-list.builds-content-list
- if @builds.blank? - if @builds.blank?
%li %li
.nothing-here-block No builds to show .nothing-here-block No builds to show
...@@ -46,14 +51,10 @@ ...@@ -46,14 +51,10 @@
%thead %thead
%tr %tr
%th Status %th Status
%th Build ID
%th Commit %th Commit
%th Ref
%th Stage %th Stage
%th Name %th Name
%th Tags %th
%th Duration
%th Finished at
- if @project.build_coverage_enabled? - if @project.build_coverage_enabled?
%th Coverage %th Coverage
%th %th
......
%tr.build %tr.build.commit
%td.status %td.status
- if can?(current_user, :read_build, build) - if can?(current_user, :read_build, build)
= ci_status_with_icon(build.status, namespace_project_build_url(build.project.namespace, build.project, build)) = ci_status_with_icon(build.status, namespace_project_build_url(build.project.namespace, build.project, build))
- else - else
= ci_status_with_icon(build.status) = ci_status_with_icon(build.status)
%td.build-link %td
.branch-commit
- if can?(current_user, :read_build, build) - if can?(current_user, :read_build, build)
= link_to namespace_project_build_url(build.project.namespace, build.project, build) do = link_to namespace_project_build_url(build.project.namespace, build.project, build) do
%strong ##{build.id} %span ##{build.id}
- else - else
%strong ##{build.id} %span ##{build.id}
- if build.stuck? - if build.stuck?
= icon('warning', class: 'text-warning has-tooltip', title: 'Build is stuck. Check runners.') = icon('warning', class: 'text-warning has-tooltip', title: 'Build is stuck. Check runners.')
- if defined?(retried) && retried - if defined?(retried) && retried
= icon('warning', class: 'text-warning has-tooltip', title: 'Build was retried.') = icon('warning', class: 'text-warning has-tooltip', title: 'Build was retried.')
- if defined?(commit_sha) && commit_sha
%td
= link_to build.short_sha, namespace_project_commit_path(build.project.namespace, build.project, build.sha), class: "monospace"
- if defined?(ref) && ref - if defined?(ref) && ref
%td
- if build.ref - if build.ref
= link_to build.ref, namespace_project_commits_path(build.project.namespace, build.project, build.ref) = link_to build.ref, namespace_project_commits_path(build.project.namespace, build.project, build.ref), class: "monospace branch-name"
- else - else
.light none .light none
= custom_icon("icon_commit")
- if defined?(commit_sha) && commit_sha
= link_to build.short_sha, namespace_project_commit_path(build.project.namespace, build.project, build.sha), class: "commit-id monospace"
.label-container
- if build.tags.any?
- build.tags.each do |tag|
%span.label.label-primary
= tag
- if build.try(:trigger_request)
%span.label.label-info triggered
- if build.try(:allow_failure)
%span.label.label-danger allowed to fail
- if defined?(retried) && retried
%span.label.label-warning retried
- if defined?(runner) && runner - if defined?(runner) && runner
%td %td
...@@ -43,24 +56,13 @@ ...@@ -43,24 +56,13 @@
= build.name = build.name
%td %td
.label-container
- if build.tags.any?
- build.tags.each do |tag|
%span.label.label-primary
= tag
- if build.try(:trigger_request)
%span.label.label-info triggered
- if build.try(:allow_failure)
%span.label.label-danger allowed to fail
- if defined?(retried) && retried
%span.label.label-warning retried
%td.duration
- if build.duration - if build.duration
#{duration_in_words(build.finished_at, build.started_at)} %p.duration
= custom_icon("icon_timer")
%td.timestamp = duration_in_numbers(build.finished_at, build.started_at)
- if build.finished_at - if build.finished_at
%p.finished-at
= icon("calendar")
%span #{time_ago_with_tooltip(build.finished_at)} %span #{time_ago_with_tooltip(build.finished_at)}
- if defined?(coverage) && coverage - if defined?(coverage) && coverage
...@@ -79,4 +81,4 @@ ...@@ -79,4 +81,4 @@
= icon('remove', class: 'cred') = icon('remove', class: 'cred')
- elsif defined?(allow_retry) && allow_retry && build.retryable? - elsif defined?(allow_retry) && allow_retry && build.retryable?
= link_to retry_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Retry', class: 'btn btn-build' do = link_to retry_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Retry', class: 'btn btn-build' do
= icon('refresh') = icon('repeat')
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment