slack-ruby-block-kit 0.10.0 → 0.14.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.deepsource.toml +15 -0
  3. data/.github/workflows/ci.yml +33 -0
  4. data/.rubocop.yml +19 -2
  5. data/CHANGELOG.md +65 -3
  6. data/Gemfile +13 -1
  7. data/Gemfile.lock +66 -43
  8. data/README.md +3 -1
  9. data/lib/slack/block_kit.rb +2 -2
  10. data/lib/slack/block_kit/blocks.rb +18 -0
  11. data/lib/slack/block_kit/composition/confirmation_dialog.rb +16 -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 +15 -26
  17. data/lib/slack/block_kit/element/conversations_select.rb +3 -11
  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 +3 -12
  21. data/lib/slack/block_kit/element/multi_conversations_select.rb +3 -12
  22. data/lib/slack/block_kit/element/multi_external_select.rb +3 -12
  23. data/lib/slack/block_kit/element/multi_static_select.rb +18 -26
  24. data/lib/slack/block_kit/element/multi_users_select.rb +3 -12
  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/timepicker.rb +49 -0
  29. data/lib/slack/block_kit/element/users_select.rb +3 -11
  30. data/lib/slack/block_kit/layout/header.rb +29 -0
  31. data/lib/slack/block_kit/layout/input.rb +196 -3
  32. data/lib/slack/block_kit/layout/section.rb +11 -4
  33. data/lib/slack/block_kit/version.rb +7 -0
  34. data/slack-ruby-block-kit.gemspec +1 -18
  35. metadata +11 -134
  36. data/.circleci/config.yml +0 -49
  37. data/.rubocop_todo.yml +0 -40
@@ -13,35 +13,26 @@ module Slack
13
13
  #
14
14
  # https://api.slack.com/reference/block-kit/block-elements#users_multi_select
15
15
  class MultiUsersSelect
16
- TYPE = 'multi_users_select'
16
+ include Composition::ConfirmationDialog::Confirmable
17
17
 
18
- attr_accessor :confirm
18
+ TYPE = 'multi_users_select'
19
19
 
20
20
  def initialize(placeholder:, action_id:, initial: nil, emoji: nil, max_selected_items: nil)
21
21
  @placeholder = Composition::PlainText.new(text: placeholder, emoji: emoji)
22
22
  @action_id = action_id
23
23
  @initial_users = initial
24
- @confirm = nil
25
24
  @max_selected_items = max_selected_items
26
25
 
27
26
  yield(self) if block_given?
28
27
  end
29
28
 
30
- def confirmation_dialog
31
- @confirm = Composition::ConfirmationDialog.new
32
-
33
- yield(@confirm) if block_given?
34
-
35
- self
36
- end
37
-
38
29
  def as_json(*)
39
30
  {
40
31
  type: TYPE,
41
32
  placeholder: @placeholder.as_json,
42
33
  action_id: @action_id,
43
34
  initial_users: @initial_users,
44
- confirm: @confirm&.as_json,
35
+ confirm: confirm&.as_json,
45
36
  max_selected_items: @max_selected_items
46
37
  }.compact
47
38
  end
@@ -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
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Slack
4
+ module BlockKit
5
+ module Element
6
+ # An element which allows selection of a time of day.
7
+ #
8
+ # On desktop clients, this time picker will take the form of a dropdown
9
+ # list with free-text entry for precise choices. On mobile clients, the
10
+ # time picker will use native time picker UIs.
11
+ #
12
+ # https://api.slack.com/reference/block-kit/block-elements#timepicker
13
+ class Timepicker
14
+ include Composition::ConfirmationDialog::Confirmable
15
+
16
+ TYPE = 'timepicker'
17
+
18
+ def initialize(action_id:)
19
+ @placeholder, @initial_time = nil
20
+ @action_id = action_id
21
+
22
+ yield(self) if block_given?
23
+ end
24
+
25
+ def placeholder(text:, emoji: nil)
26
+ @placeholder = Composition::PlainText.new(text: text, emoji: emoji)
27
+
28
+ self
29
+ end
30
+
31
+ def initial_time(time_str)
32
+ @initial_time = time_str
33
+
34
+ self
35
+ end
36
+
37
+ def as_json(*)
38
+ {
39
+ type: TYPE,
40
+ action_id: @action_id,
41
+ placeholder: @placeholder&.as_json,
42
+ initial_time: @initial_time,
43
+ confirm: confirm&.as_json
44
+ }.compact
45
+ end
46
+ end
47
+ end
48
+ end
49
+ 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
@@ -4,8 +4,8 @@ module Slack
4
4
  module BlockKit
5
5
  module Layout
6
6
  # A block that collects information from users - it can hold a plain-text
7
- # input element, a select menu element, a multi-select menu element, or a
8
- # datepicker.
7
+ # input element, a checkbox element, a radio button element,
8
+ # a select menu element, a multi-select menu element, or a datepicker.
9
9
  #
10
10
  # https://api.slack.com/reference/block-kit/blocks#input
11
11
  class Input
@@ -15,7 +15,7 @@ module Slack
15
15
 
