Merge branch 'master' into ide
* master: (177 commits) Add changelog Bump gitlab-shell version to 5.8.0 to fix Git for Windows 2.14 Make contextual sidebar collapsible Fixed sidebar context header hover colors Use correct `Environment`-class within `Gitlab` namespace Remove gl.Activities from Commits page Move `let` calls inside the `describe` block using them Add `/assign me` alias support for assigning issuables to oneself GRPC::Unavailable (< GRPC::BadStatus) is wrapped in a CommandError Use `broken_storage` in the fs_shards_spec. Eager load project creators for project dashboards Memoize a user's personal projects count Remove redundant query from User#recent_push Improve checking if projects would be returned Change spelling of gitlab-shell Remove unused #tree-holder Add custom linter for inline JavaScript to haml_lint Rename user_can_admin? because it's more accurate Synchronous zanata community contribution translation Add Korean translation to i18n ...
This commit is contained in:
commit
7767ceef47
|
@ -66,16 +66,18 @@ stages:
|
|||
- mysql:latest
|
||||
- redis:alpine
|
||||
|
||||
.only-master-and-ee-or-mysql: &only-master-and-ee-or-mysql
|
||||
.only-if-want-mysql: &only-if-want-mysql
|
||||
only:
|
||||
- /mysql/
|
||||
- /-stable/
|
||||
- master@gitlab-org/gitlab-ce
|
||||
- master@gitlab-org/gitlab-ee
|
||||
- master@gitlab/gitlabhq
|
||||
- master@gitlab/gitlab-ee
|
||||
- tags@gitlab-org/gitlab-ce
|
||||
- tags@gitlab-org/gitlab-ee
|
||||
- tags@gitlab/gitlabhq
|
||||
- //@gitlab-org/gitlab-ee
|
||||
- //@gitlab/gitlab-ee
|
||||
- tags@gitlab/gitlab-ee
|
||||
|
||||
# Skip all jobs except the ones that begin with 'docs/'.
|
||||
# Used for commits including ONLY documentation changes.
|
||||
|
@ -114,7 +116,7 @@ stages:
|
|||
.rspec-knapsack-mysql: &rspec-knapsack-mysql
|
||||
<<: *rspec-knapsack
|
||||
<<: *use-mysql
|
||||
<<: *only-master-and-ee-or-mysql
|
||||
<<: *only-if-want-mysql
|
||||
<<: *except-docs
|
||||
|
||||
.spinach-knapsack: &spinach-knapsack
|
||||
|
@ -146,7 +148,7 @@ stages:
|
|||
.spinach-knapsack-mysql: &spinach-knapsack-mysql
|
||||
<<: *spinach-knapsack
|
||||
<<: *use-mysql
|
||||
<<: *only-master-and-ee-or-mysql
|
||||
<<: *only-if-want-mysql
|
||||
<<: *except-docs
|
||||
|
||||
.only-canonical-masters: &only-canonical-masters
|
||||
|
|
|
@ -35,9 +35,21 @@ linters:
|
|||
HtmlAttributes:
|
||||
enabled: true
|
||||
|
||||
IdNames:
|
||||
enabled: false
|
||||
|
||||
ImplicitDiv:
|
||||
enabled: true
|
||||
|
||||
InlineJavaScript:
|
||||
enabled: true
|
||||
|
||||
InlineStyles:
|
||||
enabled: false
|
||||
|
||||
InstanceVariables:
|
||||
enabled: false
|
||||
|
||||
LeadingCommentSpace:
|
||||
enabled: false
|
||||
|
||||
|
@ -54,6 +66,9 @@ linters:
|
|||
ObjectReferenceAttributes:
|
||||
enabled: true
|
||||
|
||||
RepeatedId:
|
||||
enabled: false
|
||||
|
||||
RuboCop:
|
||||
enabled: false
|
||||
# These cops are incredibly noisy when it comes to HAML templates, so we
|
||||
|
@ -101,3 +116,6 @@ linters:
|
|||
|
||||
UnnecessaryStringOutput:
|
||||
enabled: true
|
||||
|
||||
ViewLength:
|
||||
enabled: false
|
||||
|
|
26
CHANGELOG.md
26
CHANGELOG.md
|
@ -1708,8 +1708,6 @@ entry.
|
|||
|
||||
## 8.16.7 (2017-02-27)
|
||||
|
||||
- No changes.
|
||||
- No changes.
|
||||
- Fix MR changes tab size count when there are over 100 files in the diff.
|
||||
|
||||
## 8.16.6 (2017-02-17)
|
||||
|
@ -1923,6 +1921,14 @@ entry.
|
|||
- Prevent the GitHub importer from assigning labels and comments to merge requests or issues belonging to other projects.
|
||||
- Patch XSS vulnerability in RDOC support.
|
||||
|
||||
## 8.15.5 (2017-01-20)
|
||||
|
||||
- Ensure export files are removed after a namespace is deleted.
|
||||
- Don't allow project guests to subscribe to merge requests through the API. (Robert Schilling)
|
||||
- Prevent users from creating notes on resources they can't access.
|
||||
- Prevent users from deleting system deploy keys via the project deploy key API.
|
||||
- Upgrade omniauth gem to 1.3.2.
|
||||
|
||||
## 8.15.4 (2017-01-09)
|
||||
|
||||
- Make successful pipeline emails off for watchers. !8176
|
||||
|
@ -2205,6 +2211,14 @@ entry.
|
|||
- Speed up group milestone index by passing group_id to IssuesFinder. !8363
|
||||
- Ensure issuable state changes only fire webhooks once.
|
||||
|
||||
## 8.14.7 (2017-01-21)
|
||||
|
||||
- Ensure export files are removed after a namespace is deleted.
|
||||
- Don't allow project guests to subscribe to merge requests through the API. (Robert Schilling)
|
||||
- Prevent users from creating notes on resources they can't access.
|
||||
- Prevent users from deleting system deploy keys via the project deploy key API.
|
||||
- Upgrade omniauth gem to 1.3.2.
|
||||
|
||||
## 8.14.6 (2017-01-10)
|
||||
|
||||
- Update the gitlab-markup gem to the version 1.5.1. !8509
|
||||
|
@ -2487,6 +2501,14 @@ entry.
|
|||
- Fix "Without projects" filter. !6611 (Ben Bodenmiller)
|
||||
- Fix 404 when visit /projects page
|
||||
|
||||
## 8.13.12 (2017-01-21)
|
||||
|
||||
- Ensure export files are removed after a namespace is deleted.
|
||||
- Don't allow project guests to subscribe to merge requests through the API. (Robert Schilling)
|
||||
- Prevent users from creating notes on resources they can't access.
|
||||
- Prevent users from deleting system deploy keys via the project deploy key API.
|
||||
- Upgrade omniauth gem to 1.3.2.
|
||||
|
||||
## 8.13.11 (2017-01-10)
|
||||
|
||||
- Update the gitlab-markup gem to the version 1.5.1. !8509
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.26.0
|
||||
0.27.0
|
||||
|
|
|
@ -1 +1 @@
|
|||
5.4.0
|
||||
5.8.0
|
||||
|
|
8
Gemfile
8
Gemfile
|
@ -314,11 +314,11 @@ group :development, :test do
|
|||
gem 'pry-rails', '~> 0.3.4'
|
||||
|
||||
gem 'awesome_print', '~> 1.2.0', require: false
|
||||
gem 'fuubar', '~> 2.0.0'
|
||||
gem 'fuubar', '~> 2.2.0'
|
||||
|
||||
gem 'database_cleaner', '~> 1.5.0'
|
||||
gem 'factory_girl_rails', '~> 4.7.0'
|
||||
gem 'rspec-rails', '~> 3.5.0'
|
||||
gem 'rspec-rails', '~> 3.6.0'
|
||||
gem 'rspec-retry', '~> 0.4.5'
|
||||
gem 'spinach-rails', '~> 0.2.1'
|
||||
gem 'spinach-rerun-reporter', '~> 0.0.2'
|
||||
|
@ -342,7 +342,7 @@ group :development, :test do
|
|||
gem 'rubocop', '~> 0.49.1', require: false
|
||||
gem 'rubocop-rspec', '~> 1.15.1', require: false
|
||||
gem 'scss_lint', '~> 0.54.0', require: false
|
||||
gem 'haml_lint', '~> 0.21.0', require: false
|
||||
gem 'haml_lint', '~> 0.26.0', require: false
|
||||
gem 'simplecov', '~> 0.14.0', require: false
|
||||
gem 'flay', '~> 2.8.0', require: false
|
||||
gem 'bundler-audit', '~> 0.5.0', require: false
|
||||
|
@ -391,7 +391,7 @@ gem 'vmstat', '~> 2.3.0'
|
|||
gem 'sys-filesystem', '~> 1.1.6'
|
||||
|
||||
# Gitaly GRPC client
|
||||
gem 'gitaly', '~> 0.21.0'
|
||||
gem 'gitaly', '~> 0.24.0'
|
||||
|
||||
gem 'toml-rb', '~> 0.3.15', require: false
|
||||
|
||||
|
|
61
Gemfile.lock
61
Gemfile.lock
|
@ -156,7 +156,7 @@ GEM
|
|||
devise (~> 4.0)
|
||||
railties
|
||||
rotp (~> 2.0)
|
||||
diff-lcs (1.2.5)
|
||||
diff-lcs (1.3)
|
||||
diffy (3.1.0)
|
||||
docile (1.1.5)
|
||||
domain_name (0.5.20161021)
|
||||
|
@ -250,8 +250,8 @@ GEM
|
|||
foreman (0.78.0)
|
||||
thor (~> 0.19.1)
|
||||
formatador (0.2.5)
|
||||
fuubar (2.0.0)
|
||||
rspec (~> 3.0)
|
||||
fuubar (2.2.0)
|
||||
rspec-core (~> 3.0)
|
||||
ruby-progressbar (~> 1.4)
|
||||
gemnasium-gitlab-service (0.2.6)
|
||||
rugged (~> 0.21)
|
||||
|
@ -269,7 +269,7 @@ GEM
|
|||
po_to_json (>= 1.0.0)
|
||||
rails (>= 3.2.0)
|
||||
gherkin-ruby (0.3.2)
|
||||
gitaly (0.21.0)
|
||||
gitaly (0.24.0)
|
||||
google-protobuf (~> 3.1)
|
||||
grpc (~> 1.0)
|
||||
github-linguist (4.7.6)
|
||||
|
@ -356,10 +356,11 @@ GEM
|
|||
googleauth (~> 0.5.1)
|
||||
haml (4.0.7)
|
||||
tilt
|
||||
haml_lint (0.21.0)
|
||||
haml (~> 4.0)
|
||||
haml_lint (0.26.0)
|
||||
haml (>= 4.0, < 5.1)
|
||||
rainbow
|
||||
rake (>= 10, < 13)
|
||||
rubocop (>= 0.47.0)
|
||||
rubocop (>= 0.49.0)
|
||||
sysexits (~> 1.1)
|
||||
hamlit (2.6.1)
|
||||
temple (~> 0.7.6)
|
||||
|
@ -393,7 +394,7 @@ GEM
|
|||
json (~> 1.8)
|
||||
multi_xml (>= 0.5.2)
|
||||
httpclient (2.8.2)
|
||||
i18n (0.8.1)
|
||||
i18n (0.8.6)
|
||||
ice_nine (0.11.2)
|
||||
influxdb (0.2.3)
|
||||
cause
|
||||
|
@ -610,7 +611,7 @@ GEM
|
|||
pry-rails (0.3.5)
|
||||
pry (>= 0.9.10)
|
||||
pyu-ruby-sasl (0.0.3.3)
|
||||
rack (1.6.5)
|
||||
rack (1.6.8)
|
||||
rack-accept (0.4.5)
|
||||
rack (>= 0.4)
|
||||
rack-attack (4.4.1)
|
||||
|
@ -658,7 +659,7 @@ GEM
|
|||
rainbow (2.2.2)
|
||||
rake
|
||||
raindrops (0.18.0)
|
||||
rake (10.5.0)
|
||||
rake (12.0.0)
|
||||
rblineprof (0.3.6)
|
||||
debugger-ruby_core_source (~> 1.3)
|
||||
rdoc (4.2.2)
|
||||
|
@ -702,30 +703,26 @@ GEM
|
|||
chunky_png
|
||||
rqrcode-rails3 (0.1.7)
|
||||
rqrcode (>= 0.4.2)
|
||||
rspec (3.5.0)
|
||||
rspec-core (~> 3.5.0)
|
||||
rspec-expectations (~> 3.5.0)
|
||||
rspec-mocks (~> 3.5.0)
|
||||
rspec-core (3.5.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-expectations (3.5.0)
|
||||
rspec-core (3.6.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-expectations (3.6.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-mocks (3.5.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-mocks (3.6.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-rails (3.5.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-rails (3.6.0)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 3.5.0)
|
||||
rspec-expectations (~> 3.5.0)
|
||||
rspec-mocks (~> 3.5.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-core (~> 3.6.0)
|
||||
rspec-expectations (~> 3.6.0)
|
||||
rspec-mocks (~> 3.6.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-retry (0.4.5)
|
||||
rspec-core
|
||||
rspec-set (0.1.3)
|
||||
rspec-support (3.5.0)
|
||||
rspec-support (3.6.0)
|
||||
rspec_profiling (0.0.5)
|
||||
activerecord
|
||||
pg
|
||||
|
@ -860,7 +857,7 @@ GEM
|
|||
truncato (0.7.8)
|
||||
htmlentities (~> 4.3.1)
|
||||
nokogiri (~> 1.6.1)
|
||||
tzinfo (1.2.2)
|
||||
tzinfo (1.2.3)
|
||||
thread_safe (~> 0.1)
|
||||
u2f (0.2.1)
|
||||
uglifier (2.7.2)
|
||||
|
@ -972,13 +969,13 @@ DEPENDENCIES
|
|||
fog-rackspace (~> 0.1.1)
|
||||
font-awesome-rails (~> 4.7)
|
||||
foreman (~> 0.78.0)
|
||||
fuubar (~> 2.0.0)
|
||||
fuubar (~> 2.2.0)
|
||||
gemnasium-gitlab-service (~> 0.2)
|
||||
gemojione (~> 3.0)
|
||||
gettext (~> 3.2.2)
|
||||
gettext_i18n_rails (~> 1.8.0)
|
||||
gettext_i18n_rails_js (~> 1.2.0)
|
||||
gitaly (~> 0.21.0)
|
||||
gitaly (~> 0.24.0)
|
||||
github-linguist (~> 4.7.0)
|
||||
gitlab-flowdock-git-hook (~> 1.0.1)
|
||||
gitlab-markup (~> 1.5.1)
|
||||
|
@ -991,7 +988,7 @@ DEPENDENCIES
|
|||
grape (~> 0.19.2)
|
||||
grape-entity (~> 0.6.0)
|
||||
grape-route-helpers (~> 2.0.0)
|
||||
haml_lint (~> 0.21.0)
|
||||
haml_lint (~> 0.26.0)
|
||||
hamlit (~> 2.6.1)
|
||||
hashie-forbidden_attributes
|
||||
health_check (~> 2.6.0)
|
||||
|
@ -1076,7 +1073,7 @@ DEPENDENCIES
|
|||
responders (~> 2.0)
|
||||
rouge (~> 2.0)
|
||||
rqrcode-rails3 (~> 0.1.7)
|
||||
rspec-rails (~> 3.5.0)
|
||||
rspec-rails (~> 3.6.0)
|
||||
rspec-retry (~> 0.4.5)
|
||||
rspec-set (~> 0.1.3)
|
||||
rspec_profiling (~> 0.0.5)
|
||||
|
@ -1130,4 +1127,4 @@ DEPENDENCIES
|
|||
wikicloth (= 0.8.1)
|
||||
|
||||
BUNDLED WITH
|
||||
1.15.1
|
||||
1.15.3
|
||||
|
|
|
@ -10,7 +10,7 @@ class AjaxLoadingSpinner {
|
|||
e.target.setAttribute('disabled', '');
|
||||
const iconElement = e.target.querySelector('i');
|
||||
// get first fa- icon
|
||||
const originalIcon = iconElement.className.match(/(fa-)([^\s]+)/g).first();
|
||||
const originalIcon = iconElement.className.match(/(fa-)([^\s]+)/g)[0];
|
||||
iconElement.dataset.icon = originalIcon;
|
||||
AjaxLoadingSpinner.toggleLoadingIcon(iconElement);
|
||||
$(e.target).off('ajax:beforeSend', AjaxLoadingSpinner.ajaxBeforeSend);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable class-methods-use-this */
|
||||
/* global Flash */
|
||||
|
||||
import _ from 'underscore';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
const animationEndEventString = 'animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd';
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import _ from 'underscore';
|
||||
import '../commons/bootstrap';
|
||||
|
||||
// Requires Input behavior
|
||||
|
@ -48,7 +49,9 @@ function hideOrShowHelpBlock(form) {
|
|||
|
||||
$(() => {
|
||||
const $form = $('form.js-requires-input');
|
||||
$form.requiresInput();
|
||||
hideOrShowHelpBlock($form);
|
||||
$('.select2.js-select-namespace').change(() => hideOrShowHelpBlock($form));
|
||||
if ($form) {
|
||||
$form.requiresInput();
|
||||
hideOrShowHelpBlock($form);
|
||||
$('.select2.js-select-namespace').change(() => hideOrShowHelpBlock($form));
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
// Toggle button. Show/hide content inside parent container.
|
||||
// Button does not change visibility. If button has icon - it changes chevron style.
|
||||
//
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
/* global BoardService */
|
||||
/* global Flash */
|
||||
|
||||
import _ from 'underscore';
|
||||
import Vue from 'vue';
|
||||
import VueResource from 'vue-resource';
|
||||
import FilteredSearchBoards from './filtered_search_boards';
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* global ListLabel */
|
||||
|
||||
import _ from 'underscore';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
const Store = gl.issueBoards.BoardsStore;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* global ListIssue */
|
||||
|
||||
import Vue from 'vue';
|
||||
import queryData from '../../utils/query_data';
|
||||
import loadingIcon from '../../../vue_shared/components/loading_icon.vue';
|
||||
import queryData from '~/boards/utils/query_data';
|
||||
import loadingIcon from '~/vue_shared/components/loading_icon.vue';
|
||||
import './header';
|
||||
import './list';
|
||||
import './footer';
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* eslint-disable comma-dangle, func-names, no-new, space-before-function-paren, one-var,
|
||||
promise/catch-or-return */
|
||||
import _ from 'underscore';
|
||||
|
||||
window.gl = window.gl || {};
|
||||
window.gl.issueBoards = window.gl.issueBoards || {};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable comma-dangle, space-before-function-paren, one-var, no-shadow, dot-notation, max-len */
|
||||
/* global List */
|
||||
|
||||
import _ from 'underscore';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
window.gl = window.gl || {};
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'bootstrap-sass/assets/javascripts/bootstrap/tab';
|
|||
import 'bootstrap-sass/assets/javascripts/bootstrap/transition';
|
||||
import 'bootstrap-sass/assets/javascripts/bootstrap/tooltip';
|
||||
import 'bootstrap-sass/assets/javascripts/bootstrap/popover';
|
||||
import 'bootstrap-sass/assets/javascripts/bootstrap/button';
|
||||
|
||||
// custom jQuery functions
|
||||
$.fn.extend({
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'underscore';
|
||||
import './polyfills';
|
||||
import './jquery';
|
||||
import './bootstrap';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable class-methods-use-this, object-shorthand, no-unused-vars, no-use-before-define, no-new, max-len, no-restricted-syntax, guard-for-in, no-continue */
|
||||
|
||||
import _ from 'underscore';
|
||||
import './lib/utils/common_utils';
|
||||
import { placeholderImage } from './lazy_loader';
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ $(() => {
|
|||
});
|
||||
},
|
||||
selectDefaultStage() {
|
||||
const stage = this.state.stages.first();
|
||||
const stage = this.state.stages[0];
|
||||
this.selectStage(stage);
|
||||
},
|
||||
selectStage(stage) {
|
||||
|
|
|
@ -94,7 +94,7 @@ const JumpToDiscussion = Vue.extend({
|
|||
hasDiscussionsToJumpTo = false;
|
||||
}
|
||||
}
|
||||
} else if (activeTab !== 'notes') {
|
||||
} else if (activeTab !== 'show') {
|
||||
// If we are on the commits or builds tabs,
|
||||
// there are no discussions to jump to.
|
||||
hasDiscussionsToJumpTo = false;
|
||||
|
@ -103,12 +103,12 @@ const JumpToDiscussion = Vue.extend({
|
|||
if (!hasDiscussionsToJumpTo) {
|
||||
// If there are no discussions to jump to on the current page,
|
||||
// switch to the notes tab and jump to the first disucssion there.
|
||||
window.mrTabs.activateTab('notes');
|
||||
activeTab = 'notes';
|
||||
window.mrTabs.activateTab('show');
|
||||
activeTab = 'show';
|
||||
jumpToFirstDiscussion = true;
|
||||
}
|
||||
|
||||
if (activeTab === 'notes') {
|
||||
if (activeTab === 'show') {
|
||||
discussionsSelector = '.discussion[data-discussion-id]';
|
||||
discussionIdsInScope = discussionIdsForElements($(discussionsSelector));
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ const JumpToDiscussion = Vue.extend({
|
|||
|
||||
let $target = $(`${discussionsSelector}[data-discussion-id="${nextUnresolvedDiscussionId}"]`);
|
||||
|
||||
if (activeTab === 'notes') {
|
||||
if (activeTab === 'show') {
|
||||
$target = $target.closest('.note-discussion');
|
||||
|
||||
// If the next discussion is closed, toggle it open.
|
||||
|
|
|
@ -80,10 +80,6 @@ import UserFeatureHelper from './helpers/user_feature_helper';
|
|||
(function() {
|
||||
var Dispatcher;
|
||||
|
||||
$(function() {
|
||||
return new Dispatcher();
|
||||
});
|
||||
|
||||
Dispatcher = (function() {
|
||||
function Dispatcher() {
|
||||
this.initSearch();
|
||||
|
@ -338,7 +334,6 @@ import UserFeatureHelper from './helpers/user_feature_helper';
|
|||
break;
|
||||
case 'projects:commits:show':
|
||||
CommitsList.init(document.querySelector('.js-project-commits-show').dataset.commitsLimit);
|
||||
new gl.Activities();
|
||||
shortcut_handler = new ShortcutsNavigation();
|
||||
GpgBadges.fetch();
|
||||
break;
|
||||
|
@ -351,6 +346,8 @@ import UserFeatureHelper from './helpers/user_feature_helper';
|
|||
break;
|
||||
case 'projects:edit':
|
||||
setupProjectEdit();
|
||||
// Initialize expandable settings panels
|
||||
initSettingsPanels();
|
||||
break;
|
||||
case 'projects:imports:show':
|
||||
new ProjectImport();
|
||||
|
@ -511,7 +508,7 @@ import UserFeatureHelper from './helpers/user_feature_helper';
|
|||
new gl.DueDateSelectors();
|
||||
break;
|
||||
}
|
||||
switch (path.first()) {
|
||||
switch (path[0]) {
|
||||
case 'sessions':
|
||||
case 'omniauth_callbacks':
|
||||
if (!gon.u2f) break;
|
||||
|
@ -640,4 +637,8 @@ import UserFeatureHelper from './helpers/user_feature_helper';
|
|||
|
||||
return Dispatcher;
|
||||
})();
|
||||
|
||||
$(function() {
|
||||
new Dispatcher();
|
||||
});
|
||||
}).call(window);
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
/* eslint-disable func-names, space-before-function-paren, wrap-iife, max-len, one-var, no-var, one-var-declaration-per-line, no-unused-vars, camelcase, quotes, no-useless-concat, prefer-template, quote-props, comma-dangle, object-shorthand, consistent-return, prefer-arrow-callback */
|
||||
/* global Dropzone */
|
||||
|
||||
import _ from 'underscore';
|
||||
import './preview_markdown';
|
||||
|
||||
window.DropzoneInput = (function() {
|
||||
function DropzoneInput(form) {
|
||||
Dropzone.autoDiscover = false;
|
||||
const divHover = '<div class="div-dropzone-hover"></div>';
|
||||
const iconPaperclip = '<i class="fa fa-paperclip div-dropzone-icon"></i>';
|
||||
const $attachButton = form.find('.button-attach-file');
|
||||
|
@ -218,7 +217,7 @@ window.DropzoneInput = (function() {
|
|||
value = e.clipboardData.getData('text/plain');
|
||||
}
|
||||
value = value.split("\r");
|
||||
return value.first();
|
||||
return value[0];
|
||||
};
|
||||
|
||||
const showSpinner = function(e) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import _ from 'underscore';
|
||||
import emojiMap from 'emojis/digests.json';
|
||||
import emojiAliases from 'emojis/aliases.json';
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
// TODO: remove this
|
||||
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Array.prototype.first = function first() {
|
||||
return this[0];
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Array.prototype.last = function last() {
|
||||
return this[this.length - 1];
|
||||
};
|
|
@ -1,3 +1,5 @@
|
|||
import _ from 'underscore';
|
||||
|
||||
/**
|
||||
* Makes search request for content when user types a value in the search input.
|
||||
* Updates the html content of the page with the received one.
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import _ from 'underscore';
|
||||
import FilteredSearchContainer from './container';
|
||||
|
||||
class DropdownUtils {
|
||||
|
@ -122,11 +123,11 @@ class DropdownUtils {
|
|||
|
||||
if (!allowMultiple && itemInExistingTokens) {
|
||||
updatedItem.droplab_hidden = true;
|
||||
} else if (!lastKey || searchInput.split('').last() === ' ') {
|
||||
} else if (!lastKey || _.last(searchInput.split('')) === ' ') {
|
||||
updatedItem.droplab_hidden = false;
|
||||
} else if (lastKey) {
|
||||
const split = lastKey.split(':');
|
||||
const tokenName = split[0].split(' ').last();
|
||||
const tokenName = _.last(split[0].split(' '));
|
||||
|
||||
const match = updatedItem.hint.indexOf(tokenName.toLowerCase()) === -1;
|
||||
updatedItem.droplab_hidden = tokenName ? match : false;
|
||||
|
|
|
@ -167,7 +167,7 @@ class FilteredSearchDropdownManager {
|
|||
// Eg. token = 'label:'
|
||||
|
||||
const split = lastToken.split(':');
|
||||
const dropdownName = split[0].split(' ').last();
|
||||
const dropdownName = _.last(split[0].split(' '));
|
||||
this.loadDropdown(split.length > 1 ? dropdownName : '');
|
||||
} else if (lastToken) {
|
||||
// Token has been initialized into an object because it has a value
|
||||
|
|
|
@ -367,7 +367,7 @@ class FilteredSearchManager {
|
|||
const fragments = searchToken.split(':');
|
||||
if (fragments.length > 1) {
|
||||
const inputValues = fragments[0].split(' ');
|
||||
const tokenKey = inputValues.last();
|
||||
const tokenKey = _.last(inputValues);
|
||||
|
||||
if (inputValues.length > 1) {
|
||||
inputValues.pop();
|
||||
|
|
|
@ -23,6 +23,7 @@ export const showSubLevelItems = (el) => {
|
|||
const top = calculateTop(boundingRect, subItems.offsetHeight);
|
||||
const isAbove = top < boundingRect.top;
|
||||
|
||||
subItems.classList.add('fly-out-list');
|
||||
subItems.style.transform = `translate3d(0, ${Math.floor(top)}px, 0)`;
|
||||
|
||||
if (isAbove) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import _ from 'underscore';
|
||||
import glRegexp from './lib/utils/regexp';
|
||||
import AjaxCache from './lib/utils/ajax_cache';
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* eslint-disable func-names, no-underscore-dangle, space-before-function-paren, no-var, one-var, one-var-declaration-per-line, prefer-rest-params, max-len, vars-on-top, wrap-iife, no-unused-vars, quotes, no-shadow, no-cond-assign, prefer-arrow-callback, no-return-assign, no-else-return, camelcase, comma-dangle, no-lonely-if, guard-for-in, no-restricted-syntax, consistent-return, prefer-template, no-param-reassign, no-loop-func, no-mixed-operators */
|
||||
/* global fuzzaldrinPlus */
|
||||
import _ from 'underscore';
|
||||
import { isObject } from './lib/utils/type_utility';
|
||||
|
||||
var GitLabDropdown, GitLabDropdownFilter, GitLabDropdownRemote, GitLabDropdownInput;
|
||||
|
@ -158,7 +159,7 @@ GitLabDropdownFilter = (function() {
|
|||
} else {
|
||||
elements = this.options.elements();
|
||||
if (search_text) {
|
||||
return elements.each(function() {
|
||||
elements.each(function() {
|
||||
var $el, matches;
|
||||
$el = $(this);
|
||||
matches = fuzzaldrinPlus.match($el.text().trim(), search_text);
|
||||
|
@ -171,8 +172,10 @@ GitLabDropdownFilter = (function() {
|
|||
}
|
||||
});
|
||||
} else {
|
||||
return elements.show().removeClass('option-hidden');
|
||||
elements.show().removeClass('option-hidden');
|
||||
}
|
||||
|
||||
elements.parent().find('.dropdown-menu-empty-link').toggleClass('hidden', elements.is(':visible'));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -782,9 +785,15 @@ GitLabDropdown = (function() {
|
|||
GitLabDropdown.prototype.focusTextInput = function(triggerFocus = false) {
|
||||
if (this.options.filterable) {
|
||||
this.dropdown.one('transitionend', () => {
|
||||
const initialScrollTop = $(window).scrollTop();
|
||||
|
||||
if (this.dropdown.is('.open')) {
|
||||
this.filterInput.focus();
|
||||
}
|
||||
|
||||
if ($(window).scrollTop() < initialScrollTop) {
|
||||
$(window).scrollTop(initialScrollTop);
|
||||
}
|
||||
});
|
||||
|
||||
if (triggerFocus) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, one-var, camelcase, one-var-declaration-per-line, quotes, no-param-reassign, quote-props, comma-dangle, prefer-template, max-len, no-return-assign, no-shadow */
|
||||
|
||||
import _ from 'underscore';
|
||||
import d3 from 'd3';
|
||||
import { ContributorsGraph, ContributorsAuthorGraph, ContributorsMasterGraph } from './stat_graph_contributors_graph';
|
||||
import ContributorsStatGraphUtil from './stat_graph_contributors_util';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, max-len, no-restricted-syntax, vars-on-top, no-use-before-define, no-param-reassign, new-cap, no-underscore-dangle, wrap-iife, comma-dangle, no-return-assign, prefer-arrow-callback, quotes, prefer-template, newline-per-chained-call, no-else-return, no-shadow */
|
||||
|
||||
import _ from 'underscore';
|
||||
import d3 from 'd3';
|
||||
|
||||
const extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* eslint-disable func-names, space-before-function-paren, object-shorthand, no-var, one-var, camelcase, one-var-declaration-per-line, comma-dangle, no-param-reassign, no-return-assign, quotes, prefer-arrow-callback, wrap-iife, consistent-return, no-unused-vars, max-len, no-cond-assign, no-else-return, max-len */
|
||||
import _ from 'underscore';
|
||||
|
||||
export default {
|
||||
parse_log: function(log) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* eslint-disable comma-dangle, quotes, consistent-return, func-names, array-callback-return, space-before-function-paren, prefer-arrow-callback, max-len, no-unused-expressions, no-sequences, no-underscore-dangle, no-unused-vars, no-param-reassign */
|
||||
/* global IssuableIndex */
|
||||
/* global Flash */
|
||||
import _ from 'underscore';
|
||||
|
||||
export default {
|
||||
init({ container, form, issues, prefixId } = {}) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable no-param-reassign, func-names, no-var, camelcase, no-unused-vars, object-shorthand, space-before-function-paren, no-return-assign, comma-dangle, consistent-return, one-var, one-var-declaration-per-line, quotes, prefer-template, prefer-arrow-callback, wrap-iife, max-len */
|
||||
/* global IssuableIndex */
|
||||
|
||||
import _ from 'underscore';
|
||||
import IssuableBulkUpdateSidebar from './issuable_bulk_update_sidebar';
|
||||
import IssuableBulkUpdateActions from './issuable_bulk_update_actions';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* eslint-disable no-useless-return, func-names, space-before-function-paren, wrap-iife, no-var, no-underscore-dangle, prefer-arrow-callback, max-len, one-var, no-unused-vars, one-var-declaration-per-line, prefer-template, no-new, consistent-return, object-shorthand, comma-dangle, no-shadow, no-param-reassign, brace-style, vars-on-top, quotes, no-lonely-if, no-else-return, dot-notation, no-empty, no-return-assign, camelcase, prefer-spread */
|
||||
/* global Issuable */
|
||||
/* global ListLabel */
|
||||
|
||||
import _ from 'underscore';
|
||||
import IssuableBulkUpdateActions from './issuable_bulk_update_actions';
|
||||
import DropdownUtils from './filtered_search/dropdown_utils';
|
||||
|
||||
|
|
|
@ -86,8 +86,9 @@
|
|||
// This is required to handle non-unicode characters in hash
|
||||
hash = decodeURIComponent(hash);
|
||||
|
||||
var fixedTabs = document.querySelector('.js-tabs-affix');
|
||||
var fixedNav = document.querySelector('.navbar-gitlab');
|
||||
const fixedTabs = document.querySelector('.js-tabs-affix');
|
||||
const fixedDiffStats = document.querySelector('.js-diff-files-changed.is-stuck');
|
||||
const fixedNav = document.querySelector('.navbar-gitlab');
|
||||
|
||||
var adjustment = 0;
|
||||
if (fixedNav) adjustment -= fixedNav.offsetHeight;
|
||||
|
@ -104,6 +105,11 @@
|
|||
if (fixedTabs) {
|
||||
adjustment -= fixedTabs.offsetHeight;
|
||||
}
|
||||
|
||||
if (fixedDiffStats) {
|
||||
adjustment -= fixedDiffStats.offsetHeight;
|
||||
}
|
||||
|
||||
window.scrollBy(0, adjustment);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import _ from 'underscore';
|
||||
|
||||
(() => {
|
||||
/*
|
||||
* TODO: Make these methods more configurable (e.g. parseSeconds timePeriodContstraints,
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
export const isSticky = (el, scrollY, stickyTop) => {
|
||||
const top = el.offsetTop - scrollY;
|
||||
|
||||
if (top === stickyTop) {
|
||||
el.classList.add('is-stuck');
|
||||
} else {
|
||||
el.classList.remove('is-stuck');
|
||||
}
|
||||
};
|
||||
|
||||
export default (el) => {
|
||||
if (!el) return;
|
||||
|
||||
const computedStyle = window.getComputedStyle(el);
|
||||
|
||||
if (!/sticky/.test(computedStyle.position)) return;
|
||||
|
||||
const stickyTop = parseInt(computedStyle.top, 10);
|
||||
|
||||
document.addEventListener('scroll', () => isSticky(el, window.scrollY, stickyTop), {
|
||||
passive: true,
|
||||
});
|
||||
};
|
|
@ -16,9 +16,6 @@ import 'mousetrap';
|
|||
import 'mousetrap/plugins/pause/mousetrap-pause';
|
||||
import 'vendor/fuzzaldrin-plus';
|
||||
|
||||
// extensions
|
||||
import './extensions/array';
|
||||
|
||||
// expose common libraries as globals (TODO: remove these)
|
||||
window.jQuery = jQuery;
|
||||
window.$ = jQuery;
|
||||
|
@ -36,9 +33,6 @@ import './shortcuts_find_file';
|
|||
import './shortcuts_issuable';
|
||||
import './shortcuts_network';
|
||||
|
||||
// behaviors
|
||||
import './behaviors/';
|
||||
|
||||
// templates
|
||||
import './templates/issuable_template_selector';
|
||||
import './templates/issuable_template_selectors';
|
||||
|
@ -56,6 +50,9 @@ import './lib/utils/pretty_time';
|
|||
import './lib/utils/text_utility';
|
||||
import './lib/utils/url_utility';
|
||||
|
||||
// behaviors
|
||||
import './behaviors/';
|
||||
|
||||
// u2f
|
||||
import './u2f/authenticate';
|
||||
import './u2f/error';
|
||||
|
@ -86,7 +83,6 @@ import './copy_as_gfm';
|
|||
import './copy_to_clipboard';
|
||||
import './create_label';
|
||||
import './diff';
|
||||
import './dispatcher';
|
||||
import './dropzone_input';
|
||||
import './due_date_select';
|
||||
import './files_comment_button';
|
||||
|
@ -150,9 +146,13 @@ import './subscription';
|
|||
import './subscription_select';
|
||||
import './syntax_highlight';
|
||||
|
||||
import './dispatcher';
|
||||
|
||||
// eslint-disable-next-line global-require, import/no-commonjs
|
||||
if (process.env.NODE_ENV !== 'production') require('./test_utils/');
|
||||
|
||||
Dropzone.autoDiscover = false;
|
||||
|
||||
document.addEventListener('beforeunload', function () {
|
||||
// Unbind scroll events
|
||||
$(document).off('scroll');
|
||||
|
|
|
@ -7,6 +7,7 @@ import Cookies from 'js-cookie';
|
|||
import './breakpoints';
|
||||
import './flash';
|
||||
import BlobForkSuggestion from './blob/blob_fork_suggestion';
|
||||
import stickyMonitor from './lib/utils/sticky';
|
||||
|
||||
/* eslint-disable max-len */
|
||||
// MergeRequestTabs
|
||||
|
@ -266,6 +267,10 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
|
|||
const $container = $('#diffs');
|
||||
$container.html(data.html);
|
||||
|
||||
this.initChangesDropdown();
|
||||
|
||||
stickyMonitor(document.querySelector('.js-diff-files-changed'));
|
||||
|
||||
if (typeof gl.diffNotesCompileComponents !== 'undefined') {
|
||||
gl.diffNotesCompileComponents();
|
||||
}
|
||||
|
@ -314,6 +319,13 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
|
|||
});
|
||||
}
|
||||
|
||||
initChangesDropdown() {
|
||||
$('.js-diff-stats-dropdown').glDropdown({
|
||||
filterable: true,
|
||||
remoteFilter: false,
|
||||
});
|
||||
}
|
||||
|
||||
// Show or hide the loading spinner
|
||||
//
|
||||
// status - Boolean, true to show, false to hide
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-underscore-dangle, prefer-arrow-callback, max-len, one-var, one-var-declaration-per-line, no-unused-vars, object-shorthand, comma-dangle, no-else-return, no-self-compare, consistent-return, no-param-reassign, no-shadow */
|
||||
/* global Issuable */
|
||||
/* global ListMilestone */
|
||||
import _ from 'underscore';
|
||||
|
||||
(function() {
|
||||
this.MilestoneSelect = (function() {
|
||||
|
|
|
@ -1,23 +1,63 @@
|
|||
import Cookies from 'js-cookie';
|
||||
import _ from 'underscore';
|
||||
/* global bp */
|
||||
import './breakpoints';
|
||||
|
||||
export default class NewNavSidebar {
|
||||
constructor() {
|
||||
this.initDomElements();
|
||||
this.render();
|
||||
}
|
||||
|
||||
initDomElements() {
|
||||
this.$page = $('.page-with-sidebar');
|
||||
this.$sidebar = $('.nav-sidebar');
|
||||
this.$overlay = $('.mobile-overlay');
|
||||
this.$openSidebar = $('.toggle-mobile-nav');
|
||||
this.$closeSidebar = $('.close-nav-button');
|
||||
this.$sidebarToggle = $('.js-toggle-sidebar');
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
this.$openSidebar.on('click', () => this.toggleSidebarNav(true));
|
||||
this.$closeSidebar.on('click', () => this.toggleSidebarNav(false));
|
||||
this.$overlay.on('click', () => this.toggleSidebarNav(false));
|
||||
this.$sidebarToggle.on('click', () => {
|
||||
const value = !this.$sidebar.hasClass('sidebar-icons-only');
|
||||
this.toggleCollapsedSidebar(value);
|
||||
});
|
||||
|
||||
$(window).on('resize', () => _.debounce(this.render(), 100));
|
||||
}
|
||||
|
||||
static setCollapsedCookie(value) {
|
||||
if (bp.getBreakpointSize() !== 'lg') {
|
||||
return;
|
||||
}
|
||||
Cookies.set('sidebar_collapsed', value, { expires: 365 * 10 });
|
||||
}
|
||||
|
||||
toggleSidebarNav(show) {
|
||||
this.$sidebar.toggleClass('nav-sidebar-expanded', show);
|
||||
this.$overlay.toggleClass('mobile-nav-open', show);
|
||||
this.$sidebar.removeClass('sidebar-icons-only');
|
||||
}
|
||||
|
||||
toggleCollapsedSidebar(collapsed) {
|
||||
this.$sidebar.toggleClass('sidebar-icons-only', collapsed);
|
||||
this.$page.toggleClass('page-with-new-sidebar', !collapsed);
|
||||
this.$page.toggleClass('page-with-icon-sidebar', collapsed);
|
||||
NewNavSidebar.setCollapsedCookie(collapsed);
|
||||
}
|
||||
|
||||
render() {
|
||||
const breakpoint = bp.getBreakpointSize();
|
||||
|
||||
if (breakpoint === 'sm' || breakpoint === 'md') {
|
||||
this.toggleCollapsedSidebar(true);
|
||||
} else if (breakpoint === 'lg') {
|
||||
const collapse = Cookies.get('sidebar_collapsed') === 'true';
|
||||
this.toggleCollapsedSidebar(collapse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ newline-per-chained-call, no-useless-escape, class-methods-use-this */
|
|||
/* global mrRefreshWidgetUrl */
|
||||
|
||||
import $ from 'jquery';
|
||||
import _ from 'underscore';
|
||||
import Cookies from 'js-cookie';
|
||||
import autosize from 'vendor/autosize';
|
||||
import Dropzone from 'dropzone';
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import pdfjsLib from 'pdfjs-dist';
|
||||
import workerSrc from 'vendor/pdf.worker';
|
||||
import pdfjsLib from 'vendor/pdf';
|
||||
import workerSrc from 'vendor/pdf.worker.min';
|
||||
|
||||
import page from './page/index.vue';
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<script>
|
||||
import _ from 'underscore';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
initialCronInterval: {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
import loadingIcon from '~/vue_shared/components/loading_icon.vue';
|
||||
import '~/flash';
|
||||
import stageColumnComponent from './stage_column_component.vue';
|
||||
import loadingIcon from '../../../vue_shared/components/loading_icon.vue';
|
||||
import '../../../flash';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* eslint-disable no-useless-escape, max-len, quotes, no-var, no-underscore-dangle, func-names, space-before-function-paren, no-unused-vars, no-return-assign, object-shorthand, one-var, one-var-declaration-per-line, comma-dangle, consistent-return, class-methods-use-this, new-parens */
|
||||
|
||||
import 'cropper';
|
||||
import _ from 'underscore';
|
||||
|
||||
((global) => {
|
||||
// Matches everything but the file name
|
||||
|
|
|
@ -10,14 +10,19 @@ import Cookies from 'js-cookie';
|
|||
const $projectCloneField = $('#project_clone');
|
||||
const $cloneBtnText = $('a.clone-dropdown-btn span');
|
||||
|
||||
const selectedCloneOption = $cloneBtnText.text().trim();
|
||||
if (selectedCloneOption.length > 0) {
|
||||
$(`a:contains('${selectedCloneOption}')`, $cloneOptions).addClass('is-active');
|
||||
}
|
||||
|
||||
$('a', $cloneOptions).on('click', (e) => {
|
||||
const $this = $(e.currentTarget);
|
||||
const url = $this.attr('href');
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
$('.active', $cloneOptions).not($this).removeClass('active');
|
||||
$this.toggleClass('active');
|
||||
$('.is-active', $cloneOptions).not($this).removeClass('is-active');
|
||||
$this.toggleClass('is-active');
|
||||
$projectCloneField.val(url);
|
||||
$cloneBtnText.text($this.text());
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export default function setupProjectEdit() {
|
||||
const $transferForm = $('.js-project-transfer-form');
|
||||
const $selectNamespace = $transferForm.find('.select2');
|
||||
const $selectNamespace = $transferForm.find('select.select2');
|
||||
|
||||
$selectNamespace.on('change', () => {
|
||||
$transferForm.find(':submit').prop('disabled', !$selectNamespace.val());
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import _ from 'underscore';
|
||||
|
||||
export default class ProtectedBranchDropdown {
|
||||
/**
|
||||
* @param {Object} options containing
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import _ from 'underscore';
|
||||
|
||||
export default class ProtectedTagDropdown {
|
||||
/**
|
||||
* @param {Object} options containing
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-unused-vars, consistent-return, one-var, one-var-declaration-per-line, quotes, prefer-template, object-shorthand, comma-dangle, no-else-return, no-param-reassign, max-len */
|
||||
|
||||
import _ from 'underscore';
|
||||
import Cookies from 'js-cookie';
|
||||
import SidebarHeightManager from './sidebar_height_manager';
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
/* global ShortcutsNavigation */
|
||||
/* global sidebar */
|
||||
|
||||
import _ from 'underscore';
|
||||
import 'mousetrap';
|
||||
import './shortcuts_navigation';
|
||||
|
||||
|
@ -58,7 +59,7 @@ import './shortcuts_navigation';
|
|||
});
|
||||
// If replyField already has some content, add a newline before our quote
|
||||
separator = replyField.val().trim() !== "" && "\n\n" || '';
|
||||
replyField.val(function(_, current) {
|
||||
replyField.val(function(a, current) {
|
||||
return current + separator + quote.join('') + "\n";
|
||||
});
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import _ from 'underscore';
|
||||
|
||||
import '~/smart_interval';
|
||||
|
||||
import timeTracker from './time_tracker';
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import _ from 'underscore';
|
||||
|
||||
export default {
|
||||
init() {
|
||||
if (!this.initialized) {
|
||||
|
@ -30,4 +32,3 @@ export default {
|
|||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ export default class Todos {
|
|||
}
|
||||
|
||||
updateRowStateClicked(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
const target = e.target;
|
||||
|
@ -92,6 +93,7 @@ export default class Todos {
|
|||
}
|
||||
|
||||
updateAllStateClicked(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
const target = e.currentTarget;
|
||||
|
@ -142,6 +144,7 @@ export default class Todos {
|
|||
if (gl.utils.isMetaClick(e)) {
|
||||
const windowTarget = '_blank';
|
||||
const selected = e.target;
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
if (selected.tagName === 'IMG') {
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
/* global U2FError */
|
||||
/* global U2FUtil */
|
||||
|
||||
import _ from 'underscore';
|
||||
|
||||
// Authenticate U2F (universal 2nd factor) devices for users to authenticate with.
|
||||
//
|
||||
// State Flow #1: setup -> in_progress -> authenticated -> POST to server
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
/* global U2FError */
|
||||
/* global U2FUtil */
|
||||
|
||||
import _ from 'underscore';
|
||||
|
||||
// Register U2F (universal 2nd factor) devices for users to authenticate with.
|
||||
//
|
||||
// State Flow #1: setup -> in_progress -> registered -> POST to server
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/* eslint-disable comma-dangle, consistent-return, class-methods-use-this, arrow-parens, no-param-reassign, max-len */
|
||||
|
||||
import _ from 'underscore';
|
||||
|
||||
const debounceTimeoutDuration = 1000;
|
||||
const invalidInputClass = 'gl-field-error-outline';
|
||||
const successInputClass = 'gl-field-success-outline';
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import _ from 'underscore';
|
||||
import d3 from 'd3';
|
||||
|
||||
const LOADING_HTML = `
|
||||
|
@ -6,6 +7,14 @@ const LOADING_HTML = `
|
|||
</div>
|
||||
`;
|
||||
|
||||
function getSystemDate(systemUtcOffsetSeconds) {
|
||||
const date = new Date();
|
||||
const localUtcOffsetMinutes = 0 - date.getTimezoneOffset();
|
||||
const systemUtcOffsetMinutes = systemUtcOffsetSeconds / 60;
|
||||
date.setMinutes((date.getMinutes() - localUtcOffsetMinutes) + systemUtcOffsetMinutes);
|
||||
return date;
|
||||
}
|
||||
|
||||
function formatTooltipText({ date, count }) {
|
||||
const dateObject = new Date(date);
|
||||
const dateDayName = gl.utils.getDayName(dateObject);
|
||||
|
@ -21,7 +30,7 @@ function formatTooltipText({ date, count }) {
|
|||
const initColorKey = () => d3.scale.linear().range(['#acd5f2', '#254e77']).domain([0, 3]);
|
||||
|
||||
export default class ActivityCalendar {
|
||||
constructor(container, timestamps, calendarActivitiesPath) {
|
||||
constructor(container, timestamps, calendarActivitiesPath, utcOffset = 0) {
|
||||
this.calendarActivitiesPath = calendarActivitiesPath;
|
||||
this.clickDay = this.clickDay.bind(this);
|
||||
this.currentSelectedDate = '';
|
||||
|
@ -36,7 +45,7 @@ export default class ActivityCalendar {
|
|||
this.timestampsTmp = [];
|
||||
let group = 0;
|
||||
|
||||
const today = new Date();
|
||||
const today = getSystemDate(utcOffset);
|
||||
today.setHours(0, 0, 0, 0, 0);
|
||||
|
||||
const oneYearAgo = new Date(today);
|
||||
|
|
|
@ -150,15 +150,21 @@ export default class UserTabs {
|
|||
const $calendarWrap = this.$parentEl.find('.user-calendar');
|
||||
const calendarPath = $calendarWrap.data('calendarPath');
|
||||
const calendarActivitiesPath = $calendarWrap.data('calendarActivitiesPath');
|
||||
const utcOffset = $calendarWrap.data('utcOffset');
|
||||
let utcFormatted = 'UTC';
|
||||
if (utcOffset !== 0) {
|
||||
utcFormatted = `UTC${utcOffset > 0 ? '+' : ''}${(utcOffset / 3600)}`;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
dataType: 'json',
|
||||
url: calendarPath,
|
||||
success: (activityData) => {
|
||||
$calendarWrap.html(CALENDAR_TEMPLATE);
|
||||
$calendarWrap.find('.calendar-hint').append(`(Timezone: ${utcFormatted})`);
|
||||
|
||||
// eslint-disable-next-line no-new
|
||||
new ActivityCalendar('.js-contrib-calendar', activityData, calendarActivitiesPath);
|
||||
new ActivityCalendar('.js-contrib-calendar', activityData, calendarActivitiesPath, utcOffset);
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* eslint-disable func-names, space-before-function-paren, one-var, no-var, prefer-rest-params, wrap-iife, quotes, max-len, one-var-declaration-per-line, vars-on-top, prefer-arrow-callback, consistent-return, comma-dangle, object-shorthand, no-shadow, no-unused-vars, no-else-return, no-self-compare, prefer-template, no-unused-expressions, no-lonely-if, yoda, prefer-spread, no-void, camelcase, no-param-reassign */
|
||||
/* global Issuable */
|
||||
/* global emitSidebarEvent */
|
||||
import _ from 'underscore';
|
||||
|
||||
// TODO: remove eventHub hack after code splitting refactor
|
||||
window.emitSidebarEvent = window.emitSidebarEvent || $.noop;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetAuthor',
|
||||
props: {
|
||||
|
@ -5,11 +7,14 @@ export default {
|
|||
showAuthorName: { type: Boolean, required: false, default: true },
|
||||
showAuthorTooltip: { type: Boolean, required: false, default: false },
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
template: `
|
||||
<a
|
||||
:href="author.webUrl || author.web_url"
|
||||
class="author-link"
|
||||
:class="{ 'has-tooltip': showAuthorTooltip }"
|
||||
class="author-link inline"
|
||||
:v-tooltip="showAuthorTooltip"
|
||||
:title="author.name">
|
||||
<img
|
||||
:src="author.avatarUrl || author.avatar_url"
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* global Flash */
|
||||
|
||||
import '~/lib/utils/datetime_utility';
|
||||
import { statusIconEntityMap } from '../../vue_shared/ci_status_icons';
|
||||
import MemoryUsage from './mr_widget_memory_usage';
|
||||
import StatusIcon from './mr_widget_status_icon';
|
||||
import MRWidgetService from '../services/mr_widget_service';
|
||||
|
||||
export default {
|
||||
|
@ -13,11 +13,7 @@ export default {
|
|||
},
|
||||
components: {
|
||||
'mr-widget-memory-usage': MemoryUsage,
|
||||
},
|
||||
computed: {
|
||||
svg() {
|
||||
return statusIconEntityMap.icon_status_success;
|
||||
},
|
||||
'status-icon': StatusIcon,
|
||||
},
|
||||
methods: {
|
||||
formatDate(date) {
|
||||
|
@ -51,51 +47,51 @@ export default {
|
|||
},
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-heading">
|
||||
<div class="mr-widget-heading deploy-heading">
|
||||
<div v-for="deployment in mr.deployments">
|
||||
<div class="ci-widget">
|
||||
<div class="ci-widget media">
|
||||
<div class="ci-status-icon ci-status-icon-success">
|
||||
<span class="js-icon-link icon-link">
|
||||
<span class="ci-status-icon"
|
||||
v-html="svg"
|
||||
aria-hidden="true"></span>
|
||||
<status-icon status="success" />
|
||||
</span>
|
||||
</div>
|
||||
<span>
|
||||
<span
|
||||
v-if="hasDeploymentMeta(deployment)">
|
||||
Deployed to
|
||||
</span>
|
||||
<a
|
||||
v-if="hasDeploymentMeta(deployment)"
|
||||
:href="deployment.url"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer nofollow"
|
||||
class="js-deploy-meta">
|
||||
{{deployment.name}}
|
||||
</a>
|
||||
<span
|
||||
v-if="hasExternalUrls(deployment)">
|
||||
on
|
||||
</span>
|
||||
<a
|
||||
v-if="hasExternalUrls(deployment)"
|
||||
:href="deployment.external_url"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer nofollow"
|
||||
class="js-deploy-url">
|
||||
<i
|
||||
class="fa fa-external-link"
|
||||
aria-hidden="true" />
|
||||
{{deployment.external_url_formatted}}
|
||||
</a>
|
||||
<span
|
||||
v-if="hasDeploymentTime(deployment)"
|
||||
:data-title="deployment.deployed_at_formatted"
|
||||
class="js-deploy-time"
|
||||
data-toggle="tooltip"
|
||||
data-placement="top">
|
||||
{{formatDate(deployment.deployed_at)}}
|
||||
<div class="media-body space-children">
|
||||
<span>
|
||||
<span
|
||||
v-if="hasDeploymentMeta(deployment)">
|
||||
Deployed to
|
||||
</span>
|
||||
<a
|
||||
v-if="hasDeploymentMeta(deployment)"
|
||||
:href="deployment.url"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer nofollow"
|
||||
class="js-deploy-meta inline">
|
||||
{{deployment.name}}
|
||||
</a>
|
||||
<span
|
||||
v-if="hasExternalUrls(deployment)">
|
||||
on
|
||||
</span>
|
||||
<a
|
||||
v-if="hasExternalUrls(deployment)"
|
||||
:href="deployment.external_url"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer nofollow"
|
||||
class="js-deploy-url inline">
|
||||
<i
|
||||
class="fa fa-external-link"
|
||||
aria-hidden="true" />
|
||||
{{deployment.external_url_formatted}}
|
||||
</a>
|
||||
<span
|
||||
v-if="hasDeploymentTime(deployment)"
|
||||
:data-title="deployment.deployed_at_formatted"
|
||||
class="js-deploy-time"
|
||||
data-toggle="tooltip"
|
||||
data-placement="top">
|
||||
{{formatDate(deployment.deployed_at)}}
|
||||
</span>
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
|
@ -104,13 +100,13 @@ export default {
|
|||
class="btn btn-default btn-xs">
|
||||
Stop environment
|
||||
</button>
|
||||
</span>
|
||||
<mr-widget-memory-usage
|
||||
v-if="deployment.metrics_url"
|
||||
:metrics-url="deployment.metrics_url"
|
||||
:metrics-monitoring-url="deployment.metrics_monitoring_url"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<mr-widget-memory-usage
|
||||
v-if="deployment.metrics_url"
|
||||
:metrics-url="deployment.metrics_url"
|
||||
:metrics-monitoring-url="deployment.metrics_monitoring_url"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import tooltip from '../../vue_shared/directives/tooltip';
|
||||
import '../../lib/utils/text_utility';
|
||||
|
||||
export default {
|
||||
|
@ -5,6 +6,9 @@ export default {
|
|||
props: {
|
||||
mr: { type: Object, required: true },
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
computed: {
|
||||
shouldShowCommitsBehindText() {
|
||||
return this.mr.divergedCommitsCount > 0;
|
||||
|
@ -29,18 +33,51 @@ export default {
|
|||
},
|
||||
template: `
|
||||
<div class="mr-source-target">
|
||||
<div
|
||||
v-if="mr.isOpen"
|
||||
class="pull-right">
|
||||
<div class="normal">
|
||||
<strong>
|
||||
Request to merge
|
||||
<span
|
||||
class="label-branch"
|
||||
:class="{'label-truncated': isBranchTitleLong(mr.sourceBranch)}"
|
||||
:title="isBranchTitleLong(mr.sourceBranch) ? mr.sourceBranch : ''"
|
||||
data-placement="bottom"
|
||||
:v-tooltip="isBranchTitleLong(mr.sourceBranch)"
|
||||
v-html="mr.sourceBranchLink"></span>
|
||||
<button
|
||||
v-tooltip
|
||||
class="btn btn-transparent btn-clipboard"
|
||||
data-title="Copy branch name to clipboard"
|
||||
:data-clipboard-text="branchNameClipboardData">
|
||||
<i
|
||||
aria-hidden="true"
|
||||
class="fa fa-clipboard"></i>
|
||||
</button>
|
||||
into
|
||||
<span
|
||||
class="label-branch"
|
||||
:v-tooltip="isBranchTitleLong(mr.sourceBranch)"
|
||||
:class="{'label-truncatedtooltip': isBranchTitleLong(mr.targetBranch)}"
|
||||
:title="isBranchTitleLong(mr.targetBranch) ? mr.targetBranch : ''"
|
||||
data-placement="bottom">
|
||||
<a :href="mr.targetBranchTreePath">{{mr.targetBranch}}</a>
|
||||
</span>
|
||||
</strong>
|
||||
<span
|
||||
v-if="shouldShowCommitsBehindText"
|
||||
class="diverged-commits-count">
|
||||
(<a :href="mr.targetBranchPath">{{mr.divergedCommitsCount}} {{commitsText}} behind</a>)
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="mr.isOpen">
|
||||
<a
|
||||
href="#modal_merge_info"
|
||||
data-toggle="modal"
|
||||
class="btn inline btn-grouped btn-sm">
|
||||
class="btn btn-small inline">
|
||||
Check out branch
|
||||
</a>
|
||||
<span class="dropdown inline prepend-left-5">
|
||||
<span class="dropdown inline prepend-left-10">
|
||||
<a
|
||||
class="btn btn-sm dropdown-toggle"
|
||||
class="btn btn-xs dropdown-toggle"
|
||||
data-toggle="dropdown"
|
||||
aria-label="Download as"
|
||||
role="button">
|
||||
|
@ -69,38 +106,6 @@ export default {
|
|||
</ul>
|
||||
</span>
|
||||
</div>
|
||||
<div class="normal">
|
||||
<strong>
|
||||
Request to merge
|
||||
<span
|
||||
class="label-branch"
|
||||
:class="{'label-truncated has-tooltip': isBranchTitleLong(mr.sourceBranch)}"
|
||||
:title="isBranchTitleLong(mr.sourceBranch) ? mr.sourceBranch : ''"
|
||||
data-placement="bottom"
|
||||
v-html="mr.sourceBranchLink"></span>
|
||||
<button
|
||||
class="btn btn-transparent btn-clipboard has-tooltip"
|
||||
data-title="Copy branch name to clipboard"
|
||||
:data-clipboard-text="branchNameClipboardData">
|
||||
<i
|
||||
aria-hidden="true"
|
||||
class="fa fa-clipboard"></i>
|
||||
</button>
|
||||
into
|
||||
<span
|
||||
class="label-branch"
|
||||
:class="{'label-truncated has-tooltip': isBranchTitleLong(mr.targetBranch)}"
|
||||
:title="isBranchTitleLong(mr.targetBranch) ? mr.targetBranch : ''"
|
||||
data-placement="bottom">
|
||||
<a :href="mr.targetBranchTreePath">{{mr.targetBranch}}</a>
|
||||
</span>
|
||||
</strong>
|
||||
<span
|
||||
v-if="shouldShowCommitsBehindText"
|
||||
class="diverged-commits-count">
|
||||
(<a :href="mr.targetBranchPath">{{mr.divergedCommitsCount}} {{commitsText}} behind</a>)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -120,13 +120,12 @@ export default {
|
|||
},
|
||||
template: `
|
||||
<div class="mr-info-list clearfix mr-memory-usage js-mr-memory-usage">
|
||||
<div class="legend"></div>
|
||||
<p
|
||||
v-if="shouldShowLoading"
|
||||
class="usage-info js-usage-info usage-info-loading">
|
||||
<i
|
||||
class="fa fa-spinner fa-spin usage-info-load-spinner"
|
||||
aria-hidden="true" />Loading deployment statistics.
|
||||
aria-hidden="true" />Loading deployment statistics
|
||||
</p>
|
||||
<p
|
||||
v-if="shouldShowMemoryGraph"
|
||||
|
@ -136,12 +135,12 @@ export default {
|
|||
<p
|
||||
v-if="shouldShowLoadFailure"
|
||||
class="usage-info js-usage-info usage-info-failed">
|
||||
Failed to load deployment statistics.
|
||||
Failed to load deployment statistics
|
||||
</p>
|
||||
<p
|
||||
v-if="shouldShowMetricsUnavailable"
|
||||
class="usage-info js-usage-info usage-info-unavailable">
|
||||
Deployment statistics are not available currently.
|
||||
Deployment statistics are not available currently
|
||||
</p>
|
||||
<mr-memory-graph
|
||||
v-if="shouldShowMemoryGraph"
|
||||
|
|
|
@ -16,7 +16,7 @@ export default {
|
|||
<a
|
||||
data-toggle="modal"
|
||||
href="#modal_merge_info">
|
||||
command line.
|
||||
command line
|
||||
</a>
|
||||
</section>
|
||||
`,
|
||||
|
|
|
@ -29,58 +29,55 @@ export default {
|
|||
},
|
||||
template: `
|
||||
<div class="mr-widget-heading">
|
||||
<div class="ci-widget">
|
||||
<div class="ci-widget media">
|
||||
<template v-if="hasCIError">
|
||||
<div class="ci-status-icon ci-status-icon-failed ci-error js-ci-error">
|
||||
<span class="js-icon-link icon-link">
|
||||
<span
|
||||
v-html="svg"
|
||||
aria-hidden="true"></span>
|
||||
</span>
|
||||
<div class="ci-status-icon ci-status-icon-failed ci-error js-ci-error append-right-10">
|
||||
<span
|
||||
v-html="svg"
|
||||
aria-hidden="true"></span>
|
||||
</div>
|
||||
<div class="media-body">
|
||||
Could not connect to the CI server. Please check your settings and try again
|
||||
</div>
|
||||
<span>Could not connect to the CI server. Please check your settings and try again.</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div>
|
||||
<div class="ci-status-icon append-right-10">
|
||||
<a
|
||||
class="icon-link"
|
||||
:href="this.status.details_path">
|
||||
<ci-icon :status="status" />
|
||||
</a>
|
||||
</div>
|
||||
<span>
|
||||
Pipeline
|
||||
<a
|
||||
:href="mr.pipeline.path"
|
||||
class="pipeline-id">#{{mr.pipeline.id}}</a>
|
||||
{{mr.pipeline.details.status.label}}
|
||||
</span>
|
||||
<span
|
||||
v-if="mr.pipeline.details.stages.length > 0">
|
||||
with {{stageText}}
|
||||
</span>
|
||||
<div class="mr-widget-pipeline-graph">
|
||||
<div class="stage-cell">
|
||||
<div
|
||||
v-if="mr.pipeline.details.stages.length > 0"
|
||||
v-for="stage in mr.pipeline.details.stages"
|
||||
class="stage-container dropdown js-mini-pipeline-graph">
|
||||
<pipeline-stage :stage="stage" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="media-body">
|
||||
<span>
|
||||
Pipeline
|
||||
<a
|
||||
:href="mr.pipeline.path"
|
||||
class="pipeline-id">#{{mr.pipeline.id}}</a>
|
||||
</span>
|
||||
<span class="mr-widget-pipeline-graph">
|
||||
<span class="stage-cell">
|
||||
<div
|
||||
v-if="mr.pipeline.details.stages.length > 0"
|
||||
v-for="stage in mr.pipeline.details.stages"
|
||||
class="stage-container dropdown js-mini-pipeline-graph">
|
||||
<pipeline-stage :stage="stage" />
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
<span>
|
||||
{{mr.pipeline.details.status.label}} for
|
||||
<a
|
||||
:href="mr.pipeline.commit.commit_path"
|
||||
class="commit-sha js-commit-link">
|
||||
{{mr.pipeline.commit.short_id}}</a>.
|
||||
</span>
|
||||
<span
|
||||
v-if="mr.pipeline.coverage"
|
||||
class="js-mr-coverage">
|
||||
Coverage {{mr.pipeline.coverage}}%
|
||||
</span>
|
||||
</div>
|
||||
<span>
|
||||
for
|
||||
<a
|
||||
:href="mr.pipeline.commit.commit_path"
|
||||
class="commit-sha js-commit-link">
|
||||
{{mr.pipeline.commit.short_id}}</a>.
|
||||
</span>
|
||||
<span
|
||||
v-if="mr.pipeline.coverage"
|
||||
class="js-mr-coverage">
|
||||
Coverage {{mr.pipeline.coverage}}%.
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,37 +2,32 @@ export default {
|
|||
name: 'MRWidgetRelatedLinks',
|
||||
props: {
|
||||
relatedLinks: { type: Object, required: true },
|
||||
state: { type: String, required: false },
|
||||
},
|
||||
computed: {
|
||||
hasLinks() {
|
||||
const { closing, mentioned, assignToMe } = this.relatedLinks;
|
||||
return closing || mentioned || assignToMe;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
hasMultipleIssues(text) {
|
||||
return !text ? false : text.match(/<\/a> and <a/);
|
||||
},
|
||||
issueLabel(field) {
|
||||
return this.hasMultipleIssues(this.relatedLinks[field]) ? 'issues' : 'issue';
|
||||
},
|
||||
verbLabel(field) {
|
||||
return this.hasMultipleIssues(this.relatedLinks[field]) ? 'are' : 'is';
|
||||
closesText() {
|
||||
if (this.state === 'merged') {
|
||||
return 'Closed';
|
||||
}
|
||||
if (this.state === 'closed') {
|
||||
return 'Did not close';
|
||||
}
|
||||
return 'Closes';
|
||||
},
|
||||
},
|
||||
template: `
|
||||
<section
|
||||
v-if="hasLinks"
|
||||
class="mr-info-list mr-links">
|
||||
<div class="legend"></div>
|
||||
<p v-if="relatedLinks.closing">
|
||||
Closes {{issueLabel('closing')}}
|
||||
<span v-html="relatedLinks.closing"></span>.
|
||||
{{closesText}} <span v-html="relatedLinks.closing"></span>
|
||||
</p>
|
||||
<p v-if="relatedLinks.mentioned">
|
||||
<span class="capitalize">{{issueLabel('mentioned')}}</span>
|
||||
<span v-html="relatedLinks.mentioned"></span>
|
||||
{{verbLabel('mentioned')}} mentioned but will not be closed.
|
||||
Mentions <span v-html="relatedLinks.mentioned"></span>
|
||||
</p>
|
||||
<p v-if="relatedLinks.assignToMe">
|
||||
<span v-html="relatedLinks.assignToMe"></span>
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
import ciIcon from '../../vue_shared/components/ci_icon.vue';
|
||||
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
status: { type: String, required: true },
|
||||
showDisabledButton: { type: Boolean, required: false },
|
||||
},
|
||||
components: {
|
||||
ciIcon,
|
||||
loadingIcon,
|
||||
},
|
||||
computed: {
|
||||
statusObj() {
|
||||
return {
|
||||
group: this.status,
|
||||
icon: `icon_status_${this.status}`,
|
||||
};
|
||||
},
|
||||
},
|
||||
template: `
|
||||
<div class="space-children flex-container-block append-right-10">
|
||||
<div v-if="status === 'loading'" class="mr-widget-icon">
|
||||
<loading-icon />
|
||||
</div>
|
||||
<ci-icon v-else :status="statusObj" />
|
||||
<button
|
||||
v-if="showDisabledButton"
|
||||
type="button"
|
||||
class="btn btn-success btn-small"
|
||||
disabled="true">
|
||||
Merge
|
||||
</button>
|
||||
</div>
|
||||
`,
|
||||
};
|
|
@ -1,16 +1,26 @@
|
|||
import statusIcon from '../mr_widget_status_icon';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetArchived',
|
||||
components: {
|
||||
statusIcon,
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-success btn-small"
|
||||
disabled="true">
|
||||
Merge
|
||||
</button>
|
||||
<span class="bold">
|
||||
This project is archived, write access has been disabled.
|
||||
</span>
|
||||
<div class="mr-widget-body media">
|
||||
<div class="space-children">
|
||||
<status-icon status="failed" />
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-success btn-small"
|
||||
disabled="true">
|
||||
Merge
|
||||
</button>
|
||||
</div>
|
||||
<div class="media-body">
|
||||
<span class="bold">
|
||||
This project is archived, write access has been disabled
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import eventHub from '../../event_hub';
|
||||
import statusIcon from '../mr_widget_status_icon';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetAutoMergeFailed',
|
||||
|
@ -10,6 +11,9 @@ export default {
|
|||
isRefreshing: false,
|
||||
};
|
||||
},
|
||||
components: {
|
||||
statusIcon,
|
||||
},
|
||||
methods: {
|
||||
refreshWidget() {
|
||||
this.isRefreshing = true;
|
||||
|
@ -19,18 +23,16 @@ export default {
|
|||
},
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<button
|
||||
class="btn btn-success btn-small"
|
||||
disabled="true"
|
||||
type="button">
|
||||
Merge
|
||||
</button>
|
||||
<span class="bold danger">
|
||||
This merge request failed to be merged automatically.
|
||||
<div class="mr-widget-body media">
|
||||
<status-icon status="failed" />
|
||||
<div class="media-body space-children">
|
||||
<span class="bold">
|
||||
<template v-if="mr.mergeError">{{mr.mergeError}}.</template>
|
||||
This merge request failed to be merged automatically
|
||||
</span>
|
||||
<button
|
||||
@click="refreshWidget"
|
||||
:class="{ disabled: isRefreshing }"
|
||||
:disabled="isRefreshing"
|
||||
type="button"
|
||||
class="btn btn-xs btn-default">
|
||||
<i
|
||||
|
@ -39,9 +41,6 @@ export default {
|
|||
aria-hidden="true" />
|
||||
Refresh
|
||||
</button>
|
||||
</span>
|
||||
<div class="merge-error-text danger bold">
|
||||
{{mr.mergeError}}
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
import statusIcon from '../mr_widget_status_icon';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetChecking',
|
||||
components: {
|
||||
statusIcon,
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-success btn-small"
|
||||
disabled="true">
|
||||
Merge
|
||||
</button>
|
||||
<span class="bold">
|
||||
Checking ability to merge automatically.
|
||||
<i
|
||||
class="fa fa-spinner fa-spin"
|
||||
aria-hidden="true" />
|
||||
</span>
|
||||
<div class="mr-widget-body media">
|
||||
<status-icon status="loading" showDisabledButton />
|
||||
<div class="media-body space-children">
|
||||
<span class="bold">
|
||||
Checking ability to merge automatically
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import mrWidgetAuthorTime from '../../components/mr_widget_author_time';
|
||||
import statusIcon from '../mr_widget_status_icon';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetClosed',
|
||||
|
@ -7,24 +8,28 @@ export default {
|
|||
},
|
||||
components: {
|
||||
'mr-widget-author-and-time': mrWidgetAuthorTime,
|
||||
statusIcon,
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<mr-widget-author-and-time
|
||||
actionText="Closed by"
|
||||
:author="mr.closedBy"
|
||||
:dateTitle="mr.updatedAt"
|
||||
:dateReadable="mr.closedAt"
|
||||
/>
|
||||
<section>
|
||||
<p>
|
||||
The changes were not merged into
|
||||
<a
|
||||
:href="mr.targetBranchPath"
|
||||
class="label-branch">
|
||||
{{mr.targetBranch}}</a>.
|
||||
</p>
|
||||
</section>
|
||||
<div class="mr-widget-body media">
|
||||
<status-icon status="failed" />
|
||||
<div class="media-body">
|
||||
<mr-widget-author-and-time
|
||||
actionText="Closed by"
|
||||
:author="mr.closedBy"
|
||||
:dateTitle="mr.updatedAt"
|
||||
:dateReadable="mr.closedAt"
|
||||
/>
|
||||
<section class="mr-info-list">
|
||||
<p>
|
||||
The changes were not merged into
|
||||
<a
|
||||
:href="mr.targetBranchPath"
|
||||
class="label-branch">
|
||||
{{mr.targetBranch}}</a>
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -1,27 +1,25 @@
|
|||
import statusIcon from '../mr_widget_status_icon';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetConflicts',
|
||||
props: {
|
||||
mr: { type: Object, required: true },
|
||||
},
|
||||
components: {
|
||||
statusIcon,
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-success btn-small"
|
||||
disabled="true">
|
||||
Merge
|
||||
</button>
|
||||
<span class="bold">
|
||||
There are merge conflicts.
|
||||
<span v-if="!mr.canMerge">
|
||||
Resolve these conflicts or ask someone with write access to this repository to merge it locally.
|
||||
<div class="mr-widget-body media">
|
||||
<status-icon status="failed" showDisabledButton />
|
||||
<div class="media-body space-children">
|
||||
<span class="bold">
|
||||
There are merge conflicts<span v-if="!mr.canMerge">.</span>
|
||||
<span v-if="!mr.canMerge">
|
||||
Resolve these conflicts or ask someone with write access to this repository to merge it locally
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
<div
|
||||
v-if="mr.canMerge"
|
||||
class="btn-group">
|
||||
<a
|
||||
v-if="mr.conflictResolutionPath"
|
||||
v-if="mr.canMerge && mr.conflictResolutionPath"
|
||||
:href="mr.conflictResolutionPath"
|
||||
class="btn btn-default btn-xs js-resolve-conflicts-button">
|
||||
Resolve conflicts
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import statusIcon from '../mr_widget_status_icon';
|
||||
import eventHub from '../../event_hub';
|
||||
|
||||
export default {
|
||||
|
@ -38,39 +39,40 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
components: {
|
||||
statusIcon,
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<button
|
||||
class="btn btn-success btn-small"
|
||||
disabled="true"
|
||||
type="button">
|
||||
Merge
|
||||
</button>
|
||||
<span
|
||||
v-if="!isRefreshing"
|
||||
class="bold danger">
|
||||
<span
|
||||
class="has-error-message"
|
||||
v-if="mr.mergeError">
|
||||
{{mr.mergeError}}
|
||||
<div class="mr-widget-body media">
|
||||
<template v-if="isRefreshing">
|
||||
<status-icon status="loading" />
|
||||
<span class="media-body bold js-refresh-label">
|
||||
Refreshing now
|
||||
</span>
|
||||
<span v-else>Merge failed.</span>
|
||||
<span
|
||||
:class="{ 'has-custom-error': mr.mergeError }">
|
||||
Refreshing in {{timerText}} to show the updated status...
|
||||
</span>
|
||||
<button
|
||||
@click="refresh"
|
||||
class="btn btn-default btn-xs js-refresh-button"
|
||||
type="button">
|
||||
Refresh now
|
||||
</button>
|
||||
</span>
|
||||
<span
|
||||
v-if="isRefreshing"
|
||||
class="bold js-refresh-label">
|
||||
Refreshing now...
|
||||
</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<status-icon status="failed" showDisabledButton />
|
||||
<div class="media-body space-children">
|
||||
<span class="bold">
|
||||
<span
|
||||
class="has-error-message"
|
||||
v-if="mr.mergeError">
|
||||
{{mr.mergeError}}.
|
||||
</span>
|
||||
<span v-else>Merge failed.</span>
|
||||
<span
|
||||
:class="{ 'has-custom-error': mr.mergeError }">
|
||||
Refreshing in {{timerText}} to show the updated status...
|
||||
</span>
|
||||
</span>
|
||||
<button
|
||||
@click="refresh"
|
||||
class="btn btn-default btn-xs js-refresh-button"
|
||||
type="button">
|
||||
Refresh now
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -1,24 +1,29 @@
|
|||
import statusIcon from '../mr_widget_status_icon';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetLocked',
|
||||
props: {
|
||||
mr: { type: Object, required: true },
|
||||
},
|
||||
components: {
|
||||
statusIcon,
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body mr-state-locked">
|
||||
<span class="state-label">Locked</span>
|
||||
This merge request is in the process of being merged, during which time it is locked and cannot be closed.
|
||||
<i
|
||||
class="fa fa-spinner fa-spin"
|
||||
aria-hidden="true" />
|
||||
<section class="mr-info-list mr-links">
|
||||
<div class="legend"></div>
|
||||
<p>
|
||||
The changes will be merged into
|
||||
<span class="label-branch">
|
||||
<a :href="mr.targetBranchPath">{{mr.targetBranch}}</a>
|
||||
</span>.
|
||||
</p>
|
||||
</section>
|
||||
<div class="mr-widget-body mr-state-locked media">
|
||||
<status-icon status="loading" />
|
||||
<div class="media-body">
|
||||
<h4>
|
||||
This merge request is in the process of being merged, during which time it is locked and cannot be closed
|
||||
</h4>
|
||||
<section class="mr-info-list">
|
||||
<p>
|
||||
The changes will be merged into
|
||||
<span class="label-branch">
|
||||
<a :href="mr.targetBranchPath">{{mr.targetBranch}}</a>
|
||||
</span>
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* global Flash */
|
||||
|
||||
import statusIcon from '../mr_widget_status_icon';
|
||||
import MRWidgetAuthor from '../../components/mr_widget_author';
|
||||
import eventHub from '../../event_hub';
|
||||
|
||||
|
@ -11,6 +11,7 @@ export default {
|
|||
},
|
||||
components: {
|
||||
'mr-widget-author': MRWidgetAuthor,
|
||||
statusIcon,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -61,56 +62,56 @@ export default {
|
|||
},
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<h4>
|
||||
Set by
|
||||
<mr-widget-author :author="mr.setToMWPSBy" />
|
||||
to be merged automatically when the pipeline succeeds.
|
||||
<a
|
||||
v-if="mr.canCancelAutomaticMerge"
|
||||
@click.prevent="cancelAutomaticMerge"
|
||||
:disabled="isCancellingAutoMerge"
|
||||
role="button"
|
||||
href="#"
|
||||
class="btn btn-xs btn-default js-cancel-auto-merge">
|
||||
<i
|
||||
v-if="isCancellingAutoMerge"
|
||||
class="fa fa-spinner fa-spin"
|
||||
aria-hidden="true" />
|
||||
Cancel automatic merge
|
||||
</a>
|
||||
</h4>
|
||||
<section class="mr-info-list">
|
||||
<div class="legend"></div>
|
||||
<p>The changes will be merged into
|
||||
<div class="mr-widget-body media">
|
||||
<status-icon status="success" />
|
||||
<div class="media-body">
|
||||
<h4>
|
||||
Set by
|
||||
<mr-widget-author :author="mr.setToMWPSBy" />
|
||||
to be merged automatically when the pipeline succeeds
|
||||
<a
|
||||
:href="mr.targetBranchPath"
|
||||
class="label-branch">
|
||||
{{mr.targetBranch}}
|
||||
</a>.
|
||||
</p>
|
||||
<p v-if="mr.shouldRemoveSourceBranch">
|
||||
The source branch will be removed.
|
||||
</p>
|
||||
<p
|
||||
v-else
|
||||
class="with-button">
|
||||
The source branch will not be removed.
|
||||
<a
|
||||
v-if="canRemoveSourceBranch"
|
||||
:disabled="isRemovingSourceBranch"
|
||||
@click.prevent="removeSourceBranch"
|
||||
v-if="mr.canCancelAutomaticMerge"
|
||||
@click.prevent="cancelAutomaticMerge"
|
||||
:disabled="isCancellingAutoMerge"
|
||||
role="button"
|
||||
class="btn btn-xs btn-default js-remove-source-branch"
|
||||
href="#">
|
||||
href="#"
|
||||
class="btn btn-xs btn-default js-cancel-auto-merge">
|
||||
<i
|
||||
v-if="isRemovingSourceBranch"
|
||||
class="fa fa-spinner fa-spin"
|
||||
aria-hidden="true" />
|
||||
Remove source branch
|
||||
v-if="isCancellingAutoMerge"
|
||||
class="fa fa-spinner fa-spin"
|
||||
aria-hidden="true" />
|
||||
Cancel automatic merge
|
||||
</a>
|
||||
</p>
|
||||
</section>
|
||||
</h4>
|
||||
<section class="mr-info-list">
|
||||
<p>The changes will be merged into
|
||||
<a
|
||||
:href="mr.targetBranchPath"
|
||||
class="label-branch">
|
||||
{{mr.targetBranch}}
|
||||
</a>
|
||||
</p>
|
||||
<p v-if="mr.shouldRemoveSourceBranch">
|
||||
The source branch will be removed
|
||||
</p>
|
||||
<p v-else>
|
||||
The source branch will not be removed
|
||||
<a
|
||||
v-if="canRemoveSourceBranch"
|
||||
:disabled="isRemovingSourceBranch"
|
||||
@click.prevent="removeSourceBranch"
|
||||
role="button"
|
||||
class="btn btn-xs btn-default js-remove-source-branch"
|
||||
href="#">
|
||||
<i
|
||||
v-if="isRemovingSourceBranch"
|
||||
class="fa fa-spinner fa-spin"
|
||||
aria-hidden="true" />
|
||||
Remove source branch
|
||||
</a>
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
/* global Flash */
|
||||
|
||||
import mrWidgetAuthorTime from '../../components/mr_widget_author_time';
|
||||
import tooltip from '../../../vue_shared/directives/tooltip';
|
||||
import loadingIcon from '../../../vue_shared/components/loading_icon.vue';
|
||||
import statusIcon from '../mr_widget_status_icon';
|
||||
import eventHub from '../../event_hub';
|
||||
|
||||
export default {
|
||||
|
@ -9,14 +12,19 @@ export default {
|
|||
mr: { type: Object, required: true },
|
||||
service: { type: Object, required: true },
|
||||
},
|
||||
components: {
|
||||
'mr-widget-author-and-time': mrWidgetAuthorTime,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isMakingRequest: false,
|
||||
};
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
components: {
|
||||
'mr-widget-author-and-time': mrWidgetAuthorTime,
|
||||
loadingIcon,
|
||||
statusIcon,
|
||||
},
|
||||
computed: {
|
||||
shouldShowRemoveSourceBranch() {
|
||||
const { sourceBranchRemoved, isRemovingSourceBranch, canRemoveSourceBranch } = this.mr;
|
||||
|
@ -55,75 +63,77 @@ export default {
|
|||
},
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<mr-widget-author-and-time
|
||||
actionText="Merged by"
|
||||
:author="mr.mergedBy"
|
||||
:dateTitle="mr.updatedAt"
|
||||
:dateReadable="mr.mergedAt" />
|
||||
<section class="mr-info-list">
|
||||
<div class="legend"></div>
|
||||
<p>
|
||||
The changes were merged into
|
||||
<span class="label-branch">
|
||||
<a :href="mr.targetBranchPath">{{mr.targetBranch}}</a>
|
||||
</span>
|
||||
</p>
|
||||
<p v-if="mr.sourceBranchRemoved">The source branch has been removed.</p>
|
||||
<p v-if="shouldShowRemoveSourceBranch">
|
||||
You can remove source branch now.
|
||||
<button
|
||||
@click="removeSourceBranch"
|
||||
:class="{ disabled: isMakingRequest }"
|
||||
type="button"
|
||||
class="btn btn-xs btn-default js-remove-branch-button">
|
||||
Remove Source Branch
|
||||
</button>
|
||||
</p>
|
||||
<p v-if="shouldShowSourceBranchRemoving">
|
||||
<i
|
||||
class="fa fa-spinner fa-spin"
|
||||
aria-hidden="true" />
|
||||
The source branch is being removed.
|
||||
</p>
|
||||
</section>
|
||||
<div
|
||||
v-if="shouldShowMergedButtons"
|
||||
class="merged-buttons clearfix">
|
||||
<a
|
||||
v-if="mr.canRevertInCurrentMR"
|
||||
class="btn btn-close btn-sm has-tooltip"
|
||||
href="#modal-revert-commit"
|
||||
data-toggle="modal"
|
||||
data-container="body"
|
||||
title="Revert this merge request in a new merge request">
|
||||
Revert
|
||||
</a>
|
||||
<a
|
||||
v-else-if="mr.revertInForkPath"
|
||||
class="btn btn-close btn-sm has-tooltip"
|
||||
data-method="post"
|
||||
:href="mr.revertInForkPath"
|
||||
title="Revert this merge request in a new merge request">
|
||||
Revert
|
||||
</a>
|
||||
<a
|
||||
v-if="mr.canCherryPickInCurrentMR"
|
||||
class="btn btn-default btn-sm has-tooltip"
|
||||
href="#modal-cherry-pick-commit"
|
||||
data-toggle="modal"
|
||||
data-container="body"
|
||||
title="Cherry-pick this merge request in a new merge request">
|
||||
Cherry-pick
|
||||
</a>
|
||||
<a
|
||||
v-else-if="mr.cherryPickInForkPath"
|
||||
class="btn btn-default btn-sm has-tooltip"
|
||||
data-method="post"
|
||||
:href="mr.cherryPickInForkPath"
|
||||
title="Cherry-pick this merge request in a new merge request">
|
||||
Cherry-pick
|
||||
</a>
|
||||
<div class="mr-widget-body media">
|
||||
<status-icon status="success" />
|
||||
<div class="media-body">
|
||||
<div class="space-children">
|
||||
<mr-widget-author-and-time
|
||||
actionText="Merged by"
|
||||
:author="mr.mergedBy"
|
||||
:dateTitle="mr.updatedAt"
|
||||
:dateReadable="mr.mergedAt" />
|
||||
<a
|
||||
v-if="mr.canRevertInCurrentMR"
|
||||
v-tooltip
|
||||
class="btn btn-close btn-xs"
|
||||
href="#modal-revert-commit"
|
||||
data-toggle="modal"
|
||||
data-container="body"
|
||||
title="Revert this merge request in a new merge request">
|
||||
Revert
|
||||
</a>
|
||||
<a
|
||||
v-else-if="mr.revertInForkPath"
|
||||
v-tooltip
|
||||
class="btn btn-close btn-xs"
|
||||
data-method="post"
|
||||
:href="mr.revertInForkPath"
|
||||
title="Revert this merge request in a new merge request">
|
||||
Revert
|
||||
</a>
|
||||
<a
|
||||
v-if="mr.canCherryPickInCurrentMR"
|
||||
v-tooltip
|
||||
class="btn btn-default btn-xs"
|
||||
href="#modal-cherry-pick-commit"
|
||||
data-toggle="modal"
|
||||
data-container="body"
|
||||
title="Cherry-pick this merge request in a new merge request">
|
||||
Cherry-pick
|
||||
</a>
|
||||
<a
|
||||
v-else-if="mr.cherryPickInForkPath"
|
||||
v-tooltip
|
||||
class="btn btn-default btn-xs"
|
||||
data-method="post"
|
||||
:href="mr.cherryPickInForkPath"
|
||||
title="Cherry-pick this merge request in a new merge request">
|
||||
Cherry-pick
|
||||
</a>
|
||||
</div>
|
||||
<section class="mr-info-list">
|
||||
<p>
|
||||
The changes were merged into
|
||||
<span class="label-branch">
|
||||
<a :href="mr.targetBranchPath">{{mr.targetBranch}}</a>
|
||||
</span>
|
||||
</p>
|
||||
<p v-if="mr.sourceBranchRemoved">The source branch has been removed</p>
|
||||
<p v-if="shouldShowRemoveSourceBranch" class="space-children">
|
||||
<span>You can remove source branch now</span>
|
||||
<button
|
||||
@click="removeSourceBranch"
|
||||
:disabled="isMakingRequest"
|
||||
type="button"
|
||||
class="btn btn-xs btn-default js-remove-branch-button">
|
||||
Remove Source Branch
|
||||
</button>
|
||||
</p>
|
||||
<p v-if="shouldShowSourceBranchRemoving">
|
||||
<loading-icon inline />
|
||||
<span>The source branch is being removed</span>
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import statusIcon from '../mr_widget_status_icon';
|
||||
import tooltip from '../../../vue_shared/directives/tooltip';
|
||||
import mrWidgetMergeHelp from '../../components/mr_widget_merge_help';
|
||||
|
||||
export default {
|
||||
|
@ -5,30 +7,37 @@ export default {
|
|||
props: {
|
||||
mr: { type: Object, required: true },
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
components: {
|
||||
'mr-widget-merge-help': mrWidgetMergeHelp,
|
||||
statusIcon,
|
||||
},
|
||||
computed: {
|
||||
missingBranchName() {
|
||||
return this.mr.sourceBranchRemoved ? 'source' : 'target';
|
||||
},
|
||||
message() {
|
||||
return `If the ${this.missingBranchName} branch exists in your local repository, you can merge this merge request manually using the command line`;
|
||||
},
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-success btn-small"
|
||||
disabled="true">
|
||||
Merge
|
||||
</button>
|
||||
<span class="bold js-branch-text">
|
||||
<span class="capitalize">
|
||||
{{missingBranchName}}
|
||||
</span> branch does not exist.
|
||||
Please restore the {{missingBranchName}} branch or use a different {{missingBranchName}} branch.
|
||||
</span>
|
||||
<mr-widget-merge-help
|
||||
:missing-branch="missingBranchName" />
|
||||
<div class="mr-widget-body media">
|
||||
<status-icon status="failed" showDisabledButton />
|
||||
<div class="media-body space-children">
|
||||
<span class="bold js-branch-text">
|
||||
<span class="capitalize">
|
||||
{{missingBranchName}}
|
||||
</span> branch does not exist.
|
||||
Please restore it or use a different {{missingBranchName}} branch
|
||||
<i
|
||||
v-tooltip
|
||||
class="fa fa-question-circle"
|
||||
:title="message"
|
||||
:aria-label="message"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
import statusIcon from '../mr_widget_status_icon';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetNotAllowed',
|
||||
components: {
|
||||
statusIcon,
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-success btn-small"
|
||||
disabled="true">
|
||||
Merge
|
||||
</button>
|
||||
<span class="bold">
|
||||
Ready to be merged automatically.
|
||||
Ask someone with write access to this repository to merge this request.
|
||||
</span>
|
||||
<div class="mr-widget-body media">
|
||||
<status-icon status="success" showDisabledButton />
|
||||
<div class="media-body space-children">
|
||||
<span class="bold">
|
||||
Ready to be merged automatically.
|
||||
Ask someone with write access to this repository to merge this request
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ export default {
|
|||
return { emptyStateSVG };
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body empty-state">
|
||||
<div class="mr-widget-body mr-widget-empty-state">
|
||||
<div class="row">
|
||||
<div class="artwork col-sm-5 col-sm-push-7 col-xs-12 text-center">
|
||||
<span v-html="emptyStateSVG"></span>
|
||||
|
@ -29,12 +29,14 @@ export default {
|
|||
Currently there are no changes in this merge request's source branch.
|
||||
Please push new commits or use a different branch.
|
||||
</p>
|
||||
<a
|
||||
v-if="mr.newBlobPath"
|
||||
:href="mr.newBlobPath"
|
||||
class="btn btn-inverted btn-save">
|
||||
Create file
|
||||
</a>
|
||||
<div>
|
||||
<a
|
||||
v-if="mr.newBlobPath"
|
||||
:href="mr.newBlobPath"
|
||||
class="btn btn-inverted btn-save">
|
||||
Create file
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import statusIcon from '../mr_widget_status_icon';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetPipelineBlocked',
|
||||
components: {
|
||||
statusIcon,
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-success btn-small"
|
||||
disabled="true">
|
||||
Merge
|
||||
</button>
|
||||
<span class="bold">
|
||||
Pipeline blocked. The pipeline for this merge request requires a manual action to proceed.
|
||||
</span>
|
||||
<div class="mr-widget-body media">
|
||||
<status-icon status="failed" showDisabledButton />
|
||||
<div class="media-body space-children">
|
||||
<span class="bold">
|
||||
Pipeline blocked. The pipeline for this merge request requires a manual action to proceed
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import statusIcon from '../mr_widget_status_icon';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetPipelineBlocked',
|
||||
components: {
|
||||
statusIcon,
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<button
|
||||
class="btn btn-success btn-small"
|
||||
disabled="true"
|
||||
type="button">
|
||||
Merge
|
||||
</button>
|
||||
<span class="bold">
|
||||
The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure.
|
||||
</span>
|
||||
<div class="mr-widget-body media">
|
||||
<status-icon status="failed" showDisabledButton />
|
||||
<div class="media-body space-children">
|
||||
<span class="bold">
|
||||
The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* global Flash */
|
||||
|
||||
import successSvg from 'icons/_icon_status_success.svg';
|
||||
import warningSvg from 'icons/_icon_status_warning.svg';
|
||||
import simplePoll from '~/lib/utils/simple_poll';
|
||||
import statusIcon from '../mr_widget_status_icon';
|
||||
import eventHub from '../../event_hub';
|
||||
|
||||
export default {
|
||||
|
@ -25,6 +25,9 @@ export default {
|
|||
warningSvg,
|
||||
};
|
||||
},
|
||||
components: {
|
||||
statusIcon,
|
||||
},
|
||||
computed: {
|
||||
commitMessageLinkTitle() {
|
||||
const withDesc = 'Include description in commit message';
|
||||
|
@ -196,84 +199,98 @@ export default {
|
|||
},
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<span class="btn-group">
|
||||
<button
|
||||
@click="handleMergeButtonClick()"
|
||||
:disabled="isMergeButtonDisabled"
|
||||
:class="mergeButtonClass"
|
||||
type="button">
|
||||
<i
|
||||
v-if="isMakingRequest"
|
||||
class="fa fa-spinner fa-spin"
|
||||
aria-hidden="true" />
|
||||
{{mergeButtonText}}
|
||||
</button>
|
||||
<button
|
||||
v-if="shouldShowMergeOptionsDropdown"
|
||||
:disabled="isMergeButtonDisabled"
|
||||
type="button"
|
||||
class="btn btn-small btn-info dropdown-toggle"
|
||||
data-toggle="dropdown">
|
||||
<i
|
||||
class="fa fa-caret-down"
|
||||
aria-hidden="true" />
|
||||
<span class="sr-only">
|
||||
Select merge moment
|
||||
<div class="mr-widget-body media">
|
||||
<status-icon status="success" />
|
||||
<div class="media-body">
|
||||
<div class="media space-children">
|
||||
<span class="btn-group">
|
||||
<button
|
||||
@click="handleMergeButtonClick()"
|
||||
:disabled="isMergeButtonDisabled"
|
||||
:class="mergeButtonClass"
|
||||
type="button">
|
||||
<i
|
||||
v-if="isMakingRequest"
|
||||
class="fa fa-spinner fa-spin"
|
||||
aria-hidden="true" />
|
||||
{{mergeButtonText}}
|
||||
</button>
|
||||
<button
|
||||
v-if="shouldShowMergeOptionsDropdown"
|
||||
:disabled="isMergeButtonDisabled"
|
||||
type="button"
|
||||
class="btn btn-small btn-info dropdown-toggle js-merge-moment"
|
||||
data-toggle="dropdown"
|
||||
aria-label="Select merge moment">
|
||||
<i
|
||||
class="fa fa-chevron-down"
|
||||
aria-hidden="true" />
|
||||
</button>
|
||||
<ul
|
||||
v-if="shouldShowMergeOptionsDropdown"
|
||||
class="dropdown-menu dropdown-menu-right"
|
||||
role="menu">
|
||||
<li>
|
||||
<a
|
||||
@click.prevent="handleMergeButtonClick(true)"
|
||||
class="merge_when_pipeline_succeeds"
|
||||
href="#">
|
||||
<span class="media">
|
||||
<span
|
||||
v-html="successSvg"
|
||||
class="merge-opt-icon"
|
||||
aria-hidden="true"></span>
|
||||
<span class="media-body merge-opt-title">Merge when pipeline succeeds</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
@click.prevent="handleMergeButtonClick(false, true)"
|
||||
class="accept-merge-request"
|
||||
href="#">
|
||||
<span class="media">
|
||||
<span
|
||||
v-html="warningSvg"
|
||||
class="merge-opt-icon"
|
||||
aria-hidden="true"></span>
|
||||
<span class="media-body merge-opt-title">Merge immediately</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
</button>
|
||||
<ul
|
||||
v-if="shouldShowMergeOptionsDropdown"
|
||||
class="dropdown-menu dropdown-menu-right"
|
||||
role="menu">
|
||||
<li>
|
||||
<a
|
||||
@click.prevent="handleMergeButtonClick(true)"
|
||||
class="merge_when_pipeline_succeeds"
|
||||
href="#">
|
||||
<span
|
||||
v-html="successSvg"
|
||||
class="merge-opt-icon"
|
||||
aria-hidden="true"></span>
|
||||
<span class="merge-opt-title">Merge when pipeline succeeds</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
@click.prevent="handleMergeButtonClick(false, true)"
|
||||
class="accept-merge-request"
|
||||
href="#">
|
||||
<span
|
||||
v-html="warningSvg"
|
||||
class="merge-opt-icon"
|
||||
aria-hidden="true"></span>
|
||||
<span class="merge-opt-title">Merge immediately</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
<template v-if="isMergeAllowed()">
|
||||
<label class="spacing">
|
||||
<input
|
||||
id="remove-source-branch-input"
|
||||
v-model="removeSourceBranch"
|
||||
:disabled="isRemoveSourceBranchButtonDisabled"
|
||||
type="checkbox"/> Remove source branch
|
||||
</label>
|
||||
<div class="media-body space-children">
|
||||
<template v-if="isMergeAllowed()">
|
||||
<label>
|
||||
<input
|
||||
id="remove-source-branch-input"
|
||||
v-model="removeSourceBranch"
|
||||
:disabled="isRemoveSourceBranchButtonDisabled"
|
||||
type="checkbox"/> Remove source branch
|
||||
</label>
|
||||
|
||||
<!-- Placeholder for EE extension of this component -->
|
||||
<squash-before-merge
|
||||
v-if="shouldShowSquashBeforeMerge"
|
||||
:mr="mr"
|
||||
:is-merge-button-disabled="isMergeButtonDisabled" />
|
||||
<!-- Placeholder for EE extension of this component -->
|
||||
<squash-before-merge
|
||||
v-if="shouldShowSquashBeforeMerge"
|
||||
:mr="mr"
|
||||
:is-merge-button-disabled="isMergeButtonDisabled" />
|
||||
|
||||
<button
|
||||
@click="toggleCommitMessageEditor"
|
||||
:disabled="isMergeButtonDisabled"
|
||||
class="btn btn-default btn-xs"
|
||||
type="button">
|
||||
Modify commit message
|
||||
</button>
|
||||
<button
|
||||
@click="toggleCommitMessageEditor"
|
||||
:disabled="isMergeButtonDisabled"
|
||||
class="btn btn-default btn-xs"
|
||||
type="button">
|
||||
Modify commit message
|
||||
</button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="bold">
|
||||
The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="showCommitMessageEditor"
|
||||
class="prepend-top-default commit-message-editor">
|
||||
|
@ -293,7 +310,7 @@ export default {
|
|||
rows="14"
|
||||
name="Commit message"></textarea>
|
||||
</div>
|
||||
<p class="hint">Try to keep the first line under 52 characters and the others under 72.</p>
|
||||
<p class="hint">Try to keep the first line under 52 characters and the others under 72</p>
|
||||
<div class="hint">
|
||||
<a
|
||||
@click.prevent="updateCommitMessage"
|
||||
|
@ -302,12 +319,7 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="bold">
|
||||
The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure.
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import statusIcon from '../mr_widget_status_icon';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetSHAMismatch',
|
||||
components: {
|
||||
statusIcon,
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-success btn-small"
|
||||
disabled="true">
|
||||
Merge
|
||||
</button>
|
||||
<span class="bold">
|
||||
The source branch HEAD has recently changed. Please reload the page and review the changes before merging.
|
||||
</span>
|
||||
<div class="mr-widget-body media">
|
||||
<status-icon status="failed" showDisabledButton />
|
||||
<div class="media-body space-children">
|
||||
<span class="bold">
|
||||
The source branch HEAD has recently changed. Please reload the page and review the changes before merging
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
import statusIcon from '../mr_widget_status_icon';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetUnresolvedDiscussions',
|
||||
props: {
|
||||
mr: { type: Object, required: true },
|
||||
},
|
||||
components: {
|
||||
statusIcon,
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-success btn-small"
|
||||
disabled="true">
|
||||
Merge
|
||||
</button>
|
||||
<span class="bold">
|
||||
There are unresolved discussions. Please resolve these discussions
|
||||
<span v-if="mr.canCreateIssue">or</span>
|
||||
<span v-else>.</span>
|
||||
</span>
|
||||
<a
|
||||
v-if="mr.createIssueToResolveDiscussionsPath"
|
||||
:href="mr.createIssueToResolveDiscussionsPath"
|
||||
class="btn btn-default btn-xs js-create-issue">
|
||||
Create an issue to resolve them later
|
||||
</a>
|
||||
<div class="mr-widget-body media">
|
||||
<status-icon status="failed" showDisabledButton />
|
||||
<div class="media-body space-children">
|
||||
<span class="bold">
|
||||
There are unresolved discussions. Please resolve these discussions
|
||||
</span>
|
||||
<a
|
||||
v-if="mr.createIssueToResolveDiscussionsPath"
|
||||
:href="mr.createIssueToResolveDiscussionsPath"
|
||||
class="btn btn-default btn-xs js-create-issue">
|
||||
Create an issue to resolve them later
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
/* global Flash */
|
||||
import statusIcon from '../mr_widget_status_icon';
|
||||
import tooltip from '../../../vue_shared/directives/tooltip';
|
||||
import eventHub from '../../event_hub';
|
||||
|
||||
export default {
|
||||
|
@ -7,11 +9,17 @@ export default {
|
|||
mr: { type: Object, required: true },
|
||||
service: { type: Object, required: true },
|
||||
},
|
||||
directives: {
|
||||
tooltip,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isMakingRequest: false,
|
||||
};
|
||||
},
|
||||
components: {
|
||||
statusIcon,
|
||||
},
|
||||
methods: {
|
||||
removeWIP() {
|
||||
this.isMakingRequest = true;
|
||||
|
@ -29,20 +37,20 @@ export default {
|
|||
},
|
||||
},
|
||||
template: `
|
||||
<div class="mr-widget-body">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-success btn-small"
|
||||
disabled="true">
|
||||
Merge</button>
|
||||
<span class="bold">
|
||||
This merge request is currently Work In Progress and therefore unable to merge
|
||||
</span>
|
||||
<template v-if="mr.removeWIPPath">
|
||||
<i
|
||||
class="fa fa-question-circle has-tooltip"
|
||||
title="When this merge request is ready, remove the WIP: prefix from the title to allow it to be merged." />
|
||||
<div class="mr-widget-body media">
|
||||
<status-icon status="failed" :showDisabledButton="Boolean(mr.removeWIPPath)" />
|
||||
<div class="media-body space-children">
|
||||
<span class="bold">
|
||||
This is a Work in Progress
|
||||
<i
|
||||
v-tooltip
|
||||
class="fa fa-question-circle"
|
||||
title="When this merge request is ready, remove the WIP: prefix from the title to allow it to be merged"
|
||||
aria-label="When this merge request is ready, remove the WIP: prefix from the title to allow it to be merged">
|
||||
</i>
|
||||
</span>
|
||||
<button
|
||||
v-if="mr.removeWIPPath"
|
||||
@click="removeWIP"
|
||||
:disabled="isMakingRequest"
|
||||
type="button"
|
||||
|
@ -53,7 +61,7 @@ export default {
|
|||
aria-hidden="true" />
|
||||
Resolve WIP status
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* This file is the centerpiece of an attempt to reduce potential conflicts
|
||||
* between the CE and EE versions of the MR widget. EE additions to the MR widget should
|
||||
* be contained in the ./vue_merge_request_widget/ee directory, and should **extend**
|
||||
* be contained in the ee/vue_merge_request_widget directory, and should **extend**
|
||||
* rather than mutate CE MR Widget code.
|
||||
*
|
||||
* This file should be the only source of conflicts between EE and CE. EE-only components should
|
||||
|
|
|
@ -35,8 +35,14 @@ import {
|
|||
export default {
|
||||
el: '#js-vue-mr-widget',
|
||||
name: 'MRWidget',
|
||||
props: {
|
||||
mrData: {
|
||||
type: Object,
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
const store = new MRWidgetStore(gl.mrWidgetData);
|
||||
const store = new MRWidgetStore(this.mrData || window.gl.mrWidgetData);
|
||||
const service = this.createService(store);
|
||||
return {
|
||||
mr: store,
|
||||
|
@ -234,14 +240,21 @@ export default {
|
|||
v-if="shouldRenderDeployments"
|
||||
:mr="mr"
|
||||
:service="service" />
|
||||
<component
|
||||
:is="componentName"
|
||||
:mr="mr"
|
||||
:service="service" />
|
||||
<mr-widget-related-links
|
||||
v-if="shouldRenderRelatedLinks"
|
||||
:related-links="mr.relatedLinks" />
|
||||
<mr-widget-merge-help v-if="shouldRenderMergeHelp" />
|
||||
<div class="mr-widget-section">
|
||||
<component
|
||||
:is="componentName"
|
||||
:mr="mr"
|
||||
:service="service" />
|
||||
<mr-widget-related-links
|
||||
v-if="shouldRenderRelatedLinks"
|
||||
:state="mr.state"
|
||||
:related-links="mr.relatedLinks" />
|
||||
</div>
|
||||
<div
|
||||
class="mr-widget-footer"
|
||||
v-if="shouldRenderMergeHelp">
|
||||
<mr-widget-merge-help />
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
@import "framework/lists";
|
||||
@import "framework/logo";
|
||||
@import "framework/markdown_area";
|
||||
@import "framework/media_object";
|
||||
@import "framework/mobile";
|
||||
@import "framework/modal";
|
||||
@import "framework/nav";
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
margin-top: -23px;
|
||||
float: right;
|
||||
font-size: 12px;
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.pika-single.gitlab-theme {
|
||||
|
|
|
@ -574,6 +574,7 @@
|
|||
|
||||
.dropdown-input-field,
|
||||
.default-dropdown-input {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 30px;
|
||||
padding: 0 7px;
|
||||
|
@ -722,3 +723,57 @@
|
|||
@include set-invisible;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// TODO: change global style and remove mixin
|
||||
@mixin new-style-dropdown {
|
||||
.dropdown-menu,
|
||||
.dropdown-menu-nav {
|
||||
.divider {
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
padding: 0 1px;
|
||||
|
||||
&.dropdown-header {
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
a {
|
||||
border-radius: 0;
|
||||
padding: 8px 16px;
|
||||
|
||||
&.is-focused,
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
background-color: $gray-darker;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
font-weight: inherit;
|
||||
|
||||
&::before {
|
||||
top: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.dropdown-menu-selectable {
|
||||
li {
|
||||
a {
|
||||
padding: 8px 40px;
|
||||
|
||||
&.is-active::before {
|
||||
left: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu-align-right {
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
*/
|
||||
|
||||
header {
|
||||
@include new-style-dropdown;
|
||||
|
||||
transition: padding $sidebar-transition-duration;
|
||||
|
||||
&.navbar-empty {
|
||||
|
@ -24,7 +26,7 @@ header {
|
|||
|
||||
&.navbar-gitlab {
|
||||
padding: 0 16px;
|
||||
z-index: 400;
|
||||
z-index: 2000;
|
||||
margin-bottom: 0;
|
||||
min-height: $header-height;
|
||||
background-color: $gray-light;
|
||||
|
@ -313,25 +315,6 @@ header {
|
|||
.impersonation i {
|
||||
color: $red-500;
|
||||
}
|
||||
|
||||
// TODO: fallback to global style
|
||||
.dropdown-menu,
|
||||
.dropdown-menu-nav {
|
||||
li {
|
||||
padding: 0 1px;
|
||||
|
||||
a {
|
||||
border-radius: 0;
|
||||
padding: 8px 16px;
|
||||
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
background-color: $gray-darker;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.with-performance-bar header.navbar-gitlab {
|
||||
|
@ -342,9 +325,9 @@ header {
|
|||
li {
|
||||
.badge {
|
||||
position: inherit;
|
||||
top: -3px;
|
||||
top: -8px;
|
||||
font-weight: normal;
|
||||
margin-left: -12px;
|
||||
margin-left: -11px;
|
||||
font-size: 11px;
|
||||
color: $white-light;
|
||||
padding: 1px 5px 2px;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
.media {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.media-body {
|
||||
flex: 1;
|
||||
}
|
|
@ -207,7 +207,6 @@ $general-hover-transition-curve: linear;
|
|||
$highlight-changes-color: rgb(235, 255, 232);
|
||||
$performance-bar-height: 35px;
|
||||
|
||||
|
||||
/*
|
||||
* Common component specific colors
|
||||
*/
|
||||
|
@ -316,6 +315,12 @@ $btn-white-active: #848484;
|
|||
$badge-bg: rgba(0, 0, 0, 0.07);
|
||||
$badge-color: $gl-text-color-secondary;
|
||||
|
||||
/*
|
||||
* Status icons
|
||||
*/
|
||||
$status-icon-size: 22px;
|
||||
$status-icon-margin: $gl-btn-padding;
|
||||
|
||||
/*
|
||||
* Award emoji
|
||||
*/
|
||||
|
|
|
@ -312,6 +312,10 @@ header.navbar-gitlab-new {
|
|||
|
||||
// TODO: fallback to global style
|
||||
.dropdown-menu {
|
||||
.divider {
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
padding: 0 1px;
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue