From 4c075db26c1cfe774ac36cb764505db20b6ce1bb Mon Sep 17 00:00:00 2001 From: ricardo Date: Mon, 24 Aug 2020 20:55:57 -0400 Subject: [PATCH] :zap: Add card comment operation --- .../nodes/Airtable/Airtable.node.ts | 2 +- .../nodes/Trello/AttachmentDescription.ts | 4 +- .../nodes/Trello/BoardDescription.ts | 4 +- .../nodes/Trello/CardCommentDescription.ts | 177 +++++++++++ .../nodes/Trello/CardDescription.ts | 4 +- .../nodes/Trello/ChecklistDescription.ts | 4 +- .../nodes/Trello/GenericFunctions.ts | 8 +- .../nodes/Trello/LabelDescription.ts | 4 +- .../nodes/Trello/ListDescription.ts | 295 ++++++++++-------- .../nodes-base/nodes/Trello/Trello.node.ts | 108 ++++++- 10 files changed, 463 insertions(+), 147 deletions(-) create mode 100644 packages/nodes-base/nodes/Trello/CardCommentDescription.ts diff --git a/packages/nodes-base/nodes/Airtable/Airtable.node.ts b/packages/nodes-base/nodes/Airtable/Airtable.node.ts index 25790c01e9..acdee495e4 100644 --- a/packages/nodes-base/nodes/Airtable/Airtable.node.ts +++ b/packages/nodes-base/nodes/Airtable/Airtable.node.ts @@ -367,7 +367,7 @@ export class Airtable implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; const application = this.getNodeParameter('application', 0) as string; - const table = this.getNodeParameter('table', 0) as string; + const table = encodeURI(this.getNodeParameter('table', 0) as string); let returnAll = false; let endpoint = ''; diff --git a/packages/nodes-base/nodes/Trello/AttachmentDescription.ts b/packages/nodes-base/nodes/Trello/AttachmentDescription.ts index 4306b2ed11..9b473a9a65 100644 --- a/packages/nodes-base/nodes/Trello/AttachmentDescription.ts +++ b/packages/nodes-base/nodes/Trello/AttachmentDescription.ts @@ -1,4 +1,6 @@ -import { INodeProperties } from "n8n-workflow"; +import { + INodeProperties, +} from "n8n-workflow"; export const attachmentOperations = [ // ---------------------------------- diff --git a/packages/nodes-base/nodes/Trello/BoardDescription.ts b/packages/nodes-base/nodes/Trello/BoardDescription.ts index b089d689ce..d9b0eead48 100644 --- a/packages/nodes-base/nodes/Trello/BoardDescription.ts +++ b/packages/nodes-base/nodes/Trello/BoardDescription.ts @@ -1,4 +1,6 @@ -import { INodeProperties } from "n8n-workflow"; +import { + INodeProperties, +} from "n8n-workflow"; export const boardOperations = [ // ---------------------------------- diff --git a/packages/nodes-base/nodes/Trello/CardCommentDescription.ts b/packages/nodes-base/nodes/Trello/CardCommentDescription.ts new file mode 100644 index 0000000000..1ce873f16e --- /dev/null +++ b/packages/nodes-base/nodes/Trello/CardCommentDescription.ts @@ -0,0 +1,177 @@ +import { + INodeProperties, +} from "n8n-workflow"; + +export const cardCommentOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'cardComment', + ], + }, + }, + options: [ + { + name: 'Add', + value: 'add', + description: 'Add a comment to a card', + }, + { + name: 'Revove', + value: 'remove', + description: 'Remove a comment from a card', + }, + { + name: 'Update', + value: 'update', + description: 'Update a comment in a card', + }, + ], + default: 'add', + description: 'The operation to perform.', + }, +] as INodeProperties[]; + +export const cardCommentFields = [ + // ---------------------------------- + // cardComment:add + // ---------------------------------- + { + displayName: 'Card ID', + name: 'cardId', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + operation: [ + 'add', + ], + resource: [ + 'cardComment', + ], + }, + }, + description: 'The id of the card', + }, + { + displayName: 'Text', + name: 'text', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + operation: [ + 'add', + ], + resource: [ + 'cardComment', + ], + }, + }, + description: 'Text of the comment', + }, + + // ---------------------------------- + // cardComment:remove + // ---------------------------------- + { + displayName: 'Card ID', + name: 'cardId', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + operation: [ + 'remove', + ], + resource: [ + 'cardComment', + ], + }, + }, + description: 'The ID of the card.', + }, + { + displayName: 'Comment ID', + name: 'commentId', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + operation: [ + 'remove', + ], + resource: [ + 'cardComment', + ], + }, + }, + description: 'The ID of the comment to delete.', + }, + + // ---------------------------------- + // cardComment:update + // ---------------------------------- + { + displayName: 'Card ID', + name: 'cardId', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'cardComment', + ], + }, + }, + description: 'The ID of the card to update.', + }, + { + displayName: 'Comment ID', + name: 'commentId', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'cardComment', + ], + }, + }, + description: 'The ID of the comment to delete.', + }, + { + displayName: 'Text', + name: 'text', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'cardComment', + ], + }, + }, + description: 'Text of the comment', + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Trello/CardDescription.ts b/packages/nodes-base/nodes/Trello/CardDescription.ts index 6b5158e6d1..0352e3e2d0 100644 --- a/packages/nodes-base/nodes/Trello/CardDescription.ts +++ b/packages/nodes-base/nodes/Trello/CardDescription.ts @@ -1,4 +1,6 @@ -import { INodeProperties } from "n8n-workflow"; +import { + INodeProperties, +} from "n8n-workflow"; export const cardOperations = [ // ---------------------------------- diff --git a/packages/nodes-base/nodes/Trello/ChecklistDescription.ts b/packages/nodes-base/nodes/Trello/ChecklistDescription.ts index be11ba6f17..a8ecb03e6d 100644 --- a/packages/nodes-base/nodes/Trello/ChecklistDescription.ts +++ b/packages/nodes-base/nodes/Trello/ChecklistDescription.ts @@ -1,4 +1,6 @@ -import { INodeProperties } from "n8n-workflow"; +import { + INodeProperties, +} from 'n8n-workflow'; export const checklistOperations = [ // ---------------------------------- diff --git a/packages/nodes-base/nodes/Trello/GenericFunctions.ts b/packages/nodes-base/nodes/Trello/GenericFunctions.ts index 831d3f3b43..b7c65c242b 100644 --- a/packages/nodes-base/nodes/Trello/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Trello/GenericFunctions.ts @@ -4,9 +4,13 @@ import { ILoadOptionsFunctions, } from 'n8n-core'; -import { OptionsWithUri } from 'request'; -import { IDataObject } from 'n8n-workflow'; +import { + OptionsWithUri, +} from 'request'; +import { + IDataObject, +} from 'n8n-workflow'; /** * Make an API request to Trello diff --git a/packages/nodes-base/nodes/Trello/LabelDescription.ts b/packages/nodes-base/nodes/Trello/LabelDescription.ts index 2b938ae5de..3aaa918098 100644 --- a/packages/nodes-base/nodes/Trello/LabelDescription.ts +++ b/packages/nodes-base/nodes/Trello/LabelDescription.ts @@ -1,4 +1,6 @@ -import { INodeProperties } from "n8n-workflow"; +import { + INodeProperties, +} from 'n8n-workflow'; export const labelOperations = [ // ---------------------------------- diff --git a/packages/nodes-base/nodes/Trello/ListDescription.ts b/packages/nodes-base/nodes/Trello/ListDescription.ts index b6b4565632..105f841144 100644 --- a/packages/nodes-base/nodes/Trello/ListDescription.ts +++ b/packages/nodes-base/nodes/Trello/ListDescription.ts @@ -1,42 +1,46 @@ -import { INodeProperties } from "n8n-workflow"; +import { + INodeProperties, +} from 'n8n-workflow'; export const listOperations = [ // ---------------------------------- // list // ---------------------------------- { - displayName: "Operation", - name: "operation", - type: "options", + displayName: 'Operation', + name: 'operation', + type: 'options', displayOptions: { show: { - resource: ["list"] - } + resource: [ + 'list', + ], + }, }, options: [ { - name: "Archive", - value: "archive", - description: "Archive/Unarchive a list" + name: 'Archive', + value: 'archive', + description: 'Archive/Unarchive a list' }, { - name: "Create", - value: "create", - description: "Create a new list" + name: 'Create', + value: 'create', + description: 'Create a new list' }, { - name: "Get", - value: "get", - description: "Get the data of a list" + name: 'Get', + value: 'get', + description: 'Get the data of a list' }, { - name: "Update", - value: "update", - description: "Update a list" + name: 'Update', + value: 'update', + description: 'Update a list' } ], - default: "create", - description: "The operation to perform." + default: 'create', + description: 'The operation to perform.' } ] as INodeProperties[]; @@ -45,92 +49,112 @@ export const listFields = [ // list:archive // ---------------------------------- { - displayName: "List ID", - name: "id", - type: "string", - default: "", + displayName: 'List ID', + name: 'id', + type: 'string', + default: '', required: true, displayOptions: { show: { - operation: ["archive"], - resource: ["list"] - } + operation: [ + 'archive', + ], + resource: [ + 'list', + ], + }, }, - description: "The ID of the list to archive or unarchive." + description: 'The ID of the list to archive or unarchive.' }, { - displayName: "Archive", - name: "archive", - type: "boolean", + displayName: 'Archive', + name: 'archive', + type: 'boolean', default: false, displayOptions: { show: { - operation: ["archive"], - resource: ["list"] - } + operation: [ + 'archive', + ], + resource: [ + 'list', + ], + }, }, - description: "If the list should be archived or unarchived." + description: 'If the list should be archived or unarchived.' }, // ---------------------------------- // list:create // ---------------------------------- { - displayName: "Board ID", - name: "idBoard", - type: "string", - default: "", + displayName: 'Board ID', + name: 'idBoard', + type: 'string', + default: '', required: true, displayOptions: { show: { - operation: ["create"], - resource: ["list"] - } + operation: [ + 'create', + ], + resource: [ + 'list', + ], + }, }, - description: "The ID of the board the list should be created in" + description: 'The ID of the board the list should be created in' }, { - displayName: "Name", - name: "name", - type: "string", - default: "", - placeholder: "My list", + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + placeholder: 'My list', required: true, displayOptions: { show: { - operation: ["create"], - resource: ["list"] - } + operation: [ + 'create', + ], + resource: [ + 'list', + ], + }, }, - description: "The name of the list" + description: 'The name of the list' }, { - displayName: "Additional Fields", - name: "additionalFields", - type: "collection", - placeholder: "Add Field", + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', displayOptions: { show: { - operation: ["create"], - resource: ["list"] - } + operation: [ + 'create', + ], + resource: [ + 'list', + ], + }, }, default: {}, options: [ { - displayName: "List Source", - name: "idListSource", - type: "string", - default: "", - description: "ID of the list to copy into the new list." + displayName: 'List Source', + name: 'idListSource', + type: 'string', + default: '', + description: 'ID of the list to copy into the new list.' }, { - displayName: "Position", - name: "pos", - type: "string", - default: "bottom", + displayName: 'Position', + name: 'pos', + type: 'string', + default: 'bottom', description: - "The position of the new list. top, bottom, or a positive float." + 'The position of the new list. top, bottom, or a positive float.' } ] }, @@ -139,39 +163,46 @@ export const listFields = [ // list:get // ---------------------------------- { - displayName: "List ID", - name: "id", - type: "string", - default: "", + displayName: 'List ID', + name: 'id', + type: 'string', + default: '', required: true, displayOptions: { show: { - operation: ["get"], - resource: ["list"] - } + operation: [ + 'get', + ], + resource: [ + 'list', + ], + }, }, - description: "The ID of the list to get." + description: 'The ID of the list to get.' }, { - displayName: "Additional Fields", - name: "additionalFields", - type: "collection", - placeholder: "Add Field", + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', displayOptions: { show: { - operation: ["get"], - resource: ["list"] - } + operation: [ + 'get', + ], + resource: [ + 'list', + ], + }, }, default: {}, options: [ { - displayName: "Fields", - name: "fields", - type: "string", - default: "all", - description: - 'Fields to return. Either "all" or a comma-separated list of fields.' + displayName: 'Fields', + name: 'fields', + type: 'string', + default: 'all', + description: 'Fields to return. Either "all" or a comma-separated list of fields.' } ] }, @@ -180,67 +211,75 @@ export const listFields = [ // list:update // ---------------------------------- { - displayName: "List ID", - name: "id", - type: "string", - default: "", + displayName: 'List ID', + name: 'id', + type: 'string', + default: '', required: true, displayOptions: { show: { - operation: ["update"], - resource: ["list"] - } + operation: [ + 'update', + ], + resource: [ + 'list', + ], + }, }, - description: "The ID of the list to update." + description: 'The ID of the list to update.' }, { - displayName: "Update Fields", - name: "updateFields", - type: "collection", - placeholder: "Add Field", + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', displayOptions: { show: { - operation: ["update"], - resource: ["list"] - } + operation: [ + 'update', + ], + resource: [ + 'list', + ], + }, }, default: {}, options: [ { - displayName: "Board ID", - name: "idBoard", - type: "string", - default: "", - description: "ID of a board the list should be moved to." + displayName: 'Board ID', + name: 'idBoard', + type: 'string', + default: '', + description: 'ID of a board the list should be moved to.' }, { - displayName: "Closed", - name: "closed", - type: "boolean", + displayName: 'Closed', + name: 'closed', + type: 'boolean', default: false, - description: "Whether the list is closed." + description: 'Whether the list is closed.' }, { - displayName: "Name", - name: "name", - type: "string", - default: "", - description: "New name of the list" + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + description: 'New name of the list' }, { - displayName: "Position", - name: "pos", - type: "string", - default: "bottom", + displayName: 'Position', + name: 'pos', + type: 'string', + default: 'bottom', description: - "The position of the list. top, bottom, or a positive float." + 'The position of the list. top, bottom, or a positive float.' }, { - displayName: "Subscribed", - name: "subscribed", - type: "boolean", + displayName: 'Subscribed', + name: 'subscribed', + type: 'boolean', default: false, - description: "Whether the acting user is subscribed to the list." + description: 'Whether the acting user is subscribed to the list.' } ] } diff --git a/packages/nodes-base/nodes/Trello/Trello.node.ts b/packages/nodes-base/nodes/Trello/Trello.node.ts index 527c94bfb1..66ba233ddb 100644 --- a/packages/nodes-base/nodes/Trello/Trello.node.ts +++ b/packages/nodes-base/nodes/Trello/Trello.node.ts @@ -1,4 +1,7 @@ -import { IExecuteFunctions } from "n8n-core"; +import { + IExecuteFunctions, +} from 'n8n-core'; + import { IDataObject, INodeTypeDescription, @@ -6,13 +9,44 @@ import { INodeType, } from 'n8n-workflow'; -import { apiRequest } from "./GenericFunctions"; -import { attachmentOperations, attachmentFields } from './AttachmentDescription'; -import { boardOperations, boardFields } from './BoardDescription'; -import { cardOperations, cardFields } from './CardDescription'; -import { checklistOperations, checklistFields } from './ChecklistDescription'; -import { labelOperations, labelFields } from './LabelDescription'; -import { listOperations, listFields } from './ListDescription'; +import { + apiRequest, +} from './GenericFunctions'; + +import { + attachmentOperations, + attachmentFields, +} from './AttachmentDescription'; + +import { + boardOperations, + boardFields, +} from './BoardDescription'; + +import { + cardOperations, + cardFields, +} from './CardDescription'; + +import { + cardCommentOperations, + cardCommentFields, +} from './CardCommentDescription'; + +import { + checklistOperations, + checklistFields, +} from './ChecklistDescription'; + +import { + labelOperations, + labelFields, +} from './LabelDescription'; + +import { + listOperations, + listFields, +} from './ListDescription'; export class Trello implements INodeType { description: INodeTypeDescription = { @@ -33,7 +67,7 @@ export class Trello implements INodeType { { name: 'trelloApi', required: true, - } + }, ], properties: [ { @@ -53,6 +87,10 @@ export class Trello implements INodeType { name: 'Card', value: 'card', }, + { + name: 'Card Comment', + value: 'cardComment', + }, { name: 'Checklist', value: 'checklist', @@ -76,6 +114,7 @@ export class Trello implements INodeType { ...attachmentOperations, ...boardOperations, ...cardOperations, + ...cardCommentOperations, ...checklistOperations, ...labelOperations, ...listOperations, @@ -86,15 +125,14 @@ export class Trello implements INodeType { ...attachmentFields, ...boardFields, ...cardFields, + ...cardCommentFields, ...checklistFields, ...labelFields, ...listFields ], - }; - async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); const returnData: IDataObject[] = []; @@ -236,6 +274,54 @@ export class Trello implements INodeType { throw new Error(`The operation "${operation}" is not known!`); } + } else if (resource === 'cardComment') { + + if (operation === 'add') { + // ---------------------------------- + // add + // ---------------------------------- + + const cardId = this.getNodeParameter('cardId', i) as string; + + qs.text = this.getNodeParameter('text', i) as string; + + requestMethod = 'POST'; + + endpoint = `cards/${cardId}/actions/comments`; + + + } else if (operation === 'remove') { + // ---------------------------------- + // delete + // ---------------------------------- + + requestMethod = 'DELETE'; + + const cardId = this.getNodeParameter('cardId', i) as string; + + const commentId = this.getNodeParameter('commentId', i) as string; + + endpoint = `/cards/${cardId}/actions/${commentId}/comments`; + + } else if (operation === 'update') { + // ---------------------------------- + // update + // ---------------------------------- + + requestMethod = 'PUT'; + + const cardId = this.getNodeParameter('cardId', i) as string; + + const commentId = this.getNodeParameter('commentId', i) as string; + + qs.text = this.getNodeParameter('text', i) as string; + + endpoint = `cards/${cardId}/actions/${commentId}/comments`; + + } else { + throw new Error(`The operation "${operation}" is not known!`); + } + } else if (resource === 'list') { if (operation === 'archive') {