16
16
  def initialize(
17
17
  label:,
18
- element:,
18
+ element: nil,
19
19
  block_id: nil,
20
20
  hint: nil,
21
21
  optional: nil,
@@ -28,6 +28,199 @@ module Slack
28
28
  @element = element
29
29
  end
30
30
 
31
+ def conversation_select(placeholder:, action_id:, initial: nil, emoji: nil)
32
+ @element = Element::ConversationsSelect.new(
33
+ placeholder: placeholder,
34
+ action_id: action_id,
35
+ initial: initial,
36
+ emoji: emoji
37
+ )
38
+
39
+ yield(@element) if block_given?
40
+
41
+ self
42
+ end
43
+
44
+ def multi_conversations_select(placeholder:, action_id:, initial: nil, emoji: nil, max_selected_items: nil)
45
+ @element = Element::MultiConversationsSelect.new(
46
+ placeholder: placeholder,
47
+ action_id: action_id,
48
+ initial: initial,
49
+ emoji: emoji,
50
+ max_selected_items: max_selected_items
51
+ )
52
+
53
+ yield(@element) if block_given?
54
+
55
+ self
56
+ end
57
+
58
+ def channels_select(placeholder:, action_id:, initial: nil, emoji: nil)
59
+ @element = Element::ChannelsSelect.new(
60
+ placeholder: placeholder,
61
+ action_id: action_id,
62
+ initial: initial,
63
+ emoji: emoji
64
+ )
65
+
66
+ yield(@element) if block_given?
67
+
68
+ self
69
+ end
70
+
71
+ def checkboxes(action_id:)
72
+ @element = Element::Checkboxes.new(action_id: action_id)
73
+
74
+ yield(@element) if block_given?
75
+
76
+ self
77
+ end
78
+
79
+ def datepicker(action_id:, placeholder: nil, initial: nil, emoji: nil)
80
+ @element = Element::DatePicker.new(
81
+ action_id: action_id,
82
+ placeholder: placeholder,
83
+ initial: initial,
84
+ emoji: emoji
85
+ )
86
+
87
+ yield(@element) if block_given?
88
+
89
+ self
90
+ end
91
+
92
+ def multi_channels_select(placeholder:, action_id:, initial: nil, emoji: nil, max_selected_items: nil)
93
+ @element = Element::MultiChannelsSelect.new(
94
+ placeholder: placeholder,
95
+ action_id: action_id,
96
+ initial: initial,
97
+ emoji: emoji,
98
+ max_selected_items: max_selected_items
99
+ )
100
+
101
+ yield(@element) if block_given?
102
+
103
+ self
104
+ end
105
+
106
+ def static_select(placeholder:, action_id:, emoji: nil)
107
+ @element = Element::StaticSelect.new(
108
+ placeholder: placeholder,
109
+ action_id: action_id,
110
+ emoji: emoji
111
+ )
112
+
113
+ yield(@element) if block_given?
114
+
115
+ self
116
+ end
117
+
118
+ def multi_static_select(placeholder:, action_id:, emoji: nil, max_selected_items: nil)
119
+ @element = Element::MultiStaticSelect.new(
120
+ placeholder: placeholder,
121
+ action_id: action_id,
122
+ emoji: emoji,
123
+ max_selected_items: max_selected_items
124
+ )
125
+
126
+ yield(@element) if block_given?
127
+
128
+ self
129
+ end
130
+
131
+ def external_select(placeholder:, action_id:, initial: nil, min_query_length: nil, emoji: nil)
132
+ @element = Element::ExternalSelect.new(
133
+ placeholder: placeholder,
134
+ action_id: action_id,
135
+ initial: initial,
136
+ min_query_length: min_query_length,
137
+ emoji: emoji
138
+ )
139
+
140
+ yield(@element) if block_given?
141
+
142
+ self
143
+ end
144
+
145
+ def multi_external_select(
146
+ placeholder:,
147
+ action_id:,
148
+ initial: nil,
149
+ min_query_length: nil,
150
+ emoji: nil,
151
+ max_selected_items: nil
152
+ )
153
+ @element = Element::MultiExternalSelect.new(
154
+ placeholder: placeholder,
155
+ action_id: action_id,
156
+ initial: initial,
157
+ min_query_length: min_query_length,
158
+ emoji: emoji,
159
+ max_selected_items: max_selected_items
160
+ )
161
+
162
+ yield(@element) if block_given?
163
+
164
+ self
165
+ end
166
+
167
+ def plain_text_input(
168
+ action_id:,
169
+ placeholder: nil,
170
+ emoji: nil,
171
+ initial_value: nil,
172
+ multiline: nil,
173
+ min_length: nil,
174
+ max_length: nil
175
+ )
176
+ @element = Element::PlainTextInput.new(
177
+ action_id: action_id,
178
+ placeholder: placeholder,
179
+ emoji: emoji,
180
+ initial_value: initial_value,
181
+ multiline: multiline,
182
+ min_length: min_length,
183
+ max_length: max_length
184
+ )
185
+
186
+ self
187
+ end
188
+
189
+ def radio_buttons(action_id:)
190
+ @element = Element::RadioButtons.new(action_id: action_id)
191
+
192
+ yield(@element) if block_given?
193
+
194
+ self
195
+ end
196
+
197
+ def users_select(placeholder:, action_id:, initial: nil, emoji: nil)
198
+ @element = Element::UsersSelect.new(
199
+ placeholder: placeholder,
200
+ action_id: action_id,
201
+ initial: initial,
202
+ emoji: emoji
203
+ )
204
+
205
+ yield(@element) if block_given?
206
+
207
+ self
208
+ end
209
+
210
+ def multi_users_select(placeholder:, action_id:, initial: nil, emoji: nil, max_selected_items: nil)
211
+ @element = Element::MultiUsersSelect.new(
212
+ placeholder: placeholder,
213
+ action_id: action_id,
214
+ initial: initial,
215
+ emoji: emoji,
216
+ max_selected_items: max_selected_items
217
+ )
218
+
219
+ yield(@element) if block_given?
220
+
221
+ self
222
+ end
223
+
31
224
  def as_json(*)
32
225
  {
33
226
  type: TYPE,