diff --git a/packages/nodes-base/nodes/Asana/Asana.node.ts b/packages/nodes-base/nodes/Asana/Asana.node.ts index 810d987d8..fe03bfbed 100644 --- a/packages/nodes-base/nodes/Asana/Asana.node.ts +++ b/packages/nodes-base/nodes/Asana/Asana.node.ts @@ -1,6 +1,4 @@ -import { - IExecuteFunctions, -} from 'n8n-core'; +import { IExecuteFunctions } from 'n8n-core'; import { IDataObject, @@ -17,15 +15,14 @@ import { import { asanaApiRequest, asanaApiRequestAllItems, + getColorOptions, getTaskFields, getWorkspaces, } from './GenericFunctions'; import * as moment from 'moment-timezone'; -import { - snakeCase, -} from 'change-case'; +import { snakeCase } from 'change-case'; export class Asana implements INodeType { description: INodeTypeDescription = { @@ -1493,6 +1490,16 @@ export class Asana implements INodeType { }, }, options: [ + { + name: 'Create', + value: 'create', + description: 'Create a new project', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a project', + }, { name: 'Get', value: 'get', @@ -1503,11 +1510,143 @@ export class Asana implements INodeType { value: 'getAll', description: 'Get all projects', }, + { + name: 'Update', + value: 'update', + description: 'Update a project', + }, ], default: 'get', description: 'The operation to perform.', }, + // ---------------------------------- + // project:create + // ---------------------------------- + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'project', + ], + }, + }, + description: 'The name of the project to create', + }, + { + displayName: 'Workspace', + name: 'workspace', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getWorkspaces', + }, + default: '', + required: true, + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'project', + ], + }, + }, + description: 'The workspace to create the project in', + }, + { + displayName: 'Team', + name: 'team', + type: 'options', + typeOptions: { + loadOptionsDependsOn: [ + 'workspace', + ], + loadOptionsMethod: 'getTeams', + }, + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'project', + ], + }, + }, + default: '', + description: 'The team this project will be assigned to.', + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + displayOptions: { + show: { + resource: [ + 'project', + ], + operation: [ + 'create', + ], + }, + }, + default: {}, + description: 'Other properties to set', + placeholder: 'Add Property', + options: [ + { + displayName: 'Color', + name: 'color', + type: 'options', + options: getColorOptions(), + default: 'none', + description: 'Color of the project.', + }, + { + displayName: 'Due On', + name: 'due_on', + type: 'dateTime', + default: '', + description: 'The day on which this project is due. This takes a date with format YYYY-MM-DD.\n', + }, + { + displayName: 'Notes', + name: 'notes', + type: 'string', + default: '', + description: 'Basic description or notes for the project.', + }, + ], + }, + // ---------------------------------- + // project:delete + // ---------------------------------- + { + displayName: 'Project ID', + name: 'id', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + operation: [ + 'delete', + ], + resource: [ + 'project', + ], + }, + }, + }, // ---------------------------------- // project:get // ---------------------------------- @@ -1635,6 +1774,118 @@ export class Asana implements INodeType { }, ], }, + // ---------------------------------- + // project:update + // ---------------------------------- + { + displayName: 'Workspace', + name: 'workspace', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getWorkspaces', + }, + options: [], + default: '', + required: true, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'project', + ], + }, + }, + description: 'The workspace in which to get users.', + }, + { + displayName: 'Project ID', + name: 'id', + type: 'string', + default: '', + required: true, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'project', + ], + }, + }, + description: 'The ID of the project to update the data of.', + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + displayOptions: { + show: { + resource: [ + 'project', + ], + operation: [ + 'update', + ], + }, + }, + default: {}, + description: 'Other properties to set', + placeholder: 'Add Property', + options: [ + { + displayName: 'Color', + name: 'color', + type: 'options', + options: getColorOptions(), + default: 'none', + description: 'Color of the project.', + }, + { + displayName: 'Due On', + name: 'due_on', + type: 'dateTime', + default: '', + description: 'The day on which this project is due. This takes a date with format YYYY-MM-DD.', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + description: 'The name of the project.', + }, + { + displayName: 'Notes', + name: 'notes', + type: 'string', + default: '', + description: 'Basic description or notes for the project.', + }, + { + displayName: 'Owner', + name: 'owner', + type: 'string', + default: '', + description: 'The new assignee/cardinal for this project.', + }, + { + displayName: 'Team', + name: 'team', + type: 'options', + typeOptions: { + loadOptionsDependsOn: [ + 'workspace', + ], + loadOptionsMethod: 'getTeams', + }, + default: '', + description: 'The team this project will be assigned to.', + }, + ], + }, ], }; @@ -1905,7 +2156,7 @@ export class Asana implements INodeType { responseData = responseData.data; - if (returnAll === false) { + if (!returnAll) { const limit = this.getNodeParameter('limit', i) as boolean; responseData = responseData.splice(0, limit); } @@ -2136,7 +2387,6 @@ export class Asana implements INodeType { } if (resource === 'taskProject') { if (operation === 'add') { - // ---------------------------------- // taskProject:add // ---------------------------------- @@ -2207,6 +2457,48 @@ export class Asana implements INodeType { } } if (resource === 'project') { + if (operation === 'create') { + // ---------------------------------- + // project:create + // ---------------------------------- + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + const teamId = this.getNodeParameter('team', i); + + // request parameters + requestMethod = 'POST'; + endpoint = `/teams/${teamId}/projects`; + + // required parameters + body.name = this.getNodeParameter('name', i); + body.workspace = this.getNodeParameter('workspace', i); + // optional parameters + if (additionalFields.color) { + qs.color = additionalFields.color; + } + if (additionalFields.due_on) { + qs.due_on = additionalFields.due_on; + } + if (additionalFields.notes) { + qs.notes = additionalFields.notes; + } + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + responseData = responseData.data; + } + + if (operation === 'delete') { + // ---------------------------------- + // project:delete + // ---------------------------------- + const projectId = this.getNodeParameter('id', i) as string; + + requestMethod = 'DELETE'; + + endpoint = `/projects/${projectId}`; + + asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + + responseData = { success: true }; + } if (operation === 'get') { // ---------------------------------- @@ -2258,6 +2550,42 @@ export class Asana implements INodeType { responseData = responseData.data; } } + + if (operation === 'update') { + // ---------------------------------- + // project:update + // ---------------------------------- + const projectId = this.getNodeParameter('id', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + // request parameters + requestMethod = 'PUT'; + endpoint = `/projects/${projectId}`; + + // optional parameters + if (updateFields.color) { + qs.color = updateFields.color; + } + if (updateFields.due_on) { + qs.due_on = updateFields.due_on; + } + if (updateFields.name) { + body.name = updateFields.name; + } + if (updateFields.notes) { + qs.notes = updateFields.notes; + } + if (updateFields.owner) { + body.owner = updateFields.owner; + } + if (updateFields.team) { + body.team = updateFields.team; + } + + responseData = await asanaApiRequest.call(this, requestMethod, endpoint, body, qs); + responseData = responseData.data; + + } } if (Array.isArray(responseData)) { diff --git a/packages/nodes-base/nodes/Asana/GenericFunctions.ts b/packages/nodes-base/nodes/Asana/GenericFunctions.ts index a005b83a1..a4737e046 100644 --- a/packages/nodes-base/nodes/Asana/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Asana/GenericFunctions.ts @@ -86,6 +86,36 @@ export async function getWorkspaces(this: ILoadOptionsFunctions): Promise { + return { + name: value, + value: value, + }; + }); +} + export function getTaskFields() { return [ '*',