Commit d8e8d666 authored by Jacques Erasmus's avatar Jacques Erasmus

Merge branch '230972-convert-epics-autocomplete-from-at-js-to-tribute' into 'master'

Add epic autocompletion to GfmAutocomplete component

See merge request gitlab-org/gitlab!48255
parents 62f75747 6254a0bb
<script>
import Tribute from 'tributejs';
import {
GfmAutocompleteType,
tributeConfig,
} from 'ee_else_ce/vue_shared/components/gfm_autocomplete/utils';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale';
import SidebarMediator from '~/sidebar/sidebar_mediator';
import { GfmAutocompleteType, tributeConfig } from '~/vue_shared/components/gfm_autocomplete/utils';
export default {
errorMessage: __(
......
......@@ -24,7 +24,7 @@ export const tributeConfig = {
[GfmAutocompleteType.Issues]: {
config: {
trigger: '#',
lookup: value => value.iid + value.title,
lookup: value => `${value.iid}${value.title}`,
menuItemTemplate: ({ original }) =>
`<small>${original.reference || original.iid}</small> ${escape(original.title)}`,
selectTemplate: ({ original }) => original.reference || `#${original.iid}`,
......@@ -61,7 +61,7 @@ export const tributeConfig = {
trigger: '@',
fillAttr: 'username',
lookup: value =>
value.type === groupType ? last(value.name.split(' / ')) : value.name + value.username,
value.type === groupType ? last(value.name.split(' / ')) : `${value.name}${value.username}`,
menuItemTemplate: ({ original }) => {
const commonClasses = 'gl-avatar gl-avatar-s24 gl-flex-shrink-0';
const noAvatarClasses = `${commonClasses} gl-rounded-small
......@@ -115,7 +115,7 @@ export const tributeConfig = {
[GfmAutocompleteType.MergeRequests]: {
config: {
trigger: '!',
lookup: value => value.iid + value.title,
lookup: value => `${value.iid}${value.title}`,
menuItemTemplate: ({ original }) =>
`<small>${original.reference || original.iid}</small> ${escape(original.title)}`,
selectTemplate: ({ original }) => original.reference || `!${original.iid}`,
......@@ -135,7 +135,7 @@ export const tributeConfig = {
config: {
trigger: '$',
fillAttr: 'id',
lookup: value => value.id + value.title,
lookup: value => `${value.id}${value.title}`,
menuItemTemplate: ({ original }) => `<small>${original.id}</small> ${escape(original.title)}`,
},
},
......
......@@ -173,7 +173,7 @@ export default {
members: this.enableAutocomplete && !this.glFeatures.tributeAutocomplete,
issues: this.enableAutocomplete && !this.glFeatures.tributeAutocomplete,
mergeRequests: this.enableAutocomplete && !this.glFeatures.tributeAutocomplete,
epics: this.enableAutocomplete,
epics: this.enableAutocomplete && !this.glFeatures.tributeAutocomplete,
milestones: this.enableAutocomplete && !this.glFeatures.tributeAutocomplete,
labels: this.enableAutocomplete && !this.glFeatures.tributeAutocomplete,
snippets: this.enableAutocomplete && !this.glFeatures.tributeAutocomplete,
......
import { escape } from 'lodash';
import {
GfmAutocompleteType as GfmAutocompleteTypeFoss,
tributeConfig as tributeConfigFoss,
} from '~/vue_shared/components/gfm_autocomplete/utils';
export const GfmAutocompleteType = {
...GfmAutocompleteTypeFoss,
Epics: 'epics',
};
export const tributeConfig = {
...tributeConfigFoss,
[GfmAutocompleteType.Epics]: {
config: {
trigger: '&',
fillAttr: 'iid',
lookup: value => `${value.iid}${value.title}`,
menuItemTemplate: ({ original }) =>
`<small>${original.iid}</small> ${escape(original.title)}`,
},
},
};
......@@ -3,10 +3,12 @@
require 'spec_helper'
RSpec.describe 'GFM autocomplete EE', :js do
let(:user) { create(:user, name: '💃speciąl someone💃', username: 'someone.special') }
let(:another_user) { create(:user, name: 'another user', username: 'another.user') }
let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let_it_be(:user) { create(:user, name: '💃speciąl someone💃', username: 'someone.special') }
let_it_be(:another_user) { create(:user, name: 'another user', username: 'another.user') }
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, group: group) }
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:epic) { create(:epic, group: group) }
before do
project.add_maintainer(user)
......@@ -46,6 +48,7 @@ RSpec.describe 'GFM autocomplete EE', :js do
describe 'when tribute_autocomplete feature flag is on' do
before do
stub_licensed_features(epics: true)
stub_feature_flags(tribute_autocomplete: true)
issue_assignee.update!(assignees: [user])
......@@ -72,6 +75,17 @@ RSpec.describe 'GFM autocomplete EE', :js do
expect(users).to have_content(user.username)
expect(users).not_to have_content(another_user.username)
end
it 'shows epics' do
note = find('#note-body')
page.within('.timeline-content-form') do
note.native.send_keys('&')
end
wait_for_requests
expect(find('.tribute-container ul', visible: true).text).to have_content(epic.title)
end
end
end
end
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ee gfm_autocomplete/utils epics config shows the iid and title in the menu item 1`] = `"<small>123456</small> Epic title &lt;script&gt;alert(&#39;hi&#39;)&lt;/script&gt;"`;
import {
GfmAutocompleteType,
tributeConfig,
} from 'ee/vue_shared/components/gfm_autocomplete/utils';
describe('ee gfm_autocomplete/utils', () => {
describe('epics config', () => {
const epicsConfig = tributeConfig[GfmAutocompleteType.Epics].config;
const epic = {
id: null,
iid: 123456,
title: "Epic title <script>alert('hi')</script>",
};
it('uses & as the trigger', () => {
expect(epicsConfig.trigger).toBe('&');
});
it('inserts the iid on autocomplete selection', () => {
expect(epicsConfig.fillAttr).toBe('iid');
});
it('searches using both the iid and title', () => {
expect(epicsConfig.lookup(epic)).toBe(`${epic.iid}${epic.title}`);
});
it('shows the iid and title in the menu item', () => {
expect(epicsConfig.menuItemTemplate({ original: epic })).toMatchSnapshot();
});
});
});
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