Skip to content
Snippets Groups Projects
Commit ea090291 authored by Eric Eastwood's avatar Eric Eastwood
Browse files

Rename "Slash commands" to "Quick actions"

Fix https://gitlab.com/gitlab-org/gitlab-ce/issues/27070

Deprecate "chat commands" in favor of "slash commands"

We looked for things like:

 - `slash commmand`
 - `slash_command`
 - `slash-command`
 - `SlashCommand`
parent 42aaae99
No related branches found
No related tags found
No related merge requests found
Showing
with 68 additions and 68 deletions
Loading
Loading
@@ -34,7 +34,7 @@ class GfmAutoComplete {
const $input = $(input);
$input.off('focus.setupAtWho').on('focus.setupAtWho', this.setupAtWho.bind(this, $input));
// This triggers at.js again
// Needed for slash commands with suffixes (ex: /label ~)
// Needed for quick actions with suffixes (ex: /label ~)
$input.on('inserted-commands.atwho', $input.trigger.bind($input, 'keyup'));
$input.on('clear-commands-cache.atwho', () => this.clearCache());
});
Loading
Loading
@@ -48,8 +48,8 @@ class GfmAutoComplete {
if (this.enableMap.mergeRequests) this.setupMergeRequests($input);
if (this.enableMap.labels) this.setupLabels($input);
 
// We don't instantiate the slash commands autocomplete for note and issue/MR edit forms
$input.filter('[data-supports-slash-commands="true"]').atwho({
// We don't instantiate the quick actions autocomplete for note and issue/MR edit forms
$input.filter('[data-supports-quick-actions="true"]').atwho({
at: '/',
alias: 'commands',
searchKey: 'search',
Loading
Loading
Loading
Loading
@@ -41,7 +41,7 @@
<textarea
id="issue-description"
class="note-textarea js-gfm-input js-autosize markdown-area"
data-supports-slash-commands="false"
data-supports-quick-actionss="false"
aria-label="Description"
v-model="formState.description"
ref="textarea"
Loading
Loading
Loading
Loading
@@ -32,7 +32,7 @@ const normalizeNewlines = function(str) {
(function() {
this.Notes = (function() {
const MAX_VISIBLE_COMMIT_LIST_COUNT = 3;
const REGEX_SLASH_COMMANDS = /^\/\w+.*$/gm;
const REGEX_QUICK_ACTIONS = /^\/\w+.*$/gm;
 
Notes.interval = null;
 
Loading
Loading
@@ -280,7 +280,7 @@ const normalizeNewlines = function(str) {
return this.initRefresh();
};
 
Notes.prototype.handleSlashCommands = function(noteEntity) {
Notes.prototype.handleQuickActions = function(noteEntity) {
var votesBlock;
if (noteEntity.commands_changes) {
if ('merge' in noteEntity.commands_changes) {
Loading
Loading
@@ -1198,27 +1198,27 @@ const normalizeNewlines = function(str) {
};
 
/**
* Identify if comment has any slash commands
* Identify if comment has any quick actions
*/
Notes.prototype.hasSlashCommands = function(formContent) {
return REGEX_SLASH_COMMANDS.test(formContent);
Notes.prototype.hasQuickActions = function(formContent) {
return REGEX_QUICK_ACTIONS.test(formContent);
};
 
/**
* Remove slash commands and leave comment with pure message
* Remove quick actions and leave comment with pure message
*/
Notes.prototype.stripSlashCommands = function(formContent) {
return formContent.replace(REGEX_SLASH_COMMANDS, '').trim();
Notes.prototype.stripQuickActions = function(formContent) {
return formContent.replace(REGEX_QUICK_ACTIONS, '').trim();
};
 
/**
* Gets appropriate description from slash commands found in provided `formContent`
* Gets appropriate description from quick actions found in provided `formContent`
*/
Notes.prototype.getSlashCommandDescription = function (formContent, availableSlashCommands = []) {
Notes.prototype.getQuickActionDescription = function (formContent, availableQuickActions = []) {
let tempFormContent;
 
// Identify executed slash commands from `formContent`
const executedCommands = availableSlashCommands.filter((command, index) => {
// Identify executed quick actions from `formContent`
const executedCommands = availableQuickActions.filter((command, index) => {
const commandRegex = new RegExp(`/${command.name}`);
return commandRegex.test(formContent);
});
Loading
Loading
@@ -1276,7 +1276,7 @@ const normalizeNewlines = function(str) {
};
 
/**
* Create Placeholder System Note DOM element populated with slash command description
* Create Placeholder System Note DOM element populated with quick action description
*/
Notes.prototype.createPlaceholderSystemNote = function ({ formContent, uniqueId }) {
const $tempNote = $(
Loading
Loading
@@ -1325,7 +1325,7 @@ const normalizeNewlines = function(str) {
const { formData, formContent, formAction } = this.getFormData($form);
let noteUniqueId;
let systemNoteUniqueId;
let hasSlashCommands = false;
let hasQuickActions = false;
let $notesContainer;
let tempFormContent;
 
Loading
Loading
@@ -1344,9 +1344,9 @@ const normalizeNewlines = function(str) {
}
 
tempFormContent = formContent;
if (this.hasSlashCommands(formContent)) {
tempFormContent = this.stripSlashCommands(formContent);
hasSlashCommands = true;
if (this.hasQuickActions(formContent)) {
tempFormContent = this.stripQuickActions(formContent);
hasQuickActions = true;
}
 
// Show placeholder note
Loading
Loading
@@ -1363,10 +1363,10 @@ const normalizeNewlines = function(str) {
}
 
// Show placeholder system note
if (hasSlashCommands) {
if (hasQuickActions) {
systemNoteUniqueId = _.uniqueId('tempSystemNote_');
$notesContainer.append(this.createPlaceholderSystemNote({
formContent: this.getSlashCommandDescription(formContent, AjaxCache.get(gl.GfmAutoComplete.dataSources.commands)),
formContent: this.getQuickActionDescription(formContent, AjaxCache.get(gl.GfmAutoComplete.dataSources.commands)),
uniqueId: systemNoteUniqueId,
}));
}
Loading
Loading
@@ -1388,7 +1388,7 @@ const normalizeNewlines = function(str) {
$notesContainer.find(`#${noteUniqueId}`).remove();
 
// Reset cached commands list when command is applied
if (hasSlashCommands) {
if (hasQuickActions) {
$form.find('textarea.js-note-text').trigger('clear-commands-cache.atwho');
}
 
Loading
Loading
@@ -1422,7 +1422,7 @@ const normalizeNewlines = function(str) {
}
 
if (note.commands_changes) {
this.handleSlashCommands(note);
this.handleQuickActions(note);
}
 
$form.trigger('ajax:success', [note]);
Loading
Loading
@@ -1430,7 +1430,7 @@ const normalizeNewlines = function(str) {
// Submission failed, remove placeholder note and show Flash error message
$notesContainer.find(`#${noteUniqueId}`).remove();
 
if (hasSlashCommands) {
if (hasQuickActions) {
$notesContainer.find(`#${systemNoteUniqueId}`).remove();
}
 
Loading
Loading
Loading
Loading
@@ -3,7 +3,7 @@
// MarkdownPreview
//
// Handles toggling the "Write" and "Preview" tab clicks, rendering the preview
// (including the explanation of slash commands), and showing a warning when
// (including the explanation of quick actions), and showing a warning when
// more than `x` users are referenced.
//
(function () {
Loading
Loading
Loading
Loading
@@ -15,10 +15,10 @@ export default {
<div class="time-tracking-help-state">
<div class="time-tracking-info">
<h4>
Track time with slash commands
Track time with quick actions
</h4>
<p>
Slash commands can be used in the issues description and comment boxes.
Quick actions can be used in the issues description and comment boxes.
</p>
<p>
<code>
Loading
Loading
Loading
Loading
@@ -16,10 +16,10 @@ export default {
'issuable-time-tracker': timeTracker,
},
methods: {
listenForSlashCommands() {
$(document).on('ajax:success', '.gfm-form', this.slashCommandListened);
listenForQuickActions() {
$(document).on('ajax:success', '.gfm-form', this.quickActionListened);
},
slashCommandListened(e, data) {
quickActionListened(e, data) {
const subscribedCommands = ['spend_time', 'time_estimate'];
let changedCommands;
if (data !== undefined) {
Loading
Loading
@@ -35,7 +35,7 @@ export default {
},
},
mounted() {
this.listenForSlashCommands();
this.listenForQuickActions();
},
template: `
<div class="block">
Loading
Loading
Loading
Loading
@@ -10,8 +10,8 @@ module NotesHelper
Ability.can_edit_note?(current_user, note)
end
 
def note_supports_slash_commands?(note)
Notes::SlashCommandsService.supported?(note, current_user)
def note_supports_quick_actions?(note)
Notes::QuickActionsService.supported?(note, current_user)
end
 
def noteable_json(noteable)
Loading
Loading
Loading
Loading
@@ -889,7 +889,7 @@ class MergeRequest < ActiveRecord::Base
!has_commits?
end
 
def mergeable_with_slash_command?(current_user, autocomplete_precheck: false, last_diff_sha: nil)
def mergeable_with_quick_action?(current_user, autocomplete_precheck: false, last_diff_sha: nil)
return false unless can_be_merged_by?(current_user)
 
return true if autocomplete_precheck
Loading
Loading
Loading
Loading
@@ -32,7 +32,7 @@ class Note < ActiveRecord::Base
# Banzai::ObjectRenderer
attr_accessor :user_visible_reference_count
 
# Attribute used to store the attributes that have ben changed by slash commands.
# Attribute used to store the attributes that have ben changed by quick actions.
attr_accessor :commands_changes
 
default_value_for :system, false
Loading
Loading
class MattermostSlashCommandsService < ChatSlashCommandsService
class MattermostSlashCommandsService < SlashCommandsService
include TriggersHelper
 
prop_accessor :token
Loading
Loading
class SlackSlashCommandsService < ChatSlashCommandsService
class SlackSlashCommandsService < SlashCommandsService
include TriggersHelper
 
def title
Loading
Loading
# Base class for Chat services
# This class is not meant to be used directly, but only to inherrit from.
class ChatSlashCommandsService < Service
class SlashCommandsService < Service
default_value_for :category, 'chat'
 
prop_accessor :token
Loading
Loading
@@ -33,10 +33,10 @@ class ChatSlashCommandsService < Service
user = find_chat_user(params)
 
if user
Gitlab::ChatCommands::Command.new(project, user, params).execute
Gitlab::SlashCommands::Command.new(project, user, params).execute
else
url = authorize_chat_name_url(params)
Gitlab::ChatCommands::Presenters::Access.new(url).authorize
Gitlab::SlashCommands::Presenters::Access.new(url).authorize
end
end
 
Loading
Loading
Loading
Loading
@@ -10,7 +10,7 @@ class GlobalPolicy < BasePolicy
can! :access_api
can! :access_git
can! :receive_notifications
can! :use_slash_commands
can! :use_quick_actions
end
end
end
Loading
Loading
@@ -142,9 +142,9 @@ class IssuableBaseService < BaseService
LabelsFinder.new(current_user, project_id: @project.id).execute
end
 
def merge_slash_commands_into_params!(issuable)
def merge_quick_actions_into_params!(issuable)
description, command_params =
SlashCommands::InterpretService.new(project, current_user).
QuickActions::InterpretService.new(project, current_user).
execute(params[:description], issuable)
 
# Avoid a description already set on an issuable to be overwritten by a nil
Loading
Loading
@@ -162,7 +162,7 @@ class IssuableBaseService < BaseService
end
 
def create(issuable)
merge_slash_commands_into_params!(issuable)
merge_quick_actions_into_params!(issuable)
filter_params(issuable)
 
params.delete(:state_event)
Loading
Loading
Loading
Loading
@@ -7,7 +7,7 @@ module MergeRequests
params.except!(:target_project_id)
params.except!(:source_branch)
 
merge_from_slash_command(merge_request) if params[:merge]
merge_from_quick_action(merge_request) if params[:merge]
 
if merge_request.closed_without_fork?
params.except!(:target_branch, :force_remove_source_branch)
Loading
Loading
@@ -74,9 +74,9 @@ module MergeRequests
end
end
 
def merge_from_slash_command(merge_request)
def merge_from_quick_action(merge_request)
last_diff_sha = params.delete(:merge)
return unless merge_request.mergeable_with_slash_command?(current_user, last_diff_sha: last_diff_sha)
return unless merge_request.mergeable_with_quick_action?(current_user, last_diff_sha: last_diff_sha)
 
merge_request.update(merge_error: nil)
 
Loading
Loading
Loading
Loading
@@ -9,11 +9,11 @@ module Notes
# We execute commands (extracted from `params[:note]`) on the noteable
# **before** we save the note because if the note consists of commands
# only, there is no need be create a note!
slash_commands_service = SlashCommandsService.new(project, current_user)
quick_actions_service = QuickActionsService.new(project, current_user)
 
if slash_commands_service.supported?(note)
if quick_actions_service.supported?(note)
options = { merge_request_diff_head_sha: merge_request_diff_head_sha }
content, command_params = slash_commands_service.extract_commands(note, options)
content, command_params = quick_actions_service.extract_commands(note, options)
 
only_commands = content.empty?
 
Loading
Loading
@@ -30,7 +30,7 @@ module Notes
end
 
if command_params.present?
slash_commands_service.execute(command_params, note)
quick_actions_service.execute(command_params, note)
 
# We must add the error after we call #save because errors are reset
# when #save is called
Loading
Loading
module Notes
class SlashCommandsService < BaseService
class QuickActionsService < BaseService
UPDATE_SERVICES = {
'Issue' => Issues::UpdateService,
'MergeRequest' => MergeRequests::UpdateService
Loading
Loading
@@ -22,7 +22,7 @@ module Notes
def extract_commands(note, options = {})
return [note.note, {}] unless supported?(note)
 
SlashCommands::InterpretService.new(project, current_user, options).
QuickActions::InterpretService.new(project, current_user, options).
execute(note.note, note.noteable)
end
 
Loading
Loading
class PreviewMarkdownService < BaseService
def execute
text, commands = explain_slash_commands(params[:text])
text, commands = explain_quick_actions(params[:text])
users = find_user_references(text)
 
success(
Loading
Loading
@@ -12,11 +12,11 @@ class PreviewMarkdownService < BaseService
 
private
 
def explain_slash_commands(text)
def explain_quick_actions(text)
return text, [] unless %w(Issue MergeRequest).include?(commands_target_type)
 
slash_commands_service = SlashCommands::InterpretService.new(project, current_user)
slash_commands_service.explain(text, find_commands_target)
quick_actions_service = QuickActions::InterpretService.new(project, current_user)
quick_actions_service.explain(text, find_commands_target)
end
 
def find_user_references(text)
Loading
Loading
@@ -36,10 +36,10 @@ class PreviewMarkdownService < BaseService
end
 
def commands_target_type
params[:slash_commands_target_type]
params[:quick_actions_target_type]
end
 
def commands_target_id
params[:slash_commands_target_id]
params[:quick_actions_target_id]
end
end
Loading
Loading
@@ -32,7 +32,7 @@ module Projects
issuable: noteable,
current_user: current_user
}
SlashCommands::InterpretService.command_definitions.map do |definition|
QuickActions::InterpretService.command_definitions.map do |definition|
next unless definition.available?(opts)
 
definition.to_h(opts)
Loading
Loading
module SlashCommands
module QuickActions
class InterpretService < BaseService
include Gitlab::SlashCommands::Dsl
include Gitlab::QuickActions::Dsl
 
attr_reader :issuable
 
# Takes a text and interprets the commands that are extracted from it.
# Returns the content without commands, and hash of changes to be applied to a record.
def execute(content, issuable)
return [content, {}] unless current_user.can?(:use_slash_commands)
return [content, {}] unless current_user.can?(:use_quick_actions)
 
@issuable = issuable
@updates = {}
Loading
Loading
@@ -20,7 +20,7 @@ module SlashCommands
# Takes a text and interprets the commands that are extracted from it.
# Returns the content without commands, and array of changes explained.
def explain(content, issuable)
return [content, []] unless current_user.can?(:use_slash_commands)
return [content, []] unless current_user.can?(:use_quick_actions)
 
@issuable = issuable
 
Loading
Loading
@@ -32,7 +32,7 @@ module SlashCommands
private
 
def extractor
Gitlab::SlashCommands::Extractor.new(self.class.command_definitions)
Gitlab::QuickActions::Extractor.new(self.class.command_definitions)
end
 
desc do
Loading
Loading
@@ -71,7 +71,7 @@ module SlashCommands
last_diff_sha = params && params[:merge_request_diff_head_sha]
issuable.is_a?(MergeRequest) &&
issuable.persisted? &&
issuable.mergeable_with_slash_command?(current_user, autocomplete_precheck: !last_diff_sha, last_diff_sha: last_diff_sha)
issuable.mergeable_with_quick_action?(current_user, autocomplete_precheck: !last_diff_sha, last_diff_sha: last_diff_sha)
end
command :merge do
@updates[:merge] = params[:merge_request_diff_head_sha]
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment