diff --git a/packages/nodes-base/credentials/JiraApi.credentials.ts b/packages/nodes-base/credentials/JiraSoftwareCloudApi.credentials.ts similarity index 75% rename from packages/nodes-base/credentials/JiraApi.credentials.ts rename to packages/nodes-base/credentials/JiraSoftwareCloudApi.credentials.ts index e6230c6fc0..b1c54bfd54 100644 --- a/packages/nodes-base/credentials/JiraApi.credentials.ts +++ b/packages/nodes-base/credentials/JiraSoftwareCloudApi.credentials.ts @@ -3,9 +3,9 @@ import { NodePropertyTypes, } from 'n8n-workflow'; -export class JiraApi implements ICredentialType { - name = 'jiraApi'; - displayName = 'Jira API'; +export class JiraSoftwareCloudApi implements ICredentialType { + name = 'jiraSoftwareCloudApi'; + displayName = 'Jira Software Cloud API'; properties = [ { displayName: 'Email', diff --git a/packages/nodes-base/nodes/Jira/GenericFunctions.ts b/packages/nodes-base/nodes/Jira/GenericFunctions.ts index 8e71e1aa1b..61a6f4a008 100644 --- a/packages/nodes-base/nodes/Jira/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Jira/GenericFunctions.ts @@ -12,13 +12,12 @@ import { IDataObject, } from 'n8n-workflow'; -export async function jiraApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, endpoint: string, method: string, body: any = {}, query?: IDataObject, uri?: string): Promise { // tslint:disable-line:no-any - const credentials = this.getCredentials('jiraApi'); +export async function jiraSoftwareCloudApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, endpoint: string, method: string, body: any = {}, query?: IDataObject, uri?: string): Promise { // tslint:disable-line:no-any + const credentials = this.getCredentials('jiraSoftwareCloudApi'); if (credentials === undefined) { throw new Error('No credentials got returned!'); } const data = Buffer.from(`${credentials!.email}:${credentials!.apiToken}`).toString(BINARY_ENCODING); - console.log(data) const headerWithAuthentication = Object.assign({}, { Authorization: `Basic ${data}`, Accept: 'application/json', 'Content-Type': 'application/json' }); @@ -49,7 +48,7 @@ export async function jiraApiRequest(this: IHookFunctions | IExecuteFunctions | * Make an API request to paginated intercom endpoint * and return all results */ -export async function jiraApiRequestAllItems(this: IHookFunctions | IExecuteFunctions, propertyName: string, endpoint: string, method: string, body: any = {}, query: IDataObject = {}): Promise { // tslint:disable-line:no-any +export async function jiraSoftwareCloudApiRequestAllItems(this: IHookFunctions | IExecuteFunctions, propertyName: string, endpoint: string, method: string, body: any = {}, query: IDataObject = {}): Promise { // tslint:disable-line:no-any const returnData: IDataObject[] = []; @@ -60,7 +59,7 @@ export async function jiraApiRequestAllItems(this: IHookFunctions | IExecuteFunc let uri: string | undefined; do { - responseData = await jiraApiRequest.call(this, endpoint, method, body, query, uri); + responseData = await jiraSoftwareCloudApiRequest.call(this, endpoint, method, body, query, uri); uri = responseData.pages.next; returnData.push.apply(returnData, responseData[propertyName]); } while ( diff --git a/packages/nodes-base/nodes/Jira/IssueDescription.ts b/packages/nodes-base/nodes/Jira/IssueDescription.ts index fd58d07b2a..13677f04b8 100644 --- a/packages/nodes-base/nodes/Jira/IssueDescription.ts +++ b/packages/nodes-base/nodes/Jira/IssueDescription.ts @@ -88,10 +88,9 @@ export const issueFields = [ description: 'Summary', }, { - displayName: 'Parent Issue Identifier', - name: 'parentIssueId', - type: 'options', - required: false, + displayName: 'Has Parent Issue?', + name: 'hasParentIssue', + type: 'boolean', displayOptions: { show: { resource: [ @@ -102,25 +101,12 @@ export const issueFields = [ ], }, }, - default: 'id', - options: [ - { - name: 'ID', - value: 'id', - description: 'Issue ID', - }, - { - name: 'Key', - value: 'key', - description: 'Issue Key', - - } - ], - description: 'Parent Issue Identifier', + default: false, + description: 'Weather The Issue Has A Parent Issue ID/Key or Not', }, { - displayName: 'Parent Issue Identifier Value', - name: 'parentIssueIdValue', + displayName: 'Parent Issue Key', + name: 'parentIssueKey', type: 'string', required: false, displayOptions: { @@ -131,10 +117,13 @@ export const issueFields = [ operation: [ 'create', ], + hasParentIssue: [ + true, + ], }, }, default: '', - description: 'Parent Issue ID/Key valie', + description: 'Parent Issue Key', }, { displayName: 'Additional Fields', @@ -186,6 +175,14 @@ export const issueFields = [ required : false, description: 'Assignee', }, + { + displayName: 'Description', + name: 'description', + type: 'string', + default: '', + required : false, + description: 'Description', + }, ], }, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Jira/IssueInterface.ts b/packages/nodes-base/nodes/Jira/IssueInterface.ts new file mode 100644 index 0000000000..b0c16d1eb0 --- /dev/null +++ b/packages/nodes-base/nodes/Jira/IssueInterface.ts @@ -0,0 +1,16 @@ +import { IDataObject } from "n8n-workflow"; + +export interface IFields { + summary: string; + project?: IDataObject; + issuetype?: IDataObject; + labels?: string[]; + priority?: IDataObject; + assignee?: IDataObject; + description?: string; + parent?: IDataObject; +} + +export interface IIssue { + fields?: IFields; +} diff --git a/packages/nodes-base/nodes/Jira/Jira.node.ts b/packages/nodes-base/nodes/Jira/JiraSoftwareCloud.node.ts similarity index 74% rename from packages/nodes-base/nodes/Jira/Jira.node.ts rename to packages/nodes-base/nodes/Jira/JiraSoftwareCloud.node.ts index aac2b21d31..fe094c01bb 100644 --- a/packages/nodes-base/nodes/Jira/Jira.node.ts +++ b/packages/nodes-base/nodes/Jira/JiraSoftwareCloud.node.ts @@ -10,33 +10,37 @@ import { INodePropertyOptions, } from 'n8n-workflow'; import { - jiraApiRequest, - jiraApiRequestAllItems, + jiraSoftwareCloudApiRequest, + jiraSoftwareCloudApiRequestAllItems, validateJSON, } from './GenericFunctions'; import { issueOpeations, issueFields, } from './IssueDescription'; +import { + IIssue, + IFields, + } from './IssueInterface'; -export class Jira implements INodeType { +export class JiraSoftwareCloud implements INodeType { description: INodeTypeDescription = { - displayName: 'Jira', - name: 'Jira', + displayName: 'Jira Software Cloud', + name: 'Jira Software Cloud', icon: 'file:jira.png', group: ['output'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', - description: 'Consume Jira API', + description: 'Consume Jira Software Cloud API', defaults: { - name: 'Jira', + name: 'Jira Software Cloud', color: '#c02428', }, inputs: ['main'], outputs: ['main'], credentials: [ { - name: 'jiraApi', + name: 'jiraSoftwareCloudApi', required: true, } ], @@ -68,7 +72,7 @@ export class Jira implements INodeType { const returnData: INodePropertyOptions[] = []; let projects; try { - projects = await jiraApiRequest.call(this, '/project/search', 'GET'); + projects = await jiraSoftwareCloudApiRequest.call(this, '/project/search', 'GET'); } catch (err) { throw new Error(`Jira Error: ${err}`); } @@ -90,7 +94,7 @@ export class Jira implements INodeType { const returnData: INodePropertyOptions[] = []; let issueTypes; try { - issueTypes = await jiraApiRequest.call(this, '/issuetype', 'GET'); + issueTypes = await jiraSoftwareCloudApiRequest.call(this, '/issuetype', 'GET'); } catch (err) { throw new Error(`Jira Error: ${err}`); } @@ -112,7 +116,7 @@ export class Jira implements INodeType { const returnData: INodePropertyOptions[] = []; let labels; try { - labels = await jiraApiRequest.call(this, '/label', 'GET'); + labels = await jiraSoftwareCloudApiRequest.call(this, '/label', 'GET'); } catch (err) { throw new Error(`Jira Error: ${err}`); } @@ -134,7 +138,7 @@ export class Jira implements INodeType { const returnData: INodePropertyOptions[] = []; let priorities; try { - priorities = await jiraApiRequest.call(this, '/priority', 'GET'); + priorities = await jiraSoftwareCloudApiRequest.call(this, '/priority', 'GET'); } catch (err) { throw new Error(`Jira Error: ${err}`); } @@ -156,7 +160,7 @@ export class Jira implements INodeType { const returnData: INodePropertyOptions[] = []; let users; try { - users = await jiraApiRequest.call(this, '/users/search', 'GET'); + users = await jiraSoftwareCloudApiRequest.call(this, '/users/search', 'GET'); } catch (err) { throw new Error(`Jira Error: ${err}`); } @@ -188,50 +192,48 @@ export class Jira implements INodeType { const summary = this.getNodeParameter('summary', i) as string; const projectId = this.getNodeParameter('project', i) as string; const issueTypeId = this.getNodeParameter('issueType', i) as string; - const parentIssueId = this.getNodeParameter('parentIssueId', i) as string; - const parentIssueIdValue = this.getNodeParameter('parentIssueIdValue', i) as string; + const hasParentIssue = this.getNodeParameter('hasParentIssue', i) as boolean; const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - const body = { - fields: { - summary, - project: { - id: projectId, - }, - issuetype: { - id: issueTypeId - }, - } + const body: IIssue = {}; + const fields: IFields = { + summary, + project: { + id: projectId, + }, + issuetype: { + id: issueTypeId, + }, }; if (additionalFields.labels) { - body.fields.labels = additionalFields.labels as string[]; + fields.labels = additionalFields.labels as string[]; } if (additionalFields.priority) { - body.fields.priority = { + fields.priority = { id: additionalFields.priority as string, }; } if (additionalFields.assignee) { - body.fields.assignee = { + fields.assignee = { id: additionalFields.assignee as string, }; } - if (!parentIssueIdValue && issueTypeId === 'sub-task') { - throw new Error('You must define a Parent ID/Key when Issue type is sub-task'); + if (additionalFields.description) { + fields.description = additionalFields.description as string; + } + if (hasParentIssue) { + const parentIssueKey = this.getNodeParameter('parentIssueKey', i) as string; + if (!parentIssueKey && issueTypeId === 'sub-task') { + throw new Error('You must define a Parent Issue Key when Issue type is sub-task'); - } else if (parentIssueIdValue && issueTypeId === 'sub-task') { - if (parentIssueId === 'id') { - body.fields.parent = { - id: parentIssueIdValue, - }; - } - if (parentIssueId === 'key') { - body.fields.parent = { - key: parentIssueIdValue, + } else if (parentIssueKey && issueTypeId === 'sub-task') { + fields.parent = { + key: parentIssueKey, }; } } + body.fields = fields; try { - responseData = await jiraApiRequest.call(this, '/issue', 'POST', body); + responseData = await jiraSoftwareCloudApiRequest.call(this, '/issue', 'POST', body); } catch (err) { throw new Error(`Jira Error: ${JSON.stringify(err)}`); } diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index 6673d95d77..a82727dbb0 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -43,7 +43,7 @@ "dist/credentials/HttpHeaderAuth.credentials.js", "dist/credentials/IntercomApi.credentials.js", "dist/credentials/Imap.credentials.js", - "dist/credentials/JiraApi.credentials.js", + "dist/credentials/JiraSoftwareCloudApi.credentials.js", "dist/credentials/LinkFishApi.credentials.js", "dist/credentials/MailchimpApi.credentials.js", "dist/credentials/MailgunApi.credentials.js", @@ -102,7 +102,7 @@ "dist/nodes/If.node.js", "dist/nodes/Interval.node.js", "dist/nodes/Intercom/Intercom.node.js", - "dist/nodes/Jira/Jira.node.js", + "dist/nodes/Jira/JiraSoftwareCloud.node.js", "dist/nodes/LinkFish/LinkFish.node.js", "dist/nodes/Mailchimp/Mailchimp.node.js", "dist/nodes/Mailgun/Mailgun.node.js",