diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-20 13:37:47 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-20 13:37:47 +0000 |
commit | aee0a117a889461ce8ced6fcf73207fe017f1d99 (patch) | |
tree | 891d9ef189227a8445d83f35c1b0fc99573f4380 /app/assets/javascripts/pages | |
parent | 8d46af3258650d305f53b819eabf7ab18d22f59e (diff) | |
download | gitlab-ce-aee0a117a889461ce8ced6fcf73207fe017f1d99.tar.gz |
Add latest changes from gitlab-org/gitlab@14-6-stable-eev14.6.0-rc42
Diffstat (limited to 'app/assets/javascripts/pages')
67 files changed, 232 insertions, 980 deletions
diff --git a/app/assets/javascripts/pages/admin/integrations/edit/index.js b/app/assets/javascripts/pages/admin/integrations/edit/index.js index 8002fa8bf78..8485b460261 100644 --- a/app/assets/javascripts/pages/admin/integrations/edit/index.js +++ b/app/assets/javascripts/pages/admin/integrations/edit/index.js @@ -1,15 +1,11 @@ -import IntegrationSettingsForm from '~/integrations/integration_settings_form'; +import initIntegrationSettingsForm from '~/integrations/edit'; import PrometheusMetrics from '~/prometheus_metrics/prometheus_metrics'; -function initIntegrations() { - const prometheusSettingsWrapper = document.querySelector('.js-prometheus-metrics-monitoring'); - const integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form'); - integrationSettingsForm.init(); +initIntegrationSettingsForm('.js-integration-settings-form'); - if (prometheusSettingsWrapper) { - const prometheusMetrics = new PrometheusMetrics('.js-prometheus-metrics-monitoring'); - prometheusMetrics.loadActiveMetrics(); - } +const prometheusSettingsSelector = '.js-prometheus-metrics-monitoring'; +const prometheusSettingsWrapper = document.querySelector(prometheusSettingsSelector); +if (prometheusSettingsWrapper) { + const prometheusMetrics = new PrometheusMetrics(prometheusSettingsSelector); + prometheusMetrics.loadActiveMetrics(); } - -initIntegrations(); diff --git a/app/assets/javascripts/pages/admin/labels/edit/index.js b/app/assets/javascripts/pages/admin/labels/edit/index.js index f7c25347e75..a3b9c43388a 100644 --- a/app/assets/javascripts/pages/admin/labels/edit/index.js +++ b/app/assets/javascripts/pages/admin/labels/edit/index.js @@ -1,3 +1,3 @@ -import Labels from '../../../../labels'; +import Labels from '~/labels/labels'; new Labels(); // eslint-disable-line no-new diff --git a/app/assets/javascripts/pages/admin/labels/index/index.js b/app/assets/javascripts/pages/admin/labels/index/index.js index 0ceab3b922f..132fe5ce8fc 100644 --- a/app/assets/javascripts/pages/admin/labels/index/index.js +++ b/app/assets/javascripts/pages/admin/labels/index/index.js @@ -1,23 +1,3 @@ -function initLabels() { - const pagination = document.querySelector('.labels .gl-pagination'); - const emptyState = document.querySelector('.labels .nothing-here-block.hidden'); +import { initAdminLabels } from '~/labels'; - function removeLabelSuccessCallback() { - this.closest('li').classList.add('gl-display-none!'); - - const labelsCount = document.querySelectorAll( - 'ul.manage-labels-list li:not(.gl-display-none\\!)', - ).length; - - // display the empty state if there are no more labels - if (labelsCount < 1 && !pagination && emptyState) { - emptyState.classList.remove('hidden'); - } - } - - document.querySelectorAll('.js-remove-label').forEach((row) => { - row.addEventListener('ajax:success', removeLabelSuccessCallback); - }); -} - -initLabels(); +initAdminLabels(); diff --git a/app/assets/javascripts/pages/admin/labels/new/index.js b/app/assets/javascripts/pages/admin/labels/new/index.js index f7c25347e75..a3b9c43388a 100644 --- a/app/assets/javascripts/pages/admin/labels/new/index.js +++ b/app/assets/javascripts/pages/admin/labels/new/index.js @@ -1,3 +1,3 @@ -import Labels from '../../../../labels'; +import Labels from '~/labels/labels'; new Labels(); // eslint-disable-line no-new diff --git a/app/assets/javascripts/pages/admin/services/edit/index.js b/app/assets/javascripts/pages/admin/services/edit/index.js deleted file mode 100644 index b8080ddff77..00000000000 --- a/app/assets/javascripts/pages/admin/services/edit/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import IntegrationSettingsForm from '~/integrations/integration_settings_form'; - -const integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form'); -integrationSettingsForm.init(); diff --git a/app/assets/javascripts/pages/admin/services/index/index.js b/app/assets/javascripts/pages/admin/services/index/index.js deleted file mode 100644 index b695cf70c5d..00000000000 --- a/app/assets/javascripts/pages/admin/services/index/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import PersistentUserCallout from '~/persistent_user_callout'; - -const callout = document.querySelector('.js-service-templates-deprecated'); -PersistentUserCallout.factory(callout); diff --git a/app/assets/javascripts/pages/constants.js b/app/assets/javascripts/pages/constants.js deleted file mode 100644 index a9773807212..00000000000 --- a/app/assets/javascripts/pages/constants.js +++ /dev/null @@ -1,6 +0,0 @@ -export const FILTERED_SEARCH = { - MERGE_REQUESTS: 'merge_requests', - ISSUES: 'issues', - ADMIN_RUNNERS: 'admin/runners', - GROUP_RUNNERS_ANCHOR: 'runners-settings', -}; diff --git a/app/assets/javascripts/pages/dashboard/issues/index.js b/app/assets/javascripts/pages/dashboard/issues/index.js index 3e09b1796b1..d0903ad53bc 100644 --- a/app/assets/javascripts/pages/dashboard/issues/index.js +++ b/app/assets/javascripts/pages/dashboard/issues/index.js @@ -1,6 +1,6 @@ import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys'; -import initManualOrdering from '~/manual_ordering'; -import { FILTERED_SEARCH } from '~/pages/constants'; +import initManualOrdering from '~/issues/manual_ordering'; +import { FILTERED_SEARCH } from '~/filtered_search/constants'; import initFilteredSearch from '~/pages/search/init_filtered_search'; import projectSelect from '~/project_select'; diff --git a/app/assets/javascripts/pages/dashboard/merge_requests/index.js b/app/assets/javascripts/pages/dashboard/merge_requests/index.js index 6c134e4fad6..1350837476b 100644 --- a/app/assets/javascripts/pages/dashboard/merge_requests/index.js +++ b/app/assets/javascripts/pages/dashboard/merge_requests/index.js @@ -1,6 +1,6 @@ import addExtraTokensForMergeRequests from 'ee_else_ce/filtered_search/add_extra_tokens_for_merge_requests'; import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys'; -import { FILTERED_SEARCH } from '~/pages/constants'; +import { FILTERED_SEARCH } from '~/filtered_search/constants'; import initFilteredSearch from '~/pages/search/init_filtered_search'; import projectSelect from '~/project_select'; diff --git a/app/assets/javascripts/pages/dashboard/milestones/show/index.js b/app/assets/javascripts/pages/dashboard/milestones/show/index.js index 1f3e458fe17..d1ff7ec336c 100644 --- a/app/assets/javascripts/pages/dashboard/milestones/show/index.js +++ b/app/assets/javascripts/pages/dashboard/milestones/show/index.js @@ -1,4 +1,4 @@ -import Milestone from '~/milestone'; +import Milestone from '~/milestones/milestone'; import Sidebar from '~/right_sidebar'; import MountMilestoneSidebar from '~/sidebar/mount_milestone_sidebar'; diff --git a/app/assets/javascripts/pages/dashboard/projects/index/components/customize_homepage_banner.vue b/app/assets/javascripts/pages/dashboard/projects/index/components/customize_homepage_banner.vue deleted file mode 100644 index 99461475af0..00000000000 --- a/app/assets/javascripts/pages/dashboard/projects/index/components/customize_homepage_banner.vue +++ /dev/null @@ -1,102 +0,0 @@ -<script> -import { GlBanner } from '@gitlab/ui'; -import axios from '~/lib/utils/axios_utils'; -import { s__ } from '~/locale'; -import Tracking from '~/tracking'; - -const trackingMixin = Tracking.mixin(); - -export default { - components: { - GlBanner, - }, - mixins: [trackingMixin], - inject: { - svgPath: { - default: '', - }, - preferencesBehaviorPath: { - default: '', - }, - calloutsPath: { - default: '', - }, - calloutsFeatureId: { - default: '', - }, - trackLabel: { - default: '', - }, - }, - i18n: { - title: s__('CustomizeHomepageBanner|Do you want to customize this page?'), - body: s__( - 'CustomizeHomepageBanner|This page shows a list of your projects by default but it can be changed to show projects\' activity, groups, your to-do list, assigned issues, assigned merge requests, and more. You can change this under "Homepage content" in your preferences', - ), - button_text: s__('CustomizeHomepageBanner|Go to preferences'), - }, - data() { - return { - visible: true, - tracking: { - label: this.trackLabel, - }, - }; - }, - created() { - this.$nextTick(() => { - this.addTrackingAttributesToButton(); - }); - }, - mounted() { - this.trackOnShow(); - }, - methods: { - handleClose() { - axios - .post(this.calloutsPath, { - feature_name: this.calloutsFeatureId, - }) - .catch((e) => { - // eslint-disable-next-line @gitlab/require-i18n-strings, no-console - console.error('Failed to dismiss banner.', e); - }); - - this.visible = false; - this.track('click_dismiss'); - }, - trackOnShow() { - if (this.visible) this.track('show_home_page_banner'); - }, - addTrackingAttributesToButton() { - // we can't directly add these on the button like we need to due to - // button not being modifiable currently - // https://gitlab.com/gitlab-org/gitlab-ui/-/blob/9209ec424e5cca14bc8a1b5c9fa12636d8c83dad/src/components/base/banner/banner.vue#L60 - const button = this.$refs.banner.$el.querySelector( - `[href='${this.preferencesBehaviorPath}']`, - ); - - if (button) { - button.setAttribute('data-track-action', 'click_go_to_preferences'); - button.setAttribute('data-track-label', this.trackLabel); - } - }, - }, -}; -</script> - -<template> - <gl-banner - v-if="visible" - ref="banner" - :title="$options.i18n.title" - :button-text="$options.i18n.button_text" - :button-link="preferencesBehaviorPath" - :svg-path="svgPath" - @close="handleClose" - > - <p> - {{ $options.i18n.body }} - </p> - </gl-banner> -</template> diff --git a/app/assets/javascripts/pages/dashboard/projects/index/index.js b/app/assets/javascripts/pages/dashboard/projects/index/index.js index c34d15b869a..6c9378b7231 100644 --- a/app/assets/javascripts/pages/dashboard/projects/index/index.js +++ b/app/assets/javascripts/pages/dashboard/projects/index/index.js @@ -1,5 +1,3 @@ import ProjectsList from '~/projects_list'; -import initCustomizeHomepageBanner from './init_customize_homepage_banner'; new ProjectsList(); // eslint-disable-line no-new -initCustomizeHomepageBanner(); diff --git a/app/assets/javascripts/pages/dashboard/projects/index/init_customize_homepage_banner.js b/app/assets/javascripts/pages/dashboard/projects/index/init_customize_homepage_banner.js deleted file mode 100644 index 8cdcd3134ee..00000000000 --- a/app/assets/javascripts/pages/dashboard/projects/index/init_customize_homepage_banner.js +++ /dev/null @@ -1,16 +0,0 @@ -import Vue from 'vue'; -import CustomizeHomepageBanner from './components/customize_homepage_banner.vue'; - -export default () => { - const el = document.querySelector('.js-customize-homepage-banner'); - - if (!el) { - return false; - } - - return new Vue({ - el, - provide: { ...el.dataset }, - render: (createElement) => createElement(CustomizeHomepageBanner), - }); -}; diff --git a/app/assets/javascripts/pages/groups/issues/index.js b/app/assets/javascripts/pages/groups/issues/index.js index 8c9f23732aa..966d55e5587 100644 --- a/app/assets/javascripts/pages/groups/issues/index.js +++ b/app/assets/javascripts/pages/groups/issues/index.js @@ -1,8 +1,8 @@ import IssuableFilteredSearchTokenKeys from 'ee_else_ce/filtered_search/issuable_filtered_search_token_keys'; -import issuableInitBulkUpdateSidebar from '~/issuable_bulk_update_sidebar/issuable_init_bulk_update_sidebar'; +import issuableInitBulkUpdateSidebar from '~/issuable/bulk_update_sidebar/issuable_init_bulk_update_sidebar'; import { mountIssuablesListApp, mountIssuesListApp } from '~/issues_list'; -import initManualOrdering from '~/manual_ordering'; -import { FILTERED_SEARCH } from '~/pages/constants'; +import initManualOrdering from '~/issues/manual_ordering'; +import { FILTERED_SEARCH } from '~/filtered_search/constants'; import initFilteredSearch from '~/pages/search/init_filtered_search'; import projectSelect from '~/project_select'; diff --git a/app/assets/javascripts/pages/groups/labels/edit/index.js b/app/assets/javascripts/pages/groups/labels/edit/index.js index 2e8308fe084..e4e377f62fc 100644 --- a/app/assets/javascripts/pages/groups/labels/edit/index.js +++ b/app/assets/javascripts/pages/groups/labels/edit/index.js @@ -1,4 +1,4 @@ -import Labels from 'ee_else_ce/labels'; +import Labels from 'ee_else_ce/labels/labels'; // eslint-disable-next-line no-new new Labels(); diff --git a/app/assets/javascripts/pages/groups/labels/index/index.js b/app/assets/javascripts/pages/groups/labels/index/index.js index 95c2c7cd7d0..bf670e8576f 100644 --- a/app/assets/javascripts/pages/groups/labels/index/index.js +++ b/app/assets/javascripts/pages/groups/labels/index/index.js @@ -1,5 +1,4 @@ -import initDeleteLabelModal from '~/delete_label_modal'; -import initLabels from '~/init_labels'; +import { initDeleteLabelModal, initLabels } from '~/labels'; initLabels(); initDeleteLabelModal(); diff --git a/app/assets/javascripts/pages/groups/labels/new/index.js b/app/assets/javascripts/pages/groups/labels/new/index.js index 2e8308fe084..e4e377f62fc 100644 --- a/app/assets/javascripts/pages/groups/labels/new/index.js +++ b/app/assets/javascripts/pages/groups/labels/new/index.js @@ -1,4 +1,4 @@ -import Labels from 'ee_else_ce/labels'; +import Labels from 'ee_else_ce/labels/labels'; // eslint-disable-next-line no-new new Labels(); diff --git a/app/assets/javascripts/pages/groups/merge_requests/index.js b/app/assets/javascripts/pages/groups/merge_requests/index.js index 02a0a50f984..cb38ee1c6e0 100644 --- a/app/assets/javascripts/pages/groups/merge_requests/index.js +++ b/app/assets/javascripts/pages/groups/merge_requests/index.js @@ -1,7 +1,7 @@ import addExtraTokensForMergeRequests from 'ee_else_ce/filtered_search/add_extra_tokens_for_merge_requests'; import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys'; -import issuableInitBulkUpdateSidebar from '~/issuable_bulk_update_sidebar/issuable_init_bulk_update_sidebar'; -import { FILTERED_SEARCH } from '~/pages/constants'; +import issuableInitBulkUpdateSidebar from '~/issuable/bulk_update_sidebar/issuable_init_bulk_update_sidebar'; +import { FILTERED_SEARCH } from '~/filtered_search/constants'; import initFilteredSearch from '~/pages/search/init_filtered_search'; import projectSelect from '~/project_select'; diff --git a/app/assets/javascripts/pages/groups/milestones/edit/index.js b/app/assets/javascripts/pages/groups/milestones/edit/index.js index 4f8514a9a1d..7fda129a85d 100644 --- a/app/assets/javascripts/pages/groups/milestones/edit/index.js +++ b/app/assets/javascripts/pages/groups/milestones/edit/index.js @@ -1,3 +1,3 @@ -import initForm from '~/shared/milestones/form'; +import { initForm } from '~/milestones'; initForm(); diff --git a/app/assets/javascripts/pages/groups/milestones/new/index.js b/app/assets/javascripts/pages/groups/milestones/new/index.js index 4f8514a9a1d..7fda129a85d 100644 --- a/app/assets/javascripts/pages/groups/milestones/new/index.js +++ b/app/assets/javascripts/pages/groups/milestones/new/index.js @@ -1,3 +1,3 @@ -import initForm from '~/shared/milestones/form'; +import { initForm } from '~/milestones'; initForm(); diff --git a/app/assets/javascripts/pages/groups/milestones/show/index.js b/app/assets/javascripts/pages/groups/milestones/show/index.js index 914e2831185..f2ab5d78374 100644 --- a/app/assets/javascripts/pages/groups/milestones/show/index.js +++ b/app/assets/javascripts/pages/groups/milestones/show/index.js @@ -1,5 +1,4 @@ -import initDeleteMilestoneModal from '~/pages/milestones/shared/delete_milestone_modal_init'; -import initMilestonesShow from '~/pages/milestones/shared/init_milestones_show'; +import { initDeleteMilestoneModal, initShow } from '~/milestones'; -initMilestonesShow(); +initShow(); initDeleteMilestoneModal(); diff --git a/app/assets/javascripts/pages/groups/packages/index/index.js b/app/assets/javascripts/pages/groups/packages/index/index.js index f9eecff4ac4..174973a9fad 100644 --- a/app/assets/javascripts/pages/groups/packages/index/index.js +++ b/app/assets/javascripts/pages/groups/packages/index/index.js @@ -1,3 +1,3 @@ -import packageList from '~/packages_and_registries/package_registry/pages/list'; +import packageApp from '~/packages_and_registries/package_registry/index'; -packageList(); +packageApp(); 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 a8d7a83cdd6..5d8ee146e62 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 @@ -1,7 +1,7 @@ import initVariableList from '~/ci_variable_list'; import GroupRunnersFilteredSearchTokenKeys from '~/filtered_search/group_runners_filtered_search_token_keys'; import initSharedRunnersForm from '~/group_settings/mount_shared_runners'; -import { FILTERED_SEARCH } from '~/pages/constants'; +import { FILTERED_SEARCH } from '~/filtered_search/constants'; import initFilteredSearch from '~/pages/search/init_filtered_search'; import { initRunnerAwsDeployments } from '~/pages/shared/mount_runner_aws_deployments'; import { initInstallRunner } from '~/pages/shared/mount_runner_instructions'; 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 a8698e10c57..8485b460261 100644 --- a/app/assets/javascripts/pages/groups/settings/integrations/edit/index.js +++ b/app/assets/javascripts/pages/groups/settings/integrations/edit/index.js @@ -1,11 +1,11 @@ -import IntegrationSettingsForm from '~/integrations/integration_settings_form'; +import initIntegrationSettingsForm from '~/integrations/edit'; import PrometheusMetrics from '~/prometheus_metrics/prometheus_metrics'; -const prometheusSettingsWrapper = document.querySelector('.js-prometheus-metrics-monitoring'); -const integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form'); -integrationSettingsForm.init(); +initIntegrationSettingsForm('.js-integration-settings-form'); +const prometheusSettingsSelector = '.js-prometheus-metrics-monitoring'; +const prometheusSettingsWrapper = document.querySelector(prometheusSettingsSelector); if (prometheusSettingsWrapper) { - const prometheusMetrics = new PrometheusMetrics('.js-prometheus-metrics-monitoring'); + const prometheusMetrics = new PrometheusMetrics(prometheusSettingsSelector); prometheusMetrics.loadActiveMetrics(); } diff --git a/app/assets/javascripts/pages/help/ui/index.js b/app/assets/javascripts/pages/help/ui/index.js deleted file mode 100644 index 9ccc9123506..00000000000 --- a/app/assets/javascripts/pages/help/ui/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import initUIKit from '~/ui_development_kit'; - -initUIKit(); 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 ec3cf4a8a92..0ec382983a5 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 @@ -7,7 +7,7 @@ import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils'; import { joinPaths } from '~/lib/utils/url_utility'; import { getBulkImportsHistory } from '~/rest_api'; import ImportStatus from '~/import_entities/components/import_status.vue'; -import PaginationBar from '~/import_entities/components/pagination_bar.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'; @@ -166,7 +166,6 @@ export default { </gl-table> <pagination-bar :page-info="pageInfo" - :items-count="historyItems.length" class="gl-m-0 gl-mt-3" @set-page="paginationConfig.page = $event" @set-page-size="paginationConfig.perPage = $event" diff --git a/app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue b/app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue deleted file mode 100644 index 34f9fe778ea..00000000000 --- a/app/assets/javascripts/pages/milestones/shared/components/delete_milestone_modal.vue +++ /dev/null @@ -1,137 +0,0 @@ -<script> -import { GlSafeHtmlDirective as SafeHtml, GlModal } from '@gitlab/ui'; -import createFlash from '~/flash'; -import axios from '~/lib/utils/axios_utils'; - -import { redirectTo } from '~/lib/utils/url_utility'; -import { __, n__, s__, sprintf } from '~/locale'; -import eventHub from '../event_hub'; - -export default { - components: { - GlModal, - }, - directives: { - SafeHtml, - }, - props: { - issueCount: { - type: Number, - required: true, - }, - mergeRequestCount: { - type: Number, - required: true, - }, - milestoneId: { - type: Number, - required: true, - }, - milestoneTitle: { - type: String, - required: true, - }, - milestoneUrl: { - type: String, - required: true, - }, - }, - computed: { - text() { - const milestoneTitle = sprintf('<strong>%{milestoneTitle}</strong>', { - milestoneTitle: this.milestoneTitle, - }); - - if (this.issueCount === 0 && this.mergeRequestCount === 0) { - return sprintf( - s__(`Milestones| -You’re about to permanently delete the milestone %{milestoneTitle}. -This milestone is not currently used in any issues or merge requests.`), - { - milestoneTitle, - }, - false, - ); - } - - return sprintf( - s__(`Milestones| -You’re about to permanently delete the milestone %{milestoneTitle} and remove it from %{issuesWithCount} and %{mergeRequestsWithCount}. -Once deleted, it cannot be undone or recovered.`), - { - milestoneTitle, - issuesWithCount: n__('%d issue', '%d issues', this.issueCount), - mergeRequestsWithCount: n__( - '%d merge request', - '%d merge requests', - this.mergeRequestCount, - ), - }, - false, - ); - }, - title() { - return sprintf(s__('Milestones|Delete milestone %{milestoneTitle}?'), { - milestoneTitle: this.milestoneTitle, - }); - }, - }, - methods: { - onSubmit() { - eventHub.$emit('deleteMilestoneModal.requestStarted', this.milestoneUrl); - - return axios - .delete(this.milestoneUrl) - .then((response) => { - eventHub.$emit('deleteMilestoneModal.requestFinished', { - milestoneUrl: this.milestoneUrl, - successful: true, - }); - - // follow the rediect to milestones overview page - redirectTo(response.request.responseURL); - }) - .catch((error) => { - eventHub.$emit('deleteMilestoneModal.requestFinished', { - milestoneUrl: this.milestoneUrl, - successful: false, - }); - - if (error.response && error.response.status === 404) { - createFlash({ - message: sprintf(s__('Milestones|Milestone %{milestoneTitle} was not found'), { - milestoneTitle: this.milestoneTitle, - }), - }); - } else { - createFlash({ - message: sprintf(s__('Milestones|Failed to delete milestone %{milestoneTitle}'), { - milestoneTitle: this.milestoneTitle, - }), - }); - } - throw error; - }); - }, - }, - primaryProps: { - text: s__('Milestones|Delete milestone'), - attributes: [{ variant: 'danger' }, { category: 'primary' }], - }, - cancelProps: { - text: __('Cancel'), - }, -}; -</script> - -<template> - <gl-modal - modal-id="delete-milestone-modal" - :title="title" - :action-primary="$options.primaryProps" - :action-cancel="$options.cancelProps" - @primary="onSubmit" - > - <p v-safe-html="text"></p> - </gl-modal> -</template> diff --git a/app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue b/app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue deleted file mode 100644 index b41611001ab..00000000000 --- a/app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue +++ /dev/null @@ -1,104 +0,0 @@ -<script> -import { GlModal } from '@gitlab/ui'; -import createFlash from '~/flash'; -import axios from '~/lib/utils/axios_utils'; -import { visitUrl } from '~/lib/utils/url_utility'; -import { __, s__, sprintf } from '~/locale'; - -export default { - components: { - GlModal, - }, - data() { - return { - milestoneTitle: '', - url: '', - groupName: '', - currentButton: null, - visible: false, - }; - }, - computed: { - title() { - return sprintf(s__('Milestones|Promote %{milestoneTitle} to group milestone?'), { - milestoneTitle: this.milestoneTitle, - }); - }, - text() { - return sprintf( - s__(`Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. - Existing project milestones with the same title will be merged.`), - { milestoneTitle: this.milestoneTitle, groupName: this.groupName }, - ); - }, - }, - mounted() { - this.getButtons().forEach((button) => { - button.addEventListener('click', this.onPromoteButtonClick); - button.removeAttribute('disabled'); - }); - }, - beforeDestroy() { - this.getButtons().forEach((button) => { - button.removeEventListener('click', this.onPromoteButtonClick); - }); - }, - methods: { - onPromoteButtonClick({ currentTarget }) { - const { milestoneTitle, url, groupName } = currentTarget.dataset; - currentTarget.setAttribute('disabled', ''); - this.visible = true; - this.milestoneTitle = milestoneTitle; - this.url = url; - this.groupName = groupName; - this.currentButton = currentTarget; - }, - getButtons() { - return document.querySelectorAll('.js-promote-project-milestone-button'); - }, - onSubmit() { - return axios - .post(this.url, { params: { format: 'json' } }) - .then((response) => { - visitUrl(response.data.url); - }) - .catch((error) => { - createFlash({ - message: error, - }); - }) - .finally(() => { - this.visible = false; - }); - }, - onClose() { - this.visible = false; - if (this.currentButton) { - this.currentButton.removeAttribute('disabled'); - } - }, - }, - primaryAction: { - text: s__('Milestones|Promote Milestone'), - attributes: [{ variant: 'warning' }], - }, - cancelAction: { - text: __('Cancel'), - attributes: [], - }, -}; -</script> -<template> - <gl-modal - :visible="visible" - modal-id="promote-milestone-modal" - :action-primary="$options.primaryAction" - :action-cancel="$options.cancelAction" - :title="title" - @primary="onSubmit" - @hide="onClose" - > - <p>{{ text }}</p> - <p>{{ s__('Milestones|This action cannot be reversed.') }}</p> - </gl-modal> -</template> diff --git a/app/assets/javascripts/pages/milestones/shared/delete_milestone_modal_init.js b/app/assets/javascripts/pages/milestones/shared/delete_milestone_modal_init.js deleted file mode 100644 index 3aeff2db2e0..00000000000 --- a/app/assets/javascripts/pages/milestones/shared/delete_milestone_modal_init.js +++ /dev/null @@ -1,75 +0,0 @@ -import Vue from 'vue'; -import { BV_SHOW_MODAL } from '~/lib/utils/constants'; -import Translate from '~/vue_shared/translate'; -import DeleteMilestoneModal from './components/delete_milestone_modal.vue'; -import eventHub from './event_hub'; - -export default () => { - Vue.use(Translate); - - const onRequestFinished = ({ milestoneUrl, successful }) => { - const button = document.querySelector( - `.js-delete-milestone-button[data-milestone-url="${milestoneUrl}"]`, - ); - - if (!successful) { - button.removeAttribute('disabled'); - } - - button.querySelector('.js-loading-icon').classList.add('hidden'); - }; - - const deleteMilestoneButtons = document.querySelectorAll('.js-delete-milestone-button'); - - const onRequestStarted = (milestoneUrl) => { - const button = document.querySelector( - `.js-delete-milestone-button[data-milestone-url="${milestoneUrl}"]`, - ); - button.setAttribute('disabled', ''); - button.querySelector('.js-loading-icon').classList.remove('hidden'); - eventHub.$once('deleteMilestoneModal.requestFinished', onRequestFinished); - }; - - return new Vue({ - el: '#js-delete-milestone-modal', - data() { - return { - modalProps: { - milestoneId: -1, - milestoneTitle: '', - milestoneUrl: '', - issueCount: -1, - mergeRequestCount: -1, - }, - }; - }, - mounted() { - eventHub.$on('deleteMilestoneModal.props', this.setModalProps); - deleteMilestoneButtons.forEach((button) => { - button.removeAttribute('disabled'); - button.addEventListener('click', () => { - this.$root.$emit(BV_SHOW_MODAL, 'delete-milestone-modal'); - eventHub.$once('deleteMilestoneModal.requestStarted', onRequestStarted); - - this.setModalProps({ - milestoneId: parseInt(button.dataset.milestoneId, 10), - milestoneTitle: button.dataset.milestoneTitle, - milestoneUrl: button.dataset.milestoneUrl, - issueCount: parseInt(button.dataset.milestoneIssueCount, 10), - mergeRequestCount: parseInt(button.dataset.milestoneMergeRequestCount, 10), - }); - }); - }); - }, - methods: { - setModalProps(modalProps) { - this.modalProps = modalProps; - }, - }, - render(createElement) { - return createElement(DeleteMilestoneModal, { - props: this.modalProps, - }); - }, - }); -}; diff --git a/app/assets/javascripts/pages/milestones/shared/event_hub.js b/app/assets/javascripts/pages/milestones/shared/event_hub.js deleted file mode 100644 index e31806ad199..00000000000 --- a/app/assets/javascripts/pages/milestones/shared/event_hub.js +++ /dev/null @@ -1,3 +0,0 @@ -import createEventHub from '~/helpers/event_hub_factory'; - -export default createEventHub(); diff --git a/app/assets/javascripts/pages/milestones/shared/index.js b/app/assets/javascripts/pages/milestones/shared/index.js deleted file mode 100644 index dabfe32848b..00000000000 --- a/app/assets/javascripts/pages/milestones/shared/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import initDeleteMilestoneModal from './delete_milestone_modal_init'; -import initPromoteMilestoneModal from './promote_milestone_modal_init'; - -export default () => { - initDeleteMilestoneModal(); - initPromoteMilestoneModal(); -}; diff --git a/app/assets/javascripts/pages/milestones/shared/init_milestones_show.js b/app/assets/javascripts/pages/milestones/shared/init_milestones_show.js deleted file mode 100644 index b2a896a3265..00000000000 --- a/app/assets/javascripts/pages/milestones/shared/init_milestones_show.js +++ /dev/null @@ -1,11 +0,0 @@ -/* eslint-disable no-new */ - -import Milestone from '~/milestone'; -import Sidebar from '~/right_sidebar'; -import MountMilestoneSidebar from '~/sidebar/mount_milestone_sidebar'; - -export default () => { - new Milestone(); - new Sidebar(); - new MountMilestoneSidebar(); -}; diff --git a/app/assets/javascripts/pages/milestones/shared/promote_milestone_modal_init.js b/app/assets/javascripts/pages/milestones/shared/promote_milestone_modal_init.js deleted file mode 100644 index 5472b8c684f..00000000000 --- a/app/assets/javascripts/pages/milestones/shared/promote_milestone_modal_init.js +++ /dev/null @@ -1,19 +0,0 @@ -import Vue from 'vue'; -import Translate from '~/vue_shared/translate'; -import PromoteMilestoneModal from './components/promote_milestone_modal.vue'; - -Vue.use(Translate); - -export default () => { - const promoteMilestoneModal = document.getElementById('promote-milestone-modal'); - if (!promoteMilestoneModal) { - return null; - } - - return new Vue({ - el: promoteMilestoneModal, - render(createElement) { - return createElement(PromoteMilestoneModal); - }, - }); -}; 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 fdbfc35456f..37e9b7e99d4 100644 --- a/app/assets/javascripts/pages/profiles/personal_access_tokens/index.js +++ b/app/assets/javascripts/pages/profiles/personal_access_tokens/index.js @@ -1,4 +1,5 @@ -import { initExpiresAtField, initProjectsField } from '~/access_tokens'; +import { initExpiresAtField, initProjectsField, initTokensApp } from '~/access_tokens'; initExpiresAtField(); initProjectsField(); +initTokensApp(); diff --git a/app/assets/javascripts/pages/projects/constants.js b/app/assets/javascripts/pages/projects/constants.js deleted file mode 100644 index 8dc765e5d10..00000000000 --- a/app/assets/javascripts/pages/projects/constants.js +++ /dev/null @@ -1,4 +0,0 @@ -export const ISSUABLE_INDEX = { - MERGE_REQUEST: 'merge_request_', - ISSUE: 'issue_', -}; diff --git a/app/assets/javascripts/pages/projects/edit/index.js b/app/assets/javascripts/pages/projects/edit/index.js index f4beefea90c..100ca5b36d9 100644 --- a/app/assets/javascripts/pages/projects/edit/index.js +++ b/app/assets/javascripts/pages/projects/edit/index.js @@ -1,13 +1,14 @@ import { PROJECT_BADGE } from '~/badges/constants'; import initLegacyConfirmDangerModal from '~/confirm_danger_modal'; +import initConfirmDanger from '~/init_confirm_danger'; import dirtySubmitFactory from '~/dirty_submit/dirty_submit_factory'; import initFilePickers from '~/file_pickers'; import mountBadgeSettings from '~/pages/shared/mount_badge_settings'; import initProjectDeleteButton from '~/projects/project_delete_button'; import initServiceDesk from '~/projects/settings_service_desk'; +import initTransferProjectForm from '~/projects/settings/init_transfer_project_form'; import initSearchSettings from '~/search_settings'; import initSettingsPanels from '~/settings_panels'; -import setupTransferEdit from '~/transfer_edit'; import UserCallout from '~/user_callout'; import initTopicsTokenSelector from '~/projects/settings/topics'; import initProjectPermissionsSettings from '../shared/permissions'; @@ -15,6 +16,7 @@ import initProjectLoadingSpinner from '../shared/save_project_loader'; initFilePickers(); initLegacyConfirmDangerModal(); +initConfirmDanger(); initSettingsPanels(); initProjectDeleteButton(); mountBadgeSettings(PROJECT_BADGE); @@ -24,7 +26,7 @@ initServiceDesk(); initProjectLoadingSpinner(); initProjectPermissionsSettings(); -setupTransferEdit('.js-project-transfer-form', 'select.select2'); +initTransferProjectForm(); dirtySubmitFactory(document.querySelectorAll('.js-general-settings-form, .js-mr-settings-form')); diff --git a/app/assets/javascripts/pages/projects/incidents/show/index.js b/app/assets/javascripts/pages/projects/incidents/show/index.js index a75b68873ef..4633eaef8f9 100644 --- a/app/assets/javascripts/pages/projects/incidents/show/index.js +++ b/app/assets/javascripts/pages/projects/incidents/show/index.js @@ -1,6 +1,6 @@ import initRelatedIssues from '~/related_issues'; import initSidebarBundle from '~/sidebar/sidebar_bundle'; -import initShow from '../../issues/show'; +import initShow from '~/issues/show'; initShow(); initSidebarBundle(); diff --git a/app/assets/javascripts/pages/projects/issues/edit/index.js b/app/assets/javascripts/pages/projects/issues/edit/index.js index 48afd2142ee..aa00d1f58bd 100644 --- a/app/assets/javascripts/pages/projects/issues/edit/index.js +++ b/app/assets/javascripts/pages/projects/issues/edit/index.js @@ -1,3 +1,3 @@ -import initForm from 'ee_else_ce/pages/projects/issues/form'; +import initForm from 'ee_else_ce/issues/form'; initForm(); diff --git a/app/assets/javascripts/pages/projects/issues/form.js b/app/assets/javascripts/pages/projects/issues/form.js deleted file mode 100644 index c0da0069a99..00000000000 --- a/app/assets/javascripts/pages/projects/issues/form.js +++ /dev/null @@ -1,25 +0,0 @@ -/* eslint-disable no-new */ - -import $ from 'jquery'; -import IssuableForm from 'ee_else_ce/issuable_form'; -import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation'; -import GLForm from '~/gl_form'; -import initSuggestions from '~/issuable_suggestions'; -import initIssuableTypeSelector from '~/issuable_type_selector'; -import LabelsSelect from '~/labels_select'; -import MilestoneSelect from '~/milestone_select'; -import IssuableTemplateSelectors from '~/templates/issuable_template_selectors'; - -export default () => { - new ShortcutsNavigation(); - new GLForm($('.issue-form')); - new IssuableForm($('.issue-form')); - new LabelsSelect(); - new MilestoneSelect(); - new IssuableTemplateSelectors({ - warnTemplateOverride: true, - }); - - initSuggestions(); - initIssuableTypeSelector(); -}; diff --git a/app/assets/javascripts/pages/projects/issues/index/index.js b/app/assets/javascripts/pages/projects/issues/index/index.js index 8cd703133f5..e937713044c 100644 --- a/app/assets/javascripts/pages/projects/issues/index/index.js +++ b/app/assets/javascripts/pages/projects/issues/index/index.js @@ -1,12 +1,11 @@ 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 { initCsvImportExportButtons, initIssuableByEmail } from '~/issuable'; +import issuableInitBulkUpdateSidebar from '~/issuable/bulk_update_sidebar/issuable_init_bulk_update_sidebar'; import { mountIssuablesListApp, mountIssuesListApp, mountJiraIssuesListApp } from '~/issues_list'; -import initManualOrdering from '~/manual_ordering'; -import { FILTERED_SEARCH } from '~/pages/constants'; -import { ISSUABLE_INDEX } from '~/pages/projects/constants'; +import initManualOrdering from '~/issues/manual_ordering'; +import { FILTERED_SEARCH } from '~/filtered_search/constants'; +import { ISSUABLE_INDEX } from '~/issuable/constants'; import initFilteredSearch from '~/pages/search/init_filtered_search'; import UsersSelect from '~/users_select'; @@ -21,7 +20,7 @@ if (gon.features?.vueIssuesList) { useDefaultState: true, }); - new IssuableIndex(ISSUABLE_INDEX.ISSUE); // eslint-disable-line no-new + issuableInitBulkUpdateSidebar.init(ISSUABLE_INDEX.ISSUE); new UsersSelect(); // eslint-disable-line no-new initCsvImportExportButtons(); diff --git a/app/assets/javascripts/pages/projects/issues/new/index.js b/app/assets/javascripts/pages/projects/issues/new/index.js index 48afd2142ee..aa00d1f58bd 100644 --- a/app/assets/javascripts/pages/projects/issues/new/index.js +++ b/app/assets/javascripts/pages/projects/issues/new/index.js @@ -1,3 +1,3 @@ -import initForm from 'ee_else_ce/pages/projects/issues/form'; +import initForm from 'ee_else_ce/issues/form'; initForm(); diff --git a/app/assets/javascripts/pages/projects/issues/service_desk/filtered_search.js b/app/assets/javascripts/pages/projects/issues/service_desk/filtered_search.js deleted file mode 100644 index bec207aa439..00000000000 --- a/app/assets/javascripts/pages/projects/issues/service_desk/filtered_search.js +++ /dev/null @@ -1,31 +0,0 @@ -/* eslint-disable class-methods-use-this */ -import FilteredSearchManager from 'ee_else_ce/filtered_search/filtered_search_manager'; -import IssuableFilteredSearchTokenKeys from 'ee_else_ce/filtered_search/issuable_filtered_search_token_keys'; - -const AUTHOR_PARAM_KEY = 'author_username'; - -export default class FilteredSearchServiceDesk extends FilteredSearchManager { - constructor(supportBotData) { - super({ - page: 'service_desk', - filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys, - useDefaultState: true, - }); - - this.supportBotData = supportBotData; - } - - canEdit(tokenName) { - return tokenName !== 'author'; - } - - modifyUrlParams(paramsArray) { - const supportBotParamPair = `${AUTHOR_PARAM_KEY}=${this.supportBotData.username}`; - const onlyValidParams = paramsArray.filter((param) => param.indexOf(AUTHOR_PARAM_KEY) === -1); - - // unshift ensures author param is always first token element - onlyValidParams.unshift(supportBotParamPair); - - return onlyValidParams; - } -} diff --git a/app/assets/javascripts/pages/projects/issues/service_desk/index.js b/app/assets/javascripts/pages/projects/issues/service_desk/index.js index d906c579697..69639d17f8a 100644 --- a/app/assets/javascripts/pages/projects/issues/service_desk/index.js +++ b/app/assets/javascripts/pages/projects/issues/service_desk/index.js @@ -1,14 +1,7 @@ import { mountIssuablesListApp } from '~/issues_list'; -import FilteredSearchServiceDesk from './filtered_search'; +import { initFilteredSearchServiceDesk } from '~/issues/init_filtered_search_service_desk'; -const supportBotData = JSON.parse( - document.querySelector('.js-service-desk-issues').dataset.supportBot, -); - -if (document.querySelector('.filtered-search')) { - const filteredSearchManager = new FilteredSearchServiceDesk(supportBotData); - filteredSearchManager.setup(); -} +initFilteredSearchServiceDesk(); if (gon.features?.vueIssuablesList) { mountIssuablesListApp(); diff --git a/app/assets/javascripts/pages/projects/issues/show.js b/app/assets/javascripts/pages/projects/issues/show.js deleted file mode 100644 index 24aa2f0da13..00000000000 --- a/app/assets/javascripts/pages/projects/issues/show.js +++ /dev/null @@ -1,60 +0,0 @@ -import loadAwardsHandler from '~/awards_handler'; -import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable'; -import initIssuableSidebar from '~/init_issuable_sidebar'; -import { IssuableType } from '~/issuable_show/constants'; -import Issue from '~/issue'; -import { initIncidentApp, initIncidentHeaderActions } from '~/issue_show/incident'; -import { initIssuableApp, initIssueHeaderActions } from '~/issue_show/issue'; -import { parseIssuableData } from '~/issue_show/utils/parse_data'; -import initNotesApp from '~/notes'; -import { store } from '~/notes/stores'; -import initRelatedMergeRequestsApp from '~/related_merge_requests'; -import initSentryErrorStackTraceApp from '~/sentry_error_stack_trace'; -import initIssuableHeaderWarning from '~/vue_shared/components/issuable/init_issuable_header_warning'; -import ZenMode from '~/zen_mode'; - -export default function initShowIssue() { - initNotesApp(); - - const initialDataEl = document.getElementById('js-issuable-app'); - const { issueType, ...issuableData } = parseIssuableData(initialDataEl); - - switch (issueType) { - case IssuableType.Incident: - initIncidentApp(issuableData); - initIncidentHeaderActions(store); - break; - case IssuableType.Issue: - initIssuableApp(issuableData, store); - initIssueHeaderActions(store); - break; - default: - initIssueHeaderActions(store); - break; - } - - initIssuableHeaderWarning(store); - initSentryErrorStackTraceApp(); - initRelatedMergeRequestsApp(); - - import(/* webpackChunkName: 'design_management' */ '~/design_management') - .then((module) => module.default()) - .catch(() => {}); - - new ZenMode(); // eslint-disable-line no-new - - if (issueType !== IssuableType.TestCase) { - const awardEmojiEl = document.getElementById('js-vue-awards-block'); - - new Issue(); // eslint-disable-line no-new - new ShortcutsIssuable(); // eslint-disable-line no-new - initIssuableSidebar(); - if (awardEmojiEl) { - import('~/emoji/awards_app') - .then((m) => m.default(awardEmojiEl)) - .catch(() => {}); - } else { - loadAwardsHandler(); - } - } -} diff --git a/app/assets/javascripts/pages/projects/issues/show/index.js b/app/assets/javascripts/pages/projects/issues/show/index.js index 1282d2aa303..d0b1942f2a4 100644 --- a/app/assets/javascripts/pages/projects/issues/show/index.js +++ b/app/assets/javascripts/pages/projects/issues/show/index.js @@ -1,7 +1,7 @@ import { store } from '~/notes/stores'; import initRelatedIssues from '~/related_issues'; import initSidebarBundle from '~/sidebar/sidebar_bundle'; -import initShow from '../show'; +import initShow from '~/issues/show'; initShow(); initSidebarBundle(store); diff --git a/app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue b/app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue deleted file mode 100644 index e708cd32fff..00000000000 --- a/app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue +++ /dev/null @@ -1,113 +0,0 @@ -<script> -import { GlSprintf, GlModal } from '@gitlab/ui'; -import createFlash from '~/flash'; -import axios from '~/lib/utils/axios_utils'; -import { visitUrl } from '~/lib/utils/url_utility'; -import { s__, __, sprintf } from '~/locale'; -import eventHub from '../event_hub'; - -export default { - primaryProps: { - text: s__('Labels|Promote Label'), - attributes: [{ variant: 'warning' }, { category: 'primary' }], - }, - cancelProps: { - text: __('Cancel'), - }, - components: { - GlModal, - GlSprintf, - }, - props: { - url: { - type: String, - required: true, - }, - labelTitle: { - type: String, - required: true, - }, - labelColor: { - type: String, - required: true, - }, - labelTextColor: { - type: String, - required: true, - }, - groupName: { - type: String, - required: true, - }, - }, - computed: { - text() { - return sprintf( - s__(`Labels|Promoting %{labelTitle} will make it available for all projects inside %{groupName}. - Existing project labels with the same title will be merged. If a group label with the same title exists, - it will also be merged. This action cannot be reversed.`), - { - labelTitle: this.labelTitle, - groupName: this.groupName, - }, - ); - }, - }, - methods: { - onSubmit() { - eventHub.$emit('promoteLabelModal.requestStarted', this.url); - return axios - .post(this.url, { params: { format: 'json' } }) - .then((response) => { - eventHub.$emit('promoteLabelModal.requestFinished', { - labelUrl: this.url, - successful: true, - }); - visitUrl(response.data.url); - }) - .catch((error) => { - eventHub.$emit('promoteLabelModal.requestFinished', { - labelUrl: this.url, - successful: false, - }); - createFlash({ - message: error, - }); - }); - }, - }, -}; -</script> -<template> - <gl-modal - modal-id="promote-label-modal" - :action-primary="$options.primaryProps" - :action-cancel="$options.cancelProps" - @primary="onSubmit" - > - <template #modal-title> - <div class="modal-title-with-label"> - <gl-sprintf - :message=" - s__( - 'Labels|%{spanStart}Promote label%{spanEnd} %{labelTitle} %{spanStart}to Group Label?%{spanEnd}', - ) - " - > - <template #labelTitle> - <span - class="label color-label" - :style="`background-color: ${labelColor}; color: ${labelTextColor};`" - > - {{ labelTitle }} - </span> - </template> - <template #span="{ content }" - ><span>{{ content }}</span></template - > - </gl-sprintf> - </div> - </template> - {{ text }} - </gl-modal> -</template> diff --git a/app/assets/javascripts/pages/projects/labels/edit/index.js b/app/assets/javascripts/pages/projects/labels/edit/index.js index 3b7562deed9..c4d7af39767 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'; +import Labels from 'ee_else_ce/labels/labels'; new Labels(); // eslint-disable-line no-new diff --git a/app/assets/javascripts/pages/projects/labels/event_hub.js b/app/assets/javascripts/pages/projects/labels/event_hub.js deleted file mode 100644 index e31806ad199..00000000000 --- a/app/assets/javascripts/pages/projects/labels/event_hub.js +++ /dev/null @@ -1,3 +0,0 @@ -import createEventHub from '~/helpers/event_hub_factory'; - -export default createEventHub(); diff --git a/app/assets/javascripts/pages/projects/labels/index/index.js b/app/assets/javascripts/pages/projects/labels/index/index.js index 94ab0d64de4..1f8ff7e0bb1 100644 --- a/app/assets/javascripts/pages/projects/labels/index/index.js +++ b/app/assets/javascripts/pages/projects/labels/index/index.js @@ -1,83 +1,3 @@ -import Vue from 'vue'; -import initDeleteLabelModal from '~/delete_label_modal'; -import initLabels from '~/init_labels'; -import { BV_SHOW_MODAL } from '~/lib/utils/constants'; -import Translate from '~/vue_shared/translate'; -import PromoteLabelModal from '../components/promote_label_modal.vue'; -import eventHub from '../event_hub'; +import { initLabelIndex } from '~/labels'; -Vue.use(Translate); - -const initLabelIndex = () => { - initLabels(); - initDeleteLabelModal(); - - const onRequestFinished = ({ labelUrl, successful }) => { - const button = document.querySelector( - `.js-promote-project-label-button[data-url="${labelUrl}"]`, - ); - - if (!successful) { - button.removeAttribute('disabled'); - } - }; - - const onRequestStarted = (labelUrl) => { - const button = document.querySelector( - `.js-promote-project-label-button[data-url="${labelUrl}"]`, - ); - button.setAttribute('disabled', ''); - eventHub.$once('promoteLabelModal.requestFinished', onRequestFinished); - }; - - const promoteLabelButtons = document.querySelectorAll('.js-promote-project-label-button'); - - return new Vue({ - el: '#js-promote-label-modal', - data() { - return { - modalProps: { - labelTitle: '', - labelColor: '', - labelTextColor: '', - url: '', - groupName: '', - }, - }; - }, - mounted() { - eventHub.$on('promoteLabelModal.props', this.setModalProps); - eventHub.$emit('promoteLabelModal.mounted'); - - promoteLabelButtons.forEach((button) => { - button.removeAttribute('disabled'); - button.addEventListener('click', () => { - this.$root.$emit(BV_SHOW_MODAL, 'promote-label-modal'); - eventHub.$once('promoteLabelModal.requestStarted', onRequestStarted); - - this.setModalProps({ - labelTitle: button.dataset.labelTitle, - labelColor: button.dataset.labelColor, - labelTextColor: button.dataset.labelTextColor, - url: button.dataset.url, - groupName: button.dataset.groupName, - }); - }); - }); - }, - beforeDestroy() { - eventHub.$off('promoteLabelModal.props', this.setModalProps); - }, - methods: { - setModalProps(modalProps) { - this.modalProps = modalProps; - }, - }, - render(createElement) { - return createElement(PromoteLabelModal, { - props: this.modalProps, - }); - }, - }); -}; initLabelIndex(); diff --git a/app/assets/javascripts/pages/projects/labels/new/index.js b/app/assets/javascripts/pages/projects/labels/new/index.js index 2e8308fe084..e4e377f62fc 100644 --- a/app/assets/javascripts/pages/projects/labels/new/index.js +++ b/app/assets/javascripts/pages/projects/labels/new/index.js @@ -1,4 +1,4 @@ -import Labels from 'ee_else_ce/labels'; +import Labels from 'ee_else_ce/labels/labels'; // eslint-disable-next-line no-new new Labels(); 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 95afcb6bda8..42c40cda601 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 @@ -1,18 +1,21 @@ <script> -import { GlProgressBar, GlSprintf } from '@gitlab/ui'; +import { GlProgressBar, GlSprintf, GlAlert } from '@gitlab/ui'; import eventHub from '~/invite_members/event_hub'; import { s__ } from '~/locale'; import { ACTION_LABELS, ACTION_SECTIONS } from '../constants'; import LearnGitlabSectionCard from './learn_gitlab_section_card.vue'; export default { - components: { GlProgressBar, GlSprintf, LearnGitlabSectionCard }, + components: { GlProgressBar, GlSprintf, GlAlert, LearnGitlabSectionCard }, i18n: { 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`), + successfulInvitations: s__( + "LearnGitLab|Your team is growing! You've successfully invited new team members to the %{projectName} project.", + ), }, props: { actions: { @@ -28,12 +31,22 @@ export default { required: false, default: false, }, + project: { + required: true, + type: Object, + }, + }, + data() { + return { + showSuccessfulInvitationsAlert: false, + actionsData: this.actions, + }; }, maxValue: Object.keys(ACTION_LABELS).length, actionSections: Object.keys(ACTION_SECTIONS), computed: { progressValue() { - return Object.values(this.actions).filter((a) => a.completed).length; + return Object.values(this.actionsData).filter((a) => a.completed).length; }, progressPercentage() { return Math.round((this.progressValue / this.$options.maxValue) * 100); @@ -43,14 +56,23 @@ export default { if (this.inviteMembersOpen) { this.openInviteMembersModal('celebrate'); } + + eventHub.$on('showSuccessfulInvitationsAlert', this.handleShowSuccessfulInvitationsAlert); + }, + beforeDestroy() { + eventHub.$off('showSuccessfulInvitationsAlert', this.handleShowSuccessfulInvitationsAlert); }, methods: { openInviteMembersModal(mode) { eventHub.$emit('openModal', { mode, inviteeType: 'members', source: 'learn-gitlab' }); }, + handleShowSuccessfulInvitationsAlert() { + this.showSuccessfulInvitationsAlert = true; + this.markActionAsCompleted('userAdded'); + }, actionsFor(section) { const actions = Object.fromEntries( - Object.entries(this.actions).filter( + Object.entries(this.actionsData).filter( ([action]) => ACTION_LABELS[action].section === section, ), ); @@ -59,11 +81,34 @@ export default { svgFor(section) { return this.sections[section].svg; }, + markActionAsCompleted(completedAction) { + Object.keys(this.actionsData).forEach((action) => { + if (action === completedAction) { + this.actionsData[action].completed = true; + this.modifySidebarPercentage(); + } + }); + }, + modifySidebarPercentage() { + const el = document.querySelector('.sidebar-top-level-items .active .count'); + el.textContent = `${this.progressPercentage}%`; + }, }, }; </script> <template> <div> + <gl-alert + v-if="showSuccessfulInvitationsAlert" + class="gl-mt-5" + @dismiss="showSuccessfulInvitationsAlert = false" + > + <gl-sprintf :message="$options.i18n.successfulInvitations"> + <template #projectName> + <strong>{{ project.name }}</strong> + </template> + </gl-sprintf> + </gl-alert> <div class="row"> <div class="gl-mb-7 gl-ml-5"> <h1 class="gl-font-size-h1">{{ $options.i18n.title }}</h1> 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 0995947f3e7..3a401f5cb31 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,5 +1,7 @@ <script> import { GlLink, GlIcon } from '@gitlab/ui'; +import { isExperimentVariant } from '~/experimentation/utils'; +import eventHub from '~/invite_members/event_hub'; import { s__ } from '~/locale'; import { ACTION_LABELS } from '../constants'; @@ -24,6 +26,20 @@ export default { trialOnly() { return ACTION_LABELS[this.action].trialRequired; }, + showInviteModalLink() { + return ( + this.action === 'userAdded' && isExperimentVariant('invite_for_help_continuous_onboarding') + ); + }, + }, + methods: { + openModal() { + eventHub.$emit('openModal', { + inviteeType: 'members', + source: 'learn_gitlab', + tasksToBeDoneEnabled: true, + }); + }, }, }; </script> @@ -33,18 +49,27 @@ export default { <gl-icon name="check-circle-filled" :size="16" data-testid="completed-icon" /> {{ $options.i18n.ACTION_LABELS[action].title }} </span> - <span v-else> - <gl-link - target="_blank" - :href="value.url" - data-track-action="click_link" - :data-track-label="$options.i18n.ACTION_LABELS[action].title" - data-track-property="Growth::Conversion::Experiment::LearnGitLab" - data-track-experiment="change_continuous_onboarding_link_urls" - > - {{ $options.i18n.ACTION_LABELS[action].title }} - </gl-link> - </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="_blank" + :href="value.url" + data-track-action="click_link" + :data-track-label="$options.i18n.ACTION_LABELS[action].title" + data-track-property="Growth::Conversion::Experiment::LearnGitLab" + data-track-experiment="change_continuous_onboarding_link_urls" + > + {{ $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> 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 ea9eec2595f..1f91cc46946 100644 --- a/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js +++ b/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js @@ -12,17 +12,18 @@ function initLearnGitlab() { const actions = convertObjectPropsToCamelCase(JSON.parse(el.dataset.actions)); const sections = convertObjectPropsToCamelCase(JSON.parse(el.dataset.sections)); + const project = convertObjectPropsToCamelCase(JSON.parse(el.dataset.project)); const { inviteMembersOpen } = el.dataset; return new Vue({ el, render(createElement) { return createElement(LearnGitlab, { - props: { actions, sections, inviteMembersOpen }, + props: { actions, sections, project, inviteMembersOpen }, }); }, }); } -initInviteMembersModal(); initLearnGitlab(); +initInviteMembersModal(); 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 d279086df7b..acd1731a700 100644 --- a/app/assets/javascripts/pages/projects/merge_requests/index/index.js +++ b/app/assets/javascripts/pages/projects/merge_requests/index/index.js @@ -1,17 +1,17 @@ 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'; -import { ISSUABLE_INDEX } from '~/pages/projects/constants'; +import { initCsvImportExportButtons, initIssuableByEmail } from '~/issuable'; +import issuableInitBulkUpdateSidebar from '~/issuable/bulk_update_sidebar/issuable_init_bulk_update_sidebar'; +import { FILTERED_SEARCH } from '~/filtered_search/constants'; +import { ISSUABLE_INDEX } from '~/issuable/constants'; import initFilteredSearch from '~/pages/search/init_filtered_search'; import UsersSelect from '~/users_select'; -new IssuableIndex(ISSUABLE_INDEX.MERGE_REQUEST); // eslint-disable-line no-new +issuableInitBulkUpdateSidebar.init(ISSUABLE_INDEX.MERGE_REQUEST); addExtraTokensForMergeRequests(IssuableFilteredSearchTokenKeys); +IssuableFilteredSearchTokenKeys.removeTokensForKeys('iteration'); initFilteredSearch({ page: FILTERED_SEARCH.MERGE_REQUESTS, diff --git a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request.js b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request.js index 7d5719cf8a8..ebf7c266482 100644 --- a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request.js +++ b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request.js @@ -1,13 +1,13 @@ /* eslint-disable no-new */ import $ from 'jquery'; -import IssuableForm from 'ee_else_ce/issuable_form'; +import IssuableForm from 'ee_else_ce/issuable/issuable_form'; import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation'; import Diff from '~/diff'; import GLForm from '~/gl_form'; -import LabelsSelect from '~/labels_select'; -import MilestoneSelect from '~/milestone_select'; -import IssuableTemplateSelectors from '~/templates/issuable_template_selectors'; +import LabelsSelect from '~/labels/labels_select'; +import MilestoneSelect from '~/milestones/milestone_select'; +import IssuableTemplateSelectors from '~/issuable/issuable_template_selectors'; export default () => { new Diff(); 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 99094617b0a..c548ea9bb80 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 @@ -3,7 +3,7 @@ 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 '~/init_issuable_sidebar'; +import { initIssuableSidebar } from '~/issuable'; import StatusBox from '~/issuable/components/status_box.vue'; import createDefaultClient from '~/lib/graphql'; import initSourcegraph from '~/sourcegraph'; diff --git a/app/assets/javascripts/pages/projects/merge_requests/queries/get_state.query.graphql b/app/assets/javascripts/pages/projects/merge_requests/queries/get_state.query.graphql index b5a82b9428e..1edb37a228d 100644 --- a/app/assets/javascripts/pages/projects/merge_requests/queries/get_state.query.graphql +++ b/app/assets/javascripts/pages/projects/merge_requests/queries/get_state.query.graphql @@ -1,6 +1,8 @@ query getMergeRequestState($projectPath: ID!, $iid: String!) { workspace: project(fullPath: $projectPath) { + id issuable: mergeRequest(iid: $iid) { + id state } } diff --git a/app/assets/javascripts/pages/projects/merge_requests/show/index.js b/app/assets/javascripts/pages/projects/merge_requests/show/index.js index 25dede33880..7f49eb60c5c 100644 --- a/app/assets/javascripts/pages/projects/merge_requests/show/index.js +++ b/app/assets/javascripts/pages/projects/merge_requests/show/index.js @@ -1,8 +1,8 @@ import { initReviewBar } from '~/batch_comments'; +import { initIssuableHeaderWarnings } from '~/issuable'; import initMrNotes from '~/mr_notes'; import store from '~/mr_notes/stores'; import initSidebarBundle from '~/sidebar/sidebar_bundle'; -import initIssuableHeaderWarning from '~/vue_shared/components/issuable/init_issuable_header_warning'; import initShow from '../init_merge_request_show'; initMrNotes(); @@ -11,5 +11,5 @@ initShow(); requestIdleCallback(() => { initSidebarBundle(store); initReviewBar(); - initIssuableHeaderWarning(store); + initIssuableHeaderWarnings(store); }); diff --git a/app/assets/javascripts/pages/projects/milestones/edit/index.js b/app/assets/javascripts/pages/projects/milestones/edit/index.js index 4f8514a9a1d..7fda129a85d 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 '~/milestones'; initForm(); diff --git a/app/assets/javascripts/pages/projects/milestones/index/index.js b/app/assets/javascripts/pages/projects/milestones/index/index.js index 150b506b121..ef1c9ab83db 100644 --- a/app/assets/javascripts/pages/projects/milestones/index/index.js +++ b/app/assets/javascripts/pages/projects/milestones/index/index.js @@ -1,3 +1,4 @@ -import milestones from '~/pages/milestones/shared'; +import { initDeleteMilestoneModal, initPromoteMilestoneModal } from '~/milestones'; -milestones(); +initDeleteMilestoneModal(); +initPromoteMilestoneModal(); diff --git a/app/assets/javascripts/pages/projects/milestones/new/index.js b/app/assets/javascripts/pages/projects/milestones/new/index.js index 4f8514a9a1d..7fda129a85d 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'; +import { initForm } from '~/milestones'; initForm(); diff --git a/app/assets/javascripts/pages/projects/milestones/show/index.js b/app/assets/javascripts/pages/projects/milestones/show/index.js index 3c755e9b98c..16aac7748da 100644 --- a/app/assets/javascripts/pages/projects/milestones/show/index.js +++ b/app/assets/javascripts/pages/projects/milestones/show/index.js @@ -1,5 +1,5 @@ -import milestones from '~/pages/milestones/shared'; -import initMilestonesShow from '~/pages/milestones/shared/init_milestones_show'; +import { initDeleteMilestoneModal, initPromoteMilestoneModal, initShow } from '~/milestones'; -initMilestonesShow(); -milestones(); +initShow(); +initDeleteMilestoneModal(); +initPromoteMilestoneModal(); diff --git a/app/assets/javascripts/pages/projects/packages/packages/index/index.js b/app/assets/javascripts/pages/projects/packages/packages/index/index.js index f9eecff4ac4..174973a9fad 100644 --- a/app/assets/javascripts/pages/projects/packages/packages/index/index.js +++ b/app/assets/javascripts/pages/projects/packages/packages/index/index.js @@ -1,3 +1,3 @@ -import packageList from '~/packages_and_registries/package_registry/pages/list'; +import packageApp from '~/packages_and_registries/package_registry/index'; -packageList(); +packageApp(); diff --git a/app/assets/javascripts/pages/projects/path_locks/index.js b/app/assets/javascripts/pages/projects/path_locks/index.js deleted file mode 100644 index e5ab5d43bbf..00000000000 --- a/app/assets/javascripts/pages/projects/path_locks/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import initDeprecatedRemoveRowBehavior from '~/behaviors/deprecated_remove_row_behavior'; - -document.addEventListener('DOMContentLoaded', initDeprecatedRemoveRowBehavior); diff --git a/app/assets/javascripts/pages/projects/services/edit/index.js b/app/assets/javascripts/pages/projects/services/edit/index.js index 03ffc323fc0..a2b18d86240 100644 --- a/app/assets/javascripts/pages/projects/services/edit/index.js +++ b/app/assets/javascripts/pages/projects/services/edit/index.js @@ -1,9 +1,8 @@ -import IntegrationSettingsForm from '~/integrations/integration_settings_form'; +import initIntegrationSettingsForm from '~/integrations/edit'; import PrometheusAlerts from '~/prometheus_alerts'; import CustomMetrics from '~/prometheus_metrics/custom_metrics'; -const integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form'); -integrationSettingsForm.init(); +initIntegrationSettingsForm('.js-integration-settings-form'); const prometheusSettingsSelector = '.js-prometheus-metrics-monitoring'; const prometheusSettingsWrapper = document.querySelector(prometheusSettingsSelector); diff --git a/app/assets/javascripts/pages/projects/usage_quotas/index.js b/app/assets/javascripts/pages/projects/usage_quotas/index.js deleted file mode 100644 index 9cd80b85c8a..00000000000 --- a/app/assets/javascripts/pages/projects/usage_quotas/index.js +++ /dev/null @@ -1,23 +0,0 @@ -import LinkedTabs from '~/lib/utils/bootstrap_linked_tabs'; -import storageCounter from '~/projects/storage_counter'; -import initSearchSettings from '~/search_settings'; - -const initLinkedTabs = () => { - if (!document.querySelector('.js-usage-quota-tabs')) { - return false; - } - - return new LinkedTabs({ - defaultAction: '#storage-quota-tab', - parentEl: '.js-usage-quota-tabs', - hashedTabs: true, - }); -}; - -const initVueApp = () => { - storageCounter('js-project-storage-count-app'); -}; - -initVueApp(); -initLinkedTabs(); -initSearchSettings(); 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 6f19a9f4379..b29e9455755 100644 --- a/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue +++ b/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue @@ -15,6 +15,7 @@ import { setUrlFragment } from '~/lib/utils/url_utility'; 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, @@ -46,7 +47,7 @@ export default { newPage: s__( 'WikiPage|Tip: You can specify the full path for the new file. We will automatically create any missing directories.', ), - moreInformation: s__('WikiPage|More Information.'), + learnMore: s__('WikiPage|Learn more.'), }, }, format: { @@ -104,6 +105,8 @@ export default { newPage: s__('WikiPage|Create page'), }, cancel: s__('WikiPage|Cancel'), + editSourceButtonText: s__('WikiPage|Edit source'), + editRichTextButtonText: s__('WikiPage|Edit rich text'), }, contentEditorFeedbackIssue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/332629', components: { @@ -123,7 +126,7 @@ export default { directives: { GlModalDirective, }, - mixins: [trackingMixin], + mixins: [trackingMixin, glFeatureFlagMixin()], inject: ['formatOptions', 'pageInfo'], data() { return { @@ -131,7 +134,6 @@ export default { format: this.pageInfo.format || 'markdown', content: this.pageInfo.content || '', isContentEditorAlertDismissed: false, - isContentEditorLoading: true, useContentEditor: false, commitMessage: '', isDirty: false, @@ -164,6 +166,11 @@ export default { linkExample() { return MARKDOWN_LINK_TEXT[this.format]; }, + toggleEditingModeButtonText() { + return this.isContentEditorActive + ? this.$options.i18n.editSourceButtonText + : this.$options.i18n.editRichTextButtonText; + }, submitButtonText() { return this.pageInfo.persisted ? this.$options.i18n.submitButton.existingPage @@ -188,7 +195,23 @@ export default { return this.format === 'markdown'; }, showContentEditorAlert() { - return this.isMarkdownFormat && !this.useContentEditor && !this.isContentEditorAlertDismissed; + 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; @@ -212,6 +235,14 @@ export default { .then(({ data }) => data.body); }, + toggleEditingMode() { + if (this.useContentEditor) { + this.content = this.contentEditor.getSerializedContent(); + } + + this.useContentEditor = !this.useContentEditor; + }, + async handleFormSubmit(e) { e.preventDefault(); @@ -311,8 +342,11 @@ export default { trackWikiFormat() { this.track(WIKI_FORMAT_UPDATED_ACTION, { label: WIKI_FORMAT_LABEL, - value: this.format, - extra: { project_path: this.pageInfo.path, old_format: this.pageInfo.format }, + extra: { + project_path: this.pageInfo.path, + old_format: this.pageInfo.format, + value: this.format, + }, }); }, @@ -371,10 +405,9 @@ export default { <span class="gl-display-inline-block gl-max-w-full gl-mt-2 gl-text-gray-600"> <gl-icon class="gl-mr-n1" name="bulb" /> {{ titleHelpText }} - <gl-link :href="helpPath" target="_blank" - ><gl-icon name="question-o" /> - {{ $options.i18n.title.helpText.moreInformation }}</gl-link - > + <gl-link :href="helpPath" target="_blank"> + {{ $options.i18n.title.helpText.learnMore }} + </gl-link> </span> </div> </div> @@ -405,6 +438,19 @@ export default { }}</label> </div> <div class="col-sm-10"> + <div + v-if="showSwitchEditingModeButton" + 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" + :data-qa-mode="toggleEditingModeButtonText" + variant="link" + @click="toggleEditingMode" + >{{ toggleEditingModeButtonText }}</gl-button + > + </div> <gl-alert v-if="showContentEditorAlert" class="gl-mb-6" @@ -498,7 +544,7 @@ export default { <div class="error-alert"></div> <div class="form-text gl-text-gray-600"> - <gl-sprintf v-if="!isContentEditorActive" :message="$options.i18n.linksHelpText"> + <gl-sprintf v-if="displayWikiSpecificMarkdownHelp" :message="$options.i18n.linksHelpText"> <template #linkExample ><code>{{ linkExample }}</code></template > @@ -513,7 +559,7 @@ export default { ></template > </gl-sprintf> - <span v-else> + <span v-if="displaySwitchBackToClassicEditorMessage"> {{ $options.i18n.contentEditor.switchToOldEditor.helpText }} <gl-button variant="link" @click="confirmSwitchToOldEditor">{{ $options.i18n.contentEditor.switchToOldEditor.label |