slack-ruby-block-kit 0.6.1 → 0.11.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.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +9 -0
- data/.github/workflows/ci.yml +31 -0
- data/.rubocop.yml +46 -1
- data/.rubocop_todo.yml +8 -0
- data/CHANGELOG.md +56 -0
- data/Gemfile +0 -1
- data/Gemfile.lock +33 -28
- data/lib/slack/block_kit.rb +49 -5
- data/lib/slack/block_kit/composition/confirmation_dialog.rb +20 -0
- data/lib/slack/block_kit/composition/conversation_filter.rb +33 -0
- data/lib/slack/block_kit/composition/option.rb +1 -1
- 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 +55 -0
- data/lib/slack/block_kit/element/conversations_select.rb +13 -7
- data/lib/slack/block_kit/element/date_picker.rb +3 -9
- data/lib/slack/block_kit/element/external_select.rb +3 -11
- data/lib/slack/block_kit/element/multi_channels_select.rb +42 -0
- data/lib/slack/block_kit/element/multi_conversations_select.rb +57 -0
- data/lib/slack/block_kit/element/multi_external_select.rb +52 -0
- data/lib/slack/block_kit/element/multi_static_select.rb +82 -0
- data/lib/slack/block_kit/element/multi_users_select.rb +42 -0
- data/lib/slack/block_kit/element/overflow_menu.rb +4 -10
- data/lib/slack/block_kit/element/plain_text_input.rb +1 -1
- data/lib/slack/block_kit/element/radio_buttons.rb +48 -0
- data/lib/slack/block_kit/element/static_select.rb +4 -10
- data/lib/slack/block_kit/element/users_select.rb +3 -11
- data/lib/slack/block_kit/layout/context.rb +1 -0
- data/lib/slack/block_kit/layout/image.rb +1 -4
- data/lib/slack/block_kit/layout/section.rb +29 -1
- data/lib/slack/block_kit/layout/section/multi_select_elements.rb +92 -0
- data/lib/slack/surfaces/home.rb +35 -0
- data/lib/slack/surfaces/message.rb +34 -0
- data/lib/slack/surfaces/modal.rb +76 -0
- metadata +21 -7
- data/.circleci/config.yml +0 -49
@@ -15,9 +15,11 @@ 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
|
@@ -37,20 +39,12 @@ module Slack
|
|
37
39
|
self
|
38
40
|
end
|
39
41
|
|
40
|
-
def confirmation_dialog
|
41
|
-
@confirm = Composition::ConfirmationDialog.new
|
42
|
-
|
43
|
-
yield(@confirm) if block_given?
|
44
|
-
|
45
|
-
self
|
46
|
-
end
|
47
|
-
|
48
42
|
def as_json(*)
|
49
43
|
{
|
50
44
|
type: TYPE,
|
51
45
|
action_id: @action_id,
|
52
46
|
options: @options.map(&:as_json),
|
53
|
-
confirm:
|
47
|
+
confirm: confirm&.as_json
|
54
48
|
}.compact
|
55
49
|
end
|
56
50
|
end
|
@@ -22,7 +22,7 @@ module Slack
|
|
22
22
|
min_length: nil,
|
23
23
|
max_length: nil
|
24
24
|
)
|
25
|
-
@placeholder = Composition::PlainText.new(text: placeholder, emoji: emoji)
|
25
|
+
@placeholder = placeholder && Composition::PlainText.new(text: placeholder, emoji: emoji)
|
26
26
|
@initial_value = initial_value
|
27
27
|
@action_id = action_id
|
28
28
|
@multiline = multiline
|
@@ -0,0 +1,48 @@
|
|
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, :initial_option
|
15
|
+
|
16
|
+
def initialize(action_id:)
|
17
|
+
@action_id = action_id
|
18
|
+
|
19
|
+
yield(self) if block_given?
|
20
|
+
end
|
21
|
+
|
22
|
+
def option(value:, text:, initial: false)
|
23
|
+
option = Composition::Option.new(
|
24
|
+
value: value,
|
25
|
+
text: text
|
26
|
+
)
|
27
|
+
|
28
|
+
@options ||= []
|
29
|
+
@options << option
|
30
|
+
|
31
|
+
@initial_option = option if initial
|
32
|
+
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def as_json(*)
|
37
|
+
{
|
38
|
+
type: TYPE,
|
39
|
+
action_id: @action_id,
|
40
|
+
options: @options&.map(&:as_json),
|
41
|
+
initial_option: @initial_option&.as_json,
|
42
|
+
confirm: confirm&.as_json
|
43
|
+
}.compact
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
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, :initial_option
|
19
21
|
|
20
22
|
def initialize(placeholder:, action_id:, emoji: nil)
|
21
23
|
@placeholder = Composition::PlainText.new(text: placeholder, emoji: emoji)
|
@@ -24,14 +26,6 @@ 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
29
|
def option(value:, text:, emoji: nil)
|
36
30
|
@options ||= []
|
37
31
|
@options << Composition::Option.new(
|
@@ -72,7 +66,7 @@ module Slack
|
|
72
66
|
options: @options&.map(&:as_json),
|
73
67
|
option_groups: @option_groups&.map(&:as_json),
|
74
68
|
initial_option: @initial_option&.as_json,
|
75
|
-
confirm:
|
69
|
+
confirm: confirm&.as_json
|
76
70
|
}.compact
|
77
71
|
end
|
78
72
|
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
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative './section/multi_select_elements'
|
4
|
+
|
3
5
|
module Slack
|
4
6
|
module BlockKit
|
5
7
|
module Layout
|
@@ -8,13 +10,19 @@ module Slack
|
|
8
10
|
# with any of the available block elements.
|
9
11
|
#
|
10
12
|
# https://api.slack.com/reference/messaging/blocks#section
|
13
|
+
# rubocop:disable Metrics/ClassLength
|
11
14
|
class Section
|
15
|
+
# rubocop:enable Metrics/ClassLength
|
16
|
+
|
17
|
+
include Section::MultiSelectElements
|
12
18
|
TYPE = 'section'
|
13
19
|
|
14
20
|
attr_accessor :fields, :text, :accessory
|
15
21
|
|
16
22
|
def initialize(block_id: nil)
|
17
23
|
@block_id = block_id
|
24
|
+
@fields = nil
|
25
|
+
@accessory = nil
|
18
26
|
|
19
27
|
yield(self) if block_given?
|
20
28
|
end
|
@@ -148,8 +156,28 @@ module Slack
|
|
148
156
|
accessorise(element)
|
149
157
|
end
|
150
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
|
+
|
151
179
|
def image(url:, alt_text:)
|
152
|
-
|
180
|
+
accessorise(Element::Image.new(image_url: url, alt_text: alt_text))
|
153
181
|
end
|
154
182
|
|
155
183
|
def accessorise(element)
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Slack
|
4
|
+
module BlockKit
|
5
|
+
module Layout
|
6
|
+
class Section
|
7
|
+
# Helper methods for Multi Select to inject to section
|
8
|
+
module MultiSelectElements
|
9
|
+
def multi_channels_select(placeholder:, action_id:,
|
10
|
+
initial: nil, emoji: nil, max_selected_items: nil)
|
11
|
+
element = Element::MultiChannelsSelect.new(
|
12
|
+
placeholder: placeholder,
|
13
|
+
action_id: action_id,
|
14
|
+
initial: initial,
|
15
|
+
emoji: emoji,
|
16
|
+
max_selected_items: max_selected_items
|
17
|
+
)
|
18
|
+
|
19
|
+
yield(element) if block_given?
|
20
|
+
|
21
|
+
accessorise(element)
|
22
|
+
end
|
23
|
+
|
24
|
+
def multi_conversations_select(placeholder:, action_id:,
|
25
|
+
initial: nil, emoji: nil, max_selected_items: nil)
|
26
|
+
element = Element::MultiConversationsSelect.new(
|
27
|
+
placeholder: placeholder,
|
28
|
+
action_id: action_id,
|
29
|
+
initial: initial,
|
30
|
+
emoji: emoji,
|
31
|
+
max_selected_items: max_selected_items
|
32
|
+
)
|
33
|
+
|
34
|
+
yield(element) if block_given?
|
35
|
+
|
36
|
+
accessorise(element)
|
37
|
+
end
|
38
|
+
|
39
|
+
def multi_external_select(placeholder:, action_id:,
|
40
|
+
initial: nil,
|
41
|
+
min_query_length: nil,
|
42
|
+
emoji: nil,
|
43
|
+
max_selected_items: nil)
|
44
|
+
element = Element::MultiExternalSelect.new(
|
45
|
+
placeholder: placeholder,
|
46
|
+
action_id: action_id,
|
47
|
+
initial: initial,
|
48
|
+
min_query_length: min_query_length,
|
49
|
+
emoji: emoji,
|
50
|
+
max_selected_items: max_selected_items
|
51
|
+
)
|
52
|
+
|
53
|
+
yield(element) if block_given?
|
54
|
+
|
55
|
+
accessorise(element)
|
56
|
+
end
|
57
|
+
|
58
|
+
def multi_static_select(placeholder:, action_id:,
|
59
|
+
emoji: nil, max_selected_items: nil)
|
60
|
+
element = Element::MultiStaticSelect.new(
|
61
|
+
placeholder: placeholder,
|
62
|
+
action_id: action_id,
|
63
|
+
emoji: emoji,
|
64
|
+
max_selected_items: max_selected_items
|
65
|
+
)
|
66
|
+
|
67
|
+
yield(element) if block_given?
|
68
|
+
|
69
|
+
accessorise(element)
|
70
|
+
end
|
71
|
+
|
72
|
+
def multi_users_select(placeholder:, action_id:,
|
73
|
+
initial: nil,
|
74
|
+
emoji: nil,
|
75
|
+
max_selected_items: nil)
|
76
|
+
element = Element::MultiUsersSelect.new(
|
77
|
+
placeholder: placeholder,
|
78
|
+
action_id: action_id,
|
79
|
+
emoji: emoji,
|
80
|
+
initial: initial,
|
81
|
+
max_selected_items: max_selected_items
|
82
|
+
)
|
83
|
+
|
84
|
+
yield(element) if block_given?
|
85
|
+
|
86
|
+
accessorise(element)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
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
|