Commit 716a98ca authored by Enrique Alcántara's avatar Enrique Alcántara Committed by David O'Regan

Remove switch editing controls feature flag

Removes the feature flag that hides the new control
to switch between Rich text and Source editing modes
in the Wikis

Changelog: other
MR: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83760
parent d5c05af3
<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 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,28 +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}.',
),
......@@ -108,7 +76,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 +83,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 +156,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 +258,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 +278,6 @@ export default {
},
});
},
dismissContentEditorAlert() {
this.isContentEditorAlertDismissed = true;
},
},
};
</script>
......@@ -438,10 +363,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 +373,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,7 +402,6 @@ 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">
......@@ -560,12 +445,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>
......
......@@ -21,10 +21,6 @@ module WikiActions
before_action :load_sidebar, except: [:pages]
before_action :set_content_class
before_action do
push_frontend_feature_flag(:wiki_switch_between_content_editor_raw_markdown, @group, default_enabled: :yaml)
end
before_action only: [:show, :edit, :update] do
@valid_encoding = valid_encoding?
end
......
---
name: wiki_switch_between_content_editor_raw_markdown
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74457
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345398
milestone: '14.6'
type: development
group: group::editor
default_enabled: true
......@@ -327,13 +327,7 @@ to disable the wiki but toggle it on (in blue).
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5643) in GitLab 14.0.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345398) switching between editing experiences in GitLab 14.7 [with a flag](../../../administration/feature_flags.md) named `wiki_switch_between_content_editor_raw_markdown`. Enabled by default.
FLAG:
On self-managed GitLab, by default this feature is available.
To hide the feature, ask an administrator to
[disable the feature flag](../../../administration/feature_flags.md) named
`wiki_switch_between_content_editor_raw_markdown`.
On GitLab.com, this feature is available.
> - Switching between editing experiences generally available in GitLab 14.10. [Feature flag `wiki_switch_between_content_editor_raw_markdown`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83760) removed.
GitLab version 14.0 introduces a WYSIWYG editing experience for GitLab Flavored Markdown
in Wikis through the [Content Editor](../../../development/fe_guide/content_editor.md).
......
......@@ -42280,9 +42280,6 @@ msgstr ""
msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
msgstr ""
msgid "WikiPage|Cancel"
msgstr ""
......@@ -42307,12 +42304,6 @@ msgstr ""
msgid "WikiPage|Format"
msgstr ""
msgid "WikiPage|Get a richer editing experience"
msgstr ""
msgid "WikiPage|Keep editing"
msgstr ""
msgid "WikiPage|Learn more."
msgstr ""
......@@ -42325,18 +42316,6 @@ msgstr ""
msgid "WikiPage|Save changes"
msgstr ""
msgid "WikiPage|Switch me back to the classic editor."
msgstr ""
msgid "WikiPage|Switch to classic editor"
msgstr ""
msgid "WikiPage|Switching to the classic editor will discard any changes you've made in the new editor."
msgstr ""
msgid "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."
msgstr ""
msgid "WikiPage|Tip: You can move this page by adding the path to the beginning of the title."
msgstr ""
......@@ -42349,18 +42328,9 @@ msgstr ""
msgid "WikiPage|To link to a (new) page, simply type %{linkExample}. More examples are in the %{linkStart}documentation%{linkEnd}."
msgstr ""
msgid "WikiPage|Try the new visual Markdown editor. Read the %{linkStart}documentation%{linkEnd} to learn what's currently supported."
msgstr ""
msgid "WikiPage|Try this later"
msgstr ""
msgid "WikiPage|Update %{pageTitle}"
msgstr ""
msgid "WikiPage|Use the new editor"
msgstr ""
msgid "WikiPage|Write your content or drag files here…"
msgstr ""
......
......@@ -14,7 +14,6 @@ module QA
element :wiki_content_textarea
element :wiki_message_textbox
element :wiki_submit_button
element :try_new_editor_container
element :editing_mode_button
end
......
import { nextTick } from 'vue';
import { GlLoadingIcon, GlModal, GlAlert, GlButton } from '@gitlab/ui';
import { GlAlert, GlButton } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
......@@ -32,11 +32,7 @@ describe('WikiForm', () => {
const findMessage = () => wrapper.find('#wiki_message');
const findSubmitButton = () => wrapper.findByTestId('wiki-submit-button');
const findCancelButton = () => wrapper.findByTestId('wiki-cancel-button');
const findUseNewEditorButton = () => wrapper.findByText('Use the new editor');
const findToggleEditingModeButton = () => wrapper.findByTestId('toggle-editing-mode-button');
const findDismissContentEditorAlertButton = () => wrapper.findByText('Try this later');
const findSwitchToOldEditorButton = () =>
wrapper.findByRole('button', { name: 'Switch me back to the classic editor.' });
const findTitleHelpLink = () => wrapper.findByText('Learn more.');
const findMarkdownHelpLink = () => wrapper.findByTestId('wiki-markdown-help-link');
const findContentEditor = () => wrapper.findComponent(ContentEditor);
......@@ -293,27 +289,21 @@ describe('WikiForm', () => {
);
});
describe('when wikiSwitchBetweenContentEditorRawMarkdown feature flag is not enabled', () => {
describe('toggle editing mode control', () => {
beforeEach(() => {
createWrapper({
glFeatures: { wikiSwitchBetweenContentEditorRawMarkdown: false },
});
});
it('hides toggle editing mode button', () => {
expect(findToggleEditingModeButton().exists()).toBe(false);
});
});
describe('when wikiSwitchBetweenContentEditorRawMarkdown feature flag is enabled', () => {
beforeEach(() => {
createWrapper({
glFeatures: { wikiSwitchBetweenContentEditorRawMarkdown: true },
});
createWrapper();
});
it('hides gl-alert containing "use new editor" button', () => {
expect(findUseNewEditorButton().exists()).toBe(false);
it.each`
format | enabled | action
${'markdown'} | ${true} | ${'displays'}
${'rdoc'} | ${false} | ${'hides'}
${'asciidoc'} | ${false} | ${'hides'}
${'org'} | ${false} | ${'hides'}
`('$action toggle editing mode button when format is $format', async ({ format, enabled }) => {
await setFormat(format);
expect(findToggleEditingModeButton().exists()).toBe(enabled);
});
it('displays toggle editing mode button', () => {
......@@ -326,8 +316,8 @@ describe('WikiForm', () => {
});
describe('when clicking the toggle editing mode button', () => {
beforeEach(() => {
findToggleEditingModeButton().vm.$emit('click');
beforeEach(async () => {
await findToggleEditingModeButton().trigger('click');
});
it('hides the classic editor', () => {
......@@ -343,17 +333,13 @@ describe('WikiForm', () => {
describe('when content editor is active', () => {
let mockContentEditor;
beforeEach(() => {
beforeEach(async () => {
mockContentEditor = {
getSerializedContent: jest.fn(),
setSerializedContent: jest.fn(),
};
findToggleEditingModeButton().vm.$emit('click');
});
it('hides switch to old editor button', () => {
expect(findSwitchToOldEditorButton().exists()).toBe(false);
await findToggleEditingModeButton().trigger('click');
});
it('displays "Edit source" label in the toggle editing mode button', () => {
......@@ -363,13 +349,13 @@ describe('WikiForm', () => {
describe('when clicking the toggle editing mode button', () => {
const contentEditorFakeSerializedContent = 'fake content';
beforeEach(() => {
beforeEach(async () => {
mockContentEditor.getSerializedContent.mockReturnValueOnce(
contentEditorFakeSerializedContent,
);
findContentEditor().vm.$emit('initialized', mockContentEditor);
findToggleEditingModeButton().vm.$emit('click');
await findToggleEditingModeButton().trigger('click');
});
it('hides the content editor', () => {
......@@ -388,75 +374,12 @@ describe('WikiForm', () => {
});
describe('wiki content editor', () => {
it.each`
format | buttonExists
${'markdown'} | ${true}
${'rdoc'} | ${false}
`(
'gl-alert containing "use new editor" button exists: $buttonExists if format is $format',
async ({ format, buttonExists }) => {
createWrapper();
await setFormat(format);
expect(findUseNewEditorButton().exists()).toBe(buttonExists);
},
);
it('gl-alert containing "use new editor" button is dismissed on clicking dismiss button', async () => {
createWrapper();
await findDismissContentEditorAlertButton().trigger('click');
expect(findUseNewEditorButton().exists()).toBe(false);
});
const assertOldEditorIsVisible = () => {
expect(findContentEditor().exists()).toBe(false);
expect(findClassicEditor().exists()).toBe(true);
expect(findSubmitButton().props('disabled')).toBe(false);
expect(wrapper.text()).not.toContain(
"Switching will discard any changes you've made in the new editor.",
);
expect(wrapper.text()).not.toContain(
"This editor is in beta and may not display the page's contents properly.",
);
};
it('shows classic editor by default', () => {
createWrapper({ persisted: true });
assertOldEditorIsVisible();
});
describe('switch format to rdoc', () => {
beforeEach(async () => {
createWrapper({ persisted: true });
await setFormat('rdoc');
});
it('continues to show the classic editor', assertOldEditorIsVisible);
describe('switch format back to markdown', () => {
beforeEach(async () => {
await setFormat('markdown');
});
it(
'still shows the classic editor and does not automatically switch to the content editor ',
assertOldEditorIsVisible,
);
});
});
describe('clicking "use new editor": editor fails to load', () => {
beforeEach(async () => {
createWrapper({ mountFn: mount });
mock.onPost(/preview-markdown/).reply(400);
await findUseNewEditorButton().trigger('click');
await findToggleEditingModeButton().trigger('click');
// try waiting for content editor to load (but it will never actually load)
await waitForPromises();
......@@ -466,14 +389,14 @@ describe('WikiForm', () => {
expect(findSubmitButton().props('disabled')).toBe(true);
});
describe('clicking "switch to classic editor"', () => {
describe('toggling editing modes to the classic editor', () => {
beforeEach(() => {
return findSwitchToOldEditorButton().trigger('click');
return findToggleEditingModeButton().trigger('click');
});
it('switches to classic editor directly without showing a modal', () => {
expect(wrapper.findComponent(ContentEditor).exists()).toBe(false);
expect(wrapper.findComponent(MarkdownField).exists()).toBe(true);
it('switches to classic editor', () => {
expect(findContentEditor().exists()).toBe(false);
expect(findClassicEditor().exists()).toBe(true);
});
});
});
......@@ -484,31 +407,19 @@ describe('WikiForm', () => {
mock.onPost(/preview-markdown/).reply(200, { body: '<p>hello <strong>world</strong></p>' });
await findUseNewEditorButton().trigger('click');
await findToggleEditingModeButton().trigger('click');
await waitForPromises();
});
it('shows a tip to send feedback', () => {
expect(wrapper.text()).toContain('Tell us your experiences with the new Markdown editor');
});
it('shows warnings that the rich text editor is in beta and may not work properly', () => {
expect(wrapper.text()).toContain(
"This editor is in beta and may not display the page's contents properly.",
);
});
it('shows the rich text editor when loading finishes', async () => {
// wait for content editor to load
await waitForPromises();
expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(false);
expect(wrapper.findComponent(ContentEditor).exists()).toBe(true);
expect(findContentEditor().exists()).toBe(true);
});
it('sends tracking event when editor loads', async () => {
// wait for content editor to load
await waitForPromises();
expect(trackingSpy).toHaveBeenCalledWith(undefined, CONTENT_EDITOR_LOADED_ACTION, {
label: WIKI_CONTENT_EDITOR_TRACKING_LABEL,
});
......@@ -564,49 +475,6 @@ describe('WikiForm', () => {
expect(findContent().element.value).toBe('hello **world**');
});
});
describe('clicking "switch to classic editor"', () => {
let modal;
beforeEach(async () => {
modal = wrapper.findComponent(GlModal);
jest.spyOn(modal.vm, 'show');
findSwitchToOldEditorButton().trigger('click');
});
it('shows a modal confirming the change', () => {
expect(modal.vm.show).toHaveBeenCalled();
});
describe('confirming "switch to classic editor" in the modal', () => {
beforeEach(async () => {
wrapper.vm.contentEditor.tiptapEditor.commands.setContent(
'<p>hello __world__ from content editor</p>',
true,
);
wrapper.findComponent(GlModal).vm.$emit('primary');
await nextTick();
});
it('switches to classic editor', () => {
expect(wrapper.findComponent(ContentEditor).exists()).toBe(false);
expect(wrapper.findComponent(MarkdownField).exists()).toBe(true);
});
it('does not show a warning about content editor', () => {
expect(wrapper.text()).not.toContain(
"This editor is in beta and may not display the page's contents properly.",
);
});
it('the classic editor retains its old value and does not use the content from the content editor', () => {
expect(findContent().element.value).toBe(' My page content ');
});
});
});
});
});
});
......@@ -145,19 +145,6 @@ RSpec.shared_examples 'User updates wiki page' do
it_behaves_like 'edits content using the content editor'
end
context 'with feature flag off' do
before do
stub_feature_flags(wiki_switch_between_content_editor_raw_markdown: false)
visit(wiki_path(wiki))
click_link('Edit')
click_button 'Use the new editor'
end
it_behaves_like 'edits content using the content editor'
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment