From 4336088741c94b934a243fbab5aa282f355bf6d2 Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Tue, 19 Jan 2021 09:09:03 -0500 Subject: [PATCH] :zap: Add Trello List getAll/getCards functionality (#1350) * Fix to add List.getCards * :zap: Small improvements to #1347 * :zap: Minor formatting improvements * :zap: Small fix Co-authored-by: tumf Co-authored-by: Jan Oberhauser --- .../nodes/Trello/GenericFunctions.ts | 23 +++ .../nodes/Trello/ListDescription.ts | 177 ++++++++++++++++++ .../nodes-base/nodes/Trello/Trello.node.ts | 65 ++++++- packages/nodes-base/nodes/Trello/trello.png | Bin 541 -> 0 bytes packages/nodes-base/nodes/Trello/trello.svg | 22 +++ 5 files changed, 283 insertions(+), 4 deletions(-) delete mode 100644 packages/nodes-base/nodes/Trello/trello.png create mode 100644 packages/nodes-base/nodes/Trello/trello.svg diff --git a/packages/nodes-base/nodes/Trello/GenericFunctions.ts b/packages/nodes-base/nodes/Trello/GenericFunctions.ts index b7c65c242b..c36e1aef0b 100644 --- a/packages/nodes-base/nodes/Trello/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Trello/GenericFunctions.ts @@ -53,3 +53,26 @@ export async function apiRequest(this: IHookFunctions | IExecuteFunctions | ILoa throw error; } } + +export async function apiRequestAllItems(this: IHookFunctions | IExecuteFunctions, method: string, endpoint: string, body: IDataObject, query: IDataObject = {}): Promise { // tslint:disable-line:no-any + + query.limit = 30; + + query.sort = '-id'; + + const returnData: IDataObject[] = []; + + let responseData; + + do { + responseData = await apiRequest.call(this, method, endpoint, body, query); + returnData.push.apply(returnData, responseData); + if (responseData.length !== 0) { + query.before = responseData[responseData.length - 1].id; + } + } while ( + query.limit <= responseData.length + ); + + return returnData; +} diff --git a/packages/nodes-base/nodes/Trello/ListDescription.ts b/packages/nodes-base/nodes/Trello/ListDescription.ts index c2a539e282..21bd54f18f 100644 --- a/packages/nodes-base/nodes/Trello/ListDescription.ts +++ b/packages/nodes-base/nodes/Trello/ListDescription.ts @@ -33,6 +33,16 @@ export const listOperations = [ value: 'get', description: 'Get the data of a list', }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all the lists', + }, + { + name: 'Get Cards', + value: 'getCards', + description: 'Get all the cards in a list', + }, { name: 'Update', value: 'update', @@ -159,6 +169,89 @@ export const listFields = [ ], }, + // ---------------------------------- + // list:getCards + // ---------------------------------- + { + displayName: 'List ID', + name: 'id', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + operation: [ + 'getCards', + ], + resource: [ + 'list', + ], + }, + }, + description: 'The ID of the list to get cards.', + }, + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'list', + ], + operation: [ + 'getCards', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + default: 20, + displayOptions: { + show: { + resource: [ + 'list', + ], + operation: [ + 'getCards', + ], + returnAll: [ + false, + ], + }, + }, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + displayOptions: { + show: { + operation: [ + 'getCards', + ], + 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.', + }, + ], + }, // ---------------------------------- // list:get // ---------------------------------- @@ -207,6 +300,90 @@ export const listFields = [ ], }, + // ---------------------------------- + // list:getAll + // ---------------------------------- + { + displayName: 'Board ID', + name: 'id', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'list', + ], + }, + }, + description: 'The ID of the board', + }, + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'list', + ], + operation: [ + 'getAll', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + default: 20, + displayOptions: { + show: { + resource: [ + 'list', + ], + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + }, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + 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.', + }, + ], + }, + // ---------------------------------- // list:update // ---------------------------------- diff --git a/packages/nodes-base/nodes/Trello/Trello.node.ts b/packages/nodes-base/nodes/Trello/Trello.node.ts index 99378d969e..807c634d09 100644 --- a/packages/nodes-base/nodes/Trello/Trello.node.ts +++ b/packages/nodes-base/nodes/Trello/Trello.node.ts @@ -11,6 +11,7 @@ import { import { apiRequest, + apiRequestAllItems, } from './GenericFunctions'; import { @@ -52,14 +53,14 @@ export class Trello implements INodeType { description: INodeTypeDescription = { displayName: 'Trello', name: 'trello', - icon: 'file:trello.png', + icon: 'file:trello.svg', group: ['transform'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', description: 'Create, change and delete boards and cards', defaults: { name: 'Trello', - color: '#026aa7', + color: '#0079bf', }, inputs: ['main'], outputs: ['main'], @@ -147,6 +148,8 @@ export class Trello implements INodeType { let requestMethod: string; let endpoint: string; + let returnAll = false; + let responseData; for (let i = 0; i < items.length; i++) { requestMethod = 'GET'; @@ -365,6 +368,46 @@ export class Trello implements INodeType { const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; Object.assign(qs, additionalFields); + } else if (operation === 'getAll') { + // ---------------------------------- + // getAll + // ---------------------------------- + + requestMethod = 'GET'; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + const id = this.getNodeParameter('id', i) as string; + + endpoint = `boards/${id}/lists`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + + } else if (operation === 'getCards') { + // ---------------------------------- + // getCards + // ---------------------------------- + + requestMethod = 'GET'; + + returnAll = this.getNodeParameter('returnAll', i) as boolean; + + if (returnAll === false) { + qs.limit = this.getNodeParameter('limit', i) as number; + } + + const id = this.getNodeParameter('id', i) as string; + + endpoint = `lists/${id}/cards`; + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + Object.assign(qs, additionalFields); + } else if (operation === 'update') { // ---------------------------------- // update @@ -549,7 +592,7 @@ export class Trello implements INodeType { const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; Object.assign(qs, additionalFields); - } else if (operation ==='completedCheckItems') { + } else if (operation === 'completedCheckItems') { // ---------------------------------- // completedCheckItems // ---------------------------------- @@ -673,7 +716,21 @@ export class Trello implements INodeType { throw new Error(`The resource "${resource}" is not known!`); } - const responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); + + // resources listed here do not support pagination so + // paginate them 'manually' + const skipPagination = [ + 'list:getAll', + ]; + + if (returnAll === true && !skipPagination.includes(`${resource}:${operation}`)) { + responseData = await apiRequestAllItems.call(this, requestMethod, endpoint, body, qs); + } else { + responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); + if (returnAll === false && qs.limit) { + responseData = responseData.splice(0, qs.limit); + } + } if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]); diff --git a/packages/nodes-base/nodes/Trello/trello.png b/packages/nodes-base/nodes/Trello/trello.png deleted file mode 100644 index 2b75a6c66cf763ce8c92479ed072d08c3642c23a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 541 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw3=&b&bO2J@1AIbUfiy$qei%ByP<@c0`Vfd) zb&#R=7DL%?5F02`e;lf&;}S#jDTbaK3|0FXY7R5h9As!b#?X8QDEt5ae}=-{45fP+ ziuX)A@sy!#-{1fLwE9nd{`se3$6e<+7bIGbGF0rhoPKt}+2`_|$N3u$v)3H_@#pW| zx8Do4+%}nVM!ol>co${tE|(|?@(X78wru`~ic2S&g#O%LGk)8zuxm+_5F-D`$SLw=wD^%u{u3vn7|VVmdx|+g0T>@9S|@PrBr7zE#wJ zh-rIy|Cq5z;##Z4Ngiq(N<32OfA>srXz5*M!=kzEbH(l-$B(V#d2FKjk-dq7*?0f^ z@LIn%uMWoKQ{AQ>8|N~#uiJ6%!7}YWiJFynb1LKw=4y#omxyj~JuaQOwo>><&F(Bl Xode5Gzvc~c1jVzbtDnm{r-UW|>^%D# diff --git a/packages/nodes-base/nodes/Trello/trello.svg b/packages/nodes-base/nodes/Trello/trello.svg new file mode 100644 index 0000000000..eecadb36bc --- /dev/null +++ b/packages/nodes-base/nodes/Trello/trello.svg @@ -0,0 +1,22 @@ + + + + trello-mark-blue-flat + Created with Sketch. + + + + + + + + + \ No newline at end of file