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
......@@ -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());
});
......@@ -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',
......
......@@ -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"
......
......@@ -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;
......@@ -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) {
......@@ -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);
});
......@@ -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 = $(
......@@ -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;
......@@ -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
......@@ -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,
}));
}
......@@ -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');
}
......@@ -1422,7 +1422,7 @@ const normalizeNewlines = function(str) {
}
if (note.commands_changes) {
this.handleSlashCommands(note);
this.handleQuickActions(note);
}
$form.trigger('ajax:success', [note]);
......@@ -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();
}
......
......@@ -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 () {
......
......@@ -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>
......
......@@ -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) {
......@@ -35,7 +35,7 @@ export default {
},
},
mounted() {
this.listenForSlashCommands();
this.listenForQuickActions();
},
template: `
<div class="block">
......
......@@ -10,8 +10,8 @@ def note_editable?(note)
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)
......
......@@ -889,7 +889,7 @@ def has_no_commits?
!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
......
......@@ -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
......
class MattermostSlashCommandsService < ChatSlashCommandsService
class MattermostSlashCommandsService < SlashCommandsService
include TriggersHelper
prop_accessor :token
......
class SlackSlashCommandsService < ChatSlashCommandsService
class SlackSlashCommandsService < SlashCommandsService
include TriggersHelper
def title
......
# 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
......@@ -33,10 +33,10 @@ def trigger(params)
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
......
......@@ -10,7 +10,7 @@ def rules
can! :access_api
can! :access_git
can! :receive_notifications
can! :use_slash_commands
can! :use_quick_actions
end
end
end
......@@ -142,9 +142,9 @@ def available_labels
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
......@@ -162,7 +162,7 @@ def create_issuable(issuable, attributes, label_ids:)
end
def create(issuable)
merge_slash_commands_into_params!(issuable)
merge_quick_actions_into_params!(issuable)
filter_params(issuable)
params.delete(:state_event)
......
......@@ -7,7 +7,7 @@ def execute(merge_request)
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)
......@@ -74,9 +74,9 @@ def handle_changes(merge_request, options)
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)
......
......@@ -9,11 +9,11 @@ def execute
# 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?
......@@ -30,7 +30,7 @@ def execute
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
......
module Notes
class SlashCommandsService < BaseService
class QuickActionsService < BaseService
UPDATE_SERVICES = {
'Issue' => Issues::UpdateService,
'MergeRequest' => MergeRequests::UpdateService
......@@ -22,7 +22,7 @@ def supported?(note)
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
......
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(
......@@ -12,11 +12,11 @@ def execute
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)
......@@ -36,10 +36,10 @@ def find_commands_target
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
......@@ -32,7 +32,7 @@ def commands(noteable, type)
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)
......
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 = {}
......@@ -20,7 +20,7 @@ def execute(content, issuable)
# 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
......@@ -32,7 +32,7 @@ def explain(content, issuable)
private
def extractor
Gitlab::SlashCommands::Extractor.new(self.class.command_definitions)
Gitlab::QuickActions::Extractor.new(self.class.command_definitions)
end
desc do
......@@ -71,7 +71,7 @@ def extractor
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]
......
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