mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-02 07:01:30 -08:00
⚡ Extended Jira Node (#1306)
* ⚡ Add Issue Attachment resource * ⚡ Add custom fields to issue:create and issue:update * ⚡ Filter custom fields by the project selected * ⚡ Change the logo to SVG * ⚡ Small improvement * ⚡ Minor improvements to Jira Node * ⚡ Add download field to issueAttachment get and getAll Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
This commit is contained in:
parent
5b371ce994
commit
46fe96b72c
|
@ -1,6 +1,6 @@
|
|||
import {
|
||||
OptionsWithUri,
|
||||
} from 'request';
|
||||
} from 'request';
|
||||
|
||||
import {
|
||||
IExecuteFunctions,
|
||||
|
@ -14,7 +14,7 @@ import {
|
|||
IDataObject,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
export async function jiraSoftwareCloudApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, endpoint: string, method: string, body: any = {}, query?: IDataObject, uri?: string): Promise<any> { // tslint:disable-line:no-any
|
||||
export async function jiraSoftwareCloudApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, endpoint: string, method: string, body: any = {}, query?: IDataObject, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
|
||||
let data; let domain;
|
||||
|
||||
const jiraVersion = this.getNodeParameter('jiraVersion', 0) as string;
|
||||
|
@ -43,6 +43,7 @@ export async function jiraSoftwareCloudApiRequest(this: IHookFunctions | IExecut
|
|||
Authorization: `Basic ${data}`,
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'X-Atlassian-Token': 'no-check',
|
||||
},
|
||||
method,
|
||||
qs: query,
|
||||
|
@ -51,6 +52,18 @@ export async function jiraSoftwareCloudApiRequest(this: IHookFunctions | IExecut
|
|||
json: true,
|
||||
};
|
||||
|
||||
if (Object.keys(option).length !== 0) {
|
||||
Object.assign(options, option);
|
||||
}
|
||||
|
||||
if (Object.keys(body).length === 0) {
|
||||
delete options.body;
|
||||
}
|
||||
|
||||
if (Object.keys(query || {}).length === 0) {
|
||||
delete options.qs;
|
||||
}
|
||||
|
||||
try {
|
||||
return await this.helpers.request!(options);
|
||||
} catch (error) {
|
||||
|
@ -82,7 +95,7 @@ export async function jiraSoftwareCloudApiRequestAllItems(this: IHookFunctions |
|
|||
query.startAt = 0;
|
||||
body.startAt = 0;
|
||||
query.maxResults = 100;
|
||||
body.maxResults = 100;
|
||||
body.maxResults = 100;
|
||||
|
||||
do {
|
||||
responseData = await jiraSoftwareCloudApiRequest.call(this, endpoint, method, body, query);
|
||||
|
@ -106,7 +119,7 @@ export function validateJSON(json: string | undefined): any { // tslint:disable-
|
|||
return result;
|
||||
}
|
||||
|
||||
export function eventExists (currentEvents : string[], webhookEvents: string[]) {
|
||||
export function eventExists(currentEvents: string[], webhookEvents: string[]) {
|
||||
for (const currentEvent of currentEvents) {
|
||||
if (!webhookEvents.includes(currentEvent)) {
|
||||
return false;
|
||||
|
@ -115,7 +128,7 @@ export function eventExists (currentEvents : string[], webhookEvents: string[])
|
|||
return true;
|
||||
}
|
||||
|
||||
export function getId (url: string) {
|
||||
export function getId(url: string) {
|
||||
return url.split('/').pop();
|
||||
}
|
||||
|
||||
|
@ -159,4 +172,4 @@ export const allEvents = [
|
|||
'worklog_created',
|
||||
'worklog_updated',
|
||||
'worklog_deleted',
|
||||
];
|
||||
];
|
266
packages/nodes-base/nodes/Jira/IssueAttachmentDescription.ts
Normal file
266
packages/nodes-base/nodes/Jira/IssueAttachmentDescription.ts
Normal file
|
@ -0,0 +1,266 @@
|
|||
import {
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
export const issueAttachmentOperations = [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'issueAttachment',
|
||||
],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'Add',
|
||||
value: 'add',
|
||||
description: 'Add attachment to issue',
|
||||
},
|
||||
{
|
||||
name: 'Get',
|
||||
value: 'get',
|
||||
description: 'Get an attachment',
|
||||
},
|
||||
{
|
||||
name: 'Get All',
|
||||
value: 'getAll',
|
||||
description: 'Get all attachments',
|
||||
},
|
||||
{
|
||||
name: 'Remove',
|
||||
value: 'remove',
|
||||
description: 'Remove an attachment',
|
||||
},
|
||||
],
|
||||
default: 'add',
|
||||
description: 'The operation to perform.',
|
||||
},
|
||||
] as INodeProperties[];
|
||||
|
||||
export const issueAttachmentFields = [
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issueAttachment:add */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Issue Key',
|
||||
name: 'issueKey',
|
||||
type: 'string',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'issueAttachment',
|
||||
],
|
||||
operation: [
|
||||
'add',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
description: 'Issue Key',
|
||||
},
|
||||
{
|
||||
displayName: 'Binary Property',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'issueAttachment',
|
||||
],
|
||||
operation: [
|
||||
'add',
|
||||
],
|
||||
},
|
||||
},
|
||||
name: 'binaryPropertyName',
|
||||
type: 'string',
|
||||
default: 'data',
|
||||
description: 'Object property name which holds binary data.',
|
||||
required: true,
|
||||
},
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issueAttachment:get */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Attachment ID',
|
||||
name: 'attachmentId',
|
||||
type: 'string',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'issueAttachment',
|
||||
],
|
||||
operation: [
|
||||
'get',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
description: 'The ID of the attachment.',
|
||||
},
|
||||
{
|
||||
displayName: 'Download',
|
||||
name: 'download',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'issueAttachment',
|
||||
],
|
||||
operation: [
|
||||
'get',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Binary Property',
|
||||
name: 'binaryProperty',
|
||||
type: 'string',
|
||||
default: 'data',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'issueAttachment',
|
||||
],
|
||||
operation: [
|
||||
'get',
|
||||
],
|
||||
download: [
|
||||
true,
|
||||
],
|
||||
},
|
||||
},
|
||||
description: 'Object property name which holds binary data.',
|
||||
required: true,
|
||||
},
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issueAttachment:getAll */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Issue Key',
|
||||
name: 'issueKey',
|
||||
type: 'string',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'issueAttachment',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
description: 'Issue Key',
|
||||
},
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
type: 'boolean',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'issueAttachment',
|
||||
],
|
||||
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: [
|
||||
'issueAttachment',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
returnAll: [
|
||||
false,
|
||||
],
|
||||
},
|
||||
},
|
||||
typeOptions: {
|
||||
minValue: 1,
|
||||
maxValue: 100,
|
||||
},
|
||||
default: 50,
|
||||
description: 'How many results to return.',
|
||||
},
|
||||
{
|
||||
displayName: 'Download',
|
||||
name: 'download',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'issueAttachment',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
displayName: 'Binary Property',
|
||||
name: 'binaryProperty',
|
||||
type: 'string',
|
||||
default: 'data',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'issueAttachment',
|
||||
],
|
||||
operation: [
|
||||
'getAll',
|
||||
],
|
||||
download: [
|
||||
true,
|
||||
],
|
||||
},
|
||||
},
|
||||
description: 'Object property name which holds binary data.',
|
||||
required: true,
|
||||
},
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issueAttachment:remove */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Attachment ID',
|
||||
name: 'attachmentId',
|
||||
type: 'string',
|
||||
required: true,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
'issueAttachment',
|
||||
],
|
||||
operation: [
|
||||
'remove',
|
||||
],
|
||||
},
|
||||
},
|
||||
default: '',
|
||||
description: 'The ID of the attachment.',
|
||||
},
|
||||
] as INodeProperties[];
|
|
@ -485,4 +485,4 @@ export const issueCommentFields = [
|
|||
},
|
||||
],
|
||||
},
|
||||
] as INodeProperties[];
|
||||
] as INodeProperties[];
|
|
@ -1,4 +1,4 @@
|
|||
import {
|
||||
import {
|
||||
INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
|
@ -63,9 +63,9 @@ export const issueOperations = [
|
|||
|
||||
export const issueFields = [
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:create */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:create */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Project',
|
||||
name: 'project',
|
||||
|
@ -155,7 +155,6 @@ export const issueFields = [
|
|||
loadOptionsMethod: 'getUsers',
|
||||
},
|
||||
default: '',
|
||||
required : false,
|
||||
description: 'Assignee',
|
||||
},
|
||||
{
|
||||
|
@ -163,9 +162,46 @@ export const issueFields = [
|
|||
name: 'description',
|
||||
type: 'string',
|
||||
default: '',
|
||||
required : false,
|
||||
description: 'Description',
|
||||
},
|
||||
{
|
||||
displayName: 'Custom Fields',
|
||||
name: 'customFieldsUi',
|
||||
type: 'fixedCollection',
|
||||
default: '',
|
||||
placeholder: 'Add Custom Field',
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'customFieldsValues',
|
||||
displayName: 'Custom Field',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Field ID',
|
||||
name: 'fieldId',
|
||||
type: 'options',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getCustomFields',
|
||||
loadOptionsDependsOn: [
|
||||
'project',
|
||||
],
|
||||
},
|
||||
description: 'ID of the field to set.',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Field Value',
|
||||
name: 'fieldValue',
|
||||
type: 'string',
|
||||
description: 'Value of the field to set.',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Labels',
|
||||
name: 'labels',
|
||||
|
@ -174,9 +210,8 @@ export const issueFields = [
|
|||
loadOptionsMethod: 'getLabels',
|
||||
},
|
||||
default: [],
|
||||
required : false,
|
||||
description: 'Labels',
|
||||
displayOptions: {
|
||||
displayOptions: {
|
||||
show: {
|
||||
'/jiraVersion': [
|
||||
'cloud',
|
||||
|
@ -189,9 +224,8 @@ export const issueFields = [
|
|||
name: 'serverLabels',
|
||||
type: 'string',
|
||||
default: [],
|
||||
required : false,
|
||||
description: 'Labels',
|
||||
displayOptions: {
|
||||
displayOptions: {
|
||||
show: {
|
||||
'/jiraVersion': [
|
||||
'server',
|
||||
|
@ -206,7 +240,6 @@ export const issueFields = [
|
|||
displayName: 'Parent Issue Key',
|
||||
name: 'parentIssueKey',
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: '',
|
||||
description: 'Parent Issue Key',
|
||||
},
|
||||
|
@ -218,7 +251,6 @@ export const issueFields = [
|
|||
loadOptionsMethod: 'getPriorities',
|
||||
},
|
||||
default: '',
|
||||
required : false,
|
||||
description: 'Priority',
|
||||
},
|
||||
{
|
||||
|
@ -226,16 +258,15 @@ export const issueFields = [
|
|||
name: 'updateHistory',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
required : false,
|
||||
description: `Whether the project in which the issue is created is added to the user's<br/>
|
||||
Recently viewed project list, as shown under Projects in Jira.`,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:update */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:update */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Issue Key',
|
||||
name: 'issueKey',
|
||||
|
@ -279,7 +310,6 @@ export const issueFields = [
|
|||
loadOptionsMethod: 'getUsers',
|
||||
},
|
||||
default: '',
|
||||
required : false,
|
||||
description: 'Assignee',
|
||||
},
|
||||
{
|
||||
|
@ -287,14 +317,50 @@ export const issueFields = [
|
|||
name: 'description',
|
||||
type: 'string',
|
||||
default: '',
|
||||
required : false,
|
||||
description: 'Description',
|
||||
},
|
||||
{
|
||||
displayName: 'Custom Fields',
|
||||
name: 'customFieldsUi',
|
||||
type: 'fixedCollection',
|
||||
default: '',
|
||||
placeholder: 'Add Custom Field',
|
||||
typeOptions: {
|
||||
multipleValues: true,
|
||||
},
|
||||
options: [
|
||||
{
|
||||
name: 'customFieldsValues',
|
||||
displayName: 'Custom Field',
|
||||
values: [
|
||||
{
|
||||
displayName: 'Field ID',
|
||||
name: 'fieldId',
|
||||
type: 'options',
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getCustomFields',
|
||||
loadOptionsDependsOn: [
|
||||
'issueKey',
|
||||
],
|
||||
},
|
||||
description: 'ID of the field to set.',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Field Value',
|
||||
name: 'fieldValue',
|
||||
type: 'string',
|
||||
description: 'Value of the field to set.',
|
||||
default: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
displayName: 'Issue Type',
|
||||
name: 'issueType',
|
||||
type: 'options',
|
||||
required: false,
|
||||
typeOptions: {
|
||||
loadOptionsMethod: 'getIssueTypes',
|
||||
},
|
||||
|
@ -309,9 +375,8 @@ export const issueFields = [
|
|||
loadOptionsMethod: 'getLabels',
|
||||
},
|
||||
default: [],
|
||||
required : false,
|
||||
description: 'Labels',
|
||||
displayOptions: {
|
||||
displayOptions: {
|
||||
show: {
|
||||
'/jiraVersion': [
|
||||
'cloud',
|
||||
|
@ -324,9 +389,8 @@ export const issueFields = [
|
|||
name: 'serverLabels',
|
||||
type: 'string',
|
||||
default: [],
|
||||
required : false,
|
||||
description: 'Labels',
|
||||
displayOptions: {
|
||||
displayOptions: {
|
||||
show: {
|
||||
'/jiraVersion': [
|
||||
'server',
|
||||
|
@ -341,7 +405,6 @@ export const issueFields = [
|
|||
displayName: 'Parent Issue Key',
|
||||
name: 'parentIssueKey',
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: '',
|
||||
description: 'Parent Issue Key',
|
||||
},
|
||||
|
@ -353,14 +416,12 @@ export const issueFields = [
|
|||
loadOptionsMethod: 'getPriorities',
|
||||
},
|
||||
default: '',
|
||||
required : false,
|
||||
description: 'Priority',
|
||||
},
|
||||
{
|
||||
displayName: 'Summary',
|
||||
name: 'summary',
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: '',
|
||||
description: 'Summary',
|
||||
},
|
||||
|
@ -371,16 +432,15 @@ export const issueFields = [
|
|||
typeOptions: {
|
||||
loadOptionsMethod: 'getTransitions',
|
||||
},
|
||||
required: false,
|
||||
default: '',
|
||||
description: 'The ID of the issue status.',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:delete */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:delete */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Issue Key',
|
||||
name: 'issueKey',
|
||||
|
@ -418,9 +478,9 @@ export const issueFields = [
|
|||
description: 'Delete Subtasks',
|
||||
},
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:get */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:get */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Issue Key',
|
||||
name: 'issueKey',
|
||||
|
@ -460,7 +520,6 @@ export const issueFields = [
|
|||
displayName: 'Expand',
|
||||
name: 'expand',
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: '',
|
||||
description: `Use expand to include additional information about the issues in the response.<br/>
|
||||
This parameter accepts a comma-separated list. Expand options include:<br/>
|
||||
|
@ -477,7 +536,6 @@ export const issueFields = [
|
|||
displayName: 'Fields',
|
||||
name: 'fields',
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: '',
|
||||
description: `A list of fields to return for the issue.<br/>
|
||||
This parameter accepts a comma-separated list.<br/>
|
||||
|
@ -490,7 +548,6 @@ export const issueFields = [
|
|||
displayName: 'Fields By Key',
|
||||
name: 'fieldsByKey',
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: false,
|
||||
description: `Indicates whether fields in fields are referenced by keys rather than IDs.<br/>
|
||||
This parameter is useful where fields have been added by a connect app and a field's key<br/>
|
||||
|
@ -500,7 +557,6 @@ export const issueFields = [
|
|||
displayName: 'Properties',
|
||||
name: 'properties',
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: '',
|
||||
description: `A list of issue properties to return for the issue.<br/>
|
||||
This parameter accepts a comma-separated list. Allowed values:<br/>
|
||||
|
@ -516,7 +572,6 @@ export const issueFields = [
|
|||
displayName: 'Update History',
|
||||
name: 'updateHistory',
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: false,
|
||||
description: `Whether the project in which the issue is created is added to the user's
|
||||
Recently viewed project list, as shown under Projects in Jira. This also populates the
|
||||
|
@ -525,9 +580,9 @@ export const issueFields = [
|
|||
],
|
||||
},
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:getAll */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:getAll */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Return All',
|
||||
name: 'returnAll',
|
||||
|
@ -649,7 +704,6 @@ export const issueFields = [
|
|||
displayName: 'Fields By Key',
|
||||
name: 'fieldsByKey',
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: false,
|
||||
description: `Indicates whether fields in fields are referenced by keys rather than IDs.<br/>
|
||||
This parameter is useful where fields have been added by a connect app and a field's key<br/>
|
||||
|
@ -667,9 +721,9 @@ export const issueFields = [
|
|||
},
|
||||
],
|
||||
},
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:changelog */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:changelog */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Issue Key',
|
||||
name: 'issueKey',
|
||||
|
@ -729,9 +783,9 @@ export const issueFields = [
|
|||
default: 50,
|
||||
description: 'How many results to return.',
|
||||
},
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:notify */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:notify */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Issue Key',
|
||||
name: 'issueKey',
|
||||
|
@ -791,7 +845,6 @@ export const issueFields = [
|
|||
typeOptions: {
|
||||
alwaysOpenEditWindow: true,
|
||||
},
|
||||
required: false,
|
||||
default: '',
|
||||
description: 'The HTML body of the email notification for the issue.',
|
||||
},
|
||||
|
@ -799,7 +852,6 @@ export const issueFields = [
|
|||
displayName: 'Subject',
|
||||
name: 'subject',
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: '',
|
||||
description: `The subject of the email notification for the issue. If this is not specified,
|
||||
then the subject is set to the issue key and summary.`,
|
||||
|
@ -811,7 +863,6 @@ export const issueFields = [
|
|||
typeOptions: {
|
||||
alwaysOpenEditWindow: true,
|
||||
},
|
||||
required: false,
|
||||
default: '',
|
||||
description: `The subject of the email notification for the issue.
|
||||
If this is not specified, then the subject is set to the issue key and summary.`,
|
||||
|
@ -906,7 +957,6 @@ export const issueFields = [
|
|||
typeOptions: {
|
||||
alwaysOpenEditWindow: true,
|
||||
},
|
||||
required: false,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
|
@ -983,7 +1033,6 @@ export const issueFields = [
|
|||
typeOptions: {
|
||||
alwaysOpenEditWindow: true,
|
||||
},
|
||||
required: false,
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: [
|
||||
|
@ -1001,9 +1050,9 @@ export const issueFields = [
|
|||
description: 'Restricts the notifications to users with the specified permissions.',
|
||||
},
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:transitions */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* issue:transitions */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
{
|
||||
displayName: 'Issue Key',
|
||||
name: 'issueKey',
|
||||
|
@ -1043,7 +1092,6 @@ export const issueFields = [
|
|||
displayName: 'Expand',
|
||||
name: 'expand',
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: '',
|
||||
description: `Use expand to include additional information about transitions in the response.<br/>
|
||||
This parameter accepts transitions.fields, which returns information about the fields in the<br/>
|
||||
|
@ -1054,7 +1102,6 @@ export const issueFields = [
|
|||
displayName: 'Transition ID',
|
||||
name: 'transitionId',
|
||||
type: 'string',
|
||||
required: false,
|
||||
default: '',
|
||||
description: 'The ID of the transition.',
|
||||
},
|
||||
|
@ -1062,11 +1109,10 @@ export const issueFields = [
|
|||
displayName: 'Skip Remote Only Condition',
|
||||
name: 'skipRemoteOnlyCondition',
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
default: false,
|
||||
description: `Indicates whether transitions with the condition Hide<br/>
|
||||
From User Condition are included in the response.`,
|
||||
},
|
||||
],
|
||||
},
|
||||
] as INodeProperties[];
|
||||
] as INodeProperties[];
|
|
@ -1,6 +1,6 @@
|
|||
import {
|
||||
IDataObject,
|
||||
} from 'n8n-workflow';
|
||||
} from 'n8n-workflow';
|
||||
|
||||
export interface IFields {
|
||||
assignee?: IDataObject;
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import {
|
||||
BINARY_ENCODING,
|
||||
IExecuteFunctions,
|
||||
} from 'n8n-core';
|
||||
|
||||
import {
|
||||
IBinaryData,
|
||||
IBinaryKeyData,
|
||||
IDataObject,
|
||||
ILoadOptionsFunctions,
|
||||
INodeExecutionData,
|
||||
|
@ -17,10 +20,15 @@ import {
|
|||
validateJSON,
|
||||
} from './GenericFunctions';
|
||||
|
||||
import {
|
||||
issueAttachmentFields,
|
||||
issueAttachmentOperations,
|
||||
} from './IssueAttachmentDescription';
|
||||
|
||||
import {
|
||||
issueCommentFields,
|
||||
issueCommentOperations,
|
||||
} from './IssueCommentDescription';
|
||||
} from './IssueCommentDescription';
|
||||
|
||||
import {
|
||||
issueFields,
|
||||
|
@ -33,13 +41,13 @@ import {
|
|||
INotificationRecipients,
|
||||
INotify,
|
||||
NotificationRecipientsRestrictions,
|
||||
} from './IssueInterface';
|
||||
} from './IssueInterface';
|
||||
|
||||
export class Jira implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'Jira Software',
|
||||
name: 'jira',
|
||||
icon: 'file:jira.png',
|
||||
icon: 'file:jira.svg',
|
||||
group: ['output'],
|
||||
version: 1,
|
||||
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
||||
|
@ -101,6 +109,11 @@ 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 Attachment',
|
||||
value: 'issueAttachment',
|
||||
description: 'Add, remove, and get an attachment from an issue.',
|
||||
},
|
||||
{
|
||||
name: 'Issue Comment',
|
||||
value: 'issueComment',
|
||||
|
@ -112,6 +125,8 @@ export class Jira implements INodeType {
|
|||
},
|
||||
...issueOperations,
|
||||
...issueFields,
|
||||
...issueAttachmentOperations,
|
||||
...issueAttachmentFields,
|
||||
...issueCommentOperations,
|
||||
...issueCommentFields,
|
||||
],
|
||||
|
@ -176,7 +191,7 @@ export class Jira implements INodeType {
|
|||
}
|
||||
} else {
|
||||
for (const issueType of issueTypes) {
|
||||
if (issueType.scope === undefined || issueType.scope.project.id === projectId) {
|
||||
if (issueType.scope !== undefined && issueType.scope.project.id === projectId) {
|
||||
const issueTypeName = issueType.name;
|
||||
const issueTypeId = issueType.id;
|
||||
|
||||
|
@ -193,7 +208,6 @@ export class Jira implements INodeType {
|
|||
if (a.name > b.name) { return 1; }
|
||||
return 0;
|
||||
});
|
||||
|
||||
return returnData;
|
||||
},
|
||||
|
||||
|
@ -342,6 +356,32 @@ export class Jira implements INodeType {
|
|||
|
||||
return returnData;
|
||||
},
|
||||
|
||||
// Get all the custom fields to display them to user so that he can
|
||||
// select them easily
|
||||
async getCustomFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||
const returnData: INodePropertyOptions[] = [];
|
||||
const operation = this.getCurrentNodeParameter('operation') as string;
|
||||
let projectId;
|
||||
if (operation === 'create') {
|
||||
projectId = this.getCurrentNodeParameter('project');
|
||||
} else {
|
||||
const issueKey = this.getCurrentNodeParameter('issueKey');
|
||||
const { fields: { project: { id } } } = await jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}`, 'GET', {}, {});
|
||||
projectId = id;
|
||||
}
|
||||
|
||||
const fields = await jiraSoftwareCloudApiRequest.call(this, `/api/2/field`, 'GET');
|
||||
for (const field of fields) {
|
||||
if (field.custom === true && field.scope && field.scope.project && field.scope.project.id === projectId) {
|
||||
returnData.push({
|
||||
name: field.name,
|
||||
value: field.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
return returnData;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -356,11 +396,10 @@ export class Jira implements INodeType {
|
|||
const operation = this.getNodeParameter('operation', 0) as string;
|
||||
const jiraVersion = this.getNodeParameter('jiraVersion', 0) as string;
|
||||
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
if (resource === 'issue') {
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-post
|
||||
if (operation === 'create') {
|
||||
if (resource === 'issue') {
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-post
|
||||
if (operation === 'create') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const summary = this.getNodeParameter('summary', i) as string;
|
||||
const projectId = this.getNodeParameter('project', i) as string;
|
||||
const issueTypeId = this.getNodeParameter('issueType', i) as string;
|
||||
|
@ -403,6 +442,13 @@ export class Jira implements INodeType {
|
|||
if (additionalFields.updateHistory) {
|
||||
qs.updateHistory = additionalFields.updateHistory as boolean;
|
||||
}
|
||||
if (additionalFields.customFieldsUi) {
|
||||
const customFields = (additionalFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
|
||||
if (customFields) {
|
||||
const data = customFields.reduce((obj, value) => Object.assign(obj, { [`${value.fieldId}`]: value.fieldValue }), {});
|
||||
Object.assign(fields, data);
|
||||
}
|
||||
}
|
||||
const issueTypes = await jiraSoftwareCloudApiRequest.call(this, '/api/2/issuetype', 'GET', body, qs);
|
||||
const subtaskIssues = [];
|
||||
for (const issueType of issueTypes) {
|
||||
|
@ -422,9 +468,12 @@ export class Jira implements INodeType {
|
|||
}
|
||||
body.fields = fields;
|
||||
responseData = await jiraSoftwareCloudApiRequest.call(this, '/api/2/issue', 'POST', body);
|
||||
returnData.push(responseData);
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-put
|
||||
if (operation === 'update') {
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-put
|
||||
if (operation === 'update') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const issueKey = this.getNodeParameter('issueKey', i) as string;
|
||||
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
|
||||
const body: IIssue = {};
|
||||
|
@ -462,6 +511,13 @@ export class Jira implements INodeType {
|
|||
if (updateFields.description) {
|
||||
fields.description = updateFields.description as string;
|
||||
}
|
||||
if (updateFields.customFieldsUi) {
|
||||
const customFields = (updateFields.customFieldsUi as IDataObject).customFieldsValues as IDataObject[];
|
||||
if (customFields) {
|
||||
const data = customFields.reduce((obj, value) => Object.assign(obj, { [`${value.fieldId}`]: value.fieldValue }), {});
|
||||
Object.assign(fields, data);
|
||||
}
|
||||
}
|
||||
const issueTypes = await jiraSoftwareCloudApiRequest.call(this, '/api/2/issuetype', 'GET', body);
|
||||
const subtaskIssues = [];
|
||||
for (const issueType of issueTypes) {
|
||||
|
@ -486,10 +542,12 @@ export class Jira implements INodeType {
|
|||
}
|
||||
|
||||
responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}`, 'PUT', body);
|
||||
responseData = { success: true };
|
||||
returnData.push({ success: true });
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-get
|
||||
if (operation === 'get') {
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-get
|
||||
if (operation === 'get') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const issueKey = this.getNodeParameter('issueKey', i) as string;
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||
if (additionalFields.fields) {
|
||||
|
@ -507,12 +565,13 @@ export class Jira implements INodeType {
|
|||
if (additionalFields.updateHistory) {
|
||||
qs.updateHistory = additionalFields.updateHistory as string;
|
||||
}
|
||||
|
||||
responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}`, 'GET', {}, qs);
|
||||
|
||||
returnData.push(responseData);
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-search-post
|
||||
if (operation === 'getAll') {
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-search-post
|
||||
if (operation === 'getAll') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||
const options = this.getNodeParameter('options', i) as IDataObject;
|
||||
const body: IDataObject = {};
|
||||
|
@ -533,21 +592,27 @@ export class Jira implements INodeType {
|
|||
responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/2/search`, 'POST', body);
|
||||
responseData = responseData.issues;
|
||||
}
|
||||
returnData.push.apply(returnData, responseData);
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-changelog-get
|
||||
if (operation === 'changelog') {
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-changelog-get
|
||||
if (operation === 'changelog') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const issueKey = this.getNodeParameter('issueKey', i) as string;
|
||||
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||
if (returnAll) {
|
||||
responseData = await jiraSoftwareCloudApiRequestAllItems.call(this, 'values',`/api/2/issue/${issueKey}/changelog`, 'GET');
|
||||
responseData = await jiraSoftwareCloudApiRequestAllItems.call(this, 'values', `/api/2/issue/${issueKey}/changelog`, 'GET');
|
||||
} else {
|
||||
qs.maxResults = this.getNodeParameter('limit', i) as number;
|
||||
responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}/changelog`, 'GET', {}, qs);
|
||||
responseData = responseData.values;
|
||||
}
|
||||
returnData.push.apply(returnData, responseData);
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-notify-post
|
||||
if (operation === 'notify') {
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-notify-post
|
||||
if (operation === 'notify') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const issueKey = this.getNodeParameter('issueKey', i) as string;
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||
const jsonActive = this.getNodeParameter('jsonParameters', 0) as boolean;
|
||||
|
@ -606,7 +671,7 @@ export class Jira implements INodeType {
|
|||
const notificationRecipientsRestrictions: NotificationRecipientsRestrictions = {};
|
||||
if (notificationRecipientsRestrictionsValues) {
|
||||
// @ts-ignore
|
||||
if (notificationRecipientsRestrictionsValues.groups. length > 0) {
|
||||
if (notificationRecipientsRestrictionsValues.groups.length > 0) {
|
||||
// @ts-ignore
|
||||
notificationRecipientsRestrictions.groups = notificationRecipientsRestrictionsValues.groups.map(group => {
|
||||
return {
|
||||
|
@ -627,10 +692,12 @@ export class Jira implements INodeType {
|
|||
}
|
||||
}
|
||||
responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}/notify`, 'POST', body, qs);
|
||||
|
||||
returnData.push(responseData);
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-transitions-get
|
||||
if (operation === 'transitions') {
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-transitions-get
|
||||
if (operation === 'transitions') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const issueKey = this.getNodeParameter('issueKey', i) as string;
|
||||
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||
if (additionalFields.transitionId) {
|
||||
|
@ -644,19 +711,118 @@ export class Jira implements INodeType {
|
|||
}
|
||||
responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}/transitions`, 'GET', {}, qs);
|
||||
responseData = responseData.transitions;
|
||||
|
||||
returnData.push.apply(returnData, responseData);
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-delete
|
||||
if (operation === 'delete') {
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-delete
|
||||
if (operation === 'delete') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const issueKey = this.getNodeParameter('issueKey', i) as string;
|
||||
const deleteSubtasks = this.getNodeParameter('deleteSubtasks', i) as boolean;
|
||||
qs.deleteSubtasks = deleteSubtasks;
|
||||
responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}`, 'DELETE', {}, qs);
|
||||
returnData.push({ success: true });
|
||||
}
|
||||
}
|
||||
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') {
|
||||
}
|
||||
if (resource === 'issueAttachment') {
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-attachments/#api-rest-api-3-issue-issueidorkey-attachments-post
|
||||
if (operation === 'add') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i) as string;
|
||||
const issueKey = this.getNodeParameter('issueKey', i) as string;
|
||||
|
||||
if (items[i].binary === undefined) {
|
||||
throw new Error('No binary data exists on item!');
|
||||
}
|
||||
|
||||
const item = items[i].binary as IBinaryKeyData;
|
||||
|
||||
const binaryData = item[binaryPropertyName] as IBinaryData;
|
||||
|
||||
if (binaryData === undefined) {
|
||||
throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`);
|
||||
}
|
||||
|
||||
responseData = await jiraSoftwareCloudApiRequest.call(
|
||||
this,
|
||||
`/api/3/issue/${issueKey}/attachments`,
|
||||
'POST',
|
||||
{},
|
||||
{},
|
||||
undefined,
|
||||
{
|
||||
formData: {
|
||||
file: {
|
||||
value: Buffer.from(binaryData.data, BINARY_ENCODING),
|
||||
options: {
|
||||
filename: binaryData.fileName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
returnData.push.apply(returnData, responseData);
|
||||
}
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-attachments/#api-rest-api-3-attachment-id-delete
|
||||
if (operation === 'remove') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const attachmentId = this.getNodeParameter('attachmentId', i) as string;
|
||||
responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/3/attachment/${attachmentId}`, 'DELETE', {}, qs);
|
||||
returnData.push({ success: true });
|
||||
}
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-attachments/#api-rest-api-3-attachment-id-get
|
||||
if (operation === 'get') {
|
||||
const download = this.getNodeParameter('download', 0) as boolean;
|
||||
for (let i = 0; i < length; i++) {
|
||||
const attachmentId = this.getNodeParameter('attachmentId', i) as string;
|
||||
responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/3/attachment/${attachmentId}`, 'GET', {}, qs);
|
||||
returnData.push({ json: responseData });
|
||||
}
|
||||
if (download) {
|
||||
const binaryPropertyName = this.getNodeParameter('binaryProperty', 0) as string;
|
||||
for (const [index, attachment] of returnData.entries()) {
|
||||
returnData[index]['binary'] = {};
|
||||
//@ts-ignore
|
||||
const buffer = await jiraSoftwareCloudApiRequest.call(this, '', 'GET', {}, {}, attachment?.json!.content, { json: false, encoding: null });
|
||||
//@ts-ignore
|
||||
returnData[index]['binary'][binaryPropertyName] = await this.helpers.prepareBinaryData(buffer, attachment.json.filename, attachment.json.mimeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (operation === 'getAll') {
|
||||
const download = this.getNodeParameter('download', 0) as boolean;
|
||||
for (let i = 0; i < length; i++) {
|
||||
const issueKey = this.getNodeParameter('issueKey', i) as string;
|
||||
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||
const { fields: { attachment } } = await jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}`, 'GET', {}, qs);
|
||||
responseData = attachment;
|
||||
if (returnAll === false) {
|
||||
const limit = this.getNodeParameter('limit', i) as number;
|
||||
responseData = responseData.slice(0, limit);
|
||||
}
|
||||
responseData = responseData.map((data: IDataObject) => ({ json: data }));
|
||||
returnData.push.apply(returnData, responseData);
|
||||
}
|
||||
if (download) {
|
||||
const binaryPropertyName = this.getNodeParameter('binaryProperty', 0) as string;
|
||||
for (const [index, attachment] of returnData.entries()) {
|
||||
returnData[index]['binary'] = {};
|
||||
//@ts-ignore
|
||||
const buffer = await jiraSoftwareCloudApiRequest.call(this, '', 'GET', {}, {}, attachment.json.content, { json: false, encoding: null });
|
||||
//@ts-ignore
|
||||
returnData[index]['binary'][binaryPropertyName] = await this.helpers.prepareBinaryData(buffer, attachment.json.filename, attachment.json.mimeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const jsonParameters = this.getNodeParameter('jsonParameters', 0) as boolean;
|
||||
const issueKey = this.getNodeParameter('issueKey', i) as string;
|
||||
const options = this.getNodeParameter('options', i) as IDataObject;
|
||||
|
@ -697,18 +863,23 @@ export class Jira implements INodeType {
|
|||
}
|
||||
|
||||
responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/3/issue/${issueKey}/comment`, 'POST', body, qs);
|
||||
returnData.push(responseData);
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-get
|
||||
if (operation === 'get') {
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-get
|
||||
if (operation === 'get') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
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);
|
||||
|
||||
returnData.push(responseData);
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-get
|
||||
if (operation === 'getAll') {
|
||||
}
|
||||
//https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-get
|
||||
if (operation === 'getAll') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const issueKey = this.getNodeParameter('issueKey', i) as string;
|
||||
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||
const options = this.getNodeParameter('options', i) as IDataObject;
|
||||
|
@ -722,16 +893,21 @@ export class Jira implements INodeType {
|
|||
responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/3/issue/${issueKey}/comment`, 'GET', body, qs);
|
||||
responseData = responseData.comments;
|
||||
}
|
||||
returnData.push.apply(returnData, responseData);
|
||||
}
|
||||
//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') {
|
||||
}
|
||||
//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') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
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 };
|
||||
returnData.push({ 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') {
|
||||
}
|
||||
//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') {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const issueKey = this.getNodeParameter('issueKey', i) as string;
|
||||
const commentId = this.getNodeParameter('commentId', i) as string;
|
||||
const options = this.getNodeParameter('options', i) as IDataObject;
|
||||
|
@ -771,14 +947,15 @@ export class Jira implements INodeType {
|
|||
Object.assign(body, { body: json });
|
||||
}
|
||||
responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/3/issue/${issueKey}/comment/${commentId}`, 'PUT', body, qs);
|
||||
returnData.push(responseData);
|
||||
}
|
||||
}
|
||||
if (Array.isArray(responseData)) {
|
||||
returnData.push.apply(returnData, responseData as IDataObject[]);
|
||||
} else {
|
||||
returnData.push(responseData as IDataObject);
|
||||
}
|
||||
}
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
|
||||
if (resource === 'issueAttachment' && (operation === 'getAll' || operation === 'get')) {
|
||||
return this.prepareOutputData(returnData as unknown as INodeExecutionData[]);
|
||||
} else {
|
||||
return [this.helpers.returnJsonArray(returnData)];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ export class JiraTrigger implements INodeType {
|
|||
description: INodeTypeDescription = {
|
||||
displayName: 'Jira Trigger',
|
||||
name: 'jiraTrigger',
|
||||
icon: 'file:jira.png',
|
||||
icon: 'file:jira.svg',
|
||||
group: ['trigger'],
|
||||
version: 1,
|
||||
description: 'Starts the workflow when Jira events occurs.',
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 872 B |
1
packages/nodes-base/nodes/Jira/jira.svg
Normal file
1
packages/nodes-base/nodes/Jira/jira.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 68.25 71.25" fill="#fff" fill-rule="evenodd" stroke="#000" stroke-linecap="round" stroke-linejoin="round"><use xlink:href="#C" x="3.125" y="3.125"/><defs><linearGradient id="A" x1="91.90%" y1="40.22%" x2="28.49%" y2="81.63%"><stop offset="18%" stop-color="#0052cc"/><stop offset="100%" stop-color="#2684ff"/></linearGradient><linearGradient id="B" x1="8.70%" y1="59.17%" x2="72.26%" y2="17.99%"><stop offset="18%" stop-color="#0052cc"/><stop offset="100%" stop-color="#2684ff"/></linearGradient></defs><symbol id="C" overflow="visible"><g stroke="none" fill-rule="nonzero"><path d="M61.161 30.211L30.95 0 .74 30.211a2.54 2.54 0 0 0 0 3.581l30.211 30.21 30.211-30.21a2.54 2.54 0 0 0 0-3.581zM30.95 41.46l-9.462-9.462 9.462-9.462 9.462 9.462z" fill="#2684ff"/><path d="M30.95 22.599C24.755 16.405 24.724 6.37 30.881.138L10.114 20.774l11.268 11.268z" fill="url(#A)"/><path d="M40.437 31.973L30.95 41.46a15.93 15.93 0 0 1 0 22.536l20.749-20.749z" fill="url(#B)"/></g></symbol></svg>
|
After Width: | Height: | Size: 1 KiB |
Loading…
Reference in a new issue