diff --git a/packages/nodes-base/nodes/Jira/IssueCommentDescription.ts b/packages/nodes-base/nodes/Jira/IssueCommentDescription.ts new file mode 100644 index 0000000000..11d12a73a5 --- /dev/null +++ b/packages/nodes-base/nodes/Jira/IssueCommentDescription.ts @@ -0,0 +1,488 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +export const issueCommentOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + }, + }, + options: [ + { + name: 'Add', + value: 'add', + description: 'Add comment to issue', + }, + { + name: 'Get', + value: 'get', + description: 'Get a comment', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all comments', + }, + { + name: 'Remove', + value: 'remove', + description: 'Remove a comment', + }, + { + name: 'Update', + value: 'update', + description: 'Update a comment', + }, + ], + default: 'add', + description: 'The operation to perform.', + }, +] as INodeProperties[]; + +export const issueCommentFields = [ + + /* -------------------------------------------------------------------------- */ + /* issueComment:add */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Issue Key', + name: 'issueKey', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'add', + ], + }, + }, + default: '', + description: 'issueComment Key', + }, + { + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'add', + ], + }, + }, + }, + { + displayName: 'Comment', + name: 'comment', + type: 'string', + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'add', + ], + jsonParameters: [ + false, + ], + }, + }, + description: `Comment's text`, + }, + { + displayName: 'Document Format (JSON)', + name: 'commentJson', + type: 'json', + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'add', + ], + jsonParameters: [ + true, + ], + }, + }, + description: `The Atlassian Document Format (ADF). Online builder can be found here.`, + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'add', + ], + }, + }, + options: [ + { + displayName: 'Expand', + name: 'expand', + type: 'options', + options: [ + { + name: 'Rendered Body', + value: 'renderedBody', + }, + ], + default: '', + description: 'Use expand to include additional information about comments
in the response. This parameter accepts Rendered Body, which
returns the comment body rendered in HTML.', + }, + ], + }, + + /* -------------------------------------------------------------------------- */ + /* issueComment:get */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Issue Key', + name: 'issueKey', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'get', + ], + }, + }, + default: '', + description: 'The ID or key of the issue.', + }, + { + displayName: 'Comment ID', + name: 'commentId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'get', + ], + }, + }, + description: 'The ID of the comment', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'get', + ], + }, + }, + options: [ + { + displayName: 'Expand', + name: 'expand', + type: 'options', + options: [ + { + name: 'Rendered Body', + value: 'renderedBody', + }, + ], + default: '', + description: 'Use expand to include additional information about comments in
the response. This parameter accepts Rendered Body, which
returns the comment body rendered in HTML.', + }, + ], + }, + + /* -------------------------------------------------------------------------- */ + /* issueComment:getAll */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Issue Key', + name: 'issueKey', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'getAll', + ], + }, + }, + default: '', + description: 'The ID or key of the issue.', + }, + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'getAll', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 100, + }, + default: 50, + description: 'How many results to return.', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'getAll', + ], + }, + }, + options: [ + { + displayName: 'Expand', + name: 'expand', + type: 'options', + options: [ + { + name: 'Rendered Body', + value: 'renderedBody', + }, + ], + default: '', + description: 'Use expand to include additional information about comments in the
response. This parameter accepts Rendered Body, which returns the comment
body rendered in HTML.', + }, + ], + }, + + /* -------------------------------------------------------------------------- */ + /* issueComment:remove */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Issue Key', + name: 'issueKey', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'remove', + ], + }, + }, + default: '', + description: 'The ID or key of the issue.', + }, + { + displayName: 'Comment ID', + name: 'commentId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'remove', + ], + }, + }, + description: 'The ID of the comment.', + }, + + /* -------------------------------------------------------------------------- */ + /* issueComment:update */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Issue Key', + name: 'issueKey', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'update', + ], + }, + }, + default: '', + description: 'The Issue Comment key.', + }, + { + displayName: 'Comment ID', + name: 'commentId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'update', + ], + }, + }, + description: 'The ID of the comment.', + }, + { + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: 'Comment', + name: 'comment', + type: 'string', + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'update', + ], + jsonParameters: [ + false, + ], + }, + }, + description: `Comment's text.`, + }, + { + displayName: 'Document Format (JSON)', + name: 'commentJson', + type: 'json', + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'update', + ], + jsonParameters: [ + true, + ], + }, + }, + description: `The Atlassian Document Format (ADF). Online builder can be found here.`, + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'issueComment', + ], + operation: [ + 'update', + ], + }, + }, + options: [ + { + displayName: 'Expand', + name: 'expand', + type: 'options', + options: [ + { + name: 'Rendered Body', + value: 'renderedBody', + }, + ], + default: '', + description: 'Use expand to include additional information about comments in the response. This parameter accepts Rendered Body, which returns the comment body rendered in HTML.', + }, + ], + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Jira/IssueDescription.ts b/packages/nodes-base/nodes/Jira/IssueDescription.ts index 30579f16d9..53e5c5224f 100644 --- a/packages/nodes-base/nodes/Jira/IssueDescription.ts +++ b/packages/nodes-base/nodes/Jira/IssueDescription.ts @@ -1,4 +1,6 @@ -import { INodeProperties } from "n8n-workflow"; +import { + INodeProperties, +} from 'n8n-workflow'; export const issueOperations = [ { diff --git a/packages/nodes-base/nodes/Jira/Jira.node.ts b/packages/nodes-base/nodes/Jira/Jira.node.ts index 98ecc8757f..79886f27eb 100644 --- a/packages/nodes-base/nodes/Jira/Jira.node.ts +++ b/packages/nodes-base/nodes/Jira/Jira.node.ts @@ -17,6 +17,11 @@ import { validateJSON, } from './GenericFunctions'; +import { + issueCommentFields, + issueCommentOperations, + } from './IssueCommentDescription'; + import { issueFields, issueOperations, @@ -96,12 +101,19 @@ export class Jira implements INodeType { value: 'issue', description: 'Creates an issue or, where the option to create subtasks is enabled in Jira, a subtask', }, + { + name: 'Issue Comment', + value: 'issueComment', + description: 'Get, create, update, and delete a comment from an issue.', + }, ], default: 'issue', description: 'Resource to consume.', }, ...issueOperations, ...issueFields, + ...issueCommentOperations, + ...issueCommentFields, ], }; @@ -642,6 +654,125 @@ export class Jira implements INodeType { responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}`, 'DELETE', {}, qs); } } + if (resource === 'issueComment') { + //https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-post + if (operation === 'add') { + const jsonParameters = this.getNodeParameter('jsonParameters', 0) as boolean; + const issueKey = this.getNodeParameter('issueKey', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const body: IDataObject = {}; + if (options.expand) { + qs.expand = options.expand as string; + delete options.expand; + } + + Object.assign(body, options); + if (jsonParameters === false) { + const comment = this.getNodeParameter('comment', i) as string; + Object.assign(body, { + body: { + type: 'doc', + version: 1, + content: [ + { + type: "paragraph", + content: [ + { + type: 'text', + text: comment, + }, + ], + }, + ], + }, + }); + } else { + const commentJson = this.getNodeParameter('commentJson', i) as string; + const json = validateJSON(commentJson); + if (json === '') { + throw new Error('Document Format must be a valid JSON'); + } + + Object.assign(body, { body: json }); + } + + responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/3/issue/${issueKey}/comment`, 'POST', body, qs); + } + //https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-get + if (operation === 'get') { + const issueKey = this.getNodeParameter('issueKey', i) as string; + const commentId = this.getNodeParameter('commentId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + Object.assign(qs, options); + responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/3/issue/${issueKey}/comment/${commentId}`, 'GET', {}, qs); + + } + //https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-get + if (operation === 'getAll') { + const issueKey = this.getNodeParameter('issueKey', i) as string; + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + const options = this.getNodeParameter('options', i) as IDataObject; + const body: IDataObject = {}; + Object.assign(qs, options); + if (returnAll) { + responseData = await jiraSoftwareCloudApiRequestAllItems.call(this, 'comments', `/api/3/issue/${issueKey}/comment`, 'GET', body, qs); + } else { + const limit = this.getNodeParameter('limit', i) as number; + body.maxResults = limit; + responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/3/issue/${issueKey}/comment`, 'GET', body, qs); + responseData = responseData.comments; + } + } + //https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-id-delete + if (operation === 'remove') { + const issueKey = this.getNodeParameter('issueKey', i) as string; + const commentId = this.getNodeParameter('commentId', i) as string; + responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/3/issue/${issueKey}/comment/${commentId}`, 'DELETE', {}, qs); + responseData = { success: true }; + } + //https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-id-put + if (operation === 'update') { + const issueKey = this.getNodeParameter('issueKey', i) as string; + const commentId = this.getNodeParameter('commentId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const jsonParameters = this.getNodeParameter('jsonParameters', 0) as boolean; + const body: IDataObject = {}; + if (options.expand) { + qs.expand = options.expand as string; + delete options.expand; + } + Object.assign(qs, options); + if (jsonParameters === false) { + const comment = this.getNodeParameter('comment', i) as string; + Object.assign(body, { + body: { + type: 'doc', + version: 1, + content: [ + { + type: "paragraph", + content: [ + { + type: 'text', + text: comment, + }, + ], + }, + ], + }, + }); + } else { + const commentJson = this.getNodeParameter('commentJson', i) as string; + const json = validateJSON(commentJson); + if (json === '') { + throw new Error('Document Format must be a valid JSON'); + } + + Object.assign(body, { body: json }); + } + responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/3/issue/${issueKey}/comment/${commentId}`, 'PUT', body, qs); + } + } if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]); } else {