Commit ab7a2b1b authored by Regis's avatar Regis

Merge branch 'master' into auto-pipelines-vue

parents 25e60f87 d9cf5c0a
/coverage-javascript/
/public/ /public/
/tmp/ /tmp/
/vendor/ /vendor/
......
{ {
"extends": "airbnb", "extends": "airbnb",
"plugins": [
"filenames"
],
"rules": {
"filenames/match-regex": [2, "^[a-z_]+$"]
},
"globals": { "globals": {
"$": false, "$": false,
"_": false, "_": false,
......
This diff is collapsed.
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
- [Technical debt](#technical-debt) - [Technical debt](#technical-debt)
- [Merge requests](#merge-requests) - [Merge requests](#merge-requests)
- [Merge request guidelines](#merge-request-guidelines) - [Merge request guidelines](#merge-request-guidelines)
- [Merge request description format](#merge-request-description-format)
- [Contribution acceptance criteria](#contribution-acceptance-criteria) - [Contribution acceptance criteria](#contribution-acceptance-criteria)
- [Changes for Stable Releases](#changes-for-stable-releases) - [Changes for Stable Releases](#changes-for-stable-releases)
- [Definition of done](#definition-of-done) - [Definition of done](#definition-of-done)
...@@ -247,13 +246,7 @@ request is as follows: ...@@ -247,13 +246,7 @@ request is as follows:
1. Fork the project into your personal space on GitLab.com 1. Fork the project into your personal space on GitLab.com
1. Create a feature branch, branch away from `master` 1. Create a feature branch, branch away from `master`
1. Write [tests](https://gitlab.com/gitlab-org/gitlab-development-kit#running-the-tests) and code 1. Write [tests](https://gitlab.com/gitlab-org/gitlab-development-kit#running-the-tests) and code
1. Add your changes to the [CHANGELOG.md](CHANGELOG.md): 1. [Generate a changelog entry with `bin/changelog`][changelog]
1. If you are fixing a ~regression issue, you can add your entry to the next
patch release (e.g. `8.12.5` if current version is `8.12.4`)
1. Otherwise, add your entry to the next minor release (e.g. `8.13.0` if
current version is `8.12.4`
1. Please add your entry at a random place among the entries of the targeted
release
1. If you are writing documentation, make sure to follow the 1. If you are writing documentation, make sure to follow the
[documentation styleguide][doc-styleguide] [documentation styleguide][doc-styleguide]
1. If you have multiple commits please combine them into one commit by 1. If you have multiple commits please combine them into one commit by
...@@ -262,8 +255,11 @@ request is as follows: ...@@ -262,8 +255,11 @@ request is as follows:
1. Submit a merge request (MR) to the `master` branch 1. Submit a merge request (MR) to the `master` branch
1. The MR title should describe the change you want to make 1. The MR title should describe the change you want to make
1. The MR description should give a motive for your change and the method you 1. The MR description should give a motive for your change and the method you
used to achieve it, see the [merge request description format] used to achieve it.
(#merge-request-description-format) 1. If you are contributing code, fill in the template already provided in the
"Description" field.
1. If you are contributing documentation, choose `Documentation` from the
"Choose a template" menu and fill in the template.
1. If the MR changes the UI it should include *Before* and *After* screenshots 1. If the MR changes the UI it should include *Before* and *After* screenshots
1. If the MR changes CSS classes please include the list of affected pages, 1. If the MR changes CSS classes please include the list of affected pages,
`grep css-class ./app -R` `grep css-class ./app -R`
...@@ -469,6 +465,7 @@ available at [http://contributor-covenant.org/version/1/1/0/](http://contributor ...@@ -469,6 +465,7 @@ available at [http://contributor-covenant.org/version/1/1/0/](http://contributor
[contributor-covenant]: http://contributor-covenant.org [contributor-covenant]: http://contributor-covenant.org
[rss-source]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md#source-code-layout [rss-source]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md#source-code-layout
[rss-naming]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md#naming [rss-naming]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md#naming
[changelog]: doc/development/changelog.md "Generate a changelog entry"
[doc-styleguide]: doc/development/doc_styleguide.md "Documentation styleguide" [doc-styleguide]: doc/development/doc_styleguide.md "Documentation styleguide"
[scss-styleguide]: doc/development/scss_styleguide.md "SCSS styleguide" [scss-styleguide]: doc/development/scss_styleguide.md "SCSS styleguide"
[newlines-styleguide]: doc/development/newlines_styleguide.md "Newlines styleguide" [newlines-styleguide]: doc/development/newlines_styleguide.md "Newlines styleguide"
......
...@@ -51,7 +51,7 @@ gem 'browser', '~> 2.2' ...@@ -51,7 +51,7 @@ gem 'browser', '~> 2.2'
# Extracting information from a git repository # Extracting information from a git repository
# Provide access to Gitlab::Git library # Provide access to Gitlab::Git library
gem 'gitlab_git', '~> 10.6.8' gem 'gitlab_git', '~> 10.7.0'
# LDAP Auth # LDAP Auth
# GitLab fork with several improvements to original library. For full list of changes # GitLab fork with several improvements to original library. For full list of changes
...@@ -117,7 +117,7 @@ gem 'truncato', '~> 0.7.8' ...@@ -117,7 +117,7 @@ gem 'truncato', '~> 0.7.8'
gem 'nokogiri', '~> 1.6.7', '>= 1.6.7.2' gem 'nokogiri', '~> 1.6.7', '>= 1.6.7.2'
# Diffs # Diffs
gem 'diffy', '~> 3.0.3' gem 'diffy', '~> 3.1.0'
# Application server # Application server
group :unicorn do group :unicorn do
...@@ -196,7 +196,7 @@ gem 'loofah', '~> 2.0.3' ...@@ -196,7 +196,7 @@ gem 'loofah', '~> 2.0.3'
gem 'licensee', '~> 8.0.0' gem 'licensee', '~> 8.0.0'
# Protect against bruteforcing # Protect against bruteforcing
gem 'rack-attack', '~> 4.3.1' gem 'rack-attack', '~> 4.4.1'
# Ace editor # Ace editor
gem 'ace-rails-ap', '~> 4.1.0' gem 'ace-rails-ap', '~> 4.1.0'
......
...@@ -180,7 +180,7 @@ GEM ...@@ -180,7 +180,7 @@ GEM
railties railties
rotp (~> 2.0) rotp (~> 2.0)
diff-lcs (1.2.5) diff-lcs (1.2.5)
diffy (3.0.7) diffy (3.1.0)
docile (1.1.5) docile (1.1.5)
doorkeeper (4.2.0) doorkeeper (4.2.0)
railties (>= 4.2) railties (>= 4.2)
...@@ -283,7 +283,7 @@ GEM ...@@ -283,7 +283,7 @@ GEM
mime-types (>= 1.16, < 3) mime-types (>= 1.16, < 3)
posix-spawn (~> 0.3) posix-spawn (~> 0.3)
gitlab-markup (1.5.0) gitlab-markup (1.5.0)
gitlab_git (10.6.8) gitlab_git (10.7.0)
activesupport (~> 4.0) activesupport (~> 4.0)
charlock_holmes (~> 0.7.3) charlock_holmes (~> 0.7.3)
github-linguist (~> 4.7.0) github-linguist (~> 4.7.0)
...@@ -520,7 +520,7 @@ GEM ...@@ -520,7 +520,7 @@ GEM
rack (1.6.4) rack (1.6.4)
rack-accept (0.4.5) rack-accept (0.4.5)
rack (>= 0.4) rack (>= 0.4)
rack-attack (4.3.1) rack-attack (4.4.1)
rack rack
rack-cors (0.4.0) rack-cors (0.4.0)
rack-mount (0.8.3) rack-mount (0.8.3)
...@@ -847,7 +847,7 @@ DEPENDENCIES ...@@ -847,7 +847,7 @@ DEPENDENCIES
default_value_for (~> 3.0.0) default_value_for (~> 3.0.0)
devise (~> 4.2) devise (~> 4.2)
devise-two-factor (~> 3.0.0) devise-two-factor (~> 3.0.0)
diffy (~> 3.0.3) diffy (~> 3.1.0)
doorkeeper (~> 4.2.0) doorkeeper (~> 4.2.0)
dropzonejs-rails (~> 0.7.1) dropzonejs-rails (~> 0.7.1)
email_reply_parser (~> 0.5.8) email_reply_parser (~> 0.5.8)
...@@ -870,7 +870,7 @@ DEPENDENCIES ...@@ -870,7 +870,7 @@ DEPENDENCIES
github-linguist (~> 4.7.0) github-linguist (~> 4.7.0)
gitlab-flowdock-git-hook (~> 1.0.1) gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-markup (~> 1.5.0) gitlab-markup (~> 1.5.0)
gitlab_git (~> 10.6.8) gitlab_git (~> 10.7.0)
gitlab_omniauth-ldap (~> 1.2.1) gitlab_omniauth-ldap (~> 1.2.1)
gollum-lib (~> 4.2) gollum-lib (~> 4.2)
gollum-rugged_adapter (~> 0.4.2) gollum-rugged_adapter (~> 0.4.2)
...@@ -929,7 +929,7 @@ DEPENDENCIES ...@@ -929,7 +929,7 @@ DEPENDENCIES
poltergeist (~> 1.9.0) poltergeist (~> 1.9.0)
premailer-rails (~> 1.9.0) premailer-rails (~> 1.9.0)
pry-rails (~> 0.3.4) pry-rails (~> 0.3.4)
rack-attack (~> 4.3.1) rack-attack (~> 4.4.1)
rack-cors (~> 0.4.0) rack-cors (~> 0.4.0)
rack-oauth2 (~> 1.2.1) rack-oauth2 (~> 1.2.1)
rails (= 4.2.7.1) rails (= 4.2.7.1)
...@@ -998,4 +998,4 @@ DEPENDENCIES ...@@ -998,4 +998,4 @@ DEPENDENCIES
wikicloth (= 0.8.1) wikicloth (= 0.8.1)
BUNDLED WITH BUNDLED WITH
1.13.3 1.13.5
/* eslint-disable */ /* eslint-disable */
// This is a manifest file that'll be compiled into including all the files listed below. // This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically // Add new JavaScript code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js // be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file. // the compiled file.
...@@ -188,6 +188,7 @@ ...@@ -188,6 +188,7 @@
// Close select2 on escape // Close select2 on escape
}); });
// Initialize tooltips // Initialize tooltips
$.fn.tooltip.Constructor.DEFAULTS.trigger = 'hover';
$body.tooltip({ $body.tooltip({
selector: '.has-tooltip, [data-toggle="tooltip"]', selector: '.has-tooltip, [data-toggle="tooltip"]',
placement: function(_, el) { placement: function(_, el) {
......
...@@ -15,6 +15,11 @@ ...@@ -15,6 +15,11 @@
return $("body").on("click", ".js-details-expand", function(e) { return $("body").on("click", ".js-details-expand", function(e) {
$(this).next('.js-details-content').removeClass("hide"); $(this).next('.js-details-content').removeClass("hide");
$(this).hide(); $(this).hide();
var truncatedItem = $(this).siblings('.js-details-short');
if (truncatedItem.length) {
truncatedItem.addClass("hide");
}
return e.preventDefault(); return e.preventDefault();
}); });
}); });
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
fallbackClass: 'is-dragging', fallbackClass: 'is-dragging',
fallbackOnBody: true, fallbackOnBody: true,
ghostClass: 'is-ghost', ghostClass: 'is-ghost',
filter: '.has-tooltip, .btn', filter: '.board-delete, .btn',
delay: gl.issueBoards.touchEnabled ? 100 : 50, delay: gl.issueBoards.touchEnabled ? 100 : 50,
scrollSensitivity: gl.issueBoards.touchEnabled ? 60 : 100, scrollSensitivity: gl.issueBoards.touchEnabled ? 60 : 100,
scrollSpeed: 20, scrollSpeed: 20,
......
/* eslint-disable */ /* eslint-disable */
// This is a manifest file that'll be compiled into including all the files listed below. // This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically // Add new JavaScript code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js // be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file. // the compiled file.
......
...@@ -238,8 +238,11 @@ ...@@ -238,8 +238,11 @@
_this.expandViewContainer(); _this.expandViewContainer();
} }
_this.diffsLoaded = true; _this.diffsLoaded = true;
var anchoredDiff = gl.utils.getLocationHash();
if (anchoredDiff) _this.openAnchoredDiff(anchoredDiff, function() {
_this.scrollToElement("#diffs"); _this.scrollToElement("#diffs");
_this.highlighSelectedLine(); _this.highlighSelectedLine();
});
_this.filesCommentButton = $('.files .diff-file').filesCommentButton(); _this.filesCommentButton = $('.files .diff-file').filesCommentButton();
return $(document).off('click', '.diff-line-num a').on('click', '.diff-line-num a', function(e) { return $(document).off('click', '.diff-line-num a').on('click', '.diff-line-num a', function(e) {
e.preventDefault(); e.preventDefault();
...@@ -252,6 +255,17 @@ ...@@ -252,6 +255,17 @@
}); });
}; };
MergeRequestTabs.prototype.openAnchoredDiff = function(anchoredDiff, cb) {
var diffTitle = $('#file-path-' + anchoredDiff);
var diffFile = diffTitle.closest('.diff-file');
var nothingHereBlock = $('.nothing-here-block:visible', diffFile);
if (nothingHereBlock.length) {
diffFile.singleFileDiff(true, cb);
} else {
cb();
}
};
MergeRequestTabs.prototype.highlighSelectedLine = function() { MergeRequestTabs.prototype.highlighSelectedLine = function() {
var $diffLine, diffLineTop, hashClassString, locationHash, navBarHeight; var $diffLine, diffLineTop, hashClassString, locationHash, navBarHeight;
$('.hll').removeClass('hll'); $('.hll').removeClass('hll');
......
/* eslint-disable */ /* eslint-disable */
// This is a manifest file that'll be compiled into including all the files listed below. // This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically // Add new JavaScript code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js // be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file. // the compiled file.
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
COLLAPSED_HTML = '<div class="nothing-here-block diff-collapsed">This diff is collapsed. <a class="click-to-expand">Click to expand it.</a></div>'; COLLAPSED_HTML = '<div class="nothing-here-block diff-collapsed">This diff is collapsed. <a class="click-to-expand">Click to expand it.</a></div>';
function SingleFileDiff(file) { function SingleFileDiff(file, forceLoad, cb) {
this.file = file; this.file = file;
this.toggleDiff = bind(this.toggleDiff, this); this.toggleDiff = bind(this.toggleDiff, this);
this.content = $('.diff-content', this.file); this.content = $('.diff-content', this.file);
...@@ -32,9 +32,12 @@ ...@@ -32,9 +32,12 @@
this.$toggleIcon.addClass('fa-caret-down'); this.$toggleIcon.addClass('fa-caret-down');
} }
$('.file-title, .click-to-expand', this.file).on('click', this.toggleDiff); $('.file-title, .click-to-expand', this.file).on('click', this.toggleDiff);
if (forceLoad) {
this.toggleDiff(null, cb);
}
} }
SingleFileDiff.prototype.toggleDiff = function(e) { SingleFileDiff.prototype.toggleDiff = function(e, cb) {
var $target = $(e.target); var $target = $(e.target);
if (!$target.hasClass('file-title') && !$target.hasClass('click-to-expand') && !$target.hasClass('diff-toggle-caret')) return; if (!$target.hasClass('file-title') && !$target.hasClass('click-to-expand') && !$target.hasClass('diff-toggle-caret')) return;
this.isOpen = !this.isOpen; this.isOpen = !this.isOpen;
...@@ -54,11 +57,11 @@ ...@@ -54,11 +57,11 @@
} }
} else { } else {
this.$toggleIcon.addClass('fa-caret-down').removeClass('fa-caret-right'); this.$toggleIcon.addClass('fa-caret-down').removeClass('fa-caret-right');
return this.getContentHTML(); return this.getContentHTML(cb);
} }
}; };
SingleFileDiff.prototype.getContentHTML = function() { SingleFileDiff.prototype.getContentHTML = function(cb) {
this.collapsedContent.hide(); this.collapsedContent.hide();
this.loadingContent.show(); this.loadingContent.show();
$.get(this.diffForPath, (function(_this) { $.get(this.diffForPath, (function(_this) {
...@@ -76,6 +79,8 @@ ...@@ -76,6 +79,8 @@
if (typeof DiffNotesApp !== 'undefined') { if (typeof DiffNotesApp !== 'undefined') {
DiffNotesApp.compileComponents(); DiffNotesApp.compileComponents();
} }
if (cb) cb();
}; };
})(this)); })(this));
}; };
...@@ -84,10 +89,10 @@ ...@@ -84,10 +89,10 @@
})(); })();
$.fn.singleFileDiff = function() { $.fn.singleFileDiff = function(forceLoad, cb) {
return this.each(function() { return this.each(function() {
if (!$.data(this, 'singleFileDiff')) { if (!$.data(this, 'singleFileDiff') || forceLoad) {
return $.data(this, 'singleFileDiff', new SingleFileDiff(this)); return $.data(this, 'singleFileDiff', new SingleFileDiff(this, forceLoad, cb));
} }
}); });
}; };
......
...@@ -11,11 +11,9 @@ ...@@ -11,11 +11,9 @@
$this.parent().find('.star-count').text(data.star_count); $this.parent().find('.star-count').text(data.star_count);
if (isStarred) { if (isStarred) {
$starSpan.removeClass('starred').text('Star'); $starSpan.removeClass('starred').text('Star');
gl.utils.updateTooltipTitle($this, 'Star project');
$starIcon.removeClass('fa-star').addClass('fa-star-o'); $starIcon.removeClass('fa-star').addClass('fa-star-o');
} else { } else {
$starSpan.addClass('starred').text('Unstar'); $starSpan.addClass('starred').text('Unstar');
gl.utils.updateTooltipTitle($this, 'Unstar project');
$starIcon.removeClass('fa-star-o').addClass('fa-star'); $starIcon.removeClass('fa-star-o').addClass('fa-star');
} }
}; };
......
.avatar { @mixin avatar-size($size, $margin-right) {
width: $size;
height: $size;
margin-right: $margin-right;
}
.avatar-container {
float: left; float: left;
margin-right: 12px; margin-right: 15px;
border-radius: $avatar_radius;
border: 1px solid rgba(0, 0, 0, .1);
&.s16 { @include avatar-size(16px, 6px); }
&.s20 { @include avatar-size(20px, 7px); }
&.s24 { @include avatar-size(24px, 8px); }
&.s26 { @include avatar-size(26px, 8px); }
&.s32 { @include avatar-size(32px, 10px); }
&.s36 { @include avatar-size(36px, 10px); }
&.s40 { @include avatar-size(40px, 10px); }
&.s46 { @include avatar-size(46px, 15px); }
&.s48 { @include avatar-size(48px, 10px); }
&.s60 { @include avatar-size(60px, 12px); }
&.s70 { @include avatar-size(70px, 14px); }
&.s90 { @include avatar-size(90px, 15px); }
&.s110 { @include avatar-size(110px, 15px); }
&.s140 { @include avatar-size(140px, 15px); }
&.s160 { @include avatar-size(160px, 20px); }
}
.avatar {
@extend .avatar-container;
width: 40px; width: 40px;
height: 40px; height: 40px;
padding: 0; padding: 0;
border-radius: $avatar_radius;
border: 1px solid rgba(0, 0, 0, .1);
&.avatar-inline { &.avatar-inline {
float: none; float: none;
...@@ -20,22 +45,6 @@ ...@@ -20,22 +45,6 @@
border-radius: 0; border-radius: 0;
border: none; border: none;
} }
&.s16 { width: 16px; height: 16px; margin-right: 6px; }
&.s20 { width: 20px; height: 20px; margin-right: 7px; }
&.s24 { width: 24px; height: 24px; margin-right: 8px; }
&.s26 { width: 26px; height: 26px; margin-right: 8px; }
&.s32 { width: 32px; height: 32px; margin-right: 10px; }
&.s36 { width: 36px; height: 36px; margin-right: 10px; }
&.s40 { width: 40px; height: 40px; margin-right: 10px; }
&.s46 { width: 46px; height: 46px; margin-right: 15px; }
&.s48 { width: 48px; height: 48px; margin-right: 10px; }
&.s60 { width: 60px; height: 60px; margin-right: 12px; }
&.s70 { width: 70px; height: 70px; margin-right: 14px; }
&.s90 { width: 90px; height: 90px; margin-right: 15px; }
&.s110 { width: 110px; height: 110px; margin-right: 15px; }
&.s140 { width: 140px; height: 140px; margin-right: 20px; }
&.s160 { width: 160px; height: 160px; margin-right: 20px; }
} }
.identicon { .identicon {
...@@ -54,3 +63,17 @@ ...@@ -54,3 +63,17 @@
&.s140 { font-size: 72px; line-height: 138px; } &.s140 { font-size: 72px; line-height: 138px; }
&.s160 { font-size: 96px; line-height: 158px; } &.s160 { font-size: 96px; line-height: 158px; }
} }
.image-container {
@extend .avatar-container;
overflow: hidden;
display: flex;
.avatar {
border-radius: 0;
border: none;
height: auto;
margin: 0;
align-self: center;
}
}
\ No newline at end of file
...@@ -216,7 +216,7 @@ ...@@ -216,7 +216,7 @@
svg, svg,
.fa { .fa {
&:not(:last-child) { &:not(:last-child) {
margin-right: 3px; margin-right: 5px;
} }
} }
} }
......
...@@ -21,7 +21,14 @@ ...@@ -21,7 +21,14 @@
background: $color-darker; background: $color-darker;
} }
.nav-sidebar li { .sidebar-header,
.sidebar-action-buttons {
color: $color-light;
background-color: lighten($color-darker, 5%);
}
.nav-sidebar {
li {
a { a {
color: $color-light; color: $color-light;
...@@ -73,6 +80,8 @@ ...@@ -73,6 +80,8 @@
} }
} }
} }
}
} }
} }
......
...@@ -49,12 +49,16 @@ header { ...@@ -49,12 +49,16 @@ header {
font-size: 18px; font-size: 18px;
padding: 0; padding: 0;
margin: ($header-height - 28) / 2 0; margin: ($header-height - 28) / 2 0;
margin-left: 10px; margin-left: 8px;
height: 28px; height: 28px;
min-width: 28px; min-width: 28px;
line-height: 28px; line-height: 28px;
text-align: center; text-align: center;
&.header-user-dropdown-toggle {
margin-left: 14px;
}
&:hover, &:hover,
&:focus, &:focus,
&:active { &:active {
......
...@@ -142,10 +142,6 @@ ul.content-list { ...@@ -142,10 +142,6 @@ ul.content-list {
} }
} }
.avatar {
margin-right: 15px;
}
.controls { .controls {
float: right; float: right;
......
...@@ -7,8 +7,70 @@ ...@@ -7,8 +7,70 @@
.pagination { .pagination {
padding: 0; padding: 0;
} }
.gap,
.gap:hover {
background-color: $gray-light;
padding: $gl-vert-padding;
cursor: default;
}
} }
.panel > .gl-pagination { .panel > .gl-pagination {
margin: 0; margin: 0;
} }
/**
* Extra-small screen pagination.
*/
@media (max-width: 320px) {
.gl-pagination {
.first,
.last {
display: none;
}
.page {
display: none;
&.active {
display: inline;
}
}
}
}
/**
* Small screen pagination
*/
@media (max-width: $screen-xs) {
.gl-pagination {
.pagination li a {
padding: 6px 10px;
}
.page {
display: none;
&.active {
display: inline;
}
}
}
}
/**
* Medium screen pagination
*/
@media (min-width: $screen-xs) and (max-width: $screen-md-max) {
.gl-pagination {
.page {
display: none;
&.active,
&.sibling {
display: inline;
}
}
}
}
...@@ -59,6 +59,11 @@ ...@@ -59,6 +59,11 @@
padding: 0 !important; padding: 0 !important;
} }
.sidebar-header {
padding: 11px 22px 12px;
font-size: 20px;
}
li { li {
&.separate-item { &.separate-item {
padding-top: 10px; padding-top: 10px;
......
...@@ -90,6 +90,8 @@ $table-border-color: #f0f0f0; ...@@ -90,6 +90,8 @@ $table-border-color: #f0f0f0;
$background-color: $gray-light; $background-color: $gray-light;
$dark-background-color: #f5f5f5; $dark-background-color: #f5f5f5;
$table-text-gray: #8f8f8f; $table-text-gray: #8f8f8f;
$widget-expand-item: #e8f2f7;
$widget-inner-border: #eef0f2;
/* /*
* Text * Text
......
.awards { .awards {
.emoji-icon { .emoji-icon {
width: 20px; width: 19px;
height: 20px; height: 19px;
} }
} }
...@@ -94,7 +94,7 @@ ...@@ -94,7 +94,7 @@
.award-control { .award-control {
margin: 3px 5px 3px 0; margin: 3px 5px 3px 0;
padding: 6px 5px; padding: 5px 6px;
outline: 0; outline: 0;
&:hover, &:hover,
...@@ -127,7 +127,7 @@ ...@@ -127,7 +127,7 @@
.award-control-icon { .award-control-icon {
float: left; float: left;
margin-right: 5px; margin-right: 5px;
font-size: 20px; font-size: 19px;
} }
.award-control-icon-loading { .award-control-icon-loading {
......
...@@ -12,6 +12,10 @@ ...@@ -12,6 +12,10 @@
opacity: 1!important; opacity: 1!important;
* { * {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
// !important to make sure no style can override this when dragging // !important to make sure no style can override this when dragging
cursor: -webkit-grabbing!important; cursor: -webkit-grabbing!important;
cursor: grabbing!important; cursor: grabbing!important;
...@@ -45,11 +49,6 @@ ...@@ -45,11 +49,6 @@
.page-with-sidebar { .page-with-sidebar {
padding-bottom: 0; padding-bottom: 0;
} }
.issues-filters {
position: relative;
z-index: 999999;
}
} }
.boards-app { .boards-app {
......
...@@ -52,10 +52,25 @@ ...@@ -52,10 +52,25 @@
.build-header { .build-header {
position: relative; position: relative;
padding: 0;
display: flex;
min-height: 58px;
align-items: center;
.btn-inverted {
@include btn-outline($white-light, $blue-normal, $blue-normal, $blue-light, $white-light, $blue-light);
}
@media (max-width: $screen-sm-max) {
padding-right: 40px; padding-right: 40px;
@media (min-width: $screen-sm-min) { .btn-inverted {
padding-right: 0; display: none;
}
}
.header-content {
flex: 1;
} }
a { a {
...@@ -137,10 +152,15 @@ ...@@ -137,10 +152,15 @@
.retry-link { .retry-link {
color: $gl-link-color; color: $gl-link-color;
display: none;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
@media (max-width: $screen-sm-max) {
display: block;
}
} }
.stage-item { .stage-item {
......
...@@ -33,10 +33,8 @@ ...@@ -33,10 +33,8 @@
&.commit-info-row-header { &.commit-info-row-header {
line-height: 34px; line-height: 34px;
padding: 10px 0;
@media (min-width: $screen-sm-min) {
margin-bottom: 0; margin-bottom: 0;
}
.commit-options-dropdown-caret { .commit-options-dropdown-caret {
@media (max-width: $screen-sm) { @media (max-width: $screen-sm) {
...@@ -80,6 +78,58 @@ ...@@ -80,6 +78,58 @@
} }
} }
.js-details-expand {
&:hover {
text-decoration: none;
}
}
.commit-info-widget {
background: $background-color;
color: $gl-gray;
border: 1px solid $border-color;
border-radius: $border-radius-default;
.widget-row {
padding: $gl-padding;
&:not(:last-of-type) {
border-bottom: 1px solid $widget-inner-border;
}
&.branch-info {
.monospace,
.commit-info {
margin-left: 4px;
}
}
}
.icon-container {
display: inline-block;
margin-right: 8px;
svg {
position: relative;
top: 2px;
height: 16px;
width: 16px;
}
&.commit-icon {
svg {
path {
fill: $gl-text-color;
}
}
}
}
.label.label-gray {
background-color: $widget-expand-item;
}
}
.ci-status-link { .ci-status-link {
svg { svg {
overflow: visible; overflow: visible;
...@@ -88,6 +138,7 @@ ...@@ -88,6 +138,7 @@
.commit-box { .commit-box {
border-top: 1px solid $border-color; border-top: 1px solid $border-color;
padding: $gl-padding 0;
.commit-title { .commit-title {
margin: 0; margin: 0;
...@@ -138,6 +189,9 @@ ...@@ -138,6 +189,9 @@
} }
.commit-action-buttons { .commit-action-buttons {
position: relative;
top: -1px;
i { i {
color: $gl-icon-color; color: $gl-icon-color;
font-size: 13px; font-size: 13px;
......
...@@ -33,7 +33,9 @@ ...@@ -33,7 +33,9 @@
color: $gl-dark-link-color; color: $gl-dark-link-color;
} }
.text-expander { }
.text-expander {
display: inline-block; display: inline-block;
background: $gray-light; background: $gray-light;
color: $gl-placeholder-color; color: $gl-placeholder-color;
...@@ -48,7 +50,6 @@ ...@@ -48,7 +50,6 @@
background-color: darken($gray-light, 10%); background-color: darken($gray-light, 10%);
text-decoration: none; text-decoration: none;
} }
}
} }
.commit-actions { .commit-actions {
......
...@@ -36,10 +36,6 @@ ...@@ -36,10 +36,6 @@
} }
} }
.dash-project-avatar {
float: left;
}
.dash-project-access-icon { .dash-project-access-icon {
float: left; float: left;
margin-right: 5px; margin-right: 5px;
......
...@@ -3,12 +3,14 @@ ...@@ -3,12 +3,14 @@
} }
.dashboard .side .panel .panel-heading .input-group { .dashboard .side .panel .panel-heading .input-group {
.form-control { .form-control {
height: 42px; height: 42px;
} }
} }
.group-row { .group-row {
.stats { .stats {
float: right; float: right;
line-height: $list-text-height; line-height: $list-text-height;
...@@ -21,12 +23,14 @@ ...@@ -21,12 +23,14 @@
} }
.ldap-group-links { .ldap-group-links {
.form-actions { .form-actions {
margin-bottom: $gl-padding; margin-bottom: $gl-padding;
} }
} }
.groups-cover-block { .groups-cover-block {
.container-fluid { .container-fluid {
position: relative; position: relative;
} }
...@@ -41,9 +45,14 @@ ...@@ -41,9 +45,14 @@
background-color: $background-color; background-color: $background-color;
} }
} }
.group-avatar {
border: 0;
}
} }
.groups-header { .groups-header {
@media (min-width: $screen-sm-min) { @media (min-width: $screen-sm-min) {
.nav-links { .nav-links {
width: 35%; width: 35%;
......
...@@ -54,7 +54,6 @@ ...@@ -54,7 +54,6 @@
margin: 0 0 10px; margin: 0 0 10px;
} }
.login-footer { .login-footer {
margin-top: 10px; margin-top: 10px;
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
} }
.ci_widget { .ci_widget {
border-bottom: 1px solid #eef0f2; border-bottom: 1px solid $widget-inner-border;
svg { svg {
margin-right: 4px; margin-right: 4px;
......
...@@ -105,11 +105,6 @@ ul.notes { ...@@ -105,11 +105,6 @@ ul.notes {
padding: 2px; padding: 2px;
margin-top: 10px; margin-top: 10px;
} }
.award-control {
font-size: 13px;
padding: 2px 5px;
}
} }
.note-header { .note-header {
......
...@@ -96,8 +96,8 @@ ...@@ -96,8 +96,8 @@
.project-avatar { .project-avatar {
float: none; float: none;
margin-left: auto; margin: 0 auto;
margin-right: auto; border: none;
&.identicon { &.identicon {
border-radius: 50%; border-radius: 50%;
......
...@@ -161,3 +161,63 @@ ...@@ -161,3 +161,63 @@
} }
} }
} }
.todos-empty {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
max-width: 900px;
margin-left: auto;
margin-right: auto;
@media (min-width: $screen-sm-min) {
-webkit-flex-direction: row;
flex-direction: row;
padding-top: 80px;
}
}
.todos-empty-content {
-webkit-align-self: center;
align-self: center;
max-width: 480px;
margin-right: 20px;
}
.todos-empty-hero {
width: 200px;
margin-left: auto;
margin-right: auto;
@media (min-width: $screen-sm-min) {
width: 300px;
margin-right: 0;
-webkit-order: 2;
order: 2;
}
}
.todos-all-done {
padding-top: 20px;
@media (min-width: $screen-sm-min) {
padding-top: 50px;
}
> svg {
display: block;
max-width: 300px;
margin: 0 auto 20px;
}
p {
max-width: 470px;
margin-left: auto;
margin-right: auto;
}
a {
font-weight: 600;
}
}
...@@ -3,7 +3,7 @@ class Admin::UsersController < Admin::ApplicationController ...@@ -3,7 +3,7 @@ class Admin::UsersController < Admin::ApplicationController
def index def index
@users = User.order_name_asc.filter(params[:filter]) @users = User.order_name_asc.filter(params[:filter])
@users = @users.search(params[:name]) if params[:name].present? @users = @users.search_with_secondary_emails(params[:search_query]) if params[:search_query].present?
@users = @users.sort(@sort = params[:sort]) @users = @users.sort(@sort = params[:sort])
@users = @users.page(params[:page]) @users = @users.page(params[:page])
end end
......
...@@ -126,7 +126,7 @@ class Projects::LabelsController < Projects::ApplicationController ...@@ -126,7 +126,7 @@ class Projects::LabelsController < Projects::ApplicationController
alias_method :subscribable_resource, :label alias_method :subscribable_resource, :label
def find_labels def find_labels
@available_labels ||= LabelsFinder.new(current_user, project_id: @project.id).execute.includes(:priorities) @available_labels ||= LabelsFinder.new(current_user, project_id: @project.id).execute
end end
def authorize_admin_labels! def authorize_admin_labels!
......
...@@ -25,18 +25,15 @@ class Projects::ProjectMembersController < Projects::ApplicationController ...@@ -25,18 +25,15 @@ class Projects::ProjectMembersController < Projects::ApplicationController
end end
def create def create
if params[:user_ids].blank? status = Members::CreateService.new(@project, current_user, params).execute
return redirect_to(namespace_project_project_members_path(@project.namespace, @project), alert: 'No users or groups specified.')
end
@project.team.add_users( redirect_url = namespace_project_project_members_path(@project.namespace, @project)
params[:user_ids].split(','),
params[:access_level],
expires_at: params[:expires_at],
current_user: current_user
)
redirect_to namespace_project_project_members_path(@project.namespace, @project), notice: 'Users were successfully added.' if status
redirect_to redirect_url, notice: 'Users were successfully added.'
else
redirect_to redirect_url, alert: 'No users or groups specified.'
end
end end
def update def update
......
...@@ -23,7 +23,7 @@ class Projects::TagsController < Projects::ApplicationController ...@@ -23,7 +23,7 @@ class Projects::TagsController < Projects::ApplicationController
return render_404 unless @tag return render_404 unless @tag
@release = @project.releases.find_or_initialize_by(tag: @tag.name) @release = @project.releases.find_or_initialize_by(tag: @tag.name)
@commit = @repository.commit(@tag.target) @commit = @repository.commit(@tag.dereferenced_target)
end end
def create def create
......
...@@ -289,7 +289,8 @@ class ProjectsController < Projects::ApplicationController ...@@ -289,7 +289,8 @@ class ProjectsController < Projects::ApplicationController
render 'projects/empty' if @project.empty_repo? render 'projects/empty' if @project.empty_repo?
else else
if @project.wiki_enabled? if @project.wiki_enabled?
@wiki_home = @project.wiki.find_page('home', params[:version_id]) @project_wiki = @project.wiki
@wiki_home = @project_wiki.find_page('home', params[:version_id])
elsif @project.feature_available?(:issues, current_user) elsif @project.feature_available?(:issues, current_user)
@issues = issues_collection @issues = issues_collection
@issues = @issues.page(params[:page]) @issues = @issues.page(params[:page])
......
...@@ -126,7 +126,7 @@ class IssuableFinder ...@@ -126,7 +126,7 @@ class IssuableFinder
@labels = @labels =
if labels? && !filter_by_no_label? if labels? && !filter_by_no_label?
LabelsFinder.new(current_user, project_ids: projects, title: label_names).execute LabelsFinder.new(current_user, project_ids: projects, title: label_names).execute(skip_authorization: true)
else else
Label.none Label.none
end end
...@@ -273,7 +273,7 @@ class IssuableFinder ...@@ -273,7 +273,7 @@ class IssuableFinder
items = items.with_label(label_names, params[:sort]) items = items.with_label(label_names, params[:sort])
if projects if projects
label_ids = LabelsFinder.new(current_user, project_ids: projects).execute.select(:id) label_ids = LabelsFinder.new(current_user, project_ids: projects).execute(skip_authorization: true).select(:id)
items = items.where(labels: { id: label_ids }) items = items.where(labels: { id: label_ids })
end end
end end
......
...@@ -16,13 +16,14 @@ module ButtonHelper ...@@ -16,13 +16,14 @@ module ButtonHelper
# See http://clipboardjs.com/#usage # See http://clipboardjs.com/#usage
def clipboard_button(data = {}) def clipboard_button(data = {})
css_class = data[:class] || 'btn-clipboard btn-transparent' css_class = data[:class] || 'btn-clipboard btn-transparent'
title = data[:title] || 'Copy to Clipboard'
data = { toggle: 'tooltip', placement: 'bottom', container: 'body' }.merge(data) data = { toggle: 'tooltip', placement: 'bottom', container: 'body' }.merge(data)
content_tag :button, content_tag :button,
icon('clipboard'), icon('clipboard'),
class: "btn #{css_class}", class: "btn #{css_class}",
data: data, data: data,
type: :button, type: :button,
title: 'Copy to Clipboard' title: title
end end
def http_clone_button(project, placement = 'right', append_link: true) def http_clone_button(project, placement = 'right', append_link: true)
......
...@@ -39,6 +39,12 @@ module EventsHelper ...@@ -39,6 +39,12 @@ module EventsHelper
end end
end end
def event_filter_visible(feature_key)
return true unless @project
@project.feature_available?(feature_key, current_user)
end
def event_preposition(event) def event_preposition(event)
if event.push? || event.commented? || event.target if event.push? || event.commented? || event.target
"at" "at"
......
...@@ -174,10 +174,14 @@ module ProjectsHelper ...@@ -174,10 +174,14 @@ module ProjectsHelper
nav_tabs << :merge_requests nav_tabs << :merge_requests
end end
if can?(current_user, :read_build, project) if can?(current_user, :read_pipeline, project)
nav_tabs << :pipelines nav_tabs << :pipelines
end end
if can?(current_user, :read_build, project)
nav_tabs << :builds
end
if Gitlab.config.registry.enabled && can?(current_user, :read_container_image, project) if Gitlab.config.registry.enabled && can?(current_user, :read_container_image, project)
nav_tabs << :container_registry nav_tabs << :container_registry
end end
......
...@@ -31,7 +31,7 @@ module ProjectFeaturesCompatibility ...@@ -31,7 +31,7 @@ module ProjectFeaturesCompatibility
def write_feature_attribute(field, value) def write_feature_attribute(field, value)
build_project_feature unless project_feature build_project_feature unless project_feature
access_level = value == "true" ? ProjectFeature::ENABLED : ProjectFeature::DISABLED access_level = Gitlab::Utils.to_boolean(value) ? ProjectFeature::ENABLED : ProjectFeature::DISABLED
project_feature.update_attribute(field, access_level) project_feature.update_attribute(field, access_level)
end end
end end
class Event < ActiveRecord::Base class Event < ActiveRecord::Base
include Sortable include Sortable
default_scope { where.not(author_id: nil) } default_scope { reorder(nil).where.not(author_id: nil) }
CREATED = 1 CREATED = 1
UPDATED = 2 UPDATED = 2
......
...@@ -5,6 +5,10 @@ class GroupLabel < Label ...@@ -5,6 +5,10 @@ class GroupLabel < Label
alias_attribute :subject, :group alias_attribute :subject, :group
def subject_foreign_key
'group_id'
end
def to_reference(source_project = nil, target_project = nil, format: :id) def to_reference(source_project = nil, target_project = nil, format: :id)
super(source_project, target_project, format: format) super(source_project, target_project, format: format)
end end
......
...@@ -92,16 +92,23 @@ class Label < ActiveRecord::Base ...@@ -92,16 +92,23 @@ class Label < ActiveRecord::Base
nil nil
end end
def open_issues_count(user = nil, project = nil) def open_issues_count(user = nil)
issues_count(user, project_id: project.try(:id) || project_id, state: 'opened') issues_count(user, state: 'opened')
end end
def closed_issues_count(user = nil, project = nil) def closed_issues_count(user = nil)
issues_count(user, project_id: project.try(:id) || project_id, state: 'closed') issues_count(user, state: 'closed')
end end
def open_merge_requests_count(user = nil, project = nil) def open_merge_requests_count(user = nil)
merge_requests_count(user, project_id: project.try(:id) || project_id, state: 'opened') params = {
subject_foreign_key => subject.id,
label_name: title,
scope: 'all',
state: 'opened'
}
MergeRequestsFinder.new(user, params.with_indifferent_access).execute.count
end end
def prioritize!(project, value) def prioritize!(project, value)
...@@ -167,15 +174,8 @@ class Label < ActiveRecord::Base ...@@ -167,15 +174,8 @@ class Label < ActiveRecord::Base
end end
def issues_count(user, params = {}) def issues_count(user, params = {})
IssuesFinder.new(user, params.reverse_merge(label_name: title, scope: 'all')) params.merge!(subject_foreign_key => subject.id, label_name: title, scope: 'all')
.execute IssuesFinder.new(user, params.with_indifferent_access).execute.count
.count
end
def merge_requests_count(user, params = {})
MergeRequestsFinder.new(user, params.reverse_merge(label_name: title, scope: 'all'))
.execute
.count
end end
def label_format_reference(format = :id) def label_format_reference(format = :id)
......
...@@ -17,4 +17,10 @@ class LfsObject < ActiveRecord::Base ...@@ -17,4 +17,10 @@ class LfsObject < ActiveRecord::Base
def project_allowed_access?(project) def project_allowed_access?(project)
projects.exists?(storage_project(project).id) projects.exists?(storage_project(project).id)
end end
def self.destroy_unreferenced
joins("LEFT JOIN lfs_objects_projects ON lfs_objects_projects.lfs_object_id = #{table_name}.id")
.where(lfs_objects_projects: { id: nil })
.destroy_all
end
end end
...@@ -30,6 +30,11 @@ class Project < ActiveRecord::Base ...@@ -30,6 +30,11 @@ class Project < ActiveRecord::Base
default_value_for :container_registry_enabled, gitlab_config_features.container_registry default_value_for :container_registry_enabled, gitlab_config_features.container_registry
default_value_for(:repository_storage) { current_application_settings.repository_storage } default_value_for(:repository_storage) { current_application_settings.repository_storage }
default_value_for(:shared_runners_enabled) { current_application_settings.shared_runners_enabled } default_value_for(:shared_runners_enabled) { current_application_settings.shared_runners_enabled }
default_value_for :issues_enabled, gitlab_config_features.issues
default_value_for :merge_requests_enabled, gitlab_config_features.merge_requests
default_value_for :builds_enabled, gitlab_config_features.builds
default_value_for :wiki_enabled, gitlab_config_features.wiki
default_value_for :snippets_enabled, gitlab_config_features.snippets
after_create :ensure_dir_exist after_create :ensure_dir_exist
after_create :create_project_feature, unless: :project_feature after_create :create_project_feature, unless: :project_feature
...@@ -390,7 +395,7 @@ class Project < ActiveRecord::Base ...@@ -390,7 +395,7 @@ class Project < ActiveRecord::Base
end end
def group_ids def group_ids
joins(:namespace).where(namespaces: { type: 'Group' }).pluck(:namespace_id) joins(:namespace).where(namespaces: { type: 'Group' }).select(:namespace_id)
end end
end end
......
...@@ -12,6 +12,10 @@ class ProjectLabel < Label ...@@ -12,6 +12,10 @@ class ProjectLabel < Label
alias_attribute :subject, :project alias_attribute :subject, :project
def subject_foreign_key
'project_id'
end
def to_reference(target_project = nil, format: :id) def to_reference(target_project = nil, format: :id)
super(project, target_project, format: format) super(project, target_project, format: format)
end end
......
...@@ -237,7 +237,7 @@ class JiraService < IssueTrackerService ...@@ -237,7 +237,7 @@ class JiraService < IssueTrackerService
end end
def resource_url(resource) def resource_url(resource)
"#{Settings.gitlab['url'].chomp("/")}#{resource}" "#{Settings.gitlab.base_url.chomp("/")}#{resource}"
end end
def build_entity_url(entity_name, entity_id) def build_entity_url(entity_name, entity_id)
......
...@@ -195,7 +195,7 @@ class Repository ...@@ -195,7 +195,7 @@ class Repository
before_remove_branch before_remove_branch
branch = find_branch(branch_name) branch = find_branch(branch_name)
oldrev = branch.try(:target).try(:id) oldrev = branch.try(:dereferenced_target).try(:id)
newrev = Gitlab::Git::BLANK_SHA newrev = Gitlab::Git::BLANK_SHA
ref = Gitlab::Git::BRANCH_REF_PREFIX + branch_name ref = Gitlab::Git::BRANCH_REF_PREFIX + branch_name
...@@ -311,10 +311,10 @@ class Repository ...@@ -311,10 +311,10 @@ class Repository
# Rugged seems to throw a `ReferenceError` when given branch_names rather # Rugged seems to throw a `ReferenceError` when given branch_names rather
# than SHA-1 hashes # than SHA-1 hashes
number_commits_behind = raw_repository. number_commits_behind = raw_repository.
count_commits_between(branch.target.sha, root_ref_hash) count_commits_between(branch.dereferenced_target.sha, root_ref_hash)
number_commits_ahead = raw_repository. number_commits_ahead = raw_repository.
count_commits_between(root_ref_hash, branch.target.sha) count_commits_between(root_ref_hash, branch.dereferenced_target.sha)
{ behind: number_commits_behind, ahead: number_commits_ahead } { behind: number_commits_behind, ahead: number_commits_ahead }
end end
...@@ -696,11 +696,11 @@ class Repository ...@@ -696,11 +696,11 @@ class Repository
branches.sort_by(&:name) branches.sort_by(&:name)
when 'updated_desc' when 'updated_desc'
branches.sort do |a, b| branches.sort do |a, b|
commit(b.target).committed_date <=> commit(a.target).committed_date commit(b.dereferenced_target).committed_date <=> commit(a.dereferenced_target).committed_date
end end
when 'updated_asc' when 'updated_asc'
branches.sort do |a, b| branches.sort do |a, b|
commit(a.target).committed_date <=> commit(b.target).committed_date commit(a.dereferenced_target).committed_date <=> commit(b.dereferenced_target).committed_date
end end
else else
branches branches
...@@ -875,7 +875,7 @@ class Repository ...@@ -875,7 +875,7 @@ class Repository
branch = find_branch(ref) branch = find_branch(ref)
if branch if branch
last_commit = branch.target last_commit = branch.dereferenced_target
index.read_tree(last_commit.raw_commit.tree) index.read_tree(last_commit.raw_commit.tree)
parents = [last_commit.sha] parents = [last_commit.sha]
end end
...@@ -962,7 +962,7 @@ class Repository ...@@ -962,7 +962,7 @@ class Repository
end end
def revert(user, commit, base_branch, revert_tree_id = nil) def revert(user, commit, base_branch, revert_tree_id = nil)
source_sha = find_branch(base_branch).target.sha source_sha = find_branch(base_branch).dereferenced_target.sha
revert_tree_id ||= check_revert_content(commit, base_branch) revert_tree_id ||= check_revert_content(commit, base_branch)
return false unless revert_tree_id return false unless revert_tree_id
...@@ -979,7 +979,7 @@ class Repository ...@@ -979,7 +979,7 @@ class Repository
end end
def cherry_pick(user, commit, base_branch, cherry_pick_tree_id = nil) def cherry_pick(user, commit, base_branch, cherry_pick_tree_id = nil)
source_sha = find_branch(base_branch).target.sha source_sha = find_branch(base_branch).dereferenced_target.sha
cherry_pick_tree_id ||= check_cherry_pick_content(commit, base_branch) cherry_pick_tree_id ||= check_cherry_pick_content(commit, base_branch)
return false unless cherry_pick_tree_id return false unless cherry_pick_tree_id
...@@ -1008,7 +1008,7 @@ class Repository ...@@ -1008,7 +1008,7 @@ class Repository
end end
def check_revert_content(commit, base_branch) def check_revert_content(commit, base_branch)
source_sha = find_branch(base_branch).target.sha source_sha = find_branch(base_branch).dereferenced_target.sha
args = [commit.id, source_sha] args = [commit.id, source_sha]
args << { mainline: 1 } if commit.merge_commit? args << { mainline: 1 } if commit.merge_commit?
...@@ -1022,7 +1022,7 @@ class Repository ...@@ -1022,7 +1022,7 @@ class Repository
end end
def check_cherry_pick_content(commit, base_branch) def check_cherry_pick_content(commit, base_branch)
source_sha = find_branch(base_branch).target.sha source_sha = find_branch(base_branch).dereferenced_target.sha
args = [commit.id, source_sha] args = [commit.id, source_sha]
args << 1 if commit.merge_commit? args << 1 if commit.merge_commit?
...@@ -1095,7 +1095,7 @@ class Repository ...@@ -1095,7 +1095,7 @@ class Repository
if rugged.lookup(newrev).parent_ids.empty? || target_branch.nil? if rugged.lookup(newrev).parent_ids.empty? || target_branch.nil?
oldrev = Gitlab::Git::BLANK_SHA oldrev = Gitlab::Git::BLANK_SHA
else else
oldrev = rugged.merge_base(newrev, target_branch.target.sha) oldrev = rugged.merge_base(newrev, target_branch.dereferenced_target.sha)
end end
GitHooksService.new.execute(current_user, path_to_repo, oldrev, newrev, ref) do GitHooksService.new.execute(current_user, path_to_repo, oldrev, newrev, ref) do
...@@ -1155,7 +1155,7 @@ class Repository ...@@ -1155,7 +1155,7 @@ class Repository
end end
def tags_sorted_by_committed_date def tags_sorted_by_committed_date
tags.sort_by { |tag| tag.target.committed_date } tags.sort_by { |tag| tag.dereferenced_target.committed_date }
end end
def keep_around_ref_name(sha) def keep_around_ref_name(sha)
......
...@@ -258,6 +258,24 @@ class User < ActiveRecord::Base ...@@ -258,6 +258,24 @@ class User < ActiveRecord::Base
) )
end end
# searches user by given pattern
# it compares name, email, username fields and user's secondary emails with given pattern
# This method uses ILIKE on PostgreSQL and LIKE on MySQL.
def search_with_secondary_emails(query)
table = arel_table
email_table = Email.arel_table
pattern = "%#{query}%"
matched_by_emails_user_ids = email_table.project(email_table[:user_id]).where(email_table[:email].matches(pattern))
where(
table[:name].matches(pattern).
or(table[:email].matches(pattern)).
or(table[:username].matches(pattern)).
or(table[:id].in(matched_by_emails_user_ids))
)
end
def by_login(login) def by_login(login)
return nil unless login return nil unless login
......
...@@ -2,11 +2,11 @@ class ProjectPolicy < BasePolicy ...@@ -2,11 +2,11 @@ class ProjectPolicy < BasePolicy
def rules def rules
team_access!(user) team_access!(user)
owner = user.admin? || owner = project.owner == user ||
project.owner == user ||
(project.group && project.group.has_owner?(user)) (project.group && project.group.has_owner?(user))
owner_access! if owner owner_access! if user.admin? || owner
team_member_owner_access! if owner
if project.public? || (project.internal? && !user.external?) if project.public? || (project.internal? && !user.external?)
guest_access! guest_access!
...@@ -16,7 +16,7 @@ class ProjectPolicy < BasePolicy ...@@ -16,7 +16,7 @@ class ProjectPolicy < BasePolicy
can! :read_build if project.public_builds? can! :read_build if project.public_builds?
if project.request_access_enabled && if project.request_access_enabled &&
!(owner || project.team.member?(user) || project_group_member?(user)) !(owner || user.admin? || project.team.member?(user) || project_group_member?(user))
can! :request_access can! :request_access
end end
end end
...@@ -135,6 +135,10 @@ class ProjectPolicy < BasePolicy ...@@ -135,6 +135,10 @@ class ProjectPolicy < BasePolicy
can! :destroy_issue can! :destroy_issue
end end
def team_member_owner_access!
team_member_reporter_access!
end
# Push abilities on the users team role # Push abilities on the users team role
def team_access!(user) def team_access!(user)
access = project.team.max_member_access(user.id) access = project.team.max_member_access(user.id)
......
...@@ -42,7 +42,7 @@ class DeleteBranchService < BaseService ...@@ -42,7 +42,7 @@ class DeleteBranchService < BaseService
Gitlab::DataBuilder::Push.build( Gitlab::DataBuilder::Push.build(
project, project,
current_user, current_user,
branch.target.sha, branch.dereferenced_target.sha,
Gitlab::Git::BLANK_SHA, Gitlab::Git::BLANK_SHA,
"#{Gitlab::Git::BRANCH_REF_PREFIX}#{branch.name}", "#{Gitlab::Git::BRANCH_REF_PREFIX}#{branch.name}",
[]) [])
......
...@@ -36,7 +36,7 @@ class DeleteTagService < BaseService ...@@ -36,7 +36,7 @@ class DeleteTagService < BaseService
Gitlab::DataBuilder::Push.build( Gitlab::DataBuilder::Push.build(
project, project,
current_user, current_user,
tag.target.sha, tag.dereferenced_target.sha,
Gitlab::Git::BLANK_SHA, Gitlab::Git::BLANK_SHA,
"#{Gitlab::Git::TAG_REF_PREFIX}#{tag.name}", "#{Gitlab::Git::TAG_REF_PREFIX}#{tag.name}",
[]) [])
......
...@@ -27,8 +27,8 @@ class GitTagPushService < BaseService ...@@ -27,8 +27,8 @@ class GitTagPushService < BaseService
tag_name = Gitlab::Git.ref_name(params[:ref]) tag_name = Gitlab::Git.ref_name(params[:ref])
tag = project.repository.find_tag(tag_name) tag = project.repository.find_tag(tag_name)
if tag && tag.object_sha == params[:newrev] if tag && tag.target == params[:newrev]
commit = project.commit(tag.target) commit = project.commit(tag.dereferenced_target)
commits = [commit].compact commits = [commit].compact
message = tag.message message = tag.message
end end
......
module Members
class CreateService < BaseService
def execute
return false if params[:user_ids].blank?
project.team.add_users(
params[:user_ids].split(','),
params[:access_level],
expires_at: params[:expires_at],
current_user: current_user
)
true
end
end
end
...@@ -13,20 +13,8 @@ module MergeRequests ...@@ -13,20 +13,8 @@ module MergeRequests
merge_request.target_project ||= (project.forked_from_project || project) merge_request.target_project ||= (project.forked_from_project || project)
merge_request.target_branch ||= merge_request.target_project.default_branch merge_request.target_branch ||= merge_request.target_project.default_branch
if merge_request.target_branch.blank? || merge_request.source_branch.blank? messages = validate_branches(merge_request)
message = return build_failed(merge_request, messages) unless messages.empty?
if params[:source_branch] || params[:target_branch]
"You must select source and target branch"
end
return build_failed(merge_request, message)
end
if merge_request.source_project == merge_request.target_project &&
merge_request.target_branch == merge_request.source_branch
return build_failed(merge_request, 'You must select different branches')
end
compare = CompareService.new.execute( compare = CompareService.new.execute(
merge_request.source_project, merge_request.source_project,
...@@ -43,6 +31,34 @@ module MergeRequests ...@@ -43,6 +31,34 @@ module MergeRequests
private private
def validate_branches(merge_request)
messages = []
if merge_request.target_branch.blank? || merge_request.source_branch.blank?
messages <<
if params[:source_branch] || params[:target_branch]
"You must select source and target branch"
end
end
if merge_request.source_project == merge_request.target_project &&
merge_request.target_branch == merge_request.source_branch
messages << 'You must select different branches'
end
# See if source and target branches exist
unless merge_request.source_project.commit(merge_request.source_branch)
messages << "Source branch \"#{merge_request.source_branch}\" does not exist"
end
unless merge_request.target_project.commit(merge_request.target_branch)
messages << "Target branch \"#{merge_request.target_branch}\" does not exist"
end
messages
end
# When your branch name starts with an iid followed by a dash this pattern will be # When your branch name starts with an iid followed by a dash this pattern will be
# interpreted as the user wants to close that issue on this project. # interpreted as the user wants to close that issue on this project.
# #
...@@ -91,8 +107,10 @@ module MergeRequests ...@@ -91,8 +107,10 @@ module MergeRequests
merge_request merge_request
end end
def build_failed(merge_request, message) def build_failed(merge_request, messages)
merge_request.errors.add(:base, message) unless message.nil? messages.compact.each do |message|
merge_request.errors.add(:base, message)
end
merge_request.compare_commits = [] merge_request.compare_commits = []
merge_request.can_be_created = false merge_request.can_be_created = false
merge_request merge_request
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
%span.visibility-icon.has-tooltip{data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group)} %span.visibility-icon.has-tooltip{data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group)}
= visibility_level_icon(group.visibility_level, fw: false) = visibility_level_icon(group.visibility_level, fw: false)
.image-container.s40
= image_tag group_icon(group), class: "avatar s40 hidden-xs" = 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
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
Group info: Group info:
%ul.well-list %ul.well-list
%li %li
.image-container.s60
= image_tag group_icon(@group), class: "avatar s60" = image_tag group_icon(@group), class: "avatar s60"
%li %li
%span.light Name: %span.light Name:
......
...@@ -76,6 +76,7 @@ ...@@ -76,6 +76,7 @@
.title .title
= link_to [:admin, project.namespace.becomes(Namespace), project] do = link_to [:admin, project.namespace.becomes(Namespace), project] do
.dash-project-avatar .dash-project-avatar
.image-container.s40
= project_icon(project, alt: '', class: 'avatar project-avatar s40') = project_icon(project, alt: '', class: 'avatar project-avatar s40')
%span.project-full-name %span.project-full-name
%span.namespace-name %span.namespace-name
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
= hidden_field_tag "filter", h(params[:filter]) = hidden_field_tag "filter", h(params[:filter])
.search-holder .search-holder
.search-field-holder .search-field-holder
= search_field_tag :name, params[:name], placeholder: 'Search by name, email or username', class: 'form-control search-text-input js-search-input', spellcheck: false = search_field_tag :search_query, params[:search_query], placeholder: 'Search by name, email or username', class: 'form-control search-text-input js-search-input', spellcheck: false
= icon("search", class: "search-icon") = icon("search", class: "search-icon")
.dropdown .dropdown
- toggle_text = if @sort.present? then sort_options_hash[@sort] else sort_title_name end - toggle_text = if @sort.present? then sort_options_hash[@sort] else sort_title_name end
......
- page_title "Todos" - page_title "Todos"
- header_title "Todos", dashboard_todos_path - header_title "Todos", dashboard_todos_path
.top-area - if current_user.todos.any?
.top-area
%ul.nav-links %ul.nav-links
- todo_pending_active = ('active' if params[:state].blank? || params[:state] == 'pending') - todo_pending_active = ('active' if params[:state].blank? || params[:state] == 'pending')
%li{class: "todos-pending #{todo_pending_active}"} %li{class: "todos-pending #{todo_pending_active}"}
...@@ -24,7 +25,7 @@ ...@@ -24,7 +25,7 @@
Mark all as done Mark all as done
= icon('spinner spin') = icon('spinner spin')
.todos-filters .todos-filters
.row-content-block.second-block .row-content-block.second-block
= form_tag todos_filter_path(without: [:project_id, :author_id, :type, :action_id]), method: :get, class: 'filter-form' do = form_tag todos_filter_path(without: [:project_id, :author_id, :type, :action_id]), method: :get, class: 'filter-form' do
.filter-item.inline .filter-item.inline
...@@ -78,5 +79,29 @@ ...@@ -78,5 +79,29 @@
%ul.content-list.todos-list %ul.content-list.todos-list
= render group[1] = render group[1]
= paginate @todos, theme: "gitlab" = paginate @todos, theme: "gitlab"
- elsif current_user.todos.any?
.todos-all-done
= render "shared/empty_states/todos_all_done.svg"
%h4.text-center
Good job! Looks like you don't have any todos left.
%p.text-center
Are you looking for things to do? Take a look at
= succeed "," do
= link_to "the opened issues", issues_dashboard_path
contribute to
= link_to "merge requests", merge_requests_dashboard_path
or mention someone in a comment to assign a new todo automatically.
- else - else
.nothing-here-block You're all done! .todos-empty
.todos-empty-hero
= render "shared/empty_states/todos_empty.svg"
.todos-empty-content
%h4
Todos let you see what you should do next.
%p
When an issue or merge request is assigned to you, or when you
%strong
@mention
in a comment, this will trigger a new item in your todo list, automatically.
%p
You will always know what to work on next.
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
.form-group .form-group
.col-sm-offset-2.col-sm-10 .col-sm-offset-2.col-sm-10
.image-container.s160
= image_tag group_icon(@group), alt: '', class: 'avatar group-avatar s160' = image_tag group_icon(@group), alt: '', class: 'avatar group-avatar s160'
%p.light %p.light
- if @group.avatar? - if @group.avatar?
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
.other-labels .other-labels
- if @labels.present? - if @labels.present?
%ul.content-list.manage-labels-list.js-other-labels %ul.content-list.manage-labels-list.js-other-labels
= render partial: 'shared/label', collection: @labels, as: :label = render partial: 'shared/label', subject: @group, collection: @labels, as: :label
= paginate @labels, theme: 'gitlab' = paginate @labels, theme: 'gitlab'
- else - else
.nothing-here-block .nothing-here-block
......
...@@ -6,7 +6,8 @@ ...@@ -6,7 +6,8 @@
.cover-block.groups-cover-block .cover-block.groups-cover-block
%div{ class: container_class } %div{ class: container_class }
= image_tag group_icon(@group), class: "avatar group-avatar s70 avatar-tile" .image-container.s70.group-avatar
= image_tag group_icon(@group), class: "avatar s70 avatar-tile"
.group-info .group-info
.cover-title .cover-title
%h1 %h1
......
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
-# total_pages: total number of pages -# total_pages: total number of pages
-# per_page: number of items to fetch per page -# per_page: number of items to fetch per page
-# remote: data-remote -# remote: data-remote
%li{class: "page"} %li
%span.page.gap %span.gap
= raw(t 'views.pagination.truncate') = raw(t 'views.pagination.truncate')
...@@ -6,5 +6,5 @@ ...@@ -6,5 +6,5 @@
-# total_pages: total number of pages -# total_pages: total number of pages
-# per_page: number of items to fetch per page -# per_page: number of items to fetch per page
-# remote: data-remote -# remote: data-remote
%li{class: "page#{' active' if page.current?}"} %li{class: "page#{' active' if page.current?}#{' sibling' if page.next? || page.prev?}"}
= link_to page, url, {remote: remote, rel: page.next? ? 'next' : page.prev? ? 'prev' : nil} = link_to page, url, {remote: remote, rel: page.next? ? 'next' : page.prev? ? 'prev' : nil}
...@@ -29,10 +29,6 @@ ...@@ -29,10 +29,6 @@
= 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?
%li
= link_to new_project_path, title: 'New project', aria: { label: "New project" }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('plus fw')
- if Gitlab::Sherlock.enabled? - if Gitlab::Sherlock.enabled?
%li %li
= link_to sherlock_transactions_path, title: 'Sherlock Transactions', = link_to sherlock_transactions_path, title: 'Sherlock Transactions',
...@@ -48,6 +44,8 @@ ...@@ -48,6 +44,8 @@
= link_to "Profile", current_user, class: 'profile-link', aria: { label: "Profile" }, 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, aria: { label: "Profile Settings" } = link_to "Profile Settings", profile_path, aria: { label: "Profile Settings" }
%li
= link_to "Help", help_path, aria: { label: "Help" }
%li.divider %li.divider
%li %li
= link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link", aria: { label: "Sign out" } = link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link", aria: { label: "Sign out" }
......
%ul.nav.nav-sidebar .nav-sidebar
.sidebar-header Across GitLab
%ul.nav
= 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
%span %span
Projects Projects
= nav_link(controller: :todos) do
= link_to dashboard_todos_path, title: 'Todos' do
%span
Todos
%span.count.js-todos-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
%span %span
...@@ -39,11 +36,3 @@ ...@@ -39,11 +36,3 @@
= link_to dashboard_snippets_path, title: 'Snippets' do = link_to dashboard_snippets_path, title: 'Snippets' do
%span %span
Snippets Snippets
= nav_link(controller: :help) do
= link_to help_path, title: 'Help' do
%span
Help
= nav_link(html_options: {class: profile_tab_class}) do
= link_to profile_path, title: 'Profile Settings', data: {placement: 'bottom'} do
%span
Profile Settings
- empty_repo = @project.empty_repo? - empty_repo = @project.empty_repo?
.project-home-panel.text-center{ class: ("empty-project" if empty_repo) } .project-home-panel.text-center{ class: ("empty-project" if empty_repo) }
%div{ class: container_class } %div{ class: container_class }
= project_icon(@project, alt: @project.name, class: 'project-avatar avatar s70 avatar-tile') .image-container.s70.project-avatar
= project_icon(@project, alt: @project.name, class: 'avatar s70 avatar-tile')
%h1.project-title %h1.project-title
= @project.name = @project.name
%span.visibility-icon.has-tooltip{data: { container: 'body' }, title: visibility_icon_description(@project)} %span.visibility-icon.has-tooltip{data: { container: 'body' }, title: visibility_icon_description(@project)}
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
.board-inner .board-inner
%header.board-header{ ":class" => "{ 'has-border': list.label }", ":style" => "{ borderTopColor: (list.label ? list.label.color : null) }" } %header.board-header{ ":class" => "{ 'has-border': list.label }", ":style" => "{ borderTopColor: (list.label ? list.label.color : null) }" }
%h3.board-title.js-board-handle{ ":class" => "{ 'user-can-drag': (!disabled && !list.preset) }" } %h3.board-title.js-board-handle{ ":class" => "{ 'user-can-drag': (!disabled && !list.preset) }" }
%span.has-tooltip{ ":title" => "(list.label ? list.label.description : '')",
data: { container: "body", placement: "bottom" } }
{{ list.title }} {{ list.title }}
.board-issue-count-holder.pull-right.clearfix{ "v-if" => "list.type !== 'blank'" } .board-issue-count-holder.pull-right.clearfix{ "v-if" => "list.type !== 'blank'" }
%span.board-issue-count.pull-left{ ":class" => "{ 'has-btn': list.type !== 'done' }" } %span.board-issue-count.pull-left{ ":class" => "{ 'has-btn': list.type !== 'done' }" }
......
- commit = @repository.commit(branch.target) - commit = @repository.commit(branch.dereferenced_target)
- bar_graph_width_factor = @max_commits > 0 ? 100.0/@max_commits : 0 - bar_graph_width_factor = @max_commits > 0 ? 100.0/@max_commits : 0
- diverging_commit_counts = @repository.diverging_commit_counts(branch) - diverging_commit_counts = @repository.diverging_commit_counts(branch)
- number_commits_behind = diverging_commit_counts[:behind] - number_commits_behind = diverging_commit_counts[:behind]
......
.content-block.build-header .content-block.build-header
.header-content
= ci_status_with_icon(@build.status) = ci_status_with_icon(@build.status)
Build Build
%strong ##{@build.id} %strong ##{@build.id}
...@@ -12,5 +13,7 @@ ...@@ -12,5 +13,7 @@
- if @build.user - if @build.user
= render "user" = render "user"
= time_ago_with_tooltip(@build.created_at) = time_ago_with_tooltip(@build.created_at)
- if can?(current_user, :update_build, @build) && @build.retryable?
= link_to "Retry build", retry_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-inverted pull-right', method: :post
%button.btn.btn-default.pull-right.visible-xs-block.visible-sm-block.build-gutter-toggle.js-sidebar-build-toggle{ role: "button", type: "button" } %button.btn.btn-default.pull-right.visible-xs-block.visible-sm-block.build-gutter-toggle.js-sidebar-build-toggle{ role: "button", type: "button" }
= icon('angle-double-left') = icon('angle-double-left')
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
.title .title
Build details Build details
- if can?(current_user, :update_build, @build) && @build.retryable? - if can?(current_user, :update_build, @build) && @build.retryable?
= link_to "Retry", retry_namespace_project_build_path(@project.namespace, @project, @build), class: 'pull-right retry-link', method: :post = link_to "Retry build", retry_namespace_project_build_path(@project.namespace, @project, @build), class: 'pull-right retry-link', method: :post
- if @build.merge_request - if @build.merge_request
%p.build-detail-row %p.build-detail-row
%span.build-light-text Merge Request: %span.build-light-text Merge Request:
......
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
= custom_icon('icon_fork') = custom_icon('icon_fork')
%span Fork %span Fork
- else - else
= link_to new_namespace_project_fork_path(@project.namespace, @project), title: 'Fork project', class: 'btn has-tooltip' do = link_to new_namespace_project_fork_path(@project.namespace, @project), title: 'Fork project', class: 'btn' do
= custom_icon('icon_fork') = custom_icon('icon_fork')
%span Fork %span Fork
%div.count-with-arrow %div.count-with-arrow
%span.arrow %span.arrow
= link_to namespace_project_forks_path(@project.namespace, @project), title: 'Forks', class: 'count has-tooltip' do = link_to namespace_project_forks_path(@project.namespace, @project), title: 'Forks', class: 'count' do
= @project.forks_count = @project.forks_count
- if current_user - if current_user
= link_to toggle_star_namespace_project_path(@project.namespace, @project), { class: 'btn star-btn toggle-star has-tooltip', method: :post, remote: true, title: current_user.starred?(@project) ? 'Unstar project' : 'Star project' } do = link_to toggle_star_namespace_project_path(@project.namespace, @project), { class: 'btn star-btn toggle-star', method: :post, remote: true } do
- if current_user.starred?(@project) - if current_user.starred?(@project)
= icon('star') = icon('star')
%span.starred Unstar %span.starred Unstar
......
.commit-info-row.commit-info-row-header .commit-info-row.commit-info-row-header
%span.hidden-xs Authored by %span.hidden-xs.hidden-sm Commit
= link_to @commit.short_id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace js-details-short"
= link_to("#", class: "js-details-expand hidden-xs hidden-sm") do
%span.text-expander
\...
%span.js-details-content.hide
= link_to @commit.id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace hidden-xs hidden-sm"
= clipboard_button(clipboard_text: @commit.id)
%span.hidden-xs authored
#{time_ago_with_tooltip(@commit.authored_date)}
%span by
= author_avatar(@commit, size: 24)
%strong %strong
= commit_author_link(@commit, avatar: true, size: 24) = commit_author_link(@commit, avatar: true, size: 24)
#{time_ago_with_tooltip(@commit.authored_date)} - if @commit.different_committer?
%span.light Committed by
%strong
= commit_committer_link(@commit, avatar: true, size: 24)
#{time_ago_with_tooltip(@commit.committed_date)}
.pull-right.commit-action-buttons .pull-right.commit-action-buttons
- if defined?(@notes_count) && @notes_count > 0 - if defined?(@notes_count) && @notes_count > 0
...@@ -33,42 +48,35 @@ ...@@ -33,42 +48,35 @@
%li= link_to "Email Patches", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch) %li= link_to "Email Patches", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch)
%li= link_to "Plain Diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff) %li= link_to "Plain Diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff)
- if @commit.different_committer? .commit-box
.commit-info-row %h3.commit-title
%span.light Committed by = markdown(@commit.title, pipeline: :single_line, author: @commit.author)
%strong - if @commit.description.present?
= commit_committer_link(@commit, avatar: true, size: 24) %pre.commit-description
#{time_ago_with_tooltip(@commit.committed_date)} = preserve(markdown(@commit.description, pipeline: :single_line, author: @commit.author))
.commit-info-row .commit-info-widget
%span.hidden-xs.hidden-sm Commit .widget-row.branch-info
= link_to @commit.id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace hidden-xs hidden-sm" .icon-container.commit-icon
= link_to @commit.short_id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace visible-xs-inline visible-sm-inline" = custom_icon("icon_commit")
= clipboard_button(clipboard_text: @commit.id)
%span.cgray= pluralize(@commit.parents.count, "parent") %span.cgray= pluralize(@commit.parents.count, "parent")
- @commit.parents.each do |parent| - @commit.parents.each do |parent|
= link_to parent.short_id, namespace_project_commit_path(@project.namespace, @project, parent), class: "monospace" = link_to parent.short_id, namespace_project_commit_path(@project.namespace, @project, parent), class: "monospace"
%span.commit-info.branches %span.commit-info.branches
%i.fa.fa-spinner.fa-spin %i.fa.fa-spinner.fa-spin
- if @commit.status - if @commit.status
.commit-info-row .widget-row.pipeline-info
Builds for .icon-container
= pluralize(@commit.pipelines.count, 'pipeline')
= link_to builds_namespace_project_commit_path(@project.namespace, @project, @commit.id), class: "ci-status-link ci-status-icon-#{@commit.status}" do
= ci_icon_for_status(@commit.status) = ci_icon_for_status(@commit.status)
Pipeline
= link_to "##{@commit.pipelines.last.id}", pipelines_namespace_project_commit_path(@project.namespace, @project, @commit.id), class: "monospace"
for
= link_to @commit.short_id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace"
%span.ci-status-label %span.ci-status-label
= ci_label_for_status(@commit.status) = ci_label_for_status(@commit.status)
in in
= time_interval_in_words @commit.pipelines.total_duration = time_interval_in_words @commit.pipelines.total_duration
.commit-box.content-block
%h3.commit-title
= markdown(@commit.title, pipeline: :single_line, author: @commit.author)
- if @commit.description.present?
%pre.commit-description
= preserve(markdown(@commit.description, pipeline: :single_line, author: @commit.author))
:javascript :javascript
$(".commit-info.branches").load("#{branches_namespace_project_commit_path(@project.namespace, @project, @commit.id)}"); $(".commit-info.branches").load("#{branches_namespace_project_commit_path(@project.namespace, @project, @commit.id)}");
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
= render "projects/commits/head" = render "projects/commits/head"
%div{ class: container_class } %div{ class: container_class }
.prepend-top-default
= render "commit_box" = render "commit_box"
= render "ci_menu" = render "ci_menu"
......
- page_title "Pipelines", "#{@commit.title} (#{@commit.short_id})", "Commits" - page_title "Pipelines", "#{@commit.title} (#{@commit.short_id})", "Commits"
.prepend-top-default = render "commit_box"
= render "commit_box"
= render "ci_menu" = render "ci_menu"
= render "pipelines_list", pipelines: @ci_pipelines = render "pipelines_list", pipelines: @ci_pipelines
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
= render "projects/commits/head" = render "projects/commits/head"
%div{ class: container_class } %div{ class: container_class }
.prepend-top-default
= render "commit_box" = render "commit_box"
- if @commit.status - if @commit.status
= render "ci_menu" = render "ci_menu"
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
= link_to '#', class: 'js-toggle-diff-comments btn active has-tooltip btn-file-option', title: "Toggle comments for this file", disabled: @diff_notes_disabled do = link_to '#', class: 'js-toggle-diff-comments btn active has-tooltip btn-file-option', title: "Toggle comments for this file", disabled: @diff_notes_disabled do
= icon('comment') = icon('comment')
\ \
= clipboard_button(clipboard_text: diff_file.new_path, class: 'btn-file-option')
- if editable_diff?(diff_file) - if editable_diff?(diff_file)
- link_opts = @merge_request.id ? { from_merge_request_id: @merge_request.id } : {} - link_opts = @merge_request.id ? { from_merge_request_id: @merge_request.id } : {}
= edit_blob_link(@merge_request.source_project, @merge_request.source_branch, diff_file.new_path, = edit_blob_link(@merge_request.source_project, @merge_request.source_branch, diff_file.new_path,
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
- if diff_file.deleted_file - if diff_file.deleted_file
deleted deleted
= clipboard_button(clipboard_text: diff_file.new_path, class: 'btn-clipboard btn-transparent prepend-left-5', title: 'Copy filename to clipboard')
- if diff_file.mode_changed? - if diff_file.mode_changed?
%small %small
= "#{diff_file.a_mode}#{diff_file.b_mode}" = "#{diff_file.a_mode}#{diff_file.b_mode}"
...@@ -118,6 +118,7 @@ ...@@ -118,6 +118,7 @@
Project avatar Project avatar
.form-group .form-group
- if @project.avatar? - if @project.avatar?
.image-container.s160
= project_icon("#{@project.namespace.to_param}/#{@project.to_param}", alt: '', class: 'avatar project-avatar s160') = project_icon("#{@project.namespace.to_param}/#{@project.to_param}", alt: '', class: 'avatar project-avatar s160')
%p.light %p.light
- if @project.avatar_in_git - if @project.avatar_in_git
...@@ -180,6 +181,7 @@ ...@@ -180,6 +181,7 @@
%ul %ul
%li Build traces and artifacts %li Build traces and artifacts
%li LFS objects %li LFS objects
%li Container registry images
%hr %hr
- if can? current_user, :archive_project, @project - if can? current_user, :archive_project, @project
.row.prepend-top-default .row.prepend-top-default
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
%ul.unstyled-list.related-merge-requests %ul.unstyled-list.related-merge-requests
- @related_branches.each do |branch| - @related_branches.each do |branch|
%li %li
- target = @project.repository.find_branch(branch).target - target = @project.repository.find_branch(branch).dereferenced_target
- pipeline = @project.pipeline_for(branch, target.sha) if target - pipeline = @project.pipeline_for(branch, target.sha) if target
- if pipeline - if pipeline
%span.related-branch-ci-status %span.related-branch-ci-status
......
...@@ -22,14 +22,14 @@ ...@@ -22,14 +22,14 @@
%ul.content-list.manage-labels-list.js-prioritized-labels{ "data-url" => set_priorities_namespace_project_labels_path(@project.namespace, @project) } %ul.content-list.manage-labels-list.js-prioritized-labels{ "data-url" => set_priorities_namespace_project_labels_path(@project.namespace, @project) }
%p.empty-message{ class: ('hidden' unless @prioritized_labels.empty?) } No prioritized labels yet %p.empty-message{ class: ('hidden' unless @prioritized_labels.empty?) } No prioritized labels yet
- if @prioritized_labels.present? - if @prioritized_labels.present?
= render partial: 'shared/label', collection: @prioritized_labels, as: :label = render partial: 'shared/label', subject: @project, collection: @prioritized_labels, as: :label
.other-labels .other-labels
- if can?(current_user, :admin_label, @project) - if can?(current_user, :admin_label, @project)
%h5{ class: ('hide' if hide) } Other Labels %h5{ class: ('hide' if hide) } Other Labels
%ul.content-list.manage-labels-list.js-other-labels %ul.content-list.manage-labels-list.js-other-labels
- if @labels.present? - if @labels.present?
= render partial: 'shared/label', collection: @labels, as: :label = render partial: 'shared/label', subject: @project, collection: @labels, as: :label
= paginate @labels, theme: 'gitlab' = paginate @labels, theme: 'gitlab'
- if @labels.blank? - if @labels.blank?
.nothing-here-block .nothing-here-block
......
- commit = @repository.commit(tag.target) - commit = @repository.commit(tag.dereferenced_target)
- release = @releases.find { |release| release.tag == tag.name } - release = @releases.find { |release| release.tag == tag.name }
%li %li
%div %div
......
...@@ -33,7 +33,12 @@ ...@@ -33,7 +33,12 @@
.form-actions .form-actions
- if @page && @page.persisted? - if @page && @page.persisted?
= f.submit 'Save changes', class: "btn-save btn" = f.submit 'Save changes', class: "btn-save btn"
= link_to "Cancel", namespace_project_wiki_path(@project.namespace, @project, @page), class: "btn btn-cancel" .pull-right
- if can?(current_user, :admin_wiki, @project)
= link_to namespace_project_wiki_path(@project.namespace, @project, @page), data: { confirm: "Are you sure you want to delete this page?"}, method: :delete, class: "btn btn-danger btn-grouped" do
Delete
= link_to "Cancel", namespace_project_wiki_path(@project.namespace, @project, @page), class: "btn btn-cancel btn-grouped"
- else - else
= f.submit 'Create page', class: "btn-create btn" = f.submit 'Create page', class: "btn-create btn"
.pull-right
= link_to "Cancel", namespace_project_wiki_path(@project.namespace, @project, :home), class: "btn btn-cancel" = link_to "Cancel", namespace_project_wiki_path(@project.namespace, @project, :home), class: "btn btn-cancel"
...@@ -7,6 +7,3 @@ ...@@ -7,6 +7,3 @@
- if can?(current_user, :create_wiki, @project) - if can?(current_user, :create_wiki, @project)
= link_to namespace_project_wiki_edit_path(@project.namespace, @project, @page), class: "btn" do = link_to namespace_project_wiki_edit_path(@project.namespace, @project, @page), class: "btn" do
Edit Edit
- if can?(current_user, :admin_wiki, @project)
= link_to namespace_project_wiki_path(@project.namespace, @project, @page), data: { confirm: "Are you sure you want to delete this page?"}, method: :delete, class: "btn btn-remove" do
Delete
...@@ -19,7 +19,5 @@ ...@@ -19,7 +19,5 @@
- if can?(current_user, :create_wiki, @project) - if can?(current_user, :create_wiki, @project)
= link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do
New Page New Page
= render 'main_links'
= render 'form' = render 'form'
%ul.nav-links.event-filter.scrolling-tabs %ul.nav-links.event-filter.scrolling-tabs
= event_filter_link EventFilter.all, 'All' = event_filter_link EventFilter.all, 'All'
- if event_filter_visible(:repository)
= event_filter_link EventFilter.push, 'Push events' = event_filter_link EventFilter.push, 'Push events'
- if event_filter_visible(:merge_requests)
= event_filter_link EventFilter.merged, 'Merge events' = event_filter_link EventFilter.merged, 'Merge events'
- if event_filter_visible(:issues)
= event_filter_link EventFilter.comments, 'Comments' = event_filter_link EventFilter.comments, 'Comments'
= event_filter_link EventFilter.team, 'Team' = event_filter_link EventFilter.team, 'Team'
- label_css_id = dom_id(label) - label_css_id = dom_id(label)
- open_issues_count = label.open_issues_count(current_user, @project) - open_issues_count = label.open_issues_count(current_user)
- open_merge_requests_count = label.open_merge_requests_count(current_user, @project) - open_merge_requests_count = label.open_merge_requests_count(current_user)
- subject = local_assigns[:subject]
%li{id: label_css_id, data: { id: label.id } } %li{id: label_css_id, data: { id: label.id } }
= render "shared/label_row", label: label = render "shared/label_row", label: label
...@@ -12,10 +13,10 @@ ...@@ -12,10 +13,10 @@
.dropdown-menu.dropdown-menu-align-right .dropdown-menu.dropdown-menu-align-right
%ul %ul
%li %li
= link_to_label(label, subject: @project, type: :merge_request) do = link_to_label(label, subject: subject, type: :merge_request) do
= pluralize open_merge_requests_count, 'merge request' = pluralize open_merge_requests_count, 'merge request'
%li %li
= link_to_label(label, subject: @project) do = link_to_label(label, subject: subject) do
= pluralize open_issues_count, 'open issue' = pluralize open_issues_count, 'open issue'
- if current_user - if current_user
%li.label-subscription{ data: toggle_subscription_data(label) } %li.label-subscription{ data: toggle_subscription_data(label) }
...@@ -28,9 +29,9 @@ ...@@ -28,9 +29,9 @@
= link_to 'Delete', destroy_label_path(label), title: 'Delete', method: :delete, remote: true, data: {confirm: 'Remove this label? Are you sure?'} = link_to 'Delete', destroy_label_path(label), title: 'Delete', method: :delete, remote: true, data: {confirm: 'Remove this label? Are you sure?'}
.pull-right.hidden-xs.hidden-sm.hidden-md .pull-right.hidden-xs.hidden-sm.hidden-md
= link_to_label(label, subject: @project, type: :merge_request, css_class: 'btn btn-transparent btn-action') do = link_to_label(label, subject: subject, type: :merge_request, css_class: 'btn btn-transparent btn-action') do
= pluralize open_merge_requests_count, 'merge request' = pluralize open_merge_requests_count, 'merge request'
= link_to_label(label, subject: @project, css_class: 'btn btn-transparent btn-action') do = link_to_label(label, subject: subject, css_class: 'btn btn-transparent btn-action') do
= pluralize open_issues_count, 'open issue' = pluralize open_issues_count, 'open issue'
- if current_user - if current_user
......
<svg viewBox="0 0 293 216"><g fill="none" fill-rule="evenodd"><g transform="rotate(-5 211.388 -693.89)"><rect width="163.6" height="200" x=".2" fill="#FFF" stroke="#EEE" stroke-width="3" stroke-linecap="round" stroke-dasharray="6 9" rx="6"/><g transform="translate(24 38)"><path fill="#FC6D26" d="M18.2 14l-4-3.8c-.4-.6-1.4-.6-2 0-.6.6-.6 1.5 0 2l5 5c.3.4.6.5 1 .5s.8 0 1-.4L28 8.8c.6-.6.6-1.5 0-2-.6-.7-1.6-.7-2 0L18 14z"/><path stroke="#6B4FBB" stroke-width="3" d="M27 23.3V27c0 2.3-1.7 4-4 4H4c-2.3 0-4-1.7-4-4V8c0-2.3 1.7-4 4-4h3.8" stroke-linecap="round"/><rect width="76" height="3" x="40" y="11" fill="#6B4FBB" opacity=".5" rx="1.5"/><rect width="43" height="3" x="40" y="21" fill="#6B4FBB" opacity=".5" rx="1.5"/></g><g transform="translate(24 83)"><path fill="#FC6D26" d="M18.2 14l-4-3.8c-.4-.6-1.4-.6-2 0-.6.6-.6 1.5 0 2l5 5c.3.4.6.5 1 .5s.8 0 1-.4L28 8.8c.6-.6.6-1.5 0-2-.6-.7-1.6-.7-2 0L18 14z"/><path stroke="#6B4FBB" stroke-width="3" d="M27 23.3V27c0 2.3-1.7 4-4 4H4c-2.3 0-4-1.7-4-4V8c0-2.3 1.7-4 4-4h3.8" stroke-linecap="round"/><rect width="76" height="3" x="40" y="11" fill="#B5A7DD" rx="1.5"/><rect width="43" height="3" x="40" y="21" fill="#B5A7DD" rx="1.5"/></g><g transform="translate(24 130)"><path fill="#FC6D26" d="M18.2 14l-4-3.8c-.4-.6-1.4-.6-2 0-.6.6-.6 1.5 0 2l5 5c.3.4.6.5 1 .5s.8 0 1-.4L28 8.8c.6-.6.6-1.5 0-2-.6-.7-1.6-.7-2 0L18 14z"/><path stroke="#6B4FBB" stroke-width="3" d="M27 23.3V27c0 2.3-1.7 4-4 4H4c-2.3 0-4-1.7-4-4V8c0-2.3 1.7-4 4-4h3.8" stroke-linecap="round"/><rect width="76" height="3" x="40" y="11" fill="#B5A7DD" rx="1.5"/><rect width="43" height="3" x="40" y="21" fill="#B5A7DD" rx="1.5"/></g></g><path fill="#FFCE29" d="M30 11l-1.8 4-2-4-4-1.8 4-2 2-4 2 4 4 2M286 60l-2.7 6.3-3-6-6-3 6-3 3-6 2.8 6.2 6.6 2.8M263 97l-2 4-2-4-4-2 4-2 2-4 2 4 4 2M12 85l-2.7 6.3-3-6-6-3 6-3 3-6 2.8 6.2 6.6 2.8"/></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 284 337" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<rect id="a" width="180" height="220" x="66.2" y="74.4" rx="6"/>
<mask id="l" width="180" height="220" x="0" y="0" fill="#fff">
<use xlink:href="#a"/>
</mask>
<rect id="b" width="180" height="220" rx="6"/>
<mask id="m" width="180" height="220" x="0" y="0" fill="#fff">
<use xlink:href="#b"/>
</mask>
<rect id="c" width="28" height="28" rx="4"/>
<mask id="n" width="28" height="28" x="0" y="0" fill="#fff">
<use xlink:href="#c"/>
</mask>
<rect id="d" width="28" height="28" rx="4"/>
<mask id="o" width="28" height="28" x="0" y="0" fill="#fff">
<use xlink:href="#d"/>
</mask>
<circle id="e" cx="21.5" cy="21.5" r="21.5"/>
<mask id="p" width="43" height="43" x="0" y="0" fill="#fff">
<use xlink:href="#e"/>
</mask>
<circle id="f" cx="26.5" cy="26.5" r="26.5"/>
<mask id="q" width="53" height="53" x="0" y="0" fill="#fff">
<use xlink:href="#f"/>
</mask>
<circle id="g" cx="9.5" cy="4.5" r="4.5"/>
<mask id="r" width="13" height="13" x="-2" y="-2">
<path fill="#fff" d="M3-2h13v13H3z"/>
<use xlink:href="#g"/>
</mask>
<circle id="h" cx="26.5" cy="26.5" r="26.5"/>
<mask id="s" width="53" height="53" x="0" y="0" fill="#fff">
<use xlink:href="#h"/>
</mask>
<circle id="i" cx="21.5" cy="21.5" r="21.5"/>
<mask id="t" width="43" height="43" x="0" y="0" fill="#fff">
<use xlink:href="#i"/>
</mask>
<path id="j" d="M18 38h15c10.5 0 19-8.5 19-19S43.5 0 33 0H19C8.5 0 0 8.5 0 19c0 6.3 3 12 7.8 15.3l5.2 9c.6 1 1.4 1 2 0l3-5.3z"/>
<mask id="u" width="52" height="44" x="0" y="0" fill="#fff">
<use xlink:href="#j"/>
</mask>
<circle id="k" cx="18.5" cy="18.5" r="18.5"/>
<mask id="v" width="37" height="37" x="0" y="0" fill="#fff">
<use xlink:href="#k"/>
</mask>
</defs>
<g fill="none" fill-rule="evenodd" transform="translate(-6 -4)">
<use stroke="#EEE" stroke-width="6" mask="url(#l)" transform="rotate(-5 156.245 184.425)" xlink:href="#a"/>
<g transform="rotate(5 -707.333 618.042)">
<use fill="#FFF" stroke="#EEE" stroke-width="6" mask="url(#m)" xlink:href="#b"/>
<g transform="translate(29 24)">
<path fill="#FC6D26" d="M18.2 14l-4-3.8c-.4-.6-1.4-.6-2 0-.6.6-.6 1.5 0 2l5 5c.3.4.6.5 1 .5s.8 0 1-.4L28 8.8c.6-.6.6-1.5 0-2-.6-.7-1.6-.7-2 0L18 14z"/>
<path stroke="#6B4FBB" stroke-width="3" d="M27 23.3V27c0 2.3-1.7 4-4 4H4c-2.3 0-4-1.7-4-4V8c0-2.3 1.7-4 4-4h3.8" stroke-linecap="round"/>
<rect width="86" height="3" x="40" y="11" fill="#6B4FBB" opacity=".5" rx="1.5"/>
<rect width="43" height="3" x="40" y="21" fill="#6B4FBB" opacity=".5" rx="1.5"/>
</g>
<g transform="translate(29 69)">
<path fill="#FC6D26" d="M18.2 14l-4-3.8c-.4-.6-1.4-.6-2 0-.6.6-.6 1.5 0 2l5 5c.3.4.6.5 1 .5s.8 0 1-.4L28 8.8c.6-.6.6-1.5 0-2-.6-.7-1.6-.7-2 0L18 14z"/>
<path stroke="#6B4FBB" stroke-width="3" d="M27 23.3V27c0 2.3-1.7 4-4 4H4c-2.3 0-4-1.7-4-4V8c0-2.3 1.7-4 4-4h3.8" stroke-linecap="round"/>
<rect width="86" height="3" x="40" y="11" fill="#B5A7DD" rx="1.5"/>
<rect width="43" height="3" x="40" y="21" fill="#B5A7DD" rx="1.5"/>
</g>
<g transform="translate(28 160)">
<use stroke="#E5E5E5" stroke-width="6" mask="url(#n)" opacity=".7" xlink:href="#c"/>
<rect width="26" height="3" x="41" y="7" fill="#ECECEC" rx="1.5"/>
<rect width="43" height="3" x="41" y="17" fill="#ECECEC" rx="1.5"/>
</g>
<g transform="translate(28 116)">
<use stroke="#E5E5E5" stroke-width="6" mask="url(#o)" xlink:href="#d"/>
<rect width="86" height="3" x="41" y="7" fill="#E5E5E5" rx="1.5"/>
<rect width="43" height="3" x="41" y="17" fill="#E5E5E5" rx="1.5"/>
</g>
</g>
<g transform="rotate(-15 601.917 -782.362)">
<use fill="#FFF" stroke="#B5A7DD" stroke-width="6" mask="url(#p)" xlink:href="#e"/>
<text fill="#6B4FBB" font-family="SourceSansPro-Black, Source Sans Pro" font-size="20" font-weight="700" letter-spacing="-.1">
<tspan x="12" y="27">@</tspan>
</text>
</g>
<g transform="rotate(15 -686.59 1035.907)">
<use fill="#FFF" stroke="#FDE5D8" stroke-width="6" mask="url(#q)" xlink:href="#f"/>
<path fill="#FC6D26" d="M26.5 38.2c3.3 0 9.5-2.5 9.5-9.6 0-7-2.4-6.6-9.5-6.6-7 0-9.5-.4-9.5 6.6s6.2 9.6 9.5 9.6z"/>
<g transform="translate(17 14)">
<use fill="#FC6D26" xlink:href="#g"/>
<use stroke="#FFF" stroke-width="4" mask="url(#r)" xlink:href="#g"/>
</g>
</g>
<g transform="rotate(15 -85.125 65.185)">
<use fill="#FFF" stroke="#B5A7DD" stroke-width="6" mask="url(#s)" xlink:href="#h"/>
<path fill="#6B4FBB" d="M24 18.5c0-1.4 1-2.5 2.5-2.5 1.4 0 2.5 1 2.5 2.5v9c0 1.4-1 2.5-2.5 2.5-1.4 0-2.5-1-2.5-2.5v-9zM26.5 37c1.4 0 2.5-1 2.5-2.5 0-1.4-1-2.5-2.5-2.5-1.4 0-2.5 1-2.5 2.5 0 1.4 1 2.5 2.5 2.5z"/>
</g>
<g transform="rotate(-15 716.492 78.873)">
<use fill="#FFF" stroke="#FDE5D8" stroke-width="6" mask="url(#t)" xlink:href="#i"/>
<path fill="#FC6D26" d="M20 23v-3h3v3h-3zm0 3v1.5c0 .8-.7 1.5-1.5 1.5s-1.5-.7-1.5-1.5V26h-2.5c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5H17v-3h-1.5c-.8 0-1.5-.7-1.5-1.5s.7-1.5 1.5-1.5H17v-2.5c0-.8.7-1.5 1.5-1.5s1.5.7 1.5 1.5V17h3v-1.5c0-.8.7-1.5 1.5-1.5s1.5.7 1.5 1.5V17h2.5c.8 0 1.5.7 1.5 1.5s-.7 1.5-1.5 1.5H26v3h1.5c.8 0 1.5.7 1.5 1.5s-.7 1.5-1.5 1.5H26v2.5c0 .8-.7 1.5-1.5 1.5s-1.5-.7-1.5-1.5V26h-3z"/>
</g>
<g transform="rotate(-15 129.114 -585.74)">
<use stroke="#FDE5D8" stroke-width="6" mask="url(#u)" xlink:href="#j"/>
<circle cx="16" cy="20" r="2" fill="#FC6D26"/>
<circle cx="27" cy="20" r="2" fill="#FC6D26"/>
<circle cx="38" cy="20" r="2" fill="#FC6D26"/>
</g>
<g transform="rotate(-15 1254.8 -458.986)">
<use stroke="#FDE5D8" stroke-width="6" mask="url(#v)" xlink:href="#k"/>
<path fill="#FC6D26" d="M10.6 19l2-2c.5-.5.5-1 0-1.5-.3-.4-1-.4-1.3 0l-2.8 2.8c-.2.2-.3.4-.3.7 0 .3 0 .5.3.7l2.8 2.8c.4.4 1 .4 1.4 0 .4-.4.4-1 0-1.4l-2-2zm14.8 0l-2-2c-.5-.5-.5-1 0-1.5.3-.4 1-.4 1.3 0l2.8 2.8c.2.2.3.4.3.7 0 .3 0 .5-.3.7l-2.8 2.8c-.4.4-1 .4-1.4 0-.4-.4-.4-1 0-1.4l2-2z"/>
<rect width="2" height="7" x="17" y="15.1" fill="#FC6D26" opacity=".5" transform="rotate(15 18.002 18.64)" rx="1"/>
</g>
</g>
</svg>
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
%span.visibility-icon.has-tooltip{data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group)} %span.visibility-icon.has-tooltip{data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group)}
= visibility_level_icon(group.visibility_level, fw: false) = visibility_level_icon(group.visibility_level, fw: false)
.image-container.s40
= image_tag group_icon(group), class: "avatar s40 hidden-xs" = image_tag group_icon(group), class: "avatar s40 hidden-xs"
.title .title
= link_to group, class: 'group-name' do = link_to group, class: 'group-name' do
......
- project = @target_project || @project - project = @target_project || @project
- extra_class = extra_class || '' - extra_class = extra_class || ''
- show_menu_above = show_menu_above || false - show_menu_above = show_menu_above || false
- selected_text = selected.try(:title) - selected_text = selected.try(:title) || params[:milestone_title]
- dropdown_title = local_assigns.fetch(:dropdown_title, "Filter by milestone") - dropdown_title = local_assigns.fetch(:dropdown_title, "Filter by milestone")
- if selected.present? - if selected.present?
= hidden_field_tag(name, name == :milestone_title ? selected.title : selected.id) = hidden_field_tag(name, name == :milestone_title ? selected_text : selected.id)
= dropdown_tag(milestone_dropdown_label(selected_text), options: { title: dropdown_title, toggle_class: "js-milestone-select js-filter-submit #{extra_class}", filter: true, dropdown_class: "dropdown-menu-selectable dropdown-menu-milestone", = dropdown_tag(milestone_dropdown_label(selected_text), options: { title: dropdown_title, toggle_class: "js-milestone-select js-filter-submit #{extra_class}", filter: true, dropdown_class: "dropdown-menu-selectable dropdown-menu-milestone",
placeholder: "Search milestones", footer_content: project.present?, data: { show_no: true, show_menu_above: show_menu_above, show_any: show_any, show_upcoming: show_upcoming, field_name: name, selected: selected.try(:title), project_id: project.try(:id), milestones: milestones_filter_dropdown_path, default_label: "Milestone" } }) do placeholder: "Search milestones", footer_content: project.present?, data: { show_no: true, show_menu_above: show_menu_above, show_any: show_any, show_upcoming: show_upcoming, field_name: name, selected: selected.try(:title), project_id: project.try(:id), milestones: milestones_filter_dropdown_path, default_label: "Milestone" } }) do
- if project - if project
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
= link_to project_path(project), class: dom_class(project) do = link_to project_path(project), class: dom_class(project) do
- if avatar - if avatar
.dash-project-avatar .dash-project-avatar
.image-container.s40
- if use_creator_avatar - if use_creator_avatar
= image_tag avatar_icon(project.creator.email, 40), class: "avatar s40", alt:'' = image_tag avatar_icon(project.creator.email, 40), class: "avatar s40", alt:''
- else - else
......
.clearfix .clearfix
- groups.each do |group| - groups.each do |group|
= link_to group, class: 'profile-groups-avatars inline', title: group.name do = link_to group, class: 'profile-groups-avatars inline', title: group.name do
.image-container.s40
= image_tag group_icon(group), class: 'avatar group-avatar s40' = image_tag group_icon(group), class: 'avatar group-avatar s40'
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