Resolve "Drop down filter for project snippets"
This commit is contained in:
parent
16d038da1c
commit
b55c320c89
13 changed files with 72 additions and 8 deletions
|
@ -15,6 +15,7 @@ export const defaultAutocompleteConfig = {
|
|||
epics: true,
|
||||
milestones: true,
|
||||
labels: true,
|
||||
snippets: true,
|
||||
};
|
||||
|
||||
class GfmAutoComplete {
|
||||
|
@ -50,6 +51,7 @@ class GfmAutoComplete {
|
|||
if (this.enableMap.milestones) this.setupMilestones($input);
|
||||
if (this.enableMap.mergeRequests) this.setupMergeRequests($input);
|
||||
if (this.enableMap.labels) this.setupLabels($input);
|
||||
if (this.enableMap.snippets) this.setupSnippets($input);
|
||||
|
||||
// We don't instantiate the quick actions autocomplete for note and issue/MR edit forms
|
||||
$input.filter('[data-supports-quick-actions="true"]').atwho({
|
||||
|
@ -360,6 +362,39 @@ class GfmAutoComplete {
|
|||
});
|
||||
}
|
||||
|
||||
setupSnippets($input) {
|
||||
$input.atwho({
|
||||
at: '$',
|
||||
alias: 'snippets',
|
||||
searchKey: 'search',
|
||||
displayTpl(value) {
|
||||
let tmpl = GfmAutoComplete.Loading.template;
|
||||
if (value.title != null) {
|
||||
tmpl = GfmAutoComplete.Issues.template;
|
||||
}
|
||||
return tmpl;
|
||||
},
|
||||
data: GfmAutoComplete.defaultLoadingData,
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
insertTpl: '${atwho-at}${id}',
|
||||
callbacks: {
|
||||
...this.getDefaultCallbacks(),
|
||||
beforeSave(snippets) {
|
||||
return $.map(snippets, (m) => {
|
||||
if (m.title == null) {
|
||||
return m;
|
||||
}
|
||||
return {
|
||||
id: m.id,
|
||||
title: sanitize(m.title),
|
||||
search: `${m.id} ${m.title}`,
|
||||
};
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
getDefaultCallbacks() {
|
||||
const fetchData = this.fetchData.bind(this);
|
||||
|
||||
|
@ -470,7 +505,7 @@ class GfmAutoComplete {
|
|||
// The below is taken from At.js source
|
||||
// Tweaked to commands to start without a space only if char before is a non-word character
|
||||
// https://github.com/ichord/At.js
|
||||
const atSymbolsWithBar = Object.keys(controllers).join('|');
|
||||
const atSymbolsWithBar = Object.keys(controllers).join('|').replace(/[$]/, '\\$&');
|
||||
const atSymbolsWithoutBar = Object.keys(controllers).join('');
|
||||
const targetSubtext = subtext.split(GfmAutoComplete.regexSubtext).pop();
|
||||
const resultantFlag = flag.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
|
||||
|
@ -497,6 +532,7 @@ GfmAutoComplete.atTypeMap = {
|
|||
'~': 'labels',
|
||||
'%': 'milestones',
|
||||
'/': 'commands',
|
||||
$: 'snippets',
|
||||
};
|
||||
|
||||
// Emoji
|
||||
|
@ -519,7 +555,7 @@ GfmAutoComplete.Labels = {
|
|||
// eslint-disable-next-line no-template-curly-in-string
|
||||
template: '<li><span class="dropdown-label-box" style="background: ${color}"></span> ${title}</li>',
|
||||
};
|
||||
// Issues and MergeRequests
|
||||
// Issues, MergeRequests and Snippets
|
||||
GfmAutoComplete.Issues = {
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
template: '<li><small>${id}</small> ${title}</li>',
|
||||
|
|
|
@ -11,6 +11,7 @@ export default () => {
|
|||
epics: false,
|
||||
milestones: false,
|
||||
labels: false,
|
||||
snippets: false,
|
||||
});
|
||||
new ZenMode(); // eslint-disable-line no-new
|
||||
};
|
||||
|
|
|
@ -15,5 +15,6 @@ export default (initGFM = true) => {
|
|||
epics: initGFM,
|
||||
milestones: initGFM,
|
||||
labels: initGFM,
|
||||
snippets: initGFM,
|
||||
});
|
||||
};
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
epics: this.enableAutocomplete,
|
||||
milestones: this.enableAutocomplete,
|
||||
labels: this.enableAutocomplete,
|
||||
snippets: this.enableAutocomplete,
|
||||
});
|
||||
},
|
||||
beforeDestroy() {
|
||||
|
|
|
@ -27,6 +27,10 @@ class Projects::AutocompleteSourcesController < Projects::ApplicationController
|
|||
render json: @autocomplete_service.commands(target, params[:type])
|
||||
end
|
||||
|
||||
def snippets
|
||||
render json: @autocomplete_service.snippets
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_autocomplete_service
|
||||
|
|
|
@ -292,7 +292,8 @@ module ApplicationHelper
|
|||
mergeRequests: merge_requests_project_autocomplete_sources_path(object),
|
||||
labels: labels_project_autocomplete_sources_path(object, type: noteable_type, type_id: params[:id]),
|
||||
milestones: milestones_project_autocomplete_sources_path(object),
|
||||
commands: commands_project_autocomplete_sources_path(object, type: noteable_type, type_id: params[:id])
|
||||
commands: commands_project_autocomplete_sources_path(object, type: noteable_type, type_id: params[:id]),
|
||||
snippets: snippets_project_autocomplete_sources_path(object)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,6 +29,10 @@ module Projects
|
|||
QuickActions::InterpretService.new(project, current_user).available_commands(noteable)
|
||||
end
|
||||
|
||||
def snippets
|
||||
SnippetsFinder.new(current_user, project: project).execute.select([:id, :title])
|
||||
end
|
||||
|
||||
def labels_as_hash(target)
|
||||
super(target, project_id: project.id, include_ancestor_groups: true)
|
||||
end
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add autocomplete drop down filter for project snippets
|
||||
merge_request: 21458
|
||||
author: Fabian Schneider
|
||||
type: added
|
|
@ -32,6 +32,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
|
|||
get 'labels'
|
||||
get 'milestones'
|
||||
get 'commands'
|
||||
get 'snippets'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ describe 'GFM autocomplete', :js do
|
|||
let(:project) { create(:project) }
|
||||
let(:label) { create(:label, project: project, title: 'special+') }
|
||||
let(:issue) { create(:issue, project: project) }
|
||||
let!(:project_snippet) { create(:project_snippet, project: project, title: 'code snippet') }
|
||||
|
||||
before do
|
||||
project.add_maintainer(user)
|
||||
|
@ -301,6 +302,16 @@ describe 'GFM autocomplete', :js do
|
|||
end
|
||||
end
|
||||
|
||||
it 'shows project snippets' do
|
||||
page.within '.timeline-content-form' do
|
||||
find('#note-body').native.send_keys('$')
|
||||
end
|
||||
|
||||
page.within '.atwho-container' do
|
||||
expect(page).to have_content(project_snippet.title)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def expect_to_wrap(should_wrap, item, note, value)
|
||||
|
|
|
@ -174,9 +174,7 @@ describe ApplicationHelper do
|
|||
|
||||
it 'returns paths for autocomplete_sources_controller' do
|
||||
sources = helper.autocomplete_data_sources(project, noteable_type)
|
||||
|
||||
expect(sources.keys).to match_array([:members, :issues, :mergeRequests, :labels, :milestones, :commands])
|
||||
|
||||
expect(sources.keys).to match_array([:members, :issues, :mergeRequests, :labels, :milestones, :commands, :snippets])
|
||||
sources.keys.each do |key|
|
||||
expect(sources[key]).not_to be_nil
|
||||
end
|
||||
|
|
|
@ -103,7 +103,7 @@ describe('GfmAutoComplete', function () {
|
|||
gfmAutoCompleteCallbacks.matcher.call(context, flag, subtext)
|
||||
);
|
||||
|
||||
const flagsUseDefaultMatcher = ['@', '#', '!', '~', '%'];
|
||||
const flagsUseDefaultMatcher = ['@', '#', '!', '~', '%', '$'];
|
||||
const otherFlags = ['/', ':'];
|
||||
const flags = flagsUseDefaultMatcher.concat(otherFlags);
|
||||
|
||||
|
|
|
@ -133,8 +133,9 @@ describe 'project routing' do
|
|||
# labels_namespace_project_autocomplete_sources_path GET /:project_id/autocomplete_sources/labels(.:format) projects/autocomplete_sources#labels
|
||||
# milestones_namespace_project_autocomplete_sources_path GET /:project_id/autocomplete_sources/milestones(.:format) projects/autocomplete_sources#milestones
|
||||
# commands_namespace_project_autocomplete_sources_path GET /:project_id/autocomplete_sources/commands(.:format) projects/autocomplete_sources#commands
|
||||
# snippets_namespace_project_autocomplete_sources_path GET /:project_id/autocomplete_sources/snippets(.:format) projects/autocomplete_sources#snippets
|
||||
describe Projects::AutocompleteSourcesController, 'routing' do
|
||||
[:members, :issues, :merge_requests, :labels, :milestones, :commands].each do |action|
|
||||
[:members, :issues, :merge_requests, :labels, :milestones, :commands, :snippets].each do |action|
|
||||
it "to ##{action}" do
|
||||
expect(get("/gitlab/gitlabhq/autocomplete_sources/#{action}")).to route_to("projects/autocomplete_sources##{action}", namespace_id: 'gitlab', project_id: 'gitlabhq')
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue