first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled

This commit is contained in:
2026-03-17 16:22:57 +03:30
commit 3d5eaf9445
15349 changed files with 2847338 additions and 0 deletions
@@ -0,0 +1,273 @@
import type { INodeProperties } from 'n8n-workflow';
export const boardOperations: INodeProperties[] = [
// ----------------------------------
// board
// ----------------------------------
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['board'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new board',
action: 'Create a board',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a board',
action: 'Delete a board',
},
{
name: 'Get',
value: 'get',
description: 'Get the data of a board',
action: 'Get a board',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many user boards',
action: 'Get many boards',
},
],
default: 'create',
},
];
export const boardFields: INodeProperties[] = [
// ----------------------------------
// board:create
// ----------------------------------
{
displayName: 'Title',
name: 'title',
type: 'string',
default: '',
placeholder: 'My board',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['board'],
},
},
description: 'The title of the board',
},
{
displayName: 'Owner Name or ID',
name: 'owner',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getUsers',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['board'],
},
},
description:
'The user ID in Wekan. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['create'],
resource: ['board'],
},
},
default: {},
options: [
{
displayName: 'Active',
name: 'isActive',
type: 'boolean',
default: false,
description: 'Whether to set the board active',
},
{
displayName: 'Admin',
name: 'isAdmin',
type: 'boolean',
default: false,
description: 'Whether to set the owner an admin of the board',
},
{
displayName: 'Color',
name: 'color',
type: 'options',
options: [
{
name: 'Belize',
value: 'belize',
},
{
name: 'Midnight',
value: 'midnight',
},
{
name: 'Nephritis',
value: 'nephritis',
},
{
name: 'Pomegranate',
value: 'pomegranate',
},
{
name: 'Pumpkin',
value: 'pumpkin',
},
{
name: 'Wisteria',
value: 'wisteria',
},
],
default: '',
description: 'The color of the board',
},
{
displayName: 'Comment Only',
name: 'isCommentOnly',
type: 'boolean',
default: false,
description: 'Whether to enable comments',
},
{
displayName: 'No Comments',
name: 'isNoComments',
type: 'boolean',
default: false,
description: 'Whether to disable comments',
},
{
displayName: 'Permission',
name: 'permission',
type: 'options',
options: [
{
name: 'Private',
value: 'private',
},
{
name: 'Public',
value: 'public',
},
],
default: 'private',
description: 'Set the board permission',
},
{
displayName: 'Worker',
name: 'isWorker',
type: 'boolean',
default: false,
description: 'Whether to only move cards, assign himself to card and comment',
},
],
},
// ----------------------------------
// board:delete
// ----------------------------------
{
displayName: 'Board ID',
name: 'boardId',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['board'],
},
},
description: 'The ID of the board to delete',
},
// ----------------------------------
// board:get
// ----------------------------------
{
displayName: 'Board ID',
name: 'boardId',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['board'],
},
},
description: 'The ID of the board to get',
},
// ----------------------------------
// board:getAll
// ----------------------------------
{
displayName: 'User Name or ID',
name: 'IdUser',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getUsers',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['getAll'],
resource: ['board'],
},
},
description:
'The ID of the user that boards are attached. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
operation: ['getAll'],
resource: ['board'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
operation: ['getAll'],
resource: ['board'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 200,
},
default: 100,
description: 'Max number of results to return',
},
];
@@ -0,0 +1,376 @@
import type { INodeProperties } from 'n8n-workflow';
export const cardCommentOperations: INodeProperties[] = [
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['cardComment'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a comment on a card',
action: 'Create a comment on a card',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a comment from a card',
action: 'Delete a comment from a card',
},
{
name: 'Get',
value: 'get',
description: 'Get a card comment',
action: 'Get a card comment',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many card comments',
action: 'Get many card comments',
},
],
default: 'create',
},
];
export const cardCommentFields: INodeProperties[] = [
// ----------------------------------
// cardComment:create
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['cardComment'],
},
},
description:
'The ID of the board that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['cardComment'],
},
},
description:
'The ID of the list that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Card Name or ID',
name: 'cardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCards',
loadOptionsDependsOn: ['boardId', 'listId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['cardComment'],
},
},
description:
'The ID of the card. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Author Name or ID',
name: 'authorId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getUsers',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['cardComment'],
},
},
description:
'The user who posted the comment. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Comment',
name: 'comment',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['cardComment'],
},
},
description: 'The comment text',
},
// ----------------------------------
// cardComment:delete
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['cardComment'],
},
},
description:
'The ID of the board that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['cardComment'],
},
},
description:
'The ID of the list that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Card Name or ID',
name: 'cardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCards',
loadOptionsDependsOn: ['boardId', 'listId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['cardComment'],
},
},
description:
'The ID of the card. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Comment Name or ID',
name: 'commentId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getComments',
loadOptionsDependsOn: ['boardId', 'cardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['cardComment'],
},
},
description:
'The ID of the comment to delete. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
// ----------------------------------
// cardComment:get
// ----------------------------------
{
displayName: 'Board ID',
name: 'boardId',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['cardComment'],
},
},
description: 'The ID of the board that card belongs to',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['cardComment'],
},
},
description:
'The ID of the list that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Card Name or ID',
name: 'cardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCards',
loadOptionsDependsOn: ['boardId', 'listId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['cardComment'],
},
},
description:
'The ID of the card. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Comment ID',
name: 'commentId',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['cardComment'],
},
},
description: 'The ID of the comment to get',
},
// ----------------------------------
// cardComment:getAll
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['getAll'],
resource: ['cardComment'],
},
},
description:
'The ID of the board that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['getAll'],
resource: ['cardComment'],
},
},
description:
'The ID of the list that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Card Name or ID',
name: 'cardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCards',
loadOptionsDependsOn: ['boardId', 'listId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['getAll'],
resource: ['cardComment'],
},
},
description:
'The ID of the card. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
operation: ['getAll'],
resource: ['cardComment'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
operation: ['getAll'],
resource: ['cardComment'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 200,
},
default: 100,
description: 'Max number of results to return',
},
];
@@ -0,0 +1,747 @@
import type { INodeProperties } from 'n8n-workflow';
export const cardOperations: INodeProperties[] = [
// ----------------------------------
// card
// ----------------------------------
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['card'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new card',
action: 'Create a card',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a card',
action: 'Delete a card',
},
{
name: 'Get',
value: 'get',
description: 'Get a card',
action: 'Get a card',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many cards',
action: 'Get many cards',
},
{
name: 'Update',
value: 'update',
description: 'Update a card',
action: 'Update a card',
},
],
default: 'create',
},
];
export const cardFields: INodeProperties[] = [
// ----------------------------------
// card:create
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['card'],
},
}, // Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>
description:
'The ID of the board that list belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['card'],
},
},
description:
'The ID of the list to create card in. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Title',
name: 'title',
type: 'string',
default: '',
placeholder: 'My card',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['card'],
},
},
description: 'The title of the card',
},
{
displayName: 'Swimlane Name or ID',
name: 'swimlaneId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getSwimlanes',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['card'],
},
},
description:
'The swimlane ID of the new card. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Author Name or ID',
name: 'authorId',
type: 'options',
description:
'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
typeOptions: {
loadOptionsMethod: 'getUsers',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['card'],
},
},
},
{
displayName: 'Additional Fields',
name: 'additionalFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['create'],
resource: ['card'],
},
},
default: {},
options: [
{
displayName: 'Assignee Names or IDs',
name: 'assignees',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getUsers',
},
default: [],
description:
'The new list of assignee IDs attached to the card. Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Description',
name: 'description',
type: 'string',
default: '',
description: 'The new description of the card',
},
{
displayName: 'Member Names or IDs',
name: 'members',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getUsers',
},
default: [],
description:
'The new list of member IDs attached to the card. Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
],
},
// ----------------------------------
// card:delete
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['card'],
},
},
description:
'The ID of the board that list belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['card'],
},
},
description:
'The ID of the list that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Card Name or ID',
name: 'cardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCards',
loadOptionsDependsOn: ['boardId', 'listId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['card'],
},
},
description:
'The ID of the card to delete. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
// ----------------------------------
// card:get
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['card'],
},
},
description:
'The ID of the board that list belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['card'],
},
},
description:
'The ID of the list that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Card ID',
name: 'cardId',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['card'],
},
},
description: 'The ID of the card to get',
},
// ----------------------------------
// card:getAll
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['getAll'],
resource: ['card'],
},
},
description:
'The ID of the board that list belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'From Object',
name: 'fromObject',
type: 'options',
required: true,
displayOptions: {
show: {
operation: ['getAll'],
resource: ['card'],
},
},
options: [
{
name: 'List',
value: 'list',
},
{
name: 'Swimlane',
value: 'swimlane',
},
],
default: '',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
fromObject: ['list'],
operation: ['getAll'],
resource: ['card'],
},
},
description:
'The ID of the list that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Swimlane Name or ID',
name: 'swimlaneId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getSwimlanes',
loadOptionsDependsOn: ['boardId'],
},
default: '',
displayOptions: {
show: {
fromObject: ['swimlane'],
operation: ['getAll'],
resource: ['card'],
},
},
description:
'The ID of the swimlane that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
operation: ['getAll'],
resource: ['card'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
operation: ['getAll'],
resource: ['card'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 200,
},
default: 100,
description: 'Max number of results to return',
},
// ----------------------------------
// card:update
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource: ['card'],
},
},
description:
'The ID of the board that list belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource: ['card'],
},
},
description:
'The ID of the list that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Card Name or ID',
name: 'cardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCards',
loadOptionsDependsOn: ['boardId', 'listId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource: ['card'],
},
},
description:
'The ID of the card to update. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['update'],
resource: ['card'],
},
},
default: {},
options: [
{
displayName: 'Author Name or ID',
name: 'authorId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getUsers',
},
default: '',
description:
'Update the owner of the card. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Assignee Names or IDs',
name: 'assignees',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getUsers',
},
default: [],
description:
'The new list of assignee IDs attached to the card. Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Color',
name: 'color',
type: 'options',
options: [
{
value: 'black',
name: 'Black',
},
{
value: 'blue',
name: 'Blue',
},
{
value: 'crimson',
name: 'Crimson',
},
{
value: 'darkgreen',
name: 'Darkgreen',
},
{
value: 'gold',
name: 'Gold',
},
{
value: 'gray',
name: 'Gray',
},
{
value: 'green',
name: 'Green',
},
{
value: 'indigo',
name: 'Indigo',
},
{
value: 'lime',
name: 'Lime',
},
{
value: 'magenta',
name: 'Magenta',
},
{
value: 'mistyrose',
name: 'Mistyrose',
},
{
value: 'navy',
name: 'Navy',
},
{
value: 'orange',
name: 'Orange',
},
{
value: 'paleturquoise',
name: 'Paleturquoise',
},
{
value: 'peachpuff',
name: 'Peachpuff',
},
{
value: 'pink',
name: 'Pink',
},
{
value: 'plum',
name: 'Plum',
},
{
value: 'purple',
name: 'Purple',
},
{
value: 'red',
name: 'Red',
},
{
value: 'saddlebrown',
name: 'Saddlebrown',
},
{
value: 'silver',
name: 'Silver',
},
{
value: 'sky',
name: 'Sky',
},
{
value: 'slateblue',
name: 'Slateblue',
},
{
value: 'white',
name: 'White',
},
{
value: 'yellow',
name: 'Yellow',
},
],
default: '',
description: 'The new color of the card',
},
{
displayName: 'Description',
name: 'description',
type: 'string',
default: '',
description: 'The new description of the card',
},
{
displayName: 'Due At',
name: 'dueAt',
type: 'dateTime',
default: '',
description: 'The new due at field of the card',
},
{
displayName: 'End At',
name: 'endAt',
type: 'dateTime',
default: '',
description: 'The new end at field of the card',
},
{
displayName: 'Label IDs',
name: 'labelIds',
type: 'string',
default: '',
description: 'The label IDs attached to the card',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
description:
'The new list ID of the card (move operation). Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Member Names or IDs',
name: 'members',
type: 'multiOptions',
typeOptions: {
loadOptionsMethod: 'getUsers',
},
default: [],
description:
'The new list of member IDs attached to the card. Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Over Time',
name: 'isOverTime',
type: 'boolean',
default: false,
// eslint-disable-next-line n8n-nodes-base/node-param-description-boolean-without-whether
description: 'The new over time field of the card',
},
{
displayName: 'Parent Name or ID',
name: 'parentId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCards',
loadOptionsDependsOn: ['boardId', 'listId'],
},
default: '',
description:
'The parent of the card. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Received At',
name: 'receivedAt',
type: 'dateTime',
default: '',
description: 'The new received at field of the card',
},
{
displayName: 'Sort',
name: 'sort',
type: 'number',
default: 0,
description: 'The internally used sort value of a card',
},
{
displayName: 'Spent Time',
name: 'spentTime',
type: 'number',
typeOptions: {
minValue: 0,
},
default: '',
description: 'The new spent time field of the card',
},
{
displayName: 'Start At',
name: 'startAt',
type: 'dateTime',
default: '',
description: 'The new start at field of the card',
},
{
displayName: 'Swimlane Name or ID',
name: 'swimlaneId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getSwimlanes',
loadOptionsDependsOn: ['boardId'],
},
default: '',
description:
'The new swimlane ID of the card. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Title',
name: 'title',
type: 'string',
default: '',
description: 'The new title of the card',
},
],
},
];
@@ -0,0 +1,387 @@
import type { INodeProperties } from 'n8n-workflow';
export const checklistOperations: INodeProperties[] = [
// ----------------------------------
// checklist
// ----------------------------------
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['checklist'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new checklist',
action: 'Create a checklist',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a checklist',
action: 'Delete a checklist',
},
{
name: 'Get',
value: 'get',
description: 'Get the data of a checklist',
action: 'Get a checklist',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Returns many checklists for the card',
action: 'Get many checklists',
},
],
default: 'getAll',
},
];
export const checklistFields: INodeProperties[] = [
// ----------------------------------
// checklist:create
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['checklist'],
},
},
description:
'The ID of the board where the card is in. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['checklist'],
},
},
description:
'The ID of the list that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Card Name or ID',
name: 'cardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCards',
loadOptionsDependsOn: ['boardId', 'listId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['checklist'],
},
},
description:
'The ID of the card to add checklist to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Title',
name: 'title',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['checklist'],
},
},
description: 'The title of the checklist to add',
},
{
displayName: 'Items',
name: 'items',
type: 'string',
typeOptions: {
multipleValues: true,
multipleValueButtonText: 'Add Item',
},
displayOptions: {
show: {
operation: ['create'],
resource: ['checklist'],
},
},
default: [],
description: 'Items to be added to the checklist',
},
// ----------------------------------
// checklist:delete
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['checklist'],
},
},
description:
'The ID of the board that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['checklist'],
},
},
description:
'The ID of the list that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Card Name or ID',
name: 'cardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCards',
loadOptionsDependsOn: ['boardId', 'listId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['checklist'],
},
},
description:
'The ID of the card that checklist belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Checklist Name or ID',
name: 'checklistId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChecklists',
loadOptionsDependsOn: ['boardId', 'cardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['checklist'],
},
},
description:
'The ID of the checklist to delete. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
// ----------------------------------
// checklist:get
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['checklist'],
},
},
description:
'The ID of the board that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['checklist'],
},
},
description:
'The ID of the list that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Card Name or ID',
name: 'cardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCards',
loadOptionsDependsOn: ['boardId', 'listId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['checklist'],
},
},
description:
'The ID of the card that checklist belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Checklist Name or ID',
name: 'checklistId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChecklists',
loadOptionsDependsOn: ['boardId', 'cardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['checklist'],
},
},
description:
'The ID of the checklist to get. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
// ----------------------------------
// checklist:getAll
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['getAll'],
resource: ['checklist'],
},
},
description:
'The ID of the board that list belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['getAll'],
resource: ['checklist'],
},
},
description:
'The ID of the list that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Card Name or ID',
name: 'cardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCards',
loadOptionsDependsOn: ['boardId', 'listId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['getAll'],
resource: ['checklist'],
},
},
description:
'The ID of the card to get checklists. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
operation: ['getAll'],
resource: ['checklist'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
operation: ['getAll'],
resource: ['checklist'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 200,
},
default: 100,
description: 'Max number of results to return',
},
];
@@ -0,0 +1,359 @@
import type { INodeProperties } from 'n8n-workflow';
export const checklistItemOperations: INodeProperties[] = [
// ----------------------------------
// checklistItem
// ----------------------------------
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['checklistItem'],
},
},
options: [
{
name: 'Delete',
value: 'delete',
description: 'Delete a checklist item',
action: 'Delete a checklist item',
},
{
name: 'Get',
value: 'get',
description: 'Get a checklist item',
action: 'Get a checklist item',
},
{
name: 'Update',
value: 'update',
description: 'Update a checklist item',
action: 'Update a checklist item',
},
],
default: 'getAll',
},
];
export const checklistItemFields: INodeProperties[] = [
// ----------------------------------
// checklistItem:delete
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['checklistItem'],
},
},
description:
'The ID of the board that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['checklistItem'],
},
},
description:
'The ID of the list that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Card Name or ID',
name: 'cardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCards',
loadOptionsDependsOn: ['boardId', 'listId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['checklistItem'],
},
},
description:
'The ID of the card that checklistItem belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Checklist Name or ID',
name: 'checklistId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChecklists',
loadOptionsDependsOn: ['boardId', 'cardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['checklistItem'],
},
},
description:
'The ID of the checklistItem that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Checklist Item Name or ID',
name: 'checklistItemId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChecklistItems',
loadOptionsDependsOn: ['boardId', 'cardId', 'checklistId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['checklistItem'],
},
},
description:
'The ID of the checklistItem item to get. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
// ----------------------------------
// checklistItem:get
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['checklistItem'],
},
},
description:
'The ID of the board that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['checklistItem'],
},
},
description:
'The ID of the list that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Card Name or ID',
name: 'cardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCards',
loadOptionsDependsOn: ['boardId', 'listId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['checklistItem'],
},
},
description:
'The ID of the card that checklistItem belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Checklist ID',
name: 'checklistId',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['checklistItem'],
},
},
description: 'The ID of the checklistItem that card belongs to',
},
{
displayName: 'Checklist Item Name or ID',
name: 'checklistItemId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChecklistItems',
loadOptionsDependsOn: ['boardId', 'cardId', 'checklistId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['checklistItem'],
},
},
description:
'The ID of the checklistItem item to get. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
// ----------------------------------
// checklistItem:update
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource: ['checklistItem'],
},
},
description:
'The ID of the board that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource: ['checklistItem'],
},
},
description:
'The ID of the list that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Card Name or ID',
name: 'cardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getCards',
loadOptionsDependsOn: ['boardId', 'listId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource: ['checklistItem'],
},
},
description:
'The ID of the card that checklistItem belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'CheckList Name or ID',
name: 'checklistId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChecklists',
loadOptionsDependsOn: ['boardId', 'cardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource: ['checklistItem'],
},
},
description:
'The ID of the checklistItem that card belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Checklist Item Name or ID',
name: 'checklistItemId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getChecklistItems',
loadOptionsDependsOn: ['boardId', 'cardId', 'checklistId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['update'],
resource: ['checklistItem'],
},
},
description:
'The ID of the checklistItem item to update. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Update Fields',
name: 'updateFields',
type: 'collection',
placeholder: 'Add Field',
displayOptions: {
show: {
operation: ['update'],
resource: ['checklistItem'],
},
},
default: {},
options: [
{
displayName: 'Title',
name: 'title',
type: 'string',
default: '',
description: 'The new title for the checklistItem item',
},
{
displayName: 'Finished',
name: 'isFinished',
type: 'boolean',
default: false,
description: 'Whether the item is checked',
},
],
},
];
@@ -0,0 +1,33 @@
import type {
IDataObject,
IExecuteFunctions,
IHookFunctions,
IHttpRequestMethods,
ILoadOptionsFunctions,
IRequestOptions,
} from 'n8n-workflow';
export async function apiRequest(
this: IHookFunctions | IExecuteFunctions | ILoadOptionsFunctions,
method: IHttpRequestMethods,
endpoint: string,
body: object,
query?: IDataObject,
): Promise<any> {
const credentials = await this.getCredentials('wekanApi');
query = query || {};
const options: IRequestOptions = {
headers: {
Accept: 'application/json',
},
method,
body,
qs: query,
uri: `${credentials.url}/api/${endpoint}`,
json: true,
};
return await this.helpers.requestWithAuthentication.call(this, 'wekanApi', options);
}
@@ -0,0 +1,214 @@
import type { INodeProperties } from 'n8n-workflow';
export const listOperations: INodeProperties[] = [
// ----------------------------------
// list
// ----------------------------------
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: ['list'],
},
},
options: [
{
name: 'Create',
value: 'create',
description: 'Create a new list',
action: 'Create a list',
},
{
name: 'Delete',
value: 'delete',
description: 'Delete a list',
action: 'Delete a list',
},
{
name: 'Get',
value: 'get',
description: 'Get the data of a list',
action: 'Get a list',
},
{
name: 'Get Many',
value: 'getAll',
description: 'Get many board lists',
action: 'Get many lists',
},
],
default: 'create',
},
];
export const listFields: INodeProperties[] = [
// ----------------------------------
// list:create
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['list'],
},
},
description:
'The ID of the board the list should be created in. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Title',
name: 'title',
type: 'string',
default: '',
placeholder: 'My list',
required: true,
displayOptions: {
show: {
operation: ['create'],
resource: ['list'],
},
},
description: 'The title of the list',
},
// ----------------------------------
// list:delete
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['list'],
},
},
description:
'The ID of the board that list belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List Name or ID',
name: 'listId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getLists',
loadOptionsDependsOn: ['boardId'],
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['delete'],
resource: ['list'],
},
},
description:
'The ID of the list to delete. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
// ----------------------------------
// list:get
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['list'],
},
},
description:
'The ID of the board that list belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'List ID',
name: 'listId',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
operation: ['get'],
resource: ['list'],
},
},
description: 'The ID of the list to get',
},
// ----------------------------------
// list:getAll
// ----------------------------------
{
displayName: 'Board Name or ID',
name: 'boardId',
type: 'options',
typeOptions: {
loadOptionsMethod: 'getBoards',
},
default: '',
required: true,
displayOptions: {
show: {
operation: ['getAll'],
resource: ['list'],
},
},
description:
'ID of the board where the lists are in. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
},
{
displayName: 'Return All',
name: 'returnAll',
type: 'boolean',
displayOptions: {
show: {
operation: ['getAll'],
resource: ['list'],
},
},
default: false,
description: 'Whether to return all results or only up to a given limit',
},
{
displayName: 'Limit',
name: 'limit',
type: 'number',
displayOptions: {
show: {
operation: ['getAll'],
resource: ['list'],
returnAll: [false],
},
},
typeOptions: {
minValue: 1,
maxValue: 200,
},
default: 100,
description: 'Max number of results to return',
},
];
@@ -0,0 +1,18 @@
{
"node": "n8n-nodes-base.wekan",
"nodeVersion": "1.0",
"codexVersion": "1.0",
"categories": ["Productivity"],
"resources": {
"credentialDocumentation": [
{
"url": "https://docs.n8n.io/integrations/builtin/credentials/wekan/"
}
],
"primaryDocumentation": [
{
"url": "https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.wekan/"
}
]
}
}
@@ -0,0 +1,676 @@
import type {
IExecuteFunctions,
IDataObject,
ILoadOptionsFunctions,
INodeExecutionData,
INodePropertyOptions,
INodeType,
INodeTypeDescription,
IHttpRequestMethods,
} from 'n8n-workflow';
import { NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';
import { boardFields, boardOperations } from './BoardDescription';
import { cardCommentFields, cardCommentOperations } from './CardCommentDescription';
import { cardFields, cardOperations } from './CardDescription';
import { checklistFields, checklistOperations } from './ChecklistDescription';
import { checklistItemFields, checklistItemOperations } from './ChecklistItemDescription';
import { apiRequest } from './GenericFunctions';
import { listFields, listOperations } from './ListDescription';
import { wrapData } from '../../utils/utilities';
// https://wekan.github.io/api/v4.41/
export class Wekan implements INodeType {
description: INodeTypeDescription = {
displayName: 'Wekan',
name: 'wekan',
icon: 'file:wekan.svg',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'Consume Wekan API',
defaults: {
name: 'Wekan',
},
usableAsTool: true,
inputs: [NodeConnectionTypes.Main],
outputs: [NodeConnectionTypes.Main],
credentials: [
{
name: 'wekanApi',
required: true,
},
],
properties: [
{
displayName: 'Resource',
name: 'resource',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Board',
value: 'board',
},
{
name: 'Card',
value: 'card',
},
{
name: 'Card Comment',
value: 'cardComment',
},
{
name: 'Checklist',
value: 'checklist',
},
{
name: 'Checklist Item',
value: 'checklistItem',
},
{
name: 'List',
value: 'list',
},
],
default: 'card',
},
// ----------------------------------
// operations
// ----------------------------------
...boardOperations,
...cardOperations,
...cardCommentOperations,
...checklistOperations,
...checklistItemOperations,
...listOperations,
// ----------------------------------
// fields
// ----------------------------------
...boardFields,
...cardFields,
...cardCommentFields,
...checklistFields,
...checklistItemFields,
...listFields,
],
};
methods = {
loadOptions: {
async getUsers(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const users = await apiRequest.call(this, 'GET', 'users', {}, {});
for (const user of users) {
returnData.push({
name: user.username,
value: user._id,
});
}
return returnData;
},
async getBoards(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const user = await apiRequest.call(this, 'GET', 'user', {}, {});
const boards = await apiRequest.call(this, 'GET', `users/${user._id}/boards`, {}, {});
for (const board of boards) {
returnData.push({
name: board.title,
value: board._id,
});
}
return returnData;
},
async getLists(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const boardId = this.getCurrentNodeParameter('boardId') as string;
const lists = await apiRequest.call(this, 'GET', `boards/${boardId}/lists`, {}, {});
for (const list of lists) {
returnData.push({
name: list.title,
value: list._id,
});
}
return returnData;
},
async getSwimlanes(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const boardId = this.getCurrentNodeParameter('boardId') as string;
const swimlanes = await apiRequest.call(this, 'GET', `boards/${boardId}/swimlanes`, {}, {});
for (const swimlane of swimlanes) {
returnData.push({
name: swimlane.title,
value: swimlane._id,
});
}
return returnData;
},
async getCards(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const boardId = this.getCurrentNodeParameter('boardId') as string;
const listId = this.getCurrentNodeParameter('listId') as string;
const cards = await apiRequest.call(
this,
'GET',
`boards/${boardId}/lists/${listId}/cards`,
{},
{},
);
for (const card of cards) {
returnData.push({
name: card.title,
value: card._id,
});
}
return returnData;
},
async getChecklists(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const boardId = this.getCurrentNodeParameter('boardId') as string;
const cardId = this.getCurrentNodeParameter('cardId') as string;
const checklists = await apiRequest.call(
this,
'GET',
`boards/${boardId}/cards/${cardId}/checklists`,
{},
{},
);
for (const checklist of checklists) {
returnData.push({
name: checklist.title,
value: checklist._id,
});
}
return returnData;
},
async getChecklistItems(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const boardId = this.getCurrentNodeParameter('boardId') as string;
const cardId = this.getCurrentNodeParameter('cardId') as string;
const checklistId = this.getCurrentNodeParameter('checklistId') as string;
const checklist = await apiRequest.call(
this,
'GET',
`boards/${boardId}/cards/${cardId}/checklists/${checklistId}`,
{},
{},
);
for (const item of checklist.items) {
returnData.push({
name: item.title,
value: item._id,
});
}
return returnData;
},
async getComments(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = [];
const boardId = this.getCurrentNodeParameter('boardId') as string;
const cardId = this.getCurrentNodeParameter('cardId') as string;
const comments = await apiRequest.call(
this,
'GET',
`boards/${boardId}/cards/${cardId}/comments`,
{},
{},
);
for (const comment of comments) {
returnData.push({
name: comment.comment,
value: comment._id,
});
}
return returnData;
},
},
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
const returnData: INodeExecutionData[] = [];
let returnAll;
let limit;
const operation = this.getNodeParameter('operation', 0);
const resource = this.getNodeParameter('resource', 0);
// For Post
let body: IDataObject;
// For Query string
let qs: IDataObject;
let requestMethod: IHttpRequestMethods;
let endpoint: string;
for (let i = 0; i < items.length; i++) {
try {
requestMethod = 'GET';
endpoint = '';
body = {};
qs = {};
if (resource === 'board') {
if (operation === 'create') {
// ----------------------------------
// create
// ----------------------------------
requestMethod = 'POST';
endpoint = 'boards';
body.title = this.getNodeParameter('title', i) as string;
body.owner = this.getNodeParameter('owner', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i);
Object.assign(body, additionalFields);
} else if (operation === 'delete') {
// ----------------------------------
// delete
// ----------------------------------
requestMethod = 'DELETE';
const boardId = this.getNodeParameter('boardId', i) as string;
endpoint = `boards/${boardId}`;
} else if (operation === 'get') {
// ----------------------------------
// get
// ----------------------------------
requestMethod = 'GET';
const boardId = this.getNodeParameter('boardId', i) as string;
endpoint = `boards/${boardId}`;
} else if (operation === 'getAll') {
// ----------------------------------
// getAll
// ----------------------------------
requestMethod = 'GET';
const userId = this.getNodeParameter('IdUser', i) as string;
returnAll = this.getNodeParameter('returnAll', i);
endpoint = `users/${userId}/boards`;
} else {
throw new NodeOperationError(
this.getNode(),
`The operation "${operation}" is not known!`,
{ itemIndex: i },
);
}
} else if (resource === 'card') {
if (operation === 'create') {
// ----------------------------------
// create
// ----------------------------------
requestMethod = 'POST';
const boardId = this.getNodeParameter('boardId', i) as string;
const listId = this.getNodeParameter('listId', i) as string;
endpoint = `boards/${boardId}/lists/${listId}/cards`;
body.title = this.getNodeParameter('title', i) as string;
body.swimlaneId = this.getNodeParameter('swimlaneId', i) as string;
body.authorId = this.getNodeParameter('authorId', i) as string;
const additionalFields = this.getNodeParameter('additionalFields', i);
Object.assign(body, additionalFields);
} else if (operation === 'delete') {
// ----------------------------------
// delete
// ----------------------------------
requestMethod = 'DELETE';
const boardId = this.getNodeParameter('boardId', i) as string;
const listId = this.getNodeParameter('listId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
endpoint = `boards/${boardId}/lists/${listId}/cards/${cardId}`;
} else if (operation === 'get') {
// ----------------------------------
// get
// ----------------------------------
requestMethod = 'GET';
const boardId = this.getNodeParameter('boardId', i) as string;
const listId = this.getNodeParameter('listId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
endpoint = `boards/${boardId}/lists/${listId}/cards/${cardId}`;
} else if (operation === 'getAll') {
// ----------------------------------
// getAll
// ----------------------------------
requestMethod = 'GET';
const boardId = this.getNodeParameter('boardId', i) as string;
const fromObject = this.getNodeParameter('fromObject', i) as string;
returnAll = this.getNodeParameter('returnAll', i);
if (fromObject === 'list') {
const listId = this.getNodeParameter('listId', i) as string;
endpoint = `boards/${boardId}/lists/${listId}/cards`;
}
if (fromObject === 'swimlane') {
const swimlaneId = this.getNodeParameter('swimlaneId', i) as string;
endpoint = `boards/${boardId}/swimlanes/${swimlaneId}/cards`;
}
} else if (operation === 'update') {
// ----------------------------------
// update
// ----------------------------------
requestMethod = 'PUT';
const boardId = this.getNodeParameter('boardId', i) as string;
const listId = this.getNodeParameter('listId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
endpoint = `boards/${boardId}/lists/${listId}/cards/${cardId}`;
const updateFields = this.getNodeParameter('updateFields', i);
Object.assign(body, updateFields);
} else {
throw new NodeOperationError(
this.getNode(),
`The operation "${operation}" is not known!`,
{ itemIndex: i },
);
}
} else if (resource === 'cardComment') {
if (operation === 'create') {
// ----------------------------------
// create
// ----------------------------------
requestMethod = 'POST';
const boardId = this.getNodeParameter('boardId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
endpoint = `boards/${boardId}/cards/${cardId}/comments`;
body.authorId = this.getNodeParameter('authorId', i) as string;
body.comment = this.getNodeParameter('comment', i) as string;
} else if (operation === 'delete') {
// ----------------------------------
// delete
// ----------------------------------
requestMethod = 'DELETE';
const boardId = this.getNodeParameter('boardId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
const commentId = this.getNodeParameter('commentId', i) as string;
endpoint = `boards/${boardId}/cards/${cardId}/comments/${commentId}`;
} else if (operation === 'get') {
// ----------------------------------
// get
// ----------------------------------
requestMethod = 'GET';
const boardId = this.getNodeParameter('boardId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
const commentId = this.getNodeParameter('commentId', i) as string;
endpoint = `boards/${boardId}/cards/${cardId}/comments/${commentId}`;
} else if (operation === 'getAll') {
// ----------------------------------
// getAll
// ----------------------------------
requestMethod = 'GET';
const boardId = this.getNodeParameter('boardId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
endpoint = `boards/${boardId}/cards/${cardId}/comments`;
} else {
throw new NodeOperationError(
this.getNode(),
`The operation "${operation}" is not known!`,
{ itemIndex: i },
);
}
} else if (resource === 'list') {
if (operation === 'create') {
// ----------------------------------
// create
// ----------------------------------
requestMethod = 'POST';
const boardId = this.getNodeParameter('boardId', i) as string;
endpoint = `boards/${boardId}/lists`;
body.title = this.getNodeParameter('title', i) as string;
} else if (operation === 'delete') {
// ----------------------------------
// delete
// ----------------------------------
requestMethod = 'DELETE';
const boardId = this.getNodeParameter('boardId', i) as string;
const listId = this.getNodeParameter('listId', i) as string;
endpoint = `boards/${boardId}/lists/${listId}`;
} else if (operation === 'get') {
// ----------------------------------
// get
// ----------------------------------
requestMethod = 'GET';
const boardId = this.getNodeParameter('boardId', i) as string;
const listId = this.getNodeParameter('listId', i) as string;
endpoint = `boards/${boardId}/lists/${listId}`;
} else if (operation === 'getAll') {
// ----------------------------------
// getAll
// ----------------------------------
requestMethod = 'GET';
const boardId = this.getNodeParameter('boardId', i) as string;
returnAll = this.getNodeParameter('returnAll', i);
endpoint = `boards/${boardId}/lists`;
} else {
throw new NodeOperationError(
this.getNode(),
`The operation "${operation}" is not known!`,
{ itemIndex: i },
);
}
} else if (resource === 'checklist') {
if (operation === 'create') {
// ----------------------------------
// create
// ----------------------------------
requestMethod = 'POST';
const boardId = this.getNodeParameter('boardId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
endpoint = `boards/${boardId}/cards/${cardId}/checklists`;
body.title = this.getNodeParameter('title', i) as string;
body.items = this.getNodeParameter('items', i) as string[];
} else if (operation === 'delete') {
// ----------------------------------
// delete
// ----------------------------------
requestMethod = 'DELETE';
const boardId = this.getNodeParameter('boardId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
const checklistId = this.getNodeParameter('checklistId', i) as string;
endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}`;
} else if (operation === 'get') {
// ----------------------------------
// get
// ----------------------------------
requestMethod = 'GET';
const boardId = this.getNodeParameter('boardId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
const checklistId = this.getNodeParameter('checklistId', i) as string;
endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}`;
} else if (operation === 'getAll') {
// ----------------------------------
// getAll
// ----------------------------------
requestMethod = 'GET';
const boardId = this.getNodeParameter('boardId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
returnAll = this.getNodeParameter('returnAll', i);
endpoint = `boards/${boardId}/cards/${cardId}/checklists`;
} else if (operation === 'getCheckItem') {
// ----------------------------------
// getCheckItem
// ----------------------------------
requestMethod = 'GET';
const boardId = this.getNodeParameter('boardId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
const checklistId = this.getNodeParameter('checklistId', i) as string;
const itemId = this.getNodeParameter('itemId', i) as string;
endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`;
} else if (operation === 'deleteCheckItem') {
// ----------------------------------
// deleteCheckItem
// ----------------------------------
requestMethod = 'DELETE';
const boardId = this.getNodeParameter('boardId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
const checklistId = this.getNodeParameter('checklistId', i) as string;
const itemId = this.getNodeParameter('itemId', i) as string;
endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`;
} else if (operation === 'updateCheckItem') {
// ----------------------------------
// updateCheckItem
// ----------------------------------
requestMethod = 'PUT';
const boardId = this.getNodeParameter('boardId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
const checklistId = this.getNodeParameter('checklistId', i) as string;
const itemId = this.getNodeParameter('itemId', i) as string;
endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`;
const updateFields = this.getNodeParameter('updateFields', i);
Object.assign(body, updateFields);
} else {
throw new NodeOperationError(
this.getNode(),
`The operation "${operation}" is not known!`,
{ itemIndex: i },
);
}
} else if (resource === 'checklistItem') {
if (operation === 'get') {
// ----------------------------------
// get
// ----------------------------------
requestMethod = 'GET';
const boardId = this.getNodeParameter('boardId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
const checklistId = this.getNodeParameter('checklistId', i) as string;
const itemId = this.getNodeParameter('checklistItemId', i) as string;
endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`;
} else if (operation === 'delete') {
// ----------------------------------
// delete
// ----------------------------------
requestMethod = 'DELETE';
const boardId = this.getNodeParameter('boardId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
const checklistId = this.getNodeParameter('checklistId', i) as string;
const itemId = this.getNodeParameter('checklistItemId', i) as string;
endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`;
} else if (operation === 'update') {
// ----------------------------------
// update
// ----------------------------------
requestMethod = 'PUT';
const boardId = this.getNodeParameter('boardId', i) as string;
const cardId = this.getNodeParameter('cardId', i) as string;
const checklistId = this.getNodeParameter('checklistId', i) as string;
const itemId = this.getNodeParameter('checklistItemId', i) as string;
endpoint = `boards/${boardId}/cards/${cardId}/checklists/${checklistId}/items/${itemId}`;
const updateFields = this.getNodeParameter('updateFields', i);
Object.assign(body, updateFields);
}
}
let responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs);
if (returnAll === false && Array.isArray(responseData)) {
limit = this.getNodeParameter('limit', i);
responseData = responseData.splice(0, limit);
}
const executionData = this.helpers.constructExecutionMetaData(
wrapData(responseData as IDataObject[]),
{ itemData: { item: i } },
);
returnData.push(...executionData);
} catch (error) {
if (this.continueOnFail()) {
returnData.push({ json: { error: error.message }, pairedItem: { item: i } });
continue;
}
throw error;
}
}
return [this.helpers.returnJsonArray(returnData)];
}
}
@@ -0,0 +1,4 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M34 0H6C2.68629 0 0 2.68629 0 6V34C0 37.3137 2.68629 40 6 40H34C37.3137 40 40 37.3137 40 34V6C40 2.68629 37.3137 0 34 0Z" fill="#006984"/>
<path d="M29.0627 24.1405C29.0627 24.1405 29.4533 23.5937 29.5315 23.2812L29.6096 23.0468L29.1408 23.1249C29.0627 23.203 28.7502 24.1405 27.6565 25.1562C27.0315 25.703 26.3283 25.8593 25.7033 25.7812C25.2346 25.7812 24.9221 25.4687 24.6877 24.9218C24.5315 24.3749 24.4533 23.7499 24.6096 22.9687C24.9221 21.4843 25.3127 20.703 25.8596 20.703C26.4846 21.2499 25.6252 23.4374 24.9221 23.9843L24.6877 24.2187H25.0002C25.7815 23.9843 26.4065 23.7499 27.0315 23.3593C27.5783 22.9687 27.969 22.578 28.1252 22.1874C28.2033 21.7187 28.0471 21.328 27.6565 21.0155C27.2658 20.703 26.719 20.5468 26.094 20.4687C25.469 20.4687 24.844 20.5468 24.2971 20.8593C25.0783 19.3749 25.9377 17.8905 26.4065 16.4062C26.7971 15.078 26.719 14.0624 26.0158 13.4374C25.7815 13.203 25.469 13.0468 25.0002 12.9687C24.0627 12.7343 23.1252 12.4218 23.8283 13.4374C23.9846 13.5937 24.0627 13.828 24.0627 13.9843C24.4533 16.4062 23.5158 18.3593 22.6565 20.1562C21.7971 21.8749 20.6252 24.3749 18.9846 25.3124L18.9065 25.078C18.8283 24.6874 18.9065 24.3749 18.9846 23.9843L19.5315 21.0155L20.1565 18.1249L20.3908 16.953C20.469 16.6405 20.3908 16.4843 20.3127 16.328L18.9846 15.5468C18.3596 15.1562 18.3596 15.1562 18.1252 15.7812L17.2658 18.203C16.4547 20.2649 15.5154 22.2741 14.4533 24.2187C13.9846 24.9999 13.594 25.3905 13.2815 25.3905C12.969 25.1562 13.1252 24.6874 13.2033 24.453C13.2815 23.5155 13.594 22.4999 13.7502 21.7187L14.4533 19.2187L15.0002 17.1093L15.469 15.6249C15.469 15.3905 15.3127 15.1562 15.0783 14.9999L13.9065 14.2968C13.5158 14.0624 13.3596 14.1405 12.969 14.2187C10.9051 14.9975 8.9175 15.9652 7.03146 17.1093C6.17208 17.7343 5.62521 18.203 5.39083 18.6718C5.07833 19.2968 5.15646 19.8437 5.46896 20.3905C5.62521 20.703 5.85958 21.0155 6.17208 21.2499C7.34396 22.0312 6.95333 21.5624 7.10958 20.6249C7.10958 20.3124 7.26583 19.9999 7.42208 19.6874C7.81271 19.0624 8.43771 18.2812 9.53146 17.4218C10.6252 16.6405 11.7971 15.9374 13.0471 15.3905L12.344 18.203L11.6408 21.1718C11.4065 22.2655 11.0158 23.2812 11.0158 24.3749C11.1721 25.3124 11.9533 26.0155 12.8908 26.0155C13.5158 26.0155 14.0627 25.6249 14.6096 24.8437C15.727 22.9004 16.6682 20.861 17.4221 18.7499L16.9533 21.2499L16.6408 23.4374C16.5627 24.0624 16.6408 24.6874 16.9533 25.1562C17.344 25.703 17.969 25.9374 18.594 26.0155C19.219 26.0155 20.0002 25.4687 21.094 24.453L21.7971 23.5937C21.7971 24.3749 22.0315 24.9218 22.5783 25.3905C23.2815 25.8593 24.0627 26.1718 25.0002 26.1718C26.4846 26.0937 28.2815 25.3124 29.0627 24.1405Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB