slack-ruby-block-kit 0.7.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +27 -0
  3. data/.rubocop.yml +19 -0
  4. data/.rubocop_todo.yml +10 -0
  5. data/CHANGELOG.md +79 -0
  6. data/Gemfile +3 -1
  7. data/Gemfile.lock +25 -14
  8. data/README.md +1 -1
  9. data/lib/slack/block_kit.rb +44 -2
  10. data/lib/slack/block_kit/composition/confirmation_dialog.rb +16 -0
  11. data/lib/slack/block_kit/composition/conversation_filter.rb +33 -0
  12. data/lib/slack/block_kit/composition/option.rb +6 -1
  13. data/lib/slack/block_kit/composition/option_group.rb +2 -2
  14. data/lib/slack/block_kit/element/button.rb +3 -11
  15. data/lib/slack/block_kit/element/channels_select.rb +3 -11
  16. data/lib/slack/block_kit/element/checkboxes.rb +53 -0
  17. data/lib/slack/block_kit/element/conversations_select.rb +13 -7
  18. data/lib/slack/block_kit/element/date_picker.rb +3 -9
  19. data/lib/slack/block_kit/element/external_select.rb +3 -12
  20. data/lib/slack/block_kit/element/multi_channels_select.rb +5 -14
  21. data/lib/slack/block_kit/element/multi_conversations_select.rb +16 -11
  22. data/lib/slack/block_kit/element/multi_external_select.rb +5 -14
  23. data/lib/slack/block_kit/element/multi_static_select.rb +18 -25
  24. data/lib/slack/block_kit/element/multi_users_select.rb +5 -14
  25. data/lib/slack/block_kit/element/overflow_menu.rb +4 -11
  26. data/lib/slack/block_kit/element/radio_buttons.rb +53 -0
  27. data/lib/slack/block_kit/element/static_select.rb +20 -25
  28. data/lib/slack/block_kit/element/users_select.rb +3 -11
  29. data/lib/slack/block_kit/layout/header.rb +29 -0
  30. data/lib/slack/block_kit/layout/image.rb +1 -4
  31. data/lib/slack/block_kit/layout/section.rb +21 -1
  32. data/lib/slack/block_kit/version.rb +7 -0
  33. data/lib/slack/surfaces/home.rb +35 -0
  34. data/lib/slack/surfaces/message.rb +34 -0
  35. data/lib/slack/surfaces/modal.rb +76 -0
  36. data/slack-ruby-block-kit.gemspec +1 -8
  37. metadata +17 -9
  38. data/.circleci/config.yml +0 -49
@@ -15,14 +15,15 @@ module Slack
15
15
  #
16
16
  # https://api.slack.com/reference/messaging/block-elements#overflow
17
17
  class OverflowMenu
18
+ include Composition::ConfirmationDialog::Confirmable
19
+
18
20
  TYPE = 'overflow'
19
21
 
20
- attr_accessor :options, :confirm
22
+ attr_accessor :options
21
23
 
22
24
  def initialize(action_id:)
23
25
  @action_id = action_id
24
26
  @options = []
25
- @confirm = nil
26
27
 
27
28
  yield(self) if block_given?
28
29
  end
@@ -38,20 +39,12 @@ module Slack
38
39
  self
39
40
  end
40
41
 
41
- def confirmation_dialog
42
- @confirm = Composition::ConfirmationDialog.new
43
-
44
- yield(@confirm) if block_given?
45
-
46
- self
47
- end
48
-
49
42
  def as_json(*)
50
43
  {
51
44
  type: TYPE,
52
45
  action_id: @action_id,
53
46
  options: @options.map(&:as_json),
54
- confirm: @confirm&.as_json
47
+ confirm: confirm&.as_json
55
48
  }.compact
56
49
  end
57
50
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Element
6
+ # A radio button group that allows a user to choose one item from a list of possible options.
7
+ #
8
+ # https://api.slack.com/reference/messaging/block-elements#radio
9
+ class RadioButtons
10
+ include Composition::ConfirmationDialog::Confirmable
11
+
12
+ TYPE = 'radio_buttons'
13
+
14
+ attr_accessor :options
15
+
16
+ def initialize(action_id:)
17
+ @action_id = action_id
18
+ @options = []
19
+
20
+ yield(self) if block_given?
21
+ end
22
+
23
+ def option(value:, text:, initial: false)
24
+ option = Composition::Option.new(
25
+ value: value,
26
+ text: text,
27
+ initial: initial
28
+ )
29
+
30
+ @options << option
31
+
32
+ self
33
+ end
34
+
35
+ def as_json(*)
36
+ {
37
+ type: TYPE,
38
+ action_id: @action_id,
39
+ options: @options.map(&:as_json),
40
+ initial_option: initial_option&.as_json,
41
+ confirm: confirm&.as_json
42
+ }.compact
43
+ end
44
+
45
+ private
46
+
47
+ def initial_option
48
+ @options&.find(&:initial?)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -13,9 +13,11 @@ module Slack
13
13
  #
14
14
  # https://api.slack.com/reference/messaging/block-elements#static-select
15
15
  class StaticSelect
16
+ include Composition::ConfirmationDialog::Confirmable
17
+
16
18
  TYPE = 'static_select'
17
19
 
18
- attr_accessor :confirm, :options, :option_groups, :initial_option
20
+ attr_accessor :options, :option_groups
19
21
 
20
22
  def initialize(placeholder:, action_id:, emoji: nil)
21
23
  @placeholder = Composition::PlainText.new(text: placeholder, emoji: emoji)
@@ -24,20 +26,13 @@ module Slack
24
26
  yield(self) if block_given?
25
27
  end
26
28
 
27
- def confirmation_dialog
28
- @confirm = Composition::ConfirmationDialog.new
29
-
30
- yield(@confirm) if block_given?
31
-
32
- self
33
- end
34
-
35
- def option(value:, text:, emoji: nil)
29
+ def option(value:, text:, initial: false, emoji: nil)
36
30
  @options ||= []
37
31
  @options << Composition::Option.new(
38
32
  value: value,
39
33
  text: text,
40
- emoji: emoji
34
+ emoji: emoji,
35
+ initial: initial
41
36
  )
42
37
 
43
38
  self
@@ -54,27 +49,27 @@ module Slack
54
49
  self
55
50
  end
56
51
 
57
- def initial(value:, text:, emoji: nil)
58
- @initial_option = Composition::Option.new(
59
- value: value,
60
- text: text,
61
- emoji: emoji
62
- )
63
-
64
- self
65
- end
66
-
67
52
  def as_json(*)
68
53
  {
69
54
  type: TYPE,
70
55
  placeholder: @placeholder.as_json,
71
56
  action_id: @action_id,
72
- options: @options&.map(&:as_json),
73
- option_groups: @option_groups&.map(&:as_json),
74
- initial_option: @initial_option&.as_json,
75
- confirm: @confirm&.as_json
57
+ options: options&.map(&:as_json),
58
+ option_groups: option_groups&.map(&:as_json),
59
+ initial_option: initial_option&.as_json,
60
+ confirm: confirm&.as_json
76
61
  }.compact
77
62
  end
63
+
64
+ private
65
+
66
+ def initial_option
67
+ opts = options || option_groups&.flat_map(&:options)
68
+
69
+ return unless opts
70
+
71
+ opts.find(&:initial?)
72
+ end
78
73
  end
79
74
  end
80
75
  end
@@ -13,9 +13,9 @@ module Slack
13
13
  #
14
14
  # https://api.slack.com/reference/messaging/block-elements#users-select
15
15
  class UsersSelect
16
- TYPE = 'users_select'
16
+ include Composition::ConfirmationDialog::Confirmable
17
17
 
18
- attr_accessor :confirm
18
+ TYPE = 'users_select'
19
19
 
20
20
  def initialize(placeholder:, action_id:, initial: nil, emoji: nil)
21
21
  @placeholder = Composition::PlainText.new(text: placeholder, emoji: emoji)
@@ -25,21 +25,13 @@ module Slack
25
25
  yield(self) if block_given?
26
26
  end
27
27
 
28
- def confirmation_dialog
29
- @confirm = Composition::ConfirmationDialog.new
30
-
31
- yield(@confirm) if block_given?
32
-
33
- self
34
- end
35
-
36
28
  def as_json(*)
37
29
  {
38
30
  type: TYPE,
39
31
  placeholder: @placeholder.as_json,
40
32
  action_id: @action_id,
41
33
  initial_user: @initial_user,
42
- confirm: @confirm&.as_json
34
+ confirm: confirm&.as_json
43
35
  }.compact
44
36
  end
45
37
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Layout
6
+ # A header is a plain-text block that displays in a larger, bold font.
7
+ # Use it to delineate between different groups of content in your app's
8
+ # surfaces.
9
+ #
10
+ # https://api.slack.com/reference/block-kit/blocks#header
11
+ class Header
12
+ TYPE = 'header'
13
+
14
+ def initialize(text:, block_id: nil, emoji: nil)
15
+ @text = Composition::PlainText.new(text: text, emoji: emoji)
16
+ @block_id = block_id
17
+ end
18
+
19
+ def as_json(*)
20
+ {
21
+ type: TYPE,
22
+ text: @text.as_json,
23
+ block_id: @block_id
24
+ }.compact
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -13,10 +13,7 @@ module Slack
13
13
  @image_url = url
14
14
  @alt_text = alt_text
15
15
  @block_id = block_id
16
-
17
- return unless title
18
-
19
- @title = Composition::PlainText.new(
16
+ @title = title && Composition::PlainText.new(
20
17
  text: title,
21
18
  emoji: emoji
22
19
  )
@@ -156,8 +156,28 @@ module Slack
156
156
  accessorise(element)
157
157
  end
158
158
 
159
+ def checkboxes(action_id:)
160
+ element = Element::Checkboxes.new(
161
+ action_id: action_id
162
+ )
163
+
164
+ yield(element) if block_given?
165
+
166
+ accessorise(element)
167
+ end
168
+
169
+ def radio_buttons(action_id:)
170
+ element = Element::RadioButtons.new(
171
+ action_id: action_id
172
+ )
173
+
174
+ yield(element) if block_given?
175
+
176
+ accessorise(element)
177
+ end
178
+
159
179
  def image(url:, alt_text:)
160
- accessorize(Element::Image.new(image_url: url, alt_text: alt_text))
180
+ accessorise(Element::Image.new(image_url: url, alt_text: alt_text))
161
181
  end
162
182
 
163
183
  def accessorise(element)
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ VERSION = '0.12.0'
6
+ end
7
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module Surfaces
5
+ # The Home tab is a persistent, yet dynamic interface
6
+ # for apps that lives within the App Home.
7
+ #
8
+ # https://api.slack.com/surfaces#tabs
9
+ # https://api.slack.com/reference/surfaces/views
10
+ class Home
11
+ TYPE = 'home'
12
+
13
+ def initialize(blocks: nil,
14
+ private_metadata: nil, callback_id: nil, external_id: nil)
15
+ @blocks = blocks || Slack::BlockKit::Blocks.new
16
+
17
+ @private_metadata = private_metadata
18
+ @callback_id = callback_id
19
+ @external_id = external_id
20
+ end
21
+
22
+ attr_reader :blocks
23
+
24
+ def as_json(*)
25
+ {
26
+ type: TYPE,
27
+ blocks: @blocks.as_json,
28
+ private_metadata: @private_metadata,
29
+ callback_id: @callback_id,
30
+ external_id: @external_id
31
+ }.compact
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module Surfaces
5
+ # App-published messages are dynamic yet transient spaces.
6
+ # They allow users to complete workflows among their Slack conversations.
7
+ #
8
+ # https://api.slack.com/surfaces#messages
9
+ # https://api.slack.com/messaging/composing#complex_layouts
10
+ class Message
11
+ TYPE = 'message'
12
+
13
+ def initialize(blocks: nil, text: nil, channel: nil, thread_ts: nil, as_user: nil)
14
+ @blocks = blocks || Slack::BlockKit::Blocks.new
15
+ @channel = channel
16
+ @thread_ts = thread_ts
17
+ @as_user = as_user
18
+ @text = text
19
+ end
20
+
21
+ attr_reader :blocks
22
+
23
+ def as_json(*)
24
+ {
25
+ channel: @channel,
26
+ thread_ts: @thread_ts,
27
+ as_user: @as_user,
28
+ text: @text,
29
+ blocks: @blocks.as_json
30
+ }.compact
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module Surfaces
5
+ # Modals provide focused spaces ideal for requesting and collecting data from users,
6
+ # or temporarily displaying dynamic and interactive information.
7
+ #
8
+ # https://api.slack.com/surfaces#modals
9
+ # https://api.slack.com/reference/surfaces/views
10
+ #
11
+ # @param title [String] title is required. Must be set as an initial argument
12
+ # or using #title for detail setup
13
+ #
14
+ class Modal
15
+ TYPE = 'modal'
16
+
17
+ def initialize(
18
+ title: nil,
19
+ blocks: nil,
20
+ private_metadata: nil,
21
+ callback_id: nil,
22
+ external_id: nil,
23
+ clear_on_close: nil,
24
+ notify_on_close: nil
25
+ )
26
+ @blocks = blocks || Slack::BlockKit::Blocks.new
27
+
28
+ @private_metadata = private_metadata
29
+ @callback_id = callback_id
30
+ @external_id = external_id
31
+
32
+ @clear_on_close = clear_on_close
33
+ @notify_on_close = notify_on_close
34
+
35
+ @title = Slack::BlockKit::Composition::PlainText.new(text: title) if title
36
+
37
+ @close, @submit = nil
38
+ end
39
+
40
+ attr_reader :blocks
41
+
42
+ def title(text:, emoji: nil)
43
+ @title = Slack::BlockKit::Composition::PlainText.new(text: text, emoji: emoji)
44
+
45
+ self
46
+ end
47
+
48
+ def close(text:, emoji: nil)
49
+ @close = Slack::BlockKit::Composition::PlainText.new(text: text, emoji: emoji)
50
+
51
+ self
52
+ end
53
+
54
+ def submit(text:, emoji: nil)
55
+ @submit = Slack::BlockKit::Composition::PlainText.new(text: text, emoji: emoji)
56
+
57
+ self
58
+ end
59
+
60
+ def as_json(*) # rubocop:disable Metrics/MethodLength
61
+ {
62
+ type: TYPE,
63
+ blocks: @blocks.as_json,
64
+ title: @title&.as_json,
65
+ close: @close&.as_json,
66
+ submit: @submit&.as_json,
67
+ clear_on_close: @clear_on_close,
68
+ notify_on_close: @notify_on_close,
69
+ private_metadata: @private_metadata,
70
+ callback_id: @callback_id,
71
+ external_id: @external_id
72
+ }.compact
73
+ end
74
+ end
75
+ end
76
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  lib = File.expand_path('lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'slack-ruby-block-kit'
5
+ require 'slack/block_kit/version'
6
6
 
7
7
  Gem::Specification.new do |spec|
8
8
  spec.name = 'slack-ruby-block-kit'
@@ -13,13 +13,6 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = 'https://github.com/CGA1123/slack-ruby-block-kit'
14
14
  spec.license = 'MIT'
15
15
 
16
- if spec.respond_to?(:metadata)
17
- spec.metadata['allowed_push_host'] = 'https://rubygems.org'
18
- else
19
- raise 'RubyGems 2.0 or newer is required to protect against ' \
20
- 'public gem pushes.'
21
- end
22
-
23
16
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
17
  `git ls-files -z`
25
18
  .split("\x0")