diff options
author | Eric Eastwood <contact@ericeastwood.com> | 2017-05-31 08:50:53 +0300 |
---|---|---|
committer | Eric Eastwood <contact@ericeastwood.com> | 2017-06-15 17:01:56 +0300 |
commit | ea090291bba6bb665b3631cc5a2659e6673a6959 (patch) | |
tree | 1daf4c15aee8afc0eebef94a345eb077d0390632 /lib/gitlab/slash_commands/presenters | |
parent | 42aaae9916b7b76da968579fcc722067947df018 (diff) |
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`
Diffstat (limited to 'lib/gitlab/slash_commands/presenters')
-rw-r--r-- | lib/gitlab/slash_commands/presenters/access.rb | 40 | ||||
-rw-r--r-- | lib/gitlab/slash_commands/presenters/base.rb | 77 | ||||
-rw-r--r-- | lib/gitlab/slash_commands/presenters/deploy.rb | 21 | ||||
-rw-r--r-- | lib/gitlab/slash_commands/presenters/help.rb | 27 | ||||
-rw-r--r-- | lib/gitlab/slash_commands/presenters/issue_base.rb | 43 | ||||
-rw-r--r-- | lib/gitlab/slash_commands/presenters/issue_new.rb | 50 | ||||
-rw-r--r-- | lib/gitlab/slash_commands/presenters/issue_search.rb | 47 | ||||
-rw-r--r-- | lib/gitlab/slash_commands/presenters/issue_show.rb | 61 |
8 files changed, 366 insertions, 0 deletions
diff --git a/lib/gitlab/slash_commands/presenters/access.rb b/lib/gitlab/slash_commands/presenters/access.rb new file mode 100644 index 00000000000..1a817eb735b --- /dev/null +++ b/lib/gitlab/slash_commands/presenters/access.rb @@ -0,0 +1,40 @@ +module Gitlab + module SlashCommands + module Presenters + class Access < Presenters::Base + def access_denied + ephemeral_response(text: "Whoops! This action is not allowed. This incident will be [reported](https://xkcd.com/838/).") + end + + def not_found + ephemeral_response(text: "404 not found! GitLab couldn't find what you were looking for! :boom:") + end + + def authorize + message = + if @resource + ":wave: Hi there! Before I do anything for you, please [connect your GitLab account](#{@resource})." + else + ":sweat_smile: Couldn't identify you, nor can I autorize you!" + end + + ephemeral_response(text: message) + end + + def unknown_command(commands) + ephemeral_response(text: help_message(trigger)) + end + + private + + def help_message(trigger) + header_with_list("Command not found, these are the commands you can use", full_commands(trigger)) + end + + def full_commands(trigger) + @resource.map { |command| "#{trigger} #{command.help_message}" } + end + end + end + end +end diff --git a/lib/gitlab/slash_commands/presenters/base.rb b/lib/gitlab/slash_commands/presenters/base.rb new file mode 100644 index 00000000000..27696436574 --- /dev/null +++ b/lib/gitlab/slash_commands/presenters/base.rb @@ -0,0 +1,77 @@ +module Gitlab + module SlashCommands + module Presenters + class Base + include Gitlab::Routing.url_helpers + + def initialize(resource = nil) + @resource = resource + end + + def display_errors + message = header_with_list("The action was not successful, because:", @resource.errors.full_messages) + + ephemeral_response(text: message) + end + + private + + def header_with_list(header, items) + message = [header] + + items.each do |item| + message << "- #{item}" + end + + message.join("\n") + end + + def ephemeral_response(message) + response = { + response_type: :ephemeral, + status: 200 + }.merge(message) + + format_response(response) + end + + def in_channel_response(message) + response = { + response_type: :in_channel, + status: 200 + }.merge(message) + + format_response(response) + end + + def format_response(response) + response[:text] = format(response[:text]) if response.key?(:text) + + if response.key?(:attachments) + response[:attachments].each do |attachment| + attachment[:pretext] = format(attachment[:pretext]) if attachment[:pretext] + attachment[:text] = format(attachment[:text]) if attachment[:text] + end + end + + response + end + + # Convert Markdown to slacks format + def format(string) + Slack::Notifier::LinkFormatter.format(string) + end + + def resource_url + url_for( + [ + @resource.project.namespace.becomes(Namespace), + @resource.project, + @resource + ] + ) + end + end + end + end +end diff --git a/lib/gitlab/slash_commands/presenters/deploy.rb b/lib/gitlab/slash_commands/presenters/deploy.rb new file mode 100644 index 00000000000..b8dc77bd37b --- /dev/null +++ b/lib/gitlab/slash_commands/presenters/deploy.rb @@ -0,0 +1,21 @@ +module Gitlab + module SlashCommands + module Presenters + class Deploy < Presenters::Base + def present(from, to) + message = "Deployment started from #{from} to #{to}. [Follow its progress](#{resource_url})." + + in_channel_response(text: message) + end + + def no_actions + ephemeral_response(text: "No action found to be executed") + end + + def too_many_actions + ephemeral_response(text: "Too many actions defined") + end + end + end + end +end diff --git a/lib/gitlab/slash_commands/presenters/help.rb b/lib/gitlab/slash_commands/presenters/help.rb new file mode 100644 index 00000000000..ea611a4d629 --- /dev/null +++ b/lib/gitlab/slash_commands/presenters/help.rb @@ -0,0 +1,27 @@ +module Gitlab + module SlashCommands + module Presenters + class Help < Presenters::Base + def present(trigger, text) + ephemeral_response(text: help_message(trigger, text)) + end + + private + + def help_message(trigger, text) + return "No commands available :thinking_face:" unless @resource.present? + + if text.start_with?('help') + header_with_list("Available commands", full_commands(trigger)) + else + header_with_list("Unknown command, these commands are available", full_commands(trigger)) + end + end + + def full_commands(trigger) + @resource.map { |command| "#{trigger} #{command.help_message}" } + end + end + end + end +end diff --git a/lib/gitlab/slash_commands/presenters/issue_base.rb b/lib/gitlab/slash_commands/presenters/issue_base.rb new file mode 100644 index 00000000000..341f2aabdd0 --- /dev/null +++ b/lib/gitlab/slash_commands/presenters/issue_base.rb @@ -0,0 +1,43 @@ +module Gitlab + module SlashCommands + module Presenters + module IssueBase + def color(issuable) + issuable.open? ? '#38ae67' : '#d22852' + end + + def status_text(issuable) + issuable.open? ? 'Open' : 'Closed' + end + + def project + @resource.project + end + + def author + @resource.author + end + + def fields + [ + { + title: "Assignee", + value: @resource.assignees.any? ? @resource.assignees.first.name : "_None_", + short: true + }, + { + title: "Milestone", + value: @resource.milestone ? @resource.milestone.title : "_None_", + short: true + }, + { + title: "Labels", + value: @resource.labels.any? ? @resource.label_names.join(', ') : "_None_", + short: true + } + ] + end + end + end + end +end diff --git a/lib/gitlab/slash_commands/presenters/issue_new.rb b/lib/gitlab/slash_commands/presenters/issue_new.rb new file mode 100644 index 00000000000..86490a39cc1 --- /dev/null +++ b/lib/gitlab/slash_commands/presenters/issue_new.rb @@ -0,0 +1,50 @@ +module Gitlab + module SlashCommands + module Presenters + class IssueNew < Presenters::Base + include Presenters::IssueBase + + def present + in_channel_response(new_issue) + end + + private + + def new_issue + { + attachments: [ + { + title: "#{@resource.title} · #{@resource.to_reference}", + title_link: resource_url, + author_name: author.name, + author_icon: author.avatar_url, + fallback: "New issue #{@resource.to_reference}: #{@resource.title}", + pretext: pretext, + color: color(@resource), + fields: fields, + mrkdwn_in: [ + :title, + :pretext, + :text, + :fields + ] + } + ] + } + end + + def pretext + "I created an issue on #{author_profile_link}'s behalf: **#{@resource.to_reference}** in #{project_link}" + end + + def project_link + "[#{project.name_with_namespace}](#{project.web_url})" + end + + def author_profile_link + "[#{author.to_reference}](#{url_for(author)})" + end + end + end + end +end diff --git a/lib/gitlab/slash_commands/presenters/issue_search.rb b/lib/gitlab/slash_commands/presenters/issue_search.rb new file mode 100644 index 00000000000..4e27d668685 --- /dev/null +++ b/lib/gitlab/slash_commands/presenters/issue_search.rb @@ -0,0 +1,47 @@ +module Gitlab + module SlashCommands + module Presenters + class IssueSearch < Presenters::Base + include Presenters::IssueBase + + def present + text = if @resource.count >= 5 + "Here are the first 5 issues I found:" + elsif @resource.one? + "Here is the only issue I found:" + else + "Here are the #{@resource.count} issues I found:" + end + + ephemeral_response(text: text, attachments: attachments) + end + + private + + def attachments + @resource.map do |issue| + url = "[#{issue.to_reference}](#{url_for([namespace, project, issue])})" + + { + color: color(issue), + fallback: "#{issue.to_reference} #{issue.title}", + text: "#{url} · #{issue.title} (#{status_text(issue)})", + + mrkdwn_in: [ + :text + ] + } + end + end + + def project + @project ||= @resource.first.project + end + + def namespace + @namespace ||= project.namespace.becomes(Namespace) + end + end + end + end +end diff --git a/lib/gitlab/slash_commands/presenters/issue_show.rb b/lib/gitlab/slash_commands/presenters/issue_show.rb new file mode 100644 index 00000000000..c99316df667 --- /dev/null +++ b/lib/gitlab/slash_commands/presenters/issue_show.rb @@ -0,0 +1,61 @@ +module Gitlab + module SlashCommands + module Presenters + class IssueShow < Presenters::Base + include Presenters::IssueBase + + def present + if @resource.confidential? + ephemeral_response(show_issue) + else + in_channel_response(show_issue) + end + end + + private + + def show_issue + { + attachments: [ + { + title: "#{@resource.title} · #{@resource.to_reference}", + title_link: resource_url, + author_name: author.name, + author_icon: author.avatar_url, + fallback: "Issue #{@resource.to_reference}: #{@resource.title}", + pretext: pretext, + text: text, + color: color(@resource), + fields: fields, + mrkdwn_in: [ + :pretext, + :text, + :fields + ] + } + ] + } + end + + def text + message = "**#{status_text(@resource)}**" + + if @resource.upvotes.zero? && @resource.downvotes.zero? && @resource.user_notes_count.zero? + return message + end + + message << " · " + message << ":+1: #{@resource.upvotes} " unless @resource.upvotes.zero? + message << ":-1: #{@resource.downvotes} " unless @resource.downvotes.zero? + message << ":speech_balloon: #{@resource.user_notes_count}" unless @resource.user_notes_count.zero? + + message + end + + def pretext + "Issue *#{@resource.to_reference}* from #{project.name_with_namespace}" + end + end + end + end +end |