Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorConstance Okoghenun <cokoghenun@gitlab.com>2018-02-27 22:35:30 +0300
committerConstance Okoghenun <cokoghenun@gitlab.com>2018-02-27 22:35:30 +0300
commitcfe4c4d984c7eeea3f374a4d4d709810aac6986b (patch)
tree8de5e4cf38aae4490e6284efd0d48b49ce5a1b3a /app
parente7c8f8fb43d2d56c3db7cd09787f4c32077afc4a (diff)
parentd4867c518f2d72125c619c191fa9577dabb1ae9a (diff)
Resolved conflicts in dispatcher.js
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/boards/index.js10
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js2
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_bundle.js4
-rw-r--r--app/assets/javascripts/dispatcher.js232
-rw-r--r--app/assets/javascripts/environments/components/environments_table.vue2
-rw-r--r--app/assets/javascripts/environments/folder/environments_folder_bundle.js4
-rw-r--r--app/assets/javascripts/ide/components/repo_file.vue6
-rw-r--r--app/assets/javascripts/ide/components/repo_tab.vue2
-rw-r--r--app/assets/javascripts/labels_select.js6
-rw-r--r--app/assets/javascripts/network/network_bundle.js17
-rw-r--r--app/assets/javascripts/pages/admin/abuse_reports/index.js2
-rw-r--r--app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js4
-rw-r--r--app/assets/javascripts/pages/admin/broadcast_messages/index.js2
-rw-r--r--app/assets/javascripts/pages/admin/cohorts/index.js2
-rw-r--r--app/assets/javascripts/pages/admin/groups/show/index.js2
-rw-r--r--app/assets/javascripts/pages/admin/labels/edit/index.js2
-rw-r--r--app/assets/javascripts/pages/admin/labels/new/index.js2
-rw-r--r--app/assets/javascripts/pages/admin/projects/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/commit/pipelines/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/commit/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/compare/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/environments/folder/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/issues/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/conflicts/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/conflicts/show/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/creations/new/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/show/index.js6
-rw-r--r--app/assets/javascripts/pages/projects/network/network.js (renamed from app/assets/javascripts/network/network.js)2
-rw-r--r--app/assets/javascripts/pages/projects/network/show/index.js16
-rw-r--r--app/assets/javascripts/pages/projects/new/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/pipelines/index/index.js (renamed from app/assets/javascripts/pipelines/pipelines_bundle.js)6
-rw-r--r--app/assets/javascripts/pages/projects/wikis/index.js4
-rw-r--r--app/assets/javascripts/pipelines/services/pipelines_service.js1
-rw-r--r--app/assets/javascripts/sidebar/sidebar_bundle.js8
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue6
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/index.js4
-rw-r--r--app/assets/stylesheets/pages/commits.scss8
-rw-r--r--app/controllers/admin/groups_controller.rb2
-rw-r--r--app/controllers/concerns/membership_actions.rb64
-rw-r--r--app/controllers/groups/application_controller.rb4
-rw-r--r--app/controllers/groups/group_members_controller.rb29
-rw-r--r--app/controllers/groups_controller.rb1
-rw-r--r--app/controllers/projects/project_members_controller.rb29
-rw-r--r--app/helpers/groups_helper.rb18
-rw-r--r--app/models/chat_name.rb21
-rw-r--r--app/models/ci/group_variable.rb5
-rw-r--r--app/models/ci/variable.rb5
-rw-r--r--app/models/concerns/access_requestable.rb2
-rw-r--r--app/models/member.rb10
-rw-r--r--app/models/project_services/slash_commands_service.rb6
-rw-r--r--app/models/user.rb2
-rw-r--r--app/services/chat_names/find_user_service.rb4
-rw-r--r--app/services/members/approve_access_request_service.rb45
-rw-r--r--app/services/members/authorized_destroy_service.rb61
-rw-r--r--app/services/members/base_service.rb49
-rw-r--r--app/services/members/create_service.rb15
-rw-r--r--app/services/members/destroy_service.rb77
-rw-r--r--app/services/members/request_access_service.rb13
-rw-r--r--app/services/members/update_service.rb16
-rw-r--r--app/validators/variable_duplicates_validator.rb2
-rw-r--r--app/views/groups/group_members/update.js.haml4
-rw-r--r--app/views/groups/issues.html.haml7
-rw-r--r--app/views/groups/merge_requests.html.haml2
-rw-r--r--app/views/layouts/nav/sidebar/_group.html.haml5
-rw-r--r--app/views/projects/commit/_pipelines_list.haml1
-rw-r--r--app/views/projects/commit/show.html.haml1
-rw-r--r--app/views/projects/commits/_commit.html.haml2
-rw-r--r--app/views/projects/environments/folder.html.haml1
-rw-r--r--app/views/projects/merge_requests/show.html.haml3
-rw-r--r--app/views/projects/network/show.html.haml2
-rw-r--r--app/views/projects/pipelines/index.html.haml3
-rw-r--r--app/views/projects/project_members/update.js.haml4
-rw-r--r--app/views/projects/services/prometheus/_configuration_banner.html.haml26
-rw-r--r--app/views/projects/services/prometheus/_help.html.haml28
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml1
-rw-r--r--app/views/shared/members/update.js.haml6
-rw-r--r--app/workers/remove_expired_members_worker.rb2
78 files changed, 443 insertions, 530 deletions
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index 06a8abea940..8e31f1865f0 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -2,11 +2,13 @@
import _ from 'underscore';
import Vue from 'vue';
-import Flash from '../flash';
-import { __ } from '../locale';
+
+import Flash from '~/flash';
+import { __ } from '~/locale';
+
import FilteredSearchBoards from './filtered_search_boards';
import eventHub from './eventhub';
-import sidebarEventHub from '../sidebar/event_hub';
+import sidebarEventHub from '~/sidebar/event_hub'; // eslint-disable-line import/first
import './models/issue';
import './models/label';
import './models/list';
@@ -22,7 +24,7 @@ import './components/board';
import './components/board_sidebar';
import './components/new_list_dropdown';
import './components/modal/index';
-import '../vue_shared/vue_resource_interceptor';
+import '~/vue_shared/vue_resource_interceptor'; // eslint-disable-line import/first
export default () => {
const $boardApp = document.getElementById('board-app');
diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js
index 798d7e0d147..348cdeec737 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js
+++ b/app/assets/javascripts/boards/stores/boards_store.js
@@ -2,7 +2,7 @@
/* global List */
import _ from 'underscore';
import Cookies from 'js-cookie';
-import { getUrlParamsArray } from '../../lib/utils/common_utils';
+import { getUrlParamsArray } from '~/lib/utils/common_utils';
window.gl = window.gl || {};
window.gl.issueBoards = window.gl.issueBoards || {};
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js
index 1f9153d95bd..3d89bf1316e 100644
--- a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js
+++ b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js
@@ -15,7 +15,7 @@ const CommitPipelinesTable = Vue.extend(commitPipelinesTable);
window.gl = window.gl || {};
window.gl.CommitPipelinesTable = CommitPipelinesTable;
-document.addEventListener('DOMContentLoaded', () => {
+export default () => {
const pipelineTableViewEl = document.querySelector('#commit-pipeline-table-view');
if (pipelineTableViewEl) {
@@ -43,4 +43,4 @@ document.addEventListener('DOMContentLoaded', () => {
pipelineTableViewEl.appendChild(table.$el);
}
}
-});
+};
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 95ba00bb49a..1ccf96a75dc 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -6,172 +6,80 @@ import GlFieldErrors from './gl_field_errors';
import Shortcuts from './shortcuts';
import SearchAutocomplete from './search_autocomplete';
-var Dispatcher;
-
-(function() {
- Dispatcher = (function() {
- function Dispatcher() {
- this.initSearch();
- this.initFieldErrors();
- this.initPageScripts();
- }
-
- Dispatcher.prototype.initPageScripts = function() {
- var path, shortcut_handler;
- const page = $('body').attr('data-page');
- if (!page) {
- return false;
- }
-
- const fail = () => Flash('Error loading dynamic module');
- const callDefault = m => m.default();
-
- path = page.split(':');
- shortcut_handler = null;
-
- $('.js-gfm-input:not(.js-vue-textarea)').each((i, el) => {
- const gfm = new GfmAutoComplete(gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources);
- const enableGFM = convertPermissionToBoolean(el.dataset.supportsAutocomplete);
- gfm.setup($(el), {
- emojis: true,
- members: enableGFM,
- issues: enableGFM,
- milestones: enableGFM,
- mergeRequests: enableGFM,
- labels: enableGFM,
- });
- });
-
- const shortcutHandlerPages = [
- 'projects:activity',
- 'projects:artifacts:browse',
- 'projects:artifacts:file',
- 'projects:blame:show',
- 'projects:blob:show',
- 'projects:commit:show',
- 'projects:commits:show',
- 'projects:find_file:show',
- 'projects:issues:edit',
- 'projects:issues:index',
- 'projects:issues:new',
- 'projects:issues:show',
- 'projects:merge_requests:creations:diffs',
- 'projects:merge_requests:creations:new',
- 'projects:merge_requests:edit',
- 'projects:merge_requests:index',
- 'projects:merge_requests:show',
- 'projects:network:show',
- 'projects:show',
- 'projects:tree:show',
- 'groups:show',
- ];
+function initSearch() {
+ // Only when search form is present
+ if ($('.search').length) {
+ return new SearchAutocomplete();
+ }
+}
- if (shortcutHandlerPages.indexOf(page) !== -1) {
- shortcut_handler = true;
- }
+function initFieldErrors() {
+ $('.gl-show-field-errors').each((i, form) => {
+ new GlFieldErrors(form);
+ });
+}
- switch (path[0]) {
- case 'admin':
- switch (path[1]) {
- case 'broadcast_messages':
- import('./pages/admin/broadcast_messages')
- .then(callDefault)
- .catch(fail);
- break;
- case 'cohorts':
- import('./pages/admin/cohorts')
- .then(callDefault)
- .catch(fail);
- break;
- case 'groups':
- switch (path[2]) {
- case 'show':
- import('./pages/admin/groups/show')
- .then(callDefault)
- .catch(fail);
- break;
- }
- break;
- case 'projects':
- import('./pages/admin/projects')
- .then(callDefault)
- .catch(fail);
- break;
- case 'labels':
- switch (path[2]) {
- case 'new':
- import('./pages/admin/labels/new')
- .then(callDefault)
- .catch(fail);
- break;
- case 'edit':
- import('./pages/admin/labels/edit')
- .then(callDefault)
- .catch(fail);
- break;
- }
- case 'abuse_reports':
- import('./pages/admin/abuse_reports')
- .then(callDefault)
- .catch(fail);
- break;
- }
- break;
- case 'projects':
- import('./pages/projects')
- .then(callDefault)
- .catch(fail);
- shortcut_handler = true;
- switch (path[1]) {
- case 'compare':
- import('./pages/projects/compare')
- .then(callDefault)
- .catch(fail);
- break;
- case 'create':
- case 'new':
- import('./pages/projects/new')
- .then(callDefault)
- .catch(fail);
- break;
- case 'wikis':
- import('./pages/projects/wikis')
- .then(callDefault)
- .catch(fail);
- shortcut_handler = true;
- break;
- }
- break;
- }
- // If we haven't installed a custom shortcut handler, install the default one
- if (!shortcut_handler) {
- new Shortcuts();
- }
+function initPageShortcuts(page) {
+ const pagesWithCustomShortcuts = [
+ 'projects:activity',
+ 'projects:artifacts:browse',
+ 'projects:artifacts:file',
+ 'projects:blame:show',
+ 'projects:blob:show',
+ 'projects:commit:show',
+ 'projects:commits:show',
+ 'projects:find_file:show',
+ 'projects:issues:edit',
+ 'projects:issues:index',
+ 'projects:issues:new',
+ 'projects:issues:show',
+ 'projects:merge_requests:creations:diffs',
+ 'projects:merge_requests:creations:new',
+ 'projects:merge_requests:edit',
+ 'projects:merge_requests:index',
+ 'projects:merge_requests:show',
+ 'projects:network:show',
+ 'projects:show',
+ 'projects:tree:show',
+ 'groups:show',
+ ];
- if (document.querySelector('#peek')) {
- import('./performance_bar')
- .then(m => new m.default({ container: '#peek' })) // eslint-disable-line new-cap
- .catch(fail);
- }
- };
+ if (pagesWithCustomShortcuts.indexOf(page) === -1) {
+ new Shortcuts();
+ }
+}
- Dispatcher.prototype.initSearch = function() {
- // Only when search form is present
- if ($('.search').length) {
- return new SearchAutocomplete();
- }
- };
+function initGFMInput() {
+ $('.js-gfm-input:not(.js-vue-textarea)').each((i, el) => {
+ const gfm = new GfmAutoComplete(gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources);
+ const enableGFM = convertPermissionToBoolean(el.dataset.supportsAutocomplete);
+ gfm.setup($(el), {
+ emojis: true,
+ members: enableGFM,
+ issues: enableGFM,
+ milestones: enableGFM,
+ mergeRequests: enableGFM,
+ labels: enableGFM,
+ });
+ });
+}
- Dispatcher.prototype.initFieldErrors = function() {
- $('.gl-show-field-errors').each((i, form) => {
- new GlFieldErrors(form);
- });
- };
+function initPerformanceBar() {
+ if (document.querySelector('#peek')) {
+ import('./performance_bar')
+ .then(m => new m.default({ container: '#peek' })) // eslint-disable-line new-cap
+ .catch(() => Flash('Error loading performance bar module'));
+ }
+}
- return Dispatcher;
- })();
-})();
+export default () => {
+ initSearch();
+ initFieldErrors();
-export default function initDispatcher() {
- return new Dispatcher();
-}
+ const page = $('body').attr('data-page');
+ if (page) {
+ initPageShortcuts(page);
+ initGFMInput();
+ initPerformanceBar();
+ }
+};
diff --git a/app/assets/javascripts/environments/components/environments_table.vue b/app/assets/javascripts/environments/components/environments_table.vue
index b4eca47957e..22863e926d4 100644
--- a/app/assets/javascripts/environments/components/environments_table.vue
+++ b/app/assets/javascripts/environments/components/environments_table.vue
@@ -2,8 +2,8 @@
/**
* Render environments table.
*/
+import loadingIcon from '~/vue_shared/components/loading_icon.vue';
import environmentItem from './environment_item.vue';
-import loadingIcon from '../../vue_shared/components/loading_icon.vue';
export default {
components: {
diff --git a/app/assets/javascripts/environments/folder/environments_folder_bundle.js b/app/assets/javascripts/environments/folder/environments_folder_bundle.js
index 5d2d14c7682..de0fbdb2e91 100644
--- a/app/assets/javascripts/environments/folder/environments_folder_bundle.js
+++ b/app/assets/javascripts/environments/folder/environments_folder_bundle.js
@@ -5,7 +5,7 @@ import Translate from '../../vue_shared/translate';
Vue.use(Translate);
-document.addEventListener('DOMContentLoaded', () => new Vue({
+export default () => new Vue({
el: '#environments-folder-list-view',
components: {
environmentsFolderApp,
@@ -32,4 +32,4 @@ document.addEventListener('DOMContentLoaded', () => new Vue({
},
});
},
-}));
+});
diff --git a/app/assets/javascripts/ide/components/repo_file.vue b/app/assets/javascripts/ide/components/repo_file.vue
index 110918872fb..cbbab765e1c 100644
--- a/app/assets/javascripts/ide/components/repo_file.vue
+++ b/app/assets/javascripts/ide/components/repo_file.vue
@@ -1,9 +1,9 @@
<script>
import { mapState } from 'vuex';
- import timeAgoMixin from '../../vue_shared/mixins/timeago';
- import skeletonLoadingContainer from '../../vue_shared/components/skeleton_loading_container.vue';
+ import timeAgoMixin from '~/vue_shared/mixins/timeago';
+ import skeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue';
+ import fileIcon from '~/vue_shared/components/file_icon.vue';
import newDropdown from './new_dropdown/index.vue';
- import fileIcon from '../../vue_shared/components/file_icon.vue';
export default {
components: {
diff --git a/app/assets/javascripts/ide/components/repo_tab.vue b/app/assets/javascripts/ide/components/repo_tab.vue
index 5ed7bddf6ae..5656081c598 100644
--- a/app/assets/javascripts/ide/components/repo_tab.vue
+++ b/app/assets/javascripts/ide/components/repo_tab.vue
@@ -1,6 +1,6 @@
<script>
import { mapActions } from 'vuex';
- import fileIcon from '../../vue_shared/components/file_icon.vue';
+ import fileIcon from '~/vue_shared/components/file_icon.vue';
export default {
components: {
diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js
index 7151ac05a09..89a246f56cf 100644
--- a/app/assets/javascripts/labels_select.js
+++ b/app/assets/javascripts/labels_select.js
@@ -242,10 +242,16 @@ export default class LabelsSelect {
filterable: true,
selected: $dropdown.data('selected') || [],
toggleLabel: function(selected, el) {
+ var $dropdownParent = $dropdown.parent();
+ var $dropdownInputField = $dropdownParent.find('.dropdown-input-field');
var isSelected = el !== null ? el.hasClass('is-active') : false;
var title = selected.title;
var selectedLabels = this.selected;
+ if ($dropdownInputField.length && $dropdownInputField.val().length) {
+ $dropdownParent.find('.dropdown-input-clear').trigger('click');
+ }
+
if (selected.id === 0) {
this.selected = [];
return 'No Label';
diff --git a/app/assets/javascripts/network/network_bundle.js b/app/assets/javascripts/network/network_bundle.js
deleted file mode 100644
index 129f1724cb8..00000000000
--- a/app/assets/javascripts/network/network_bundle.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/* eslint-disable func-names, space-before-function-paren, prefer-arrow-callback, quotes, no-var, vars-on-top, camelcase, comma-dangle, consistent-return, max-len */
-
-import ShortcutsNetwork from '../shortcuts_network';
-import Network from './network';
-
-$(function() {
- if (!$(".network-graph").length) return;
-
- var network_graph;
- network_graph = new Network({
- url: $(".network-graph").attr('data-url'),
- commit_url: $(".network-graph").attr('data-commit-url'),
- ref: $(".network-graph").attr('data-ref'),
- commit_id: $(".network-graph").attr('data-commit-id')
- });
- return new ShortcutsNetwork(network_graph.branch_graph);
-});
diff --git a/app/assets/javascripts/pages/admin/abuse_reports/index.js b/app/assets/javascripts/pages/admin/abuse_reports/index.js
index c0b6e8d4095..d76b1f174fc 100644
--- a/app/assets/javascripts/pages/admin/abuse_reports/index.js
+++ b/app/assets/javascripts/pages/admin/abuse_reports/index.js
@@ -1,3 +1,3 @@
import AbuseReports from './abuse_reports';
-export default () => new AbuseReports();
+document.addEventListener('DOMContentLoaded', () => new AbuseReports());
diff --git a/app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js b/app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js
index b68ce5d32d8..f92450cbaa7 100644
--- a/app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js
+++ b/app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js
@@ -3,7 +3,7 @@ import axios from '~/lib/utils/axios_utils';
import flash from '~/flash';
import { __ } from '~/locale';
-export default function initBroadcastMessagesForm() {
+export default () => {
$('input#broadcast_message_color').on('input', function onMessageColorInput() {
const previewColor = $(this).val();
$('div.broadcast-message-preview').css('background-color', previewColor);
@@ -32,4 +32,4 @@ export default function initBroadcastMessagesForm() {
.catch(() => flash(__('An error occurred while rendering preview broadcast message')));
}
}, 250));
-}
+};
diff --git a/app/assets/javascripts/pages/admin/broadcast_messages/index.js b/app/assets/javascripts/pages/admin/broadcast_messages/index.js
index b548c48282a..d6cc6a850eb 100644
--- a/app/assets/javascripts/pages/admin/broadcast_messages/index.js
+++ b/app/assets/javascripts/pages/admin/broadcast_messages/index.js
@@ -1,3 +1,3 @@
import initBroadcastMessagesForm from './broadcast_message';
-export default () => initBroadcastMessagesForm();
+document.addEventListener('DOMContentLoaded', initBroadcastMessagesForm);
diff --git a/app/assets/javascripts/pages/admin/cohorts/index.js b/app/assets/javascripts/pages/admin/cohorts/index.js
index 42ef9d38ef7..2d5020dbef4 100644
--- a/app/assets/javascripts/pages/admin/cohorts/index.js
+++ b/app/assets/javascripts/pages/admin/cohorts/index.js
@@ -1,3 +1,3 @@
import initUsagePing from './usage_ping';
-export default () => initUsagePing();
+document.addEventListener('DOMContentLoaded', initUsagePing);
diff --git a/app/assets/javascripts/pages/admin/groups/show/index.js b/app/assets/javascripts/pages/admin/groups/show/index.js
index 5defea104d4..b0cdad627a6 100644
--- a/app/assets/javascripts/pages/admin/groups/show/index.js
+++ b/app/assets/javascripts/pages/admin/groups/show/index.js
@@ -1,3 +1,3 @@
import UsersSelect from '../../../../users_select';
-export default () => new UsersSelect();
+document.addEventListener('DOMContentLoaded', () => new UsersSelect());
diff --git a/app/assets/javascripts/pages/admin/labels/edit/index.js b/app/assets/javascripts/pages/admin/labels/edit/index.js
index d7ec6e47f67..5de1d4d6344 100644
--- a/app/assets/javascripts/pages/admin/labels/edit/index.js
+++ b/app/assets/javascripts/pages/admin/labels/edit/index.js
@@ -1,3 +1,3 @@
import Labels from '../../../../labels';
-export default () => new Labels();
+document.addEventListener('DOMContentLoaded', () => new Labels());
diff --git a/app/assets/javascripts/pages/admin/labels/new/index.js b/app/assets/javascripts/pages/admin/labels/new/index.js
index d7ec6e47f67..5de1d4d6344 100644
--- a/app/assets/javascripts/pages/admin/labels/new/index.js
+++ b/app/assets/javascripts/pages/admin/labels/new/index.js
@@ -1,3 +1,3 @@
import Labels from '../../../../labels';
-export default () => new Labels();
+document.addEventListener('DOMContentLoaded', () => new Labels());
diff --git a/app/assets/javascripts/pages/admin/projects/index.js b/app/assets/javascripts/pages/admin/projects/index.js
index 71e0ddcd7b6..31c96eb87af 100644
--- a/app/assets/javascripts/pages/admin/projects/index.js
+++ b/app/assets/javascripts/pages/admin/projects/index.js
@@ -1,9 +1,9 @@
import ProjectsList from '../../../projects_list';
import NamespaceSelect from '../../../namespace_select';
-export default () => {
+document.addEventListener('DOMContentLoaded', () => {
new ProjectsList(); // eslint-disable-line no-new
document.querySelectorAll('.js-namespace-select')
.forEach(dropdown => new NamespaceSelect({ dropdown }));
-};
+});
diff --git a/app/assets/javascripts/pages/projects/commit/pipelines/index.js b/app/assets/javascripts/pages/projects/commit/pipelines/index.js
index 7889704a324..cd923f13ce8 100644
--- a/app/assets/javascripts/pages/projects/commit/pipelines/index.js
+++ b/app/assets/javascripts/pages/projects/commit/pipelines/index.js
@@ -1,8 +1,10 @@
import MiniPipelineGraph from '~/mini_pipeline_graph_dropdown';
+import initPipelines from '~/commit/pipelines/pipelines_bundle';
document.addEventListener('DOMContentLoaded', () => {
new MiniPipelineGraph({
container: '.js-commit-pipeline-graph',
}).bindEvents();
$('.commit-info.branches').load(document.querySelector('.js-commit-box').dataset.commitPath);
+ initPipelines();
});
diff --git a/app/assets/javascripts/pages/projects/commit/show/index.js b/app/assets/javascripts/pages/projects/commit/show/index.js
index 460a54ab504..1aeed197385 100644
--- a/app/assets/javascripts/pages/projects/commit/show/index.js
+++ b/app/assets/javascripts/pages/projects/commit/show/index.js
@@ -5,6 +5,7 @@ import ShortcutsNavigation from '~/shortcuts_navigation';
import MiniPipelineGraph from '~/mini_pipeline_graph_dropdown';
import initNotes from '~/init_notes';
import initChangesDropdown from '~/init_changes_dropdown';
+import initDiffNotes from '~/diff_notes/diff_notes_bundle';
import { fetchCommitMergeRequests } from '~/commit_merge_requests';
document.addEventListener('DOMContentLoaded', () => {
@@ -19,4 +20,5 @@ document.addEventListener('DOMContentLoaded', () => {
initChangesDropdown(document.querySelector('.navbar-gitlab').offsetHeight - stickyBarPaddingTop);
$('.commit-info.branches').load(document.querySelector('.js-commit-box').dataset.commitPath);
fetchCommitMergeRequests();
+ initDiffNotes();
});
diff --git a/app/assets/javascripts/pages/projects/compare/index.js b/app/assets/javascripts/pages/projects/compare/index.js
index 890062eeee6..d1c78bd61db 100644
--- a/app/assets/javascripts/pages/projects/compare/index.js
+++ b/app/assets/javascripts/pages/projects/compare/index.js
@@ -1,5 +1,3 @@
import initCompareAutocomplete from '~/compare_autocomplete';
-export default () => {
- initCompareAutocomplete();
-};
+document.addEventListener('DOMContentLoaded', initCompareAutocomplete);
diff --git a/app/assets/javascripts/pages/projects/environments/folder/index.js b/app/assets/javascripts/pages/projects/environments/folder/index.js
new file mode 100644
index 00000000000..5feaf944038
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/environments/folder/index.js
@@ -0,0 +1,3 @@
+import initEnvironmentsFolderBundle from '~/environments/folder/environments_folder_bundle';
+
+document.addEventListener('DOMContentLoaded', initEnvironmentsFolderBundle);
diff --git a/app/assets/javascripts/pages/projects/index.js b/app/assets/javascripts/pages/projects/index.js
index 9b1d52692a3..de1e13de7e9 100644
--- a/app/assets/javascripts/pages/projects/index.js
+++ b/app/assets/javascripts/pages/projects/index.js
@@ -1,7 +1,7 @@
import Project from './project';
import ShortcutsNavigation from '../../shortcuts_navigation';
-export default () => {
+document.addEventListener('DOMContentLoaded', () => {
new Project(); // eslint-disable-line no-new
new ShortcutsNavigation(); // eslint-disable-line no-new
-};
+});
diff --git a/app/assets/javascripts/pages/projects/issues/show/index.js b/app/assets/javascripts/pages/projects/issues/show/index.js
index 1e56aa58da2..3950fe0a1fd 100644
--- a/app/assets/javascripts/pages/projects/issues/show/index.js
+++ b/app/assets/javascripts/pages/projects/issues/show/index.js
@@ -1,4 +1,5 @@
import initIssuableSidebar from '~/init_issuable_sidebar';
+import initSidebarBundle from '~/sidebar/sidebar_bundle';
import Issue from '~/issue';
import ShortcutsIssuable from '~/shortcuts_issuable';
import ZenMode from '~/zen_mode';
@@ -10,4 +11,5 @@ document.addEventListener('DOMContentLoaded', () => {
new ShortcutsIssuable(); // eslint-disable-line no-new
new ZenMode(); // eslint-disable-line no-new
initIssuableSidebar();
+ initSidebarBundle();
});
diff --git a/app/assets/javascripts/pages/projects/merge_requests/conflicts/index.js b/app/assets/javascripts/pages/projects/merge_requests/conflicts/index.js
new file mode 100644
index 00000000000..b92aef53510
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/merge_requests/conflicts/index.js
@@ -0,0 +1,3 @@
+import initSidebarBundle from '~/sidebar/sidebar_bundle';
+
+document.addEventListener('DOMContentLoaded', initSidebarBundle);
diff --git a/app/assets/javascripts/pages/projects/merge_requests/conflicts/show/index.js b/app/assets/javascripts/pages/projects/merge_requests/conflicts/show/index.js
new file mode 100644
index 00000000000..b92aef53510
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/merge_requests/conflicts/show/index.js
@@ -0,0 +1,3 @@
+import initSidebarBundle from '~/sidebar/sidebar_bundle';
+
+document.addEventListener('DOMContentLoaded', initSidebarBundle);
diff --git a/app/assets/javascripts/pages/projects/merge_requests/creations/new/index.js b/app/assets/javascripts/pages/projects/merge_requests/creations/new/index.js
index 1d5aec4001d..6c9afddefac 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/creations/new/index.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/creations/new/index.js
@@ -1,5 +1,6 @@
import Compare from '~/compare';
import MergeRequest from '~/merge_request';
+import initPipelines from '~/commit/pipelines/pipelines_bundle';
document.addEventListener('DOMContentLoaded', () => {
const mrNewCompareNode = document.querySelector('.js-merge-request-new-compare');
@@ -14,5 +15,6 @@ document.addEventListener('DOMContentLoaded', () => {
new MergeRequest({ // eslint-disable-line no-new
action: mrNewSubmitNode.dataset.mrSubmitAction,
});
+ initPipelines();
}
});
diff --git a/app/assets/javascripts/pages/projects/merge_requests/show/index.js b/app/assets/javascripts/pages/projects/merge_requests/show/index.js
index 07f3e579c97..b7b6b0b5364 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/show/index.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/show/index.js
@@ -3,18 +3,23 @@ import ZenMode from '~/zen_mode';
import initNotes from '~/init_notes';
import initIssuableSidebar from '~/init_issuable_sidebar';
import initDiffNotes from '~/diff_notes/diff_notes_bundle';
+import initSidebarBundle from '~/sidebar/sidebar_bundle';
import ShortcutsIssuable from '~/shortcuts_issuable';
import Diff from '~/diff';
import { handleLocationHash } from '~/lib/utils/common_utils';
import howToMerge from '~/how_to_merge';
+import initPipelines from '~/commit/pipelines/pipelines_bundle';
+import initWidget from '../../../../vue_merge_request_widget';
document.addEventListener('DOMContentLoaded', () => {
new Diff(); // eslint-disable-line no-new
new ZenMode(); // eslint-disable-line no-new
initIssuableSidebar();
+ initSidebarBundle();
initNotes();
initDiffNotes();
+ initPipelines();
const mrShowNode = document.querySelector('.merge-request');
@@ -25,4 +30,5 @@ document.addEventListener('DOMContentLoaded', () => {
new ShortcutsIssuable(true); // eslint-disable-line no-new
handleLocationHash();
howToMerge();
+ initWidget();
});
diff --git a/app/assets/javascripts/network/network.js b/app/assets/javascripts/pages/projects/network/network.js
index a3fd22aff2a..7354243e4c8 100644
--- a/app/assets/javascripts/network/network.js
+++ b/app/assets/javascripts/pages/projects/network/network.js
@@ -1,6 +1,6 @@
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, quotes, quote-props, prefer-template, comma-dangle, max-len */
-import BranchGraph from './branch_graph';
+import BranchGraph from '../../../network/branch_graph';
export default (function() {
function Network(opts) {
diff --git a/app/assets/javascripts/pages/projects/network/show/index.js b/app/assets/javascripts/pages/projects/network/show/index.js
new file mode 100644
index 00000000000..e7dfd2d0128
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/network/show/index.js
@@ -0,0 +1,16 @@
+import ShortcutsNetwork from '../../../../shortcuts_network';
+import Network from '../network';
+
+document.addEventListener('DOMContentLoaded', () => {
+ if (!$('.network-graph').length) return;
+
+ const networkGraph = new Network({
+ url: $('.network-graph').attr('data-url'),
+ commit_url: $('.network-graph').attr('data-commit-url'),
+ ref: $('.network-graph').attr('data-ref'),
+ commit_id: $('.network-graph').attr('data-commit-id'),
+ });
+
+ // eslint-disable-next-line no-new
+ new ShortcutsNetwork(networkGraph.branch_graph);
+});
diff --git a/app/assets/javascripts/pages/projects/new/index.js b/app/assets/javascripts/pages/projects/new/index.js
index 71c49deb9d0..ea6fd961393 100644
--- a/app/assets/javascripts/pages/projects/new/index.js
+++ b/app/assets/javascripts/pages/projects/new/index.js
@@ -2,8 +2,8 @@ import ProjectNew from '../shared/project_new';
import initProjectVisibilitySelector from '../../../project_visibility';
import initProjectNew from '../../../projects/project_new';
-export default () => {
+document.addEventListener('DOMContentLoaded', () => {
new ProjectNew(); // eslint-disable-line no-new
initProjectVisibilitySelector();
initProjectNew.bindEvents();
-};
+});
diff --git a/app/assets/javascripts/pipelines/pipelines_bundle.js b/app/assets/javascripts/pages/projects/pipelines/index/index.js
index ab5596e70f0..25dfa99ad9c 100644
--- a/app/assets/javascripts/pipelines/pipelines_bundle.js
+++ b/app/assets/javascripts/pages/projects/pipelines/index/index.js
@@ -1,7 +1,7 @@
import Vue from 'vue';
-import PipelinesStore from './stores/pipelines_store';
-import pipelinesComponent from './components/pipelines.vue';
-import Translate from '../vue_shared/translate';
+import PipelinesStore from '../../../../pipelines/stores/pipelines_store';
+import pipelinesComponent from '../../../../pipelines/components/pipelines.vue';
+import Translate from '../../../../vue_shared/translate';
Vue.use(Translate);
diff --git a/app/assets/javascripts/pages/projects/wikis/index.js b/app/assets/javascripts/pages/projects/wikis/index.js
index eb14c7a0e78..b9f8707fd6e 100644
--- a/app/assets/javascripts/pages/projects/wikis/index.js
+++ b/app/assets/javascripts/pages/projects/wikis/index.js
@@ -3,9 +3,9 @@ import ShortcutsWiki from '../../../shortcuts_wiki';
import ZenMode from '../../../zen_mode';
import GLForm from '../../../gl_form';
-export default () => {
+document.addEventListener('DOMContentLoaded', () => {
new Wikis(); // eslint-disable-line no-new
new ShortcutsWiki(); // eslint-disable-line no-new
new ZenMode(); // eslint-disable-line no-new
new GLForm($('.wiki-form'), true); // eslint-disable-line no-new
-};
+});
diff --git a/app/assets/javascripts/pipelines/services/pipelines_service.js b/app/assets/javascripts/pipelines/services/pipelines_service.js
index e2285494e62..47736fc5f42 100644
--- a/app/assets/javascripts/pipelines/services/pipelines_service.js
+++ b/app/assets/javascripts/pipelines/services/pipelines_service.js
@@ -1,6 +1,7 @@
/* eslint-disable class-methods-use-this */
import Vue from 'vue';
import VueResource from 'vue-resource';
+import '../../vue_shared/vue_resource_interceptor';
Vue.use(VueResource);
diff --git a/app/assets/javascripts/sidebar/sidebar_bundle.js b/app/assets/javascripts/sidebar/sidebar_bundle.js
index 04c39d7b6b5..377846db70e 100644
--- a/app/assets/javascripts/sidebar/sidebar_bundle.js
+++ b/app/assets/javascripts/sidebar/sidebar_bundle.js
@@ -1,13 +1,9 @@
import Mediator from './sidebar_mediator';
import { mountSidebar, getSidebarOptions } from './mount_sidebar';
-function domContentLoaded() {
+export default () => {
const mediator = new Mediator(getSidebarOptions());
mediator.fetch();
mountSidebar(mediator);
-}
-
-document.addEventListener('DOMContentLoaded', domContentLoaded);
-
-export default domContentLoaded;
+};
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
index 109a302a172..54a98abf860 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
@@ -1,8 +1,8 @@
<script>
/* eslint-disable vue/require-default-prop */
- import pipelineStage from '../../pipelines/components/stage.vue';
- import ciIcon from '../../vue_shared/components/ci_icon.vue';
- import icon from '../../vue_shared/components/icon.vue';
+ import pipelineStage from '~/pipelines/components/stage.vue';
+ import ciIcon from '~/vue_shared/components/ci_icon.vue';
+ import icon from '~/vue_shared/components/icon.vue';
export default {
name: 'MRWidgetPipeline',
diff --git a/app/assets/javascripts/vue_merge_request_widget/index.js b/app/assets/javascripts/vue_merge_request_widget/index.js
index 6b9918b65b0..69a9132a2da 100644
--- a/app/assets/javascripts/vue_merge_request_widget/index.js
+++ b/app/assets/javascripts/vue_merge_request_widget/index.js
@@ -6,7 +6,7 @@ import Translate from '../vue_shared/translate';
Vue.use(Translate);
-document.addEventListener('DOMContentLoaded', () => {
+export default () => {
gl.mrWidgetData.gitlabLogo = gon.gitlab_logo;
const vm = new Vue(mrWidgetOptions);
@@ -14,4 +14,4 @@ document.addEventListener('DOMContentLoaded', () => {
window.gl.mrWidget = {
checkStatus: vm.checkStatus,
};
-});
+};
diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss
index 17801ed5910..8b680c2dc52 100644
--- a/app/assets/stylesheets/pages/commits.scss
+++ b/app/assets/stylesheets/pages/commits.scss
@@ -196,17 +196,9 @@
@media (min-width: $screen-sm-min) {
font-size: 0;
- div {
- display: inline;
- }
-
.fa-spinner {
font-size: 12px;
}
-
- span {
- font-size: 6px;
- }
}
.ci-status-link {
diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb
index a94726887d9..cc38608eda5 100644
--- a/app/controllers/admin/groups_controller.rb
+++ b/app/controllers/admin/groups_controller.rb
@@ -48,7 +48,7 @@ class Admin::GroupsController < Admin::ApplicationController
def members_update
member_params = params.permit(:user_ids, :access_level, :expires_at)
- result = Members::CreateService.new(@group, current_user, member_params.merge(limit: -1)).execute
+ result = Members::CreateService.new(current_user, member_params.merge(limit: -1)).execute(@group)
if result[:status] == :success
redirect_to [:admin, @group], notice: 'Users were successfully added.'
diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb
index c6b1e443de6..7a6a00b8e13 100644
--- a/app/controllers/concerns/membership_actions.rb
+++ b/app/controllers/concerns/membership_actions.rb
@@ -3,20 +3,31 @@ module MembershipActions
def create
create_params = params.permit(:user_ids, :access_level, :expires_at)
- result = Members::CreateService.new(membershipable, current_user, create_params).execute
-
- redirect_url = members_page_url
+ result = Members::CreateService.new(current_user, create_params).execute(membershipable)
if result[:status] == :success
- redirect_to redirect_url, notice: 'Users were successfully added.'
+ redirect_to members_page_url, notice: 'Users were successfully added.'
else
- redirect_to redirect_url, alert: result[:message]
+ redirect_to members_page_url, alert: result[:message]
+ end
+ end
+
+ def update
+ update_params = params.require(root_params_key).permit(:access_level, :expires_at)
+ member = membershipable.members_and_requesters.find(params[:id])
+ member = Members::UpdateService
+ .new(current_user, update_params)
+ .execute(member)
+ .present(current_user: current_user)
+
+ respond_to do |format|
+ format.js { render 'shared/members/update', locals: { member: member } }
end
end
def destroy
- Members::DestroyService.new(membershipable, current_user, params)
- .execute(:all)
+ member = membershipable.members_and_requesters.find(params[:id])
+ Members::DestroyService.new(current_user).execute(member)
respond_to do |format|
format.html do
@@ -36,14 +47,17 @@ module MembershipActions
end
def approve_access_request
- Members::ApproveAccessRequestService.new(membershipable, current_user, params).execute
+ access_requester = membershipable.requesters.find(params[:id])
+ Members::ApproveAccessRequestService
+ .new(current_user, params)
+ .execute(access_requester)
redirect_to members_page_url
end
def leave
- member = Members::DestroyService.new(membershipable, current_user, user_id: current_user.id)
- .execute(:all)
+ member = membershipable.members_and_requesters.find_by!(user_id: current_user.id)
+ Members::DestroyService.new(current_user).execute(member)
notice =
if member.request?
@@ -62,17 +76,43 @@ module MembershipActions
end
end
+ def resend_invite
+ member = membershipable.members.find(params[:id])
+
+ if member.invite?
+ member.resend_invite
+
+ redirect_to members_page_url, notice: 'The invitation was successfully resent.'
+ else
+ redirect_to members_page_url, alert: 'The invitation has already been accepted.'
+ end
+ end
+
protected
def membershipable
raise NotImplementedError
end
+ def root_params_key
+ case membershipable
+ when Namespace
+ :group_member
+ when Project
+ :project_member
+ else
+ raise "Unknown membershipable type: #{membershipable}!"
+ end
+ end
+
def members_page_url
- if membershipable.is_a?(Project)
+ case membershipable
+ when Namespace
+ polymorphic_url([membershipable, :members])
+ when Project
project_project_members_path(membershipable)
else
- polymorphic_url([membershipable, :members])
+ raise "Unknown membershipable type: #{membershipable}!"
end
end
diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb
index 4a2bfc1f887..9f3bb60b4cc 100644
--- a/app/controllers/groups/application_controller.rb
+++ b/app/controllers/groups/application_controller.rb
@@ -18,10 +18,6 @@ class Groups::ApplicationController < ApplicationController
@projects ||= GroupProjectsFinder.new(group: group, current_user: current_user).execute
end
- def group_merge_requests
- @group_merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id).execute
- end
-
def authorize_admin_group!
unless can?(current_user, :admin_group, group)
return render_404
diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb
index 2c371e76313..f210434b2d7 100644
--- a/app/controllers/groups/group_members_controller.rb
+++ b/app/controllers/groups/group_members_controller.rb
@@ -27,35 +27,6 @@ class Groups::GroupMembersController < Groups::ApplicationController
@group_member = @group.group_members.new
end
- def update
- @group_member = @group.members_and_requesters.find(params[:id])
- .present(current_user: current_user)
-
- return render_403 unless can?(current_user, :update_group_member, @group_member)
-
- @group_member.update_attributes(member_params)
- end
-
- def resend_invite
- redirect_path = group_group_members_path(@group)
-
- @group_member = @group.group_members.find(params[:id])
-
- if @group_member.invite?
- @group_member.resend_invite
-
- redirect_to redirect_path, notice: 'The invitation was successfully resent.'
- else
- redirect_to redirect_path, alert: 'The invitation has already been accepted.'
- end
- end
-
- protected
-
- def member_params
- params.require(:group_member).permit(:access_level, :user_id, :expires_at)
- end
-
# MembershipActions concern
alias_method :membershipable, :group
end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 14b9d6c22bd..283c3e5f1e0 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -14,7 +14,6 @@ class GroupsController < Groups::ApplicationController
before_action :authorize_create_group!, only: [:new]
before_action :group_projects, only: [:projects, :activity, :issues, :merge_requests]
- before_action :group_merge_requests, only: [:merge_requests]
before_action :event_filter, only: [:activity]
before_action :user_actions, only: [:show, :subgroups]
diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb
index d7372beb9d3..e9b4679f94c 100644
--- a/app/controllers/projects/project_members_controller.rb
+++ b/app/controllers/projects/project_members_controller.rb
@@ -26,29 +26,6 @@ class Projects::ProjectMembersController < Projects::ApplicationController
@project_member = @project.project_members.new
end
- def update
- @project_member = @project.members_and_requesters.find(params[:id])
- .present(current_user: current_user)
-
- return render_403 unless can?(current_user, :update_project_member, @project_member)
-
- @project_member.update_attributes(member_params)
- end
-
- def resend_invite
- redirect_path = project_project_members_path(@project)
-
- @project_member = @project.project_members.find(params[:id])
-
- if @project_member.invite?
- @project_member.resend_invite
-
- redirect_to redirect_path, notice: 'The invitation was successfully resent.'
- else
- redirect_to redirect_path, alert: 'The invitation has already been accepted.'
- end
- end
-
def import
@projects = current_user.authorized_projects.order_id_desc
end
@@ -67,12 +44,6 @@ class Projects::ProjectMembersController < Projects::ApplicationController
notice: notice)
end
- protected
-
- def member_params
- params.require(:project_member).permit(:user_id, :access_level, :expires_at)
- end
-
# MembershipActions concern
alias_method :membershipable, :project
end
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index 5fbaa17c40e..7910de73c52 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -19,6 +19,20 @@ module GroupsHelper
can?(current_user, :change_share_with_group_lock, group)
end
+ def group_issues_count(state:)
+ IssuesFinder
+ .new(current_user, group_id: @group.id, state: state, non_archived: true, include_subgroups: true)
+ .execute
+ .count
+ end
+
+ def group_merge_requests_count(state:)
+ MergeRequestsFinder
+ .new(current_user, group_id: @group.id, state: state, non_archived: true, include_subgroups: true)
+ .execute
+ .count
+ end
+
def group_icon(group, options = {})
img_path = group_icon_url(group, options)
image_tag img_path, options
@@ -77,10 +91,6 @@ module GroupsHelper
end
end
- def group_issues(group)
- IssuesFinder.new(current_user, group_id: group.id).execute
- end
-
def remove_group_message(group)
_("You are going to remove %{group_name}. Removed groups CANNOT be restored! Are you ABSOLUTELY sure?") %
{ group_name: group.name }
diff --git a/app/models/chat_name.rb b/app/models/chat_name.rb
index f321db75eeb..fbd0f123341 100644
--- a/app/models/chat_name.rb
+++ b/app/models/chat_name.rb
@@ -1,4 +1,6 @@
class ChatName < ActiveRecord::Base
+ LAST_USED_AT_INTERVAL = 1.hour
+
belongs_to :service
belongs_to :user
@@ -9,4 +11,23 @@ class ChatName < ActiveRecord::Base
validates :user_id, uniqueness: { scope: [:service_id] }
validates :chat_id, uniqueness: { scope: [:service_id, :team_id] }
+
+ # Updates the "last_used_timestamp" but only if it wasn't already updated
+ # recently.
+ #
+ # The throttling this method uses is put in place to ensure that high chat
+ # traffic doesn't result in many UPDATE queries being performed.
+ def update_last_used_at
+ return unless update_last_used_at?
+
+ obtained = Gitlab::ExclusiveLease
+ .new("chat_name/last_used_at/#{id}", timeout: LAST_USED_AT_INTERVAL.to_i)
+ .try_obtain
+
+ touch(:last_used_at) if obtained
+ end
+
+ def update_last_used_at?
+ last_used_at.nil? || last_used_at > LAST_USED_AT_INTERVAL.ago
+ end
end
diff --git a/app/models/ci/group_variable.rb b/app/models/ci/group_variable.rb
index afeae69ba39..1dd0e050ba9 100644
--- a/app/models/ci/group_variable.rb
+++ b/app/models/ci/group_variable.rb
@@ -6,7 +6,10 @@ module Ci
belongs_to :group
- validates :key, uniqueness: { scope: :group_id }
+ validates :key, uniqueness: {
+ scope: :group_id,
+ message: "(%{value}) has already been taken"
+ }
scope :unprotected, -> { where(protected: false) }
end
diff --git a/app/models/ci/variable.rb b/app/models/ci/variable.rb
index 67d3ec81b6f..7c71291de84 100644
--- a/app/models/ci/variable.rb
+++ b/app/models/ci/variable.rb
@@ -6,7 +6,10 @@ module Ci
belongs_to :project
- validates :key, uniqueness: { scope: [:project_id, :environment_scope] }
+ validates :key, uniqueness: {
+ scope: [:project_id, :environment_scope],
+ message: "(%{value}) has already been taken"
+ }
scope :unprotected, -> { where(protected: false) }
end
diff --git a/app/models/concerns/access_requestable.rb b/app/models/concerns/access_requestable.rb
index 62bc6b809f4..d502e7e54c6 100644
--- a/app/models/concerns/access_requestable.rb
+++ b/app/models/concerns/access_requestable.rb
@@ -8,6 +8,6 @@ module AccessRequestable
extend ActiveSupport::Concern
def request_access(user)
- Members::RequestAccessService.new(self, user).execute
+ Members::RequestAccessService.new(user).execute(self)
end
end
diff --git a/app/models/member.rb b/app/models/member.rb
index 2d17795e62d..408e8b2d704 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -128,7 +128,7 @@ class Member < ActiveRecord::Base
find_by(invite_token: invite_token)
end
- def add_user(source, user, access_level, existing_members: nil, current_user: nil, expires_at: nil)
+ def add_user(source, user, access_level, existing_members: nil, current_user: nil, expires_at: nil, ldap: false)
# `user` can be either a User object, User ID or an email to be invited
member = retrieve_member(source, user, existing_members)
access_level = retrieve_access_level(access_level)
@@ -143,11 +143,13 @@ class Member < ActiveRecord::Base
if member.request?
::Members::ApproveAccessRequestService.new(
- source,
current_user,
- id: member.id,
access_level: access_level
- ).execute
+ ).execute(
+ member,
+ skip_authorization: ldap,
+ skip_log_audit_event: ldap
+ )
else
member.save
end
diff --git a/app/models/project_services/slash_commands_service.rb b/app/models/project_services/slash_commands_service.rb
index eb4da68bb7e..37ea45109ae 100644
--- a/app/models/project_services/slash_commands_service.rb
+++ b/app/models/project_services/slash_commands_service.rb
@@ -30,10 +30,10 @@ class SlashCommandsService < Service
def trigger(params)
return unless valid_token?(params[:token])
- user = find_chat_user(params)
+ chat_user = find_chat_user(params)
- if user
- Gitlab::SlashCommands::Command.new(project, user, params).execute
+ if chat_user&.user
+ Gitlab::SlashCommands::Command.new(project, chat_user, params).execute
else
url = authorize_chat_name_url(params)
Gitlab::SlashCommands::Presenters::Access.new(url).authorize
diff --git a/app/models/user.rb b/app/models/user.rb
index 8610ca27b7f..982080763d2 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -431,7 +431,7 @@ class User < ActiveRecord::Base
end
def self.non_internal
- where(Hash[internal_attributes.zip([[false, nil]] * internal_attributes.size)])
+ where(internal_attributes.map { |attr| "#{attr} IS NOT TRUE" }.join(" AND "))
end
#
diff --git a/app/services/chat_names/find_user_service.rb b/app/services/chat_names/find_user_service.rb
index 4f5c5567b42..d458b814183 100644
--- a/app/services/chat_names/find_user_service.rb
+++ b/app/services/chat_names/find_user_service.rb
@@ -9,8 +9,8 @@ module ChatNames
chat_name = find_chat_name
return unless chat_name
- chat_name.touch(:last_used_at)
- chat_name.user
+ chat_name.update_last_used_at
+ chat_name
end
private
diff --git a/app/services/members/approve_access_request_service.rb b/app/services/members/approve_access_request_service.rb
index 2a2bb0cae5b..6be08b590bc 100644
--- a/app/services/members/approve_access_request_service.rb
+++ b/app/services/members/approve_access_request_service.rb
@@ -1,51 +1,20 @@
module Members
- class ApproveAccessRequestService < BaseService
- include MembersHelper
-
- attr_accessor :source
-
- # source - The source object that respond to `#requesters` (i.g. project or group)
- # current_user - The user that performs the access request approval
- # params - A hash of parameters
- # :user_id - User ID used to retrieve the access requester
- # :id - Member ID used to retrieve the access requester
- # :access_level - Optional access level set when the request is accepted
- def initialize(source, current_user, params = {})
- @source = source
- @current_user = current_user
- @params = params.slice(:user_id, :id, :access_level)
- end
-
- # opts - A hash of options
- # :force - Bypass permission check: current_user can be nil in that case
- def execute(opts = {})
- condition = params[:user_id] ? { user_id: params[:user_id] } : { id: params[:id] }
- access_requester = source.requesters.find_by!(condition)
-
- raise Gitlab::Access::AccessDeniedError unless can_update_access_requester?(access_requester, opts)
+ class ApproveAccessRequestService < Members::BaseService
+ def execute(access_requester, skip_authorization: false, skip_log_audit_event: false)
+ raise Gitlab::Access::AccessDeniedError unless skip_authorization || can_update_access_requester?(access_requester)
access_requester.access_level = params[:access_level] if params[:access_level]
access_requester.accept_request
+ after_execute(member: access_requester, skip_log_audit_event: skip_log_audit_event)
+
access_requester
end
private
- def can_update_access_requester?(access_requester, opts = {})
- access_requester && (
- opts[:force] ||
- can?(current_user, update_member_permission(access_requester), access_requester)
- )
- end
-
- def update_member_permission(member)
- case member
- when GroupMember
- :update_group_member
- when ProjectMember
- :update_project_member
- end
+ def can_update_access_requester?(access_requester)
+ can?(current_user, update_member_permission(access_requester), access_requester)
end
end
end
diff --git a/app/services/members/authorized_destroy_service.rb b/app/services/members/authorized_destroy_service.rb
deleted file mode 100644
index 2e89f00dad8..00000000000
--- a/app/services/members/authorized_destroy_service.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-module Members
- class AuthorizedDestroyService < BaseService
- attr_accessor :member, :user
-
- def initialize(member, user = nil)
- @member, @user = member, user
- end
-
- def execute
- return false if member.is_a?(GroupMember) && member.source.last_owner?(member.user)
-
- Member.transaction do
- unassign_issues_and_merge_requests(member) unless member.invite?
- member.notification_setting&.destroy
-
- member.destroy
- end
-
- if member.request? && member.user != user
- notification_service.decline_access_request(member)
- end
-
- member
- end
-
- private
-
- def unassign_issues_and_merge_requests(member)
- if member.is_a?(GroupMember)
- issues = Issue.unscoped.select(1)
- .joins(:project)
- .where('issues.id = issue_assignees.issue_id AND projects.namespace_id = ?', member.source_id)
-
- # DELETE FROM issue_assignees WHERE user_id = X AND EXISTS (...)
- IssueAssignee.unscoped
- .where('user_id = :user_id AND EXISTS (:sub)', user_id: member.user_id, sub: issues)
- .delete_all
-
- MergeRequestsFinder.new(user, group_id: member.source_id, assignee_id: member.user_id)
- .execute
- .update_all(assignee_id: nil)
- else
- project = member.source
-
- # SELECT 1 FROM issues WHERE issues.id = issue_assignees.issue_id AND issues.project_id = X
- issues = Issue.unscoped.select(1)
- .where('issues.id = issue_assignees.issue_id')
- .where(project_id: project.id)
-
- # DELETE FROM issue_assignees WHERE user_id = X AND EXISTS (...)
- IssueAssignee.unscoped
- .where('user_id = :user_id AND EXISTS (:sub)', user_id: member.user_id, sub: issues)
- .delete_all
-
- project.merge_requests.opened.assigned_to(member.user).update_all(assignee_id: nil)
- end
-
- member.user.invalidate_cache_counts
- end
- end
-end
diff --git a/app/services/members/base_service.rb b/app/services/members/base_service.rb
new file mode 100644
index 00000000000..74556fb20cf
--- /dev/null
+++ b/app/services/members/base_service.rb
@@ -0,0 +1,49 @@
+module Members
+ class BaseService < ::BaseService
+ # current_user - The user that performs the action
+ # params - A hash of parameters
+ def initialize(current_user = nil, params = {})
+ @current_user = current_user
+ @params = params
+ end
+
+ def after_execute(args)
+ # overriden in EE::Members modules
+ end
+
+ private
+
+ def update_member_permission(member)
+ case member
+ when GroupMember
+ :update_group_member
+ when ProjectMember
+ :update_project_member
+ else
+ raise "Unknown member type: #{member}!"
+ end
+ end
+
+ def override_member_permission(member)
+ case member
+ when GroupMember
+ :override_group_member
+ when ProjectMember
+ :override_project_member
+ else
+ raise "Unknown member type: #{member}!"
+ end
+ end
+
+ def action_member_permission(action, member)
+ case action
+ when :update
+ update_member_permission(member)
+ when :override
+ override_member_permission(member)
+ else
+ raise "Unknown action '#{action}' on #{member}!"
+ end
+ end
+ end
+end
diff --git a/app/services/members/create_service.rb b/app/services/members/create_service.rb
index 26906ae7167..bc6a9405aac 100644
--- a/app/services/members/create_service.rb
+++ b/app/services/members/create_service.rb
@@ -1,15 +1,8 @@
module Members
- class CreateService < BaseService
+ class CreateService < Members::BaseService
DEFAULT_LIMIT = 100
- def initialize(source, current_user, params = {})
- @source = source
- @current_user = current_user
- @params = params
- @error = nil
- end
-
- def execute
+ def execute(source)
return error('No users specified.') if params[:user_ids].blank?
user_ids = params[:user_ids].split(',').uniq
@@ -17,13 +10,15 @@ module Members
return error("Too many users specified (limit is #{user_limit})") if
user_limit && user_ids.size > user_limit
- @source.add_users(
+ members = source.add_users(
user_ids,
params[:access_level],
expires_at: params[:expires_at],
current_user: current_user
)
+ members.each { |member| after_execute(member: member) }
+
success
end
diff --git a/app/services/members/destroy_service.rb b/app/services/members/destroy_service.rb
index 05b93ac8fdb..b141bfd5fbc 100644
--- a/app/services/members/destroy_service.rb
+++ b/app/services/members/destroy_service.rb
@@ -1,42 +1,30 @@
module Members
- class DestroyService < BaseService
- include MembersHelper
+ class DestroyService < Members::BaseService
+ def execute(member, skip_authorization: false)
+ raise Gitlab::Access::AccessDeniedError unless skip_authorization || can_destroy_member?(member)
- attr_accessor :source
+ return member if member.is_a?(GroupMember) && member.source.last_owner?(member.user)
- ALLOWED_SCOPES = %i[members requesters all].freeze
+ Member.transaction do
+ unassign_issues_and_merge_requests(member) unless member.invite?
+ member.notification_setting&.destroy
- def initialize(source, current_user, params = {})
- @source = source
- @current_user = current_user
- @params = params
- end
-
- def execute(scope = :members)
- raise "scope :#{scope} is not allowed!" unless ALLOWED_SCOPES.include?(scope)
+ member.destroy
+ end
- member = find_member!(scope)
+ if member.request? && member.user != current_user
+ notification_service.decline_access_request(member)
+ end
- raise Gitlab::Access::AccessDeniedError unless can_destroy_member?(member)
+ after_execute(member: member)
- AuthorizedDestroyService.new(member, current_user).execute
+ member
end
private
- def find_member!(scope)
- condition = params[:user_id] ? { user_id: params[:user_id] } : { id: params[:id] }
- case scope
- when :all
- source.members.find_by(condition) ||
- source.requesters.find_by!(condition)
- else
- source.public_send(scope).find_by!(condition) # rubocop:disable GitlabSecurity/PublicSend
- end
- end
-
def can_destroy_member?(member)
- member && can?(current_user, destroy_member_permission(member), member)
+ can?(current_user, destroy_member_permission(member), member)
end
def destroy_member_permission(member)
@@ -45,7 +33,42 @@ module Members
:destroy_group_member
when ProjectMember
:destroy_project_member
+ else
+ raise "Unknown member type: #{member}!"
end
end
+
+ def unassign_issues_and_merge_requests(member)
+ if member.is_a?(GroupMember)
+ issues = Issue.unscoped.select(1)
+ .joins(:project)
+ .where('issues.id = issue_assignees.issue_id AND projects.namespace_id = ?', member.source_id)
+
+ # DELETE FROM issue_assignees WHERE user_id = X AND EXISTS (...)
+ IssueAssignee.unscoped
+ .where('user_id = :user_id AND EXISTS (:sub)', user_id: member.user_id, sub: issues)
+ .delete_all
+
+ MergeRequestsFinder.new(current_user, group_id: member.source_id, assignee_id: member.user_id)
+ .execute
+ .update_all(assignee_id: nil)
+ else
+ project = member.source
+
+ # SELECT 1 FROM issues WHERE issues.id = issue_assignees.issue_id AND issues.project_id = X
+ issues = Issue.unscoped.select(1)
+ .where('issues.id = issue_assignees.issue_id')
+ .where(project_id: project.id)
+
+ # DELETE FROM issue_assignees WHERE user_id = X AND EXISTS (...)
+ IssueAssignee.unscoped
+ .where('user_id = :user_id AND EXISTS (:sub)', user_id: member.user_id, sub: issues)
+ .delete_all
+
+ project.merge_requests.opened.assigned_to(member.user).update_all(assignee_id: nil)
+ end
+
+ member.user.invalidate_cache_counts
+ end
end
end
diff --git a/app/services/members/request_access_service.rb b/app/services/members/request_access_service.rb
index 2614153d900..24293b30005 100644
--- a/app/services/members/request_access_service.rb
+++ b/app/services/members/request_access_service.rb
@@ -1,13 +1,6 @@
module Members
- class RequestAccessService < BaseService
- attr_accessor :source
-
- def initialize(source, current_user)
- @source = source
- @current_user = current_user
- end
-
- def execute
+ class RequestAccessService < Members::BaseService
+ def execute(source)
raise Gitlab::Access::AccessDeniedError unless can_request_access?(source)
source.members.create(
@@ -19,7 +12,7 @@ module Members
private
def can_request_access?(source)
- source && can?(current_user, :request_access, source)
+ can?(current_user, :request_access, source)
end
end
end
diff --git a/app/services/members/update_service.rb b/app/services/members/update_service.rb
new file mode 100644
index 00000000000..48b3d59f7bd
--- /dev/null
+++ b/app/services/members/update_service.rb
@@ -0,0 +1,16 @@
+module Members
+ class UpdateService < Members::BaseService
+ # returns the updated member
+ def execute(member, permission: :update)
+ raise Gitlab::Access::AccessDeniedError unless can?(current_user, action_member_permission(permission, member), member)
+
+ old_access_level = member.human_access
+
+ if member.update_attributes(params)
+ after_execute(action: permission, old_access_level: old_access_level, member: member)
+ end
+
+ member
+ end
+ end
+end
diff --git a/app/validators/variable_duplicates_validator.rb b/app/validators/variable_duplicates_validator.rb
index 4bfa3c45303..72660be6c43 100644
--- a/app/validators/variable_duplicates_validator.rb
+++ b/app/validators/variable_duplicates_validator.rb
@@ -5,6 +5,8 @@
# - Use `validates :xxx, uniqueness: { scope: :xxx_id }` in a child model
class VariableDuplicatesValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
+ return if record.errors.include?(:"#{attribute}.key")
+
if options[:scope]
scoped = value.group_by do |variable|
Array(options[:scope]).map { |attr| variable.send(attr) } # rubocop:disable GitlabSecurity/PublicSend
diff --git a/app/views/groups/group_members/update.js.haml b/app/views/groups/group_members/update.js.haml
deleted file mode 100644
index 9d05bff6c4e..00000000000
--- a/app/views/groups/group_members/update.js.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-:plain
- var $listItem = $('#{escape_javascript(render('shared/members/member', member: @group_member))}');
- $("##{dom_id(@group_member)} .list-item-name").replaceWith($listItem.find('.list-item-name'));
- gl.utils.localTimeAgo($('.js-timeago'), $("##{dom_id(@group_member)}"));
diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml
index f2ae7c52031..ca3f018c5e6 100644
--- a/app/views/groups/issues.html.haml
+++ b/app/views/groups/issues.html.haml
@@ -1,12 +1,13 @@
- page_title "Issues"
-- group_issues_exists = group_issues(@group).exists?
= content_for :meta_tags do
= auto_discovery_link_tag(:atom, params.merge(rss_url_options), title: "#{@group.name} issues")
- content_for :page_specific_javascripts do
= webpack_bundle_tag 'common_vue'
-- if group_issues_exists
+- if group_issues_count(state: 'all').zero?
+ = render 'shared/empty_states/issues', project_select_button: true
+- else
.top-area
= render 'shared/issuable/nav', type: :issues
.nav-controls
@@ -19,5 +20,3 @@
= render 'shared/issuable/search_bar', type: :issues
= render 'shared/issues'
-- else
- = render 'shared/empty_states/issues', project_select_button: true
diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml
index 046b92bd9fb..520fe217ae1 100644
--- a/app/views/groups/merge_requests.html.haml
+++ b/app/views/groups/merge_requests.html.haml
@@ -3,7 +3,7 @@
- content_for :page_specific_javascripts do
= webpack_bundle_tag 'common_vue'
-- if @group_merge_requests.empty?
+- if group_merge_requests_count(state: 'all').zero?
= render 'shared/empty_states/merge_requests', project_select_button: true
- else
.top-area
diff --git a/app/views/layouts/nav/sidebar/_group.html.haml b/app/views/layouts/nav/sidebar/_group.html.haml
index 47ae79b7a69..b520f28123f 100644
--- a/app/views/layouts/nav/sidebar/_group.html.haml
+++ b/app/views/layouts/nav/sidebar/_group.html.haml
@@ -1,6 +1,5 @@
-- issues_count = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute.count
-- merge_requests_count = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened', non_archived: true).execute.count
-
+- issues_count = group_issues_count(state: 'opened')
+- merge_requests_count = group_merge_requests_count(state: 'opened')
- issues_sub_menu_items = ['groups#issues', 'labels#index', 'milestones#index']
.nav-sidebar{ class: ("sidebar-collapsed-desktop" if collapsed_sidebar?) }
diff --git a/app/views/projects/commit/_pipelines_list.haml b/app/views/projects/commit/_pipelines_list.haml
index 3f699882c5f..a3fed25af28 100644
--- a/app/views/projects/commit/_pipelines_list.haml
+++ b/app/views/projects/commit/_pipelines_list.haml
@@ -9,4 +9,3 @@
- content_for :page_specific_javascripts do
= webpack_bundle_tag('common_vue')
- = webpack_bundle_tag('commit_pipelines')
diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml
index 4058e61eb9a..ba86d943967 100644
--- a/app/views/projects/commit/show.html.haml
+++ b/app/views/projects/commit/show.html.haml
@@ -8,7 +8,6 @@
- page_description @commit.description
- content_for :page_specific_javascripts do
= webpack_bundle_tag('common_vue')
- = webpack_bundle_tag('diff_notes')
.container-fluid{ class: [limited_container_width, container_class] }
= render "commit_box"
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index 6ff7bcae54f..078bd0eee63 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -20,7 +20,7 @@
.avatar-cell.hidden-xs
= author_avatar(commit, size: 36)
- .commit-detail
+ .commit-detail.flex-list
.commit-content
= link_to_markdown_field(commit, :title, link, class: "commit-row-message item-title")
%span.commit-row-message.visible-xs-inline
diff --git a/app/views/projects/environments/folder.html.haml b/app/views/projects/environments/folder.html.haml
index eca10d99908..d8054dbc372 100644
--- a/app/views/projects/environments/folder.html.haml
+++ b/app/views/projects/environments/folder.html.haml
@@ -3,7 +3,6 @@
- content_for :page_specific_javascripts do
= webpack_bundle_tag('common_vue')
- = webpack_bundle_tag("environments_folder")
#environments-folder-list-view{ data: { endpoint: folder_project_environments_path(@project, @folder, format: :json),
"folder-name" => @folder,
diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml
index e29f21b3bec..7cbc984ef19 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -23,9 +23,6 @@
#js-vue-mr-widget.mr-widget
- - content_for :page_specific_javascripts do
- = webpack_bundle_tag 'vue_merge_request_widget'
-
.content-block.content-block-small.emoji-list-container
= render 'award_emoji/awards_block', awardable: @merge_request, inline: true
diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml
index 97be8950db0..4b7be9a223f 100644
--- a/app/views/projects/network/show.html.haml
+++ b/app/views/projects/network/show.html.haml
@@ -1,7 +1,5 @@
- breadcrumb_title "Graph"
- page_title "Graph", @ref
-- content_for :page_specific_javascripts do
- = webpack_bundle_tag('network')
= render "head"
%div{ class: container_class }
.project-network
diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml
index fdcc60f48a5..cf95cdbfec2 100644
--- a/app/views/projects/pipelines/index.html.haml
+++ b/app/views/projects/pipelines/index.html.haml
@@ -12,6 +12,3 @@
"has-ci" => @repository.gitlab_ci_yml,
"ci-lint-path" => ci_lint_path,
"reset-cache-path" => reset_cache_project_settings_ci_cd_path(@project) } }
-
- = webpack_bundle_tag('common_vue')
- = webpack_bundle_tag('pipelines')
diff --git a/app/views/projects/project_members/update.js.haml b/app/views/projects/project_members/update.js.haml
deleted file mode 100644
index d15f4310ff5..00000000000
--- a/app/views/projects/project_members/update.js.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-:plain
- var $listItem = $('#{escape_javascript(render('shared/members/member', member: @project_member))}');
- $("##{dom_id(@project_member)} .list-item-name").replaceWith($listItem.find('.list-item-name'));
- gl.utils.localTimeAgo($('.js-timeago'), $("##{dom_id(@project_member)}"));
diff --git a/app/views/projects/services/prometheus/_configuration_banner.html.haml b/app/views/projects/services/prometheus/_configuration_banner.html.haml
new file mode 100644
index 00000000000..2cc2a6b2b5b
--- /dev/null
+++ b/app/views/projects/services/prometheus/_configuration_banner.html.haml
@@ -0,0 +1,26 @@
+%h4
+ = s_('PrometheusService|Auto configuration')
+
+- if service.manual_configuration?
+ .well
+ = s_('PrometheusService|To enable the installation of Prometheus on your clusters, deactivate the manual configuration below')
+- else
+ .container-fluid
+ .row
+ - if service.prometheus_installed?
+ .col-sm-2
+ .svg-container
+ = image_tag 'illustrations/monitoring/getting_started.svg'
+ .col-sm-10
+ %p.text-success.prepend-top-default
+ = s_('PrometheusService|Prometheus is being automatically managed on your clusters')
+ = link_to s_('PrometheusService|Manage clusters'), project_clusters_path(project), class: 'btn'
+ - else
+ .col-sm-2
+ = image_tag 'illustrations/monitoring/loading.svg'
+ .col-sm-10
+ %p.prepend-top-default
+ = s_('PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments')
+ = link_to s_('PrometheusService|Install Prometheus on clusters'), project_clusters_path(project), class: 'btn btn-success'
+
+%hr
diff --git a/app/views/projects/services/prometheus/_help.html.haml b/app/views/projects/services/prometheus/_help.html.haml
index 5e320a252d8..88acb824ba7 100644
--- a/app/views/projects/services/prometheus/_help.html.haml
+++ b/app/views/projects/services/prometheus/_help.html.haml
@@ -1,29 +1,5 @@
-%h4
- = s_('PrometheusService|Auto configuration')
-
-- if @service.manual_configuration?
- .well
- = s_('PrometheusService|To enable the installation of Prometheus on your clusters, deactivate the manual configuration below')
-- else
- .container-fluid
- .row
- - if @service.prometheus_installed?
- .col-sm-2
- .svg-container
- = image_tag 'illustrations/monitoring/getting_started.svg'
- .col-sm-10
- %p.text-success.prepend-top-default
- = s_('PrometheusService|Prometheus is being automatically managed on your clusters')
- = link_to s_('PrometheusService|Manage clusters'), project_clusters_path(@project), class: 'btn'
- - else
- .col-sm-2
- = image_tag 'illustrations/monitoring/loading.svg'
- .col-sm-10
- %p.prepend-top-default
- = s_('PrometheusService|Automatically deploy and configure Prometheus on your clusters to monitor your project’s environments')
- = link_to s_('PrometheusService|Install Prometheus on clusters'), project_clusters_path(@project), class: 'btn btn-success'
-
-%hr
+- if @project
+ = render 'projects/services/prometheus/configuration_banner', project: @project, service: @service
%h4.append-bottom-default
= s_('PrometheusService|Manual configuration')
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index dc583d3eb3b..c1589027898 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -1,7 +1,6 @@
- todo = issuable_todo(issuable)
- content_for :page_specific_javascripts do
= webpack_bundle_tag('common_vue')
- = webpack_bundle_tag('sidebar')
%aside.right-sidebar.js-right-sidebar.js-issuable-sidebar{ data: { signed: { in: current_user.present? } }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' }
.issuable-sidebar{ data: { endpoint: "#{issuable_json_path(issuable)}" } }
diff --git a/app/views/shared/members/update.js.haml b/app/views/shared/members/update.js.haml
new file mode 100644
index 00000000000..55050bd8a15
--- /dev/null
+++ b/app/views/shared/members/update.js.haml
@@ -0,0 +1,6 @@
+- member = local_assigns.fetch(:member)
+
+:plain
+ var $listItem = $('#{escape_javascript(render('shared/members/member', member: member))}');
+ $("##{dom_id(member)} .list-item-name").replaceWith($listItem.find('.list-item-name'));
+ gl.utils.localTimeAgo($('.js-timeago'), $("##{dom_id(member)}"));
diff --git a/app/workers/remove_expired_members_worker.rb b/app/workers/remove_expired_members_worker.rb
index d80b3b15840..68960f72bf6 100644
--- a/app/workers/remove_expired_members_worker.rb
+++ b/app/workers/remove_expired_members_worker.rb
@@ -5,7 +5,7 @@ class RemoveExpiredMembersWorker
def perform
Member.expired.find_each do |member|
begin
- Members::AuthorizedDestroyService.new(member).execute
+ Members::DestroyService.new.execute(member, skip_authorization: true)
rescue => ex
logger.error("Expired Member ID=#{member.id} cannot be removed - #{ex}")
end