-
Notifications
You must be signed in to change notification settings - Fork 232
feat(block-kit): add data_table layout block #1613
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
61f0681
a6cc250
715e9a2
6d8ffce
43e03d1
698d88a
393dd22
f6e66bf
e417c31
36396ef
ec6733e
60a4781
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package com.slack.api.model.block; | ||
|
|
||
| import com.slack.api.model.block.composition.TableCell; | ||
| import lombok.AllArgsConstructor; | ||
| import lombok.Builder; | ||
| import lombok.Data; | ||
| import lombok.NoArgsConstructor; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| /** | ||
| * Displays rich tables that support pagination, sorting, filtering, and interactivity. | ||
| * | ||
| * @see <a href="https://docs.slack.dev/reference/block-kit/blocks/data-table-block">Data table block</a> | ||
| */ | ||
| @Data | ||
| @Builder | ||
| @NoArgsConstructor | ||
| @AllArgsConstructor | ||
| public class DataTableBlock implements LayoutBlock { | ||
| public static final String TYPE = "data_table"; | ||
| private final String type = TYPE; | ||
|
|
||
| /** | ||
| * An array consisting of table rows. | ||
| */ | ||
| @Builder.Default | ||
| private List<List<TableCell>> rows = new ArrayList<>(); | ||
|
|
||
| /** | ||
| * A caption for the table; used as the value for the HTML caption element. | ||
| */ | ||
| private String caption; | ||
|
|
||
| /** | ||
| * Number of rows per page. Min {@code 1}, Max {@code 100}. Defaults to {@code 5} if omitted. | ||
| */ | ||
| private Integer pageSize; | ||
|
|
||
| /** | ||
| * The 0-based index of the column that uniquely identifies each row (the row header). This column | ||
| * is treated as the row's primary identifier for screen readers. Defaults to {@code 0} if omitted. | ||
| */ | ||
| private Integer rowHeaderColumnIndex; | ||
|
|
||
| private String blockId; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -54,6 +54,26 @@ public static MarkdownTextObject markdownText(String text) { | |
| return MarkdownTextObject.builder().text(text).build(); | ||
| } | ||
|
|
||
| // RawNumberObject | ||
|
|
||
| public static RawNumberObject rawNumber(ModelConfigurator<RawNumberObject.RawNumberObjectBuilder> configurator) { | ||
| return configurator.configure(RawNumberObject.builder()).build(); | ||
| } | ||
|
|
||
| public static RawNumberObject rawNumber(Double value, String text) { | ||
| return RawNumberObject.builder().value(value).text(text).build(); | ||
| } | ||
|
Comment on lines
+57
to
+65
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👁️🗨️ note: These introduce helper functions to - RawTextObject.builder().text("Name").build()
+ BlockCompositions.rawText("Name"), |
||
|
|
||
| // RawTextObject | ||
|
|
||
| public static RawTextObject rawText(ModelConfigurator<RawTextObject.RawTextObjectBuilder> configurator) { | ||
| return configurator.configure(RawTextObject.builder()).build(); | ||
| } | ||
|
|
||
| public static RawTextObject rawText(String text) { | ||
| return RawTextObject.builder().text(text).build(); | ||
| } | ||
|
|
||
| // OptionGroupObject | ||
|
|
||
| public static OptionGroupObject optionGroup(ModelConfigurator<OptionGroupObject.OptionGroupObjectBuilder> configurator) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package com.slack.api.model.block.composition; | ||
|
|
||
| import lombok.AllArgsConstructor; | ||
| import lombok.Builder; | ||
| import lombok.Data; | ||
| import lombok.NoArgsConstructor; | ||
|
|
||
| /** | ||
| * Defines an object containing a numeric value. | ||
| * | ||
| * @see <a href="https://docs.slack.dev/reference/block-kit/blocks/table-block">Table block</a> | ||
| * @see <a href="https://docs.slack.dev/reference/block-kit/blocks/data-table-block">Data table block</a> | ||
| */ | ||
| @Data | ||
| @Builder | ||
| @NoArgsConstructor | ||
| @AllArgsConstructor | ||
| public class RawNumberObject implements TableCell { | ||
| public static final String TYPE = "raw_number"; | ||
| private final String type = TYPE; | ||
|
|
||
| /** | ||
| * The numeric value. | ||
| */ | ||
| private Double value; | ||
|
|
||
| /** | ||
| * The text used to display the value. The minimum length is 1 character. | ||
| */ | ||
| private String text; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package com.slack.api.model.block.composition; | ||
|
|
||
| import lombok.AllArgsConstructor; | ||
| import lombok.Builder; | ||
| import lombok.Data; | ||
| import lombok.NoArgsConstructor; | ||
|
|
||
| /** | ||
| * Defines an object containing some text. | ||
| * | ||
| * @see <a href="https://docs.slack.dev/reference/block-kit/blocks/table-block">Table block</a> | ||
| * @see <a href="https://docs.slack.dev/reference/block-kit/blocks/data-table-block">Data table block</a> | ||
| */ | ||
| @Data | ||
| @Builder | ||
| @NoArgsConstructor | ||
| @AllArgsConstructor | ||
| public class RawTextObject implements TableCell { | ||
| public static final String TYPE = "raw_text"; | ||
| private final String type = TYPE; | ||
|
|
||
| /** | ||
| * The text for the block. The minimum length is 1 character. | ||
| */ | ||
| private String text; | ||
| } |
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🦠 note: I have some confidence this is a consistent shared type but it's not clear if it's meant to be stable because it's not in reference. Hoping to add this here and #1611 for shared implementation! |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package com.slack.api.model.block.composition; | ||
|
|
||
| /** | ||
| * A single cell within a table or data table row. A cell can be one of: | ||
| * | ||
| * <ul> | ||
| * <li>{@link RawTextObject} ({@code raw_text})</li> | ||
| * <li>{@link RawNumberObject} ({@code raw_number})</li> | ||
| * <li>{@link com.slack.api.model.block.RichTextBlock RichTextBlock} ({@code rich_text})</li> | ||
| * </ul> | ||
| * | ||
| * @see <a href="https://docs.slack.dev/reference/block-kit/blocks/table-block">Table block</a> | ||
| * @see <a href="https://docs.slack.dev/reference/block-kit/blocks/data-table-block">Data table block</a> | ||
| */ | ||
| public interface TableCell { | ||
|
|
||
| String getType(); | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| package com.slack.api.util.json; | ||
|
|
||
| import com.google.gson.*; | ||
| import com.slack.api.model.block.RichTextBlock; | ||
| import com.slack.api.model.block.composition.RawNumberObject; | ||
| import com.slack.api.model.block.composition.RawTextObject; | ||
| import com.slack.api.model.block.composition.TableCell; | ||
|
|
||
| import java.lang.reflect.Type; | ||
|
|
||
| /** | ||
| * Factory for deserializing the cells of a | ||
| * {@link com.slack.api.model.block.DataTableBlock data table block}. | ||
| * | ||
| * @see <a href="https://docs.slack.dev/reference/block-kit/blocks/data-table-block">Data table block</a> | ||
| */ | ||
| public class GsonTableCellFactory implements JsonDeserializer<TableCell>, JsonSerializer<TableCell> { | ||
|
|
||
| private final boolean failOnUnknownProperties; | ||
|
|
||
| public GsonTableCellFactory() { | ||
| this(false); | ||
| } | ||
|
|
||
| public GsonTableCellFactory(boolean failOnUnknownProperties) { | ||
| this.failOnUnknownProperties = failOnUnknownProperties; | ||
| } | ||
|
|
||
| @Override | ||
| public TableCell deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) | ||
| throws JsonParseException { | ||
| final JsonObject jsonObject = json.getAsJsonObject(); | ||
| final JsonPrimitive prim = (JsonPrimitive) jsonObject.get("type"); | ||
| final String typeName = prim.getAsString(); | ||
| final Class<? extends TableCell> clazz = getTableCellClassInstance(typeName); | ||
| return context.deserialize(jsonObject, clazz); | ||
| } | ||
|
|
||
| @Override | ||
| public JsonElement serialize(TableCell src, Type typeOfSrc, JsonSerializationContext context) { | ||
| return context.serialize(src); | ||
| } | ||
|
|
||
| private Class<? extends TableCell> getTableCellClassInstance(String typeName) { | ||
| switch (typeName) { | ||
| case RawTextObject.TYPE: | ||
| return RawTextObject.class; | ||
| case RawNumberObject.TYPE: | ||
| return RawNumberObject.class; | ||
| case RichTextBlock.TYPE: | ||
| return RichTextBlock.class; | ||
| default: | ||
| throw new JsonParseException("Unknown table cell type: " + typeName); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📢 note: Here we add custom deserialization to handle the various
typepossibilities of the table cell.