Read about our upcoming Code of Conduct on this issue

Commit 5ee20b63 authored by Kamil Trzciński's avatar Kamil Trzciński
Browse files

Merge branch 'master' into '37970-ci-sections-tracking'

# Conflicts:
#   db/schema.rb
......@@ -27,7 +27,7 @@ variables:
GET_SOURCES_ATTEMPTS: "3"
KNAPSACK_RSPEC_SUITE_REPORT_PATH: knapsack/${CI_PROJECT_NAME}/rspec_report-master.json
KNAPSACK_SPINACH_SUITE_REPORT_PATH: knapsack/${CI_PROJECT_NAME}/spinach_report-master.json
FLAKY_RSPEC_SUITE_REPORT_PATH: rspec_flaky/${CI_PROJECT_NAME}/report-master.json
FLAKY_RSPEC_SUITE_REPORT_PATH: rspec_flaky/report-suite.json
before_script:
- bundle --version
......@@ -87,12 +87,13 @@ stages:
- export CI_NODE_TOTAL=${JOB_NAME[-1]}
- export KNAPSACK_REPORT_PATH=knapsack/${CI_PROJECT_NAME}/${JOB_NAME[0]}_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
- export KNAPSACK_GENERATE_REPORT=true
- export ALL_FLAKY_RSPEC_REPORT_PATH=rspec_flaky/${CI_PROJECT_NAME}/all_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
- export NEW_FLAKY_RSPEC_REPORT_PATH=rspec_flaky/${CI_PROJECT_NAME}/new_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
- export SUITE_FLAKY_RSPEC_REPORT_PATH=${FLAKY_RSPEC_SUITE_REPORT_PATH}
- export FLAKY_RSPEC_REPORT_PATH=rspec_flaky/all_${JOB_NAME[0]}_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
- export NEW_FLAKY_RSPEC_REPORT_PATH=rspec_flaky/new_${JOB_NAME[0]}_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
- export FLAKY_RSPEC_GENERATE_REPORT=true
- export CACHE_CLASSES=true
- cp ${KNAPSACK_RSPEC_SUITE_REPORT_PATH} ${KNAPSACK_REPORT_PATH}
- cp ${FLAKY_RSPEC_SUITE_REPORT_PATH} ${ALL_FLAKY_RSPEC_REPORT_PATH}
- '[[ -f $FLAKY_RSPEC_REPORT_PATH ]] || echo "{}" > ${FLAKY_RSPEC_REPORT_PATH}'
- '[[ -f $NEW_FLAKY_RSPEC_REPORT_PATH ]] || echo "{}" > ${NEW_FLAKY_RSPEC_REPORT_PATH}'
- scripts/gitaly-test-spawn
- knapsack rspec "--color --format documentation"
......@@ -233,7 +234,7 @@ retrieve-tests-metadata:
- wget -O $KNAPSACK_SPINACH_SUITE_REPORT_PATH http://${TESTS_METADATA_S3_BUCKET}.s3.amazonaws.com/$KNAPSACK_SPINACH_SUITE_REPORT_PATH || rm $KNAPSACK_SPINACH_SUITE_REPORT_PATH
- '[[ -f $KNAPSACK_RSPEC_SUITE_REPORT_PATH ]] || echo "{}" > ${KNAPSACK_RSPEC_SUITE_REPORT_PATH}'
- '[[ -f $KNAPSACK_SPINACH_SUITE_REPORT_PATH ]] || echo "{}" > ${KNAPSACK_SPINACH_SUITE_REPORT_PATH}'
- mkdir -p rspec_flaky/${CI_PROJECT_NAME}/
- mkdir -p rspec_flaky/
- wget -O $FLAKY_RSPEC_SUITE_REPORT_PATH http://${TESTS_METADATA_S3_BUCKET}.s3.amazonaws.com/$FLAKY_RSPEC_SUITE_REPORT_PATH || rm $FLAKY_RSPEC_SUITE_REPORT_PATH
- '[[ -f $FLAKY_RSPEC_SUITE_REPORT_PATH ]] || echo "{}" > ${FLAKY_RSPEC_SUITE_REPORT_PATH}'
......@@ -252,22 +253,21 @@ update-tests-metadata:
- retry gem install fog-aws mime-types
- scripts/merge-reports ${KNAPSACK_RSPEC_SUITE_REPORT_PATH} knapsack/${CI_PROJECT_NAME}/rspec-pg_node_*.json
- scripts/merge-reports ${KNAPSACK_SPINACH_SUITE_REPORT_PATH} knapsack/${CI_PROJECT_NAME}/spinach-pg_node_*.json
- scripts/merge-reports ${FLAKY_RSPEC_SUITE_REPORT_PATH} rspec_flaky/${CI_PROJECT_NAME}/all_node_*.json
- scripts/merge-reports ${FLAKY_RSPEC_SUITE_REPORT_PATH} rspec_flaky/all_*_*.json
- '[[ -z ${TESTS_METADATA_S3_BUCKET} ]] || scripts/sync-reports put $TESTS_METADATA_S3_BUCKET $KNAPSACK_RSPEC_SUITE_REPORT_PATH $KNAPSACK_SPINACH_SUITE_REPORT_PATH'
- '[[ -z ${TESTS_METADATA_S3_BUCKET} ]] || scripts/sync-reports put $TESTS_METADATA_S3_BUCKET $FLAKY_RSPEC_SUITE_REPORT_PATH'
- rm -f knapsack/${CI_PROJECT_NAME}/*_node_*.json
- rm -f rspec_flaky/${CI_PROJECT_NAME}/*_node_*.json
- rm -f rspec_flaky/all_*.json rspec_flaky/new_*.json
flaky-examples-check:
<<: *dedicated-runner
image: ruby:2.3-alpine
services: []
before_script: []
cache: {}
variables:
SETUP_DB: "false"
USE_BUNDLE_INSTALL: "false"
NEW_FLAKY_SPECS_REPORT: rspec_flaky/${CI_PROJECT_NAME}/new_rspec_flaky_examples.json
NEW_FLAKY_SPECS_REPORT: rspec_flaky/report-new.json
stage: post-test
allow_failure: yes
only:
......@@ -281,7 +281,7 @@ flaky-examples-check:
- rspec_flaky/
script:
- '[[ -f $NEW_FLAKY_SPECS_REPORT ]] || echo "{}" > ${NEW_FLAKY_SPECS_REPORT}'
- scripts/merge-reports $NEW_FLAKY_SPECS_REPORT rspec_flaky/${CI_PROJECT_NAME}/new_node_*.json
- scripts/merge-reports ${NEW_FLAKY_SPECS_REPORT} rspec_flaky/new_*_*.json
- scripts/detect-new-flaky-examples $NEW_FLAKY_SPECS_REPORT
setup-test-env:
......
......@@ -2,6 +2,23 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
## 10.0.3 (2017-10-05)
- [FIXED] find_user Users helper method no longer overrides find_user API helper method. !14418
- [FIXED] Fix CSRF validation issue when closing/opening merge requests from the UI. !14555
- [FIXED] Kubernetes integration: ensure v1.8.0 compatibility. !14635
- [FIXED] Fixes data parameter not being sent in ajax request for jobs log.
- [FIXED] Improves UX of autodevops popover to match gpg one.
- [FIXED] Fixed commenting on side-by-side commit diff.
- [FIXED] Make sure API responds with 401 when invalid authentication info is provided.
- [FIXED] Fix merge request counter updates after merge.
- [FIXED] Fix gitlab-rake gitlab:import:repos task failing.
- [FIXED] Fix pushes to an empty repository not invalidating has_visible_content? cache.
- [FIXED] Ensure all refs are restored on a restore from backup.
- [FIXED] Gitaly RepositoryExists remains opt-in for all method calls.
- [FIXED] Fix 500 error on merged merge requests when GitLab is restored from a backup.
- [FIXED] Adjust MRs being stuck on "process of being merged" for more than 2 hours.
## 10.0.2 (2017-09-27)
- [FIXED] Notes will not show an empty bubble when the author isn't a member. !14450
......@@ -195,6 +212,10 @@ entry.
- Added type to CHANGELOG entries. (Jacopo Beschi @jacopo-beschi)
- [BUGIFX] Improves subgroup creation permissions. !13418
## 9.5.8 (2017-10-04)
- [FIXED] Fixed fork button being disabled for users who can fork to a group.
## 9.5.7 (2017-10-03)
- Fix gitlab rake:import:repos task.
......
......@@ -23,7 +23,7 @@ gem 'faraday', '~> 0.12'
# Authentication libraries
gem 'devise', '~> 4.2'
gem 'doorkeeper', '~> 4.2.0'
gem 'doorkeeper-openid_connect', '~> 1.1.0'
gem 'doorkeeper-openid_connect', '~> 1.2.0'
gem 'omniauth', '~> 1.4.2'
gem 'omniauth-auth0', '~> 1.4.1'
gem 'omniauth-azure-oauth2', '~> 0.0.9'
......
......@@ -80,7 +80,7 @@ GEM
coderay (>= 1.0.0)
erubis (>= 2.6.6)
rack (>= 0.9.0)
bindata (2.3.5)
bindata (2.4.1)
binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1)
bootstrap-sass (3.3.6)
......@@ -166,9 +166,9 @@ GEM
docile (1.1.5)
domain_name (0.5.20161021)
unf (>= 0.0.5, < 1.0.0)
doorkeeper (4.2.0)
doorkeeper (4.2.6)
railties (>= 4.2)
doorkeeper-openid_connect (1.1.2)
doorkeeper-openid_connect (1.2.0)
doorkeeper (~> 4.0)
json-jwt (~> 1.6)
dropzonejs-rails (0.7.2)
......@@ -410,7 +410,7 @@ GEM
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
json (1.8.6)
json-jwt (1.7.1)
json-jwt (1.7.2)
activesupport
bindata
multi_json (>= 1.3)
......@@ -681,7 +681,7 @@ GEM
rainbow (2.2.2)
rake
raindrops (0.18.0)
rake (12.0.0)
rake (12.1.0)
rblineprof (0.3.6)
debugger-ruby_core_source (~> 1.3)
rbnacl (4.0.2)
......@@ -910,7 +910,7 @@ GEM
json (>= 1.8.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.2)
unf_ext (0.0.7.4)
unicode-display_width (1.3.0)
unicorn (5.1.0)
kgio (~> 2.6)
......@@ -1002,7 +1002,7 @@ DEPENDENCIES
devise-two-factor (~> 3.0.0)
diffy (~> 3.1.0)
doorkeeper (~> 4.2.0)
doorkeeper-openid_connect (~> 1.1.0)
doorkeeper-openid_connect (~> 1.2.0)
dropzonejs-rails (~> 0.7.1)
email_reply_trimmer (~> 0.1)
email_spec (~> 1.6.0)
......
<svg width="24" height="30" viewBox="0 0 24 30" xmlns="http://www.w3.org/2000/svg"><title>cursor</title><g fill="none" fill-rule="evenodd"><path d="M24 12.105c0 6.686-5.74 11.58-12 17.895C5.74 23.684 0 18.79 0 12.105 0 5.42 5.373 0 12 0s12 5.42 12 12.105z" fill="#1F78D1" fill-rule="nonzero"/><path d="M15.28 25.249c1.458-1.475 2.539-2.635 3.474-3.747 2.851-3.394 4.203-6.265 4.203-9.397 0-6.111-4.908-11.062-10.957-11.062-6.05 0-10.957 4.951-10.957 11.062 0 3.132 1.352 6.003 4.203 9.397.935 1.112 2.016 2.272 3.474 3.747.511.517 2.216 2.213 3.28 3.275 1.064-1.062 2.769-2.758 3.28-3.275z" fill="#FFF"/><path d="M14.551 8.256A6.874 6.874 0 0 0 12 7.787c-.91 0-1.763.156-2.558.469-.79.308-1.42.725-1.888 1.252-.465.527-.697 1.096-.697 1.708 0 .5.159.977.476 1.433.321.45.772.841 1.352 1.172l.583.334-.181.643c-.107.407-.263.79-.469 1.152a6.604 6.604 0 0 0 1.842-1.145l.288-.254.381.04c.309.035.599.053.871.053.91 0 1.761-.154 2.551-.462.795-.312 1.424-.732 1.889-1.259.468-.526.703-1.096.703-1.707 0-.612-.235-1.181-.703-1.708-.465-.527-1.094-.944-1.889-1.252zm2.645.81c.536.656.804 1.373.804 2.15 0 .776-.268 1.495-.804 2.156-.535.656-1.263 1.176-2.183 1.56-.92.38-1.924.57-3.013.57a9.16 9.16 0 0 1-.971-.054 7.32 7.32 0 0 1-3.08 1.62 5.044 5.044 0 0 1-.764.148h-.033a.26.26 0 0 1-.181-.074.324.324 0 0 1-.107-.18v-.007c-.014-.018-.016-.045-.007-.08.014-.037.018-.059.014-.068 0-.009.01-.031.033-.067a.645.645 0 0 0 .04-.06 1.73 1.73 0 0 0 .047-.054l.054-.06a53.034 53.034 0 0 1 .435-.489c.049-.049.118-.136.207-.26.094-.126.168-.24.221-.342.054-.103.114-.235.181-.395.067-.161.125-.33.174-.51-.7-.397-1.254-.888-1.66-1.473A3.261 3.261 0 0 1 6 11.216c0-.777.268-1.494.804-2.15.535-.66 1.263-1.18 2.183-1.56.92-.384 1.924-.576 3.013-.576 1.09 0 2.094.192 3.013.576.92.38 1.648.9 2.183 1.56z" fill="#1F78D1" fill-rule="nonzero"/></g></svg>
<svg width="48" height="60" viewBox="0 0 48 60" xmlns="http://www.w3.org/2000/svg"><title>cursor_2x</title><g fill="none" fill-rule="evenodd"><path d="M48 24.21C48 37.583 36.522 47.369 24 60 11.478 47.368 0 37.582 0 24.21 0 10.84 10.745 0 24 0s24 10.84 24 24.21z" fill="#1F78D1" fill-rule="nonzero"/><path d="M30.56 50.497c2.915-2.95 5.078-5.268 6.947-7.493 5.703-6.788 8.406-12.53 8.406-18.793 0-12.223-9.815-22.124-21.913-22.124S2.087 11.988 2.087 24.211c0 6.263 2.703 12.005 8.406 18.793 1.87 2.225 4.032 4.544 6.947 7.493 1.022 1.035 4.432 4.426 6.56 6.55 2.128-2.124 5.538-5.515 6.56-6.55z" fill="#FFF"/><path d="M29.103 16.512c-1.58-.625-3.282-.938-5.103-.938-1.821 0-3.527.313-5.116.938-1.58.616-2.84 1.45-3.777 2.504-.928 1.054-1.393 2.192-1.393 3.415 0 1 .317 1.956.951 2.866.643.902 1.545 1.684 2.706 2.344l1.165.67-.362 1.286a9.603 9.603 0 0 1-.937 2.303 13.208 13.208 0 0 0 3.683-2.29l.576-.509.763.08c.616.072 1.196.108 1.741.108 1.821 0 3.522-.308 5.103-.925 1.589-.625 2.848-1.464 3.776-2.517.938-1.054 1.407-2.192 1.407-3.416 0-1.223-.469-2.361-1.407-3.415-.928-1.053-2.187-1.888-3.776-2.504zm5.29 1.62c1.071 1.313 1.607 2.746 1.607 4.3 0 1.553-.536 2.99-1.607 4.312-1.072 1.312-2.527 2.353-4.366 3.12-1.84.76-3.848 1.139-6.027 1.139a18.32 18.32 0 0 1-1.942-.107c-1.768 1.562-3.821 2.643-6.16 3.24-.438.126-.947.224-1.527.295h-.067a.521.521 0 0 1-.362-.147.649.649 0 0 1-.214-.362v-.013c-.027-.036-.032-.09-.014-.16.027-.072.036-.117.027-.135 0-.017.022-.062.067-.133a1.29 1.29 0 0 0 .08-.121c.01-.009.04-.045.094-.107a106.068 106.068 0 0 1 .522-.59c.215-.232.367-.401.456-.508.098-.099.236-.273.415-.523.188-.25.335-.477.442-.683.107-.205.228-.468.362-.79.134-.321.25-.66.348-1.018-1.402-.794-2.51-1.777-3.322-2.946C12.402 25.025 12 23.77 12 22.43c0-1.553.536-2.986 1.607-4.299 1.072-1.321 2.527-2.361 4.366-3.12 1.84-.768 3.848-1.152 6.027-1.152 2.179 0 4.188.384 6.027 1.152 1.84.759 3.294 1.799 4.366 3.12z" fill="#1F78D1" fill-rule="nonzero"/></g></svg>
/* eslint-disable func-names, space-before-function-paren, wrap-iife, prefer-arrow-callback, no-unused-vars, no-return-assign, max-len */
import { visitUrl } from './lib/utils/url_utility';
import { convertPermissionToBoolean } from './lib/utils/common_utils';
window.BuildArtifacts = (function() {
function BuildArtifacts() {
this.disablePropagation();
this.setupEntryClick();
this.setupTooltips();
}
BuildArtifacts.prototype.disablePropagation = function() {
......@@ -17,9 +20,28 @@ window.BuildArtifacts = (function() {
BuildArtifacts.prototype.setupEntryClick = function() {
return $('.tree-holder').on('click', 'tr[data-link]', function(e) {
return window.location = this.dataset.link;
visitUrl(this.dataset.link, convertPermissionToBoolean(this.dataset.externalLink));
});
};
BuildArtifacts.prototype.setupTooltips = function() {
$('.js-artifact-tree-tooltip').tooltip({
placement: 'bottom',
// Stop the tooltip from hiding when we stop hovering the element directly
// We handle all the showing/hiding below
trigger: 'manual',
});
// We want the tooltip to show if you hover anywhere on the row
// But be placed below and in the middle of the file name
$('.js-artifact-tree-row')
.on('mouseenter', (e) => {
$(e.currentTarget).find('.js-artifact-tree-tooltip').tooltip('show');
})
.on('mouseleave', (e) => {
$(e.currentTarget).find('.js-artifact-tree-tooltip').tooltip('hide');
});
};
return BuildArtifacts;
})();
/* globals Flash */
import Visibility from 'visibilityjs';
import axios from 'axios';
import Poll from './lib/utils/poll';
import { s__ } from './locale';
import './flash';
/**
* Cluster page has 2 separate parts:
* Toggle button
*
* - Polling status while creating or scheduled
* -- Update status area with the response result
*/
class ClusterService {
constructor(options = {}) {
this.options = options;
}
fetchData() {
return axios.get(this.options.endpoint);
}
}
export default class Clusters {
constructor() {
const dataset = document.querySelector('.js-edit-cluster-form').dataset;
this.state = {
statusPath: dataset.statusPath,
clusterStatus: dataset.clusterStatus,
clusterStatusReason: dataset.clusterStatusReason,
toggleStatus: dataset.toggleStatus,
};
this.service = new ClusterService({ endpoint: this.state.statusPath });
this.toggleButton = document.querySelector('.js-toggle-cluster');
this.toggleInput = document.querySelector('.js-toggle-input');
this.errorContainer = document.querySelector('.js-cluster-error');
this.successContainer = document.querySelector('.js-cluster-success');
this.creatingContainer = document.querySelector('.js-cluster-creating');
this.errorReasonContainer = this.errorContainer.querySelector('.js-error-reason');
this.toggleButton.addEventListener('click', this.toggle.bind(this));
if (this.state.clusterStatus !== 'created') {
this.updateContainer(this.state.clusterStatus, this.state.clusterStatusReason);
}
if (this.state.statusPath) {
this.initPolling();
}
}
toggle() {
this.toggleButton.classList.toggle('checked');
this.toggleInput.setAttribute('value', this.toggleButton.classList.contains('checked').toString());
}
initPolling() {
this.poll = new Poll({
resource: this.service,
method: 'fetchData',
successCallback: (data) => {
const { status, status_reason } = data.data;
this.updateContainer(status, status_reason);
},
errorCallback: () => {
Flash(s__('ClusterIntegration|Something went wrong on our end.'));
},
});
if (!Visibility.hidden()) {
this.poll.makeRequest();
} else {
this.service.fetchData();
}
Visibility.change(() => {
if (!Visibility.hidden()) {
this.poll.restart();
} else {
this.poll.stop();
}
});
}
hideAll() {
this.errorContainer.classList.add('hidden');
this.successContainer.classList.add('hidden');
this.creatingContainer.classList.add('hidden');
}
updateContainer(status, error) {
this.hideAll();
switch (status) {
case 'created':
this.successContainer.classList.remove('hidden');
break;
case 'errored':
this.errorContainer.classList.remove('hidden');
this.errorReasonContainer.textContent = error;
break;
case 'scheduled':
case 'creating':
this.creatingContainer.classList.remove('hidden');
break;
default:
this.hideAll();
}
}
}
/* eslint-disable func-names, space-before-function-paren, wrap-iife */
/* global CommitFile */
window.Commit = (function() {
function Commit() {
$('.files .diff-file').each(function() {
return new CommitFile(this);
});
}
return Commit;
})();
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-new */
/* global ImageFile */
(function() {
this.CommitFile = (function() {
function CommitFile(file) {
if ($('.image', file).length) {
new gl.ImageFile(file);
}
}
return CommitFile;
})();
}).call(window);
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-use-before-define, prefer-arrow-callback, no-else-return, consistent-return, prefer-template, quotes, one-var, one-var-declaration-per-line, no-unused-vars, no-return-assign, comma-dangle, quote-props, no-unused-expressions, no-sequences, object-shorthand, max-len */
import 'vendor/jquery.waitforimages';
(function() {
gl.ImageFile = (function() {
var prepareFrames;
......@@ -17,15 +19,10 @@
// Load two-up view after images are loaded
// so that we can display the correct width and height information
const images = $('.two-up.view img', _this.file);
let loadedCount = 0;
images.on('load', () => {
loadedCount += 1;
const $images = $('.two-up.view img', _this.file);
if (loadedCount === images.length) {
_this.initView('two-up');
}
$images.waitForImages(function() {
_this.initView('two-up');
});
});
};
......
......@@ -20,7 +20,7 @@
<template v-if="time.days">{{ time.days }} <span>{{ n__('day', 'days', time.days) }}</span></template>
<template v-if="time.hours">{{ time.hours }} <span>{{ n__('Time|hr', 'Time|hrs', time.hours) }}</span></template>
<template v-if="time.mins && !time.days">{{ time.mins }} <span>{{ n__('Time|min', 'Time|mins', time.mins) }}</span></template>
<template v-if="time.seconds && hasDa === 1 || time.seconds === 0">{{ time.seconds }} <span>{{ s__('Time|s') }}</span></template>
<template v-if="time.seconds && hasData === 1 || time.seconds === 0">{{ time.seconds }} <span>{{ s__('Time|s') }}</span></template>
</template>
<template v-else>
--
......
......@@ -3,6 +3,7 @@
import './lib/utils/url_utility';
import FilesCommentButton from './files_comment_button';
import SingleFileDiff from './single_file_diff';
import imageDiffHelper from './image_diff/helpers/index';
const UNFOLD_COUNT = 20;
let isBound = false;
......@@ -17,9 +18,12 @@ class Diff {
}
});
FilesCommentButton.init($diffFile);
const tab = document.getElementById('diffs');
if (!tab || (tab && tab.dataset && tab.dataset.isLocked !== '')) FilesCommentButton.init($diffFile);
$diffFile.each((index, file) => new gl.ImageFile(file));
const firstFile = $('.files').first().get(0);
const canCreateNote = firstFile && firstFile.hasAttribute('data-can-create-note');
$diffFile.each((index, file) => imageDiffHelper.initImageDiff(file, canCreateNote));
if (!isBound) {
$(document)
......
......@@ -171,7 +171,14 @@ const JumpToDiscussion = Vue.extend({
// When jumping between unresolved discussions on the diffs tab, we show them.
$target.closest(".content").show();
$target = $target.closest("tr.notes_holder");
const $notesHolder = $target.closest("tr.notes_holder");
// Image diff discussions does not use notes_holder
// so we should keep original $target value in those cases
if ($notesHolder.length > 0) {
$target = $notesHolder;
}
$target.show();
// If we are on the diffs tab, we don't scroll to the discussion itself, but to
......
......@@ -7,7 +7,6 @@
/* global IssuableForm */
/* global LabelsSelect */
/* global MilestoneSelect */
/* global Commit */
/* global CommitsList */
/* global NewBranchForm */
/* global NotificationsForm */
......@@ -316,7 +315,6 @@ import { ajaxGet, convertPermissionToBoolean } from './lib/utils/common_utils';
new gl.Activities();
break;
case 'projects:commit:show':
new Commit();
new gl.Diff();
new ZenMode();
shortcut_handler = new ShortcutsNavigation();
......@@ -525,6 +523,11 @@ import { ajaxGet, convertPermissionToBoolean } from './lib/utils/common_utils';
case 'admin:impersonation_tokens:index':
new gl.DueDateSelectors();
break;
case 'projects:clusters:show':
import(/* webpackChunkName: "clusters" */ './clusters')
.then(cluster => new cluster.default()) // eslint-disable-line new-cap
.catch(() => {});
break;
}
switch (path[0]) {
case 'sessions':
......
......@@ -738,7 +738,7 @@ GitLabDropdown = (function() {
: selectedObject.id;
if (isInput) {
field = $(this.el);
} else if (value) {
} else if (value != null) {
field = this.dropdown.parent().find("input[name='" + fieldName + "'][value='" + value.toString().replace(/'/g, '\\\'') + "']");
}
......@@ -746,7 +746,7 @@ GitLabDropdown = (function() {
return;
}
if (el.hasClass(ACTIVE_CLASS)) {
if (el.hasClass(ACTIVE_CLASS) && value !== 0) {
isMarking = false;
el.removeClass(ACTIVE_CLASS);
if (field && field.length) {
......@@ -852,7 +852,7 @@ GitLabDropdown = (function() {
if (href && href !== '#') {
gl.utils.visitUrl(href);
} else {
$el.first().trigger('click');
$el.trigger('click');
}
}
};
......
export function createImageBadge(noteId, { x, y }, classNames = []) {
const buttonEl = document.createElement('button');
const classList = classNames.concat(['js-image-badge']);
classList.forEach(className => buttonEl.classList.add(className));
buttonEl.setAttribute('type', 'button');
buttonEl.setAttribute('disabled', true);
buttonEl.dataset.noteId = noteId;
buttonEl.style.left = `${x}px`;
buttonEl.style.top = `${y}px`;
return buttonEl;
}
export function addImageBadge(containerEl, { coordinate, badgeText, noteId }) {
const buttonEl = createImageBadge(noteId, coordinate, ['badge']);
buttonEl.innerText = badgeText;
containerEl.appendChild(buttonEl);
}
export function addImageCommentBadge(containerEl, { coordinate, noteId }) {
const buttonEl = createImageBadge(noteId, coordinate, ['image-comment-badge', 'inverted']);
const iconEl = document.createElement('i');
iconEl.className = 'fa fa-comment-o';
iconEl.setAttribute('aria-label', 'comment');
buttonEl.appendChild(iconEl);
containerEl.appendChild(buttonEl);
}
export function addAvatarBadge(el, event) {
const { noteId, badgeNumber } = event.detail;
// Add badge to new comment
const avatarBadgeEl = el.querySelector(`#${noteId} .badge`);
avatarBadgeEl.innerText = badgeNumber;
avatarBadgeEl.classList.remove('hidden');
}
export function addCommentIndicator(containerEl, { x, y }) {
const buttonEl = document.createElement('button');
buttonEl.classList.add('btn-transparent');
buttonEl.classList.add('comment-indicator');
buttonEl.setAttribute('type', 'button');
buttonEl.style.left = `${x}px`;
buttonEl.style.top = `${y}px`;
buttonEl.innerHTML = gl.utils.spriteIcon('image-comment-dark');
containerEl.appendChild(buttonEl);
}
export function removeCommentIndicator(imageFrameEl) {
const commentIndicatorEl = imageFrameEl.querySelector('.comment-indicator');
const imageEl = imageFrameEl.querySelector('img');
const willRemove = !!commentIndicatorEl;
let meta = {};
if (willRemove) {
meta = {
x: parseInt(commentIndicatorEl.style.left, 10),
y: parseInt(commentIndicatorEl.style.top, 10),
image: {
width: imageEl.width,
height: imageEl.height,
},
};
commentIndicatorEl.remove();
}
return Object.assign({}, meta, {
removed: willRemove,
});
}
export function showCommentIndicator(imageFrameEl, coordinate) {
const { x, y } = coordinate;
const commentIndicatorEl = imageFrameEl.querySelector('.comment-indicator');
if (commentIndicatorEl) {
commentIndicatorEl.style.left = `${x}px`;
commentIndicatorEl.style.top = `${y}px`;
} else {
addCommentIndicator(imageFrameEl, coordinate);
}
}
export function commentIndicatorOnClick(event) {
// Prevent from triggering onAddImageDiffNote in notes.js
event.stopPropagation();
const buttonEl = event.currentTarget;
const diffViewerEl = buttonEl.closest('.diff-viewer');
const textareaEl = diffViewerEl.querySelector('.note-container .note-textarea');
textareaEl.focus();
}