From af04dfb413fa099f82ed64ba5d3b653d5c774883 Mon Sep 17 00:00:00 2001 From: Keigo Aoki Date: Sun, 18 Aug 2024 17:00:23 +0900 Subject: [PATCH 1/2] Add workflow button --- README.md | 1 + src/bits/index.ts | 15 ++++++ src/bits/workflow.ts | 36 +++++++++++++ src/elements/index.ts | 18 +++++++ src/elements/workflow-button.ts | 55 ++++++++++++++++++++ src/internal/constants/element-types.ts | 1 + src/internal/constants/props.ts | 3 ++ src/internal/dto/slack-dto.ts | 3 ++ src/internal/helpers/build-helpers.ts | 16 +++++- src/internal/methods/set-methods.ts | 36 ++++++++++++- src/internal/objects/index.ts | 1 + src/internal/objects/trigger-object.ts | 20 +++++++ src/internal/types/index.ts | 7 ++- tests/bits/mocks/index.ts | 1 + tests/bits/mocks/workflow.mock.ts | 12 +++++ tests/bits/workflow.spec.ts | 22 ++++++++ tests/checks/built-trigger-property.ts | 30 +++++++++++ tests/checks/index.ts | 1 + tests/elements/mocks/index.ts | 1 + tests/elements/mocks/workflow-button.mock.ts | 9 ++++ tests/elements/workflow-button.spec.ts | 27 ++++++++++ tests/methods/index.ts | 2 + tests/methods/trigger.ts | 20 +++++++ tests/methods/workflow.ts | 19 +++++++ tests/mocks/method-arg-mocks-by-type.ts | 2 + tests/mocks/method-arg-mocks.ts | 2 + 26 files changed, 356 insertions(+), 4 deletions(-) create mode 100644 src/bits/workflow.ts create mode 100644 src/elements/workflow-button.ts create mode 100644 src/internal/objects/trigger-object.ts create mode 100644 tests/bits/mocks/workflow.mock.ts create mode 100644 tests/bits/workflow.spec.ts create mode 100644 tests/checks/built-trigger-property.ts create mode 100644 tests/elements/mocks/workflow-button.mock.ts create mode 100644 tests/elements/workflow-button.spec.ts create mode 100644 tests/methods/trigger.ts create mode 100644 tests/methods/workflow.ts diff --git a/README.md b/README.md index 6147507..56aa3a7 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,7 @@ Below is a list of supported objects and how to access them in **Block Builder** | Select Menus | Element | :white_check_mark: | `Elements.[Type]Select()` | Multi-Select Menus | Element | :white_check_mark: | `Elements.[Type]MultiSelect()` | URL Input | Element | :white_check_mark: | `Elements.NumberInput()` +| Workflow Button | Element | :white_check_mark: | `Elements.WorkflowButton()` | Option | Composition Object | :white_check_mark: | `Bits.Option()` | Confirm Dialog | Composition Object | :white_check_mark: | `Bits.ConfirmationDialog()` | Option Group | Composition Object | :white_check_mark: | `Bits.OptionGroup()` diff --git a/src/bits/index.ts b/src/bits/index.ts index 4fdb2a5..b0c93d0 100644 --- a/src/bits/index.ts +++ b/src/bits/index.ts @@ -4,6 +4,7 @@ import { AttachmentBuilder, AttachmentParams } from './attachment'; import { ConfirmationDialogBuilder, ConfirmationDialogParams } from './confirmation-dialog'; import { OptionBuilder, OptionParams } from './option'; import { OptionGroupBuilder, OptionGroupParams } from './option-group'; +import { WorkflowBuilder, WorkflowParams } from './workflow'; export type { AttachmentBuilder, @@ -14,6 +15,8 @@ export type { OptionParams, OptionGroupBuilder, OptionGroupParams, + WorkflowBuilder, + WorkflowParams, }; /** @@ -70,11 +73,23 @@ export function OptionGroup(params?: OptionGroupParams): OptionGroupBuilder { return new OptionGroupBuilder(params); } +/** + * @param {Object} [params] Parameters passed to the constructor. + * @param {string} [params.trigger] Sets the trigger object that contains information about a workflow's trigger. + * + * {@link https://api.slack.com/reference/block-kit/composition-objects#workflow|View in Slack API Documentation} + */ + +export function Workflow(params?: WorkflowParams): WorkflowBuilder { + return new WorkflowBuilder(params); +} + const bits = { Attachment, ConfirmationDialog, Option, OptionGroup, + Workflow, }; // Strange export. I know. For IDE highlighting purposes. diff --git a/src/bits/workflow.ts b/src/bits/workflow.ts new file mode 100644 index 0000000..03e1394 --- /dev/null +++ b/src/bits/workflow.ts @@ -0,0 +1,36 @@ +import { BitBuilderBase } from '../internal/base'; +import { SlackDto } from '../internal/dto'; +import { applyMixins, getTriggerObject } from '../internal/helpers'; +import { + End, + Trigger, +} from '../internal/methods'; +import type { TriggerObject } from '../internal/objects'; + +export interface WorkflowParams { + trigger?: TriggerObject; +} + +export interface WorkflowBuilder extends End, + Trigger { +} + +/** + * @@link https://api.slack.com/reference/block-kit/composition-objects#workflow + * @@displayName Workflow + */ + +export class WorkflowBuilder extends BitBuilderBase { + /** @internal */ + + public build(): Readonly { + return this.getResult(SlackDto, { + trigger: getTriggerObject(this.props.trigger), + }); + } +} + +applyMixins(WorkflowBuilder, [ + End, + Trigger, +]); diff --git a/src/elements/index.ts b/src/elements/index.ts index d70c058..f1e8b30 100644 --- a/src/elements/index.ts +++ b/src/elements/index.ts @@ -23,6 +23,7 @@ import { TimePickerBuilder, TimePickerParams } from './timepicker'; import { URLInputBuilder, URLInputParams } from './url-input'; import { UserMultiSelectBuilder, UserMultiSelectParams } from './user-multi-select'; import { UserSelectBuilder, UserSelectParams } from './user-select'; +import { WorkflowButtonBuilder, WorkflowButtonParams } from './workflow-button'; export type { ButtonBuilder, @@ -71,6 +72,8 @@ export type { UserSelectParams, FileInputBuilder, FileInputParams, + WorkflowButtonBuilder, + WorkflowButtonParams, }; /** @@ -375,6 +378,20 @@ export function UserSelect(params?: UserSelectParams): UserSelectBuilder { return new UserSelectBuilder(params); } +/** + * @param {Object} [params] Parameters passed to the constructor. + * @param {string} [params.accessibilityLabel] Sets a longer descriptive text that will be read out by screen readers instead of the button text object. + * @param {string} [params.actionId] Sets a string to be an identifier for the source of an action in interaction payloads. + * @param {string} [params.text] Sets the display text for the button. + * @param {string} [params.trigger] Sets a trigger object that contains information about a workflow's trigger. + * + * {@link https://api.slack.com/reference/block-kit/block-elements#workflow_button|View in Slack API Documentation} + */ + +export function WorkflowButton(params?: WorkflowButtonParams): WorkflowButtonBuilder { + return new WorkflowButtonBuilder(params); +} + const elements = { Button, ChannelMultiSelect, @@ -399,6 +416,7 @@ const elements = { UserMultiSelect, UserSelect, FileInput, + WorkflowButton, }; // Strange export. I know. For IDE highlighting purposes. diff --git a/src/elements/workflow-button.ts b/src/elements/workflow-button.ts new file mode 100644 index 0000000..d514ee6 --- /dev/null +++ b/src/elements/workflow-button.ts @@ -0,0 +1,55 @@ +import { ElementBuilderBase } from '../internal/base'; +import { ElementType } from '../internal/constants'; +import { SlackElementDto } from '../internal/dto'; +import { applyMixins, getPlainTextObject, getBuilderResult } from '../internal/helpers'; +import { + AccessibilityLabel, + ActionId, + Danger, + End, + Primary, + Text, + Workflow, +} from '../internal/methods'; + +export interface WorkflowButtonParams { + accessibilityLabel?: string; + actionId?: string; + text?: string; +} + +export interface WorkflowButtonBuilder extends AccessibilityLabel, + ActionId, + Danger, + End, + Primary, + Text, + Workflow { +} + +/** + * @@link https://api.slack.com/reference/block-kit/block-elements#workflow_button + * @@displayName WorkflowButton + */ + +export class WorkflowButtonBuilder extends ElementBuilderBase { + /** @internal */ + + public build(): Readonly { + return this.getResult(SlackElementDto, { + type: ElementType.WorkflowButton, + text: getPlainTextObject(this.props.text), + workflow: getBuilderResult(this.props.workflow), + }); + } +} + +applyMixins(WorkflowButtonBuilder, [ + AccessibilityLabel, + ActionId, + Danger, + End, + Primary, + Text, + Workflow, +]); diff --git a/src/internal/constants/element-types.ts b/src/internal/constants/element-types.ts index e3db341..0f0cd98 100644 --- a/src/internal/constants/element-types.ts +++ b/src/internal/constants/element-types.ts @@ -22,4 +22,5 @@ export enum ElementType { EmailInput = 'email_text_input', NumberInput = 'number_input', FileInput = 'file_input', + WorkflowButton = 'workflow_button', } diff --git a/src/internal/constants/props.ts b/src/internal/constants/props.ts index f31343c..e3445a9 100644 --- a/src/internal/constants/props.ts +++ b/src/internal/constants/props.ts @@ -89,4 +89,7 @@ export enum Prop { VideoUrl = 'videoUrl', MaxFiles = 'maxFiles', Filetypes = 'filetypes', + Workflow = 'workflow', + Trigger = 'trigger', + CustomizableInputParameters = 'customizableInputParameters', } diff --git a/src/internal/dto/slack-dto.ts b/src/internal/dto/slack-dto.ts index 6595fe1..07412b0 100644 --- a/src/internal/dto/slack-dto.ts +++ b/src/internal/dto/slack-dto.ts @@ -88,6 +88,9 @@ export enum Param { maxFiles = 'max_files', filetypes = 'filetypes', source = 'source', + workflow = 'workflow', + trigger = 'trigger', + customizableInputParameters = 'customizable_input_parameters', } export class SlackDto implements ObjectLiteral { diff --git a/src/internal/helpers/build-helpers.ts b/src/internal/helpers/build-helpers.ts index 28039e6..8ddf685 100644 --- a/src/internal/helpers/build-helpers.ts +++ b/src/internal/helpers/build-helpers.ts @@ -5,6 +5,7 @@ import { FilterObject, FilterParams, DispatchActionsConfigurationObject, + TriggerParams, } from '../objects'; import type { @@ -12,7 +13,7 @@ import type { ContextElement, Undefinable, } from '../types'; -import type { SlackElementDto } from '../dto'; +import { SlackDto, type SlackElementDto } from '../dto'; const defaultParams = { isMarkdown: false, @@ -85,3 +86,16 @@ export function getDispatchActionsConfigurationObject( && new DispatchActionsConfigurationObject([onEnterPressed, onCharacterEntered] .filter(Boolean)); } + +export function getTriggerObject(trigger: TriggerParams): Undefinable { + return valueOrUndefined(trigger) && new SlackDto({ + url: trigger.url, + customizableInputParameters: + trigger.customizableInputParameters === undefined + ? undefined + : Object.keys(trigger.customizableInputParameters).map((paramName) => ({ + name: paramName, + value: trigger.customizableInputParameters[paramName], + })), + }); +} diff --git a/src/internal/methods/set-methods.ts b/src/internal/methods/set-methods.ts index 3c7bbf1..6be440f 100644 --- a/src/internal/methods/set-methods.ts +++ b/src/internal/methods/set-methods.ts @@ -5,7 +5,8 @@ import { Builder } from '../lib'; import { Prop } from '../constants'; import type { SectionElementBuilder, Settable } from '../types'; -import type { OptionBuilder } from '../../bits'; +import type { OptionBuilder, WorkflowBuilder } from '../../bits'; +import type { TriggerObject } from '../objects'; export abstract class AccessibilityLabel extends Builder { /** @@ -801,3 +802,36 @@ export abstract class Filetypes extends Builder { return this.set(filetypes.flat(), Prop.Filetypes); } } + +export abstract class Workflow extends Builder { + /** + * @description Sets a workflow object that contains details about the workflow that will run when the button is clicked. + * + * **Slack Validation Rules and Tips:** + * * **Required** ⚠ + * + * {@link https://api.slack.com/block-kit|Open Official Slack Block Kit Documentation} + * {@link https://www.blockbuilder.dev|Open Block Builder Documentation} + */ + + public workflow(workflow: Settable): this { + return this.set(workflow, Prop.Workflow); + } +} + +export abstract class Trigger extends Builder { + /** + * @description A trigger object that contains information about a workflow's trigger. + * + * **Slack Validation Rules and Tips:** + * * **Required** ⚠ + * * Must be associated with a valid trigger. + * + * {@link https://api.slack.com/block-kit|Open Official Slack Block Kit Documentation} + * {@link https://www.blockbuilder.dev|Open Block Builder Documentation} + */ + + public trigger(trigger: Settable): this { + return this.set(trigger, Prop.Trigger); + } +} diff --git a/src/internal/objects/index.ts b/src/internal/objects/index.ts index 376915d..2a49571 100644 --- a/src/internal/objects/index.ts +++ b/src/internal/objects/index.ts @@ -2,3 +2,4 @@ export * from './dispatch-actions-configuration-object'; export * from './filter-object'; export * from './markdown-object'; export * from './plain-text-object'; +export * from './trigger-object'; diff --git a/src/internal/objects/trigger-object.ts b/src/internal/objects/trigger-object.ts new file mode 100644 index 0000000..2f2dcd6 --- /dev/null +++ b/src/internal/objects/trigger-object.ts @@ -0,0 +1,20 @@ +import { CompositionObjectBase } from '../base'; +import type { ObjectLiteral } from '../types'; + +export interface TriggerParams { + url: string; + customizableInputParameters?: ObjectLiteral; +} + +export class TriggerObject extends CompositionObjectBase { + public url: string; + + public customizableInputParameters?: ObjectLiteral; + + constructor(params: TriggerParams) { + super(); + + this.url = params.url; + this.customizableInputParameters = params.customizableInputParameters; + } +} diff --git a/src/internal/types/index.ts b/src/internal/types/index.ts index 248acfb..801e89c 100644 --- a/src/internal/types/index.ts +++ b/src/internal/types/index.ts @@ -18,6 +18,7 @@ import type { TimePickerBuilder, UserMultiSelectBuilder, UserSelectBuilder, + WorkflowButtonBuilder, } from '../../elements'; import type { ActionsBuilder, @@ -44,7 +45,8 @@ export type ActionsElementBuilder = | RadioButtonsBuilder | StaticSelectBuilder | TimePickerBuilder - | UserSelectBuilder; + | UserSelectBuilder + | WorkflowButtonBuilder; export type SectionElementBuilder = ButtonBuilder @@ -63,7 +65,8 @@ export type SectionElementBuilder = | StaticSelectBuilder | TimePickerBuilder | UserMultiSelectBuilder - | UserSelectBuilder; + | UserSelectBuilder + | WorkflowButtonBuilder; export type InputElementBuilder = | ChannelMultiSelectBuilder diff --git a/tests/bits/mocks/index.ts b/tests/bits/mocks/index.ts index 5767d3a..b2c4e2f 100644 --- a/tests/bits/mocks/index.ts +++ b/tests/bits/mocks/index.ts @@ -2,3 +2,4 @@ export * as Attachment from './attachment.mock'; export * as ConfirmationDialog from './confirmation-dialog.mock'; export * as Option from './option.mock'; export * as OptionGroup from './option-group.mock'; +export * as Workflow from './workflow.mock'; diff --git a/tests/bits/mocks/workflow.mock.ts b/tests/bits/mocks/workflow.mock.ts new file mode 100644 index 0000000..feb686b --- /dev/null +++ b/tests/bits/mocks/workflow.mock.ts @@ -0,0 +1,12 @@ +import { WorkflowBuilder } from '../../../src/bits/workflow'; +import { TriggerObject } from '../../../src/internal'; + +export const params = { + trigger: { + url: 'string', + }, +}; + +const trigger = new TriggerObject(params.trigger); + +export const mock = new WorkflowBuilder().trigger(trigger); diff --git a/tests/bits/workflow.spec.ts b/tests/bits/workflow.spec.ts new file mode 100644 index 0000000..3562e05 --- /dev/null +++ b/tests/bits/workflow.spec.ts @@ -0,0 +1,22 @@ +import { WorkflowBuilder as Class } from '../../src/bits/workflow'; +import { SlackDto as DtoClass } from '../../src/internal'; +import { params } from './mocks/workflow.mock'; +import { testCompositeBuilderClass } from '../test-composite-builder-class'; +import * as methods from '../methods'; + +const className = 'WorkflowBuilder'; +const category = 'Bits'; + +const config = { + Class, + DtoClass, + params, + className, + category, +}; + +const methodsConfig = [ + methods.trigger, +]; + +testCompositeBuilderClass({ config, methods: methodsConfig }); diff --git a/tests/checks/built-trigger-property.ts b/tests/checks/built-trigger-property.ts new file mode 100644 index 0000000..c39efb1 --- /dev/null +++ b/tests/checks/built-trigger-property.ts @@ -0,0 +1,30 @@ +import { MethodTestArgs } from '../test-config-types'; +import { Prop } from '../../src/internal/constants'; + +export const builtTriggerProperty = (params: MethodTestArgs): void => { + const { + Class, + methodName, + propSetterPropName, + slackDtoParamName, + methodArgMock, + } = params; + + test(`Building the object with a defined property of '${propSetterPropName}' should include the DTO property of '${slackDtoParamName}' only on the trigger object.`, () => { + const instance = new Class(); + + instance[methodName](methodArgMock); + + const built = instance.build(); + + expect(built).toHaveProperty(slackDtoParamName); + expect(built[Prop.Trigger]).toHaveProperty('url'); + expect(built[Prop.Trigger]).toHaveProperty('customizable_input_parameters'); + expect(built[Prop.Trigger].url).toBeDefined(); + + built[Prop.Trigger].customizable_input_parameters.forEach((param) => { + expect(param).toHaveProperty('name'); + expect(param).toHaveProperty('value'); + }); + }); +}; diff --git a/tests/checks/index.ts b/tests/checks/index.ts index 62d1c28..5a85a4d 100644 --- a/tests/checks/index.ts +++ b/tests/checks/index.ts @@ -4,6 +4,7 @@ export * from './bool-settable-property'; export * from './bool-true-property'; export * from './built-child-build'; export * from './built-filter-property'; +export * from './built-trigger-property'; export * from './call-from-index'; export * from './configurable-enum-value-property'; export * from './end-method-call'; diff --git a/tests/elements/mocks/index.ts b/tests/elements/mocks/index.ts index fbce905..8a207b9 100644 --- a/tests/elements/mocks/index.ts +++ b/tests/elements/mocks/index.ts @@ -21,3 +21,4 @@ export * as URLInput from './url-input.mock'; export * as UserMultiSelect from './user-multiselect.mock'; export * as UserSelect from './user-select.mock'; export * as FileInput from './file-input.mock'; +export * as WorkflowButton from './workflow-button.mock'; diff --git a/tests/elements/mocks/workflow-button.mock.ts b/tests/elements/mocks/workflow-button.mock.ts new file mode 100644 index 0000000..f519722 --- /dev/null +++ b/tests/elements/mocks/workflow-button.mock.ts @@ -0,0 +1,9 @@ +import { WorkflowButtonBuilder } from '../../../src/elements/workflow-button'; + +export const params = { + text: 'text', + actionId: 'actionId', + accessibilityLabel: 'accessibilityLabel', +}; + +export const mock = new WorkflowButtonBuilder(params).danger(); diff --git a/tests/elements/workflow-button.spec.ts b/tests/elements/workflow-button.spec.ts new file mode 100644 index 0000000..b4d870e --- /dev/null +++ b/tests/elements/workflow-button.spec.ts @@ -0,0 +1,27 @@ +import { WorkflowButtonBuilder as Class } from '../../src/elements/workflow-button'; +import { SlackElementDto as DtoClass } from '../../src/internal'; +import { params } from './mocks/workflow-button.mock'; +import * as methods from '../methods'; +import { testCompositeBuilderClass } from '../test-composite-builder-class'; + +const className = 'WorkflowButtonBuilder'; +const category = 'Elements'; + +const config = { + Class, + DtoClass, + params, + className, + category, +}; + +const methodsConfig = [ + methods.accessibilityLabel, + methods.actionId, + methods.text, + methods.danger, + methods.primary, + methods.workflow, +]; + +testCompositeBuilderClass({ config, methods: methodsConfig }); diff --git a/tests/methods/index.ts b/tests/methods/index.ts index 44bb464..d4d2a40 100644 --- a/tests/methods/index.ts +++ b/tests/methods/index.ts @@ -84,3 +84,5 @@ export * from './value'; export * from './video-url'; export * from './max-files'; export * from './filetypes'; +export * from './trigger'; +export * from './workflow'; diff --git a/tests/methods/trigger.ts b/tests/methods/trigger.ts new file mode 100644 index 0000000..81e0d49 --- /dev/null +++ b/tests/methods/trigger.ts @@ -0,0 +1,20 @@ +import { CompositeBuilderClassConfig } from '../test-config-types'; +import { Prop } from '../../src/internal/constants'; +import { methodArgMocks } from '../mocks/method-arg-mocks'; +import { SlackDto } from '../../src/internal'; +import * as checks from '../checks'; + +export const trigger = (params: CompositeBuilderClassConfig): void => { + const config = { + ...params, + methodArgMock: methodArgMocks.trigger, + methodName: Prop.Trigger, + propSetterPropName: Prop.Trigger, + slackDtoParamName: SlackDto.mapParam(Prop.Trigger), + mutatedValueType: SlackDto, + }; + + checks.settableProperty(config); + checks.mutatedBuild(config); + checks.builtTriggerProperty(config); +}; diff --git a/tests/methods/workflow.ts b/tests/methods/workflow.ts new file mode 100644 index 0000000..c74426e --- /dev/null +++ b/tests/methods/workflow.ts @@ -0,0 +1,19 @@ +import { CompositeBuilderClassConfig } from '../test-config-types'; +import { Prop } from '../../src/internal/constants'; +import { methodArgMocks } from '../mocks/method-arg-mocks'; +import { SlackDto } from '../../src/internal'; +import * as checks from '../checks'; + +export const workflow = (params: CompositeBuilderClassConfig): void => { + const config = { + ...params, + methodArgMock: methodArgMocks.workflow, + methodName: Prop.Workflow, + propSetterPropName: Prop.Workflow, + slackDtoParamName: SlackDto.mapParam(Prop.Workflow), + mutatedValueType: SlackDto, + }; + + checks.settableProperty(config); + checks.mutatedBuild(config); +}; diff --git a/tests/mocks/method-arg-mocks-by-type.ts b/tests/mocks/method-arg-mocks-by-type.ts index 23b8606..6e3dd0b 100644 --- a/tests/mocks/method-arg-mocks-by-type.ts +++ b/tests/mocks/method-arg-mocks-by-type.ts @@ -31,4 +31,6 @@ export const methodArgMocksByType = { falseBool: false, onEnterPressed: 'on_enter_pressed', onCharacterEntered: 'on_character_entered', + trigger: { url: 'string', customizableInputParameters: { parameter: 'string' } }, + workflow: bitMocks.Workflow.mock, }; diff --git a/tests/mocks/method-arg-mocks.ts b/tests/mocks/method-arg-mocks.ts index e5b42eb..fcf3245 100644 --- a/tests/mocks/method-arg-mocks.ts +++ b/tests/mocks/method-arg-mocks.ts @@ -87,4 +87,6 @@ export const methodArgMocks = { videoUrl: methodArgMocksByType.string, maxFiles: methodArgMocksByType.int, filetypes: methodArgMocksByType.arrayStrings, + trigger: methodArgMocksByType.trigger, + workflow: methodArgMocksByType.workflow, }; From 72c01669feac2712ff5226f23d435322f485f717 Mon Sep 17 00:00:00 2001 From: Keigo Aoki Date: Sun, 18 Aug 2024 17:02:47 +0900 Subject: [PATCH 2/2] Add docs --- README.md | 3 +- docs-generator/mappers/map-type.ts | 4 ++ docs/_sidebar.md | 2 + docs/bits/introduction.md | 2 +- docs/bits/workflow.md | 49 +++++++++++++++++++ docs/elements/workflow-button.md | 78 ++++++++++++++++++++++++++++++ docs/support.md | 2 + 7 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 docs/bits/workflow.md create mode 100644 docs/elements/workflow-button.md diff --git a/README.md b/README.md index 56aa3a7..b23d7d3 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ import { Modal, Section, bold, link } from 'slack-block-builder'; `Elements` – UI elements that are used to capture user interaction. -`Bits` – These are composition objects and other bits and pieces from Slack's docs. Included are `Attachment`, `Options`, `OptionGroup`, and `ConfirmationDialog`. They felt like they were deserving of their own category. +`Bits` – These are composition objects and other bits and pieces from Slack's docs. Included are `Attachment`, `Options`, `OptionGroup`,`ConfirmationDialog`, and `Workflow`. They felt like they were deserving of their own category. `Utilities` – A group of utility functions. See [Utility Functions](#utility-functions). @@ -162,6 +162,7 @@ Below is a list of supported objects and how to access them in **Block Builder** | Option | Composition Object | :white_check_mark: | `Bits.Option()` | Confirm Dialog | Composition Object | :white_check_mark: | `Bits.ConfirmationDialog()` | Option Group | Composition Object | :white_check_mark: | `Bits.OptionGroup()` +| Workflow | Composition Object | :white_check_mark: | `Bits.Workflow()` | Attachment | Legacy Feature | :white_check_mark: | `Bits.Attachment()` ### Creating a Simple Interactive Message diff --git a/docs-generator/mappers/map-type.ts b/docs-generator/mappers/map-type.ts index c78a8ac..4394a89 100644 --- a/docs-generator/mappers/map-type.ts +++ b/docs-generator/mappers/map-type.ts @@ -35,6 +35,10 @@ export default (type: string, capitalize = false): string => { return type.replace('Builder', ''); } + if (type === 'TriggerObject') { + return 'TriggerObject'; + } + if (type === 'T') { return 'T'; // Means it is a generic and should be replaced when class mapped with methods } diff --git a/docs/_sidebar.md b/docs/_sidebar.md index d0f07a1..3d76296 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -60,6 +60,7 @@ * [URL Input](elements/url-input.md "Block Builder – URL Input – Maintainable JavaScript Code for Slack Block Kit") * [User Multi-Select](elements/user-multi-select.md "Block Builder – User Multi-Select – Maintainable JavaScript Code for Slack Block Kit") * [User Select](elements/user-select.md "Block Builder – User Select – Maintainable JavaScript Code for Slack Block Kit") + * [Workflow Button](elements/workflow-button.md "Block Builder – Workflow Button – Maintainable JavaScript Code for Slack Block Kit") * **Bit References** * [Introduction](bits/introduction.md "Block Builder – Bits – Introduction – Maintainable JavaScript Code for Slack Block Kit") @@ -67,6 +68,7 @@ * [Confirmation Dialog](bits/confirmation-dialog.md "Block Builder – Confirmation Dialog – Maintainable JavaScript Code for Slack Block Kit") * [Option](bits/option.md "Block Builder – Option – Maintainable JavaScript Code for Slack Block Kit") * [Option Group](bits/option-group.md "Block Builder – Option Group – Maintainable JavaScript Code for Slack Block Kit") + * [Workflow](bits/workflow.md "Block Builder – Workflow – Maintainable JavaScript Code for Slack Block Kit") * **Component References** * [Paginator](components/paginator.md "Block Builder – Paginator – Maintainable JavaScript Code for Slack Block Kit") diff --git a/docs/bits/introduction.md b/docs/bits/introduction.md index 9cbbd51..adeffed 100644 --- a/docs/bits/introduction.md +++ b/docs/bits/introduction.md @@ -2,7 +2,7 @@ This is the one category of objects that differs from those laid out in the [Slack Block Kit](https://api.slack.com/block-kit) documentation. -The `Bits` object in **Block Builder** contains various bits and pieces from the Slack Block Kit documentation. More specifically, **Attachment**, **Options**, **Option Groups**, and **Confirmation Dialogs**. +The `Bits` object in **Block Builder** contains various bits and pieces from the Slack Block Kit documentation. More specifically, **Attachment**, **Options**, **Option Groups**, **Confirmation Dialogs**, and **Workflow**. ### Accessing Bits in Block Builder diff --git a/docs/bits/workflow.md b/docs/bits/workflow.md new file mode 100644 index 0000000..8d7d500 --- /dev/null +++ b/docs/bits/workflow.md @@ -0,0 +1,49 @@ +# Workflow + +?> **Note:** This document is a reference to the `WorkflowBuilder` object in **Block Builder**. For more information on how this carries over to the Slack API, view the [the Workflow docs](https://api.slack.com/reference/block-kit/composition-objects#workflow) on Slack's doc site. + +### Creating an Instance + +The function that creates a new instance of `WorkflowBuilder` is available as both a top-level import and as a member of its 'category', `Bits`: + +```javascript +import { Workflow } from 'slack-block-builder'; + +const myObj = Workflow(params?); + +``` + +```javascript +import { Bits } from 'slack-block-builder'; + +const myObj = Bits.Workflow(params?); +``` + +### Params + +Each instance of the `WorkflowBuilder` object has chainable setter methods for the object's properties. However, properties with primitive values can optionally be passed to the instantiating function, should you prefer: + +`trigger` – *TriggerObject* + + +?> **Note:** For an explanation of any one of the parameters, see its corresponding setter method below. + +### Setter Methods + +All setter methods return `this`, the instance of `WorkflowBuilder` on which it is called. + +```javascript +WorkflowBuilder.trigger(TriggerObject); +``` + +A trigger object that contains information about a workflow's trigger. + +### Other Methods + +The `WorkflowBuilder` object also has other methods available: + +```javascript +WorkflowBuilder.end(); +``` + +Performs no alterations to the object on which it is called. It is meant to simulate a closing HTML tag for those who prefer to have an explicit end declared for an object. diff --git a/docs/elements/workflow-button.md b/docs/elements/workflow-button.md new file mode 100644 index 0000000..9e58136 --- /dev/null +++ b/docs/elements/workflow-button.md @@ -0,0 +1,78 @@ +# WorkflowButton + +?> **Note:** This document is a reference to the `WorkflowButtonBuilder` object in **Block Builder**. For more information on how this carries over to the Slack API, view the [the WorkflowButton docs](https://api.slack.com/reference/block-kit/block-elements#workflow_button) on Slack's doc site. + +### Creating an Instance + +The function that creates a new instance of `WorkflowButtonBuilder` is available as both a top-level import and as a member of its 'category', `Elements`: + +```javascript +import { WorkflowButton } from 'slack-block-builder'; + +const myObj = WorkflowButton(params?); + +``` + +```javascript +import { Elements } from 'slack-block-builder'; + +const myObj = Elements.WorkflowButton(params?); +``` + +### Params + +Each instance of the `WorkflowButtonBuilder` object has chainable setter methods for the object's properties. However, properties with primitive values can optionally be passed to the instantiating function, should you prefer: + +`accessibilityLabel` – *String* + +`actionId` – *String* + +`text` – *String* + + +?> **Note:** For an explanation of any one of the parameters, see its corresponding setter method below. + +### Setter Methods + +All setter methods return `this`, the instance of `WorkflowButtonBuilder` on which it is called. + +```javascript +WorkflowButtonBuilder.danger(boolean?); +``` + +For a button element, this changes the color to red. For confirmation dialogs, this sets the main button in the bottom right corner to red, indicating that an action is potentially destructive. Defaults to `true`. +```javascript +WorkflowButtonBuilder.primary(boolean?); +``` + +For a button element, this changes the color to green. For confirmation dialogs, this sets the main button in the bottom right corner to green, which is meant to confirm the action. Defaults to `true`. +```javascript +WorkflowButtonBuilder.accessibilityLabel(string); +``` + +A label for longer descriptive text about a button element. This label will be read out by screen readers instead of the button text object. +```javascript +WorkflowButtonBuilder.actionId(string); +``` + +Sets a string to be an identifier for the action taken by the user. It is sent back to your app in the interaction payload when the element is interacted or when the view is submitted. +```javascript +WorkflowButtonBuilder.text(string); +``` + +Sets the text displayed for buttons, headers, confirmation dialogs, sections, context blocks, and options. +```javascript +WorkflowButtonBuilder.workflow(Workflow); +``` + +Sets a workflow object that contains details about the workflow that will run when the button is clicked. + +### Other Methods + +The `WorkflowButtonBuilder` object also has other methods available: + +```javascript +WorkflowButtonBuilder.end(); +``` + +Performs no alterations to the object on which it is called. It is meant to simulate a closing HTML tag for those who prefer to have an explicit end declared for an object. diff --git a/docs/support.md b/docs/support.md index b2e8a94..17cc550 100644 --- a/docs/support.md +++ b/docs/support.md @@ -34,8 +34,10 @@ Below is a list of supported components and how to access them in **Block Builde | Select Menus | Element | **Yes** | `Elements.[Type]Select()` | | Multi-Select Menus | Element | **Yes** | `Elements.[Type]MultiSelect()` | | URL Input | Element | **Yes** | `Elements.URLInput()` | [View Docs](/elements/url-input.md) +| Workflow Button | Element | **Yes** | `Elements.WorkflowButton()` | [View Docs](/elements/workflow-button.md) | Attachment | Legacy Feature | **Yes** | `Bits.Attachment()` | [View Docs](/bits/attachment.md) | Confirmation Dialog | Composition Object | **Yes** | `Bits.ConfirmationDialog()` | [View Docs](/bits/confirmation-dialog.md) | Option | Composition Object | **Yes** | `Bits.Option()` | [View Docs](/bits/option.md) | Option Group | Composition Object | **Yes** | `Bits.OptionGroup()` | [View Docs](/bits/option-group.md) +| Workflow | Composition Object | **Yes** | `Bits.Workflow()` | [View Docs](/bits/workflow.md)