diff --git a/README.md b/README.md index 74f9967a..071357a0 100644 --- a/README.md +++ b/README.md @@ -218,6 +218,8 @@ Our MCP server provides a rich set of tools that give AI assistants the ability | | delete_column | Remove a column from a board | | **Account Operations** | get_users_by_name | Retrieve user information by name or partial name | | | list_users_and_teams | Retrieve user or team's details by id, name or by searching the account | +| **WorkForms Operations** | create_form | Create a new monday.com form | +| | get_form | Get a form by its token | ## 🔮 Dynamic API Tools (Beta) diff --git a/packages/agent-toolkit/README.md b/packages/agent-toolkit/README.md index c2702b1c..502148bd 100644 --- a/packages/agent-toolkit/README.md +++ b/packages/agent-toolkit/README.md @@ -34,6 +34,10 @@ The toolkit includes several pre-built tools for common monday.com operations, o - `CreateColumnTool` - Create a new column in a monday.com board - `DeleteColumnTool` - Delete a column from a monday.com board +### WorkForms Operations +- `CreateFormTool` - Create a monday.com form +- `GetFormTool` - Get a form by its token, found in the form's URL + ### Account Operations - `GetUsersTool` - Get users, can be filtered by name or partial name - `ListUsersAndTeams` - Get users or teams, either by ids, names or by searching the account diff --git a/packages/agent-toolkit/src/core/tools/platform-api-tools/index.ts b/packages/agent-toolkit/src/core/tools/platform-api-tools/index.ts index 66bcd64d..7f55ef95 100644 --- a/packages/agent-toolkit/src/core/tools/platform-api-tools/index.ts +++ b/packages/agent-toolkit/src/core/tools/platform-api-tools/index.ts @@ -2,6 +2,8 @@ import { AllMondayApiTool } from './all-monday-api-tool'; import { BaseMondayApiToolConstructor } from './base-monday-api-tool'; import { ChangeItemColumnValuesTool } from './change-item-column-values-tool'; import { CreateBoardTool } from './create-board-tool'; +import { CreateFormTool } from './workforms-tools/create-form-tool'; +import { GetFormTool } from './workforms-tools/get-form-tool'; import { CreateColumnTool } from './create-column-tool'; import { CreateCustomActivityTool } from './create-custom-activity-tool'; import { CreateItemTool } from './create-item-tool'; @@ -42,6 +44,8 @@ export const allGraphqlApiTools: BaseMondayApiToolConstructor[] = [ ChangeItemColumnValuesTool, MoveItemToGroupTool, CreateBoardTool, + CreateFormTool, + GetFormTool, CreateColumnTool, DeleteColumnTool, AllMondayApiTool, @@ -65,6 +69,8 @@ export const allGraphqlApiTools: BaseMondayApiToolConstructor[] = [ export * from './all-monday-api-tool'; export * from './change-item-column-values-tool'; export * from './create-board-tool'; +export * from './workforms-tools/create-form-tool'; +export * from './workforms-tools/get-form-tool'; export * from './create-column-tool'; export * from './create-custom-activity-tool'; export * from './create-item-tool'; diff --git a/packages/agent-toolkit/src/core/tools/platform-api-tools/workforms-tools/create-form-tool.ts b/packages/agent-toolkit/src/core/tools/platform-api-tools/workforms-tools/create-form-tool.ts new file mode 100644 index 00000000..a76b06aa --- /dev/null +++ b/packages/agent-toolkit/src/core/tools/platform-api-tools/workforms-tools/create-form-tool.ts @@ -0,0 +1,64 @@ +import { z } from 'zod'; +import { + BoardKind, + CreateFormMutation, + CreateFormMutationVariables, +} from '../../../../monday-graphql/generated/graphql'; +import { createForm } from './workforms.graphql'; +import { ToolInputType, ToolOutputType, ToolType } from '../../../tool'; +import { BaseMondayApiTool, createMondayApiAnnotations } from '../base-monday-api-tool'; +import { GraphQLDescriptions } from './workforms.consts'; + +export const createFormToolSchema = { + destination_workspace_id: z.number().describe(GraphQLDescriptions.form.args.destinationWorkspaceId), + destination_folder_id: z.number().optional().describe(GraphQLDescriptions.form.args.destinationFolderId), + destination_folder_name: z.string().optional().describe(GraphQLDescriptions.form.args.destinationFolderName), + board_kind: z.nativeEnum(BoardKind).optional().describe(GraphQLDescriptions.form.args.boardKind), + destination_name: z.string().optional().describe(GraphQLDescriptions.form.args.destinationName), + board_owner_ids: z.array(z.number()).optional().describe(GraphQLDescriptions.form.args.boardOwnerIds), + board_owner_team_ids: z.array(z.number()).optional().describe(GraphQLDescriptions.form.args.boardOwnerTeamIds), + board_subscriber_ids: z.array(z.number()).optional().describe(GraphQLDescriptions.form.args.boardSubscriberIds), + board_subscriber_teams_ids: z + .array(z.number()) + .optional() + .describe(GraphQLDescriptions.form.args.boardSubscriberTeamsIds), +}; + +export class CreateFormTool extends BaseMondayApiTool { + name = 'create_form'; + type = ToolType.WRITE; + annotations = createMondayApiAnnotations({ + title: 'Create Form', + readOnlyHint: false, + destructiveHint: false, + idempotentHint: false, + }); + + getDescription(): string { + return 'Create a monday.com form. This will create a new form as well as a new board for which the form’s responses will be stored. The returned board_id is the ID of the board that was created while the returned formToken can be used for all future queries and mutations to continue editing the form.'; + } + + getInputSchema(): typeof createFormToolSchema { + return createFormToolSchema; + } + + protected async executeInternal(input: ToolInputType): Promise> { + const variables: CreateFormMutationVariables = { + destination_workspace_id: input.destination_workspace_id, + destination_folder_id: input.destination_folder_id, + destination_folder_name: input.destination_folder_name, + board_kind: input.board_kind, + destination_name: input.destination_name, + board_owner_ids: input.board_owner_ids, + board_owner_team_ids: input.board_owner_team_ids, + board_subscriber_ids: input.board_subscriber_ids, + board_subscriber_teams_ids: input.board_subscriber_teams_ids, + }; + + const res = await this.mondayApi.request(createForm, variables); + + return { + content: `Form created successfully. Board ID: ${res.create_form?.boardId}, Token: ${res.create_form?.token}`, + }; + } +} diff --git a/packages/agent-toolkit/src/core/tools/platform-api-tools/workforms-tools/get-form-tool.ts b/packages/agent-toolkit/src/core/tools/platform-api-tools/workforms-tools/get-form-tool.ts new file mode 100644 index 00000000..a203df8b --- /dev/null +++ b/packages/agent-toolkit/src/core/tools/platform-api-tools/workforms-tools/get-form-tool.ts @@ -0,0 +1,46 @@ +import { z } from 'zod'; +import { GetFormQuery, GetFormQueryVariables } from '../../../../monday-graphql/generated/graphql'; +import { getForm } from './workforms.graphql'; +import { ToolInputType, ToolOutputType, ToolType } from '../../../tool'; +import { BaseMondayApiTool, createMondayApiAnnotations } from '../base-monday-api-tool'; +import { GraphQLDescriptions } from './workforms.consts'; + +export const getFormToolSchema = { + formToken: z.string().describe(GraphQLDescriptions.commonArgs.formToken), +}; + +export class GetFormTool extends BaseMondayApiTool { + name = 'get_form'; + type = ToolType.READ; + annotations = createMondayApiAnnotations({ + title: 'Get Form', + readOnlyHint: true, + destructiveHint: false, + }); + + getDescription(): string { + return 'Get a monday.com form by its form token. Form tokens can be extracted from the form’s url. Given a form url, such as https://forms.monday.com/forms/abc123def456ghi789?r=use1, the token is the alphanumeric string that appears right after /forms/ and before the ?. In the example, the token is abc123def456ghi789.'; + } + + getInputSchema(): typeof getFormToolSchema { + return getFormToolSchema; + } + + protected async executeInternal(input: ToolInputType): Promise> { + const variables: GetFormQueryVariables = { + formToken: input.formToken, + }; + + const res = await this.mondayApi.request(getForm, variables); + + if (!res.form) { + return { + content: `Form with token ${input.formToken} not found or you don't have access to it.`, + }; + } + + return { + content: `The form with the token ${input.formToken} is: ${JSON.stringify(res.form, null, 2)}`, + }; + } +} diff --git a/packages/agent-toolkit/src/core/tools/platform-api-tools/workforms-tools/workforms.consts.ts b/packages/agent-toolkit/src/core/tools/platform-api-tools/workforms-tools/workforms.consts.ts new file mode 100644 index 00000000..37a8e730 --- /dev/null +++ b/packages/agent-toolkit/src/core/tools/platform-api-tools/workforms-tools/workforms.consts.ts @@ -0,0 +1,240 @@ +export const GraphQLDescriptions = { + commonArgs: { + formToken: 'The unique identifier token for the form. Required for all form-specific operations.', + questionId: 'The unique identifier for the question. Used to target specific questions within a form.', + }, + form: { + operations: { + createForm: 'Create a new form with specified configuration. Returns the created form with its unique token.', + updateForm: 'Update form properties including title, description, or question order.', + activateForm: 'Activate a form to make it visible to users and accept new submissions.', + deactivateForm: 'Deactivate a form to hide it from users and stop accepting submissions. Form data is preserved.', + }, + properties: { + id: 'The unique identifier for the form. Auto-generated upon creation.', + token: 'The unique token used to access and identify the form. Used in public URLs and API calls.', + boardId: 'The board ID connected to the form. Used to store form responses as items.', + title: 'The display title shown to users at the top of the form.', + description: 'Optional detailed description explaining the form purpose, displayed below the title.', + active: 'Boolean indicating if the form is currently accepting responses and visible to users.', + ownerId: 'The ID of the user who created and owns this form. Determines permissions.', + createWithAI: 'Boolean indicating if this form was initially created using AI assistance.', + builtWithAI: 'Boolean indicating if this form was built or modified using AI functionality.', + questions: 'Array of question objects that make up the form content, in display order.', + isSuspicious: + 'Boolean flag indicating if the form has been flagged for review due to suspicious content or activity.', + isAnonymous: 'Boolean indicating if responses are collected without identifying the submitter.', + type: 'The category or classification of the form for organizational purposes.', + features: 'Object containing feature toggles and settings like password protection, response limits, etc.', + appearance: 'Object containing visual styling settings including colors, fonts, layout, and branding.', + accessibility: 'Object containing accessibility settings such as language, alt text, and reading direction.', + tags: 'Array of tracking tags for categorization and analytics (e.g., UTM parameters for marketing tracking).', + }, + inputs: { + title: 'The title text for the form. Must be at least 1 character long.', + description: 'Optional description text providing context about the form purpose.', + input: 'Complete form configuration object containing properties to create or update.', + questions: 'Ordered array of question IDs for reordering. Must include all existing question IDs.', + }, + args: { + formToken: 'The unique form token identifying which form to operate on.', + includeFullFormDetails: + 'Boolean indicating if the full form details should be included in the response. Default will be to only return the core properties of the form and its questions', + destinationWorkspaceId: 'The workspace in which the form will be created in.', + destinationFolderId: 'The folder in which the form will be created under.', + destinationFolderName: 'The name of the folder in which the form will be created in.', + boardKind: 'The board kind to create for the board in which the form will create items in.', + destinationName: 'The name of the board that will be created to store the form responses in.', + boardOwnerIds: + 'Array of user IDs who will have owner permissions on the board in which the form will create items in.', + boardOwnerTeamIds: + 'Array of team IDs whose members will have owner permissions on the board in which the form will create items in.', + boardSubscriberIds: + 'Array of user IDs who will receive notifications about board activity for the board in which the form will create items in.', + boardSubscriberTeamsIds: + 'Array of team IDs whose members will receive notifications about board activity for the board in which the form will create items in.', + }, + }, + formSettings: { + operations: { + updateFormSettings: 'Update form configuration including features, appearance, and accessibility options.', + setFormPassword: + 'Set a password on a form to restrict access. This will enable password protection for the form.', + shortenUrl: 'Shorten a URL for a form and store it in the form settings. Returns the shortened link object.', + }, + properties: { + features: + 'Object containing form features including but not limited to password protection, response limits, login requirements, etc.', + appearance: 'Object containing visual styling including colors, layout, fonts, and branding elements.', + accessibility: 'Object containing accessibility options such as language, alt text, etc.', + isInternal: 'Boolean indicating if the form is restricted to internal users only.', + reCaptchaChallenge: 'Boolean enabling reCAPTCHA verification to prevent spam submissions.', + password: 'Object containing password protection configuration for the form.', + passwordEnabled: + 'Boolean enabling password protection. When true, users must enter a password to access the form.', + requireLogin: 'Object containing login requirement settings for form access.', + requireLoginEnabled: 'Boolean requiring users to be logged in before submitting responses.', + redirectToLogin: 'Boolean automatically redirecting unauthenticated users to the login page.', + shortenedLink: 'Object containing shortened URL configuration for easy form sharing.', + shortenedLinkEnabled: 'Boolean enabling generation of shortened URLs for the form.', + shortenedLinkUrl: 'The generated shortened URL for form access. Only available when shortened links are enabled.', + draftSubmission: 'Object containing draft saving configuration allowing users to save progress.', + draftSubmissionEnabled: 'Boolean allowing users to save incomplete responses as drafts.', + aiTranslate: 'Object containing AI translation configuration for the form.', + aiTranslateEnabled: 'Boolean enabling AI translation for the form.', + responseLimit: 'Object containing response limitation settings to control submission volume.', + responseLimitEnabled: 'Boolean enabling response count limits for the form.', + responseLimitValue: 'Integer specifying the maximum number of responses allowed.', + closeDate: 'Object containing automatic form closure configuration.', + closeDateEnabled: 'Boolean enabling automatic form closure at a specified date and time.', + closeDateValue: 'ISO timestamp when the form will automatically stop accepting responses.', + allowResubmit: 'Boolean allowing users to submit multiple responses to the same form.', + allowEditSubmission: 'Boolean allowing users to modify their submitted responses after submission.', + allowViewSubmission: 'Boolean allowing users to view their submitted responses.', + preSubmissionView: 'Object containing welcome screen configuration displayed before the form.', + preSubmissionEnabled: 'Boolean showing a welcome/introduction screen before the form begins.', + preSubmissionTitle: 'Text displayed as the title on the welcome screen.', + preSubmissionDescription: 'Text providing context or instructions on the welcome screen.', + startButton: 'Object containing start button configuration for the welcome screen.', + startButtonText: 'Custom text for the button that begins the form experience.', + afterSubmissionView: 'Object containing settings for the post-submission user experience.', + postSubmissionTitle: 'Text displayed as the title after successful form submission.', + postSubmissionDescription: 'Text shown to users after they complete the form.', + showSuccessImage: 'Boolean displaying a success image after form completion.', + redirectAfterSubmission: 'Object containing redirect configuration after form submission.', + redirectAfterSubmissionEnabled: 'Boolean enabling automatic redirect after form completion to a specified URL.', + redirectUrl: 'The URL where users will be redirected after successfully submitting the form.', + monday: 'Object containing board settings for response handling.', + itemGroupId: 'The board group ID where new items from form responses will be created.', + includeNameQuestion: + 'Boolean adding a name question to the form. This is a special question type that represents the name column from the associated monday board', + includeUpdateQuestion: + 'Boolean adding an update/comment field to the form. This is a special question type that represents the updates from the associated item of the submission on the monday board. ', + syncQuestionAndColumnsTitles: + 'Boolean synchronizing form question titles with board column names. When true, the form question titles will be synchronized with the board column names.', + hideBranding: 'Boolean hiding monday branding from the form display.', + showProgressBar: 'Boolean displaying a progress indicator showing form completion progress bar.', + primaryColor: 'Hex color code for the primary theme color used throughout the form.', + layout: 'Object containing form structure and presentation settings.', + format: 'String specifying the form display format. Can be a step by step form or a classic one page form.', + alignment: 'String controlling text and content alignment.', + direction: 'String setting reading direction.', + background: 'Object containing background appearance configuration for the form.', + backgroundType: 'String specifying background style.', + backgroundValue: + 'String containing the background value. The value will depend on the background type. If the background type is color, the value will be a hex color code. If the background type is image, the value will be an image URL.', + text: 'Object containing typography and text styling configuration.', + font: 'String specifying the font family used throughout the form.', + textColor: 'Hex color code for the text color in the form.', + fontSize: 'String or number specifying the base font size for form text.', + logo: 'Object containing logo display configuration for form branding.', + logoPosition: 'String specifying logo placement ("top", "bottom", "header").', + logoUrl: 'URL pointing to the logo image file for display on the form.', + logoSize: + 'String specifying logo size ("small", "medium", "large") for the logo that appears on the header of the form.', + logoAltText: 'Alternative text description for the logo image for accessibility.', + submitButton: 'Object containing submit button styling and text configuration.', + submitButtonText: 'Custom text displayed on the form submission button.', + language: 'Language code for form localization and interface text (e.g., "en", "es", "fr").', + }, + inputs: { + settings: 'Complete form settings object containing all configuration options.', + features: 'Form features configuration including security, limits, and access controls.', + appearance: 'Visual styling configuration including colors, layout, and branding.', + accessibility: 'Accessibility configuration including language and reading direction.', + password: + 'Password configuration for the form. Only setting enabled to false is supported. To enable a form to be password protected, please use the set_form_password mutation instead.', + passwordValue: 'The password to set for the form. Must be at least 1 character long.', + }, + }, + question: { + operations: { + createQuestion: 'Create a new question within a form. Returns the created question with auto-generated ID.', + updateQuestion: + 'Update an existing question properties including title, type, or settings. Requires question ID.', + deleteQuestion: 'Permanently remove a question from a form. This action cannot be undone.', + }, + properties: { + title: + 'The question text displayed to respondents. Must be at least 1 character long and clearly indicate the expected response.', + type: 'The question type determining input behavior and validation (e.g., "text", "email", "single_select", "multi_select").', + visible: + 'Boolean controlling question visibility to respondents. Hidden questions remain in form structure but are not displayed.', + required: 'Boolean indicating if the question must be answered before form submission.', + position: 'Integer specifying the display order of the question within the form (zero-based).', + description: + 'Optional explanatory text providing additional context, instructions, or examples for the question.', + placeholder: 'Optional placeholder text shown in input fields to guide user input.', + createdAt: 'ISO timestamp when the question was created.', + updatedAt: 'ISO timestamp when the question was last modified.', + selectOptions: + 'Array of option objects for choice-based questions (single_select, multi_select). Required for select types.', + selectLabel: 'The display text for individual option choices in select-type questions.', + }, + inputs: { + question: 'Complete question object containing all properties for creation or update.', + questionData: 'Question configuration including type, title, and type-specific settings.', + position: 'Integer position where the question should be placed in the form sequence.', + }, + }, + questionSettings: { + properties: { + validation: 'Validation rules applied to the question response', + prefill: + 'Configuration for automatically populating question values from various data sources such as user account information or URL query parameters.', + prefillEnabled: + 'Whether prefill functionality is enabled for this question. When true, the question will attempt to auto-populate values from the specified source.', + prefillSource: + 'The data source to use for prefilling the question value. Check the PrefillSources for available options.', + prefillLookup: + 'The specific field or parameter name to lookup from the prefill source. For account sources, this would be a user property like "name" or "email". For query parameters, this would be the parameter name that would be set in the URL.', + prefixAutofilled: + "Phone questions only: Automatically detect and fill the phone country prefix based on the user's geographic location or browser settings.", + prefixPredefined: + 'Phone questions only: Configuration for setting a specific predefined phone country prefix that will be pre-selected for users.', + prefixPredefinedEnabled: + 'Whether a predefined phone prefix is enabled for phone number questions. When true, the specified prefix will be pre-selected.', + prefixPredefinedPrefix: + 'The predefined phone country prefix to use as country code in capital letters (e.g., "US", "UK", "IL"). Only used when enabled is true.', + checkedByDefault: + 'Boolean/checkbox questions only: Whether the checkbox should be checked by default when the form loads.', + defaultCurrentDate: + 'Date based questions only: Automatically set the current date as the default value when the form loads.', + includeTime: + 'Date questions only: Whether to include time selection (hours and minutes) in addition to the date picker. When false, only date selection is available.', + display: + 'Single/Multi Select questions only: Controls how the selection options are visually presented to users.', + optionsOrder: 'Single/Multi Select questions only: Determines the ordering of selection options.', + labelLimitCount: 'Multi Select questions only: Limits the number of options a user can select.', + locationAutofilled: + "Location questions only: Automatically detect and fill the user's current location using browser geolocation services, requiring user permission.", + limit: 'Rating questions only: Maximum rating value that users can select.', + skipValidation: 'Link/URL questions only: Whether to skip URL format validation, allowing any text input.', + }, + inputs: { + settings: 'Question-specific configuration object that varies by question type.', + validationRules: 'Validation constraints and rules', + choiceOptions: 'List of available choices for selection questions', + fileSettings: 'File upload constraints and settings', + }, + }, + tag: { + operations: { + createTag: 'Create a new tag for a form. Tags are used to categorize and track responses. (e.g. UTM tags)', + deleteTag: 'Delete a tag from a form', + updateTag: 'Update an existing tag in a form', + }, + properties: { + id: 'The unique identifier for the tag', + name: 'The name of the tag', + value: 'The value of the tag', + columnId: 'The ID of the column this tag is associated with', + }, + inputs: { + tagInput: 'The tag data to create', + name: 'The name of the tag. Must be unique within the form and not reserved.', + value: 'The value of the tag', + deleteTagInput: 'Options for deleting the tag', + }, + }, +}; diff --git a/packages/agent-toolkit/src/core/tools/platform-api-tools/workforms-tools/workforms.graphql.ts b/packages/agent-toolkit/src/core/tools/platform-api-tools/workforms-tools/workforms.graphql.ts new file mode 100644 index 00000000..2e3e06b1 --- /dev/null +++ b/packages/agent-toolkit/src/core/tools/platform-api-tools/workforms-tools/workforms.graphql.ts @@ -0,0 +1,170 @@ +import { gql } from 'graphql-request'; + +// Create a new monday form (API version 2025-10) +export const createForm = gql` + mutation createForm( + $destination_workspace_id: Float! + $destination_folder_id: Float + $destination_folder_name: String + $board_kind: BoardKind + $destination_name: String + $board_owner_ids: [Float!] + $board_owner_team_ids: [Float!] + $board_subscriber_ids: [Float!] + $board_subscriber_teams_ids: [Float!] + ) { + create_form( + destination_workspace_id: $destination_workspace_id + destination_folder_id: $destination_folder_id + destination_folder_name: $destination_folder_name + board_kind: $board_kind + destination_name: $destination_name + board_owner_ids: $board_owner_ids + board_owner_team_ids: $board_owner_team_ids + board_subscriber_ids: $board_subscriber_ids + board_subscriber_teams_ids: $board_subscriber_teams_ids + ) { + boardId + token + } + } +`; + +// Fetch a full form with all its details by its token +export const getForm = gql` + query getForm($formToken: String!) { + form(formToken: $formToken) { + id + token + title + description + active + ownerId + type + builtWithAI + isAnonymous + questions { + id + type + visible + title + description + required + showIfRules + options { + label + } + settings { + prefill { + enabled + source + lookup + } + prefixAutofilled + prefixPredefined { + enabled + prefix + } + checkedByDefault + defaultCurrentDate + includeTime + display + optionsOrder + labelLimitCount + locationAutofilled + limit + skipValidation + } + } + features { + isInternal + reCaptchaChallenge + shortenedLink { + enabled + url + } + password { + enabled + } + draftSubmission { + enabled + } + requireLogin { + enabled + redirectToLogin + } + responseLimit { + enabled + limit + } + closeDate { + enabled + date + } + preSubmissionView { + enabled + title + description + startButton { + text + } + } + afterSubmissionView { + title + description + redirectAfterSubmission { + enabled + redirectUrl + } + allowResubmit + showSuccessImage + allowEditSubmission + allowViewSubmission + } + monday { + itemGroupId + includeNameQuestion + includeUpdateQuestion + syncQuestionAndColumnsTitles + } + } + appearance { + hideBranding + showProgressBar + primaryColor + layout { + format + alignment + direction + } + background { + type + value + } + text { + font + color + size + } + logo { + position + url + size + } + submitButton { + text + } + } + accessibility { + language + logoAltText + } + tags { + id + name + value + columnId + } + } + } +`; diff --git a/packages/agent-toolkit/src/core/tools/platform-api-tools/workforms-tools/workforms.types.ts b/packages/agent-toolkit/src/core/tools/platform-api-tools/workforms-tools/workforms.types.ts new file mode 100644 index 00000000..998bd81f --- /dev/null +++ b/packages/agent-toolkit/src/core/tools/platform-api-tools/workforms-tools/workforms.types.ts @@ -0,0 +1,455 @@ +enum FormType { + Internal = 'internal', + InlineInternal = 'inline_internal', + Preview = 'preview', + Standard = 'standard', + EnforcedItemCreationForm = 'enforced_item_creation_form', +} + +enum LogoSize { + Small = 'small', + Medium = 'medium', + Large = 'large', + ExtraLarge = 'extraLarge', +} + +enum LogoPosition { + Auto = 'auto', + Left = 'left', + Center = 'center', + Right = 'right', +} + +interface Tag { + id: string; + name: string; + columnId: string; + value?: string; +} + +enum BackgroundType { + Image = 'image', + Color = 'color', + None = 'none', +} + +enum Direction { + LtR = 'ltr', + Rtl = 'rtl', +} + +enum Format { + OneByOne = 'one-by-one', + Classic = 'classic', +} + +enum Alignment { + FullLeft = 'full-left', + Left = 'left', + Center = 'center', + Right = 'right', + FullRight = 'full-right', +} + +enum FontSize { + Small = 'small', + Medium = 'medium', + Large = 'large', +} + +enum WorkformsQuestionType { + Boolean = 'Boolean', + ConnectedBoards = 'ConnectedBoards', + Country = 'Country', + Date = 'Date', + DateRange = 'DateRange', + Email = 'Email', + File = 'File', + Link = 'Link', + Location = 'Location', + LongText = 'LongText', + MultiSelect = 'MultiSelect', + Name = 'Name', + Number = 'Number', + People = 'People', + Phone = 'Phone', + Rating = 'Rating', + ShortText = 'ShortText', + Signature = 'Signature', + SingleSelect = 'SingleSelect', + Subitems = 'Subitems', + Updates = 'Updates', +} + +enum PrefillSources { + Account = 'account', + QueryParam = 'queryParam', +} + +enum PrefillAccountLookups { + Email = 'email', + Name = 'name', + Title = 'title', + Phone = 'phone', + FirstName = 'first_name', + LastName = 'last_name', + Location = 'location', + Timezone = 'time_zone', + ManagerName = 'manager_display_name', +} + +enum ConditionOperator { + And = 'AND', + Or = 'OR', +} + +type Condition = { + id: string; + buildingBlockId: string; // id of the parent question + operator: ConditionOperator; + values: string[]; +}; + +type PhoneQuestionSettings = { + prefixAutofilled: boolean; + prefixPredefined: { + enabled: boolean; + prefix: string | null; + }; +}; + +type BooleanQuestionSettings = { + checkedByDefault: boolean; +}; + +type ConnectedBoardsQuestionSettings = { + boards: { + id: number; + name: string; + }[]; + allowMultipleItems: boolean; +}; + +type DateQuestionSettings = { + defaultCurrentDate: boolean; + includeTime: boolean; +}; + +enum SelectDisplay { + Horizontal = 'horizontal', + Vertical = 'vertical', + Dropdown = 'dropdown', +} + +enum SelectOrderByOptions { + Alphabetical = 'alphabetical', + Random = 'random', + Custom = 'custom', +} + +type SingleSelectQuestionSettings = { + display: SelectDisplay; + optionsOrder: SelectOrderByOptions; + optionsPositions?: Record; +}; + +type MultiSelectQuestionSettings = { + display: SelectDisplay; + labelLimitCount: number | null; + optionsOrder: SelectOrderByOptions; + optionsPositions?: Record; +}; + +type LocationQuestionSettings = { + locationAutofilled: boolean; +}; + +type RatingQuestionSettings = { + limit: 3 | 4 | 5; +}; + +type PeopleQuestionSettings = { + people: { + id: number; + name: string; + photoUrl: string | null; + title: string | null; + }[]; + maximum: number | null; +}; + +type LinkQuestionSettings = { + skipValidation: boolean; +}; + +type SubitemsQuestionSettings = { + subitemBoardId: string; + // eslint-disable-next-line no-use-before-define + subQuestions: Question[]; +}; + +type PrefillSettingsValue = { + enabled: boolean; + source: PrefillSources; + lookup: PrefillAccountLookups | string; +}; + +type PrefillSettings = { + prefill?: PrefillSettingsValue; +}; + +type ShowIfRule = { + id: string; + operator: ConditionOperator.Or; + conditions: string[]; +}; + +enum SelectOptionsType { + MultiSelect = 'multi-select', + SingleSelect = 'single-select', + People = 'people', + Location = 'location', + CountryCode = 'country-code', + Country = 'country', + ConnectedBoards = 'connected_boards', +} + +interface SelectOption { + label: string; + value: string; +} + +interface PeopleOption extends SelectOption { + avatarUrl?: string; +} + +interface MultiSelectOption extends SelectOption { + position: number; + visible?: boolean; + active?: boolean; +} + +interface SingleSelectOption extends SelectOption { + position: number; + visible?: boolean; + active?: boolean; +} + +interface LocationOption extends SelectOption { + address?: string; + locationDetails?: { + address: string; + placeId: string; + }; +} + +// Base settings that no-specific question uses, so we can add more settings to it +type BaseQuestionSettings = PrefillSettings; + +type QuestionSettings = + | BaseQuestionSettings + | PhoneQuestionSettings + | BooleanQuestionSettings + | DateQuestionSettings + | SingleSelectQuestionSettings + | MultiSelectQuestionSettings + | LocationQuestionSettings + | RatingQuestionSettings + | PeopleQuestionSettings + | LinkQuestionSettings + | ConnectedBoardsQuestionSettings + | SubitemsQuestionSettings; + +interface BaseQuestion { + id: string; + type: WorkformsQuestionType; + visible: boolean; + title: string; + description: string | null; + settings: QuestionSettings; + required: boolean; + showIfRules: { + operator: ConditionOperator.Or; + rules: ShowIfRule[]; + }; + forceRequired?: boolean; +} + +export type PhoneQuestion = BaseQuestion & { + type: WorkformsQuestionType.Phone; + settings: PhoneQuestionSettings; +}; + +export type BooleanQuestion = BaseQuestion & { + type: WorkformsQuestionType.Boolean; + settings: BooleanQuestionSettings; +}; + +export type ConnectedBoardsQuestion = BaseQuestion & { + type: WorkformsQuestionType.ConnectedBoards; + settings: ConnectedBoardsQuestionSettings; +}; + +export type DateQuestion = BaseQuestion & { + type: WorkformsQuestionType.Date; + settings: DateQuestionSettings; +}; + +export type SingleSelectQuestion = BaseQuestion & { + type: WorkformsQuestionType.SingleSelect; + settings: SingleSelectQuestionSettings; + options: SingleSelectOption[]; +}; + +export type MultiSelectQuestion = BaseQuestion & { + type: WorkformsQuestionType.MultiSelect; + settings: MultiSelectQuestionSettings; + options: MultiSelectOption[]; +}; + +export type LocationQuestion = BaseQuestion & { + type: WorkformsQuestionType.Location; + settings: LocationQuestionSettings; + options: LocationOption[]; +}; + +export type RatingQuestion = BaseQuestion & { + type: WorkformsQuestionType.Rating; + settings: RatingQuestionSettings; +}; + +type PeopleQuestion = BaseQuestion & { + type: WorkformsQuestionType.People; + settings: PeopleQuestionSettings; + options: PeopleOption[]; +}; + +type LinkQuestion = BaseQuestion & { + type: WorkformsQuestionType.Link; + settings: LinkQuestionSettings; +}; + +type SubitemsQuestion = BaseQuestion & { + type: WorkformsQuestionType.Subitems; + settings: SubitemsQuestionSettings; +}; + +export type Question = + | BaseQuestion + | BooleanQuestion + | DateQuestion + | LocationQuestion + | RatingQuestion + | MultiSelectQuestion + | PeopleQuestion + | PhoneQuestion + | SingleSelectQuestion + | LinkQuestion + | ConnectedBoardsQuestion + | SubitemsQuestion; + +export interface Form { + id: number; + token: string; + active: boolean; + title: string; + ownerId?: number; + createWithAI: boolean; + builtWithAI: boolean; + description: string | null; + closeDate: string | null; + questions: Question[]; + conditions: { + [id: string]: Condition; + }; + isSuspicious: boolean; + isAnonymous: boolean; + type: FormType; + features: { + isInternal: boolean; + reCaptchaChallenge: boolean; + shortenedLink: { + enabled: boolean; + url: string | null; + }; + password: { + enabled: boolean; + }; + draftSubmission: { + enabled: boolean; + }; + requireLogin: { + enabled: boolean; + redirectToLogin: boolean; + }; + responseLimit: { + enabled: boolean; + limit: number | null; + }; + closeDate: { + enabled: boolean; + date: string | null; + }; + preSubmissionView: { + enabled: boolean; + title: string | null; + description: string | null; + startButton: { + text: string | null; + }; + }; + postSubmissionView: { + title: string | null; + description: string | null; + redirectAfterSubmission: { + enabled: boolean; + redirectUrl: string | null; + }; + allowResubmit: boolean; + showSuccessImage: boolean; + allowEditSubmission: boolean; + allowViewSubmission: boolean; + }; + monday: { + itemGroupId: string | null; + includeNameQuestion: boolean; + includeUpdateQuestion: boolean; + syncQuestionAndColumnsTitles: boolean; + }; + aiTranslate: { + enabled: boolean; + }; + }; + appearance: { + hideBranding: boolean; + showProgressBar: boolean; + primaryColor: string | null; + layout: { + format: Format; + alignment: Alignment; + direction: Direction; + }; + background: + | { type: BackgroundType.Color; value: string | null } + | { type: BackgroundType.Image; value: string } + | { type: BackgroundType.None }; + text: { + font: string | null; + color: string | null; + size: FontSize | null; + }; + logo: { + position: LogoPosition; + url: string | null; + size: LogoSize; + }; + submitButton: { + text: string | null; + }; + }; + accessibility: { + language: string | null; + logoAltText: string | null; + }; + tags: Tag[]; +} diff --git a/packages/agent-toolkit/src/monday-graphql/generated/graphql.ts b/packages/agent-toolkit/src/monday-graphql/generated/graphql.ts index bd05a1d4..09c163c5 100644 --- a/packages/agent-toolkit/src/monday-graphql/generated/graphql.ts +++ b/packages/agent-toolkit/src/monday-graphql/generated/graphql.ts @@ -1,3 +1,5 @@ +import { Form } from "src/core/tools/platform-api-tools/workforms-tools/workforms.types" + export type Maybe = T | null; export type InputMaybe = Maybe; export type Exact = { [K in keyof T]: T[K] }; @@ -8511,3 +8513,27 @@ export type GetWorkspaceInfoQueryVariables = Exact<{ export type GetWorkspaceInfoQuery = { __typename?: 'Query', workspaces?: Array<{ __typename?: 'Workspace', id?: string | null, name: string, description?: string | null, kind?: WorkspaceKind | null, created_at?: any | null, state?: State | null, is_default_workspace?: boolean | null, owners_subscribers?: Array<{ __typename?: 'User', id: string, name: string, email: string } | null> | null } | null> | null, boards?: Array<{ __typename?: 'Board', id: string, name: string, board_folder_id?: string | null } | null> | null, docs?: Array<{ __typename?: 'Document', id: string, name: string, doc_folder_id?: string | null } | null> | null, folders?: Array<{ __typename?: 'Folder', id: string, name: string } | null> | null }; + +// ----------------------------- +// WorkForms (Forms) Types +// ----------------------------- + +export type CreateFormMutationVariables = Exact<{ + destination_workspace_id: Scalars['Float']['input']; + destination_folder_id?: InputMaybe; + destination_folder_name?: InputMaybe; + board_kind?: InputMaybe; + destination_name?: InputMaybe; + board_owner_ids?: InputMaybe>; + board_owner_team_ids?: InputMaybe>; + board_subscriber_ids?: InputMaybe>; + board_subscriber_teams_ids?: InputMaybe>; +}>; + +export type CreateFormMutation = { __typename?: 'Mutation', create_form?: { __typename?: 'CreateFormResult', boardId: string, token: string } | null }; + +export type GetFormQueryVariables = Exact<{ + formToken: Scalars['String']['input']; +}>; + +export type GetFormQuery = { __typename?: 'Query', form?: Form & { __typename?: 'Form' } | null };