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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-04-20 13:00:54 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-04-20 13:00:54 +0300
commit3cccd102ba543e02725d247893729e5c73b38295 (patch)
treef36a04ec38517f5deaaacb5acc7d949688d1e187 /app/assets/javascripts/pages
parent205943281328046ef7b4528031b90fbda70c75ac (diff)
Add latest changes from gitlab-org/gitlab@14-10-stable-eev14.10.0-rc42
Diffstat (limited to 'app/assets/javascripts/pages')
-rw-r--r--app/assets/javascripts/pages/admin/abuse_reports/abuse_reports.js2
-rw-r--r--app/assets/javascripts/pages/admin/admin.js2
-rw-r--r--app/assets/javascripts/pages/admin/application_settings/payload_downloader.js4
-rw-r--r--app/assets/javascripts/pages/admin/application_settings/payload_previewer.js4
-rw-r--r--app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js1
-rw-r--r--app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js88
-rw-r--r--app/assets/javascripts/pages/admin/groups/new/index.js4
-rw-r--r--app/assets/javascripts/pages/admin/index.js4
-rw-r--r--app/assets/javascripts/pages/groups/clusters/index/index.js8
-rw-r--r--app/assets/javascripts/pages/groups/crm/contacts/index.js2
-rw-r--r--app/assets/javascripts/pages/groups/crm/organizations/index.js2
-rw-r--r--app/assets/javascripts/pages/groups/edit/index.js28
-rw-r--r--app/assets/javascripts/pages/groups/group_members/index.js26
-rw-r--r--app/assets/javascripts/pages/groups/harbor/repositories/index.js8
-rw-r--r--app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue4
-rw-r--r--app/assets/javascripts/pages/import/history/components/import_error_details.vue43
-rw-r--r--app/assets/javascripts/pages/import/history/components/import_history_app.vue199
-rw-r--r--app/assets/javascripts/pages/import/history/index.js21
-rw-r--r--app/assets/javascripts/pages/import/history/utils/error_messages.js3
-rw-r--r--app/assets/javascripts/pages/profiles/preferences/show/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/commit/show/index.js32
-rw-r--r--app/assets/javascripts/pages/projects/harbor/repositories/index.js8
-rw-r--r--app/assets/javascripts/pages/projects/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue8
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_card.vue24
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue100
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/index/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js12
-rw-r--r--app/assets/javascripts/pages/projects/network/network.js2
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue3
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js18
-rw-r--r--app/assets/javascripts/pages/projects/project.js2
-rw-r--r--app/assets/javascripts/pages/projects/project_members/index.js11
-rw-r--r--app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js54
-rw-r--r--app/assets/javascripts/pages/projects/settings/repository/show/index.js8
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/project_feature_setting.vue16
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue20
-rw-r--r--app/assets/javascripts/pages/projects/snippets/show/index.js9
-rw-r--r--app/assets/javascripts/pages/projects/tags/new/index.js6
-rw-r--r--app/assets/javascripts/pages/projects/tree/show/index.js4
-rw-r--r--app/assets/javascripts/pages/projects/wikis/show/index.js2
-rw-r--r--app/assets/javascripts/pages/sessions/new/index.js2
-rw-r--r--app/assets/javascripts/pages/sessions/new/length_validator.js2
-rw-r--r--app/assets/javascripts/pages/shared/wikis/components/wiki_content.vue92
-rw-r--r--app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue146
-rw-r--r--app/assets/javascripts/pages/shared/wikis/edit.js4
-rw-r--r--app/assets/javascripts/pages/shared/wikis/render_gfm_facade.js5
-rw-r--r--app/assets/javascripts/pages/shared/wikis/show.js27
49 files changed, 702 insertions, 383 deletions
diff --git a/app/assets/javascripts/pages/admin/abuse_reports/abuse_reports.js b/app/assets/javascripts/pages/admin/abuse_reports/abuse_reports.js
index e78b3f9ec95..29e92a8abad 100644
--- a/app/assets/javascripts/pages/admin/abuse_reports/abuse_reports.js
+++ b/app/assets/javascripts/pages/admin/abuse_reports/abuse_reports.js
@@ -1,6 +1,6 @@
import $ from 'jquery';
import { parseBoolean } from '~/lib/utils/common_utils';
-import { truncate } from '../../../lib/utils/text_utility';
+import { truncate } from '~/lib/utils/text_utility';
const MAX_MESSAGE_LENGTH = 500;
const MESSAGE_CELL_SELECTOR = '.abuse-reports .message';
diff --git a/app/assets/javascripts/pages/admin/admin.js b/app/assets/javascripts/pages/admin/admin.js
index 6b7bfbf217d..e6c1d6d147b 100644
--- a/app/assets/javascripts/pages/admin/admin.js
+++ b/app/assets/javascripts/pages/admin/admin.js
@@ -1,5 +1,5 @@
import $ from 'jquery';
-import { refreshCurrentPage } from '../../lib/utils/url_utility';
+import { refreshCurrentPage } from '~/lib/utils/url_utility';
export default function adminInit() {
$('input#user_force_random_password').on('change', function randomPasswordClick() {
diff --git a/app/assets/javascripts/pages/admin/application_settings/payload_downloader.js b/app/assets/javascripts/pages/admin/application_settings/payload_downloader.js
index 67eee2c3209..7c81cf80dc6 100644
--- a/app/assets/javascripts/pages/admin/application_settings/payload_downloader.js
+++ b/app/assets/javascripts/pages/admin/application_settings/payload_downloader.js
@@ -1,6 +1,6 @@
import createFlash from '~/flash';
-import axios from '../../../lib/utils/axios_utils';
-import { __ } from '../../../locale';
+import axios from '~/lib/utils/axios_utils';
+import { __ } from '~/locale';
export default class PayloadDownloader {
constructor(trigger) {
diff --git a/app/assets/javascripts/pages/admin/application_settings/payload_previewer.js b/app/assets/javascripts/pages/admin/application_settings/payload_previewer.js
index c017cf0afa2..ae08806fe4c 100644
--- a/app/assets/javascripts/pages/admin/application_settings/payload_previewer.js
+++ b/app/assets/javascripts/pages/admin/application_settings/payload_previewer.js
@@ -1,6 +1,6 @@
import createFlash from '~/flash';
-import axios from '../../../lib/utils/axios_utils';
-import { __ } from '../../../locale';
+import axios from '~/lib/utils/axios_utils';
+import { __ } from '~/locale';
export default class PayloadPreviewer {
constructor(trigger) {
diff --git a/app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js b/app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js
index 70b896f6372..a50d8de0e88 100644
--- a/app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js
+++ b/app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js
@@ -23,6 +23,7 @@ export default function initSignupRestrictions(elementSelector = '#js-signup-for
return new Vue({
el,
+ name: 'SignupRestrictions',
provide: {
...parsedDataset,
},
diff --git a/app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js b/app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js
index 2a7e6a45cdd..18ba89f8856 100644
--- a/app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js
+++ b/app/assets/javascripts/pages/admin/broadcast_messages/broadcast_message.js
@@ -2,52 +2,41 @@ import $ from 'jquery';
import { debounce } from 'lodash';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
-import { textColorForBackground } from '~/lib/utils/color_utils';
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
import { __ } from '~/locale';
export default () => {
- const $broadcastMessageColor = $('.js-broadcast-message-color');
+ const $broadcastMessageTheme = $('.js-broadcast-message-theme');
const $broadcastMessageType = $('.js-broadcast-message-type');
- const $broadcastBannerMessagePreview = $('.js-broadcast-banner-message-preview');
+ const $broadcastBannerMessagePreview = $('.js-broadcast-banner-message-preview [role="alert"]');
const $broadcastMessage = $('.js-broadcast-message-message');
- const $jsBroadcastMessagePreview = $('.js-broadcast-message-preview');
+ const $jsBroadcastMessagePreview = $('#broadcast-message-preview');
const reloadPreview = function reloadPreview() {
const previewPath = $broadcastMessage.data('previewPath');
const message = $broadcastMessage.val();
const type = $broadcastMessageType.val();
-
- if (message === '') {
- $jsBroadcastMessagePreview.text(__('Your message here'));
- } else {
- axios
- .post(previewPath, {
- broadcast_message: {
- message,
- broadcast_type: type,
- },
- })
- .then(({ data }) => {
- $jsBroadcastMessagePreview.html(data.message);
- })
- .catch(() =>
- createFlash({
- message: __('An error occurred while rendering preview broadcast message'),
- }),
- );
- }
+ const theme = $broadcastMessageTheme.val();
+
+ axios
+ .post(previewPath, {
+ broadcast_message: {
+ message,
+ broadcast_type: type,
+ theme,
+ },
+ })
+ .then(({ data }) => {
+ $jsBroadcastMessagePreview.html(data);
+ })
+ .catch(() =>
+ createFlash({
+ message: __('An error occurred while rendering preview broadcast message'),
+ }),
+ );
};
- $broadcastMessageColor.on('input', function onMessageColorInput() {
- const previewColor = $(this).val();
- $broadcastBannerMessagePreview.css('background-color', previewColor);
- });
-
- $('input#broadcast_message_font').on('input', function onMessageFontInput() {
- const previewColor = $(this).val();
- $broadcastBannerMessagePreview.css('color', previewColor);
- });
+ $broadcastMessageTheme.on('change', reloadPreview);
$broadcastMessageType.on('change', () => {
const $broadcastMessageColorFormGroup = $('.js-broadcast-message-background-color-form-group');
@@ -68,37 +57,4 @@ export default () => {
reloadPreview();
}, DEFAULT_DEBOUNCE_AND_THROTTLE_MS),
);
-
- const updateColorPreview = () => {
- const selectedBackgroundColor = $broadcastMessageColor.val();
- const contrastTextColor = textColorForBackground(selectedBackgroundColor);
-
- // save contrastTextColor to hidden input field
- $('input.text-font-color').val(contrastTextColor);
-
- // Updates the preview color with the hex-color input
- const selectedColorStyle = {
- backgroundColor: selectedBackgroundColor,
- color: contrastTextColor,
- };
-
- $('.label-color-preview').css(selectedColorStyle);
-
- return $jsBroadcastMessagePreview.css(selectedColorStyle);
- };
-
- const setSuggestedColor = (e) => {
- const color = $(e.currentTarget).data('color');
- $broadcastMessageColor
- .val(color)
- // Notify the form, that color has changed
- .trigger('input');
- // Only banner supports colors
- if ($broadcastMessageType === 'banner') {
- updateColorPreview();
- }
- return e.preventDefault();
- };
-
- $(document).on('click', '.suggest-colors a', setSuggestedColor);
};
diff --git a/app/assets/javascripts/pages/admin/groups/new/index.js b/app/assets/javascripts/pages/admin/groups/new/index.js
index 1630cfb8253..710d2d72f4c 100644
--- a/app/assets/javascripts/pages/admin/groups/new/index.js
+++ b/app/assets/javascripts/pages/admin/groups/new/index.js
@@ -1,6 +1,6 @@
import initFilePickers from '~/file_pickers';
-import BindInOut from '../../../../behaviors/bind_in_out';
-import Group from '../../../../group';
+import BindInOut from '~/behaviors/bind_in_out';
+import Group from '~/group';
(() => {
BindInOut.initAll();
diff --git a/app/assets/javascripts/pages/admin/index.js b/app/assets/javascripts/pages/admin/index.js
index f0f85b82e2b..a249864fa36 100644
--- a/app/assets/javascripts/pages/admin/index.js
+++ b/app/assets/javascripts/pages/admin/index.js
@@ -1,6 +1,6 @@
import initGitlabVersionCheck from '~/gitlab_version_check';
-import initAdminStatisticsPanel from '../../admin/statistics_panel/index';
-import initVueAlerts from '../../vue_alerts';
+import initAdminStatisticsPanel from '~/admin/statistics_panel/index';
+import initVueAlerts from '~/vue_alerts';
import initAdmin from './admin';
initVueAlerts();
diff --git a/app/assets/javascripts/pages/groups/clusters/index/index.js b/app/assets/javascripts/pages/groups/clusters/index/index.js
index a99e0dfa4f0..a1ba920b322 100644
--- a/app/assets/javascripts/pages/groups/clusters/index/index.js
+++ b/app/assets/javascripts/pages/groups/clusters/index/index.js
@@ -1,8 +1,6 @@
import initClustersListApp from '~/clusters_list';
import PersistentUserCallout from '~/persistent_user_callout';
-document.addEventListener('DOMContentLoaded', () => {
- const callout = document.querySelector('.gcp-signup-offer');
- PersistentUserCallout.factory(callout);
- initClustersListApp();
-});
+const callout = document.querySelector('.gcp-signup-offer');
+PersistentUserCallout.factory(callout);
+initClustersListApp();
diff --git a/app/assets/javascripts/pages/groups/crm/contacts/index.js b/app/assets/javascripts/pages/groups/crm/contacts/index.js
index a595246957f..6af47621c1d 100644
--- a/app/assets/javascripts/pages/groups/crm/contacts/index.js
+++ b/app/assets/javascripts/pages/groups/crm/contacts/index.js
@@ -1,3 +1,3 @@
-import initCrmContactsApp from '~/crm/contacts_bundle';
+import initCrmContactsApp from '~/crm/contacts/bundle';
initCrmContactsApp();
diff --git a/app/assets/javascripts/pages/groups/crm/organizations/index.js b/app/assets/javascripts/pages/groups/crm/organizations/index.js
index 16479b43d52..2ad0904688e 100644
--- a/app/assets/javascripts/pages/groups/crm/organizations/index.js
+++ b/app/assets/javascripts/pages/groups/crm/organizations/index.js
@@ -1,3 +1,3 @@
-import initCrmOrganizationsApp from '~/crm/organizations_bundle';
+import initCrmOrganizationsApp from '~/crm/organizations/bundle';
initCrmOrganizationsApp();
diff --git a/app/assets/javascripts/pages/groups/edit/index.js b/app/assets/javascripts/pages/groups/edit/index.js
index 96487e14e30..58ca195d7b9 100644
--- a/app/assets/javascripts/pages/groups/edit/index.js
+++ b/app/assets/javascripts/pages/groups/edit/index.js
@@ -10,21 +10,19 @@ import initSearchSettings from '~/search_settings';
import initSettingsPanels from '~/settings_panels';
import initConfirmDanger from '~/init_confirm_danger';
-document.addEventListener('DOMContentLoaded', () => {
- initFilePickers();
- initConfirmDanger();
- initSettingsPanels();
- initTransferGroupForm();
- dirtySubmitFactory(
- document.querySelectorAll('.js-general-settings-form, .js-general-permissions-form'),
- );
- mountBadgeSettings(GROUP_BADGE);
+initFilePickers();
+initConfirmDanger();
+initSettingsPanels();
+initTransferGroupForm();
+dirtySubmitFactory(
+ document.querySelectorAll('.js-general-settings-form, .js-general-permissions-form'),
+);
+mountBadgeSettings(GROUP_BADGE);
- // Initialize Subgroups selector
- groupsSelect();
+// Initialize Subgroups selector
+groupsSelect();
- projectSelect();
+projectSelect();
- initSearchSettings();
- initCascadingSettingsLockPopovers();
-});
+initSearchSettings();
+initCascadingSettingsLockPopovers();
diff --git a/app/assets/javascripts/pages/groups/group_members/index.js b/app/assets/javascripts/pages/groups/group_members/index.js
index 280b544af3c..79ac31f1659 100644
--- a/app/assets/javascripts/pages/groups/group_members/index.js
+++ b/app/assets/javascripts/pages/groups/group_members/index.js
@@ -12,9 +12,16 @@ const SHARED_FIELDS = ['account', 'maxRole', 'expiration', 'actions'];
initMembersApp(document.querySelector('.js-group-members-list-app'), {
[MEMBER_TYPES.user]: {
- tableFields: SHARED_FIELDS.concat(['source', 'granted']),
+ tableFields: SHARED_FIELDS.concat(['source', 'granted', 'userCreatedAt', 'lastActivityOn']),
tableAttrs: { tr: { 'data-qa-selector': 'member_row' } },
- tableSortableFields: ['account', 'granted', 'maxRole', 'lastSignIn'],
+ tableSortableFields: [
+ 'account',
+ 'granted',
+ 'maxRole',
+ 'lastSignIn',
+ 'userCreatedAt',
+ 'lastActivityOn',
+ ],
requestFormatter: groupMemberRequestFormatter,
filteredSearchBar: {
show: true,
@@ -25,12 +32,25 @@ initMembersApp(document.querySelector('.js-group-members-list-app'), {
},
},
[MEMBER_TYPES.group]: {
- tableFields: SHARED_FIELDS.concat('granted'),
+ tableFields: gon?.features?.groupMemberInheritedGroup
+ ? SHARED_FIELDS.concat(['source', 'granted'])
+ : SHARED_FIELDS.concat(['granted']),
tableAttrs: {
table: { 'data-qa-selector': 'groups_list' },
tr: { 'data-qa-selector': 'group_row' },
},
requestFormatter: groupLinkRequestFormatter,
+ ...(gon?.features?.groupMemberInheritedGroup
+ ? {
+ filteredSearchBar: {
+ show: true,
+ tokens: ['with_inherited_permissions'],
+ searchParam: 'search_groups',
+ placeholder: s__('Members|Filter groups'),
+ recentSearchesStorageKey: 'group_links_members',
+ },
+ }
+ : {}),
},
[MEMBER_TYPES.invite]: {
tableFields: SHARED_FIELDS.concat('invited'),
diff --git a/app/assets/javascripts/pages/groups/harbor/repositories/index.js b/app/assets/javascripts/pages/groups/harbor/repositories/index.js
new file mode 100644
index 00000000000..0ecce44be54
--- /dev/null
+++ b/app/assets/javascripts/pages/groups/harbor/repositories/index.js
@@ -0,0 +1,8 @@
+import HarborRegistryExplorer from '~/packages_and_registries/harbor_registry/index';
+
+const explorer = HarborRegistryExplorer('js-harbor-registry-list-group');
+
+if (explorer) {
+ explorer.attachBreadcrumb();
+ explorer.attachMainComponent();
+}
diff --git a/app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue b/app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue
index 0ec382983a5..9a4054eb110 100644
--- a/app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue
+++ b/app/assets/javascripts/pages/import/bulk_imports/history/components/bulk_imports_history_app.vue
@@ -111,7 +111,7 @@ export default {
},
getFullDestinationUrl(params) {
- return joinPaths(gon.relative_url_root || '', this.getDestinationUrl(params));
+ return joinPaths(gon.relative_url_root || '', '/', this.getDestinationUrl(params));
},
},
@@ -161,7 +161,7 @@ export default {
>
</template>
<template #row-details="{ item }">
- <pre>{{ item.failures }}</pre>
+ <pre><code>{{ item.failures }}</code></pre>
</template>
</gl-table>
<pagination-bar
diff --git a/app/assets/javascripts/pages/import/history/components/import_error_details.vue b/app/assets/javascripts/pages/import/history/components/import_error_details.vue
new file mode 100644
index 00000000000..33ba73317f8
--- /dev/null
+++ b/app/assets/javascripts/pages/import/history/components/import_error_details.vue
@@ -0,0 +1,43 @@
+<script>
+import { GlLoadingIcon } from '@gitlab/ui';
+import API from '~/api';
+import { createAlert } from '~/flash';
+import { DEFAULT_ERROR } from '../utils/error_messages';
+
+export default {
+ components: {
+ GlLoadingIcon,
+ },
+ props: {
+ id: {
+ type: Number,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ loading: true,
+ error: null,
+ };
+ },
+ async mounted() {
+ try {
+ const {
+ data: { import_error: importError },
+ } = await API.project(this.id);
+ this.error = importError;
+ } catch (e) {
+ createAlert({ message: DEFAULT_ERROR });
+ this.error = null;
+ } finally {
+ this.loading = false;
+ }
+ },
+};
+</script>
+<template>
+ <gl-loading-icon v-if="loading" size="md" />
+ <pre
+ v-else
+ ><code>{{ error || s__('BulkImport|No additional information provided.') }}</code></pre>
+</template>
diff --git a/app/assets/javascripts/pages/import/history/components/import_history_app.vue b/app/assets/javascripts/pages/import/history/components/import_history_app.vue
new file mode 100644
index 00000000000..557e25f66e2
--- /dev/null
+++ b/app/assets/javascripts/pages/import/history/components/import_history_app.vue
@@ -0,0 +1,199 @@
+<script>
+import { GlButton, GlEmptyState, GlIcon, GlLink, GlLoadingIcon, GlTable } from '@gitlab/ui';
+import { s__, __ } from '~/locale';
+import createFlash from '~/flash';
+import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
+import { getProjects } from '~/rest_api';
+import ImportStatus from '~/import_entities/components/import_status.vue';
+import PaginationBar from '~/vue_shared/components/pagination_bar/pagination_bar.vue';
+import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
+import { DEFAULT_ERROR } from '../utils/error_messages';
+import ImportErrorDetails from './import_error_details.vue';
+
+const DEFAULT_PER_PAGE = 20;
+const DEFAULT_TH_CLASSES =
+ 'gl-bg-transparent! gl-border-b-solid! gl-border-b-gray-200! gl-border-b-1! gl-p-5!';
+
+const tableCell = (config) => ({
+ thClass: DEFAULT_TH_CLASSES,
+ tdClass: (value, key, item) => {
+ return {
+ // eslint-disable-next-line no-underscore-dangle
+ 'gl-border-b-0!': item._showDetails,
+ };
+ },
+ ...config,
+});
+
+export default {
+ components: {
+ GlButton,
+ GlEmptyState,
+ GlIcon,
+ GlLink,
+ GlLoadingIcon,
+ GlTable,
+ PaginationBar,
+ ImportStatus,
+ ImportErrorDetails,
+ TimeAgo,
+ },
+
+ inject: ['assets'],
+
+ data() {
+ return {
+ loading: true,
+ historyItems: [],
+ paginationConfig: {
+ page: 1,
+ perPage: DEFAULT_PER_PAGE,
+ },
+ pageInfo: {},
+ };
+ },
+
+ fields: [
+ tableCell({
+ key: 'source',
+ label: s__('BulkImport|Source'),
+ thClass: `${DEFAULT_TH_CLASSES} gl-w-30p`,
+ }),
+ tableCell({
+ key: 'destination',
+ label: s__('BulkImport|Destination'),
+ thClass: `${DEFAULT_TH_CLASSES} gl-w-40p`,
+ }),
+ tableCell({
+ key: 'created_at',
+ label: __('Date'),
+ }),
+ tableCell({
+ key: 'status',
+ label: __('Status'),
+ tdAttr: { 'data-qa-selector': 'import_status_indicator' },
+ }),
+ ],
+
+ computed: {
+ hasHistoryItems() {
+ return this.historyItems.length > 0;
+ },
+ },
+
+ watch: {
+ paginationConfig: {
+ handler() {
+ this.loadHistoryItems();
+ },
+ deep: true,
+ immediate: true,
+ },
+ },
+
+ methods: {
+ async loadHistoryItems() {
+ try {
+ this.loading = true;
+ const { data: historyItems, headers } = await getProjects(undefined, {
+ imported: true,
+ simple: false,
+ page: this.paginationConfig.page,
+ per_page: this.paginationConfig.perPage,
+ });
+ this.pageInfo = parseIntPagination(normalizeHeaders(headers));
+ this.historyItems = historyItems;
+ } catch (e) {
+ createFlash({ message: DEFAULT_ERROR, captureError: true, error: e });
+ } finally {
+ this.loading = false;
+ }
+ },
+
+ hasHttpProtocol(url) {
+ try {
+ const parsedUrl = new URL(url);
+ return ['http:', 'https:'].includes(parsedUrl.protocol);
+ } catch (e) {
+ return false;
+ }
+ },
+
+ setPageSize(size) {
+ this.paginationConfig.perPage = size;
+ this.paginationConfig.page = 1;
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <div
+ class="gl-border-solid gl-border-gray-200 gl-border-0 gl-border-b-1 gl-display-flex gl-align-items-center"
+ >
+ <h1 class="gl-my-0 gl-py-4 gl-font-size-h1">
+ <img :src="assets.gitlabLogo" class="gl-w-6 gl-h-6 gl-mb-2 gl-display-inline gl-mr-2" />
+ {{ s__('BulkImport|Project import history') }}
+ </h1>
+ </div>
+ <gl-loading-icon v-if="loading" size="md" class="gl-mt-5" />
+ <gl-empty-state
+ v-else-if="!hasHistoryItems"
+ :title="s__('BulkImport|No history is available')"
+ :description="s__('BulkImport|Your imported projects will appear here.')"
+ />
+ <template v-else>
+ <gl-table
+ :fields="$options.fields"
+ :items="historyItems"
+ data-qa-selector="import_history_table"
+ class="gl-w-full"
+ >
+ <template #cell(source)="{ item }">
+ <template v-if="item.import_url">
+ <gl-link
+ v-if="hasHttpProtocol(item.import_url)"
+ :href="item.import_url"
+ target="_blank"
+ >
+ {{ item.import_url }}
+ <gl-icon name="external-link" class="gl-vertical-align-middle" />
+ </gl-link>
+ <span v-else>{{ item.import_url }}</span>
+ </template>
+ <span v-else>{{
+ s__('BulkImport|Template / File-based import / GitLab Migration')
+ }}</span>
+ </template>
+ <template #cell(destination)="{ item }">
+ <gl-link :href="item.http_url_to_repo">
+ {{ item.path_with_namespace }}
+ </gl-link>
+ </template>
+ <template #cell(created_at)="{ value }">
+ <time-ago :time="value" />
+ </template>
+ <template #cell(status)="{ item, toggleDetails, detailsShowing }">
+ <import-status :status="item.import_status" class="gl-display-inline-block gl-w-13" />
+ <gl-button
+ v-if="item.import_status === 'failed'"
+ class="gl-ml-3"
+ :selected="detailsShowing"
+ @click="toggleDetails"
+ >{{ __('Details') }}</gl-button
+ >
+ </template>
+ <template #row-details="{ item }">
+ <import-error-details :id="item.id" />
+ </template>
+ </gl-table>
+ <pagination-bar
+ :page-info="pageInfo"
+ class="gl-m-0 gl-mt-3"
+ @set-page="paginationConfig.page = $event"
+ @set-page-size="setPageSize"
+ />
+ </template>
+ </div>
+</template>
diff --git a/app/assets/javascripts/pages/import/history/index.js b/app/assets/javascripts/pages/import/history/index.js
new file mode 100644
index 00000000000..d540272c266
--- /dev/null
+++ b/app/assets/javascripts/pages/import/history/index.js
@@ -0,0 +1,21 @@
+import Vue from 'vue';
+import ImportHistoryApp from './components/import_history_app.vue';
+
+function mountImportHistoryApp(mountElement) {
+ if (!mountElement) return undefined;
+
+ return new Vue({
+ el: mountElement,
+ name: 'ImportHistoryRoot',
+ provide: {
+ assets: {
+ gitlabLogo: mountElement.dataset.logo,
+ },
+ },
+ render(createElement) {
+ return createElement(ImportHistoryApp);
+ },
+ });
+}
+
+mountImportHistoryApp(document.querySelector('#import-history-mount-element'));
diff --git a/app/assets/javascripts/pages/import/history/utils/error_messages.js b/app/assets/javascripts/pages/import/history/utils/error_messages.js
new file mode 100644
index 00000000000..24669e22ade
--- /dev/null
+++ b/app/assets/javascripts/pages/import/history/utils/error_messages.js
@@ -0,0 +1,3 @@
+import { __ } from '~/locale';
+
+export const DEFAULT_ERROR = __('Something went wrong on our end.');
diff --git a/app/assets/javascripts/pages/profiles/preferences/show/index.js b/app/assets/javascripts/pages/profiles/preferences/show/index.js
index d489ed80f46..76939434680 100644
--- a/app/assets/javascripts/pages/profiles/preferences/show/index.js
+++ b/app/assets/javascripts/pages/profiles/preferences/show/index.js
@@ -1,3 +1,5 @@
import initProfilePreferences from '~/profile/preferences/profile_preferences_bundle';
+import initProfilePreferencesDiffsColors from '~/profile/preferences/profile_preferences_diffs_colors';
-document.addEventListener('DOMContentLoaded', initProfilePreferences);
+initProfilePreferences();
+initProfilePreferencesDiffsColors();
diff --git a/app/assets/javascripts/pages/projects/commit/show/index.js b/app/assets/javascripts/pages/projects/commit/show/index.js
index c6a76df7bde..eca3cf7ab13 100644
--- a/app/assets/javascripts/pages/projects/commit/show/index.js
+++ b/app/assets/javascripts/pages/projects/commit/show/index.js
@@ -1,5 +1,6 @@
/* eslint-disable no-new */
import $ from 'jquery';
+import Vue from 'vue';
import loadAwardsHandler from '~/awards_handler';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import Diff from '~/diff';
@@ -14,6 +15,7 @@ import { initCommitBoxInfo } from '~/projects/commit_box/info';
import syntaxHighlight from '~/syntax_highlight';
import ZenMode from '~/zen_mode';
import '~/sourcegraph/load';
+import DiffStats from '~/diffs/components/diff_stats.vue';
const hasPerfBar = document.querySelector('.with-performance-bar');
const performanceHeight = hasPerfBar ? 35 : 0;
@@ -25,6 +27,33 @@ initCommitBoxInfo();
initDeprecatedNotes();
+const loadDiffStats = () => {
+ const diffStatsElements = document.querySelectorAll('#js-diff-stats');
+
+ if (diffStatsElements.length) {
+ diffStatsElements.forEach((diffStatsEl) => {
+ const { addedLines, removedLines, oldSize, newSize, viewerName } = diffStatsEl.dataset;
+
+ new Vue({
+ el: diffStatsEl,
+ render(createElement) {
+ return createElement(DiffStats, {
+ props: {
+ diffFile: {
+ old_size: oldSize,
+ new_size: newSize,
+ viewer: { name: viewerName },
+ },
+ addedLines: Number(addedLines),
+ removedLines: Number(removedLines),
+ },
+ });
+ },
+ });
+ });
+ }
+};
+
const filesContainer = $('.js-diffs-batch');
if (filesContainer.length) {
@@ -37,12 +66,15 @@ if (filesContainer.length) {
syntaxHighlight(filesContainer);
handleLocationHash();
new Diff();
+ loadDiffStats();
})
.catch(() => {
createFlash({ message: __('An error occurred while retrieving diff files') });
});
} else {
new Diff();
+ loadDiffStats();
}
+
loadAwardsHandler();
initCommitActions();
diff --git a/app/assets/javascripts/pages/projects/harbor/repositories/index.js b/app/assets/javascripts/pages/projects/harbor/repositories/index.js
new file mode 100644
index 00000000000..efbe24ac346
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/harbor/repositories/index.js
@@ -0,0 +1,8 @@
+import HarborRegistryExplorer from '~/packages_and_registries/harbor_registry/index';
+
+const explorer = HarborRegistryExplorer('js-harbor-registry-list-project');
+
+if (explorer) {
+ explorer.attachBreadcrumb();
+ explorer.attachMainComponent();
+}
diff --git a/app/assets/javascripts/pages/projects/index.js b/app/assets/javascripts/pages/projects/index.js
index 8ec6e5e66b3..7380055cbbf 100644
--- a/app/assets/javascripts/pages/projects/index.js
+++ b/app/assets/javascripts/pages/projects/index.js
@@ -1,5 +1,5 @@
-import ShortcutsNavigation from '../../behaviors/shortcuts/shortcuts_navigation';
-import initTerraformNotification from '../../projects/terraform_notification';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
+import initTerraformNotification from '~/projects/terraform_notification';
import { initSidebarTracking } from '../shared/nav/sidebar_tracking';
import Project from './project';
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue
index 67962d69fa5..db9ef4df8af 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue
@@ -127,8 +127,12 @@ export default {
</p>
<gl-progress-bar :value="progressValue" :max="$options.maxValue" />
</div>
- <div class="row row-cols-1 row-cols-md-3 gl-mt-5">
- <div v-for="section in $options.actionSections" :key="section" class="col gl-mb-6">
+ <div class="row">
+ <div
+ v-for="section in $options.actionSections"
+ :key="section"
+ class="gl-mt-5 col-sm-12 col-mb-6 col-lg-4"
+ >
<learn-gitlab-section-card
:section="section"
:svg="svgFor(section)"
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_card.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_card.vue
index 6a196687a76..e8f0e6c47ee 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_card.vue
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_card.vue
@@ -34,17 +34,23 @@ export default {
};
</script>
<template>
- <gl-card class="gl-pt-0 learn-gitlab-section-card">
- <div class="learn-gitlab-section-card-header">
+ <gl-card
+ class="gl-pt-0 h-100"
+ header-class="gl-bg-white gl-border-0 gl-pb-0"
+ body-class="gl-pt-0"
+ >
+ <template #header>
<img :src="svg" />
<h2 class="gl-font-lg gl-mb-3">{{ $options.i18n[section].title }}</h2>
<p class="gl-text-gray-700 gl-mb-6">{{ $options.i18n[section].description }}</p>
- </div>
- <learn-gitlab-section-link
- v-for="[action, value] in sortedActions"
- :key="action"
- :action="action"
- :value="value"
- />
+ </template>
+ <template #default>
+ <learn-gitlab-section-link
+ v-for="[action, value] in sortedActions"
+ :key="action"
+ :action="action"
+ :value="value"
+ />
+ </template>
</gl-card>
</template>
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue
index 573f996a254..1667f2c3576 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue
@@ -1,16 +1,25 @@
<script>
-import { GlLink, GlIcon } from '@gitlab/ui';
+import { GlLink, GlIcon, GlButton, GlTooltipDirective as GlTooltip } from '@gitlab/ui';
+import GitlabExperiment from '~/experimentation/components/gitlab_experiment.vue';
import { isExperimentVariant } from '~/experimentation/utils';
import eventHub from '~/invite_members/event_hub';
-import { s__ } from '~/locale';
+import { s__, __ } from '~/locale';
import { ACTION_LABELS } from '../constants';
export default {
name: 'LearnGitlabSectionLink',
- components: { GlLink, GlIcon },
+ components: {
+ GlLink,
+ GlIcon,
+ GlButton,
+ GitlabExperiment,
+ },
+ directives: {
+ GlTooltip,
+ },
i18n: {
- ACTION_LABELS,
trialOnly: s__('LearnGitlab|Trial only'),
+ watchHow: __('Watch how'),
},
props: {
action: {
@@ -23,6 +32,9 @@ export default {
},
},
computed: {
+ linkTitle() {
+ return ACTION_LABELS[this.action].title;
+ },
trialOnly() {
return ACTION_LABELS[this.action].trialRequired;
},
@@ -34,6 +46,9 @@ export default {
openInNewTab() {
return ACTION_LABELS[this.action]?.openInNewTab === true || this.value.openInNewTab === true;
},
+ linkToVideoTutorial() {
+ return ACTION_LABELS[this.action].videoTutorial;
+ },
},
methods: {
openModal() {
@@ -44,32 +59,55 @@ export default {
</script>
<template>
<div class="gl-mb-4">
- <span v-if="value.completed" class="gl-text-green-500">
- <gl-icon name="check-circle-filled" :size="16" data-testid="completed-icon" />
- {{ $options.i18n.ACTION_LABELS[action].title }}
- </span>
- <gl-link
- v-else-if="showInviteModalLink"
- data-track-action="click_link"
- :data-track-label="$options.i18n.ACTION_LABELS[action].title"
- data-track-property="Growth::Activation::Experiment::InviteForHelpContinuousOnboarding"
- data-testid="invite-for-help-continuous-onboarding-experiment-link"
- @click="openModal"
- >
- {{ $options.i18n.ACTION_LABELS[action].title }}
- </gl-link>
- <gl-link
- v-else
- :target="openInNewTab ? '_blank' : '_self'"
- :href="value.url"
- data-testid="uncompleted-learn-gitlab-link"
- data-track-action="click_link"
- :data-track-label="$options.i18n.ACTION_LABELS[action].title"
- >
- {{ $options.i18n.ACTION_LABELS[action].title }}
- </gl-link>
- <span v-if="trialOnly" class="gl-font-style-italic gl-text-gray-500" data-testid="trial-only">
- - {{ $options.i18n.trialOnly }}
- </span>
+ <div v-if="trialOnly" class="gl-font-style-italic gl-text-gray-500" data-testid="trial-only">
+ {{ $options.i18n.trialOnly }}
+ </div>
+ <div class="flex align-items-center">
+ <span v-if="value.completed" class="gl-text-green-500">
+ <gl-icon name="check-circle-filled" :size="16" data-testid="completed-icon" />
+ {{ linkTitle }}
+ </span>
+ <gl-link
+ v-else-if="showInviteModalLink"
+ data-track-action="click_link"
+ :data-track-label="linkTitle"
+ data-track-property="Growth::Activation::Experiment::InviteForHelpContinuousOnboarding"
+ data-testid="invite-for-help-continuous-onboarding-experiment-link"
+ @click="openModal"
+ >
+ {{ linkTitle }}
+ </gl-link>
+ <gl-link
+ v-else
+ :target="openInNewTab ? '_blank' : '_self'"
+ :href="value.url"
+ data-testid="uncompleted-learn-gitlab-link"
+ data-track-action="click_link"
+ :data-track-label="linkTitle"
+ >
+ {{ linkTitle }}
+ </gl-link>
+ <gitlab-experiment name="video_tutorials_continuous_onboarding">
+ <template #control></template>
+ <template #candidate>
+ <gl-button
+ v-if="linkToVideoTutorial"
+ v-gl-tooltip
+ category="tertiary"
+ icon="live-preview"
+ :title="$options.i18n.watchHow"
+ :aria-label="$options.i18n.watchHow"
+ :href="linkToVideoTutorial"
+ target="_blank"
+ class="ml-auto"
+ data-testid="video-tutorial-link"
+ data-track-action="click_video_link"
+ :data-track-label="linkTitle"
+ data-track-property="Growth::Conversion::Experiment::LearnGitLab"
+ data-track-experiment="video_tutorials_continuous_onboarding"
+ />
+ </template>
+ </gitlab-experiment>
+ </div>
</div>
</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 1887c48dd1b..9ba5e17237a 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js
@@ -40,6 +40,7 @@ export const ACTION_LABELS = {
trialRequired: true,
section: 'workspace',
position: 4,
+ videoTutorial: 'https://vimeo.com/670896787',
},
requiredMrApprovalsEnabled: {
title: s__('LearnGitLab|Add merge request approval'),
@@ -48,6 +49,7 @@ export const ACTION_LABELS = {
trialRequired: true,
section: 'workspace',
position: 5,
+ videoTutorial: 'https://vimeo.com/670904904',
},
mergeRequestCreated: {
title: s__('LearnGitLab|Submit a merge request'),
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js b/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js
index 63357ea9c72..af4a6f8a0c9 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js
@@ -1,5 +1,6 @@
import Vue from 'vue';
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
+import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import LearnGitlab from '../components/learn_gitlab.vue';
@@ -24,5 +25,7 @@ function initLearnGitlab() {
});
}
-initLearnGitlab();
initInviteMembersModal();
+initInviteMembersTrigger();
+
+initLearnGitlab();
diff --git a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
index c548ea9bb80..0e0c1475eda 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
@@ -1,6 +1,5 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
-import loadAwardsHandler from '~/awards_handler';
import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable';
import { initPipelineCountListener } from '~/commit/pipelines/utils';
import { initIssuableSidebar } from '~/issuable';
@@ -8,23 +7,16 @@ import StatusBox from '~/issuable/components/status_box.vue';
import createDefaultClient from '~/lib/graphql';
import initSourcegraph from '~/sourcegraph';
import ZenMode from '~/zen_mode';
+import initAwardsApp from '~/emoji/awards_app';
import getStateQuery from './queries/get_state.query.graphql';
export default function initMergeRequestShow() {
- const awardEmojiEl = document.getElementById('js-vue-awards-block');
-
new ZenMode(); // eslint-disable-line no-new
initPipelineCountListener(document.querySelector('#commit-pipeline-table-view'));
new ShortcutsIssuable(true); // eslint-disable-line no-new
initSourcegraph();
initIssuableSidebar();
- if (awardEmojiEl) {
- import('~/emoji/awards_app')
- .then((m) => m.default(awardEmojiEl))
- .catch(() => {});
- } else {
- loadAwardsHandler();
- }
+ initAwardsApp(document.getElementById('js-vue-awards-block'));
const el = document.querySelector('.js-mr-status-box');
const apolloProvider = new VueApollo({
diff --git a/app/assets/javascripts/pages/projects/network/network.js b/app/assets/javascripts/pages/projects/network/network.js
index 5f2014f1631..b88127384dc 100644
--- a/app/assets/javascripts/pages/projects/network/network.js
+++ b/app/assets/javascripts/pages/projects/network/network.js
@@ -1,5 +1,5 @@
import $ from 'jquery';
-import BranchGraph from '../../../network/branch_graph';
+import BranchGraph from '~/network/branch_graph';
const vph = $(window).height() - 250;
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue
index ee70ff858be..37e8a316ee4 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue
@@ -2,8 +2,7 @@
import { GlButton } from '@gitlab/ui';
import Vue from 'vue';
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
-
-import Translate from '../../../../../vue_shared/translate';
+import Translate from '~/vue_shared/translate';
Vue.use(Translate);
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js
index 9c039a6be81..5dae812bbcb 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js
@@ -3,9 +3,9 @@ import Vue from 'vue';
import { __ } from '~/locale';
import RefSelector from '~/ref/components/ref_selector.vue';
import { REF_TYPE_BRANCHES, REF_TYPE_TAGS } from '~/ref/constants';
-import setupNativeFormVariableList from '../../../../ci_variable_list/native_form_variable_list';
-import GlFieldErrors from '../../../../gl_field_errors';
-import Translate from '../../../../vue_shared/translate';
+import setupNativeFormVariableList from '~/ci_variable_list/native_form_variable_list';
+import GlFieldErrors from '~/gl_field_errors';
+import Translate from '~/vue_shared/translate';
import intervalPatternInput from './components/interval_pattern_input.vue';
import TimezoneDropdown from './components/timezone_dropdown';
@@ -33,13 +33,7 @@ function initIntervalPatternInput() {
}
function getEnabledRefTypes() {
- const refTypes = [REF_TYPE_BRANCHES];
-
- if (gon.features.pipelineSchedulesWithTags) {
- refTypes.push(REF_TYPE_TAGS);
- }
-
- return refTypes;
+ return [REF_TYPE_BRANCHES, REF_TYPE_TAGS];
}
function initTargetRefDropdown() {
@@ -61,9 +55,7 @@ function initTargetRefDropdown() {
value: $refField.value,
useSymbolicRefNames: true,
translations: {
- dropdownHeader: gon.features.pipelineSchedulesWithTags
- ? __('Select target branch or tag')
- : __('Select target branch'),
+ dropdownHeader: __('Select target branch or tag'),
},
},
class: 'gl-w-full',
diff --git a/app/assets/javascripts/pages/projects/project.js b/app/assets/javascripts/pages/projects/project.js
index 0c17bf2f344..4f57e1308df 100644
--- a/app/assets/javascripts/pages/projects/project.js
+++ b/app/assets/javascripts/pages/projects/project.js
@@ -9,7 +9,7 @@ import axios from '~/lib/utils/axios_utils';
import { serializeForm } from '~/lib/utils/forms';
import { mergeUrlParams } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
-import projectSelect from '../../project_select';
+import projectSelect from '~/project_select';
export default class Project {
constructor() {
diff --git a/app/assets/javascripts/pages/projects/project_members/index.js b/app/assets/javascripts/pages/projects/project_members/index.js
index 2c0394dc12c..bf4fb5f3b7e 100644
--- a/app/assets/javascripts/pages/projects/project_members/index.js
+++ b/app/assets/javascripts/pages/projects/project_members/index.js
@@ -18,9 +18,16 @@ initInviteGroupTrigger();
const SHARED_FIELDS = ['account', 'maxRole', 'expiration', 'actions'];
initMembersApp(document.querySelector('.js-project-members-list-app'), {
[MEMBER_TYPES.user]: {
- tableFields: SHARED_FIELDS.concat(['source', 'granted']),
+ tableFields: SHARED_FIELDS.concat(['source', 'granted', 'userCreatedAt', 'lastActivityOn']),
tableAttrs: { tr: { 'data-qa-selector': 'member_row' } },
- tableSortableFields: ['account', 'granted', 'maxRole', 'lastSignIn'],
+ tableSortableFields: [
+ 'account',
+ 'granted',
+ 'maxRole',
+ 'lastSignIn',
+ 'userCreatedAt',
+ 'lastActivityOn',
+ ],
requestFormatter: projectMemberRequestFormatter,
filteredSearchBar: {
show: true,
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 e88dbf20e1b..43ab829f5f9 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
@@ -10,36 +10,34 @@ import initSharedRunnersToggle from '~/projects/settings/mount_shared_runners_to
import initSettingsPanels from '~/settings_panels';
import { initTokenAccess } from '~/token_access';
-document.addEventListener('DOMContentLoaded', () => {
- // Initialize expandable settings panels
- initSettingsPanels();
+// Initialize expandable settings panels
+initSettingsPanels();
- const runnerToken = document.querySelector('.js-secret-runner-token');
- if (runnerToken) {
- const runnerTokenSecretValue = new SecretValues({
- container: runnerToken,
- });
- runnerTokenSecretValue.init();
- }
-
- initVariableList();
-
- // hide extra auto devops settings based checkbox state
- const autoDevOpsExtraSettings = document.querySelector('.js-extra-settings');
- const instanceDefaultBadge = document.querySelector('.js-instance-default-badge');
- document.querySelector('.js-toggle-extra-settings').addEventListener('click', (event) => {
- const { target } = event;
- if (instanceDefaultBadge) instanceDefaultBadge.style.display = 'none';
- autoDevOpsExtraSettings.classList.toggle('hidden', !target.checked);
+const runnerToken = document.querySelector('.js-secret-runner-token');
+if (runnerToken) {
+ const runnerTokenSecretValue = new SecretValues({
+ container: runnerToken,
});
+ runnerTokenSecretValue.init();
+}
- registrySettingsApp();
- initDeployFreeze();
+initVariableList();
- initSettingsPipelinesTriggers();
- initArtifactsSettings();
- initSharedRunnersToggle();
- initInstallRunner();
- initRunnerAwsDeployments();
- initTokenAccess();
+// hide extra auto devops settings based checkbox state
+const autoDevOpsExtraSettings = document.querySelector('.js-extra-settings');
+const instanceDefaultBadge = document.querySelector('.js-instance-default-badge');
+document.querySelector('.js-toggle-extra-settings').addEventListener('click', (event) => {
+ const { target } = event;
+ if (instanceDefaultBadge) instanceDefaultBadge.style.display = 'none';
+ autoDevOpsExtraSettings.classList.toggle('hidden', !target.checked);
});
+
+registrySettingsApp();
+initDeployFreeze();
+
+initSettingsPipelinesTriggers();
+initArtifactsSettings();
+initSharedRunnersToggle();
+initInstallRunner();
+initRunnerAwsDeployments();
+initTokenAccess();
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..d45052d76f4 100644
--- a/app/assets/javascripts/pages/projects/settings/repository/show/index.js
+++ b/app/assets/javascripts/pages/projects/settings/repository/show/index.js
@@ -1,9 +1,7 @@
import MirrorRepos from '~/mirrors/mirror_repos';
import initForm from '../form';
-document.addEventListener('DOMContentLoaded', () => {
- initForm();
+initForm();
- const mirrorReposContainer = document.querySelector('.js-mirror-settings');
- if (mirrorReposContainer) new MirrorRepos(mirrorReposContainer).init();
-});
+const mirrorReposContainer = document.querySelector('.js-mirror-settings');
+if (mirrorReposContainer) new MirrorRepos(mirrorReposContainer).init();
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/project_feature_setting.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/project_feature_setting.vue
index 9fb8be3fdb9..b2d32c2c943 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/components/project_feature_setting.vue
+++ b/app/assets/javascripts/pages/projects/shared/permissions/components/project_feature_setting.vue
@@ -44,6 +44,15 @@ export default {
},
},
computed: {
+ internalValue: {
+ get() {
+ return this.value;
+ },
+ set(value) {
+ this.$emit('change', value);
+ },
+ },
+
featureEnabled() {
return this.value !== 0;
},
@@ -68,10 +77,6 @@ export default {
this.$emit('change', firstOptionValue);
}
},
-
- selectOption(e) {
- this.$emit('change', Number(e.target.value));
- },
},
};
</script>
@@ -93,15 +98,14 @@ export default {
/>
<div class="select-wrapper gl-flex-grow-1">
<select
+ v-model="internalValue"
:disabled="displaySelectInput"
class="form-control project-repo-select select-control"
- @change="selectOption"
>
<option
v-for="[optionValue, optionName] in displayOptions"
:key="optionValue"
:value="optionValue"
- :selected="optionValue === value"
>
{{ optionName }}
</option>
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 184bda4410f..03bab0fa773 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
@@ -9,7 +9,6 @@ import {
featureAccessLevelMembers,
featureAccessLevelEveryone,
featureAccessLevel,
- featureAccessLevelNone,
CVE_ID_REQUEST_BUTTON_I18N,
featureAccessLevelDescriptions,
} from '../constants';
@@ -225,8 +224,6 @@ export default {
},
operationsFeatureAccessLevelOptions() {
- if (!this.operationsEnabled) return [featureAccessLevelNone];
-
return this.featureAccessLevelOptions.filter(
([value]) => value <= this.operationsAccessLevel,
);
@@ -251,10 +248,6 @@ export default {
return options;
},
- metricsOptionsDropdownDisabled() {
- return this.operationsFeatureAccessLevelOptions.length < 2 || !this.operationsEnabled;
- },
-
operationsEnabled() {
return this.operationsAccessLevel > featureAccessLevel.NOT_ENABLED;
},
@@ -392,6 +385,15 @@ export default {
else if (oldValue === featureAccessLevel.NOT_ENABLED)
toggleHiddenClassBySelector('.merge-requests-feature', false);
},
+
+ operationsAccessLevel(value, oldValue) {
+ if (value < oldValue) {
+ // sub-features cannot have more permissive access level
+ this.metricsDashboardAccessLevel = Math.min(this.metricsDashboardAccessLevel, value);
+ } else if (oldValue === 0) {
+ this.metricsDashboardAccessLevel = value;
+ }
+ },
},
methods: {
@@ -590,7 +592,9 @@ export default {
:help-path="packagesHelpPath"
:label="$options.i18n.packagesLabel"
:help-text="
- s__('ProjectSettings|Every project can have its own space to store its packages.')
+ s__(
+ 'ProjectSettings|Every project can have its own space to store its packages. Note: The Package Registry is always visible when a project is public.',
+ )
"
>
<gl-toggle
diff --git a/app/assets/javascripts/pages/projects/snippets/show/index.js b/app/assets/javascripts/pages/projects/snippets/show/index.js
index c719601ee0b..77baa6d77a5 100644
--- a/app/assets/javascripts/pages/projects/snippets/show/index.js
+++ b/app/assets/javascripts/pages/projects/snippets/show/index.js
@@ -1,9 +1,4 @@
import '~/snippet/snippet_show';
+import initAwardsApp from '~/emoji/awards_app';
-const awardEmojiEl = document.getElementById('js-vue-awards-block');
-
-if (awardEmojiEl) {
- import('~/emoji/awards_app')
- .then((m) => m.default(awardEmojiEl))
- .catch(() => {});
-}
+initAwardsApp(document.getElementById('js-vue-awards-block'));
diff --git a/app/assets/javascripts/pages/projects/tags/new/index.js b/app/assets/javascripts/pages/projects/tags/new/index.js
index b071e7a45fc..9ef1017f9f2 100644
--- a/app/assets/javascripts/pages/projects/tags/new/index.js
+++ b/app/assets/javascripts/pages/projects/tags/new/index.js
@@ -1,7 +1,7 @@
import $ from 'jquery';
-import GLForm from '../../../../gl_form';
-import RefSelectDropdown from '../../../../ref_select_dropdown';
-import ZenMode from '../../../../zen_mode';
+import GLForm from '~/gl_form';
+import RefSelectDropdown from '~/ref_select_dropdown';
+import ZenMode from '~/zen_mode';
new ZenMode(); // eslint-disable-line no-new
new GLForm($('.tag-form')); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/projects/tree/show/index.js b/app/assets/javascripts/pages/projects/tree/show/index.js
index 4bb461aadad..cf7162f477d 100644
--- a/app/assets/javascripts/pages/projects/tree/show/index.js
+++ b/app/assets/javascripts/pages/projects/tree/show/index.js
@@ -1,8 +1,8 @@
import $ from 'jquery';
import initTree from 'ee_else_ce/repository';
import initBlob from '~/blob_edit/blob_bundle';
-import ShortcutsNavigation from '../../../../behaviors/shortcuts/shortcuts_navigation';
-import NewCommitForm from '../../../../new_commit_form';
+import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
+import NewCommitForm from '~/new_commit_form';
new NewCommitForm($('.js-create-dir-form')); // eslint-disable-line no-new
initBlob();
diff --git a/app/assets/javascripts/pages/projects/wikis/show/index.js b/app/assets/javascripts/pages/projects/wikis/show/index.js
index c08a10122b6..7ca5f6964cd 100644
--- a/app/assets/javascripts/pages/projects/wikis/show/index.js
+++ b/app/assets/javascripts/pages/projects/wikis/show/index.js
@@ -1,3 +1,5 @@
+import { mountApplications } from '~/pages/shared/wikis/show';
import { mountApplications as mountEditApplications } from '~/pages/shared/wikis/async_edit';
+mountApplications();
mountEditApplications();
diff --git a/app/assets/javascripts/pages/sessions/new/index.js b/app/assets/javascripts/pages/sessions/new/index.js
index 8c2fd624a83..b62417cf595 100644
--- a/app/assets/javascripts/pages/sessions/new/index.js
+++ b/app/assets/javascripts/pages/sessions/new/index.js
@@ -1,6 +1,6 @@
import $ from 'jquery';
import initVueAlerts from '~/vue_alerts';
-import NoEmojiValidator from '../../../emoji/no_emoji_validator';
+import NoEmojiValidator from '~/emoji/no_emoji_validator';
import LengthValidator from './length_validator';
import OAuthRememberMe from './oauth_remember_me';
import preserveUrlFragment from './preserve_url_fragment';
diff --git a/app/assets/javascripts/pages/sessions/new/length_validator.js b/app/assets/javascripts/pages/sessions/new/length_validator.js
index 17acad10bc1..b2074fb1e39 100644
--- a/app/assets/javascripts/pages/sessions/new/length_validator.js
+++ b/app/assets/javascripts/pages/sessions/new/length_validator.js
@@ -1,4 +1,4 @@
-import InputValidator from '../../../validators/input_validator';
+import InputValidator from '~/validators/input_validator';
const errorMessageClass = 'gl-field-error';
diff --git a/app/assets/javascripts/pages/shared/wikis/components/wiki_content.vue b/app/assets/javascripts/pages/shared/wikis/components/wiki_content.vue
new file mode 100644
index 00000000000..7c23f60954a
--- /dev/null
+++ b/app/assets/javascripts/pages/shared/wikis/components/wiki_content.vue
@@ -0,0 +1,92 @@
+<script>
+import { GlSkeletonLoader, GlSafeHtmlDirective, GlAlert } from '@gitlab/ui';
+import createFlash from '~/flash';
+import { __ } from '~/locale';
+import axios from '~/lib/utils/axios_utils';
+import { renderGFM } from '../render_gfm_facade';
+
+export default {
+ components: {
+ GlSkeletonLoader,
+ GlAlert,
+ },
+ directives: {
+ SafeHtml: GlSafeHtmlDirective,
+ },
+ props: {
+ getWikiContentUrl: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ isLoadingContent: false,
+ loadingContentFailed: false,
+ content: null,
+ };
+ },
+ mounted() {
+ this.loadWikiContent();
+ },
+ methods: {
+ async loadWikiContent() {
+ this.loadingContentFailed = false;
+ this.isLoadingContent = true;
+
+ try {
+ const {
+ data: { content },
+ } = await axios.get(this.getWikiContentUrl, { params: { render_html: true } });
+ this.content = content;
+
+ this.$nextTick()
+ .then(() => {
+ renderGFM(this.$refs.content);
+ })
+ .catch(() =>
+ createFlash({
+ message: this.$options.i18n.renderingContentFailed,
+ }),
+ );
+ } catch (e) {
+ this.loadingContentFailed = true;
+ } finally {
+ this.isLoadingContent = false;
+ }
+ },
+ },
+ i18n: {
+ loadingContentFailed: __(
+ 'The content for this wiki page failed to load. To fix this error, reload the page.',
+ ),
+ retryLoadingContent: __('Retry'),
+ renderingContentFailed: __('The content for this wiki page failed to render.'),
+ },
+};
+</script>
+<template>
+ <gl-skeleton-loader v-if="isLoadingContent" :width="830" :height="113">
+ <rect width="540" height="16" rx="4" />
+ <rect y="49" width="701" height="16" rx="4" />
+ <rect y="24" width="830" height="16" rx="4" />
+ <rect y="73" width="540" height="16" rx="4" />
+ </gl-skeleton-loader>
+ <gl-alert
+ v-else-if="loadingContentFailed"
+ :dismissible="false"
+ variant="danger"
+ :primary-button-text="$options.i18n.retryLoadingContent"
+ @primaryAction="loadWikiContent"
+ >
+ {{ $options.i18n.loadingContentFailed }}
+ </gl-alert>
+ <div
+ v-else-if="!loadingContentFailed && !isLoadingContent"
+ ref="content"
+ data-qa-selector="wiki_page_content"
+ data-testid="wiki_page_content"
+ class="js-wiki-page-content md"
+ v-html="content /* eslint-disable-line vue/no-v-html */"
+ ></div>
+</template>
diff --git a/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue b/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
index 8ef31b9b983..024b3bc9595 100644
--- a/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
+++ b/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
@@ -1,21 +1,11 @@
<script>
-import {
- GlForm,
- GlIcon,
- GlLink,
- GlButton,
- GlSprintf,
- GlAlert,
- GlModal,
- GlModalDirective,
-} from '@gitlab/ui';
+import { GlForm, GlIcon, GlLink, GlButton, GlSprintf, GlAlert } from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils';
import csrf from '~/lib/utils/csrf';
import { setUrlFragment } from '~/lib/utils/url_utility';
-import { __, s__, sprintf } from '~/locale';
+import { s__, sprintf } from '~/locale';
import Tracking from '~/tracking';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import {
CONTENT_EDITOR_LOADED_ACTION,
SAVED_USING_CONTENT_EDITOR_ACTION,
@@ -64,31 +54,6 @@ export default {
),
primaryAction: s__('WikiPage|Retry'),
},
- useNewEditor: {
- primaryLabel: s__('WikiPage|Use the new editor'),
- secondaryLabel: s__('WikiPage|Try this later'),
- title: s__('WikiPage|Get a richer editing experience'),
- text: s__(
- "WikiPage|Try the new visual Markdown editor. Read the %{linkStart}documentation%{linkEnd} to learn what's currently supported.",
- ),
- },
- switchToOldEditor: {
- label: s__('WikiPage|Switch me back to the classic editor.'),
- helpText: s__(
- "WikiPage|This editor is in beta and may not display the page's contents properly. Switching back to the classic editor will discard changes you've made in the new editor.",
- ),
- modal: {
- title: s__('WikiPage|Are you sure you want to switch back to the classic editor?'),
- primary: s__('WikiPage|Switch to classic editor'),
- cancel: s__('WikiPage|Keep editing'),
- text: s__(
- "WikiPage|Switching to the classic editor will discard any changes you've made in the new editor.",
- ),
- },
- },
- feedbackTip: __(
- 'Tell us your experiences with the new Markdown editor %{linkStart}in this feedback issue%{linkEnd}.',
- ),
},
linksHelpText: s__(
'WikiPage|To link to a (new) page, simply type %{linkExample}. More examples are in the %{linkStart}documentation%{linkEnd}.',
@@ -108,7 +73,6 @@ export default {
editSourceButtonText: s__('WikiPage|Edit source'),
editRichTextButtonText: s__('WikiPage|Edit rich text'),
},
- contentEditorFeedbackIssue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/332629',
components: {
GlAlert,
GlForm,
@@ -116,24 +80,19 @@ export default {
GlIcon,
GlLink,
GlButton,
- GlModal,
MarkdownField,
ContentEditor: () =>
import(
/* webpackChunkName: 'content_editor' */ '~/content_editor/components/content_editor.vue'
),
},
- directives: {
- GlModalDirective,
- },
- mixins: [trackingMixin, glFeatureFlagMixin()],
+ mixins: [trackingMixin],
inject: ['formatOptions', 'pageInfo'],
data() {
return {
title: this.pageInfo.title?.trim() || '',
format: this.pageInfo.format || 'markdown',
content: this.pageInfo.content || '',
- isContentEditorAlertDismissed: false,
useContentEditor: false,
commitMessage: '',
isDirty: false,
@@ -194,25 +153,9 @@ export default {
isMarkdownFormat() {
return this.format === 'markdown';
},
- showContentEditorAlert() {
- return (
- !this.glFeatures.wikiSwitchBetweenContentEditorRawMarkdown &&
- this.isMarkdownFormat &&
- !this.useContentEditor &&
- !this.isContentEditorAlertDismissed
- );
- },
- showSwitchEditingModeButton() {
- return this.glFeatures.wikiSwitchBetweenContentEditorRawMarkdown && this.isMarkdownFormat;
- },
displayWikiSpecificMarkdownHelp() {
return !this.isContentEditorActive;
},
- displaySwitchBackToClassicEditorMessage() {
- return (
- !this.glFeatures.wikiSwitchBetweenContentEditorRawMarkdown && this.isContentEditorActive
- );
- },
disableSubmitButton() {
return this.noContent || !this.title || this.contentEditorRenderFailed;
},
@@ -312,23 +255,6 @@ export default {
this.commitMessage = newCommitMessage;
},
- initContentEditor() {
- this.useContentEditor = true;
- },
-
- switchToOldEditor() {
- this.useContentEditor = false;
- },
-
- confirmSwitchToOldEditor() {
- if (this.contentEditorRenderFailed) {
- this.contentEditorRenderFailed = false;
- this.switchToOldEditor();
- } else {
- this.$refs.confirmSwitchToOldEditorModal.show();
- }
- },
-
trackContentEditorLoaded() {
this.track(CONTENT_EDITOR_LOADED_ACTION);
},
@@ -349,10 +275,6 @@ export default {
},
});
},
-
- dismissContentEditorAlert() {
- this.isContentEditorAlertDismissed = true;
- },
},
};
</script>
@@ -438,10 +360,7 @@ export default {
}}</label>
</div>
<div class="col-sm-10">
- <div
- v-if="showSwitchEditingModeButton"
- class="gl-display-flex gl-justify-content-end gl-mb-3"
- >
+ <div v-if="isMarkdownFormat" class="gl-display-flex gl-justify-content-end gl-mb-3">
<gl-button
data-testid="toggle-editing-mode-button"
data-qa-selector="editing_mode_button"
@@ -451,42 +370,6 @@ export default {
>{{ toggleEditingModeButtonText }}</gl-button
>
</div>
- <gl-alert
- v-if="showContentEditorAlert"
- class="gl-mb-6"
- variant="info"
- data-qa-selector="try_new_editor_container"
- :primary-button-text="$options.i18n.contentEditor.useNewEditor.primaryLabel"
- :secondary-button-text="$options.i18n.contentEditor.useNewEditor.secondaryLabel"
- :dismiss-label="$options.i18n.contentEditor.useNewEditor.secondaryLabel"
- :title="$options.i18n.contentEditor.useNewEditor.title"
- @primaryAction="initContentEditor"
- @secondaryAction="dismissContentEditorAlert"
- @dismiss="dismissContentEditorAlert"
- >
- <gl-sprintf :message="$options.i18n.contentEditor.useNewEditor.text">
- <template
- #link="// eslint-disable-next-line vue/no-template-shadow
- { content }"
- ><gl-link
- :href="contentEditorHelpPath"
- target="_blank"
- data-testid="content-editor-help-link"
- >{{ content }}</gl-link
- ></template
- >
- </gl-sprintf>
- </gl-alert>
- <gl-modal
- ref="confirmSwitchToOldEditorModal"
- modal-id="confirm-switch-to-old-editor"
- :title="$options.i18n.contentEditor.switchToOldEditor.modal.title"
- :action-primary="{ text: $options.i18n.contentEditor.switchToOldEditor.modal.primary }"
- :action-cancel="{ text: $options.i18n.contentEditor.switchToOldEditor.modal.cancel }"
- @primary="switchToOldEditor"
- >
- {{ $options.i18n.contentEditor.switchToOldEditor.modal.text }}
- </gl-modal>
<markdown-field
v-if="!isContentEditorActive"
:markdown-preview-path="pageInfo.markdownPreviewPath"
@@ -516,22 +399,7 @@ export default {
</textarea>
</template>
</markdown-field>
-
<div v-if="isContentEditorActive">
- <gl-alert class="gl-mb-6" variant="tip" :dismissible="false">
- <gl-sprintf :message="$options.i18n.contentEditor.feedbackTip">
- <template
- #link="// eslint-disable-next-line vue/no-template-shadow
- { content }"
- ><gl-link
- :href="$options.contentEditorFeedbackIssue"
- target="_blank"
- data-testid="wiki-markdown-help-link"
- >{{ content }}</gl-link
- ></template
- >
- </gl-sprintf>
- </gl-alert>
<content-editor
:render-markdown="renderMarkdown"
:uploads-path="pageInfo.uploadsPath"
@@ -560,12 +428,6 @@ export default {
></template
>
</gl-sprintf>
- <span v-if="displaySwitchBackToClassicEditorMessage">
- {{ $options.i18n.contentEditor.switchToOldEditor.helpText }}
- <gl-button variant="link" @click="confirmSwitchToOldEditor">{{
- $options.i18n.contentEditor.switchToOldEditor.label
- }}</gl-button>
- </span>
</div>
</div>
</div>
diff --git a/app/assets/javascripts/pages/shared/wikis/edit.js b/app/assets/javascripts/pages/shared/wikis/edit.js
index beeabfde1a6..02878633916 100644
--- a/app/assets/javascripts/pages/shared/wikis/edit.js
+++ b/app/assets/javascripts/pages/shared/wikis/edit.js
@@ -3,8 +3,8 @@ import Vue from 'vue';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import csrf from '~/lib/utils/csrf';
import Translate from '~/vue_shared/translate';
-import GLForm from '../../../gl_form';
-import ZenMode from '../../../zen_mode';
+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 wikiForm from './components/wiki_form.vue';
diff --git a/app/assets/javascripts/pages/shared/wikis/render_gfm_facade.js b/app/assets/javascripts/pages/shared/wikis/render_gfm_facade.js
new file mode 100644
index 00000000000..90cc2983153
--- /dev/null
+++ b/app/assets/javascripts/pages/shared/wikis/render_gfm_facade.js
@@ -0,0 +1,5 @@
+import $ from 'jquery';
+
+export const renderGFM = (el) => {
+ return $(el).renderGFM();
+};
diff --git a/app/assets/javascripts/pages/shared/wikis/show.js b/app/assets/javascripts/pages/shared/wikis/show.js
new file mode 100644
index 00000000000..9906cb595f8
--- /dev/null
+++ b/app/assets/javascripts/pages/shared/wikis/show.js
@@ -0,0 +1,27 @@
+import Vue from 'vue';
+import Wikis from './wikis';
+import WikiContent from './components/wiki_content.vue';
+
+const mountWikiContentApp = () => {
+ const el = document.querySelector('.js-async-wiki-page-content');
+
+ if (el) {
+ const { getWikiContentUrl } = el.dataset;
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ render(createElement) {
+ return createElement(WikiContent, {
+ props: { getWikiContentUrl },
+ });
+ },
+ });
+ }
+};
+
+export const mountApplications = () => {
+ // eslint-disable-next-line no-new
+ new Wikis();
+ mountWikiContentApp();
+};