slack-ruby-block-kit 0.10.0 → 0.14.1
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.
- checksums.yaml +4 -4
- data/.deepsource.toml +15 -0
- data/.github/workflows/ci.yml +33 -0
- data/.rubocop.yml +19 -2
- data/CHANGELOG.md +65 -3
- data/Gemfile +13 -1
- data/Gemfile.lock +66 -43
- data/README.md +3 -1
- data/lib/slack/block_kit.rb +2 -2
- data/lib/slack/block_kit/blocks.rb +18 -0
- data/lib/slack/block_kit/composition/confirmation_dialog.rb +16 -0
- data/lib/slack/block_kit/composition/option.rb +6 -1
- data/lib/slack/block_kit/composition/option_group.rb +2 -2
- data/lib/slack/block_kit/element/button.rb +3 -11
- data/lib/slack/block_kit/element/channels_select.rb +3 -11
- data/lib/slack/block_kit/element/checkboxes.rb +15 -26
- data/lib/slack/block_kit/element/conversations_select.rb +3 -11
- data/lib/slack/block_kit/element/date_picker.rb +3 -9
- data/lib/slack/block_kit/element/external_select.rb +3 -12
- data/lib/slack/block_kit/element/multi_channels_select.rb +3 -12
- data/lib/slack/block_kit/element/multi_conversations_select.rb +3 -12
- data/lib/slack/block_kit/element/multi_external_select.rb +3 -12
- data/lib/slack/block_kit/element/multi_static_select.rb +18 -26
- data/lib/slack/block_kit/element/multi_users_select.rb +3 -12
- data/lib/slack/block_kit/element/overflow_menu.rb +4 -11
- data/lib/slack/block_kit/element/radio_buttons.rb +53 -0
- data/lib/slack/block_kit/element/static_select.rb +20 -25
- data/lib/slack/block_kit/element/timepicker.rb +49 -0
- data/lib/slack/block_kit/element/users_select.rb +3 -11
- data/lib/slack/block_kit/layout/header.rb +29 -0
- data/lib/slack/block_kit/layout/input.rb +196 -3
- data/lib/slack/block_kit/layout/section.rb +11 -4
- data/lib/slack/block_kit/version.rb +7 -0
- data/slack-ruby-block-kit.gemspec +1 -18
- metadata +11 -134
- data/.circleci/config.yml +0 -49
- 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
|
-
|
16
|
+
include Composition::ConfirmationDialog::Confirmable
|
17
17
|
|
18
|
-
|
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:
|
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
|
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:
|
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 :
|
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
|
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:
|
73
|
-
option_groups:
|
74
|
-
initial_option:
|
75
|
-
confirm:
|
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
|
-
|
16
|
+
include Composition::ConfirmationDialog::Confirmable
|
17
17
|
|
18
|
-
|
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:
|
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
|
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,
|