summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/pages
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-03-16 18:18:33 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-03-16 18:18:33 +0000
commitf64a639bcfa1fc2bc89ca7db268f594306edfd7c (patch)
treea2c3c2ebcc3b45e596949db485d6ed18ffaacfa1 /app/assets/javascripts/pages
parentbfbc3e0d6583ea1a91f627528bedc3d65ba4b10f (diff)
downloadgitlab-ce-f64a639bcfa1fc2bc89ca7db268f594306edfd7c.tar.gz
Add latest changes from gitlab-org/gitlab@13-10-stable-eev13.10.0-rc40
Diffstat (limited to 'app/assets/javascripts/pages')
-rw-r--r--app/assets/javascripts/pages/admin/abuse_reports/index.js7
-rw-r--r--app/assets/javascripts/pages/admin/admin.js32
-rw-r--r--app/assets/javascripts/pages/admin/application_settings/general/index.js26
-rw-r--r--app/assets/javascripts/pages/admin/application_settings/index.js18
-rw-r--r--app/assets/javascripts/pages/admin/dev_ops_report/index.js4
-rw-r--r--app/assets/javascripts/pages/admin/impersonation_tokens/index.js4
-rw-r--r--app/assets/javascripts/pages/admin/index.js10
-rw-r--r--app/assets/javascripts/pages/admin/instance_statistics/index.js3
-rw-r--r--app/assets/javascripts/pages/admin/projects/index.js12
-rw-r--r--app/assets/javascripts/pages/admin/projects/index/index.js4
-rw-r--r--app/assets/javascripts/pages/admin/runners/index.js14
-rw-r--r--app/assets/javascripts/pages/admin/services/index/index.js6
-rw-r--r--app/assets/javascripts/pages/admin/usage_trends/index.js3
-rw-r--r--app/assets/javascripts/pages/dashboard/issues/index.js16
-rw-r--r--app/assets/javascripts/pages/dashboard/milestones/show/index.js2
-rw-r--r--app/assets/javascripts/pages/dashboard/projects/index/index.js7
-rw-r--r--app/assets/javascripts/pages/dashboard/todos/index/index.js2
-rw-r--r--app/assets/javascripts/pages/groups/activity/index.js3
-rw-r--r--app/assets/javascripts/pages/groups/edit/index.js3
-rw-r--r--app/assets/javascripts/pages/groups/group_members/index.js9
-rw-r--r--app/assets/javascripts/pages/groups/milestones/show/index.js2
-rw-r--r--app/assets/javascripts/pages/groups/new/index.js14
-rw-r--r--app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js27
-rw-r--r--app/assets/javascripts/pages/groups/settings/integrations/edit/index.js16
-rw-r--r--app/assets/javascripts/pages/groups/settings/packages_and_registries/index.js3
-rw-r--r--app/assets/javascripts/pages/groups/settings/repository/show/index.js11
-rw-r--r--app/assets/javascripts/pages/groups/shared/group_details.js13
-rw-r--r--app/assets/javascripts/pages/groups/show/index.js6
-rw-r--r--app/assets/javascripts/pages/profiles/index.js28
-rw-r--r--app/assets/javascripts/pages/profiles/index/index.js7
-rw-r--r--app/assets/javascripts/pages/profiles/notifications/show/index.js4
-rw-r--r--app/assets/javascripts/pages/profiles/personal_access_tokens/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/blob/edit/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/blob/new/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/blob/show/index.js98
-rw-r--r--app/assets/javascripts/pages/projects/boards/index.js8
-rw-r--r--app/assets/javascripts/pages/projects/branches/index/index.js8
-rw-r--r--app/assets/javascripts/pages/projects/branches/new/index.js11
-rw-r--r--app/assets/javascripts/pages/projects/compare/show/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/cycle_analytics/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/feature_flags_user_lists/edit/index.js22
-rw-r--r--app/assets/javascripts/pages/projects/feature_flags_user_lists/new/index.js28
-rw-r--r--app/assets/javascripts/pages/projects/feature_flags_user_lists/show/index.js19
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/components/app.vue72
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue304
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list_item.vue20
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/index.js48
-rw-r--r--app/assets/javascripts/pages/projects/imports/show/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/issues/index/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/jobs/index/index.js30
-rw-r--r--app/assets/javascripts/pages/projects/labels/edit/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_a.vue8
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_b.vue109
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_info_card.vue70
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js56
-rw-r--r--app/assets/javascripts/pages/projects/logs/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/edit/index.js6
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/index/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/milestones/edit/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/milestones/index/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/milestones/new/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/milestones/show/index.js6
-rw-r--r--app/assets/javascripts/pages/projects/new/index.js42
-rw-r--r--app/assets/javascripts/pages/projects/project_members/index.js110
-rw-r--r--app/assets/javascripts/pages/projects/prometheus/metrics/edit/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/prometheus/metrics/new/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/settings/access_tokens/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/settings/operations/show/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/settings/repository/show/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue42
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/constants.js6
-rw-r--r--app/assets/javascripts/pages/projects/show/index.js22
-rw-r--r--app/assets/javascripts/pages/projects/tags/new/index.js8
-rw-r--r--app/assets/javascripts/pages/projects/tags/releases/index.js6
-rw-r--r--app/assets/javascripts/pages/search/show/index.js4
-rw-r--r--app/assets/javascripts/pages/shared/wikis/components/wiki_alert.vue31
-rw-r--r--app/assets/javascripts/pages/shared/wikis/index.js28
-rw-r--r--app/assets/javascripts/pages/users/index.js10
79 files changed, 1106 insertions, 500 deletions
diff --git a/app/assets/javascripts/pages/admin/abuse_reports/index.js b/app/assets/javascripts/pages/admin/abuse_reports/index.js
index 5649c47d7e8..0a4311ec73a 100644
--- a/app/assets/javascripts/pages/admin/abuse_reports/index.js
+++ b/app/assets/javascripts/pages/admin/abuse_reports/index.js
@@ -1,8 +1,5 @@
-/* eslint-disable no-new */
import UsersSelect from '~/users_select';
import AbuseReports from './abuse_reports';
-document.addEventListener('DOMContentLoaded', () => {
- new AbuseReports();
- new UsersSelect();
-});
+new AbuseReports(); /* eslint-disable-line no-new */
+new UsersSelect(); /* eslint-disable-line no-new */
diff --git a/app/assets/javascripts/pages/admin/admin.js b/app/assets/javascripts/pages/admin/admin.js
index e92262852cf..2732fc191be 100644
--- a/app/assets/javascripts/pages/admin/admin.js
+++ b/app/assets/javascripts/pages/admin/admin.js
@@ -12,8 +12,6 @@ function showDenylistType() {
}
export default function adminInit() {
- const modal = $('.change-owner-holder');
-
$('input#user_force_random_password').on('change', function randomPasswordClick() {
const $elems = $('#user_password, #user_password_confirmation');
if ($(this).attr('checked')) {
@@ -28,36 +26,6 @@ export default function adminInit() {
$('.js-toggle-colors-container').toggleClass('hide');
});
- $('.log-tabs a').on('click', function logTabsClick(e) {
- e.preventDefault();
- $(this).tab('show');
- });
-
- $('.log-bottom').on('click', (e) => {
- e.preventDefault();
- const $visibleLog = $('.file-content:visible');
-
- // eslint-disable-next-line no-jquery/no-animate
- $visibleLog.animate(
- {
- scrollTop: $visibleLog.find('ol').height(),
- },
- 'fast',
- );
- });
-
- $('.change-owner-link').on('click', function changeOwnerLinkClick(e) {
- e.preventDefault();
- $(this).hide();
- modal.show();
- });
-
- $('.change-owner-cancel-link').on('click', (e) => {
- e.preventDefault();
- modal.hide();
- $('.change-owner-link').show();
- });
-
$('li.project_member, li.group_member').on('ajax:success', refreshCurrentPage);
$("input[name='denylist_type']").on('click', showDenylistType);
diff --git a/app/assets/javascripts/pages/admin/application_settings/general/index.js b/app/assets/javascripts/pages/admin/application_settings/general/index.js
index f7bd32880ff..eda1a9d3599 100644
--- a/app/assets/javascripts/pages/admin/application_settings/general/index.js
+++ b/app/assets/javascripts/pages/admin/application_settings/general/index.js
@@ -1,25 +1,27 @@
-// This is a true violation of @gitlab/no-runtime-template-compiler, as it
-// relies on app/views/admin/application_settings/_gitpod.html.haml for its
-// template.
-/* eslint-disable @gitlab/no-runtime-template-compiler */
import Vue from 'vue';
import IntegrationHelpText from '~/vue_shared/components/integrations_help_text.vue';
import initUserInternalRegexPlaceholder from '../account_and_limits';
-document.addEventListener('DOMContentLoaded', () => {
+(() => {
initUserInternalRegexPlaceholder();
- const gitpodSettingEl = document.querySelector('#js-gitpod-settings-help-text');
- if (!gitpodSettingEl) {
+ const el = document.querySelector('#js-gitpod-settings-help-text');
+ if (!el) {
return;
}
+ const { message, messageUrl } = el.dataset;
+
// eslint-disable-next-line no-new
new Vue({
- el: gitpodSettingEl,
- name: 'GitpodSettings',
- components: {
- IntegrationHelpText,
+ el,
+ render(createElement) {
+ return createElement(IntegrationHelpText, {
+ props: {
+ message,
+ messageUrl,
+ },
+ });
},
});
-});
+})();
diff --git a/app/assets/javascripts/pages/admin/application_settings/index.js b/app/assets/javascripts/pages/admin/application_settings/index.js
index e7e74588bec..e3c6b0f6f5b 100644
--- a/app/assets/javascripts/pages/admin/application_settings/index.js
+++ b/app/assets/javascripts/pages/admin/application_settings/index.js
@@ -4,13 +4,11 @@ import initSearchSettings from '~/search_settings';
import selfMonitor from '~/self_monitor';
import initSettingsPanels from '~/settings_panels';
-document.addEventListener('DOMContentLoaded', () => {
- if (gon.features?.ciInstanceVariablesUi) {
- initVariableList('js-instance-variables');
- }
- selfMonitor();
- // Initialize expandable settings panels
- initSettingsPanels();
- projectSelect();
- initSearchSettings();
-});
+if (gon.features?.ciInstanceVariablesUi) {
+ initVariableList('js-instance-variables');
+}
+selfMonitor();
+// Initialize expandable settings panels
+initSettingsPanels();
+projectSelect();
+initSearchSettings();
diff --git a/app/assets/javascripts/pages/admin/dev_ops_report/index.js b/app/assets/javascripts/pages/admin/dev_ops_report/index.js
index 220fc049562..cf06ee2c22a 100644
--- a/app/assets/javascripts/pages/admin/dev_ops_report/index.js
+++ b/app/assets/javascripts/pages/admin/dev_ops_report/index.js
@@ -1,5 +1,3 @@
-import initDevopAdoption from 'ee_else_ce/admin/dev_ops_report/devops_adoption';
-import initDevOpsScoreEmptyState from '~/admin/dev_ops_report/devops_score_empty_state';
+import initDevOpsScoreEmptyState from '~/analytics/devops_report/devops_score_empty_state';
initDevOpsScoreEmptyState();
-initDevopAdoption();
diff --git a/app/assets/javascripts/pages/admin/impersonation_tokens/index.js b/app/assets/javascripts/pages/admin/impersonation_tokens/index.js
index ae2209b0292..dc1bb88bf4b 100644
--- a/app/assets/javascripts/pages/admin/impersonation_tokens/index.js
+++ b/app/assets/javascripts/pages/admin/impersonation_tokens/index.js
@@ -1,3 +1,3 @@
-import initExpiresAtField from '~/access_tokens';
+import { initExpiresAtField } from '~/access_tokens';
-document.addEventListener('DOMContentLoaded', initExpiresAtField);
+initExpiresAtField();
diff --git a/app/assets/javascripts/pages/admin/index.js b/app/assets/javascripts/pages/admin/index.js
index 792a6eda14e..8d5dfd689e8 100644
--- a/app/assets/javascripts/pages/admin/index.js
+++ b/app/assets/javascripts/pages/admin/index.js
@@ -2,10 +2,8 @@ import initAdminStatisticsPanel from '../../admin/statistics_panel/index';
import initVueAlerts from '../../vue_alerts';
import initAdmin from './admin';
-document.addEventListener('DOMContentLoaded', initVueAlerts);
+initVueAlerts();
-document.addEventListener('DOMContentLoaded', () => {
- const statisticsPanelContainer = document.getElementById('js-admin-statistics-container');
- initAdmin();
- initAdminStatisticsPanel(statisticsPanelContainer);
-});
+const statisticsPanelContainer = document.getElementById('js-admin-statistics-container');
+initAdmin();
+initAdminStatisticsPanel(statisticsPanelContainer);
diff --git a/app/assets/javascripts/pages/admin/instance_statistics/index.js b/app/assets/javascripts/pages/admin/instance_statistics/index.js
deleted file mode 100644
index d6b0a834ce3..00000000000
--- a/app/assets/javascripts/pages/admin/instance_statistics/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import initInstanceStatisticsApp from '~/analytics/instance_statistics';
-
-document.addEventListener('DOMContentLoaded', () => initInstanceStatisticsApp());
diff --git a/app/assets/javascripts/pages/admin/projects/index.js b/app/assets/javascripts/pages/admin/projects/index.js
index 2286a085143..042ff7808f1 100644
--- a/app/assets/javascripts/pages/admin/projects/index.js
+++ b/app/assets/javascripts/pages/admin/projects/index.js
@@ -17,12 +17,10 @@ function mountRemoveMemberModal() {
});
}
-document.addEventListener('DOMContentLoaded', () => {
- mountRemoveMemberModal();
+mountRemoveMemberModal();
- new ProjectsList(); // eslint-disable-line no-new
+new ProjectsList(); // eslint-disable-line no-new
- document
- .querySelectorAll('.js-namespace-select')
- .forEach((dropdown) => new NamespaceSelect({ dropdown }));
-});
+document
+ .querySelectorAll('.js-namespace-select')
+ .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 1971323abac..cc9a9b6cc38 100644
--- a/app/assets/javascripts/pages/admin/projects/index/index.js
+++ b/app/assets/javascripts/pages/admin/projects/index/index.js
@@ -6,7 +6,7 @@ import Translate from '~/vue_shared/translate';
import deleteProjectModal from './components/delete_project_modal.vue';
-document.addEventListener('DOMContentLoaded', () => {
+(() => {
Vue.use(Translate);
const deleteProjectModalEl = document.getElementById('delete-project-modal');
@@ -39,4 +39,4 @@ document.addEventListener('DOMContentLoaded', () => {
});
},
});
-});
+})();
diff --git a/app/assets/javascripts/pages/admin/runners/index.js b/app/assets/javascripts/pages/admin/runners/index.js
index f07ac1d8674..45ed3ac6bd8 100644
--- a/app/assets/javascripts/pages/admin/runners/index.js
+++ b/app/assets/javascripts/pages/admin/runners/index.js
@@ -3,12 +3,10 @@ import { FILTERED_SEARCH } from '~/pages/constants';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import { initInstallRunner } from '~/pages/shared/mount_runner_instructions';
-document.addEventListener('DOMContentLoaded', () => {
- initFilteredSearch({
- page: FILTERED_SEARCH.ADMIN_RUNNERS,
- filteredSearchTokenKeys: AdminRunnersFilteredSearchTokenKeys,
- useDefaultState: true,
- });
-
- initInstallRunner();
+initFilteredSearch({
+ page: FILTERED_SEARCH.ADMIN_RUNNERS,
+ filteredSearchTokenKeys: AdminRunnersFilteredSearchTokenKeys,
+ useDefaultState: true,
});
+
+initInstallRunner();
diff --git a/app/assets/javascripts/pages/admin/services/index/index.js b/app/assets/javascripts/pages/admin/services/index/index.js
index b2dfbb5a9fc..b695cf70c5d 100644
--- a/app/assets/javascripts/pages/admin/services/index/index.js
+++ b/app/assets/javascripts/pages/admin/services/index/index.js
@@ -1,6 +1,4 @@
import PersistentUserCallout from '~/persistent_user_callout';
-document.addEventListener('DOMContentLoaded', () => {
- const callout = document.querySelector('.js-service-templates-deprecated');
- PersistentUserCallout.factory(callout);
-});
+const callout = document.querySelector('.js-service-templates-deprecated');
+PersistentUserCallout.factory(callout);
diff --git a/app/assets/javascripts/pages/admin/usage_trends/index.js b/app/assets/javascripts/pages/admin/usage_trends/index.js
new file mode 100644
index 00000000000..23d2bd85979
--- /dev/null
+++ b/app/assets/javascripts/pages/admin/usage_trends/index.js
@@ -0,0 +1,3 @@
+import initUsageTrendsApp from '~/analytics/usage_trends';
+
+initUsageTrendsApp();
diff --git a/app/assets/javascripts/pages/dashboard/issues/index.js b/app/assets/javascripts/pages/dashboard/issues/index.js
index 3ad95fb1318..3e09b1796b1 100644
--- a/app/assets/javascripts/pages/dashboard/issues/index.js
+++ b/app/assets/javascripts/pages/dashboard/issues/index.js
@@ -4,13 +4,11 @@ import { FILTERED_SEARCH } from '~/pages/constants';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import projectSelect from '~/project_select';
-document.addEventListener('DOMContentLoaded', () => {
- initFilteredSearch({
- page: FILTERED_SEARCH.ISSUES,
- filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys,
- useDefaultState: true,
- });
-
- projectSelect();
- initManualOrdering();
+initFilteredSearch({
+ page: FILTERED_SEARCH.ISSUES,
+ filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys,
+ useDefaultState: true,
});
+
+projectSelect();
+initManualOrdering();
diff --git a/app/assets/javascripts/pages/dashboard/milestones/show/index.js b/app/assets/javascripts/pages/dashboard/milestones/show/index.js
index 8b529585898..397149aaa9e 100644
--- a/app/assets/javascripts/pages/dashboard/milestones/show/index.js
+++ b/app/assets/javascripts/pages/dashboard/milestones/show/index.js
@@ -6,6 +6,4 @@ document.addEventListener('DOMContentLoaded', () => {
new Milestone(); // eslint-disable-line no-new
new Sidebar(); // eslint-disable-line no-new
new MountMilestoneSidebar(); // eslint-disable-line no-new
-
- Milestone.initDeprecationMessage();
});
diff --git a/app/assets/javascripts/pages/dashboard/projects/index/index.js b/app/assets/javascripts/pages/dashboard/projects/index/index.js
index b3c95f4ac1f..c34d15b869a 100644
--- a/app/assets/javascripts/pages/dashboard/projects/index/index.js
+++ b/app/assets/javascripts/pages/dashboard/projects/index/index.js
@@ -1,8 +1,5 @@
import ProjectsList from '~/projects_list';
import initCustomizeHomepageBanner from './init_customize_homepage_banner';
-document.addEventListener('DOMContentLoaded', () => {
- new ProjectsList(); // eslint-disable-line no-new
-
- initCustomizeHomepageBanner();
-});
+new ProjectsList(); // eslint-disable-line no-new
+initCustomizeHomepageBanner();
diff --git a/app/assets/javascripts/pages/dashboard/todos/index/index.js b/app/assets/javascripts/pages/dashboard/todos/index/index.js
index 9d2c2f2994f..2fe90c24e77 100644
--- a/app/assets/javascripts/pages/dashboard/todos/index/index.js
+++ b/app/assets/javascripts/pages/dashboard/todos/index/index.js
@@ -1,3 +1,3 @@
import Todos from './todos';
-document.addEventListener('DOMContentLoaded', () => new Todos());
+new Todos(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/groups/activity/index.js b/app/assets/javascripts/pages/groups/activity/index.js
index 1b887cad496..8b7c36a0976 100644
--- a/app/assets/javascripts/pages/groups/activity/index.js
+++ b/app/assets/javascripts/pages/groups/activity/index.js
@@ -1,3 +1,4 @@
import Activities from '~/activities';
-document.addEventListener('DOMContentLoaded', () => new Activities());
+// eslint-disable-next-line no-new
+new Activities();
diff --git a/app/assets/javascripts/pages/groups/edit/index.js b/app/assets/javascripts/pages/groups/edit/index.js
index 95ee512b71a..176d2406751 100644
--- a/app/assets/javascripts/pages/groups/edit/index.js
+++ b/app/assets/javascripts/pages/groups/edit/index.js
@@ -6,6 +6,7 @@ import TransferDropdown from '~/groups/transfer_dropdown';
import groupsSelect from '~/groups_select';
import mountBadgeSettings from '~/pages/shared/mount_badge_settings';
import projectSelect from '~/project_select';
+import initSearchSettings from '~/search_settings';
import initSettingsPanels from '~/settings_panels';
import setupTransferEdit from '~/transfer_edit';
@@ -24,5 +25,7 @@ document.addEventListener('DOMContentLoaded', () => {
projectSelect();
+ initSearchSettings();
+
return new TransferDropdown();
});
diff --git a/app/assets/javascripts/pages/groups/group_members/index.js b/app/assets/javascripts/pages/groups/group_members/index.js
index 3496f699b06..ab70fa572ba 100644
--- a/app/assets/javascripts/pages/groups/group_members/index.js
+++ b/app/assets/javascripts/pages/groups/group_members/index.js
@@ -1,11 +1,13 @@
import Vue from 'vue';
import { groupMemberRequestFormatter } from '~/groups/members/utils';
import groupsSelect from '~/groups_select';
+import initInviteGroupTrigger from '~/invite_members/init_invite_group_trigger';
+import initInviteMembersForm from '~/invite_members/init_invite_members_form';
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
import { s__ } from '~/locale';
import memberExpirationDate from '~/member_expiration_date';
-import { initMembersApp } from '~/members/index';
+import { initMembersApp } from '~/members';
import { groupLinkRequestFormatter } from '~/members/utils';
import UsersSelect from '~/users_select';
import RemoveMemberModal from '~/vue_shared/components/remove_member_modal.vue';
@@ -70,5 +72,10 @@ memberExpirationDate('.js-access-expiration-date-groups');
mountRemoveMemberModal();
initInviteMembersModal();
initInviteMembersTrigger();
+initInviteGroupTrigger();
+
+// This is only used when `invite_members_group_modal` feature flag is disabled.
+// This can be removed when `invite_members_group_modal` feature flag is removed.
+initInviteMembersForm();
new UsersSelect(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/groups/milestones/show/index.js b/app/assets/javascripts/pages/groups/milestones/show/index.js
index 3094fe5cd21..2a2cc5faebe 100644
--- a/app/assets/javascripts/pages/groups/milestones/show/index.js
+++ b/app/assets/javascripts/pages/groups/milestones/show/index.js
@@ -1,9 +1,7 @@
-import Milestone from '~/milestone';
import initDeleteMilestoneModal from '~/pages/milestones/shared/delete_milestone_modal_init';
import initMilestonesShow from '~/pages/milestones/shared/init_milestones_show';
document.addEventListener('DOMContentLoaded', () => {
initMilestonesShow();
initDeleteMilestoneModal();
- Milestone.initDeprecationMessage();
});
diff --git a/app/assets/javascripts/pages/groups/new/index.js b/app/assets/javascripts/pages/groups/new/index.js
index 63515abe698..322ad2c79e7 100644
--- a/app/assets/javascripts/pages/groups/new/index.js
+++ b/app/assets/javascripts/pages/groups/new/index.js
@@ -2,6 +2,7 @@ import $ from 'jquery';
import BindInOut from '~/behaviors/bind_in_out';
import initFilePickers from '~/file_pickers';
import Group from '~/group';
+import LinkedTabs from '~/lib/utils/bootstrap_linked_tabs';
import GroupPathValidator from './group_path_validator';
const parentId = $('#group_parent_id');
@@ -12,3 +13,16 @@ BindInOut.initAll();
initFilePickers();
new Group(); // eslint-disable-line no-new
+
+const CONTAINER_SELECTOR = '.group-edit-container .nav-tabs';
+const DEFAULT_ACTION = '#create-group-pane';
+// eslint-disable-next-line no-new
+new LinkedTabs({
+ defaultAction: DEFAULT_ACTION,
+ parentEl: CONTAINER_SELECTOR,
+ hashedTabs: true,
+});
+
+if (window.location.hash) {
+ $(CONTAINER_SELECTOR).find(`a[href="${window.location.hash}"]`).tab('show');
+}
diff --git a/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js b/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js
index 378b8663777..0c3fdcf3e75 100644
--- a/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js
+++ b/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js
@@ -4,21 +4,22 @@ import initSharedRunnersForm from '~/group_settings/mount_shared_runners';
import { FILTERED_SEARCH } from '~/pages/constants';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import { initInstallRunner } from '~/pages/shared/mount_runner_instructions';
+import initSearchSettings from '~/search_settings';
import initSettingsPanels from '~/settings_panels';
-document.addEventListener('DOMContentLoaded', () => {
- // Initialize expandable settings panels
- initSettingsPanels();
+// Initialize expandable settings panels
+initSettingsPanels();
- initFilteredSearch({
- page: FILTERED_SEARCH.ADMIN_RUNNERS,
- filteredSearchTokenKeys: GroupRunnersFilteredSearchTokenKeys,
- anchor: FILTERED_SEARCH.GROUP_RUNNERS_ANCHOR,
- useDefaultState: false,
- });
+initFilteredSearch({
+ page: FILTERED_SEARCH.ADMIN_RUNNERS,
+ filteredSearchTokenKeys: GroupRunnersFilteredSearchTokenKeys,
+ anchor: FILTERED_SEARCH.GROUP_RUNNERS_ANCHOR,
+ useDefaultState: false,
+});
- initSharedRunnersForm();
- initVariableList();
+initSharedRunnersForm();
+initVariableList();
- initInstallRunner();
-});
+initInstallRunner();
+
+initSearchSettings();
diff --git a/app/assets/javascripts/pages/groups/settings/integrations/edit/index.js b/app/assets/javascripts/pages/groups/settings/integrations/edit/index.js
index ba4b271f09e..a8698e10c57 100644
--- a/app/assets/javascripts/pages/groups/settings/integrations/edit/index.js
+++ b/app/assets/javascripts/pages/groups/settings/integrations/edit/index.js
@@ -1,13 +1,11 @@
import IntegrationSettingsForm from '~/integrations/integration_settings_form';
import PrometheusMetrics from '~/prometheus_metrics/prometheus_metrics';
-document.addEventListener('DOMContentLoaded', () => {
- const prometheusSettingsWrapper = document.querySelector('.js-prometheus-metrics-monitoring');
- const integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form');
- integrationSettingsForm.init();
+const prometheusSettingsWrapper = document.querySelector('.js-prometheus-metrics-monitoring');
+const integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form');
+integrationSettingsForm.init();
- if (prometheusSettingsWrapper) {
- const prometheusMetrics = new PrometheusMetrics('.js-prometheus-metrics-monitoring');
- prometheusMetrics.loadActiveMetrics();
- }
-});
+if (prometheusSettingsWrapper) {
+ const prometheusMetrics = new PrometheusMetrics('.js-prometheus-metrics-monitoring');
+ prometheusMetrics.loadActiveMetrics();
+}
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
index 3b922622d2c..d13bf026777 100644
--- a/app/assets/javascripts/pages/groups/settings/packages_and_registries/index.js
+++ b/app/assets/javascripts/pages/groups/settings/packages_and_registries/index.js
@@ -1,3 +1,6 @@
import bundle from '~/packages_and_registries/settings/group/bundle';
+import initSearchSettings from '~/search_settings';
bundle();
+
+document.addEventListener('DOMContentLoaded', initSearchSettings);
diff --git a/app/assets/javascripts/pages/groups/settings/repository/show/index.js b/app/assets/javascripts/pages/groups/settings/repository/show/index.js
index a1bcf6dbf57..2c9867653de 100644
--- a/app/assets/javascripts/pages/groups/settings/repository/show/index.js
+++ b/app/assets/javascripts/pages/groups/settings/repository/show/index.js
@@ -1,9 +1,10 @@
import DueDateSelectors from '~/due_date_select';
+import initSearchSettings from '~/search_settings';
import initSettingsPanels from '~/settings_panels';
-document.addEventListener('DOMContentLoaded', () => {
- // Initialize expandable settings panels
- initSettingsPanels();
+// Initialize expandable settings panels
+initSettingsPanels();
- new DueDateSelectors(); // eslint-disable-line no-new
-});
+new DueDateSelectors(); // eslint-disable-line no-new
+
+initSearchSettings();
diff --git a/app/assets/javascripts/pages/groups/shared/group_details.js b/app/assets/javascripts/pages/groups/shared/group_details.js
index 8c272e561db..9e75985c130 100644
--- a/app/assets/javascripts/pages/groups/shared/group_details.js
+++ b/app/assets/javascripts/pages/groups/shared/group_details.js
@@ -3,12 +3,8 @@
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import { ACTIVE_TAB_SHARED, ACTIVE_TAB_ARCHIVED } from '~/groups/constants';
import initInviteMembersBanner from '~/groups/init_invite_members_banner';
-import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
-import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
import { getPagePath, getDashPath } from '~/lib/utils/common_utils';
import initNotificationsDropdown from '~/notifications';
-import notificationsDropdown from '~/notifications_dropdown';
-import NotificationsForm from '~/notifications_form';
import ProjectsList from '~/projects_list';
import GroupTabs from './group_tabs';
@@ -22,17 +18,10 @@ export default function initGroupDetails(actionName = 'show') {
new GroupTabs({ parentEl: '.groups-listing', action });
new ShortcutsNavigation();
- new NotificationsForm();
- if (gon.features?.vueNotificationDropdown) {
- initNotificationsDropdown();
- } else {
- notificationsDropdown();
- }
+ initNotificationsDropdown();
new ProjectsList();
initInviteMembersBanner();
- initInviteMembersModal();
- initInviteMembersTrigger();
}
diff --git a/app/assets/javascripts/pages/groups/show/index.js b/app/assets/javascripts/pages/groups/show/index.js
index 82ee5ead83d..e4a84dd5eec 100644
--- a/app/assets/javascripts/pages/groups/show/index.js
+++ b/app/assets/javascripts/pages/groups/show/index.js
@@ -1,7 +1,5 @@
import leaveByUrl from '~/namespaces/leave_by_url';
import initGroupDetails from '../shared/group_details';
-document.addEventListener('DOMContentLoaded', () => {
- leaveByUrl('group');
- initGroupDetails();
-});
+leaveByUrl('group');
+initGroupDetails();
diff --git a/app/assets/javascripts/pages/profiles/index.js b/app/assets/javascripts/pages/profiles/index.js
index 535fe5fa4eb..80bc32dd43f 100644
--- a/app/assets/javascripts/pages/profiles/index.js
+++ b/app/assets/javascripts/pages/profiles/index.js
@@ -3,21 +3,19 @@ import '~/profile/gl_crop';
import Profile from '~/profile/profile';
import initSearchSettings from '~/search_settings';
-document.addEventListener('DOMContentLoaded', () => {
- // eslint-disable-next-line func-names
- $(document).on('input.ssh_key', '#key_key', function () {
- const $title = $('#key_title');
- const comment = $(this)
- .val()
- .match(/^\S+ \S+ (.+)\n?$/);
+// eslint-disable-next-line func-names
+$(document).on('input.ssh_key', '#key_key', function () {
+ const $title = $('#key_title');
+ const comment = $(this)
+ .val()
+ .match(/^\S+ \S+ (.+)\n?$/);
- // Extract the SSH Key title from its comment
- if (comment && comment.length > 1) {
- $title.val(comment[1]).change();
- }
- });
+ // Extract the SSH Key title from its comment
+ if (comment && comment.length > 1) {
+ $title.val(comment[1]).change();
+ }
+});
- new Profile(); // eslint-disable-line no-new
+new Profile(); // eslint-disable-line no-new
- initSearchSettings();
-});
+initSearchSettings();
diff --git a/app/assets/javascripts/pages/profiles/index/index.js b/app/assets/javascripts/pages/profiles/index/index.js
deleted file mode 100644
index 586b3be8661..00000000000
--- a/app/assets/javascripts/pages/profiles/index/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import notificationsDropdown from '../../../notifications_dropdown';
-import NotificationsForm from '../../../notifications_form';
-
-document.addEventListener('DOMContentLoaded', () => {
- new NotificationsForm(); // eslint-disable-line no-new
- notificationsDropdown();
-});
diff --git a/app/assets/javascripts/pages/profiles/notifications/show/index.js b/app/assets/javascripts/pages/profiles/notifications/show/index.js
index 639f5deb72c..51ba6c7a01e 100644
--- a/app/assets/javascripts/pages/profiles/notifications/show/index.js
+++ b/app/assets/javascripts/pages/profiles/notifications/show/index.js
@@ -1,9 +1,5 @@
import initNotificationsDropdown from '~/notifications';
-import notificationsDropdown from '../../../../notifications_dropdown';
-import NotificationsForm from '../../../../notifications_form';
document.addEventListener('DOMContentLoaded', () => {
- new NotificationsForm(); // eslint-disable-line no-new
- notificationsDropdown();
initNotificationsDropdown();
});
diff --git a/app/assets/javascripts/pages/profiles/personal_access_tokens/index.js b/app/assets/javascripts/pages/profiles/personal_access_tokens/index.js
index ae2209b0292..fdbfc35456f 100644
--- a/app/assets/javascripts/pages/profiles/personal_access_tokens/index.js
+++ b/app/assets/javascripts/pages/profiles/personal_access_tokens/index.js
@@ -1,3 +1,4 @@
-import initExpiresAtField from '~/access_tokens';
+import { initExpiresAtField, initProjectsField } from '~/access_tokens';
-document.addEventListener('DOMContentLoaded', initExpiresAtField);
+initExpiresAtField();
+initProjectsField();
diff --git a/app/assets/javascripts/pages/projects/blob/edit/index.js b/app/assets/javascripts/pages/projects/blob/edit/index.js
index 189053f3ed7..ed416610173 100644
--- a/app/assets/javascripts/pages/projects/blob/edit/index.js
+++ b/app/assets/javascripts/pages/projects/blob/edit/index.js
@@ -1,3 +1,3 @@
import initBlobBundle from '~/blob_edit/blob_bundle';
-document.addEventListener('DOMContentLoaded', initBlobBundle);
+initBlobBundle();
diff --git a/app/assets/javascripts/pages/projects/blob/new/index.js b/app/assets/javascripts/pages/projects/blob/new/index.js
index 189053f3ed7..ed416610173 100644
--- a/app/assets/javascripts/pages/projects/blob/new/index.js
+++ b/app/assets/javascripts/pages/projects/blob/new/index.js
@@ -1,3 +1,3 @@
import initBlobBundle from '~/blob_edit/blob_bundle';
-document.addEventListener('DOMContentLoaded', initBlobBundle);
+initBlobBundle();
diff --git a/app/assets/javascripts/pages/projects/blob/show/index.js b/app/assets/javascripts/pages/projects/blob/show/index.js
index 61ff1c95a38..10bac6d60c2 100644
--- a/app/assets/javascripts/pages/projects/blob/show/index.js
+++ b/app/assets/javascripts/pages/projects/blob/show/index.js
@@ -7,61 +7,59 @@ import initWebIdeLink from '~/pages/projects/shared/web_ide_link';
import commitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue';
import '~/sourcegraph/load';
-document.addEventListener('DOMContentLoaded', () => {
- new BlobViewer(); // eslint-disable-line no-new
- initBlob();
+new BlobViewer(); // eslint-disable-line no-new
+initBlob();
- const CommitPipelineStatusEl = document.querySelector('.js-commit-pipeline-status');
- const statusLink = document.querySelector('.commit-actions .ci-status-link');
- if (statusLink) {
- statusLink.remove();
- // eslint-disable-next-line no-new
- new Vue({
- el: CommitPipelineStatusEl,
- components: {
- commitPipelineStatus,
- },
- render(createElement) {
- return createElement('commit-pipeline-status', {
- props: {
- endpoint: CommitPipelineStatusEl.dataset.endpoint,
- },
- });
- },
- });
- }
+const CommitPipelineStatusEl = document.querySelector('.js-commit-pipeline-status');
+const statusLink = document.querySelector('.commit-actions .ci-status-link');
+if (statusLink) {
+ statusLink.remove();
+ // eslint-disable-next-line no-new
+ new Vue({
+ el: CommitPipelineStatusEl,
+ components: {
+ commitPipelineStatus,
+ },
+ render(createElement) {
+ return createElement('commit-pipeline-status', {
+ props: {
+ endpoint: CommitPipelineStatusEl.dataset.endpoint,
+ },
+ });
+ },
+ });
+}
- initWebIdeLink({ el: document.getElementById('js-blob-web-ide-link') });
+initWebIdeLink({ el: document.getElementById('js-blob-web-ide-link') });
- GpgBadges.fetch();
+GpgBadges.fetch();
- const codeNavEl = document.getElementById('js-code-navigation');
+const codeNavEl = document.getElementById('js-code-navigation');
- if (codeNavEl) {
- const { codeNavigationPath, blobPath, definitionPathPrefix } = codeNavEl.dataset;
+if (codeNavEl) {
+ const { codeNavigationPath, blobPath, definitionPathPrefix } = codeNavEl.dataset;
- // eslint-disable-next-line promise/catch-or-return
- import('~/code_navigation').then((m) =>
- m.default({
- blobs: [{ path: blobPath, codeNavigationPath }],
- definitionPathPrefix,
- }),
- );
- }
+ // eslint-disable-next-line promise/catch-or-return
+ import('~/code_navigation').then((m) =>
+ m.default({
+ blobs: [{ path: blobPath, codeNavigationPath }],
+ definitionPathPrefix,
+ }),
+ );
+}
- const successPipelineEl = document.querySelector('.js-success-pipeline-modal');
+const successPipelineEl = document.querySelector('.js-success-pipeline-modal');
- if (successPipelineEl) {
- // eslint-disable-next-line no-new
- new Vue({
- el: successPipelineEl,
- render(createElement) {
- return createElement(PipelineTourSuccessModal, {
- props: {
- ...successPipelineEl.dataset,
- },
- });
- },
- });
- }
-});
+if (successPipelineEl) {
+ // eslint-disable-next-line no-new
+ new Vue({
+ el: successPipelineEl,
+ render(createElement) {
+ return createElement(PipelineTourSuccessModal, {
+ props: {
+ ...successPipelineEl.dataset,
+ },
+ });
+ },
+ });
+}
diff --git a/app/assets/javascripts/pages/projects/boards/index.js b/app/assets/javascripts/pages/projects/boards/index.js
index 3a06d0faa3e..bde0007ec6a 100644
--- a/app/assets/javascripts/pages/projects/boards/index.js
+++ b/app/assets/javascripts/pages/projects/boards/index.js
@@ -2,8 +2,6 @@ import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import initBoards from '~/boards';
import UsersSelect from '~/users_select';
-document.addEventListener('DOMContentLoaded', () => {
- new UsersSelect(); // eslint-disable-line no-new
- new ShortcutsNavigation(); // eslint-disable-line no-new
- initBoards();
-});
+new UsersSelect(); // eslint-disable-line no-new
+new ShortcutsNavigation(); // eslint-disable-line no-new
+initBoards();
diff --git a/app/assets/javascripts/pages/projects/branches/index/index.js b/app/assets/javascripts/pages/projects/branches/index/index.js
index 623d0a10606..72861855c5a 100644
--- a/app/assets/javascripts/pages/projects/branches/index/index.js
+++ b/app/assets/javascripts/pages/projects/branches/index/index.js
@@ -2,8 +2,6 @@ import AjaxLoadingSpinner from '~/branches/ajax_loading_spinner';
import DeleteModal from '~/branches/branches_delete_modal';
import initDiverganceGraph from '~/branches/divergence_graph';
-document.addEventListener('DOMContentLoaded', () => {
- AjaxLoadingSpinner.init();
- new DeleteModal(); // eslint-disable-line no-new
- initDiverganceGraph(document.querySelector('.js-branch-list').dataset.divergingCountsEndpoint);
-});
+AjaxLoadingSpinner.init();
+new DeleteModal(); // eslint-disable-line no-new
+initDiverganceGraph(document.querySelector('.js-branch-list').dataset.divergingCountsEndpoint);
diff --git a/app/assets/javascripts/pages/projects/branches/new/index.js b/app/assets/javascripts/pages/projects/branches/new/index.js
index 13ff47d53c2..364223f1898 100644
--- a/app/assets/javascripts/pages/projects/branches/new/index.js
+++ b/app/assets/javascripts/pages/projects/branches/new/index.js
@@ -1,11 +1,8 @@
import $ from 'jquery';
import NewBranchForm from '~/new_branch_form';
-document.addEventListener(
- 'DOMContentLoaded',
- () =>
- new NewBranchForm(
- $('.js-create-branch-form'),
- JSON.parse(document.getElementById('availableRefs').innerHTML),
- ),
+// eslint-disable-next-line no-new
+new NewBranchForm(
+ $('.js-create-branch-form'),
+ JSON.parse(document.getElementById('availableRefs').innerHTML),
);
diff --git a/app/assets/javascripts/pages/projects/compare/show/index.js b/app/assets/javascripts/pages/projects/compare/show/index.js
index f1cf9caa28b..549e596cb8d 100644
--- a/app/assets/javascripts/pages/projects/compare/show/index.js
+++ b/app/assets/javascripts/pages/projects/compare/show/index.js
@@ -1,6 +1,9 @@
import Diff from '~/diff';
import GpgBadges from '~/gpg_badges';
import initChangesDropdown from '~/init_changes_dropdown';
+import initCompareSelector from '~/projects/compare';
+
+initCompareSelector();
document.addEventListener('DOMContentLoaded', () => {
new Diff(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/projects/cycle_analytics/show/index.js b/app/assets/javascripts/pages/projects/cycle_analytics/show/index.js
index df58e9dd072..255d05b39be 100644
--- a/app/assets/javascripts/pages/projects/cycle_analytics/show/index.js
+++ b/app/assets/javascripts/pages/projects/cycle_analytics/show/index.js
@@ -1,3 +1,3 @@
-import initCycleAnalytics from '~/cycle_analytics/cycle_analytics_bundle';
+import initCycleAnalytics from '~/cycle_analytics';
document.addEventListener('DOMContentLoaded', initCycleAnalytics);
diff --git a/app/assets/javascripts/pages/projects/feature_flags_user_lists/edit/index.js b/app/assets/javascripts/pages/projects/feature_flags_user_lists/edit/index.js
index bbe84322462..43fd5375222 100644
--- a/app/assets/javascripts/pages/projects/feature_flags_user_lists/edit/index.js
+++ b/app/assets/javascripts/pages/projects/feature_flags_user_lists/edit/index.js
@@ -1,3 +1,5 @@
+/* eslint-disable no-new */
+
import Vue from 'vue';
import Vuex from 'vuex';
import EditUserList from '~/user_lists/components/edit_user_list.vue';
@@ -5,15 +7,13 @@ import createStore from '~/user_lists/store/edit';
Vue.use(Vuex);
-document.addEventListener('DOMContentLoaded', () => {
- const el = document.getElementById('js-edit-user-list');
- const { userListsDocsPath } = el.dataset;
- return new Vue({
- el,
- store: createStore(el.dataset),
- provide: { userListsDocsPath },
- render(h) {
- return h(EditUserList, {});
- },
- });
+const el = document.getElementById('js-edit-user-list');
+const { userListsDocsPath } = el.dataset;
+new Vue({
+ el,
+ store: createStore(el.dataset),
+ provide: { userListsDocsPath },
+ render(h) {
+ return h(EditUserList, {});
+ },
});
diff --git a/app/assets/javascripts/pages/projects/feature_flags_user_lists/new/index.js b/app/assets/javascripts/pages/projects/feature_flags_user_lists/new/index.js
index 679f0af8efc..e855447d5ce 100644
--- a/app/assets/javascripts/pages/projects/feature_flags_user_lists/new/index.js
+++ b/app/assets/javascripts/pages/projects/feature_flags_user_lists/new/index.js
@@ -1,3 +1,5 @@
+/* eslint-disable no-new */
+
import Vue from 'vue';
import Vuex from 'vuex';
import NewUserList from '~/user_lists/components/new_user_list.vue';
@@ -5,18 +7,16 @@ import createStore from '~/user_lists/store/new';
Vue.use(Vuex);
-document.addEventListener('DOMContentLoaded', () => {
- const el = document.getElementById('js-new-user-list');
- const { userListsDocsPath, featureFlagsPath } = el.dataset;
- return new Vue({
- el,
- store: createStore(el.dataset),
- provide: {
- userListsDocsPath,
- featureFlagsPath,
- },
- render(h) {
- return h(NewUserList);
- },
- });
+const el = document.getElementById('js-new-user-list');
+const { userListsDocsPath, featureFlagsPath } = el.dataset;
+new Vue({
+ el,
+ store: createStore(el.dataset),
+ provide: {
+ userListsDocsPath,
+ featureFlagsPath,
+ },
+ render(h) {
+ return h(NewUserList);
+ },
});
diff --git a/app/assets/javascripts/pages/projects/feature_flags_user_lists/show/index.js b/app/assets/javascripts/pages/projects/feature_flags_user_lists/show/index.js
index bccd9dce2ec..2dca0ea7f29 100644
--- a/app/assets/javascripts/pages/projects/feature_flags_user_lists/show/index.js
+++ b/app/assets/javascripts/pages/projects/feature_flags_user_lists/show/index.js
@@ -1,18 +1,3 @@
-import Vue from 'vue';
-import Vuex from 'vuex';
-import UserList from '~/user_lists/components/user_list.vue';
-import createStore from '~/user_lists/store/show';
+import featureFlagsUserListInit from '~/projects/feature_flags_user_lists/show/index';
-Vue.use(Vuex);
-
-document.addEventListener('DOMContentLoaded', () => {
- const el = document.getElementById('js-edit-user-list');
- return new Vue({
- el,
- store: createStore(el.dataset),
- render(h) {
- const { emptyStatePath } = el.dataset;
- return h(UserList, { props: { emptyStatePath } });
- },
- });
-});
+featureFlagsUserListInit();
diff --git a/app/assets/javascripts/pages/projects/forks/new/components/app.vue b/app/assets/javascripts/pages/projects/forks/new/components/app.vue
new file mode 100644
index 00000000000..02b357d389b
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/forks/new/components/app.vue
@@ -0,0 +1,72 @@
+<script>
+import ForkForm from './fork_form.vue';
+
+export default {
+ components: {
+ ForkForm,
+ },
+ props: {
+ forkIllustration: {
+ type: String,
+ required: true,
+ },
+ endpoint: {
+ type: String,
+ required: true,
+ },
+ projectFullPath: {
+ type: String,
+ required: true,
+ },
+ projectId: {
+ type: String,
+ required: true,
+ },
+ projectName: {
+ type: String,
+ required: true,
+ },
+ projectPath: {
+ type: String,
+ required: true,
+ },
+ projectDescription: {
+ type: String,
+ required: true,
+ },
+ projectVisibility: {
+ type: String,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="row gl-mt-5">
+ <div class="col-lg-3">
+ <img :src="forkIllustration" />
+ <h4 class="">{{ s__('ForkProject|Fork project') }}</h4>
+ <p>
+ {{ s__('ForkProject|A fork is a copy of a project.') }}
+ <br />
+ {{
+ s__(
+ 'ForkProject|Forking a repository allows you to make changes without affecting the original project.',
+ )
+ }}
+ </p>
+ </div>
+ <div class="col-lg-9">
+ <fork-form
+ :endpoint="endpoint"
+ :project-full-path="projectFullPath"
+ :project-id="projectId"
+ :project-name="projectName"
+ :project-path="projectPath"
+ :project-description="projectDescription"
+ :project-visibility="projectVisibility"
+ />
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue b/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue
new file mode 100644
index 00000000000..7112b23775d
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue
@@ -0,0 +1,304 @@
+<script>
+import {
+ GlIcon,
+ GlLink,
+ GlForm,
+ GlFormInputGroup,
+ GlInputGroupText,
+ GlFormInput,
+ GlFormGroup,
+ GlFormTextarea,
+ GlButton,
+ GlFormRadio,
+ GlFormRadioGroup,
+ GlFormSelect,
+} from '@gitlab/ui';
+import { buildApiUrl } from '~/api/api_utils';
+import createFlash from '~/flash';
+import axios from '~/lib/utils/axios_utils';
+import csrf from '~/lib/utils/csrf';
+import { redirectTo } from '~/lib/utils/url_utility';
+import { s__ } from '~/locale';
+
+const PRIVATE_VISIBILITY = 'private';
+const INTERNAL_VISIBILITY = 'internal';
+const PUBLIC_VISIBILITY = 'public';
+
+const ALLOWED_VISIBILITY = {
+ private: [PRIVATE_VISIBILITY],
+ internal: [INTERNAL_VISIBILITY, PRIVATE_VISIBILITY],
+ public: [INTERNAL_VISIBILITY, PRIVATE_VISIBILITY, PUBLIC_VISIBILITY],
+};
+
+export default {
+ components: {
+ GlForm,
+ GlIcon,
+ GlLink,
+ GlButton,
+ GlFormInputGroup,
+ GlInputGroupText,
+ GlFormInput,
+ GlFormTextarea,
+ GlFormGroup,
+ GlFormRadio,
+ GlFormRadioGroup,
+ GlFormSelect,
+ },
+ inject: {
+ newGroupPath: {
+ default: '',
+ },
+ visibilityHelpPath: {
+ default: '',
+ },
+ },
+ props: {
+ endpoint: {
+ type: String,
+ required: true,
+ },
+ projectFullPath: {
+ type: String,
+ required: true,
+ },
+ projectId: {
+ type: String,
+ required: true,
+ },
+ projectName: {
+ type: String,
+ required: true,
+ },
+ projectPath: {
+ type: String,
+ required: true,
+ },
+ projectDescription: {
+ type: String,
+ required: true,
+ },
+ projectVisibility: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ isSaving: false,
+ namespaces: [],
+ selectedNamespace: {},
+ fork: {
+ name: this.projectName,
+ slug: this.projectPath,
+ description: this.projectDescription,
+ visibility: this.projectVisibility,
+ },
+ };
+ },
+ computed: {
+ projectUrl() {
+ return `${gon.gitlab_url}/`;
+ },
+ projectAllowedVisibility() {
+ return ALLOWED_VISIBILITY[this.projectVisibility];
+ },
+ namespaceAllowedVisibility() {
+ return (
+ ALLOWED_VISIBILITY[this.selectedNamespace.visibility] ||
+ ALLOWED_VISIBILITY[PUBLIC_VISIBILITY]
+ );
+ },
+ visibilityLevels() {
+ return [
+ {
+ text: s__('ForkProject|Private'),
+ value: PRIVATE_VISIBILITY,
+ icon: 'lock',
+ help: s__('ForkProject|The project can be accessed without any authentication.'),
+ disabled: this.isVisibilityLevelDisabled(PRIVATE_VISIBILITY),
+ },
+ {
+ text: s__('ForkProject|Internal'),
+ value: INTERNAL_VISIBILITY,
+ icon: 'shield',
+ help: s__('ForkProject|The project can be accessed by any logged in user.'),
+ disabled: this.isVisibilityLevelDisabled(INTERNAL_VISIBILITY),
+ },
+ {
+ text: s__('ForkProject|Public'),
+ value: PUBLIC_VISIBILITY,
+ icon: 'earth',
+ help: s__(
+ 'ForkProject|Project access must be granted explicitly to each user. If this project is part of a group, access will be granted to members of the group.',
+ ),
+ disabled: this.isVisibilityLevelDisabled(PUBLIC_VISIBILITY),
+ },
+ ];
+ },
+ },
+ watch: {
+ selectedNamespace(newVal) {
+ const { visibility } = newVal;
+
+ if (this.projectAllowedVisibility.includes(visibility)) {
+ this.fork.visibility = visibility;
+ }
+ },
+ },
+ mounted() {
+ this.fetchNamespaces();
+ },
+ methods: {
+ async fetchNamespaces() {
+ const { data } = await axios.get(this.endpoint);
+ this.namespaces = data.namespaces;
+ },
+ isVisibilityLevelDisabled(visibilityLevel) {
+ return !(
+ this.projectAllowedVisibility.includes(visibilityLevel) &&
+ this.namespaceAllowedVisibility.includes(visibilityLevel)
+ );
+ },
+ async onSubmit() {
+ this.isSaving = true;
+
+ const { projectId } = this;
+ const { name, slug, description, visibility } = this.fork;
+ const { id: namespaceId } = this.selectedNamespace;
+
+ const postParams = {
+ id: projectId,
+ name,
+ namespace_id: namespaceId,
+ path: slug,
+ description,
+ visibility,
+ };
+
+ const forkProjectPath = `/api/:version/projects/:id/fork`;
+ const url = buildApiUrl(forkProjectPath).replace(':id', encodeURIComponent(this.projectId));
+
+ try {
+ const { data } = await axios.post(url, postParams);
+ redirectTo(data.web_url);
+ return;
+ } catch (error) {
+ createFlash({ message: error });
+ }
+ },
+ },
+ csrf,
+};
+</script>
+
+<template>
+ <gl-form method="POST" @submit.prevent="onSubmit">
+ <input type="hidden" name="authenticity_token" :value="$options.csrf.token" />
+
+ <gl-form-group label="Project name" label-for="fork-name">
+ <gl-form-input id="fork-name" v-model="fork.name" data-testid="fork-name-input" required />
+ </gl-form-group>
+
+ <div class="gl-md-display-flex">
+ <div class="gl-flex-basis-half">
+ <gl-form-group label="Project URL" label-for="fork-url" class="gl-md-mr-3">
+ <gl-form-input-group>
+ <template #prepend>
+ <gl-input-group-text>
+ {{ projectUrl }}
+ </gl-input-group-text>
+ </template>
+ <gl-form-select
+ id="fork-url"
+ v-model="selectedNamespace"
+ data-testid="fork-url-input"
+ required
+ >
+ <template slot="first">
+ <option :value="null" disabled>{{ s__('ForkProject|Select a namespace') }}</option>
+ </template>
+ <option v-for="namespace in namespaces" :key="namespace.id" :value="namespace">
+ {{ namespace.name }}
+ </option>
+ </gl-form-select>
+ </gl-form-input-group>
+ </gl-form-group>
+ </div>
+ <div class="gl-flex-basis-half">
+ <gl-form-group label="Project slug" label-for="fork-slug" class="gl-md-ml-3">
+ <gl-form-input
+ id="fork-slug"
+ v-model="fork.slug"
+ data-testid="fork-slug-input"
+ required
+ />
+ </gl-form-group>
+ </div>
+ </div>
+
+ <p class="gl-mt-n5 gl-text-gray-500">
+ {{ s__('ForkProject|Want to house several dependent projects under the same namespace?') }}
+ <gl-link :href="newGroupPath" target="_blank">
+ {{ s__('ForkProject|Create a group') }}
+ </gl-link>
+ </p>
+
+ <gl-form-group label="Project description (optional)" label-for="fork-description">
+ <gl-form-textarea
+ id="fork-description"
+ v-model="fork.description"
+ data-testid="fork-description-textarea"
+ />
+ </gl-form-group>
+
+ <gl-form-group>
+ <label>
+ {{ s__('ForkProject|Visibility level') }}
+ <gl-link :href="visibilityHelpPath" target="_blank">
+ <gl-icon name="question-o" />
+ </gl-link>
+ </label>
+ <gl-form-radio-group
+ v-model="fork.visibility"
+ data-testid="fork-visibility-radio-group"
+ required
+ >
+ <gl-form-radio
+ v-for="{ text, value, icon, help, disabled } in visibilityLevels"
+ :key="value"
+ :value="value"
+ :disabled="disabled"
+ :data-testid="`radio-${value}`"
+ >
+ <div>
+ <gl-icon :name="icon" />
+ <span>{{ text }}</span>
+ </div>
+ <template #help>{{ help }}</template>
+ </gl-form-radio>
+ </gl-form-radio-group>
+ </gl-form-group>
+
+ <div class="gl-display-flex gl-justify-content-space-between gl-mt-8">
+ <gl-button
+ type="submit"
+ category="primary"
+ variant="confirm"
+ data-testid="submit-button"
+ :loading="isSaving"
+ >
+ {{ s__('ForkProject|Fork project') }}
+ </gl-button>
+ <gl-button
+ type="reset"
+ class="gl-mr-3"
+ data-testid="cancel-button"
+ :disabled="isSaving"
+ :href="projectFullPath"
+ >
+ {{ s__('ForkProject|Cancel') }}
+ </gl-button>
+ </div>
+ </gl-form>
+</template>
diff --git a/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list_item.vue b/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list_item.vue
index 46d1696b88b..88f4bba5e2a 100644
--- a/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list_item.vue
+++ b/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list_item.vue
@@ -11,6 +11,7 @@ import {
} from '@gitlab/ui';
import { VISIBILITY_TYPE_ICON, GROUP_VISIBILITY_TYPE } from '~/groups/constants';
import csrf from '~/lib/utils/csrf';
+import UserAccessRoleBadge from '~/vue_shared/components/user_access_role_badge.vue';
export default {
components: {
@@ -20,6 +21,7 @@ export default {
GlButton,
GlTooltip,
GlLink,
+ UserAccessRoleBadge,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -72,7 +74,9 @@ export default {
<template>
<li :class="rowClass" class="group-row">
<div class="group-row-contents gl-display-flex gl-align-items-center gl-py-3 gl-pr-5">
- <div class="folder-toggle-wrap gl-mr-2 gl-display-flex gl-align-items-center">
+ <div
+ class="folder-toggle-wrap gl-mr-3 gl-display-flex gl-align-items-center gl-text-gray-500"
+ >
<gl-icon name="folder-o" />
</div>
<gl-link
@@ -84,12 +88,12 @@ export default {
<div class="gl-min-w-0 gl-display-flex gl-flex-grow-1 gl-flex-shrink-1 gl-align-items-center">
<div class="gl-min-w-0 gl-flex-grow-1 flex-shrink-1">
<div class="title gl-display-flex gl-align-items-center gl-flex-wrap gl-mr-3">
- <gl-link :href="group.relative_path" class="gl-mt-3 gl-mr-3 gl-text-gray-900!">{{
- group.full_name
- }}</gl-link>
+ <gl-link :href="group.relative_path" class="gl-mt-3 gl-mr-3 gl-text-gray-900!">
+ {{ group.full_name }}
+ </gl-link>
<gl-icon
v-gl-tooltip.hover.bottom
- class="gl-mr-0 gl-inline-flex gl-mt-3 text-secondary"
+ class="gl-display-inline-flex gl-mt-3 gl-mr-3 gl-text-gray-500"
:name="visibilityIcon"
:title="visibilityTooltip"
/>
@@ -99,11 +103,11 @@ export default {
class="gl-display-none gl-sm-display-flex gl-mt-3 gl-mr-1"
>{{ __('pending removal') }}</gl-badge
>
- <span v-if="group.permission" class="user-access-role gl-mt-3">
+ <user-access-role-badge v-if="group.permission" class="gl-mt-3">
{{ group.permission }}
- </span>
+ </user-access-role-badge>
</div>
- <div v-if="group.description" class="description">
+ <div v-if="group.description" class="description gl-line-height-20">
<span v-safe-html="group.markdown_description"> </span>
</div>
</div>
diff --git a/app/assets/javascripts/pages/projects/forks/new/index.js b/app/assets/javascripts/pages/projects/forks/new/index.js
index a018d7e0926..372967c8a1e 100644
--- a/app/assets/javascripts/pages/projects/forks/new/index.js
+++ b/app/assets/javascripts/pages/projects/forks/new/index.js
@@ -1,12 +1,52 @@
import Vue from 'vue';
+import App from './components/app.vue';
import ForkGroupsList from './components/fork_groups_list.vue';
-document.addEventListener('DOMContentLoaded', () => {
- const mountElement = document.getElementById('fork-groups-mount-element');
+const mountElement = document.getElementById('fork-groups-mount-element');
+if (gon.features.forkProjectForm) {
+ const {
+ forkIllustration,
+ endpoint,
+ newGroupPath,
+ projectFullPath,
+ visibilityHelpPath,
+ projectId,
+ projectName,
+ projectPath,
+ projectDescription,
+ projectVisibility,
+ } = mountElement.dataset;
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el: mountElement,
+ provide: {
+ newGroupPath,
+ visibilityHelpPath,
+ },
+ render(h) {
+ return h(App, {
+ props: {
+ forkIllustration,
+ endpoint,
+ newGroupPath,
+ projectFullPath,
+ visibilityHelpPath,
+ projectId,
+ projectName,
+ projectPath,
+ projectDescription,
+ projectVisibility,
+ },
+ });
+ },
+ });
+} else {
const { endpoint } = mountElement.dataset;
- return new Vue({
+ // eslint-disable-next-line no-new
+ new Vue({
el: mountElement,
render(h) {
return h(ForkGroupsList, {
@@ -16,4 +56,4 @@ document.addEventListener('DOMContentLoaded', () => {
});
},
});
-});
+}
diff --git a/app/assets/javascripts/pages/projects/imports/show/index.js b/app/assets/javascripts/pages/projects/imports/show/index.js
index d5f92baf054..8397826f8eb 100644
--- a/app/assets/javascripts/pages/projects/imports/show/index.js
+++ b/app/assets/javascripts/pages/projects/imports/show/index.js
@@ -1,5 +1,3 @@
import ProjectImport from '~/project_import';
-document.addEventListener('DOMContentLoaded', () => {
- new ProjectImport(); // eslint-disable-line no-new
-});
+new ProjectImport(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/projects/issues/index/index.js b/app/assets/javascripts/pages/projects/issues/index/index.js
index 525d90e162d..366f8dc61bc 100644
--- a/app/assets/javascripts/pages/projects/issues/index/index.js
+++ b/app/assets/javascripts/pages/projects/issues/index/index.js
@@ -2,9 +2,10 @@
import IssuableFilteredSearchTokenKeys from 'ee_else_ce/filtered_search/issuable_filtered_search_token_keys';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
+import initCsvImportExportButtons from '~/issuable/init_csv_import_export_buttons';
import initIssuableByEmail from '~/issuable/init_issuable_by_email';
import IssuableIndex from '~/issuable_index';
-import initIssuablesList from '~/issues_list';
+import initIssuablesList, { initIssuesListApp } from '~/issues_list';
import initManualOrdering from '~/manual_ordering';
import { FILTERED_SEARCH } from '~/pages/constants';
import { ISSUABLE_INDEX } from '~/pages/projects/constants';
@@ -26,3 +27,5 @@ new UsersSelect();
initManualOrdering();
initIssuablesList();
initIssuableByEmail();
+initCsvImportExportButtons();
+initIssuesListApp();
diff --git a/app/assets/javascripts/pages/projects/jobs/index/index.js b/app/assets/javascripts/pages/projects/jobs/index/index.js
index 6a70d4cf26d..681d151b77f 100644
--- a/app/assets/javascripts/pages/projects/jobs/index/index.js
+++ b/app/assets/javascripts/pages/projects/jobs/index/index.js
@@ -1,19 +1,17 @@
import Vue from 'vue';
import GlCountdown from '~/vue_shared/components/gl_countdown.vue';
-document.addEventListener('DOMContentLoaded', () => {
- const remainingTimeElements = document.querySelectorAll('.js-remaining-time');
- remainingTimeElements.forEach(
- (el) =>
- new Vue({
- el,
- render(h) {
- return h(GlCountdown, {
- props: {
- endDateString: el.dateTime,
- },
- });
- },
- }),
- );
-});
+const remainingTimeElements = document.querySelectorAll('.js-remaining-time');
+remainingTimeElements.forEach(
+ (el) =>
+ new Vue({
+ el,
+ render(h) {
+ return h(GlCountdown, {
+ props: {
+ endDateString: el.dateTime,
+ },
+ });
+ },
+ }),
+);
diff --git a/app/assets/javascripts/pages/projects/labels/edit/index.js b/app/assets/javascripts/pages/projects/labels/edit/index.js
index 83d6ac9fd14..3b7562deed9 100644
--- a/app/assets/javascripts/pages/projects/labels/edit/index.js
+++ b/app/assets/javascripts/pages/projects/labels/edit/index.js
@@ -1,3 +1,3 @@
import Labels from 'ee_else_ce/labels';
-document.addEventListener('DOMContentLoaded', () => new Labels());
+new Labels(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_a.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_a.vue
index 0393793bfe1..32ca623ca45 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_a.vue
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_a.vue
@@ -1,11 +1,11 @@
<script>
import { GlLink } from '@gitlab/ui';
-import { ACTION_TEXT } from '../constants';
+import { ACTION_LABELS } from '../constants';
export default {
components: { GlLink },
i18n: {
- ACTION_TEXT,
+ ACTION_LABELS,
},
props: {
actions: {
@@ -18,9 +18,9 @@ export default {
<template>
<ul>
<li v-for="(value, action) in actions" :key="action">
- <span v-if="value.completed">{{ $options.i18n.ACTION_TEXT[action] }}</span>
+ <span v-if="value.completed">{{ $options.i18n.ACTION_LABELS[action].title }}</span>
<span v-else>
- <gl-link :href="value.url">{{ $options.i18n.ACTION_TEXT[action] }}</gl-link>
+ <gl-link :href="value.url">{{ $options.i18n.ACTION_LABELS[action].title }}</gl-link>
</span>
</li>
</ul>
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_b.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_b.vue
index 0393793bfe1..230054ff76e 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_b.vue
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_b.vue
@@ -1,11 +1,35 @@
<script>
-import { GlLink } from '@gitlab/ui';
-import { ACTION_TEXT } from '../constants';
+import { GlProgressBar, GlSprintf } from '@gitlab/ui';
+import { s__ } from '~/locale';
+import { ACTION_LABELS } from '../constants';
+import LearnGitlabInfoCard from './learn_gitlab_info_card.vue';
export default {
- components: { GlLink },
+ components: { LearnGitlabInfoCard, GlProgressBar, GlSprintf },
i18n: {
- ACTION_TEXT,
+ title: s__('LearnGitLab|Learn GitLab'),
+ description: s__(
+ 'LearnGitLab|Ready to get started with GitLab? Follow these steps to set up your workspace, plan and commit changes, and deploy your project.',
+ ),
+ percentageCompleted: s__(`LearnGitLab|%{percentage}%{percentSymbol} completed`),
+ workspace: {
+ title: s__('LearnGitLab|Set up your workspace'),
+ description: s__(
+ "LearnGitLab|Complete these tasks first so you can enjoy GitLab's features to their fullest:",
+ ),
+ },
+ plan: {
+ title: s__('LearnGitLab|Plan and execute'),
+ description: s__(
+ 'LearnGitLab|Create a workflow for your new workspace, and learn how GitLab features work together:',
+ ),
+ },
+ deploy: {
+ title: s__('LearnGitLab|Deploy'),
+ description: s__(
+ 'LearnGitLab|Use your new GitLab workflow to deploy your application, monitor its health, and keep it secure:',
+ ),
+ },
},
props: {
actions: {
@@ -13,15 +37,76 @@ export default {
type: Object,
},
},
+ maxValue: Object.keys(ACTION_LABELS).length,
+ methods: {
+ infoProps(action) {
+ return {
+ ...this.actions[action],
+ ...ACTION_LABELS[action],
+ };
+ },
+ progressValue() {
+ return Object.values(this.actions).filter((a) => a.completed).length;
+ },
+ progressPercentage() {
+ return Math.round((this.progressValue() / this.$options.maxValue) * 100);
+ },
+ },
};
</script>
<template>
- <ul>
- <li v-for="(value, action) in actions" :key="action">
- <span v-if="value.completed">{{ $options.i18n.ACTION_TEXT[action] }}</span>
- <span v-else>
- <gl-link :href="value.url">{{ $options.i18n.ACTION_TEXT[action] }}</gl-link>
- </span>
- </li>
- </ul>
+ <div>
+ <div class="row">
+ <div class="gl-mb-7 col-md-8 col-lg-7">
+ <h1 class="gl-font-size-h1">{{ $options.i18n.title }}</h1>
+ <p class="gl-text-gray-700 gl-mb-0">{{ $options.i18n.description }}</p>
+ </div>
+ </div>
+
+ <div class="gl-mb-3">
+ <p class="gl-text-gray-500 gl-mb-2" data-testid="completion-percentage">
+ <gl-sprintf :message="$options.i18n.percentageCompleted">
+ <template #percentage>{{ progressPercentage() }}</template>
+ <template #percentSymbol>%</template>
+ </gl-sprintf>
+ </p>
+ <gl-progress-bar :value="progressValue()" :max="$options.maxValue" />
+ </div>
+
+ <h2 class="gl-font-lg gl-mb-3">{{ $options.i18n.workspace.title }}</h2>
+ <p class="gl-text-gray-700 gl-mb-6">{{ $options.i18n.workspace.description }}</p>
+
+ <div class="row row-cols-2 row-cols-md-3 row-cols-lg-4">
+ <div class="col gl-mb-6"><learn-gitlab-info-card v-bind="infoProps('userAdded')" /></div>
+ <div class="col gl-mb-6"><learn-gitlab-info-card v-bind="infoProps('gitWrite')" /></div>
+ <div class="col gl-mb-6">
+ <learn-gitlab-info-card v-bind="infoProps('pipelineCreated')" />
+ </div>
+ <div class="col gl-mb-6"><learn-gitlab-info-card v-bind="infoProps('trialStarted')" /></div>
+ <div class="col gl-mb-6">
+ <learn-gitlab-info-card v-bind="infoProps('codeOwnersEnabled')" />
+ </div>
+ <div class="col gl-mb-6">
+ <learn-gitlab-info-card v-bind="infoProps('requiredMrApprovalsEnabled')" />
+ </div>
+ </div>
+
+ <h2 class="gl-font-lg gl-mb-3">{{ $options.i18n.plan.title }}</h2>
+ <p class="gl-text-gray-700 gl-mb-6">{{ $options.i18n.plan.description }}</p>
+
+ <div class="row row-cols-2 row-cols-md-3 row-cols-lg-4">
+ <div class="col gl-mb-6">
+ <learn-gitlab-info-card v-bind="infoProps('mergeRequestCreated')" />
+ </div>
+ </div>
+
+ <h2 class="gl-font-lg gl-mb-3">{{ $options.i18n.deploy.title }}</h2>
+ <p class="gl-text-gray-700 gl-mb-6">{{ $options.i18n.deploy.description }}</p>
+
+ <div class="row row-cols-2 row-cols-lg-4 g-2 g-lg-3">
+ <div class="col gl-mb-6">
+ <learn-gitlab-info-card v-bind="infoProps('securityScanEnabled')" />
+ </div>
+ </div>
+ </div>
</template>
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_info_card.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_info_card.vue
new file mode 100644
index 00000000000..3d2a8eed9d4
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_info_card.vue
@@ -0,0 +1,70 @@
+<script>
+import { GlLink, GlCard, GlIcon } from '@gitlab/ui';
+import { s__ } from '~/locale';
+
+export default {
+ name: 'LearnGitlabInfoCard',
+ components: { GlLink, GlCard, GlIcon },
+ i18n: {
+ trial: s__('Learn GitLab|Trial only'),
+ },
+ props: {
+ title: {
+ required: true,
+ type: String,
+ },
+ description: {
+ required: true,
+ type: String,
+ },
+ actionLabel: {
+ required: true,
+ type: String,
+ },
+ url: {
+ required: true,
+ type: String,
+ },
+ completed: {
+ required: true,
+ type: Boolean,
+ },
+ svg: {
+ required: true,
+ type: String,
+ },
+ trialRequired: {
+ default: false,
+ required: false,
+ type: Boolean,
+ },
+ },
+};
+</script>
+<template>
+ <gl-card class="gl-pt-0">
+ <div class="gl-text-right gl-h-5">
+ <gl-icon
+ v-if="completed"
+ name="check-circle-filled"
+ class="gl-text-green-500"
+ :size="16"
+ data-testid="completed-icon"
+ />
+ <span
+ v-else-if="trialRequired"
+ class="gl-text-gray-500 gl-font-sm gl-font-style-italic"
+ data-testid="trial-only"
+ >{{ $options.i18n.trial }}</span
+ >
+ </div>
+ <div
+ class="gl-text-center gl-display-flex gl-justify-content-center gl-align-items-center gl-flex-direction-column learn-gitlab-info-card-content"
+ >
+ <img :src="svg" />
+ <h6>{{ title }}</h6>
+ <p class="gl-font-sm gl-text-gray-700">{{ description }}</p>
+ <gl-link :href="url" target="_blank">{{ actionLabel }}</gl-link>
+ </div>
+ </gl-card>
+</template>
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js b/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js
index 8606af29785..80f04b0cf44 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js
@@ -1,12 +1,50 @@
import { s__ } from '~/locale';
-export const ACTION_TEXT = {
- gitWrite: s__('LearnGitLab|Create a repository'),
- userAdded: s__('LearnGitLab|Invite your colleagues'),
- pipelineCreated: s__('LearnGitLab|Set-up CI/CD'),
- trialStarted: s__('LearnGitLab|Start a free trial of GitLab Gold'),
- codeOwnersEnabled: s__('LearnGitLab|Add code owners'),
- requiredMrApprovalsEnabled: s__('LearnGitLab|Enable require merge approvals'),
- mergeRequestCreated: s__('LearnGitLab|Submit a merge request (MR)'),
- securityScanEnabled: s__('LearnGitLab|Run a Security scan using CI/CD'),
+export const ACTION_LABELS = {
+ gitWrite: {
+ title: s__('LearnGitLab|Create or import a repository'),
+ actionLabel: s__('LearnGitLab|Create or import a repository'),
+ description: s__('LearnGitLab|Create or import your first repository into your new project.'),
+ },
+ userAdded: {
+ title: s__('LearnGitLab|Invite your colleagues'),
+ actionLabel: s__('LearnGitLab|Invite your colleagues'),
+ description: s__(
+ 'LearnGitLab|GitLab works best as a team. Invite your colleague to enjoy all features.',
+ ),
+ },
+ pipelineCreated: {
+ title: s__('LearnGitLab|Set up CI/CD'),
+ actionLabel: s__('LearnGitLab|Set-up CI/CD'),
+ description: s__('LearnGitLab|Save time by automating your integration and deployment tasks.'),
+ },
+ trialStarted: {
+ title: s__('LearnGitLab|Start a free Ultimate trial'),
+ actionLabel: s__('LearnGitLab|Try GitLab Ultimate for free'),
+ description: s__('LearnGitLab|Try all GitLab features for 30 days, no credit card required.'),
+ },
+ codeOwnersEnabled: {
+ title: s__('LearnGitLab|Add code owners'),
+ actionLabel: s__('LearnGitLab|Add code owners'),
+ description: s__(
+ 'LearnGitLab|Prevent unexpected changes to important assets by assigning ownership of files and paths.',
+ ),
+ trialRequired: true,
+ },
+ requiredMrApprovalsEnabled: {
+ title: s__('LearnGitLab|Add merge request approval'),
+ actionLabel: s__('LearnGitLab|Enable require merge approvals'),
+ description: s__('LearnGitLab|Route code reviews to the right reviewers, every time.'),
+ trialRequired: true,
+ },
+ mergeRequestCreated: {
+ title: s__('LearnGitLab|Submit a merge request'),
+ actionLabel: s__('LearnGitLab|Submit a merge request (MR)'),
+ description: s__('LearnGitLab|Review and edit proposed changes to source code.'),
+ },
+ securityScanEnabled: {
+ title: s__('LearnGitLab|Run a security scan'),
+ actionLabel: s__('LearnGitLab|Run a Security scan'),
+ description: s__('LearnGitLab|Scan your code to uncover vulnerabilities before deploying.'),
+ },
};
diff --git a/app/assets/javascripts/pages/projects/logs/index.js b/app/assets/javascripts/pages/projects/logs/index.js
index 36747069ebb..0cff1ffc27e 100644
--- a/app/assets/javascripts/pages/projects/logs/index.js
+++ b/app/assets/javascripts/pages/projects/logs/index.js
@@ -1,3 +1,3 @@
import logsBundle from '~/logs';
-document.addEventListener('DOMContentLoaded', logsBundle);
+logsBundle();
diff --git a/app/assets/javascripts/pages/projects/merge_requests/edit/index.js b/app/assets/javascripts/pages/projects/merge_requests/edit/index.js
index 399aebb0c83..ec21d8c84e0 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/edit/index.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/edit/index.js
@@ -1,7 +1,5 @@
import initMergeRequest from '~/pages/projects/merge_requests/init_merge_request';
import initCheckFormState from './check_form_state';
-document.addEventListener('DOMContentLoaded', () => {
- initMergeRequest();
- initCheckFormState();
-});
+initMergeRequest();
+initCheckFormState();
diff --git a/app/assets/javascripts/pages/projects/merge_requests/index/index.js b/app/assets/javascripts/pages/projects/merge_requests/index/index.js
index 76705256fe2..d279086df7b 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/index/index.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/index/index.js
@@ -1,6 +1,7 @@
import addExtraTokensForMergeRequests from 'ee_else_ce/filtered_search/add_extra_tokens_for_merge_requests';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
+import initCsvImportExportButtons from '~/issuable/init_csv_import_export_buttons';
import initIssuableByEmail from '~/issuable/init_issuable_by_email';
import IssuableIndex from '~/issuable_index';
import { FILTERED_SEARCH } from '~/pages/constants';
@@ -22,3 +23,4 @@ new UsersSelect(); // eslint-disable-line no-new
new ShortcutsNavigation(); // eslint-disable-line no-new
initIssuableByEmail();
+initCsvImportExportButtons();
diff --git a/app/assets/javascripts/pages/projects/milestones/edit/index.js b/app/assets/javascripts/pages/projects/milestones/edit/index.js
index 9a4ebf9890d..4f8514a9a1d 100644
--- a/app/assets/javascripts/pages/projects/milestones/edit/index.js
+++ b/app/assets/javascripts/pages/projects/milestones/edit/index.js
@@ -1,3 +1,3 @@
-import initForm from '../../../../shared/milestones/form';
+import initForm from '~/shared/milestones/form';
-document.addEventListener('DOMContentLoaded', () => initForm());
+initForm();
diff --git a/app/assets/javascripts/pages/projects/milestones/index/index.js b/app/assets/javascripts/pages/projects/milestones/index/index.js
index 38789365a67..150b506b121 100644
--- a/app/assets/javascripts/pages/projects/milestones/index/index.js
+++ b/app/assets/javascripts/pages/projects/milestones/index/index.js
@@ -1,3 +1,3 @@
import milestones from '~/pages/milestones/shared';
-document.addEventListener('DOMContentLoaded', milestones);
+milestones();
diff --git a/app/assets/javascripts/pages/projects/milestones/new/index.js b/app/assets/javascripts/pages/projects/milestones/new/index.js
index 9a4ebf9890d..364b0d95d9c 100644
--- a/app/assets/javascripts/pages/projects/milestones/new/index.js
+++ b/app/assets/javascripts/pages/projects/milestones/new/index.js
@@ -1,3 +1,3 @@
import initForm from '../../../../shared/milestones/form';
-document.addEventListener('DOMContentLoaded', () => initForm());
+initForm();
diff --git a/app/assets/javascripts/pages/projects/milestones/show/index.js b/app/assets/javascripts/pages/projects/milestones/show/index.js
index a853413e1f7..3c755e9b98c 100644
--- a/app/assets/javascripts/pages/projects/milestones/show/index.js
+++ b/app/assets/javascripts/pages/projects/milestones/show/index.js
@@ -1,7 +1,5 @@
import milestones from '~/pages/milestones/shared';
import initMilestonesShow from '~/pages/milestones/shared/init_milestones_show';
-document.addEventListener('DOMContentLoaded', () => {
- initMilestonesShow();
- milestones();
-});
+initMilestonesShow();
+milestones();
diff --git a/app/assets/javascripts/pages/projects/new/index.js b/app/assets/javascripts/pages/projects/new/index.js
index 437594fdf11..e10e2872dce 100644
--- a/app/assets/javascripts/pages/projects/new/index.js
+++ b/app/assets/javascripts/pages/projects/new/index.js
@@ -3,28 +3,26 @@ import { __ } from '~/locale';
import initProjectVisibilitySelector from '../../../project_visibility';
import initProjectNew from '../../../projects/project_new';
-document.addEventListener('DOMContentLoaded', () => {
- initProjectVisibilitySelector();
- initProjectNew.bindEvents();
+initProjectVisibilitySelector();
+initProjectNew.bindEvents();
- import(
- /* webpackChunkName: 'experiment_new_project_creation' */ '../../../projects/experiment_new_project_creation'
- )
- .then((m) => {
- const el = document.querySelector('.js-experiment-new-project-creation');
+import(
+ /* webpackChunkName: 'experiment_new_project_creation' */ '../../../projects/experiment_new_project_creation'
+)
+ .then((m) => {
+ const el = document.querySelector('.js-experiment-new-project-creation');
- if (!el) {
- return;
- }
+ if (!el) {
+ return;
+ }
- const config = {
- hasErrors: 'hasErrors' in el.dataset,
- isCiCdAvailable: 'isCiCdAvailable' in el.dataset,
- newProjectGuidelines: el.dataset.newProjectGuidelines,
- };
- m.default(el, config);
- })
- .catch(() => {
- createFlash(__('An error occurred while loading project creation UI'));
- });
-});
+ const config = {
+ hasErrors: 'hasErrors' in el.dataset,
+ isCiCdAvailable: 'isCiCdAvailable' in el.dataset,
+ newProjectGuidelines: el.dataset.newProjectGuidelines,
+ };
+ m.default(el, config);
+ })
+ .catch(() => {
+ createFlash(__('An error occurred while loading project creation UI'));
+ });
diff --git a/app/assets/javascripts/pages/projects/project_members/index.js b/app/assets/javascripts/pages/projects/project_members/index.js
index ed11b07be4a..4aea5614bfb 100644
--- a/app/assets/javascripts/pages/projects/project_members/index.js
+++ b/app/assets/javascripts/pages/projects/project_members/index.js
@@ -1,11 +1,14 @@
import Vue from 'vue';
-import { deprecatedCreateFlash as flash } from '~/flash';
import groupsSelect from '~/groups_select';
+import initInviteGroupTrigger from '~/invite_members/init_invite_group_trigger';
+import initInviteMembersForm from '~/invite_members/init_invite_members_form';
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
-import { __ } from '~/locale';
+import { s__ } from '~/locale';
import memberExpirationDate from '~/member_expiration_date';
-import Members from '~/members';
+import { initMembersApp } from '~/members';
+import { groupLinkRequestFormatter } from '~/members/utils';
+import { projectMemberRequestFormatter } from '~/projects/members/utils';
import UsersSelect from '~/users_select';
import RemoveMemberModal from '~/vue_shared/components/remove_member_modal.vue';
@@ -29,68 +32,51 @@ memberExpirationDate('.js-access-expiration-date-groups');
mountRemoveMemberModal();
initInviteMembersModal();
initInviteMembersTrigger();
+initInviteGroupTrigger();
-new Members(); // eslint-disable-line no-new
-new UsersSelect(); // eslint-disable-line no-new
+// This is only used when `invite_members_group_modal` feature flag is disabled.
+// This can be removed when `invite_members_group_modal` feature flag is removed.
+initInviteMembersForm();
-if (window.gon.features.vueProjectMembersList) {
- const SHARED_FIELDS = ['account', 'expires', 'maxRole', 'expiration', 'actions'];
+new UsersSelect(); // eslint-disable-line no-new
- Promise.all([
- import('~/members/index'),
- import('~/members/utils'),
- import('~/projects/members/utils'),
- import('~/locale'),
- ])
- .then(
- ([
- { initMembersApp },
- { groupLinkRequestFormatter },
- { projectMemberRequestFormatter },
- { s__ },
- ]) => {
- initMembersApp(document.querySelector('.js-project-members-list'), {
- tableFields: SHARED_FIELDS.concat(['source', 'granted']),
- tableAttrs: { tr: { 'data-qa-selector': 'member_row' } },
- tableSortableFields: ['account', 'granted', 'maxRole', 'lastSignIn'],
- requestFormatter: projectMemberRequestFormatter,
- filteredSearchBar: {
- show: true,
- tokens: ['with_inherited_permissions'],
- searchParam: 'search',
- placeholder: s__('Members|Filter members'),
- recentSearchesStorageKey: 'project_members',
- },
- });
+const SHARED_FIELDS = ['account', 'expires', 'maxRole', 'expiration', 'actions'];
+initMembersApp(document.querySelector('.js-project-members-list'), {
+ tableFields: SHARED_FIELDS.concat(['source', 'granted']),
+ tableAttrs: { tr: { 'data-qa-selector': 'member_row' } },
+ tableSortableFields: ['account', 'granted', 'maxRole', 'lastSignIn'],
+ requestFormatter: projectMemberRequestFormatter,
+ filteredSearchBar: {
+ show: true,
+ tokens: ['with_inherited_permissions'],
+ searchParam: 'search',
+ placeholder: s__('Members|Filter members'),
+ recentSearchesStorageKey: 'project_members',
+ },
+});
- initMembersApp(document.querySelector('.js-project-group-links-list'), {
- tableFields: SHARED_FIELDS.concat('granted'),
- tableAttrs: {
- table: { 'data-qa-selector': 'groups_list' },
- tr: { 'data-qa-selector': 'group_row' },
- },
- requestFormatter: groupLinkRequestFormatter,
- filteredSearchBar: {
- show: true,
- tokens: [],
- searchParam: 'search_groups',
- placeholder: s__('Members|Search groups'),
- recentSearchesStorageKey: 'project_group_links',
- },
- });
+initMembersApp(document.querySelector('.js-project-group-links-list'), {
+ tableFields: SHARED_FIELDS.concat('granted'),
+ tableAttrs: {
+ table: { 'data-qa-selector': 'groups_list' },
+ tr: { 'data-qa-selector': 'group_row' },
+ },
+ requestFormatter: groupLinkRequestFormatter,
+ filteredSearchBar: {
+ show: true,
+ tokens: [],
+ searchParam: 'search_groups',
+ placeholder: s__('Members|Search groups'),
+ recentSearchesStorageKey: 'project_group_links',
+ },
+});
- initMembersApp(document.querySelector('.js-project-invited-members-list'), {
- tableFields: SHARED_FIELDS.concat('invited'),
- requestFormatter: projectMemberRequestFormatter,
- });
+initMembersApp(document.querySelector('.js-project-invited-members-list'), {
+ tableFields: SHARED_FIELDS.concat('invited'),
+ requestFormatter: projectMemberRequestFormatter,
+});
- initMembersApp(document.querySelector('.js-project-access-requests-list'), {
- tableFields: SHARED_FIELDS.concat('requested'),
- requestFormatter: projectMemberRequestFormatter,
- });
- },
- )
- .catch(() => {
- flash(__('An error occurred while loading the members, please try again.'));
- });
-}
+initMembersApp(document.querySelector('.js-project-access-requests-list'), {
+ tableFields: SHARED_FIELDS.concat('requested'),
+ requestFormatter: projectMemberRequestFormatter,
+});
diff --git a/app/assets/javascripts/pages/projects/prometheus/metrics/edit/index.js b/app/assets/javascripts/pages/projects/prometheus/metrics/edit/index.js
index 2fd047675b9..82856c1c8b9 100644
--- a/app/assets/javascripts/pages/projects/prometheus/metrics/edit/index.js
+++ b/app/assets/javascripts/pages/projects/prometheus/metrics/edit/index.js
@@ -1,3 +1,3 @@
-import customMetrics from '~/custom_metrics';
+import CustomMetrics from '~/custom_metrics';
-document.addEventListener('DOMContentLoaded', customMetrics);
+CustomMetrics();
diff --git a/app/assets/javascripts/pages/projects/prometheus/metrics/new/index.js b/app/assets/javascripts/pages/projects/prometheus/metrics/new/index.js
index 2fd047675b9..82856c1c8b9 100644
--- a/app/assets/javascripts/pages/projects/prometheus/metrics/new/index.js
+++ b/app/assets/javascripts/pages/projects/prometheus/metrics/new/index.js
@@ -1,3 +1,3 @@
-import customMetrics from '~/custom_metrics';
+import CustomMetrics from '~/custom_metrics';
-document.addEventListener('DOMContentLoaded', customMetrics);
+CustomMetrics();
diff --git a/app/assets/javascripts/pages/projects/settings/access_tokens/index.js b/app/assets/javascripts/pages/projects/settings/access_tokens/index.js
index 22dddb72f98..dc1bb88bf4b 100644
--- a/app/assets/javascripts/pages/projects/settings/access_tokens/index.js
+++ b/app/assets/javascripts/pages/projects/settings/access_tokens/index.js
@@ -1,3 +1,3 @@
-import initExpiresAtField from '~/access_tokens';
+import { initExpiresAtField } from '~/access_tokens';
initExpiresAtField();
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 be9259ec3ca..b7e8d4b03ac 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
@@ -6,6 +6,7 @@ import initDeployFreeze from '~/deploy_freeze';
import { initInstallRunner } from '~/pages/shared/mount_runner_instructions';
import initSharedRunnersToggle from '~/projects/settings/mount_shared_runners_toggle';
import registrySettingsApp from '~/registry/settings/registry_settings_bundle';
+import initSearchSettings from '~/search_settings';
import initSettingsPanels from '~/settings_panels';
document.addEventListener('DOMContentLoaded', () => {
@@ -42,4 +43,6 @@ document.addEventListener('DOMContentLoaded', () => {
}
initInstallRunner();
+
+ initSearchSettings();
});
diff --git a/app/assets/javascripts/pages/projects/settings/operations/show/index.js b/app/assets/javascripts/pages/projects/settings/operations/show/index.js
index 3a46241e2eb..4a800ab150d 100644
--- a/app/assets/javascripts/pages/projects/settings/operations/show/index.js
+++ b/app/assets/javascripts/pages/projects/settings/operations/show/index.js
@@ -3,6 +3,7 @@ import mountErrorTrackingForm from '~/error_tracking_settings';
import mountGrafanaIntegration from '~/grafana_integration';
import initIncidentsSettings from '~/incidents_settings';
import mountOperationSettings from '~/operation_settings';
+import initSearchSettings from '~/search_settings';
import initSettingsPanels from '~/settings_panels';
initIncidentsSettings();
@@ -13,3 +14,7 @@ if (!IS_EE) {
initSettingsPanels();
}
mountAlertsSettings(document.querySelector('.js-alerts-settings'));
+
+document.addEventListener('DOMContentLoaded', () => {
+ initSearchSettings();
+});
diff --git a/app/assets/javascripts/pages/projects/settings/repository/show/index.js b/app/assets/javascripts/pages/projects/settings/repository/show/index.js
index e90954c14c5..c7bcbb83051 100644
--- a/app/assets/javascripts/pages/projects/settings/repository/show/index.js
+++ b/app/assets/javascripts/pages/projects/settings/repository/show/index.js
@@ -1,4 +1,5 @@
import MirrorRepos from '~/mirrors/mirror_repos';
+import initSearchSettings from '~/search_settings';
import initForm from '../form';
document.addEventListener('DOMContentLoaded', () => {
@@ -6,4 +7,6 @@ document.addEventListener('DOMContentLoaded', () => {
const mirrorReposContainer = document.querySelector('.js-mirror-settings');
if (mirrorReposContainer) new MirrorRepos(mirrorReposContainer).init();
+
+ initSearchSettings();
});
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 94a9bc168e5..0b58cb4731d 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
@@ -11,6 +11,7 @@ import {
featureAccessLevelEveryone,
featureAccessLevel,
featureAccessLevelNone,
+ CVE_ID_REQUEST_BUTTON_I18N,
} from '../constants';
import { toggleHiddenClassBySelector } from '../external';
import projectFeatureSetting from './project_feature_setting.vue';
@@ -19,6 +20,10 @@ import projectSettingRow from './project_setting_row.vue';
const PAGE_FEATURE_ACCESS_LEVEL = s__('ProjectSettings|Everyone');
export default {
+ i18n: {
+ ...CVE_ID_REQUEST_BUTTON_I18N,
+ },
+
components: {
projectFeatureSetting,
projectSettingRow,
@@ -31,6 +36,11 @@ export default {
mixins: [settingsMixin, glFeatureFlagsMixin()],
props: {
+ requestCveAvailable: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
currentSettings: {
type: Object,
required: true,
@@ -74,11 +84,6 @@ export default {
required: false,
default: false,
},
- securityAndComplianceAvailable: {
- type: Boolean,
- required: false,
- default: false,
- },
visibilityHelpPath: {
type: String,
required: false,
@@ -99,6 +104,11 @@ export default {
required: false,
default: '',
},
+ cveIdRequestHelpPath: {
+ type: String,
+ required: false,
+ default: '',
+ },
registryHelpPath: {
type: String,
required: false,
@@ -152,6 +162,7 @@ export default {
requestAccessEnabled: true,
highlightChangesClass: false,
emailsDisabled: false,
+ cveIdRequestEnabled: true,
featureAccessLevelEveryone,
featureAccessLevelMembers,
};
@@ -230,6 +241,9 @@ export default {
'ProjectSettings|View and edit files in this project. Non-project members will only have read access.',
);
},
+ cveIdRequestIsDisabled() {
+ return this.visibilityLevel !== visibilityOptions.PUBLIC;
+ },
},
watch: {
@@ -417,6 +431,19 @@ export default {
:options="featureAccessLevelOptions"
name="project[project_feature_attributes][issues_access_level]"
/>
+ <project-setting-row
+ v-if="requestCveAvailable"
+ :help-path="cveIdRequestHelpPath"
+ :help-text="$options.i18n.cve_request_toggle_label"
+ >
+ <gl-toggle
+ v-model="cveIdRequestEnabled"
+ class="gl-my-2"
+ :disabled="cveIdRequestIsDisabled"
+ name="project[project_setting_attributes][cve_id_request_enabled]"
+ data-testid="cve_id_request_toggle"
+ />
+ </project-setting-row>
</project-setting-row>
<project-setting-row
ref="repository-settings"
@@ -563,7 +590,6 @@ export default {
/>
</project-setting-row>
<project-setting-row
- v-if="securityAndComplianceAvailable"
:label="s__('ProjectSettings|Security & Compliance')"
:help-text="s__('ProjectSettings|Security & Compliance for this project')"
>
@@ -613,7 +639,9 @@ export default {
<project-setting-row
ref="operations-settings"
:label="s__('ProjectSettings|Operations')"
- :help-text="s__('ProjectSettings|Environments, logs, cluster management, and more.')"
+ :help-text="
+ s__('ProjectSettings|Configure your project resources and monitor their health.')
+ "
>
<project-feature-setting
v-model="operationsAccessLevel"
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/constants.js b/app/assets/javascripts/pages/projects/shared/permissions/constants.js
index 6771391254e..e160fdacca6 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/constants.js
+++ b/app/assets/javascripts/pages/projects/shared/permissions/constants.js
@@ -1,4 +1,4 @@
-import { __ } from '~/locale';
+import { s__, __ } from '~/locale';
export const visibilityOptions = {
PRIVATE: 0,
@@ -42,3 +42,7 @@ export const featureAccessLevelEveryone = [
featureAccessLevel.EVERYONE,
featureAccessLevelDescriptions[featureAccessLevel.EVERYONE],
];
+
+export const CVE_ID_REQUEST_BUTTON_I18N = {
+ cve_request_toggle_label: s__('CVE|Enable CVE ID requests in the issue sidebar'),
+};
diff --git a/app/assets/javascripts/pages/projects/show/index.js b/app/assets/javascripts/pages/projects/show/index.js
index 0494dad6e33..83e43d7ac48 100644
--- a/app/assets/javascripts/pages/projects/show/index.js
+++ b/app/assets/javascripts/pages/projects/show/index.js
@@ -3,20 +3,16 @@ import Activities from '~/activities';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import BlobViewer from '~/blob/viewer/index';
import { initUploadForm } from '~/blob_edit/blob_bundle';
-import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
-import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
import leaveByUrl from '~/namespaces/leave_by_url';
import initVueNotificationsDropdown from '~/notifications';
-import NotificationsForm from '~/notifications_form';
+import { initUploadFileTrigger } from '~/projects/upload_file_experiment';
import initReadMore from '~/read_more';
import UserCallout from '~/user_callout';
-import notificationsDropdown from '../../../notifications_dropdown';
import Star from '../../../star';
initReadMore();
new Star(); // eslint-disable-line no-new
-new NotificationsForm(); // eslint-disable-line no-new
// eslint-disable-next-line no-new
new UserCallout({
setCalloutPerProject: false,
@@ -24,9 +20,12 @@ new UserCallout({
});
// Project show page loads different overview content based on user preferences
-const treeSlider = document.getElementById('js-tree-list');
-if (treeSlider) {
+
+if (document.querySelector('.js-upload-blob-form')) {
initUploadForm();
+}
+
+if (document.getElementById('js-tree-list')) {
initTree();
}
@@ -40,15 +39,8 @@ if (document.querySelector('.project-show-activity')) {
leaveByUrl('project');
-if (gon.features?.vueNotificationDropdown) {
- initVueNotificationsDropdown();
-} else {
- notificationsDropdown();
-}
-
initVueNotificationsDropdown();
new ShortcutsNavigation(); // eslint-disable-line no-new
-initInviteMembersTrigger();
-initInviteMembersModal();
+initUploadFileTrigger();
diff --git a/app/assets/javascripts/pages/projects/tags/new/index.js b/app/assets/javascripts/pages/projects/tags/new/index.js
index 11a19a673b1..b071e7a45fc 100644
--- a/app/assets/javascripts/pages/projects/tags/new/index.js
+++ b/app/assets/javascripts/pages/projects/tags/new/index.js
@@ -3,8 +3,6 @@ import GLForm from '../../../../gl_form';
import RefSelectDropdown from '../../../../ref_select_dropdown';
import ZenMode from '../../../../zen_mode';
-document.addEventListener('DOMContentLoaded', () => {
- new ZenMode(); // eslint-disable-line no-new
- new GLForm($('.tag-form')); // eslint-disable-line no-new
- new RefSelectDropdown($('.js-branch-select')); // eslint-disable-line no-new
-});
+new ZenMode(); // eslint-disable-line no-new
+new GLForm($('.tag-form')); // eslint-disable-line no-new
+new RefSelectDropdown($('.js-branch-select')); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/projects/tags/releases/index.js b/app/assets/javascripts/pages/projects/tags/releases/index.js
index abdc97f62d0..cafd880b4be 100644
--- a/app/assets/javascripts/pages/projects/tags/releases/index.js
+++ b/app/assets/javascripts/pages/projects/tags/releases/index.js
@@ -2,7 +2,5 @@ import $ from 'jquery';
import GLForm from '~/gl_form';
import ZenMode from '~/zen_mode';
-document.addEventListener('DOMContentLoaded', () => {
- new ZenMode(); // eslint-disable-line no-new
- new GLForm($('.release-form')); // eslint-disable-line no-new
-});
+new ZenMode(); // eslint-disable-line no-new
+new GLForm($('.release-form')); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/search/show/index.js b/app/assets/javascripts/pages/search/show/index.js
index a8c288c3663..2ee33584ee1 100644
--- a/app/assets/javascripts/pages/search/show/index.js
+++ b/app/assets/javascripts/pages/search/show/index.js
@@ -1,5 +1,3 @@
import { initSearchApp } from '~/search';
-document.addEventListener('DOMContentLoaded', () => {
- initSearchApp();
-});
+initSearchApp();
diff --git a/app/assets/javascripts/pages/shared/wikis/components/wiki_alert.vue b/app/assets/javascripts/pages/shared/wikis/components/wiki_alert.vue
new file mode 100644
index 00000000000..6cea26f2bed
--- /dev/null
+++ b/app/assets/javascripts/pages/shared/wikis/components/wiki_alert.vue
@@ -0,0 +1,31 @@
+<script>
+import { GlAlert, GlLink, GlSprintf } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlAlert,
+ GlLink,
+ GlSprintf,
+ },
+ props: {
+ error: {
+ type: String,
+ required: true,
+ },
+ wikiPagePath: {
+ type: String,
+ required: true,
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-alert variant="danger" :dismissible="false">
+ <gl-sprintf :message="error">
+ <template #wikiLink="{ content }">
+ <gl-link :href="wikiPagePath" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </gl-alert>
+</template>
diff --git a/app/assets/javascripts/pages/shared/wikis/index.js b/app/assets/javascripts/pages/shared/wikis/index.js
index c8dc75828e4..c382a372260 100644
--- a/app/assets/javascripts/pages/shared/wikis/index.js
+++ b/app/assets/javascripts/pages/shared/wikis/index.js
@@ -6,9 +6,10 @@ import Translate from '~/vue_shared/translate';
import GLForm from '../../../gl_form';
import ZenMode from '../../../zen_mode';
import deleteWikiModal from './components/delete_wiki_modal.vue';
+import wikiAlert from './components/wiki_alert.vue';
import Wikis from './wikis';
-export default () => {
+const createModalVueApp = () => {
new Wikis(); // eslint-disable-line no-new
new ShortcutsWiki(); // eslint-disable-line no-new
new ZenMode(); // eslint-disable-line no-new
@@ -39,3 +40,28 @@ export default () => {
});
}
};
+
+const createAlertVueApp = () => {
+ const el = document.getElementById('js-wiki-error');
+ if (el) {
+ const { error, wikiPagePath } = el.dataset;
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ render(createElement) {
+ return createElement(wikiAlert, {
+ props: {
+ error,
+ wikiPagePath,
+ },
+ });
+ },
+ });
+ }
+};
+
+export default () => {
+ createModalVueApp();
+ createAlertVueApp();
+};
diff --git a/app/assets/javascripts/pages/users/index.js b/app/assets/javascripts/pages/users/index.js
index b22287a0093..58ceb524360 100644
--- a/app/assets/javascripts/pages/users/index.js
+++ b/app/assets/javascripts/pages/users/index.js
@@ -15,9 +15,7 @@ function initUserProfile(action) {
});
}
-document.addEventListener('DOMContentLoaded', () => {
- const page = $('body').attr('data-page');
- const action = page.split(':')[1];
- initUserProfile(action);
- new UserCallout(); // eslint-disable-line no-new
-});
+const page = $('body').attr('data-page');
+const action = page.split(':')[1];
+initUserProfile(action);
+new UserCallout(); // eslint-disable-line no-new