Commit 7d746076 authored by Alex Kalderimis's avatar Alex Kalderimis

Merge branch '327762-ff-wiki_content_editor' into 'master'

[Feature flag] Remove `wiki_content_editor` [RUN ALL RSPEC] [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!62919
parents e95f91e8 2dddbe79
......@@ -9,6 +9,13 @@ export class ContentEditor {
return this._tiptapEditor;
}
get empty() {
const doc = this.tiptapEditor?.state.doc;
// Makes sure the document has more than one empty paragraph
return doc.childCount === 0 || (doc.childCount === 1 && doc.child(0).childCount === 0);
}
async setSerializedContent(serializedContent) {
const { _tiptapEditor: editor, _serializer: serializer } = this;
......
......@@ -14,8 +14,17 @@ 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 {
WIKI_CONTENT_EDITOR_TRACKING_LABEL,
CONTENT_EDITOR_LOADED_ACTION,
SAVED_USING_CONTENT_EDITOR_ACTION,
} from '../constants';
const trackingMixin = Tracking.mixin({
label: WIKI_CONTENT_EDITOR_TRACKING_LABEL,
});
const MARKDOWN_LINK_TEXT = {
markdown: '[Link Title](page-slug)',
......@@ -104,7 +113,7 @@ export default {
directives: {
GlModalDirective,
},
mixins: [glFeatureFlagMixin()],
mixins: [trackingMixin],
inject: ['formatOptions', 'pageInfo'],
data() {
return {
......@@ -120,6 +129,10 @@ export default {
};
},
computed: {
noContent() {
if (this.isContentEditorActive) return this.contentEditor?.empty;
return !this.content;
},
csrfToken() {
return csrf.token;
},
......@@ -161,10 +174,10 @@ export default {
return this.format === 'markdown';
},
showContentEditorButton() {
return this.isMarkdownFormat && !this.useContentEditor && this.glFeatures.wikiContentEditor;
return this.isMarkdownFormat && !this.useContentEditor;
},
disableSubmitButton() {
return !this.content || !this.title || this.contentEditorRenderFailed;
return this.noContent || !this.title || this.contentEditorRenderFailed;
},
isContentEditorActive() {
return this.isMarkdownFormat && this.useContentEditor;
......@@ -188,6 +201,8 @@ export default {
handleFormSubmit() {
if (this.useContentEditor) {
this.content = this.contentEditor.getSerializedContent();
this.trackFormSubmit();
}
this.isDirty = false;
......@@ -236,6 +251,8 @@ export default {
try {
await this.contentEditor.setSerializedContent(this.content);
this.isContentEditorLoading = false;
this.trackContentEditorLoaded();
} catch (e) {
this.contentEditorRenderFailed = true;
}
......@@ -258,6 +275,16 @@ export default {
this.$refs.confirmSwitchToOldEditorModal.show();
}
},
async trackContentEditorLoaded() {
await this.track(CONTENT_EDITOR_LOADED_ACTION);
},
async trackFormSubmit() {
if (this.isContentEditorActive) {
await this.track(SAVED_USING_CONTENT_EDITOR_ACTION);
}
},
},
};
</script>
......
export const WIKI_CONTENT_EDITOR_TRACKING_LABEL = 'wiki_content_editor';
export const CONTENT_EDITOR_LOADED_ACTION = 'content_editor_loaded';
export const SAVED_USING_CONTENT_EDITOR_ACTION = 'saved_using_content_editor';
......@@ -6,8 +6,4 @@ class Projects::WikisController < Projects::ApplicationController
alias_method :container, :project
feature_category :wiki
before_action do
push_frontend_feature_flag(:wiki_content_editor, project, default_enabled: :yaml)
end
end
---
name: wiki_content_editor
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57370
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/255919
group: group::editor
type: development
default_enabled: false
milestone: '13.12'
......@@ -2,15 +2,23 @@ import { GlLoadingIcon, GlModal } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import { mockTracking } from 'helpers/tracking_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import ContentEditor from '~/content_editor/components/content_editor.vue';
import WikiForm from '~/pages/shared/wikis/components/wiki_form.vue';
import {
WIKI_CONTENT_EDITOR_TRACKING_LABEL,
CONTENT_EDITOR_LOADED_ACTION,
SAVED_USING_CONTENT_EDITOR_ACTION,
} from '~/pages/shared/wikis/constants';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
describe('WikiForm', () => {
let wrapper;
let mock;
let trackingSpy;
const findForm = () => wrapper.find('form');
const findTitle = () => wrapper.find('#wiki_title');
......@@ -60,10 +68,7 @@ describe('WikiForm', () => {
path: '/project/path/-/wikis/home',
};
function createWrapper(
persisted = false,
{ pageInfo, glFeatures } = { glFeatures: { wikiContentEditor: false } },
) {
function createWrapper(persisted = false, { pageInfo } = {}) {
wrapper = extendedWrapper(
mount(
WikiForm,
......@@ -79,7 +84,6 @@ describe('WikiForm', () => {
...(persisted ? pageInfoPersisted : pageInfoNew),
...pageInfo,
},
glFeatures,
},
},
{ attachToDocument: true },
......@@ -88,6 +92,7 @@ describe('WikiForm', () => {
}
beforeEach(() => {
trackingSpy = mockTracking(undefined, null, jest.spyOn);
mock = new MockAdapter(axios);
});
......@@ -193,13 +198,21 @@ describe('WikiForm', () => {
expect(e.preventDefault).toHaveBeenCalledTimes(1);
});
it('when form submitted, unsets before unload warning', async () => {
triggerFormSubmit();
describe('form submit', () => {
beforeEach(async () => {
triggerFormSubmit();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
});
const e = dispatchBeforeUnload();
expect(e.preventDefault).not.toHaveBeenCalled();
it('when form submitted, unsets before unload warning', async () => {
const e = dispatchBeforeUnload();
expect(e.preventDefault).not.toHaveBeenCalled();
});
it('does not trigger tracking event', async () => {
expect(trackingSpy).not.toHaveBeenCalled();
});
});
});
......@@ -251,9 +264,9 @@ describe('WikiForm', () => {
);
});
describe('when feature flag wikiContentEditor is enabled', () => {
describe('wiki content editor', () => {
beforeEach(() => {
createWrapper(true, { glFeatures: { wikiContentEditor: true } });
createWrapper(true);
});
it.each`
......@@ -368,6 +381,15 @@ describe('WikiForm', () => {
expect(wrapper.findComponent(ContentEditor).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,
});
});
it('disables the format dropdown', () => {
expect(findFormat().element.getAttribute('disabled')).toBeDefined();
});
......@@ -400,6 +422,16 @@ describe('WikiForm', () => {
});
});
it('triggers tracking event on form submit', async () => {
triggerFormSubmit();
await wrapper.vm.$nextTick();
expect(trackingSpy).toHaveBeenCalledWith(undefined, SAVED_USING_CONTENT_EDITOR_ACTION, {
label: WIKI_CONTENT_EDITOR_TRACKING_LABEL,
});
});
it('updates content from content editor on form submit', async () => {
// old value
expect(findContent().element.value).toBe('My page content');
......
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