From 6639ccefc17011cad7b4dcfd84523f959e082d5e Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Sat, 18 Jan 2020 20:36:57 -0600 Subject: [PATCH] :zap: Minor improvements to ClickUp-Node --- .../nodes-base/nodes/ClickUp/ClickUp.node.ts | 42 ++-- .../nodes/ClickUp/ClickUpTrigger.node.ts | 185 ++++++++---------- .../nodes/ClickUp/GenericFunctions.ts | 6 +- .../nodes/ClickUp/TaskDescription.ts | 170 ++++++++-------- packages/nodes-base/package.json | 4 +- 5 files changed, 196 insertions(+), 211 deletions(-) diff --git a/packages/nodes-base/nodes/ClickUp/ClickUp.node.ts b/packages/nodes-base/nodes/ClickUp/ClickUp.node.ts index f3fd1db9db..20ee32b65d 100644 --- a/packages/nodes-base/nodes/ClickUp/ClickUp.node.ts +++ b/packages/nodes-base/nodes/ClickUp/ClickUp.node.ts @@ -3,11 +3,11 @@ import { } from 'n8n-core'; import { IDataObject, - INodeTypeDescription, - INodeExecutionData, - INodeType, ILoadOptionsFunctions, + INodeExecutionData, INodePropertyOptions, + INodeType, + INodeTypeDescription, } from 'n8n-workflow'; import { clickupApiRequest, @@ -23,7 +23,7 @@ import { export class ClickUp implements INodeType { description: INodeTypeDescription = { displayName: 'ClickUp', - name: 'clickup', + name: 'clickUp', icon: 'file:clickup.png', group: ['output'], version: 1, @@ -182,9 +182,11 @@ export class ClickUp implements INodeType { const length = items.length as unknown as number; const qs: IDataObject = {}; let responseData; + + const resource = this.getNodeParameter('resource', 0) as string; + const operation = this.getNodeParameter('operation', 0) as string; + for (let i = 0; i < length; i++) { - const resource = this.getNodeParameter('resource', 0) as string; - const operation = this.getNodeParameter('operation', 0) as string; if (resource === 'task') { if (operation === 'create') { const listId = this.getNodeParameter('list', i) as string; @@ -233,11 +235,8 @@ export class ClickUp implements INodeType { delete body.content; body.markdown_content = additionalFields.content as string; } - try { - responseData = await clickupApiRequest.call(this, 'POST', `/list/${listId}/task`, body); - } catch (err) { - throw new Error(`ClickUp Error: ${err}`); - } + + responseData = await clickupApiRequest.call(this, 'POST', `/list/${listId}/task`, body); } if (operation === 'update') { const taskId = this.getNodeParameter('id', i) as string; @@ -267,6 +266,9 @@ export class ClickUp implements INodeType { if (updateFields.notifyAll) { body.notify_all = updateFields.notifyAll as boolean; } + if (updateFields.name) { + body.name = updateFields.name as string; + } if (updateFields.parentId) { body.parent = updateFields.parentId as string; } @@ -274,27 +276,15 @@ export class ClickUp implements INodeType { delete body.content; body.markdown_content = updateFields.content as string; } - try { - responseData = await clickupApiRequest.call(this, 'PUT', `/task/${taskId}`, body); - } catch (err) { - throw new Error(`ClickUp Error: ${err}`); - } + responseData = await clickupApiRequest.call(this, 'PUT', `/task/${taskId}`, body); } if (operation === 'get') { const taskId = this.getNodeParameter('id', i) as string; - try { - responseData = await clickupApiRequest.call(this, 'GET', `/task/${taskId}`); - } catch (err) { - throw new Error(`ClickUp Error: ${err}`); - } + responseData = await clickupApiRequest.call(this, 'GET', `/task/${taskId}`); } if (operation === 'delete') { const taskId = this.getNodeParameter('id', i) as string; - try { - responseData = await clickupApiRequest.call(this, 'DELETE', `/task/${taskId}`, {}); - } catch (err) { - throw new Error(`ClickUp Error: ${err}`); - } + responseData = await clickupApiRequest.call(this, 'DELETE', `/task/${taskId}`, {}); } } if (Array.isArray(responseData)) { diff --git a/packages/nodes-base/nodes/ClickUp/ClickUpTrigger.node.ts b/packages/nodes-base/nodes/ClickUp/ClickUpTrigger.node.ts index 4ee6d66bba..36d523313e 100644 --- a/packages/nodes-base/nodes/ClickUp/ClickUpTrigger.node.ts +++ b/packages/nodes-base/nodes/ClickUp/ClickUpTrigger.node.ts @@ -5,11 +5,11 @@ import { import { IDataObject, - INodeTypeDescription, - INodeType, - IWebhookResponseData, - INodePropertyOptions, ILoadOptionsFunctions, + INodePropertyOptions, + INodeType, + INodeTypeDescription, + IWebhookResponseData, } from 'n8n-workflow'; import { @@ -21,7 +21,7 @@ import { createHmac } from 'crypto'; export class ClickUpTrigger implements INodeType { description: INodeTypeDescription = { displayName: 'ClickUp Trigger', - name: 'clickupTrigger', + name: 'clickUpTrigger', icon: 'file:clickup.png', group: ['trigger'], version: 1, @@ -68,89 +68,17 @@ export class ClickUpTrigger implements INodeType { name: '*', value: '*', }, - { - name: 'task.created', - value: 'taskCreated', - }, - { - name: 'task.updated', - value: 'taskUpdated', - }, - { - name: 'task.deleted', - value: 'taskDeleted', - }, - { - name: 'task.status.updated', - value: 'taskStatusUpdated', - }, - { - name: 'task.assignee.updated', - value: 'taskAssigneeUpdated', - }, - { - name: 'task.dueDate.updated', - value: 'taskDueDateUpdated', - }, - { - name: 'task.tag.updated', - value: 'taskTagUpdated', - }, - { - name: 'task.moved', - value: 'taskMoved', - }, - { - name: 'task.comment.posted', - value: 'taskCommentPosted', - }, - { - name: 'task.comment.updated', - value: 'taskCommentUpdated', - }, - { - name: 'task.timeEstimate.updated', - value: 'taskTimeEstimateUpdated', - }, - { - name: 'task.timeTracked.updated', - value: 'taskTimeTrackedUpdated', - }, - { - name: 'list.created', - value: 'listCreated', - }, - { - name: 'list.updated', - value: 'listUpdated', - }, - { - name: 'list.deleted', - value: 'listDeleted', - }, { name: 'folder.created', value: 'folderCreated', }, - { - name: 'folder.updated', - value: 'folderUpdated', - }, { name: 'folder.deleted', value: 'folderDeleted', }, { - name: 'space.created', - value: 'spaceCreated', - }, - { - name: 'space.updated', - value: 'spaceUpdated', - }, - { - name: 'space.deleted', - value: 'spaceDeleted', + name: 'folder.updated', + value: 'folderUpdated', }, { name: 'goal.created', @@ -168,23 +96,88 @@ export class ClickUpTrigger implements INodeType { name: 'keyResult.created', value: 'keyResultCreated', }, + { + name: 'keyResult.deleted', + value: 'keyResultDelete', + }, { name: 'keyResult.updated', value: 'keyResultUpdated', }, { - name: 'keyResult.deleted', - value: 'keyResultDelete', + name: 'list.created', + value: 'listCreated', + }, + { + name: 'list.deleted', + value: 'listDeleted', + }, + { + name: 'list.updated', + value: 'listUpdated', + }, + { + name: 'space.created', + value: 'spaceCreated', + }, + { + name: 'space.deleted', + value: 'spaceDeleted', + }, + { + name: 'space.updated', + value: 'spaceUpdated', + }, + { + name: 'task.assignee.updated', + value: 'taskAssigneeUpdated', + }, + { + name: 'task.comment.posted', + value: 'taskCommentPosted', + }, + { + name: 'task.comment.updated', + value: 'taskCommentUpdated', + }, + { + name: 'task.created', + value: 'taskCreated', + }, + { + name: 'task.deleted', + value: 'taskDeleted', + }, + { + name: 'task.dueDate.updated', + value: 'taskDueDateUpdated', + }, + { + name: 'task.moved', + value: 'taskMoved', + }, + { + name: 'task.status.updated', + value: 'taskStatusUpdated', + }, + { + name: 'task.tag.updated', + value: 'taskTagUpdated', + }, + { + name: 'task.timeEstimate.updated', + value: 'taskTimeEstimateUpdated', + }, + { + name: 'task.timeTracked.updated', + value: 'taskTimeTrackedUpdated', + }, + { + name: 'task.updated', + value: 'taskUpdated', }, ], }, - { - displayName: 'RAW Data', - name: 'rawData', - type: 'boolean', - default: false, - description: 'If the data should be returned RAW instead of parsed.', - }, { displayName: 'Filters', name: 'filters', @@ -192,12 +185,6 @@ export class ClickUpTrigger implements INodeType { placeholder: 'Add Field', default: {}, options: [ - { - displayName: 'Space ID', - name: 'spaceId', - type: 'string', - default: '', - }, { displayName: 'Folder ID', name: 'folderId', @@ -210,6 +197,12 @@ export class ClickUpTrigger implements INodeType { type: 'string', default: '', }, + { + displayName: 'Space ID', + name: 'spaceId', + type: 'string', + default: '', + }, { displayName: 'Task ID', name: 'taskId', @@ -309,16 +302,12 @@ export class ClickUpTrigger implements INodeType { async webhook(this: IWebhookFunctions): Promise { const webhookData = this.getWorkflowStaticData('node'); const headerData = this.getHeaderData() as IDataObject; - const rawData = this.getNodeParameter('rawData') as boolean; const req = this.getRequestObject(); const computedSignature = createHmac('sha256', webhookData.secret as string).update(JSON.stringify(req.body)).digest('hex'); if (headerData['x-signature'] !== computedSignature) { // Signature is not valid so ignore call return {}; } - if (!rawData) { - delete req.body.history_items - } return { workflowData: [ this.helpers.returnJsonArray(req.body), diff --git a/packages/nodes-base/nodes/ClickUp/GenericFunctions.ts b/packages/nodes-base/nodes/ClickUp/GenericFunctions.ts index e29a0f99b6..08375c5317 100644 --- a/packages/nodes-base/nodes/ClickUp/GenericFunctions.ts +++ b/packages/nodes-base/nodes/ClickUp/GenericFunctions.ts @@ -14,7 +14,7 @@ export async function clickupApiRequest(this: IHookFunctions | IExecuteFunctions throw new Error('No credentials got returned!'); } - let options: OptionsWithUri = { + const options: OptionsWithUri = { headers: { Authorization: credentials.accessToken, 'Content-Type': 'application/json', @@ -30,8 +30,8 @@ export async function clickupApiRequest(this: IHookFunctions | IExecuteFunctions } catch (error) { let errorMessage = error; if (error.err) { - errorMessage = error.err + errorMessage = error.err; } - throw new Error('Click Up Error: ' + errorMessage); + throw new Error('ClickUp Error: ' + errorMessage); } } diff --git a/packages/nodes-base/nodes/ClickUp/TaskDescription.ts b/packages/nodes-base/nodes/ClickUp/TaskDescription.ts index 1b9b989c07..b3883040c3 100644 --- a/packages/nodes-base/nodes/ClickUp/TaskDescription.ts +++ b/packages/nodes-base/nodes/ClickUp/TaskDescription.ts @@ -19,9 +19,9 @@ export const taskOperations = [ description: 'Create a task', }, { - name: 'Update', - value: 'update', - description: 'Update a task', + name: 'Delete', + value: 'delete', + description: 'Delete a task', }, { name: 'Get', @@ -29,9 +29,9 @@ export const taskOperations = [ description: 'Get a task', }, { - name: 'Delete', - value: 'delete', - description: 'Delete a task', + name: 'Update', + value: 'update', + description: 'Update a task', }, ], default: 'create', @@ -168,6 +168,19 @@ export const taskFields = [ }, }, options: [ + { + displayName: 'Assignees', + name: 'assignees', + type: 'multiOptions', + loadOptionsDependsOn: [ + 'list', + ], + typeOptions: { + loadOptionsMethod: 'getAssignees', + }, + + default: [], + }, { displayName: 'Content', name: 'content', @@ -178,58 +191,22 @@ export const taskFields = [ default: '', }, { - displayName: 'Is Markdown Content', - name: 'markdownContent', + displayName: 'Due Date', + name: 'dueDate', + type: 'dateTime', + default: '', + }, + { + displayName: 'Due Date Time', + name: 'dueDateTime', type: 'boolean', default: false, }, { - displayName: 'Assignees', - name: 'assignees', - type: 'multiOptions', - loadOptionsDependsOn: [ - 'list', - ], - typeOptions: { - loadOptionsMethod: 'getAssignees' - }, - - default: [], - }, - { - displayName: 'Tags', - name: 'tags', - type: 'multiOptions', - loadOptionsDependsOn: [ - 'space', - ], - typeOptions: { - loadOptionsMethod: 'getTags', - }, - default: [], - description: 'The array of tags applied to this task', - }, - { - displayName: 'Status', - name: 'status', - type: 'options', - loadOptionsDependsOn: [ - 'list', - ], - typeOptions: { - loadOptionsMethod: 'getStatuses', - }, - default: '', - }, - { - displayName: 'Priority', - name: 'priority', - type: 'number', - typeOptions: { - maxValue: 4, - }, - description: 'Integer mapping as 1 : Urgent, 2 : High, 3 : Normal, 4 : Low', - default: 1, + displayName: 'Is Markdown Content', + name: 'markdownContent', + type: 'boolean', + default: false, }, { displayName: 'Notify All', @@ -243,6 +220,16 @@ export const taskFields = [ type: 'string', default: '', }, + { + displayName: 'Priority', + name: 'priority', + type: 'number', + typeOptions: { + maxValue: 4, + }, + description: 'Integer mapping as 1 : Urgent, 2 : High, 3 : Normal, 4 : Low', + default: 3, + }, { displayName: 'Start Date Time', name: 'startDateTime', @@ -250,16 +237,29 @@ export const taskFields = [ default: false, }, { - displayName: 'Due Date Time', - name: 'dueDateTime', - type: 'boolean', - default: false, + displayName: 'Status', + name: 'status', + type: 'options', + loadOptionsDependsOn: [ + 'list', + ], + typeOptions: { + loadOptionsMethod: 'getStatuses', + }, + default: '', }, { - displayName: 'Due Date', - name: 'dueDate', - type: 'dateTime', - default: '', + displayName: 'Tags', + name: 'tags', + type: 'multiOptions', + loadOptionsDependsOn: [ + 'space', + ], + typeOptions: { + loadOptionsMethod: 'getTags', + }, + default: [], + description: 'The array of tags applied to this task', }, { displayName: 'Time Estimate', @@ -317,6 +317,18 @@ export const taskFields = [ }, default: '', }, + { + displayName: 'Due Date', + name: 'dueDate', + type: 'dateTime', + default: '', + }, + { + displayName: 'Due Date Time', + name: 'dueDateTime', + type: 'boolean', + default: false, + }, { displayName: 'Is Markdown Content', name: 'markdownContent', @@ -324,14 +336,10 @@ export const taskFields = [ default: false, }, { - displayName: 'Priority', - name: 'priority', - type: 'number', - typeOptions: { - maxValue: 4, - }, - description: 'Integer mapping as 1 : Urgent, 2 : High, 3 : Normal, 4 : Low', - default: 1, + displayName: 'Name', + name: 'name', + type: 'string', + default: '', }, { displayName: 'Notify All', @@ -345,24 +353,22 @@ export const taskFields = [ type: 'string', default: '', }, + { + displayName: 'Priority', + name: 'priority', + type: 'number', + typeOptions: { + maxValue: 4, + }, + description: 'Integer mapping as 1 : Urgent, 2 : High, 3 : Normal, 4 : Low', + default: 3, + }, { displayName: 'Start Date Time', name: 'startDateTime', type: 'boolean', default: false, }, - { - displayName: 'Due Date Time', - name: 'dueDateTime', - type: 'boolean', - default: false, - }, - { - displayName: 'Due Date', - name: 'dueDate', - type: 'dateTime', - default: '', - }, { displayName: 'Time Estimate', name: 'timeEstimate', diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index 4087568d57..3b2dea916b 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -34,8 +34,8 @@ "dist/credentials/Aws.credentials.js", "dist/credentials/BitbucketApi.credentials.js", "dist/credentials/ChargebeeApi.credentials.js", - "dist/credentials/CodaApi.credentials.js", "dist/credentials/ClickUpApi.credentials.js", + "dist/credentials/CodaApi.credentials.js", "dist/credentials/CopperApi.credentials.js", "dist/credentials/DropboxApi.credentials.js", "dist/credentials/EventbriteApi.credentials.js", @@ -98,9 +98,9 @@ "dist/nodes/Bitbucket/BitbucketTrigger.node.js", "dist/nodes/Chargebee/Chargebee.node.js", "dist/nodes/Chargebee/ChargebeeTrigger.node.js", - "dist/nodes/Coda/Coda.node.js", "dist/nodes/ClickUp/ClickUp.node.js", "dist/nodes/ClickUp/ClickUpTrigger.node.js", + "dist/nodes/Coda/Coda.node.js", "dist/nodes/Copper/CopperTrigger.node.js", "dist/nodes/Cron.node.js", "dist/nodes/Discord/Discord.node.js",