summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/pages
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/pages')
-rw-r--r--app/assets/javascripts/pages/admin/admin.js6
-rw-r--r--app/assets/javascripts/pages/admin/application_settings/payload_previewer.js2
-rw-r--r--app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js2
-rw-r--r--app/assets/javascripts/pages/admin/jobs/index/components/stop_jobs_modal.vue4
-rw-r--r--app/assets/javascripts/pages/admin/projects/index.js2
-rw-r--r--app/assets/javascripts/pages/admin/projects/index/index.js2
-rw-r--r--app/assets/javascripts/pages/admin/users/index.js2
-rw-r--r--app/assets/javascripts/pages/admin/users/new/index.js2
-rw-r--r--app/assets/javascripts/pages/dashboard/projects/index/components/customize_homepage_banner.vue2
-rw-r--r--app/assets/javascripts/pages/dashboard/projects/index/init_customize_homepage_banner.js2
-rw-r--r--app/assets/javascripts/pages/dashboard/todos/index/todos.js2
-rw-r--r--app/assets/javascripts/pages/groups/group_members/index.js6
-rw-r--r--app/assets/javascripts/pages/groups/issues/index.js1
-rw-r--r--app/assets/javascripts/pages/groups/new/group_path_validator.js6
-rw-r--r--app/assets/javascripts/pages/groups/settings/packages_and_registries/index.js3
-rw-r--r--app/assets/javascripts/pages/groups/shared/group_tabs.js4
-rw-r--r--app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue4
-rw-r--r--app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue99
-rw-r--r--app/assets/javascripts/pages/milestones/shared/delete_milestone_modal_init.js4
-rw-r--r--app/assets/javascripts/pages/milestones/shared/promote_milestone_modal_init.js85
-rw-r--r--app/assets/javascripts/pages/profiles/index.js2
-rw-r--r--app/assets/javascripts/pages/profiles/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/blob/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/commit/show/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/edit/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/edit/mount_search_settings.js12
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue6
-rw-r--r--app/assets/javascripts/pages/projects/graphs/charts/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue6
-rw-r--r--app/assets/javascripts/pages/projects/init_form.js2
-rw-r--r--app/assets/javascripts/pages/projects/issues/service_desk/filtered_search.js2
-rw-r--r--app/assets/javascripts/pages/projects/issues/show.js4
-rw-r--r--app/assets/javascripts/pages/projects/jobs/index/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue4
-rw-r--r--app/assets/javascripts/pages/projects/labels/index/index.js7
-rw-r--r--app/assets/javascripts/pages/projects/labels/new/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/creations/new/compare.js12
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js17
-rw-r--r--app/assets/javascripts/pages/projects/new/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/pages_domains/form.js6
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js6
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue2
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/target_branch_dropdown.js8
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js12
-rw-r--r--app/assets/javascripts/pages/projects/pipelines/charts/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/pipelines/init_pipelines.js2
-rw-r--r--app/assets/javascripts/pages/projects/pipelines/new/index.js22
-rw-r--r--app/assets/javascripts/pages/projects/project.js30
-rw-r--r--app/assets/javascripts/pages/projects/project_members/index.js6
-rw-r--r--app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/project_feature_setting.vue6
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue97
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/external.js2
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/tags/index/index.js7
-rw-r--r--app/assets/javascripts/pages/search/show/refresh_counts.js2
-rw-r--r--app/assets/javascripts/pages/search/show/search.js13
-rw-r--r--app/assets/javascripts/pages/sessions/new/length_validator.js2
-rw-r--r--app/assets/javascripts/pages/sessions/new/preserve_url_fragment.js4
-rw-r--r--app/assets/javascripts/pages/sessions/new/signin_tabs_memoizer.js2
-rw-r--r--app/assets/javascripts/pages/sessions/new/username_validator.js6
-rw-r--r--app/assets/javascripts/pages/shared/mount_badge_settings.js2
-rw-r--r--app/assets/javascripts/pages/shared/wikis/wikis.js34
-rw-r--r--app/assets/javascripts/pages/users/activity_calendar.js29
-rw-r--r--app/assets/javascripts/pages/users/index.js6
-rw-r--r--app/assets/javascripts/pages/users/user_tabs.js20
66 files changed, 343 insertions, 330 deletions
diff --git a/app/assets/javascripts/pages/admin/admin.js b/app/assets/javascripts/pages/admin/admin.js
index 038bbe392ba..e92262852cf 100644
--- a/app/assets/javascripts/pages/admin/admin.js
+++ b/app/assets/javascripts/pages/admin/admin.js
@@ -23,7 +23,7 @@ export default function adminInit() {
}
});
- $('body').on('click', '.js-toggle-colors-link', e => {
+ $('body').on('click', '.js-toggle-colors-link', (e) => {
e.preventDefault();
$('.js-toggle-colors-container').toggleClass('hide');
});
@@ -33,7 +33,7 @@ export default function adminInit() {
$(this).tab('show');
});
- $('.log-bottom').on('click', e => {
+ $('.log-bottom').on('click', (e) => {
e.preventDefault();
const $visibleLog = $('.file-content:visible');
@@ -52,7 +52,7 @@ export default function adminInit() {
modal.show();
});
- $('.change-owner-cancel-link').on('click', e => {
+ $('.change-owner-cancel-link').on('click', (e) => {
e.preventDefault();
modal.hide();
$('.change-owner-link').show();
diff --git a/app/assets/javascripts/pages/admin/application_settings/payload_previewer.js b/app/assets/javascripts/pages/admin/application_settings/payload_previewer.js
index f8fc53799a8..b995cb1d3dd 100644
--- a/app/assets/javascripts/pages/admin/application_settings/payload_previewer.js
+++ b/app/assets/javascripts/pages/admin/application_settings/payload_previewer.js
@@ -14,7 +14,7 @@ export default class PayloadPreviewer {
this.spinner = this.trigger.querySelector('.js-spinner');
this.text = this.trigger.querySelector('.js-text');
- this.trigger.addEventListener('click', event => {
+ this.trigger.addEventListener('click', (event) => {
event.preventDefault();
if (this.isVisible) return this.hidePayload();
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 a75f5d318a0..9e4c4d9f615 100644
--- a/app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js
+++ b/app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js
@@ -82,7 +82,7 @@ export default () => {
return $jsBroadcastMessagePreview.css(selectedColorStyle);
};
- const setSuggestedColor = e => {
+ const setSuggestedColor = (e) => {
const color = $(e.currentTarget).data('color');
$broadcastMessageColor
.val(color)
diff --git a/app/assets/javascripts/pages/admin/jobs/index/components/stop_jobs_modal.vue b/app/assets/javascripts/pages/admin/jobs/index/components/stop_jobs_modal.vue
index 4b6f52c09be..d65593963ce 100644
--- a/app/assets/javascripts/pages/admin/jobs/index/components/stop_jobs_modal.vue
+++ b/app/assets/javascripts/pages/admin/jobs/index/components/stop_jobs_modal.vue
@@ -26,11 +26,11 @@ export default {
onSubmit() {
return axios
.post(this.url)
- .then(response => {
+ .then((response) => {
// follow the rediect to refresh the page
redirectTo(response.request.responseURL);
})
- .catch(error => {
+ .catch((error) => {
createFlash(s__('AdminArea|Stopping jobs failed'));
throw error;
});
diff --git a/app/assets/javascripts/pages/admin/projects/index.js b/app/assets/javascripts/pages/admin/projects/index.js
index d86c5e2ddb8..fa2b0546c02 100644
--- a/app/assets/javascripts/pages/admin/projects/index.js
+++ b/app/assets/javascripts/pages/admin/projects/index.js
@@ -24,5 +24,5 @@ document.addEventListener('DOMContentLoaded', () => {
document
.querySelectorAll('.js-namespace-select')
- .forEach(dropdown => new NamespaceSelect({ dropdown }));
+ .forEach((dropdown) => new NamespaceSelect({ dropdown }));
});
diff --git a/app/assets/javascripts/pages/admin/projects/index/index.js b/app/assets/javascripts/pages/admin/projects/index/index.js
index ebb1a74e970..bf512ef395d 100644
--- a/app/assets/javascripts/pages/admin/projects/index/index.js
+++ b/app/assets/javascripts/pages/admin/projects/index/index.js
@@ -18,7 +18,7 @@ document.addEventListener('DOMContentLoaded', () => {
},
mounted() {
const deleteProjectButtons = document.querySelectorAll('.delete-project-button');
- deleteProjectButtons.forEach(button => {
+ deleteProjectButtons.forEach((button) => {
button.addEventListener('click', () => {
const buttonProps = button.dataset;
deleteModal.deleteProjectUrl = buttonProps.deleteProjectUrl;
diff --git a/app/assets/javascripts/pages/admin/users/index.js b/app/assets/javascripts/pages/admin/users/index.js
index 07462b4592f..75a8284f5f8 100644
--- a/app/assets/javascripts/pages/admin/users/index.js
+++ b/app/assets/javascripts/pages/admin/users/index.js
@@ -17,7 +17,7 @@ function loadModalsConfigurationFromHtml(modalsElement) {
throw new Error('Modals content element not found!');
}
- Array.from(modalsElement.children).forEach(node => {
+ Array.from(modalsElement.children).forEach((node) => {
const { modal, ...config } = node.dataset;
modalsConfiguration[modal] = {
title: node.dataset.title,
diff --git a/app/assets/javascripts/pages/admin/users/new/index.js b/app/assets/javascripts/pages/admin/users/new/index.js
index 3e6a090cb0e..7b7d4c169ef 100644
--- a/app/assets/javascripts/pages/admin/users/new/index.js
+++ b/app/assets/javascripts/pages/admin/users/new/index.js
@@ -15,7 +15,7 @@ export default class UserInternalRegexHandler {
}
addListenerToEmailField() {
- $('#user_email').on('input', event => {
+ $('#user_email').on('input', (event) => {
this.setExternalCheckbox(event.currentTarget.value);
});
}
diff --git a/app/assets/javascripts/pages/dashboard/projects/index/components/customize_homepage_banner.vue b/app/assets/javascripts/pages/dashboard/projects/index/components/customize_homepage_banner.vue
index 9fa441348c7..bed753b0c40 100644
--- a/app/assets/javascripts/pages/dashboard/projects/index/components/customize_homepage_banner.vue
+++ b/app/assets/javascripts/pages/dashboard/projects/index/components/customize_homepage_banner.vue
@@ -57,7 +57,7 @@ export default {
.post(this.calloutsPath, {
feature_name: this.calloutsFeatureId,
})
- .catch(e => {
+ .catch((e) => {
// eslint-disable-next-line @gitlab/require-i18n-strings, no-console
console.error('Failed to dismiss banner.', e);
});
diff --git a/app/assets/javascripts/pages/dashboard/projects/index/init_customize_homepage_banner.js b/app/assets/javascripts/pages/dashboard/projects/index/init_customize_homepage_banner.js
index c0735dde1da..8cdcd3134ee 100644
--- a/app/assets/javascripts/pages/dashboard/projects/index/init_customize_homepage_banner.js
+++ b/app/assets/javascripts/pages/dashboard/projects/index/init_customize_homepage_banner.js
@@ -11,6 +11,6 @@ export default () => {
return new Vue({
el,
provide: { ...el.dataset },
- render: createElement => createElement(CustomizeHomepageBanner),
+ render: (createElement) => createElement(CustomizeHomepageBanner),
});
};
diff --git a/app/assets/javascripts/pages/dashboard/todos/index/todos.js b/app/assets/javascripts/pages/dashboard/todos/index/todos.js
index 6f8d954d798..bd283201eff 100644
--- a/app/assets/javascripts/pages/dashboard/todos/index/todos.js
+++ b/app/assets/javascripts/pages/dashboard/todos/index/todos.js
@@ -154,7 +154,7 @@ export default class Todos {
goToTodoUrl(e) {
const todoLink = this.dataset.url;
- if (!todoLink || e.target.tagName === 'A' || e.target.tagName === 'IMG') {
+ if (!todoLink || e.target.closest('a')) {
return;
}
diff --git a/app/assets/javascripts/pages/groups/group_members/index.js b/app/assets/javascripts/pages/groups/group_members/index.js
index d3900b84fa7..5346e3720e8 100644
--- a/app/assets/javascripts/pages/groups/group_members/index.js
+++ b/app/assets/javascripts/pages/groups/group_members/index.js
@@ -1,10 +1,11 @@
import Vue from 'vue';
-import Members from 'ee_else_ce/members';
import memberExpirationDate from '~/member_expiration_date';
import UsersSelect from '~/users_select';
import groupsSelect from '~/groups_select';
import RemoveMemberModal from '~/vue_shared/components/remove_member_modal.vue';
import { initGroupMembersApp } from '~/groups/members';
+import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
+import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
import { memberRequestFormatter, groupLinkRequestFormatter } from '~/groups/members/utils';
import { s__ } from '~/locale';
@@ -65,6 +66,7 @@ groupsSelect();
memberExpirationDate();
memberExpirationDate('.js-access-expiration-date-groups');
mountRemoveMemberModal();
+initInviteMembersModal();
+initInviteMembersTrigger();
-new Members(); // eslint-disable-line no-new
new UsersSelect(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/groups/issues/index.js b/app/assets/javascripts/pages/groups/issues/index.js
index 4d0a03e151a..5cb21ca61ab 100644
--- a/app/assets/javascripts/pages/groups/issues/index.js
+++ b/app/assets/javascripts/pages/groups/issues/index.js
@@ -9,6 +9,7 @@ import initManualOrdering from '~/manual_ordering';
const ISSUE_BULK_UPDATE_PREFIX = 'issue_';
IssuableFilteredSearchTokenKeys.addExtraTokensForIssues();
+IssuableFilteredSearchTokenKeys.removeTokensForKeys('release');
issuableInitBulkUpdateSidebar.init(ISSUE_BULK_UPDATE_PREFIX);
initIssuablesList();
diff --git a/app/assets/javascripts/pages/groups/new/group_path_validator.js b/app/assets/javascripts/pages/groups/new/group_path_validator.js
index 83b38b0f1a5..97f3d8cf7f5 100644
--- a/app/assets/javascripts/pages/groups/new/group_path_validator.js
+++ b/app/assets/javascripts/pages/groups/new/group_path_validator.js
@@ -21,11 +21,11 @@ export default class GroupPathValidator extends InputValidator {
const container = opts.container || '';
const validateElements = document.querySelectorAll(`${container} .js-validate-group-path`);
- this.debounceValidateInput = debounce(inputDomElement => {
+ this.debounceValidateInput = debounce((inputDomElement) => {
GroupPathValidator.validateGroupPathInput(inputDomElement);
}, debounceTimeoutDuration);
- validateElements.forEach(element =>
+ validateElements.forEach((element) =>
element.addEventListener('input', this.eventHandler.bind(this)),
);
}
@@ -45,7 +45,7 @@ export default class GroupPathValidator extends InputValidator {
fetchGroupPathAvailability(groupPath)
.then(({ data }) => data)
- .then(data => {
+ .then((data) => {
GroupPathValidator.setInputState(inputDomElement, !data.exists);
GroupPathValidator.setMessageVisibility(inputDomElement, pendingMessageSelector, false);
GroupPathValidator.setMessageVisibility(
diff --git a/app/assets/javascripts/pages/groups/settings/packages_and_registries/index.js b/app/assets/javascripts/pages/groups/settings/packages_and_registries/index.js
new file mode 100644
index 00000000000..3b922622d2c
--- /dev/null
+++ b/app/assets/javascripts/pages/groups/settings/packages_and_registries/index.js
@@ -0,0 +1,3 @@
+import bundle from '~/packages_and_registries/settings/group/bundle';
+
+bundle();
diff --git a/app/assets/javascripts/pages/groups/shared/group_tabs.js b/app/assets/javascripts/pages/groups/shared/group_tabs.js
index c6fe61d2bd9..033843d8504 100644
--- a/app/assets/javascripts/pages/groups/shared/group_tabs.js
+++ b/app/assets/javascripts/pages/groups/shared/group_tabs.js
@@ -20,7 +20,7 @@ export default class GroupTabs extends UserTabs {
bindEvents() {
this.$parentEl
.off('shown.bs.tab', '.nav-links a[data-toggle="tab"]')
- .on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', event => this.tabShown(event));
+ .on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', (event) => this.tabShown(event));
}
tabShown(event) {
@@ -117,7 +117,7 @@ export default class GroupTabs extends UserTabs {
cleanFilterState() {
const values = Object.values(this.loaded);
- const loadedTabs = values.filter(e => e === true);
+ const loadedTabs = values.filter((e) => e === true);
if (!loadedTabs.length) {
return;
diff --git a/app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue b/app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue
index 93fe38831be..f47945c5a9f 100644
--- a/app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue
+++ b/app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue
@@ -82,7 +82,7 @@ Once deleted, it cannot be undone or recovered.`),
return axios
.delete(this.milestoneUrl)
- .then(response => {
+ .then((response) => {
eventHub.$emit('deleteMilestoneModal.requestFinished', {
milestoneUrl: this.milestoneUrl,
successful: true,
@@ -91,7 +91,7 @@ Once deleted, it cannot be undone or recovered.`),
// follow the rediect to milestones overview page
redirectTo(response.request.responseURL);
})
- .catch(error => {
+ .catch((error) => {
eventHub.$emit('deleteMilestoneModal.requestFinished', {
milestoneUrl: this.milestoneUrl,
successful: false,
diff --git a/app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue b/app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue
index 0dc54b612ba..ecde11aff40 100644
--- a/app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue
+++ b/app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue
@@ -1,28 +1,22 @@
<script>
+import { GlModal } from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils';
import { deprecatedCreateFlash as createFlash } from '~/flash';
-import DeprecatedModal2 from '~/vue_shared/components/deprecated_modal_2.vue';
import { s__, sprintf } from '~/locale';
import { visitUrl } from '~/lib/utils/url_utility';
-import eventHub from '../event_hub';
export default {
components: {
- GlModal: DeprecatedModal2,
+ GlModal,
},
- props: {
- milestoneTitle: {
- type: String,
- required: true,
- },
- url: {
- type: String,
- required: true,
- },
- groupName: {
- type: String,
- required: true,
- },
+ data() {
+ return {
+ milestoneTitle: '',
+ url: '',
+ groupName: '',
+ currentButton: null,
+ visible: false,
+ };
},
computed: {
title() {
@@ -38,42 +32,71 @@ export default {
);
},
},
+ mounted() {
+ this.getButtons().forEach((button) => {
+ button.addEventListener('click', this.onPromoteButtonClick);
+ button.removeAttribute('disabled');
+ });
+ },
+ beforeDestroy() {
+ this.getButtons().forEach((button) => {
+ button.removeEventListener('click', this.onPromoteButtonClick);
+ });
+ },
methods: {
+ onPromoteButtonClick({ currentTarget }) {
+ const { milestoneTitle, url, groupName } = currentTarget.dataset;
+ currentTarget.setAttribute('disabled', '');
+ this.visible = true;
+ this.milestoneTitle = milestoneTitle;
+ this.url = url;
+ this.groupName = groupName;
+ this.currentButton = currentTarget;
+ },
+ getButtons() {
+ return document.querySelectorAll('.js-promote-project-milestone-button');
+ },
onSubmit() {
- eventHub.$emit('promoteMilestoneModal.requestStarted', this.url);
return axios
.post(this.url, { params: { format: 'json' } })
- .then(response => {
- eventHub.$emit('promoteMilestoneModal.requestFinished', {
- milestoneUrl: this.url,
- successful: true,
- });
+ .then((response) => {
visitUrl(response.data.url);
})
- .catch(error => {
- eventHub.$emit('promoteMilestoneModal.requestFinished', {
- milestoneUrl: this.url,
- successful: false,
- });
+ .catch((error) => {
createFlash(error);
+ })
+ .finally(() => {
+ this.visible = false;
});
},
+ onClose() {
+ this.visible = false;
+ if (this.currentButton) {
+ this.currentButton.removeAttribute('disabled');
+ }
+ },
+ },
+ primaryAction: {
+ text: s__('Milestones|Promote Milestone'),
+ attributes: [{ variant: 'warning' }],
+ },
+ cancelAction: {
+ text: s__('Cancel'),
+ attributes: [],
},
};
</script>
<template>
<gl-modal
- id="promote-milestone-modal"
- :footer-primary-button-text="s__('Milestones|Promote Milestone')"
- footer-primary-button-variant="warning"
- @submit="onSubmit"
+ :visible="visible"
+ modal-id="promote-milestone-modal"
+ :action-primary="$options.primaryAction"
+ :action-cancel="$options.cancelAction"
+ :title="title"
+ @primary="onSubmit"
+ @hide="onClose"
>
- <template #title>
- {{ title }}
- </template>
- <div>
- <p>{{ text }}</p>
- <p>{{ s__('Milestones|This action cannot be reversed.') }}</p>
- </div>
+ <p>{{ text }}</p>
+ <p>{{ s__('Milestones|This action cannot be reversed.') }}</p>
</gl-modal>
</template>
diff --git a/app/assets/javascripts/pages/milestones/shared/delete_milestone_modal_init.js b/app/assets/javascripts/pages/milestones/shared/delete_milestone_modal_init.js
index 6e68114e04b..e8b67891c42 100644
--- a/app/assets/javascripts/pages/milestones/shared/delete_milestone_modal_init.js
+++ b/app/assets/javascripts/pages/milestones/shared/delete_milestone_modal_init.js
@@ -20,7 +20,7 @@ export default () => {
const deleteMilestoneButtons = document.querySelectorAll('.js-delete-milestone-button');
- const onRequestStarted = milestoneUrl => {
+ const onRequestStarted = (milestoneUrl) => {
const button = document.querySelector(
`.js-delete-milestone-button[data-milestone-url="${milestoneUrl}"]`,
);
@@ -44,7 +44,7 @@ export default () => {
},
mounted() {
eventHub.$on('deleteMilestoneModal.props', this.setModalProps);
- deleteMilestoneButtons.forEach(button => {
+ deleteMilestoneButtons.forEach((button) => {
button.removeAttribute('disabled');
button.addEventListener('click', () => {
this.$root.$emit('bv::show::modal', 'delete-milestone-modal');
diff --git a/app/assets/javascripts/pages/milestones/shared/promote_milestone_modal_init.js b/app/assets/javascripts/pages/milestones/shared/promote_milestone_modal_init.js
index fcc62a2b2af..5472b8c684f 100644
--- a/app/assets/javascripts/pages/milestones/shared/promote_milestone_modal_init.js
+++ b/app/assets/javascripts/pages/milestones/shared/promote_milestone_modal_init.js
@@ -1,88 +1,19 @@
import Vue from 'vue';
import Translate from '~/vue_shared/translate';
import PromoteMilestoneModal from './components/promote_milestone_modal.vue';
-import eventHub from './event_hub';
Vue.use(Translate);
export default () => {
- const onRequestFinished = ({ milestoneUrl, successful }) => {
- const button = document.querySelector(
- `.js-promote-project-milestone-button[data-url="${milestoneUrl}"]`,
- );
-
- if (!successful) {
- button.removeAttribute('disabled');
- }
- };
-
- const onRequestStarted = milestoneUrl => {
- const button = document.querySelector(
- `.js-promote-project-milestone-button[data-url="${milestoneUrl}"]`,
- );
- button.setAttribute('disabled', '');
- eventHub.$once('promoteMilestoneModal.requestFinished', onRequestFinished);
- };
-
- const onDeleteButtonClick = event => {
- const button = event.currentTarget;
- const modalProps = {
- milestoneTitle: button.dataset.milestoneTitle,
- url: button.dataset.url,
- groupName: button.dataset.groupName,
- };
- eventHub.$once('promoteMilestoneModal.requestStarted', onRequestStarted);
- eventHub.$emit('promoteMilestoneModal.props', modalProps);
- };
-
- const promoteMilestoneButtons = document.querySelectorAll('.js-promote-project-milestone-button');
- promoteMilestoneButtons.forEach(button => {
- button.addEventListener('click', onDeleteButtonClick);
- });
-
- eventHub.$once('promoteMilestoneModal.mounted', () => {
- promoteMilestoneButtons.forEach(button => {
- button.removeAttribute('disabled');
- });
- });
-
const promoteMilestoneModal = document.getElementById('promote-milestone-modal');
- let promoteMilestoneComponent;
-
- if (promoteMilestoneModal) {
- promoteMilestoneComponent = new Vue({
- el: promoteMilestoneModal,
- components: {
- PromoteMilestoneModal,
- },
- data() {
- return {
- modalProps: {
- milestoneTitle: '',
- groupName: '',
- url: '',
- },
- };
- },
- mounted() {
- eventHub.$on('promoteMilestoneModal.props', this.setModalProps);
- eventHub.$emit('promoteMilestoneModal.mounted');
- },
- beforeDestroy() {
- eventHub.$off('promoteMilestoneModal.props', this.setModalProps);
- },
- methods: {
- setModalProps(modalProps) {
- this.modalProps = modalProps;
- },
- },
- render(createElement) {
- return createElement('promote-milestone-modal', {
- props: this.modalProps,
- });
- },
- });
+ if (!promoteMilestoneModal) {
+ return null;
}
- return promoteMilestoneComponent;
+ return new Vue({
+ el: promoteMilestoneModal,
+ render(createElement) {
+ return createElement(PromoteMilestoneModal);
+ },
+ });
};
diff --git a/app/assets/javascripts/pages/profiles/index.js b/app/assets/javascripts/pages/profiles/index.js
index 883be18b336..d2b00d0ef45 100644
--- a/app/assets/javascripts/pages/profiles/index.js
+++ b/app/assets/javascripts/pages/profiles/index.js
@@ -4,7 +4,7 @@ import Profile from '~/profile/profile';
document.addEventListener('DOMContentLoaded', () => {
// eslint-disable-next-line func-names
- $(document).on('input.ssh_key', '#key_key', function() {
+ $(document).on('input.ssh_key', '#key_key', function () {
const $title = $('#key_title');
const comment = $(this)
.val()
diff --git a/app/assets/javascripts/pages/profiles/show/index.js b/app/assets/javascripts/pages/profiles/show/index.js
index 60510eac384..b78f24ca2fb 100644
--- a/app/assets/javascripts/pages/profiles/show/index.js
+++ b/app/assets/javascripts/pages/profiles/show/index.js
@@ -14,7 +14,7 @@ document.addEventListener('DOMContentLoaded', () => {
const statusEmojiField = document.getElementById('js-status-emoji-field');
const statusMessageField = document.getElementById('js-status-message-field');
- const toggleNoEmojiPlaceholder = isVisible => {
+ const toggleNoEmojiPlaceholder = (isVisible) => {
const placeholderElement = document.getElementById('js-no-emoji-placeholder');
placeholderElement.classList.toggle('hidden', !isVisible);
};
diff --git a/app/assets/javascripts/pages/projects/blob/show/index.js b/app/assets/javascripts/pages/projects/blob/show/index.js
index a96b88732b4..57c4ffd3933 100644
--- a/app/assets/javascripts/pages/projects/blob/show/index.js
+++ b/app/assets/javascripts/pages/projects/blob/show/index.js
@@ -41,7 +41,7 @@ document.addEventListener('DOMContentLoaded', () => {
const { codeNavigationPath, blobPath, definitionPathPrefix } = codeNavEl.dataset;
// eslint-disable-next-line promise/catch-or-return
- import('~/code_navigation').then(m =>
+ import('~/code_navigation').then((m) =>
m.default({
blobs: [{ path: blobPath, codeNavigationPath }],
definitionPathPrefix,
diff --git a/app/assets/javascripts/pages/projects/commit/show/index.js b/app/assets/javascripts/pages/projects/commit/show/index.js
index 0750f472341..5cfdb125e4f 100644
--- a/app/assets/javascripts/pages/projects/commit/show/index.js
+++ b/app/assets/javascripts/pages/projects/commit/show/index.js
@@ -14,6 +14,8 @@ import flash from '~/flash';
import { __ } from '~/locale';
import loadAwardsHandler from '~/awards_handler';
import { initCommitBoxInfo } from '~/projects/commit_box/info';
+import initRevertCommitTrigger from '~/projects/commit/init_revert_commit_trigger';
+import initRevertCommitModal from '~/projects/commit/init_revert_commit_modal';
const hasPerfBar = document.querySelector('.with-performance-bar');
const performanceHeight = hasPerfBar ? 35 : 0;
@@ -45,3 +47,5 @@ if (filesContainer.length) {
new Diff();
}
loadAwardsHandler();
+initRevertCommitModal();
+initRevertCommitTrigger();
diff --git a/app/assets/javascripts/pages/projects/edit/index.js b/app/assets/javascripts/pages/projects/edit/index.js
index 7eeb0c852e5..5f1d3edc3ba 100644
--- a/app/assets/javascripts/pages/projects/edit/index.js
+++ b/app/assets/javascripts/pages/projects/edit/index.js
@@ -10,6 +10,7 @@ import initProjectPermissionsSettings from '../shared/permissions';
import initProjectDeleteButton from '~/projects/project_delete_button';
import UserCallout from '~/user_callout';
import initServiceDesk from '~/projects/settings_service_desk';
+import mountSearchSettings from './mount_search_settings';
document.addEventListener('DOMContentLoaded', () => {
initFilePickers();
@@ -30,4 +31,6 @@ document.addEventListener('DOMContentLoaded', () => {
'.js-general-settings-form, .js-mr-settings-form, .js-mr-approvals-form',
),
);
+
+ mountSearchSettings();
});
diff --git a/app/assets/javascripts/pages/projects/edit/mount_search_settings.js b/app/assets/javascripts/pages/projects/edit/mount_search_settings.js
new file mode 100644
index 00000000000..6c477dd7e80
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/edit/mount_search_settings.js
@@ -0,0 +1,12 @@
+const mountSearchSettings = async () => {
+ const el = document.querySelector('.js-search-settings-app');
+
+ if (el) {
+ const { default: initSearch } = await import(
+ /* webpackChunkName: 'search_settings' */ '~/search_settings'
+ );
+ initSearch({ el });
+ }
+};
+
+export default mountSearchSettings;
diff --git a/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue b/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue
index 6c0d20c55e9..a614443bcd9 100644
--- a/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue
+++ b/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue
@@ -31,7 +31,9 @@ export default {
},
computed: {
filteredNamespaces() {
- return this.namespaces.filter(n => n.name.toLowerCase().includes(this.filter.toLowerCase()));
+ return this.namespaces.filter((n) =>
+ n.name.toLowerCase().includes(this.filter.toLowerCase()),
+ );
},
},
@@ -43,7 +45,7 @@ export default {
loadGroups() {
axios
.get(this.endpoint)
- .then(response => {
+ .then((response) => {
this.namespaces = response.data.namespaces;
})
.catch(() => createFlash(__('There was a problem fetching groups.')));
diff --git a/app/assets/javascripts/pages/projects/graphs/charts/index.js b/app/assets/javascripts/pages/projects/graphs/charts/index.js
index 6cf36463bda..ea38b8e15a4 100644
--- a/app/assets/javascripts/pages/projects/graphs/charts/index.js
+++ b/app/assets/javascripts/pages/projects/graphs/charts/index.js
@@ -5,7 +5,7 @@ import { __ } from '~/locale';
import CodeCoverage from '../components/code_coverage.vue';
import SeriesDataMixin from './series_data_mixin';
-const seriesDataToBarData = raw => Object.entries(raw).map(([name, data]) => ({ name, data }));
+const seriesDataToBarData = (raw) => Object.entries(raw).map(([name, data]) => ({ name, data }));
document.addEventListener('DOMContentLoaded', () => {
waitForCSSLoaded(() => {
@@ -43,7 +43,7 @@ document.addEventListener('DOMContentLoaded', () => {
},
computed: {
seriesData() {
- return [{ name: 'full', data: this.chartData.map(d => [d.label, d.value]) }];
+ return [{ name: 'full', data: this.chartData.map((d) => [d.label, d.value]) }];
},
},
render(h) {
diff --git a/app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue b/app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue
index 6dd50958fa4..3b5e764b712 100644
--- a/app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue
+++ b/app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue
@@ -74,7 +74,7 @@ export default {
);
},
formattedData() {
- return this.sortedData.map(value => [dateFormat(value.date, 'mmm dd'), value.coverage]);
+ return this.sortedData.map((value) => [dateFormat(value.date, 'mmm dd'), value.coverage]);
},
chartData() {
return [
@@ -161,9 +161,7 @@ export default {
<template #coveragePercentage>
{{ coveragePercentage }}
</template>
- <template #percentSymbol>
- %
- </template>
+ <template #percentSymbol> % </template>
</gl-sprintf>
</template>
</gl-area-chart>
diff --git a/app/assets/javascripts/pages/projects/init_form.js b/app/assets/javascripts/pages/projects/init_form.js
index 019efe077f7..9f20a3e4e46 100644
--- a/app/assets/javascripts/pages/projects/init_form.js
+++ b/app/assets/javascripts/pages/projects/init_form.js
@@ -1,7 +1,7 @@
import ZenMode from '~/zen_mode';
import GLForm from '~/gl_form';
-export default function($formEl) {
+export default function ($formEl) {
new ZenMode(); // eslint-disable-line no-new
new GLForm($formEl); // eslint-disable-line no-new
}
diff --git a/app/assets/javascripts/pages/projects/issues/service_desk/filtered_search.js b/app/assets/javascripts/pages/projects/issues/service_desk/filtered_search.js
index fc0922d9112..ccb453a59ea 100644
--- a/app/assets/javascripts/pages/projects/issues/service_desk/filtered_search.js
+++ b/app/assets/javascripts/pages/projects/issues/service_desk/filtered_search.js
@@ -21,7 +21,7 @@ export default class FilteredSearchServiceDesk extends FilteredSearchManager {
modifyUrlParams(paramsArray) {
const supportBotParamPair = `${AUTHOR_PARAM_KEY}=${this.supportBotData.username}`;
- const onlyValidParams = paramsArray.filter(param => param.indexOf(AUTHOR_PARAM_KEY) === -1);
+ const onlyValidParams = paramsArray.filter((param) => param.indexOf(AUTHOR_PARAM_KEY) === -1);
// unshift ensures author param is always first token element
onlyValidParams.unshift(supportBotParamPair);
diff --git a/app/assets/javascripts/pages/projects/issues/show.js b/app/assets/javascripts/pages/projects/issues/show.js
index 614f8262e5b..7068574ecb8 100644
--- a/app/assets/javascripts/pages/projects/issues/show.js
+++ b/app/assets/javascripts/pages/projects/issues/show.js
@@ -16,7 +16,7 @@ import initInviteMemberModal from '~/invite_member/init_invite_member_modal';
import { IssuableType } from '~/issuable_show/constants';
-export default function() {
+export default function () {
const initialDataEl = document.getElementById('js-issuable-app');
const { issueType, ...issuableData } = parseIssuableData(initialDataEl);
@@ -37,7 +37,7 @@ export default function() {
initRelatedMergeRequestsApp();
import(/* webpackChunkName: 'design_management' */ '~/design_management')
- .then(module => module.default())
+ .then((module) => module.default())
.catch(() => {});
new ZenMode(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/projects/jobs/index/index.js b/app/assets/javascripts/pages/projects/jobs/index/index.js
index ae04d070e62..c343a37b292 100644
--- a/app/assets/javascripts/pages/projects/jobs/index/index.js
+++ b/app/assets/javascripts/pages/projects/jobs/index/index.js
@@ -5,7 +5,7 @@ import Tracking from '~/tracking';
document.addEventListener('DOMContentLoaded', () => {
const remainingTimeElements = document.querySelectorAll('.js-remaining-time');
remainingTimeElements.forEach(
- el =>
+ (el) =>
new Vue({
...GlCountdown,
el,
@@ -22,5 +22,5 @@ document.addEventListener('DOMContentLoaded', () => {
}
};
const buttons = document.querySelectorAll('.js-empty-state-button');
- buttons.forEach(button => button.addEventListener('click', trackButtonClick));
+ buttons.forEach((button) => button.addEventListener('click', trackButtonClick));
});
diff --git a/app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue b/app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue
index 7b5e0f70b7b..8626fd18233 100644
--- a/app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue
+++ b/app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue
@@ -58,14 +58,14 @@ export default {
eventHub.$emit('promoteLabelModal.requestStarted', this.url);
return axios
.post(this.url, { params: { format: 'json' } })
- .then(response => {
+ .then((response) => {
eventHub.$emit('promoteLabelModal.requestFinished', {
labelUrl: this.url,
successful: true,
});
visitUrl(response.data.url);
})
- .catch(error => {
+ .catch((error) => {
eventHub.$emit('promoteLabelModal.requestFinished', {
labelUrl: this.url,
successful: false,
diff --git a/app/assets/javascripts/pages/projects/labels/index/index.js b/app/assets/javascripts/pages/projects/labels/index/index.js
index ee129011f9a..4f5e5c8cceb 100644
--- a/app/assets/javascripts/pages/projects/labels/index/index.js
+++ b/app/assets/javascripts/pages/projects/labels/index/index.js
@@ -19,7 +19,7 @@ const initLabelIndex = () => {
}
};
- const onRequestStarted = labelUrl => {
+ const onRequestStarted = (labelUrl) => {
const button = document.querySelector(
`.js-promote-project-label-button[data-url="${labelUrl}"]`,
);
@@ -46,7 +46,7 @@ const initLabelIndex = () => {
eventHub.$on('promoteLabelModal.props', this.setModalProps);
eventHub.$emit('promoteLabelModal.mounted');
- promoteLabelButtons.forEach(button => {
+ promoteLabelButtons.forEach((button) => {
button.removeAttribute('disabled');
button.addEventListener('click', () => {
this.$root.$emit('bv::show::modal', 'promote-label-modal');
@@ -77,5 +77,4 @@ const initLabelIndex = () => {
},
});
};
-
-document.addEventListener('DOMContentLoaded', initLabelIndex);
+initLabelIndex();
diff --git a/app/assets/javascripts/pages/projects/labels/new/index.js b/app/assets/javascripts/pages/projects/labels/new/index.js
index 83d6ac9fd14..2e8308fe084 100644
--- a/app/assets/javascripts/pages/projects/labels/new/index.js
+++ b/app/assets/javascripts/pages/projects/labels/new/index.js
@@ -1,3 +1,4 @@
import Labels from 'ee_else_ce/labels';
-document.addEventListener('DOMContentLoaded', () => new Labels());
+// eslint-disable-next-line no-new
+new Labels();
diff --git a/app/assets/javascripts/pages/projects/merge_requests/creations/new/compare.js b/app/assets/javascripts/pages/projects/merge_requests/creations/new/compare.js
index 46f3f55a400..eb2692c7cb4 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/creations/new/compare.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/creations/new/compare.js
@@ -19,7 +19,7 @@ const updateCommitList = (url, $loadingIndicator, $commitList, params) => {
});
};
-export default mrNewCompareNode => {
+export default (mrNewCompareNode) => {
const { sourceBranchUrl, targetBranchUrl } = mrNewCompareNode.dataset;
initTargetProjectDropdown();
@@ -29,9 +29,7 @@ export default mrNewCompareNode => {
$(mrNewCompareNode).find('.js-source-loading'),
$(mrNewCompareNode).find('.mr_source_commit'),
{
- ref: $(mrNewCompareNode)
- .find("input[name='merge_request[source_branch]']")
- .val(),
+ ref: $(mrNewCompareNode).find("input[name='merge_request[source_branch]']").val(),
},
);
const updateTargetBranchCommitList = () =>
@@ -43,12 +41,10 @@ export default mrNewCompareNode => {
target_project_id: $(mrNewCompareNode)
.find("input[name='merge_request[target_project_id]']")
.val(),
- ref: $(mrNewCompareNode)
- .find("input[name='merge_request[target_branch]']")
- .val(),
+ ref: $(mrNewCompareNode).find("input[name='merge_request[target_branch]']").val(),
},
);
- initCompareAutocomplete('branches', $dropdown => {
+ initCompareAutocomplete('branches', ($dropdown) => {
if ($dropdown.is('.js-target-branch')) {
updateTargetBranchCommitList();
} else if ($dropdown.is('.js-source-branch')) {
diff --git a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
index 0714fc21b17..1a0c5860991 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
@@ -1,3 +1,4 @@
+import Vue from 'vue';
import ZenMode from '~/zen_mode';
import initIssuableSidebar from '~/init_issuable_sidebar';
import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable';
@@ -7,8 +8,9 @@ import initSourcegraph from '~/sourcegraph';
import loadAwardsHandler from '~/awards_handler';
import initInviteMemberTrigger from '~/invite_member/init_invite_member_trigger';
import initInviteMemberModal from '~/invite_member/init_invite_member_modal';
+import StatusBox from '~/merge_request/components/status_box.vue';
-export default function() {
+export default function () {
new ZenMode(); // eslint-disable-line no-new
initIssuableSidebar();
initPipelines();
@@ -18,4 +20,17 @@ export default function() {
loadAwardsHandler();
initInviteMemberModal();
initInviteMemberTrigger();
+
+ const el = document.querySelector('.js-mr-status-box');
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ render(h) {
+ return h(StatusBox, {
+ props: {
+ initialState: el.dataset.state,
+ },
+ });
+ },
+ });
}
diff --git a/app/assets/javascripts/pages/projects/new/index.js b/app/assets/javascripts/pages/projects/new/index.js
index 19aeb1d1ecf..88f4db3ec08 100644
--- a/app/assets/javascripts/pages/projects/new/index.js
+++ b/app/assets/javascripts/pages/projects/new/index.js
@@ -10,7 +10,7 @@ document.addEventListener('DOMContentLoaded', () => {
import(
/* webpackChunkName: 'experiment_new_project_creation' */ '../../../projects/experiment_new_project_creation'
)
- .then(m => {
+ .then((m) => {
const el = document.querySelector('.js-experiment-new-project-creation');
if (!el) {
@@ -20,6 +20,7 @@ document.addEventListener('DOMContentLoaded', () => {
const config = {
hasErrors: 'hasErrors' in el.dataset,
isCiCdAvailable: 'isCiCdAvailable' in el.dataset,
+ newProjectGuidelines: el.dataset.newProjectGuidelines,
};
m.default(el, config);
})
diff --git a/app/assets/javascripts/pages/projects/pages_domains/form.js b/app/assets/javascripts/pages/projects/pages_domains/form.js
index ae5368179b1..169530685ad 100644
--- a/app/assets/javascripts/pages/projects/pages_domains/form.js
+++ b/app/assets/javascripts/pages/projects/pages_domains/form.js
@@ -1,7 +1,7 @@
import setupToggleButtons from '~/toggle_buttons';
function updateVisibility(selector, isVisible) {
- Array.from(document.querySelectorAll(selector)).forEach(el => {
+ Array.from(document.querySelectorAll(selector)).forEach((el) => {
if (isVisible) {
el.classList.remove('d-none');
} else {
@@ -14,12 +14,12 @@ export default () => {
const toggleContainer = document.querySelector('.js-auto-ssl-toggle-container');
if (toggleContainer) {
- const onToggleButtonClicked = isAutoSslEnabled => {
+ const onToggleButtonClicked = (isAutoSslEnabled) => {
updateVisibility('.js-shown-unless-auto-ssl', !isAutoSslEnabled);
updateVisibility('.js-shown-if-auto-ssl', isAutoSslEnabled);
- Array.from(document.querySelectorAll('.js-enabled-unless-auto-ssl')).forEach(el => {
+ Array.from(document.querySelectorAll('.js-enabled-unless-auto-ssl')).forEach((el) => {
if (isAutoSslEnabled) {
el.setAttribute('disabled', 'disabled');
} else {
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js b/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js
index 90d2df50d5a..40730ec7e60 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/index/index.js
@@ -13,12 +13,12 @@ document.addEventListener('DOMContentLoaded', () => {
// eslint-disable-next-line no-new
new Vue({
el,
- render(createElement) {
- return createElement(PipelineSchedulesCallout);
- },
provide: {
docsUrl,
illustrationUrl,
},
+ render(createElement) {
+ return createElement(PipelineSchedulesCallout);
+ },
});
});
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue
index 5ef1f959b2c..aa7414f3ae7 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue
@@ -125,7 +125,7 @@ export default {
:data-testid="option.value"
>
<gl-sprintf v-if="option.link" :message="option.text">
- <template #link="{content}">
+ <template #link="{ content }">
<gl-link :href="option.link" target="_blank" class="gl-font-sm">
{{ content }}
</gl-link>
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/target_branch_dropdown.js b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/target_branch_dropdown.js
index 4b203891640..6017cd653e4 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/target_branch_dropdown.js
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/target_branch_dropdown.js
@@ -15,19 +15,19 @@ export default class TargetBranchDropdown {
data: this.formatBranchesList(),
filterable: true,
selectable: true,
- toggleLabel: item => item.name,
+ toggleLabel: (item) => item.name,
search: {
fields: ['name'],
},
- clicked: cfg => this.updateInputValue(cfg),
- text: item => item.name,
+ clicked: (cfg) => this.updateInputValue(cfg),
+ text: (item) => item.name,
});
this.setDropdownToggle();
}
formatBranchesList() {
- return this.$dropdown.data('data').map(val => ({ name: val }));
+ return this.$dropdown.data('data').map((val) => ({ name: val }));
}
setDropdownToggle() {
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js
index 2a58e015ff1..16c4a6191b2 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown.js
@@ -5,10 +5,10 @@ const defaults = {
$inputEl: null,
$dropdownEl: null,
onSelectTimezone: null,
- displayFormat: item => item.name,
+ displayFormat: (item) => item.name,
};
-export const formatUtcOffset = offset => {
+export const formatUtcOffset = (offset) => {
const parsed = parseInt(offset, 10);
if (Number.isNaN(parsed) || parsed === 0) {
return `0`;
@@ -17,11 +17,11 @@ export const formatUtcOffset = offset => {
return `${prefix} ${Math.abs(offset / 3600)}`;
};
-export const formatTimezone = item => `[UTC ${formatUtcOffset(item.offset)}] ${item.name}`;
+export const formatTimezone = (item) => `[UTC ${formatUtcOffset(item.offset)}] ${item.name}`;
export const findTimezoneByIdentifier = (tzList = [], identifier = null) => {
if (tzList && tzList.length && identifier && identifier.length) {
- return tzList.find(tz => tz.identifier === identifier) || null;
+ return tzList.find((tz) => tz.identifier === identifier) || null;
}
return null;
};
@@ -52,8 +52,8 @@ export default class TimezoneDropdown {
search: {
fields: ['name'],
},
- clicked: cfg => this.updateInputValue(cfg),
- text: item => formatTimezone(item),
+ clicked: (cfg) => this.updateInputValue(cfg),
+ text: (item) => formatTimezone(item),
});
this.setDropdownToggle(this.displayFormat(this.initialTimezone));
diff --git a/app/assets/javascripts/pages/projects/pipelines/charts/index.js b/app/assets/javascripts/pages/projects/pipelines/charts/index.js
index d77b84a3b24..44d7555e639 100644
--- a/app/assets/javascripts/pages/projects/pipelines/charts/index.js
+++ b/app/assets/javascripts/pages/projects/pipelines/charts/index.js
@@ -1,3 +1,3 @@
import initProjectPipelinesChartsApp from '~/projects/pipelines/charts/index';
-document.addEventListener('DOMContentLoaded', initProjectPipelinesChartsApp);
+initProjectPipelinesChartsApp();
diff --git a/app/assets/javascripts/pages/projects/pipelines/init_pipelines.js b/app/assets/javascripts/pages/projects/pipelines/init_pipelines.js
index 5fd3fce88aa..0c29f8817e7 100644
--- a/app/assets/javascripts/pages/projects/pipelines/init_pipelines.js
+++ b/app/assets/javascripts/pages/projects/pipelines/init_pipelines.js
@@ -6,7 +6,7 @@ export default () => {
const fullMergeRequestList = document.querySelector('.js-full-mr-list');
if (mergeRequestListToggle) {
- mergeRequestListToggle.addEventListener('click', e => {
+ mergeRequestListToggle.addEventListener('click', (e) => {
e.preventDefault();
truncatedMergeRequestList.classList.toggle('hide');
fullMergeRequestList.classList.toggle('hide');
diff --git a/app/assets/javascripts/pages/projects/pipelines/new/index.js b/app/assets/javascripts/pages/projects/pipelines/new/index.js
index d5563143f0c..08c31f2b3c6 100644
--- a/app/assets/javascripts/pages/projects/pipelines/new/index.js
+++ b/app/assets/javascripts/pages/projects/pipelines/new/index.js
@@ -3,17 +3,15 @@ import NewBranchForm from '~/new_branch_form';
import setupNativeFormVariableList from '~/ci_variable_list/native_form_variable_list';
import initNewPipeline from '~/pipeline_new/index';
-document.addEventListener('DOMContentLoaded', () => {
- const el = document.getElementById('js-new-pipeline');
+const el = document.getElementById('js-new-pipeline');
- if (el) {
- initNewPipeline();
- } else {
- new NewBranchForm($('.js-new-pipeline-form')); // eslint-disable-line no-new
+if (el) {
+ initNewPipeline();
+} else {
+ new NewBranchForm($('.js-new-pipeline-form')); // eslint-disable-line no-new
- setupNativeFormVariableList({
- container: $('.js-ci-variable-list-section'),
- formField: 'variables_attributes',
- });
- }
-});
+ setupNativeFormVariableList({
+ container: $('.js-ci-variable-list-section'),
+ formField: 'variables_attributes',
+ });
+}
diff --git a/app/assets/javascripts/pages/projects/project.js b/app/assets/javascripts/pages/projects/project.js
index 8c7aa04a0b6..ef6953db83b 100644
--- a/app/assets/javascripts/pages/projects/project.js
+++ b/app/assets/javascripts/pages/projects/project.js
@@ -18,34 +18,26 @@ export default class Project {
// Ref switcher
if (document.querySelector('.js-project-refs-dropdown')) {
Project.initRefSwitcher();
- $('.project-refs-select').on('change', function() {
- return $(this)
- .parents('form')
- .trigger('submit');
+ $('.project-refs-select').on('change', function () {
+ return $(this).parents('form').trigger('submit');
});
}
- $('.hide-no-ssh-message').on('click', function(e) {
+ $('.hide-no-ssh-message').on('click', function (e) {
Cookies.set('hide_no_ssh_message', 'false');
- $(this)
- .parents('.no-ssh-key-message')
- .remove();
+ $(this).parents('.no-ssh-key-message').remove();
return e.preventDefault();
});
- $('.hide-no-password-message').on('click', function(e) {
+ $('.hide-no-password-message').on('click', function (e) {
Cookies.set('hide_no_password_message', 'false');
- $(this)
- .parents('.no-password-message')
- .remove();
+ $(this).parents('.no-password-message').remove();
return e.preventDefault();
});
- $('.hide-auto-devops-implicitly-enabled-banner').on('click', function(e) {
+ $('.hide-auto-devops-implicitly-enabled-banner').on('click', function (e) {
const projectId = $(this).data('project-id');
const cookieKey = `hide_auto_devops_implicitly_enabled_banner_${projectId}`;
Cookies.set(cookieKey, 'false');
- $(this)
- .parents('.auto-devops-implicitly-enabled-banner')
- .remove();
+ $(this).parents('.auto-devops-implicitly-enabled-banner').remove();
return e.preventDefault();
});
@@ -54,7 +46,7 @@ export default class Project {
static projectSelectDropdown() {
projectSelect();
- $('.project-item-select').on('click', e => Project.changeProject($(e.currentTarget).val()));
+ $('.project-item-select').on('click', (e) => Project.changeProject($(e.currentTarget).val()));
}
static changeProject(url) {
@@ -67,7 +59,7 @@ export default class Project {
refLink.href = '#';
- return $('.js-project-refs-dropdown').each(function() {
+ return $('.js-project-refs-dropdown').each(function () {
const $dropdown = $(this);
const selected = $dropdown.data('selected');
const fieldName = $dropdown.data('fieldName');
@@ -132,7 +124,7 @@ export default class Project {
if (loc.includes('/-/')) {
const refs = this.fullData.Branches.concat(this.fullData.Tags);
- const currentRef = refs.find(ref => loc.indexOf(ref) > -1);
+ const currentRef = refs.find((ref) => loc.indexOf(ref) > -1);
if (currentRef) {
const targetPath = loc.split(currentRef)[1].slice(1);
selectedUrl.searchParams.set('path', targetPath);
diff --git a/app/assets/javascripts/pages/projects/project_members/index.js b/app/assets/javascripts/pages/projects/project_members/index.js
index e146592e134..3e0a48ee6a2 100644
--- a/app/assets/javascripts/pages/projects/project_members/index.js
+++ b/app/assets/javascripts/pages/projects/project_members/index.js
@@ -1,9 +1,11 @@
import Vue from 'vue';
-import Members from 'ee_else_ce/members';
+import Members from '~/members';
import memberExpirationDate from '~/member_expiration_date';
import UsersSelect from '~/users_select';
import groupsSelect from '~/groups_select';
import RemoveMemberModal from '~/vue_shared/components/remove_member_modal.vue';
+import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
+import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
function mountRemoveMemberModal() {
const el = document.querySelector('.js-remove-member-modal');
@@ -24,6 +26,8 @@ document.addEventListener('DOMContentLoaded', () => {
memberExpirationDate();
memberExpirationDate('.js-access-expiration-date-groups');
mountRemoveMemberModal();
+ initInviteMembersModal();
+ initInviteMembersTrigger();
new Members(); // eslint-disable-line no-new
new UsersSelect(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js b/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js
index 83bec0092cb..1321155b7ec 100644
--- a/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js
+++ b/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js
@@ -5,6 +5,7 @@ import initVariableList from '~/ci_variable_list';
import initDeployFreeze from '~/deploy_freeze';
import initSettingsPipelinesTriggers from '~/ci_settings_pipeline_triggers';
import initSharedRunnersToggle from '~/projects/settings/mount_shared_runners_toggle';
+import initArtifactsSettings from '~/artifacts_settings';
document.addEventListener('DOMContentLoaded', () => {
// Initialize expandable settings panels
@@ -23,7 +24,7 @@ document.addEventListener('DOMContentLoaded', () => {
// hide extra auto devops settings based checkbox state
const autoDevOpsExtraSettings = document.querySelector('.js-extra-settings');
const instanceDefaultBadge = document.querySelector('.js-instance-default-badge');
- document.querySelector('.js-toggle-extra-settings').addEventListener('click', event => {
+ document.querySelector('.js-toggle-extra-settings').addEventListener('click', (event) => {
const { target } = event;
if (instanceDefaultBadge) instanceDefaultBadge.style.display = 'none';
autoDevOpsExtraSettings.classList.toggle('hidden', !target.checked);
@@ -33,6 +34,7 @@ document.addEventListener('DOMContentLoaded', () => {
initDeployFreeze();
initSettingsPipelinesTriggers();
+ initArtifactsSettings();
if (gon?.features?.vueifySharedRunnersToggle) {
initSharedRunnersToggle();
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/project_feature_setting.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/project_feature_setting.vue
index 242c58c4981..eee666bea05 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/components/project_feature_setting.vue
+++ b/app/assets/javascripts/pages/projects/shared/permissions/components/project_feature_setting.vue
@@ -33,6 +33,11 @@ export default {
required: false,
default: false,
},
+ showToggle: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
},
computed: {
featureEnabled() {
@@ -74,6 +79,7 @@ export default {
>
<input v-if="name" :name="name" :value="value" type="hidden" />
<project-feature-toggle
+ v-if="showToggle"
class="gl-flex-grow-0 gl-mr-3"
:value="featureEnabled"
:disabled-input="disabledInput"
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
index be197a50775..4af476fbd68 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
+++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
@@ -12,6 +12,7 @@ import {
featureAccessLevelMembers,
featureAccessLevelEveryone,
featureAccessLevel,
+ featureAccessLevelNone,
} from '../constants';
import { toggleHiddenClassBySelector } from '../external';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
@@ -140,6 +141,7 @@ export default {
metricsDashboardAccessLevel: featureAccessLevel.PROJECT_MEMBERS,
analyticsAccessLevel: featureAccessLevel.EVERYONE,
requirementsAccessLevel: featureAccessLevel.EVERYONE,
+ operationsAccessLevel: featureAccessLevel.EVERYONE,
containerRegistryEnabled: true,
lfsEnabled: true,
requestAccessEnabled: true,
@@ -167,6 +169,14 @@ export default {
);
},
+ operationsFeatureAccessLevelOptions() {
+ if (!this.operationsEnabled) return [featureAccessLevelNone];
+
+ return this.featureAccessLevelOptions.filter(
+ ([value]) => value <= this.operationsAccessLevel,
+ );
+ },
+
pagesFeatureAccessLevelOptions() {
const options = [featureAccessLevelMembers];
@@ -186,8 +196,12 @@ export default {
return options;
},
- metricsOptionsDropdownEnabled() {
- return this.featureAccessLevelOptions.length < 2;
+ metricsOptionsDropdownDisabled() {
+ return this.operationsFeatureAccessLevelOptions.length < 2 || !this.operationsEnabled;
+ },
+
+ operationsEnabled() {
+ return this.operationsAccessLevel > featureAccessLevel.NOT_ENABLED;
},
repositoryEnabled() {
@@ -250,6 +264,10 @@ export default {
featureAccessLevel.PROJECT_MEMBERS,
this.requirementsAccessLevel,
);
+ this.operationsAccessLevel = Math.min(
+ featureAccessLevel.PROJECT_MEMBERS,
+ this.operationsAccessLevel,
+ );
if (this.pagesAccessLevel === featureAccessLevel.EVERYONE) {
// When from Internal->Private narrow access for only members
this.pagesAccessLevel = featureAccessLevel.PROJECT_MEMBERS;
@@ -277,6 +295,8 @@ export default {
this.metricsDashboardAccessLevel = featureAccessLevel.EVERYONE;
if (this.requirementsAccessLevel === featureAccessLevel.PROJECT_MEMBERS)
this.requirementsAccessLevel = featureAccessLevel.EVERYONE;
+ if (this.operationsAccessLevel === featureAccessLevel.PROJECT_MEMBERS)
+ this.operationsAccessLevel = featureAccessLevel.EVERYONE;
this.highlightChanges();
}
@@ -334,18 +354,21 @@ export default {
<option
:value="visibilityOptions.PRIVATE"
:disabled="!visibilityAllowed(visibilityOptions.PRIVATE)"
- >{{ s__('ProjectSettings|Private') }}</option
>
+ {{ s__('ProjectSettings|Private') }}
+ </option>
<option
:value="visibilityOptions.INTERNAL"
:disabled="!visibilityAllowed(visibilityOptions.INTERNAL)"
- >{{ s__('ProjectSettings|Internal') }}</option
>
+ {{ s__('ProjectSettings|Internal') }}
+ </option>
<option
:value="visibilityOptions.PUBLIC"
:disabled="!visibilityAllowed(visibilityOptions.PUBLIC)"
- >{{ s__('ProjectSettings|Public') }}</option
>
+ {{ s__('ProjectSettings|Public') }}
+ </option>
</select>
<gl-icon
name="chevron-down"
@@ -354,6 +377,11 @@ export default {
/>
</div>
</div>
+ <span v-if="!visibilityAllowed(visibilityLevel)" class="form-text text-muted">{{
+ s__(
+ 'ProjectSettings|Visibility options for this fork are limited by the current visibility of the source project.',
+ )
+ }}</span>
<span class="form-text text-muted">{{ visibilityLevelDescription }}</span>
<label v-if="visibilityLevel !== visibilityOptions.PRIVATE" class="gl-line-height-28">
<input
@@ -562,41 +590,34 @@ export default {
/>
</project-setting-row>
<project-setting-row
- ref="metrics-visibility-settings"
- :label="__('Metrics Dashboard')"
- :help-text="
- s__(
- 'ProjectSettings|With Metrics Dashboard you can visualize this project performance metrics',
- )
- "
+ ref="operations-settings"
+ :label="s__('ProjectSettings|Operations')"
+ :help-text="s__('ProjectSettings|Environments, logs, cluster management, and more')"
>
- <div class="project-feature-controls gl-display-flex gl-align-items-center gl-my-3 gl-mx-0">
- <div class="select-wrapper gl-flex-fill-1">
- <select
- v-model="metricsDashboardAccessLevel"
- :disabled="metricsOptionsDropdownEnabled"
- name="project[project_feature_attributes][metrics_dashboard_access_level]"
- class="form-control project-repo-select select-control"
- >
- <option
- :value="featureAccessLevelMembers[0]"
- :disabled="!visibilityAllowed(visibilityOptions.INTERNAL)"
- >{{ featureAccessLevelMembers[1] }}</option
- >
- <option
- :value="featureAccessLevelEveryone[0]"
- :disabled="!visibilityAllowed(visibilityOptions.PUBLIC)"
- >{{ featureAccessLevelEveryone[1] }}</option
- >
- </select>
- <gl-icon
- name="chevron-down"
- data-hidden="true"
- class="gl-absolute gl-top-3 gl-right-3 gl-text-gray-500"
- />
- </div>
- </div>
+ <project-feature-setting
+ v-model="operationsAccessLevel"
+ :options="featureAccessLevelOptions"
+ name="project[project_feature_attributes][operations_access_level]"
+ />
</project-setting-row>
+ <div class="project-feature-setting-group gl-pl-7 gl-sm-pl-5">
+ <project-setting-row
+ ref="metrics-visibility-settings"
+ :label="__('Metrics Dashboard')"
+ :help-text="
+ s__(
+ 'ProjectSettings|With Metrics Dashboard you can visualize this project performance metrics',
+ )
+ "
+ >
+ <project-feature-setting
+ v-model="metricsDashboardAccessLevel"
+ :show-toggle="false"
+ :options="operationsFeatureAccessLevelOptions"
+ name="project[project_feature_attributes][metrics_dashboard_access_level]"
+ />
+ </project-setting-row>
+ </div>
</div>
<project-setting-row v-if="canDisableEmails" ref="email-settings" class="mb-3">
<label class="js-emails-disabled">
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/external.js b/app/assets/javascripts/pages/projects/shared/permissions/external.js
index 460af4a2111..49f6ebcc20f 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/external.js
+++ b/app/assets/javascripts/pages/projects/shared/permissions/external.js
@@ -14,5 +14,5 @@ export function toggleHiddenClassBySelector(selector, hidden) {
if (!selectorCache[selector]) {
selectorCache[selector] = document.querySelectorAll(selector);
}
- selectorCache[selector].forEach(elm => toggleHiddenClass(elm, hidden));
+ selectorCache[selector].forEach((elm) => toggleHiddenClass(elm, hidden));
}
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/index.js b/app/assets/javascripts/pages/projects/shared/permissions/index.js
index dbde8dda634..d7bae44e96e 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/index.js
+++ b/app/assets/javascripts/pages/projects/shared/permissions/index.js
@@ -8,6 +8,6 @@ export default function initProjectPermissionsSettings() {
return new Vue({
el: mountPoint,
- render: createElement => createElement(settingsPanel, { props: { ...componentProps } }),
+ render: (createElement) => createElement(settingsPanel, { props: { ...componentProps } }),
});
}
diff --git a/app/assets/javascripts/pages/projects/tags/index/index.js b/app/assets/javascripts/pages/projects/tags/index/index.js
index ec56fa3e075..96e52850936 100644
--- a/app/assets/javascripts/pages/projects/tags/index/index.js
+++ b/app/assets/javascripts/pages/projects/tags/index/index.js
@@ -2,11 +2,8 @@ import { initRemoveTag } from '../remove_tag';
document.addEventListener('DOMContentLoaded', () => {
initRemoveTag({
- onDelete: path => {
- document
- .querySelector(`[data-path="${path}"]`)
- .closest('.js-tag-list')
- .remove();
+ onDelete: (path) => {
+ document.querySelector(`[data-path="${path}"]`).closest('.js-tag-list').remove();
},
});
});
diff --git a/app/assets/javascripts/pages/search/show/refresh_counts.js b/app/assets/javascripts/pages/search/show/refresh_counts.js
index fa75ee6075d..f3f6312cb7c 100644
--- a/app/assets/javascripts/pages/search/show/refresh_counts.js
+++ b/app/assets/javascripts/pages/search/show/refresh_counts.js
@@ -11,7 +11,7 @@ function refreshCount(el) {
return axios
.get(url)
.then(({ data }) => showCount(el, data.count))
- .catch(e => {
+ .catch((e) => {
// eslint-disable-next-line no-console
console.error(`Failed to fetch search count from '${url}'.`, e);
});
diff --git a/app/assets/javascripts/pages/search/show/search.js b/app/assets/javascripts/pages/search/show/search.js
index b411b637f36..cbef5ab1bbc 100644
--- a/app/assets/javascripts/pages/search/show/search.js
+++ b/app/assets/javascripts/pages/search/show/search.js
@@ -16,16 +16,12 @@ export default class Search {
}
eventListeners() {
- $(document)
- .off('keyup', this.searchInput)
- .on('keyup', this.searchInput, this.searchKeyUp);
+ $(document).off('keyup', this.searchInput).on('keyup', this.searchInput, this.searchKeyUp);
$(document)
.off('click', this.searchClear)
.on('click', this.searchClear, this.clearSearchField.bind(this));
- $('a.js-search-clear')
- .off('click', this.clearSearchFilter)
- .on('click', this.clearSearchFilter);
+ $('a.js-search-clear').off('click', this.clearSearchFilter).on('click', this.clearSearchFilter);
}
static submitSearch() {
@@ -42,10 +38,7 @@ export default class Search {
}
clearSearchField() {
- return $(this.searchInput)
- .val('')
- .trigger('keyup')
- .focus();
+ return $(this.searchInput).val('').trigger('keyup').focus();
}
// We need to manually follow the link on the anchors
diff --git a/app/assets/javascripts/pages/sessions/new/length_validator.js b/app/assets/javascripts/pages/sessions/new/length_validator.js
index 92482c81f3c..17acad10bc1 100644
--- a/app/assets/javascripts/pages/sessions/new/length_validator.js
+++ b/app/assets/javascripts/pages/sessions/new/length_validator.js
@@ -9,7 +9,7 @@ export default class LengthValidator extends InputValidator {
const container = opts.container || '';
const validateLengthElements = document.querySelectorAll(`${container} .js-validate-length`);
- validateLengthElements.forEach(element =>
+ validateLengthElements.forEach((element) =>
element.addEventListener('input', this.eventHandler.bind(this)),
);
}
diff --git a/app/assets/javascripts/pages/sessions/new/preserve_url_fragment.js b/app/assets/javascripts/pages/sessions/new/preserve_url_fragment.js
index 1d47a9aed47..70e5e336e78 100644
--- a/app/assets/javascripts/pages/sessions/new/preserve_url_fragment.js
+++ b/app/assets/javascripts/pages/sessions/new/preserve_url_fragment.js
@@ -13,7 +13,7 @@ export default function preserveUrlFragment(fragment = '') {
// Append the fragment to all sign-in/sign-up form actions so it is preserved when the user is
// eventually redirected back to the originally requested URL.
const forms = document.querySelectorAll('#signin-container .tab-content form');
- Array.prototype.forEach.call(forms, form => {
+ Array.prototype.forEach.call(forms, (form) => {
const actionWithFragment = setUrlFragment(form.getAttribute('action'), `#${normalFragment}`);
form.setAttribute('action', actionWithFragment);
});
@@ -21,7 +21,7 @@ export default function preserveUrlFragment(fragment = '') {
// Append a redirect_fragment query param to all oauth provider links. The redirect_fragment
// query param will be available in the omniauth callback upon successful authentication
const oauthForms = document.querySelectorAll('#signin-container .omniauth-container form');
- Array.prototype.forEach.call(oauthForms, oauthForm => {
+ Array.prototype.forEach.call(oauthForms, (oauthForm) => {
const newHref = mergeUrlParams(
{ redirect_fragment: normalFragment },
oauthForm.getAttribute('action'),
diff --git a/app/assets/javascripts/pages/sessions/new/signin_tabs_memoizer.js b/app/assets/javascripts/pages/sessions/new/signin_tabs_memoizer.js
index 2b8f1e8b0ef..1e7c29aefaa 100644
--- a/app/assets/javascripts/pages/sessions/new/signin_tabs_memoizer.js
+++ b/app/assets/javascripts/pages/sessions/new/signin_tabs_memoizer.js
@@ -20,7 +20,7 @@ export default class SigninTabsMemoizer {
bootstrap() {
const tabs = document.querySelectorAll(this.tabSelector);
if (tabs.length > 0) {
- tabs[0].addEventListener('click', e => {
+ tabs[0].addEventListener('click', (e) => {
if (e.target && e.target.nodeName === 'A') {
const anchorName = e.target.getAttribute('href');
this.saveData(anchorName);
diff --git a/app/assets/javascripts/pages/sessions/new/username_validator.js b/app/assets/javascripts/pages/sessions/new/username_validator.js
index 62f6e3fb84f..f3b0948a40d 100644
--- a/app/assets/javascripts/pages/sessions/new/username_validator.js
+++ b/app/assets/javascripts/pages/sessions/new/username_validator.js
@@ -20,11 +20,11 @@ export default class UsernameValidator extends InputValidator {
const container = opts.container || '';
const validateLengthElements = document.querySelectorAll(`${container} .js-validate-username`);
- this.debounceValidateInput = debounce(inputDomElement => {
+ this.debounceValidateInput = debounce((inputDomElement) => {
UsernameValidator.validateUsernameInput(inputDomElement);
}, debounceTimeoutDuration);
- validateLengthElements.forEach(element =>
+ validateLengthElements.forEach((element) =>
element.addEventListener('input', this.eventHandler.bind(this)),
);
}
@@ -42,7 +42,7 @@ export default class UsernameValidator extends InputValidator {
if (inputDomElement.checkValidity() && username.length > 1) {
UsernameValidator.setMessageVisibility(inputDomElement, pendingMessageSelector);
UsernameValidator.fetchUsernameAvailability(username)
- .then(usernameTaken => {
+ .then((usernameTaken) => {
UsernameValidator.setInputState(inputDomElement, !usernameTaken);
UsernameValidator.setMessageVisibility(inputDomElement, pendingMessageSelector, false);
UsernameValidator.setMessageVisibility(
diff --git a/app/assets/javascripts/pages/shared/mount_badge_settings.js b/app/assets/javascripts/pages/shared/mount_badge_settings.js
index 1397c0834ff..aeb9f2fb8d3 100644
--- a/app/assets/javascripts/pages/shared/mount_badge_settings.js
+++ b/app/assets/javascripts/pages/shared/mount_badge_settings.js
@@ -2,7 +2,7 @@ import Vue from 'vue';
import BadgeSettings from '~/badges/components/badge_settings.vue';
import store from '~/badges/store';
-export default kind => {
+export default (kind) => {
const badgeSettingsElement = document.getElementById('badge-settings');
store.dispatch('loadBadges', {
diff --git a/app/assets/javascripts/pages/shared/wikis/wikis.js b/app/assets/javascripts/pages/shared/wikis/wikis.js
index fe9caba351e..4b4d2f7d238 100644
--- a/app/assets/javascripts/pages/shared/wikis/wikis.js
+++ b/app/assets/javascripts/pages/shared/wikis/wikis.js
@@ -20,12 +20,13 @@ export default class Wikis {
const sidebarToggles = document.querySelectorAll('.js-sidebar-wiki-toggle');
for (let i = 0; i < sidebarToggles.length; i += 1) {
- sidebarToggles[i].addEventListener('click', e => this.handleToggleSidebar(e));
+ sidebarToggles[i].addEventListener('click', (e) => this.handleToggleSidebar(e));
}
this.isNewWikiPage = Boolean(document.querySelector('.js-new-wiki-page'));
this.editTitleInput = document.querySelector('form.wiki-form #wiki_title');
this.commitMessageInput = document.querySelector('form.wiki-form #wiki_message');
+ this.submitButton = document.querySelector('.js-wiki-btn-submit');
this.commitMessageI18n = this.isNewWikiPage
? s__('WikiPageCreate|Create %{pageTitle}')
: s__('WikiPageEdit|Update %{pageTitle}');
@@ -35,7 +36,7 @@ export default class Wikis {
if (this.editTitleInput.value) this.setWikiCommitMessage(this.editTitleInput.value);
// Set the commit message as the page title is changed
- this.editTitleInput.addEventListener('keyup', e => this.handleWikiTitleChange(e));
+ this.editTitleInput.addEventListener('keyup', (e) => this.handleWikiTitleChange(e));
}
window.addEventListener('resize', () => this.renderSidebar());
@@ -45,18 +46,16 @@ export default class Wikis {
const linkExample = document.querySelector('.js-markup-link-example');
if (changeFormatSelect) {
- changeFormatSelect.addEventListener('change', e => {
+ changeFormatSelect.addEventListener('change', (e) => {
linkExample.innerHTML = MARKDOWN_LINK_TEXT[e.target.value];
});
}
- const wikiTextarea = document.querySelector('form.wiki-form #wiki_content');
+ this.wikiTextarea = document.querySelector('form.wiki-form #wiki_content');
const wikiForm = document.querySelector('form.wiki-form');
- if (wikiTextarea) {
- wikiTextarea.addEventListener('input', () => {
- window.onbeforeunload = () => '';
- });
+ if (this.wikiTextarea) {
+ this.wikiTextarea.addEventListener('input', () => this.handleWikiContentChange());
wikiForm.addEventListener('submit', () => {
window.onbeforeunload = null;
@@ -65,12 +64,29 @@ export default class Wikis {
Wikis.trackPageView();
Wikis.showToasts();
+
+ this.updateSubmitButton();
+ }
+
+ handleWikiContentChange() {
+ this.updateSubmitButton();
+
+ window.onbeforeunload = () => '';
}
handleWikiTitleChange(e) {
+ this.updateSubmitButton();
this.setWikiCommitMessage(e.target.value);
}
+ updateSubmitButton() {
+ if (!this.wikiTextarea) return;
+
+ const isEnabled = Boolean(this.wikiTextarea.value.trim() && this.editTitleInput.value.trim());
+ if (isEnabled) this.submitButton.removeAttribute('disabled');
+ else this.submitButton.setAttribute('disabled', 'true');
+ }
+
setWikiCommitMessage(rawTitle) {
let title = rawTitle;
@@ -121,6 +137,6 @@ export default class Wikis {
static showToasts() {
const toasts = document.querySelectorAll('.js-toast-message');
- toasts.forEach(toast => showToast(toast.dataset.message));
+ toasts.forEach((toast) => showToast(toast.dataset.message));
}
}
diff --git a/app/assets/javascripts/pages/users/activity_calendar.js b/app/assets/javascripts/pages/users/activity_calendar.js
index 54666af540e..149e666256b 100644
--- a/app/assets/javascripts/pages/users/activity_calendar.js
+++ b/app/assets/javascripts/pages/users/activity_calendar.js
@@ -42,11 +42,7 @@ function formatTooltipText({ date, count }) {
return `${contribText}<br />${dateDayName} ${dateText}`;
}
-const initColorKey = () =>
- d3
- .scaleLinear()
- .range(['#acd5f2', '#254e77'])
- .domain([0, 3]);
+const initColorKey = () => d3.scaleLinear().range(['#acd5f2', '#254e77']).domain([0, 3]);
export default class ActivityCalendar {
constructor(
@@ -177,17 +173,17 @@ export default class ActivityCalendar {
return `translate(${this.daySizeWithSpace * i + 1 + this.daySizeWithSpace}, 18)`;
})
.selectAll('rect')
- .data(stamp => stamp)
+ .data((stamp) => stamp)
.enter()
.append('rect')
.attr('x', '0')
- .attr('y', stamp => this.dayYPos(stamp.day))
+ .attr('y', (stamp) => this.dayYPos(stamp.day))
.attr('width', this.daySize)
.attr('height', this.daySize)
- .attr('fill', stamp =>
+ .attr('fill', (stamp) =>
stamp.count !== 0 ? this.color(Math.min(stamp.count, 40)) : '#ededed',
)
- .attr('title', stamp => formatTooltipText(stamp))
+ .attr('title', (stamp) => formatTooltipText(stamp))
.attr('class', 'user-contrib-cell has-tooltip')
.attr('data-html', true)
.attr('data-container', 'body')
@@ -230,8 +226,8 @@ export default class ActivityCalendar {
.append('text')
.attr('text-anchor', 'middle')
.attr('x', 8)
- .attr('y', day => day.y)
- .text(day => day.text)
+ .attr('y', (day) => day.y)
+ .text((day) => day.text)
.attr('class', 'user-contrib-text');
}
@@ -243,10 +239,10 @@ export default class ActivityCalendar {
.data(this.months)
.enter()
.append('text')
- .attr('x', date => date.x)
+ .attr('x', (date) => date.x)
.attr('y', 10)
.attr('class', 'user-contrib-text')
- .text(date => this.monthNames[date.month]);
+ .text((date) => this.monthNames[date.month]);
}
renderKey() {
@@ -276,7 +272,7 @@ export default class ActivityCalendar {
.attr('height', this.daySize)
.attr('x', (color, i) => this.daySizeWithSpace * i)
.attr('y', 0)
- .attr('fill', color => color)
+ .attr('fill', (color) => color)
.attr('class', 'has-tooltip')
.attr('title', (color, i) => keyValues[i])
.attr('data-container', 'body')
@@ -291,10 +287,7 @@ export default class ActivityCalendar {
this.colorKey(2),
this.colorKey(3),
];
- return d3
- .scaleThreshold()
- .domain([0, 10, 20, 30])
- .range(colorRange);
+ return d3.scaleThreshold().domain([0, 10, 20, 30]).range(colorRange);
}
clickDay(stamp) {
diff --git a/app/assets/javascripts/pages/users/index.js b/app/assets/javascripts/pages/users/index.js
index 8adbc2a8168..b22287a0093 100644
--- a/app/assets/javascripts/pages/users/index.js
+++ b/app/assets/javascripts/pages/users/index.js
@@ -8,12 +8,10 @@ function initUserProfile(action) {
new UserTabs({ parentEl: '.user-profile', action });
// hide project limit message
- $('.hide-project-limit-message').on('click', e => {
+ $('.hide-project-limit-message').on('click', (e) => {
e.preventDefault();
Cookies.set('hide_project_limit_message', 'false');
- $(this)
- .parents('.project-limit-message')
- .remove();
+ $(this).parents('.project-limit-message').remove();
});
}
diff --git a/app/assets/javascripts/pages/users/user_tabs.js b/app/assets/javascripts/pages/users/user_tabs.js
index 2485853afc7..7c88aa53e4b 100644
--- a/app/assets/javascripts/pages/users/user_tabs.js
+++ b/app/assets/javascripts/pages/users/user_tabs.js
@@ -100,8 +100,8 @@ export default class UserTabs {
bindEvents() {
this.$parentEl
.off('shown.bs.tab', '.nav-links a[data-toggle="tab"]')
- .on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', event => this.tabShown(event))
- .on('click', '.gl-pagination a', event => this.changeProjectsPage(event));
+ .on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', (event) => this.tabShown(event))
+ .on('click', '.gl-pagination a', (event) => this.changeProjectsPage(event));
window.addEventListener('resize', () => this.onResize());
}
@@ -212,17 +212,19 @@ export default class UserTabs {
const calendarPath = $calendarWrap.data('calendarPath');
AjaxCache.retrieve(calendarPath)
- .then(data => UserTabs.renderActivityCalendar(data, $calendarWrap))
+ .then((data) => UserTabs.renderActivityCalendar(data, $calendarWrap))
.catch(() => {
const cWrap = $calendarWrap[0];
cWrap.querySelector('.spinner').classList.add('invisible');
cWrap.querySelector('.user-calendar-error').classList.remove('invisible');
- cWrap.querySelector('.user-calendar-error .js-retry-load').addEventListener('click', e => {
- e.preventDefault();
- cWrap.querySelector('.user-calendar-error').classList.add('invisible');
- cWrap.querySelector('.spinner').classList.remove('invisible');
- this.loadActivityCalendar();
- });
+ cWrap
+ .querySelector('.user-calendar-error .js-retry-load')
+ .addEventListener('click', (e) => {
+ e.preventDefault();
+ cWrap.querySelector('.user-calendar-error').classList.add('invisible');
+ cWrap.querySelector('.spinner').classList.remove('invisible');
+ this.loadActivityCalendar();
+ });
});
}