From 9ac9ff3557a545d549634fe44f04925a9f71e9ec Mon Sep 17 00:00:00 2001 From: Rupenieks Date: Thu, 30 Apr 2020 14:03:36 +0200 Subject: [PATCH 01/15] node setup --- .../credentials/AgileCrmApi.credentials.ts | 23 + .../nodes/AgileCrm/AgileCrm.node.ts | 148 ++++++ .../nodes/AgileCrm/ContactDescription.ts | 473 ++++++++++++++++++ .../nodes/AgileCrm/ContactInterface.ts | 18 + .../nodes/AgileCrm/GenericFunctions.ts | 59 +++ .../nodes-base/nodes/AgileCrm/agilecrm.png | Bin 0 -> 20236 bytes packages/nodes-base/package.json | 2 + 7 files changed, 723 insertions(+) create mode 100644 packages/nodes-base/credentials/AgileCrmApi.credentials.ts create mode 100644 packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts create mode 100644 packages/nodes-base/nodes/AgileCrm/ContactDescription.ts create mode 100644 packages/nodes-base/nodes/AgileCrm/ContactInterface.ts create mode 100644 packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts create mode 100644 packages/nodes-base/nodes/AgileCrm/agilecrm.png diff --git a/packages/nodes-base/credentials/AgileCrmApi.credentials.ts b/packages/nodes-base/credentials/AgileCrmApi.credentials.ts new file mode 100644 index 0000000000..d189270932 --- /dev/null +++ b/packages/nodes-base/credentials/AgileCrmApi.credentials.ts @@ -0,0 +1,23 @@ +import { + ICredentialType, + NodePropertyTypes, +} from 'n8n-workflow'; + +export class AgileCrmApi implements ICredentialType { + name = 'agileCrmApi'; + displayName = 'AgileCRM API'; + properties = [ + { + displayName: 'Email', + name: 'email', + type: 'string' as NodePropertyTypes, + default: '', + }, + { + displayName: 'API Key', + name: 'apiKey', + type: 'string' as NodePropertyTypes, + default: '', + }, + ]; +} diff --git a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts new file mode 100644 index 0000000000..84be0ddcfc --- /dev/null +++ b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts @@ -0,0 +1,148 @@ +import { IExecuteFunctions } from 'n8n-core'; +import { + INodeExecutionData, + INodeType, + INodeTypeDescription, + IDataObject +} from 'n8n-workflow'; + +import { + contactOperations, + contactFields +} from './ContactDescription'; +import { agileCrmApiRequest, validateJSON} from './GenericFunctions'; +import { IContact, IProperty } from './ContactInterface'; + + +export class AgileCrm implements INodeType { + description: INodeTypeDescription = { + displayName: 'AgileCRM', + name: 'agileCrm', + icon: 'file:agilecrm.png', + group: ['transform'], + version: 1, + description: 'Consume AgileCRM API', + defaults: { + name: 'AgileCRM', + color: '#772244', + }, + inputs: ['main'], + outputs: ['main'], + credentials: [ + { + name: 'agileCrmApi', + required: true, + } + ], + properties: [ + // Node properties which the user gets displayed and + // can change on the node. + { + displayName: 'Resource', + name: 'resource', + type: 'options', + options: [ + { + name: 'Contact', + value: 'contact' + } + ], + default: 'contact', + description: 'Resource to consume.', + }, + // CONTACT + ...contactOperations, + ...contactFields, + ], + + }; + + + async execute(this: IExecuteFunctions): Promise { + + const items = this.getInputData(); + const returnData: IDataObject[] = []; + const length = items.length as unknown as number; + let responseData; + const qs: IDataObject = {}; + const resource = this.getNodeParameter('resource', 0) as string; + const operation = this.getNodeParameter('operation', 0) as string; + + for (let i = 0; i < length; i++) { + + if(resource === 'contact'){ + + if(operation === 'get'){ + const contactId = this.getNodeParameter('contactId', i) as string; + + const endpoint = `api/contacts/${contactId}`; + responseData = await agileCrmApiRequest.call(this, 'GET', endpoint); + + } + + if(operation === 'getAll'){ + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + if (returnAll) { + const endpoint = `api/contacts`; + responseData = await agileCrmApiRequest.call(this, 'GET', endpoint); + } else { + const limit = this.getNodeParameter('limit', i) as number; + const endpoint = `api/contacts?page_size=${limit}`; + responseData = await agileCrmApiRequest.call(this, 'GET', endpoint); + } + } + + if(operation === 'create'){ + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + const body: IContact = {}; + + if (jsonParameters) { + const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; + + if (additionalFieldsJson !== '' ) { + + if (validateJSON(additionalFieldsJson) !== undefined) { + + Object.assign(body, JSON.parse(additionalFieldsJson)); + + } else { + throw new Error('Additional fields must be a valid JSON'); + } + } + + } else { + + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.starValue) { + body.star_value = additionalFields.starValue as string; + } + if (additionalFields.leadScore) { + body.lead_score = additionalFields.leadScore as string; + } + if (additionalFields.tags) { + body.tags = additionalFields.tags as string[]; + } + if (additionalFields.properties) { + body.properties = (additionalFields.properties as IDataObject).property as IDataObject[]; + } + } + const endpoint = 'api/contacts'; + console.log(body); + responseData = await agileCrmApiRequest.call(this, 'POST', endpoint, body); + } + + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); + } + } + + } + + return [this.helpers.returnJsonArray(returnData)]; + } + +} diff --git a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts new file mode 100644 index 0000000000..b660cff6b2 --- /dev/null +++ b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts @@ -0,0 +1,473 @@ +import { + INodeProperties, + } from 'n8n-workflow'; + +export const contactOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'contact', + ], + }, + }, + options: [ + { + name: 'Get', + value: 'get', + description: 'Get a contact', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all contacts', + }, + { + name: 'Create', + value: 'create', + description: 'Create a new contact', + }, + ], + default: 'get', + description: 'The operation to perform.', + }, +] as INodeProperties[]; + +export const contactFields = [ +/* -------------------------------------------------------------------------- */ +/* contact:get */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Contact ID', + name: 'contactId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'get', + ], + }, + }, + default: '', + description: 'Unique identifier for a particular contact', + }, + + +/* -------------------------------------------------------------------------- */ +/* contact:get all */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'contact', + ], + 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: [ + 'contact', + ], + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + } + }, + +/* -------------------------------------------------------------------------- */ +/* ticket:create */ +/* -------------------------------------------------------------------------- */ + +{ + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'create', + ], + }, + }, +}, +{ + displayName: ' Additional Fields', + name: 'additionalFieldsJson', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'create', + ], + jsonParameters: [ + true, + ], + }, + }, + + description: `Object of values to set as described here.`, +}, + +{ + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'create', + ], + jsonParameters: [ + false, + ], + }, + }, + options: [ + { + displayName: 'Star Value', + name: 'starValue', + type: 'options', + default: '', + required: false, + description: 'Rating of contact (Max value 5). This is not applicable for companies.', + options: [ + { + name: '0', + value: 0 + }, + { + name: '1', + value: 1 + }, + { + name: '2', + value: 2 + }, + { + name: '3', + value: 3 + }, + { + name: '4', + value: 4 + }, + { + name: '5', + value: 5 + }, + ] + }, + { + displayName: 'Lead Score', + name: 'leadScore', + type: 'number', + default: '', + description: 'Score of contact. This is not applicable for companies.', + required: false, + typeOptions: { + minValue: 0 + } + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + typeOptions: { + multipleValues: true, + multipleValueButtonText: 'Add Tag', + }, + default: [], + placeholder: 'Tag', + description: 'Unique identifiers added to contact, for easy management of contacts. This is not applicable for companies.', + }, + { + displayName: 'Properties', + name: 'properties', + type: 'fixedCollection', + default: {}, + description: 'Contact properties are represented by list of JSON objects, each JSON object should follow the prototype shown. Custom fields will have type as CUSTOM and others will have type as SYSTEM.', + required: true, + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Property', + name: 'property', + values: [ + { + displayName: 'Type', + name: 'type', + type: 'options', + default: 'SYSTEM', + required: true, + description: 'Type of the field.', + options: [ + { + name: 'SYSTEM', + value: 'SYSTEM', + }, + { + name: 'CUSTOM', + value: 'CUSTOM' + } + ] + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + required: true, + description: 'Name of the field.' + }, + { + displayName: 'Sub Type', + name: 'subType', + default: '', + required: false, + type: 'options', + description: 'Name of the field.', + displayOptions: { + show: { + type: [ + 'SYSTEM' + ], + name: [ + 'email' + ] + } + }, + options: [ + { + name: 'Work', + value: 'work', + + }, + { + name: 'Personal', + value: 'personal', + + } + ] + }, + { + displayName: 'Sub Type', + name: 'subType', + default: '', + required: false, + type: 'options', + description: 'Name of the field.', + displayOptions: { + show: { + type: [ + 'SYSTEM' + ], + name: [ + 'phone' + ] + } + }, + options: [ + { + name: 'Work', + value: 'work', + + }, + { + name: 'Home', + value: 'home', + }, + { + name: 'Mobile', + value: 'mobile', + }, + { + name: 'Main', + value: 'main', + }, + { + name: 'Home Fax', + value: 'homeFax', + }, + { + name: 'Work Fax', + value: 'workFax', + }, + { + name: 'Other', + value: 'other', + }, + ] + }, + { + displayName: 'Sub Type', + name: 'subType', + default: '', + required: false, + type: 'options', + description: 'Name of the field.', + displayOptions: { + show: { + type: [ + 'SYSTEM' + ], + name: [ + 'address' + ] + } + }, + options: [ + { + name: 'Home', + value: 'home', + }, + { + name: 'Postal', + value: 'postal', + }, + { + name: 'Office', + value: 'office', + }, + ] + }, + { + displayName: 'Sub Type', + name: 'subType', + default: '', + required: false, + type: 'options', + description: 'Name of the field.', + displayOptions: { + show: { + type: [ + 'SYSTEM' + ], + name: [ + 'website' + ] + } + }, + options: [ + { + name: 'URL', + value: 'url', + }, + { + name: 'SKYPE', + value: 'skype', + }, + { + name: 'TWITTER', + value: 'twitter', + }, + { + name: 'LINKEDIN', + value: 'linkedin', + }, + { + name: 'FACEBOOK', + value: 'facebook', + }, + { + name: 'XING', + value: 'xing', + }, + { + name: 'FEED', + value: 'feed', + }, + { + name: 'GOOGLE_PLUS', + value: 'googlePlus', + }, + { + name: 'FLICKR', + value: 'flickr', + }, + { + name: 'GITHUB', + value: 'github', + }, + { + name: 'YOUTUBE', + value: 'youtube', + }, + ] + }, + { + displayName: 'Sub Type', + name: 'subType', + default: '', + required: false, + type: 'string', + description: 'Name of the field.', + displayOptions: { + show: { + type: [ + 'CUSTOM' + ], + } + } + }, + { + displayName: 'Value', + name: 'value', + default: '', + required: false, + type: 'string', + description: 'Value of the property.' + }, + ] + } + + ] + + }, + ], +}, + +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts b/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts new file mode 100644 index 0000000000..661a4c4742 --- /dev/null +++ b/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts @@ -0,0 +1,18 @@ +import { + IDataObject, + } from 'n8n-workflow'; + + export interface IProperty { + type: string; + name: string; + subtype?: string; + value?: string; +} + + export interface IContact { + star_value?: string; + lead_score?: string; + tags?: string[]; + properties?: IDataObject[]; + } + diff --git a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts new file mode 100644 index 0000000000..d363443b50 --- /dev/null +++ b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts @@ -0,0 +1,59 @@ +import { + OptionsWithUri, + } from 'request'; + +import { + IExecuteFunctions, + IHookFunctions, + ILoadOptionsFunctions, + IExecuteSingleFunctions, +} from 'n8n-core'; + +import { + IDataObject, +} from 'n8n-workflow'; + + +export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: any = {}, query: IDataObject = {}, uri?: string): Promise { + + const node = this.getNodeParameter('credentials', 1); + const credentials = this.getCredentials('agileCrmApi'); + + const options: OptionsWithUri = { + method, + headers: { + 'Accept': 'application/json', + }, + body: body! || {}, + auth: { + username: credentials!.email as string, + password: credentials!.apiKey as string + }, + uri: uri || `https://n8nio.agilecrm.com/dev/${endpoint}`, + json: true + }; + + + try { + return await this.helpers.request!(options); + } catch (error) { + + if (error.response && error.response.body && error.response.body.errors) { + const errorMessages = error.response.body.errors.map((e: IDataObject) => e.message); + throw new Error(`AgileCRM error response [${error.statusCode}]: ${errorMessages.join(' | ')}`); + } + + throw error; + } +} + +export function validateJSON(json: string | undefined): any { // tslint:disable-line:no-any + let result; + try { + result = JSON.parse(json!); + } catch (exception) { + result = undefined; + } + return result; +} + diff --git a/packages/nodes-base/nodes/AgileCrm/agilecrm.png b/packages/nodes-base/nodes/AgileCrm/agilecrm.png new file mode 100644 index 0000000000000000000000000000000000000000..ef6ac995a32b776d569b203cbdd1969d99aa977b GIT binary patch literal 20236 zcmeI4cT|&0(C{CMfQU2!3!*fU77`$oVCcO|lcESAgb*pA1Zj#O-2wvA1rZgbcN9eh zL_pBcM7l^9xPWx7hW+^1d-!plxKElW=T*tKW-K>?)P*aragh8R`V`91P!LnpR0ZMG+W6QG<(-)ujt$1C;!tRI&gi4T`|DBmom3gBq}HLE4Q1 z$3cMY(F+ruKw#Q>vOfiI@;VPYMMez3y$2Pc1~?uA@>@?_QU@#`0GoquJq+jp0T69- z2Q8rZK2U>a-c<_FF#r&wh)^Mb+8?lO;^XrHLXrVCjYV_#f=D6rq%eV0aw)uuAEq93 zk`ClfYi=%fND!~RSA;+VsIQ7UJ>JQI(7~ zpy{VHTfBC5qo2oH^W2mGU>FzB{#g`Ub|CN=O`yx?%p-Huj;D8Jc&%M_C}mQr05Ycf z%$MA@*{I*TR@K`(J~q~)Q?GIo(QJPHGrG>E#(dNH?*RCxwUu{IM)-pytb;VE*WcB> zT-LjLur+pPh~2^XwXX%~r~(~>hg-e3<`p+JGmZd( z4%)Hq0B~B3U(B?*OtFy;0Ms&qgo~9qmuvTl*3cZR-7!$R>yxc?hzfswoeHxGy?x+8 z4_l%9izZZNaaVxS%ygj$v_bjAC_W4;ba$m_8!t(rX2)gLYCYH_`1u@bpDc z*j=*Vi=x|`9JeMR^ZOSokT8hcU;R0EvsA z!m2gJuLqSH$-ic(P_4Qrb09<`b61-^PCO-=BO|rVqx^vU73o`(ZF!DNebEZ4jgXr6 z`)DQWogrck&s0ieMR&#_TS|EI8S)wq6raeadK9^WY%TGoW(`uW*(pu!t-_5sq^xD3 zXJOEzb&vZXKa{0!r_4^O5Tm-Iym9w*%LN{?{9V7#PC`7~LQ9nI4QuosFtdMzYP}3U zYow~g(W+~d+9h{PJ6Jn3I$VwUrbKg6p;`y{;$HOGJC)MHu8VSuG=+|(jXfKa9OE40 zSv*OfW~bzSXWe8((75@G&i--cap*V=DoH}w>~@Or;JsU>EK<={Dh0PHjf;%J@9lwl zrNCYVb7vli3noYN-f3pLCnO-6HezD~$9%S}5zW5Q{I&N+53JQsZrYpQrBz;ZK^#`2lo zGegxoMj0hGqty-EyO8_Kd_;MicISn81xeKll)UOacUJgO(k9oV%ksH7w_vK0I+EsP z#!J^76lq73+}Cg540cWmW+yHMTzbnkFEk>=nFZCW5=WhK%1ua2u*lQOGs@GPc`RKx zo1K>RSpAXZMi8TNqt4M&M>WyW_#J7JCcP$u+4R{Q`tousg<`o*cR6o8QuBW5nmw14 z{^WFEx*j(Bt?%Q>j|b0#H%&KPK4!0IGFZ@*G4Rv$GvN2ZpG&!8;auRx{skjd>t{-; zcMgB7lRQ@c}#?%P`VScz8Nt9*dcE*-PVvYe}|b`7ClUv$8JJ zC`c^W}soFxsM(xwS`fv~o|2P(3Ei zB(+l$y%$~O8N3v6Ia2pxi&&z9SSn}3VAJC<9o&k$^{`*ZN?K}JYTfL;{-QbQIm}%6 zz|EJ?n?mW9lAdkPnpEEzjkhcAx)~2~8p;naR5c7jS4{GOk>D8fg6`t`cfE7h5c7K# zRuw#Mjw+18W!_4>wX}IDQ**!Rev9EVY`RV8km?1#E&DCMt#%+g@CXH(Dl$kp=p^OF zy5BjTr%{S>{ixN_-dW`<8CA;c%F!1KE{@k0@HjU8b*+GBZ88ZTgU2w29uIi`ri~Uc zfw=rEfZ=Fpc&K@pVw78i#esJ5L@Dp~0aec-wU25EYHw4~;)bvykdBnFLax{uc%RHe z=tIQ@F$c?+T^4B;+RnNMVPe9C(yq==hCa>Bmon*?sMcJsZ3uUihy=ExCa z6_ra+(u**Vz5YR&S@<5ul_QILypKfD`_^&Qp?SgW((MsFs;7hx87yiE>-)w26;mzc z%l};RuIPAG$kCi@)q1=222D>h zan5jT^V8&k>*YCl^;Pz*4jm3t6K_H3Cm9oR6DJZGU3d5PmG2%pQ9iq}s@@Myd?ncb zD7aF!>h@FkgKAXv3;e5Nil%o=mrXyKO3!r+Rv^09UEAk4{i|1@e|7brtX|txc=4p) zjKWO6%b^Rkp}kSIrdSx6JGGv$;bL82;Nm{pNYz2LNz2Dr*pK4)HwQ$$c!dq znDJNeM?r9%6g>9>BLH2V)T-GIU^eRY;hUts#CE_TMD7hA8S#iyMQ5c_+;wm-Ad ze-eowI>UsWf5?m*?oi*lJbA4882;4a1KeV1|M(vB2j(e7ayBm0xM}$3xK6{yM>ig& z6jq&bs+#kAT;cDqHpQ7PgCAUe?7P6R^`;~U!SF7{lb;8A<_9jEsqxNOY9G*CqX`Xe{T#Cr&7`^`Iyt%}Ys>S5`1YjsTZxN_aZg>&-QAq7nb}{| z-%!_Z=*bHoN%7OmCpKnly$8Ix=5G%%8IGOfz96{e_;<;QNn7?t-2S+@Eo!QyrB6sn zP(R_+3Bj0J;4Jj@})b z*vs>pOX)-O-BeMI7%e{!l!>2#Dbmjg3A5)_RG^3Z$Ppa4pl}Fo9~Wm=PdOiX-Y!MxmGy5OATd6l;Va$D#h=T^mfptz;Pq(MlCv<$ZlOiWx#Mg}S)$}IsAmjXj1 z!IBV=grpo4A_tY={&wS4peMY8d)Pb38LMf03rCRTc^z>$H#soa+uK{rTT%?`fd-4i zU@$O50xTf`BJ==x`nuu}J|I_5zOPQc`%y!AB0Vr}I1JX6d)qI<4(o-J=jGiF^yBtz zUM_Aw0=asAV@IF}_CdIT#l;}te=*Y6CvE29@<&TgocdY9NWRVNj{!YRece!CW0WV> z%L9p0KZ|n3@%?EK_Q)T8+`K%Tzwog~f>F*W7lMf=VesOA9D>{TZy-O+e;dXR^}o&@ zhjIA1IKSC$YyQ;?<%9Vbvu({+voEReb%o%B{F77lKp}8g4^u4GS>bDz{rvt!`1-V+ zRosH+7*~6&x2F&sOlyAOSRIc--@9Ksce(pFO-%v}tFv6q9v z#2ut%q>vzKNhv81L<$N8!K4T?MG$r((g7-qLW#q^O!9a0f4Ek|BE7Z~iQxL{#<#~J z3GRQShny@Di4uoEksw)!9RwsUjzWMCl28Yby)+@79Yg{qVTbx2=oe@I2xRDiA=D*= z^Dlk2=VHG-7bpa3FA1{)LBvrGAeaQy4rGUf$$(^$GEkHxN(L(FAoD%MAKd&SlorO5 zkWIe7WEmmXzEmC)l>6_k-xbc7FBQZM;o*te-k9>d-*@JZlJldYY} zZl^EG9uEGk_2;mDSbj6Z{9!r&6N0b)e=+~}7~YO3S5oQ!)zz0?|L(*S>wxn{c%YQg zgbevFJM*j8-_3~K!@=9N+8Oh|un?Yzv;UvV@Sk?o|A}SznZ-y)gew|luK@m@z~3AG z+sb`i&);{}_ucx>od~x_$~j;?To5<~j0*yd0=v1Q;ozT*KV!mw)*w}^GuA^NYmZWp zgoFRo{6{OoFK@@c{_v*YX{@Qjt*x#qEe?~G21$sC|LW$Ke!uwH{*aR+R2xF(Bfji% zg3UkLi2GY?R}E*cFa2dCAcPxOeEa#E>91;HQ%lmOzp9B%e_EQkVsHu)-=YyU|6;ZM zNi6pTstMuHh*BU-jkt-p_i>C5%Gp8|D;zUU*sS}KuC*ZT%`FBY00>VfRGl+ zxJdIM(vooz0U<4tagpXjq$T4b0zz6O<08$6NK3{=1cbCm#zmSBk(P{$2ncDBjEgiM zA}tvg5fIWM85e0jL|QT~A|RwiGA`15h_qx}L_kQ3WL%{A5NXM{h=7n5$+$@KA<~j@ z5dk4Bl5vsdL!>3+A_78MB;z8@he%7tMFfPjNXA8)50RFPiwFp5k&KHpA0jOo7ZDKB zA{iHHK15nFE+QbLMKUhZe2BDUTtq-fi)37+`4DNzxQKv|7Rk6s^C8lbaS;I_Es}AO z=0l_<<01k=S|o{!{^w<&C|AO@pWcLvJkR8`;0PCpawD~j^#Q=|2mk~I1Hj)~gx4tm z@PYuqv@PM<(j)-bi;cB;u0i-)lMQV(WmBKNzfyd!SetP*Dozgg51rreFFWfX_p&XB zLl`tDXe(sJmyi-cV`O~h(nWra-8mGA_4k6PW1cJ4Usb$5&a~&Y1q+W>5G%Da`++;R zs464caa&lR}KYhw$W3UBW?EoVG-byQvDY~T*@ zT?Mc6=lx5DV+vn7$A?ow?qo=g?}=5ADT*xdGQ0AySpNCZb$D0$#ITG+`5LD042Xfk zZ#Ai`j7AjTIkK^#d&=slkFAM(3uj&S)rE7>n^cUCVK*;|+`C$n8KR7Y)ey z()u_XMyao`T+GtQv%H1Jr)cX6P3;pbalQ2}hBGCy-{Cpa(*SrYKG^rP;+z}*T|poE zyWF<)XM!(v=}ViJhg7-yG6?C_QC#+yk&b0pT__ubSvfg7Q#l0to;cBSEtc;Yqps7t z)|08%cmbuXF}H3!PkNtC#(QP2dVWMO4>es-2W6wl@;G~FY)hX&@cf19sFqZ|c=XU# z^Ugzk@^$JftIj>EFZHeHlpo$%7~pL^UlQ5i(|aX4`|?2bCjZ7qc*1Myok^4hUHft( z)Gn23DkLnnosJAwFni{un&G=isSRk1YZG4rN8-hq|D)ButkO^Y{M@f zsr>XLQB}1#lSiwj4Oy44_C#f7aivmNoA=;ErQ+^|x?97|5gRfmSW2KUG+q*9^x_JX zhEm_0;|;Xe+0s%RxbV5K%+|xtMtmfKL>7u2% zy(2S;&#P85dy?)Ko!*C7siS+hv^Xr<-@gR+E)FT$ow7%OB4=S`ERU_?ol^5~7oPWI z0xiXZ2lVO3-rXu;K___|GKyxrf7V`0X=BAcF=zN15tTCk9?xfOeEpPmQ%Ais^0ga- zbor6qwgh`~bVB3WonGHNfe0FmK3%nTb-^3k6aoK7nmwiPoi!s50p%FwJxbho!CB~0 zDKH2oXZkKGPi3I$$t{n&@2~fKJ{y%7#qqvb_>>JRgu1}}`A2mYg(`j>>pKUdyDRD~ zx>+Zl2U~t_JN@qFV=*3GiT2eKN=*_|_!|exxiQFo0jo4$gpdpq()1ZhjjFz>_lJj9vo~@W zX&oajX1{h^bbsg%0PlI+vHD=~I-kn(t z1Hc2N%&LUJ+_X;PgI_4FacVqx<~GL*TUf$PmJbo5omMUjQ+H$N@xd231?Eqds~t&C zX~JANb3n(4Dw>`<-~*n$jIS0S}M09_}|ZJJAik`p)OG<5Ye& zqo{_>r<)1IaQKjBL>XRBw_{{@P$=Lr`WhY=No%9Mhp9hlGz z-@rm5#p()1EWhHz`3u#{UehYoLOj;5Z!`&?kfB$2Dq7p;5O+jMSyq2BId7t~-Nv@D zmN)uoGS6(vjhoO9@#*)9li$7wW=6^TanHnhv8}MY8WE2B_#iTU(B#R^r?o)XqQd-g zysXhR(TF7ei*_AWK7HXBtKgd3V!}D<3G(BCnXhN`ZbOqo>#2+NmErrwF51FwFJ}2r zBMpWsZq$|T*0+A}Y3S;ferJ6CbbcEATw6cYBQUSI;M^p$+C UrKTU<{! Date: Sat, 2 May 2020 13:59:17 +0200 Subject: [PATCH 02/15] Fixed GET method 400 response --- packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts | 6 +++--- .../nodes-base/nodes/AgileCrm/GenericFunctions.ts | 13 ++++++++----- packages/nodes-base/package.json | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts index 84be0ddcfc..4d493bffbd 100644 --- a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts +++ b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts @@ -76,7 +76,7 @@ export class AgileCrm implements INodeType { const contactId = this.getNodeParameter('contactId', i) as string; const endpoint = `api/contacts/${contactId}`; - responseData = await agileCrmApiRequest.call(this, 'GET', endpoint); + responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); } @@ -85,11 +85,11 @@ export class AgileCrm implements INodeType { if (returnAll) { const endpoint = `api/contacts`; - responseData = await agileCrmApiRequest.call(this, 'GET', endpoint); + responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); } else { const limit = this.getNodeParameter('limit', i) as number; const endpoint = `api/contacts?page_size=${limit}`; - responseData = await agileCrmApiRequest.call(this, 'GET', endpoint); + responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); } } diff --git a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts index d363443b50..cabcf2c322 100644 --- a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts +++ b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts @@ -14,17 +14,14 @@ import { } from 'n8n-workflow'; -export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: any = {}, query: IDataObject = {}, uri?: string): Promise { +export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: object, query: IDataObject = {}, uri?: string): Promise { - const node = this.getNodeParameter('credentials', 1); const credentials = this.getCredentials('agileCrmApi'); - const options: OptionsWithUri = { method, headers: { 'Accept': 'application/json', }, - body: body! || {}, auth: { username: credentials!.email as string, password: credentials!.apiKey as string @@ -32,8 +29,14 @@ export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunction uri: uri || `https://n8nio.agilecrm.com/dev/${endpoint}`, json: true }; - + // Only add Body property if method not GET to avoid 400 response + if(method !== "GET"){ + options.body = body; + } + + console.log(options); + try { return await this.helpers.request!(options); } catch (error) { diff --git a/packages/nodes-base/package.json b/packages/nodes-base/package.json index d147d860d0..6b8b9c9713 100644 --- a/packages/nodes-base/package.json +++ b/packages/nodes-base/package.json @@ -27,7 +27,7 @@ "n8n": { "credentials": [ "dist/credentials/ActiveCampaignApi.credentials.js", - "dist/credentials/AgileCrm.credentials.js", + "dist/credentials/AgileCrmApi.credentials.js", "dist/credentials/AcuitySchedulingApi.credentials.js", "dist/credentials/AirtableApi.credentials.js", "dist/credentials/Amqp.credentials.js", From 93efb17c10d393061bc78b6920543f51492d6497 Mon Sep 17 00:00:00 2001 From: Rupenieks Date: Sat, 2 May 2020 20:06:49 +0200 Subject: [PATCH 03/15] Simplified field insertion for users, added all create contact functionality --- .../nodes/AgileCrm/AgileCrm.node.ts | 88 +++- .../nodes/AgileCrm/ContactDescription.ts | 391 +++++++++++------- .../nodes/AgileCrm/GenericFunctions.ts | 4 +- 3 files changed, 326 insertions(+), 157 deletions(-) diff --git a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts index 4d493bffbd..ba44bfdb41 100644 --- a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts +++ b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts @@ -96,6 +96,7 @@ export class AgileCrm implements INodeType { if(operation === 'create'){ const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; const body: IContact = {}; + let properties : IDataObject[] = []; if (jsonParameters) { const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; @@ -124,12 +125,93 @@ export class AgileCrm implements INodeType { if (additionalFields.tags) { body.tags = additionalFields.tags as string[]; } - if (additionalFields.properties) { - body.properties = (additionalFields.properties as IDataObject).property as IDataObject[]; + if(additionalFields.firstName){ + properties.push({ + type: 'SYSTEM', + name: 'first_name', + value: additionalFields.firstName as string + } as IDataObject); } + if(additionalFields.lastName){ + properties.push({ + type: 'SYSTEM', + name: 'last_name', + value: additionalFields.lastName as string + } as IDataObject); + } + if(additionalFields.company){ + properties.push({ + type: 'SYSTEM', + name: 'company', + value: additionalFields.company as string + } as IDataObject); + } + if(additionalFields.title){ + properties.push({ + type: 'SYSTEM', + name: 'title', + value: additionalFields.title as string + } as IDataObject); + } + if(additionalFields.emailOptions){ + //@ts-ignore + additionalFields.emailOptions.emailProperties.map(property => { + properties.push({ + type: 'SYSTEM', + subtype: property.subtype as string, + name: 'email', + value: property.email as string + } as IDataObject); + }) + } + if(additionalFields.addressOptions){ + //@ts-ignore + additionalFields.addressOptions.addressProperties.map(property => { + properties.push({ + type: 'SYSTEM', + subtype: property.subtype as string, + name: 'address', + value: property.address as string + } as IDataObject); + }) + } + if(additionalFields.websiteOptions){ + //@ts-ignore + additionalFields.websiteOptions.websiteProperties.map(property => { + properties.push({ + type: 'SYSTEM', + subtype: property.subtype as string, + name: 'webiste', + value: property.url as string + } as IDataObject); + }) + } + if(additionalFields.phoneOptions){ + //@ts-ignore + additionalFields.phoneOptions.phoneProperties.map(property => { + properties.push({ + type: 'SYSTEM', + subtype: property.subtype as string, + name: 'phone', + value: property.number as string + } as IDataObject); + }) + } + if(additionalFields.customProperties){ + //@ts-ignore + additionalFields.customProperties.customProperty.map(property => { + properties.push({ + type: 'CUSTOM', + subtype: property.subtype as string, + name: property.name, + value: property.value as string + } as IDataObject); + }) + } + body.properties = properties; + } const endpoint = 'api/contacts'; - console.log(body); responseData = await agileCrmApiRequest.call(this, 'POST', endpoint, body); } diff --git a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts index b660cff6b2..67f659301e 100644 --- a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts @@ -223,174 +223,162 @@ export const contactFields = [ description: 'Unique identifiers added to contact, for easy management of contacts. This is not applicable for companies.', }, { - displayName: 'Properties', - name: 'properties', + displayName: 'First Name', + name: 'firstName', + type: 'string', + required: false, + default: "", + placeholder: 'First Name', + description: 'Contact first name.', + }, + { + displayName: 'Last Name', + name: 'lastName', + type: 'string', + required: false, + default: "", + placeholder: 'Last Name', + description: 'Contact last name.', + }, + { + displayName: 'Company', + name: 'company', + type: 'string', + required: false, + default: "", + placeholder: 'Company', + description: 'Company Name.', + }, + { + displayName: 'Title', + name: 'title', + type: 'string', + required: false, + default: "", + placeholder: 'Title', + description: 'Professional title.', + }, + { + displayName: 'Email', + name: 'emailOptions', type: 'fixedCollection', - default: {}, - description: 'Contact properties are represented by list of JSON objects, each JSON object should follow the prototype shown. Custom fields will have type as CUSTOM and others will have type as SYSTEM.', - required: true, + required: false, + description: 'Contact email.', typeOptions: { multipleValues: true, }, options: [ { - displayName: 'Property', - name: 'property', + displayName: 'Email Properties', + name: 'emailProperties', values: [ { displayName: 'Type', - name: 'type', + name: 'subtype', type: 'options', - default: 'SYSTEM', required: true, - description: 'Type of the field.', - options: [ - { - name: 'SYSTEM', - value: 'SYSTEM', - }, - { - name: 'CUSTOM', - value: 'CUSTOM' - } - ] - }, - { - displayName: 'Name', - name: 'name', - type: 'string', - default: '', - required: true, - description: 'Name of the field.' - }, - { - displayName: 'Sub Type', - name: 'subType', - default: '', - required: false, - type: 'options', - description: 'Name of the field.', - displayOptions: { - show: { - type: [ - 'SYSTEM' - ], - name: [ - 'email' - ] - } - }, + default: "", + placeholder: '', + description: 'Type of Email', options: [ { name: 'Work', - value: 'work', - + value: 'work' }, { name: 'Personal', - value: 'personal', - + value: 'personal' } ] }, { - displayName: 'Sub Type', - name: 'subType', - default: '', - required: false, - type: 'options', - description: 'Name of the field.', - displayOptions: { - show: { - type: [ - 'SYSTEM' - ], - name: [ - 'phone' - ] - } - }, - options: [ - { - name: 'Work', - value: 'work', - - }, - { - name: 'Home', - value: 'home', - }, - { - name: 'Mobile', - value: 'mobile', - }, - { - name: 'Main', - value: 'main', - }, - { - name: 'Home Fax', - value: 'homeFax', - }, - { - name: 'Work Fax', - value: 'workFax', - }, - { - name: 'Other', - value: 'other', - }, - ] - }, + displayName: 'Email', + name: 'email', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Email', + } + ] + }, + + ] + }, + { + displayName: 'Address', + name: 'addressOptions', + type: 'fixedCollection', + required: false, + description: 'Contacts address.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Address Properties', + name: 'addressProperties', + values: [ { - displayName: 'Sub Type', - name: 'subType', - default: '', - required: false, + displayName: 'Type', + name: 'subtype', type: 'options', - description: 'Name of the field.', - displayOptions: { - show: { - type: [ - 'SYSTEM' - ], - name: [ - 'address' - ] - } - }, + required: true, + default: "", + placeholder: '', + description: 'Type of address.', options: [ { name: 'Home', - value: 'home', + value: 'home' }, { name: 'Postal', - value: 'postal', - }, + value: 'postal' + } + , { name: 'Office', - value: 'office', - }, + value: 'office' + } ] }, { - displayName: 'Sub Type', - name: 'subType', - default: '', - required: false, + displayName: 'Address', + name: 'address', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Full address.', + } + ] + }, + + ] + }, + { + displayName: 'Website', + name: 'websiteOptions', + type: 'fixedCollection', + required: false, + description: 'Contacts websites.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Website properties.', + name: 'websiteProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', type: 'options', - description: 'Name of the field.', - displayOptions: { - show: { - type: [ - 'SYSTEM' - ], - name: [ - 'website' - ] - } - }, + required: true, + default: "", + placeholder: '', + description: 'Type of website.', options: [ { name: 'URL', @@ -439,34 +427,135 @@ export const contactFields = [ ] }, { - displayName: 'Sub Type', - name: 'subType', - default: '', - required: false, + displayName: 'URL', + name: 'url', type: 'string', - description: 'Name of the field.', - displayOptions: { - show: { - type: [ - 'CUSTOM' - ], + required: true, + default: "", + placeholder: '', + description: 'Website URL', + } + ] + }, + + ] + }, + { + displayName: 'Phone', + name: 'phoneOptions', + type: 'fixedCollection', + required: false, + description: 'Contacts phone.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Phone properties', + name: 'phoneProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: "", + placeholder: '', + description: 'Type of phone number.', + options: [ + { + name: 'Home', + value: 'home' + }, + { + name: 'Work', + value: 'work' } - } + , + { + name: 'Mobile', + value: 'mobile' + }, + { + name: 'Main', + value: 'main' + }, + { + name: 'Home Fax', + value: 'homeFax' + }, + { + name: 'Work Fax', + value: 'workFax' + }, + { + name: 'Other', + value: 'other' + }, + ] + }, + { + displayName: 'Number', + name: 'number', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Phone number.', + } + ] + }, + + ] + }, + { + displayName: 'Custom Properties', + name: 'customProperties', + type: 'fixedCollection', + required: false, + description: 'Custom Properties', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Property', + name: 'customProperty', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Property name.' + }, + { + displayName: 'Sub Type', + name: 'subtype', + type: 'string', + required: false, + default: "", + placeholder: '', + description: 'Property sub type.', }, { displayName: 'Value', name: 'value', - default: '', - required: false, type: 'string', - description: 'Value of the property.' - }, + required: false, + default: "", + placeholder: '', + description: 'Property value.', + } ] - } - + }, + ] - }, + + ], }, diff --git a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts index cabcf2c322..5fe49fd1df 100644 --- a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts +++ b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts @@ -14,7 +14,7 @@ import { } from 'n8n-workflow'; -export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: object, query: IDataObject = {}, uri?: string): Promise { +export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: any = {}, query: IDataObject = {}, uri?: string): Promise { const credentials = this.getCredentials('agileCrmApi'); const options: OptionsWithUri = { @@ -34,8 +34,6 @@ export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunction if(method !== "GET"){ options.body = body; } - - console.log(options); try { return await this.helpers.request!(options); From dce70ad5c7221dbf89969d2743a2408535a500c9 Mon Sep 17 00:00:00 2001 From: Rupenieks Date: Sat, 2 May 2020 20:12:11 +0200 Subject: [PATCH 04/15] GetAll Limit default value --- packages/nodes-base/nodes/AgileCrm/ContactDescription.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts index 67f659301e..8a9fc3801a 100644 --- a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts @@ -84,6 +84,7 @@ export const contactFields = [ displayName: 'Limit', name: 'limit', type: 'number', + default: 20, displayOptions: { show: { resource: [ From e17df72dc6fa37b4256abb80f07ffbddf81b3cbb Mon Sep 17 00:00:00 2001 From: Rupenieks Date: Mon, 4 May 2020 15:14:22 +0200 Subject: [PATCH 05/15] Contact Delete --- .../nodes/AgileCrm/AgileCrm.node.ts | 8 +++++ .../nodes/AgileCrm/ContactDescription.ts | 33 +++++++++++++++++-- .../nodes/AgileCrm/GenericFunctions.ts | 4 +-- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts index ba44bfdb41..01ee92de03 100644 --- a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts +++ b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts @@ -80,6 +80,14 @@ export class AgileCrm implements INodeType { } + if(operation === 'delete'){ + const contactId = this.getNodeParameter('contactId', i) as string; + + const endpoint = `api/contacts/${contactId}`; + responseData = await agileCrmApiRequest.call(this, 'DELETE', endpoint, {}); + + } + if(operation === 'getAll'){ const returnAll = this.getNodeParameter('returnAll', i) as boolean; diff --git a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts index 8a9fc3801a..c9414f5fa8 100644 --- a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts @@ -30,6 +30,16 @@ export const contactOperations = [ value: 'create', description: 'Create a new contact', }, + { + name: 'Update', + value: 'update', + description: 'Update contact properties', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a contact', + }, ], default: 'get', description: 'The operation to perform.', @@ -555,9 +565,28 @@ export const contactFields = [ ] }, - - ], }, +/* -------------------------------------------------------------------------- */ +/* contact:delete */ +/* -------------------------------------------------------------------------- */ +{ + displayName: 'Contact ID', + name: 'contactId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'delete', + ], + }, + }, + default: '', + description: 'Unique identifier for a particular contact', +}, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts index 5fe49fd1df..b87fedd024 100644 --- a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts +++ b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts @@ -30,8 +30,8 @@ export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunction json: true }; - // Only add Body property if method not GET to avoid 400 response - if(method !== "GET"){ + // Only add Body property if method not GET or DELETE to avoid 400 response + if(method !== "GET" && method !== "DELETE"){ options.body = body; } From a5821bdd1414398c62cf65ef0d4c7f9d55a72a99 Mon Sep 17 00:00:00 2001 From: Rupenieks Date: Tue, 5 May 2020 11:08:30 +0200 Subject: [PATCH 06/15] Contact update --- .../nodes/AgileCrm/AgileCrm.node.ts | 131 ++++- .../nodes/AgileCrm/ContactDescription.ts | 473 ++++++++++++++++++ .../nodes/AgileCrm/ContactInterface.ts | 8 + .../nodes/AgileCrm/GenericFunctions.ts | 81 +++ 4 files changed, 691 insertions(+), 2 deletions(-) diff --git a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts index 01ee92de03..4fecdcd94d 100644 --- a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts +++ b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts @@ -10,8 +10,8 @@ import { contactOperations, contactFields } from './ContactDescription'; -import { agileCrmApiRequest, validateJSON} from './GenericFunctions'; -import { IContact, IProperty } from './ContactInterface'; +import { agileCrmApiRequest, validateJSON, agileCrmApiRequestUpdate} from './GenericFunctions'; +import { IContact, IProperty, IContactUpdate } from './ContactInterface'; export class AgileCrm implements INodeType { @@ -223,6 +223,133 @@ export class AgileCrm implements INodeType { responseData = await agileCrmApiRequest.call(this, 'POST', endpoint, body); } + if(operation === "update") { + const contactId = this.getNodeParameter('contactId', i) as string; + let contactUpdatePayload : IContactUpdate = {id: contactId}; + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + const body: IContact = {}; + let properties : IDataObject[] = []; + + if (jsonParameters) { + const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; + + if (additionalFieldsJson !== '' ) { + + if (validateJSON(additionalFieldsJson) !== undefined) { + + Object.assign(body, JSON.parse(additionalFieldsJson)); + + } else { + throw new Error('Additional fields must be a valid JSON'); + } + } + } else { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + if (additionalFields.starValue) { + body.star_value = additionalFields.starValue as string; + } + if (additionalFields.leadScore) { + body.lead_score = additionalFields.leadScore as string; + } + if (additionalFields.tags) { + body.tags = additionalFields.tags as string[]; + } + if(additionalFields.firstName){ + properties.push({ + type: 'SYSTEM', + name: 'first_name', + value: additionalFields.firstName as string + } as IDataObject); + } + if(additionalFields.lastName){ + properties.push({ + type: 'SYSTEM', + name: 'last_name', + value: additionalFields.lastName as string + } as IDataObject); + } + if(additionalFields.company){ + properties.push({ + type: 'SYSTEM', + name: 'company', + value: additionalFields.company as string + } as IDataObject); + } + if(additionalFields.title){ + properties.push({ + type: 'SYSTEM', + name: 'title', + value: additionalFields.title as string + } as IDataObject); + } + if(additionalFields.emailOptions){ + //@ts-ignore + additionalFields.emailOptions.emailProperties.map(property => { + properties.push({ + type: 'SYSTEM', + subtype: property.subtype as string, + name: 'email', + value: property.email as string + } as IDataObject); + }) + } + if(additionalFields.addressOptions){ + //@ts-ignore + additionalFields.addressOptions.addressProperties.map(property => { + properties.push({ + type: 'SYSTEM', + subtype: property.subtype as string, + name: 'address', + value: property.address as string + } as IDataObject); + }) + } + if(additionalFields.websiteOptions){ + //@ts-ignore + additionalFields.websiteOptions.websiteProperties.map(property => { + properties.push({ + type: 'SYSTEM', + subtype: property.subtype as string, + name: 'webiste', + value: property.url as string + } as IDataObject); + }) + } + if(additionalFields.phoneOptions){ + //@ts-ignore + additionalFields.phoneOptions.phoneProperties.map(property => { + properties.push({ + type: 'SYSTEM', + subtype: property.subtype as string, + name: 'phone', + value: property.number as string + } as IDataObject); + }) + } + if(additionalFields.customProperties){ + //@ts-ignore + additionalFields.customProperties.customProperty.map(property => { + properties.push({ + type: 'CUSTOM', + subtype: property.subtype as string, + name: property.name, + value: property.value as string + } as IDataObject); + }) + } + body.properties = properties; + + + + } + + Object.assign(contactUpdatePayload, body); + + responseData = await agileCrmApiRequestUpdate.call(this, 'PUT', '', contactUpdatePayload); + + } + if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]); } else { diff --git a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts index c9414f5fa8..e37dc65e38 100644 --- a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts @@ -588,5 +588,478 @@ export const contactFields = [ default: '', description: 'Unique identifier for a particular contact', }, +/* -------------------------------------------------------------------------- */ +/* contact:update */ +/* -------------------------------------------------------------------------- */ +{ + displayName: 'Contact ID', + name: 'contactId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'update', + ], + }, + }, + default: '', + description: 'Unique identifier for a particular contact', +}, +{ + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'update', + ], + }, + }, +}, +{ + displayName: ' Additional Fields', + name: 'additionalFieldsJson', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'update', + ], + jsonParameters: [ + true, + ], + }, + }, + + description: `Object of values to set as described here.`, +}, +{ + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'update', + ], + jsonParameters: [ + false, + ], + }, + }, + options: [ + { + displayName: 'Star Value', + name: 'starValue', + type: 'options', + default: '', + required: false, + description: 'Rating of contact (Max value 5). This is not applicable for companies.', + options: [ + { + name: '0', + value: 0 + }, + { + name: '1', + value: 1 + }, + { + name: '2', + value: 2 + }, + { + name: '3', + value: 3 + }, + { + name: '4', + value: 4 + }, + { + name: '5', + value: 5 + }, + ] + }, + { + displayName: 'Lead Score', + name: 'leadScore', + type: 'number', + default: '', + description: 'Score of contact. This is not applicable for companies.', + required: false, + typeOptions: { + minValue: 0 + } + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + typeOptions: { + multipleValues: true, + multipleValueButtonText: 'Add Tag', + }, + default: [], + placeholder: 'Tag', + description: 'Unique identifiers added to contact, for easy management of contacts. This is not applicable for companies.', + }, + { + displayName: 'First Name', + name: 'firstName', + type: 'string', + required: false, + default: "", + placeholder: 'First Name', + description: 'Contact first name.', + }, + { + displayName: 'Last Name', + name: 'lastName', + type: 'string', + required: false, + default: "", + placeholder: 'Last Name', + description: 'Contact last name.', + }, + { + displayName: 'Company', + name: 'company', + type: 'string', + required: false, + default: "", + placeholder: 'Company', + description: 'Company Name.', + }, + { + displayName: 'Title', + name: 'title', + type: 'string', + required: false, + default: "", + placeholder: 'Title', + description: 'Professional title.', + }, + { + displayName: 'Email', + name: 'emailOptions', + type: 'fixedCollection', + required: false, + description: 'Contact email.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Email Properties', + name: 'emailProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: "", + placeholder: '', + description: 'Type of Email', + options: [ + { + name: 'Work', + value: 'work' + }, + { + name: 'Personal', + value: 'personal' + } + ] + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Email', + } + ] + }, + + ] + }, + { + displayName: 'Address', + name: 'addressOptions', + type: 'fixedCollection', + required: false, + description: 'Contacts address.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Address Properties', + name: 'addressProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: "", + placeholder: '', + description: 'Type of address.', + options: [ + { + name: 'Home', + value: 'home' + }, + { + name: 'Postal', + value: 'postal' + } + , + { + name: 'Office', + value: 'office' + } + ] + }, + { + displayName: 'Address', + name: 'address', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Full address.', + } + ] + }, + + ] + }, + { + displayName: 'Website', + name: 'websiteOptions', + type: 'fixedCollection', + required: false, + description: 'Contacts websites.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Website properties.', + name: 'websiteProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: "", + placeholder: '', + description: 'Type of website.', + options: [ + { + name: 'URL', + value: 'url', + }, + { + name: 'SKYPE', + value: 'skype', + }, + { + name: 'TWITTER', + value: 'twitter', + }, + { + name: 'LINKEDIN', + value: 'linkedin', + }, + { + name: 'FACEBOOK', + value: 'facebook', + }, + { + name: 'XING', + value: 'xing', + }, + { + name: 'FEED', + value: 'feed', + }, + { + name: 'GOOGLE_PLUS', + value: 'googlePlus', + }, + { + name: 'FLICKR', + value: 'flickr', + }, + { + name: 'GITHUB', + value: 'github', + }, + { + name: 'YOUTUBE', + value: 'youtube', + }, + ] + }, + { + displayName: 'URL', + name: 'url', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Website URL', + } + ] + }, + + ] + }, + { + displayName: 'Phone', + name: 'phoneOptions', + type: 'fixedCollection', + required: false, + description: 'Contacts phone.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Phone properties', + name: 'phoneProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: "", + placeholder: '', + description: 'Type of phone number.', + options: [ + { + name: 'Home', + value: 'home' + }, + { + name: 'Work', + value: 'work' + } + , + { + name: 'Mobile', + value: 'mobile' + }, + { + name: 'Main', + value: 'main' + }, + { + name: 'Home Fax', + value: 'homeFax' + }, + { + name: 'Work Fax', + value: 'workFax' + }, + { + name: 'Other', + value: 'other' + }, + ] + }, + { + displayName: 'Number', + name: 'number', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Phone number.', + } + ] + }, + + ] + }, + { + displayName: 'Custom Properties', + name: 'customProperties', + type: 'fixedCollection', + required: false, + description: 'Custom Properties', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Property', + name: 'customProperty', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Property name.' + }, + { + displayName: 'Sub Type', + name: 'subtype', + type: 'string', + required: false, + default: "", + placeholder: '', + description: 'Property sub type.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + required: false, + default: "", + placeholder: '', + description: 'Property value.', + } + ] + }, + + ] + }, + ], +}, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts b/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts index 661a4c4742..ae384df943 100644 --- a/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts +++ b/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts @@ -16,3 +16,11 @@ import { properties?: IDataObject[]; } + export interface IContactUpdate { + id: string, + properties?: IDataObject[], + star_value?: string; + lead_score?: string; + tags?: string[]; + } + diff --git a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts index b87fedd024..046b7c187a 100644 --- a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts +++ b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts @@ -12,6 +12,7 @@ import { import { IDataObject, } from 'n8n-workflow'; +import { IContactUpdate } from './ContactInterface'; export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: any = {}, query: IDataObject = {}, uri?: string): Promise { @@ -46,6 +47,86 @@ export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunction throw error; } + +} + +export async function agileCrmApiRequestUpdate(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string = 'PUT', endpoint?: string, body: any = {}, query: IDataObject = {}, uri?: string): Promise { + const baseUri = 'https://n8nio.agilecrm.com/dev/'; + const credentials = this.getCredentials('agileCrmApi'); + const options: OptionsWithUri = { + method, + headers: { + 'Accept': 'application/json', + }, + body: {id: body.id}, + auth: { + username: credentials!.email as string, + password: credentials!.apiKey as string + }, + uri: uri || baseUri, + json: true + }; + + let successfulUpdates = []; + let lastSuccesfulUpdateReturn : any; + let payload : IContactUpdate = body; + + try { + // Due to API, we must update each property separately + if(payload.properties){ + options.body.properties = payload.properties; + options.uri = baseUri + 'api/contacts/edit-properties'; + lastSuccesfulUpdateReturn = await this.helpers.request!(options); + + // Iterate trough properties and show them as individial updates instead of only vague "properties" + payload.properties?.map((property : any) => { + successfulUpdates.push(`${property.name} `); + }) + + delete options.body.properties; + } + if(payload.lead_score){ + options.body.lead_score = payload.lead_score; + options.uri = baseUri + 'api/contacts/edit/lead-score'; + lastSuccesfulUpdateReturn = await this.helpers.request!(options); + + successfulUpdates.push('lead_score'); + + delete options.body.lead_score; + } + if(body.tags){ + options.body.tags = payload.tags; + options.uri = baseUri + 'api/contacts/edit/tagaas'; + lastSuccesfulUpdateReturn = await this.helpers.request!(options); + + payload.tags?.map((tag : string) => { + successfulUpdates.push(`(Tag) ${tag} `); + }) + + delete options.body.tags; + } + if(body.star_value){ + options.body.star_value = payload.star_value; + options.uri = baseUri + 'api/contacts/edit/add-star'; + lastSuccesfulUpdateReturn = await this.helpers.request!(options); + + successfulUpdates.push('star_value'); + + delete options.body.star_value; + } + + return lastSuccesfulUpdateReturn; + + } catch (error) { + + if (error.response && error.response.body && error.response.body.errors) { + const errorMessages = error.response.body.errors.map((e: IDataObject) => e.message); + throw new Error(`AgileCRM error response [${error.statusCode}]: ${errorMessages.join(' | ')}`); + } + + throw new Error(`Not all items updated. Updated items: ${successfulUpdates.join(' , ')} \n \n` + error); + } + } export function validateJSON(json: string | undefined): any { // tslint:disable-line:no-any From 3d11b52c630e4dafe7220ffc52e9417eab4bf46a Mon Sep 17 00:00:00 2001 From: Rupenieks Date: Tue, 5 May 2020 11:10:27 +0200 Subject: [PATCH 07/15] Removed intentional fail url --- packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts index 046b7c187a..eb7497f2fa 100644 --- a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts +++ b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts @@ -96,7 +96,7 @@ export async function agileCrmApiRequestUpdate(this: IHookFunctions | IExecuteFu } if(body.tags){ options.body.tags = payload.tags; - options.uri = baseUri + 'api/contacts/edit/tagaas'; + options.uri = baseUri + 'api/contacts/edit/tags'; lastSuccesfulUpdateReturn = await this.helpers.request!(options); payload.tags?.map((tag : string) => { From 5ecefd777df7324a529a6f1f44d88f465d3ce867 Mon Sep 17 00:00:00 2001 From: Rupenieks Date: Tue, 5 May 2020 13:59:45 +0200 Subject: [PATCH 08/15] Company get / getAll / create / update --- .../nodes/AgileCrm/AgileCrm.node.ts | 331 +++++--- .../nodes/AgileCrm/CompanyDescription.ts | 732 ++++++++++++++++++ .../nodes/AgileCrm/ContactDescription.ts | 2 +- .../nodes/AgileCrm/ContactInterface.ts | 1 + 4 files changed, 945 insertions(+), 121 deletions(-) create mode 100644 packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts diff --git a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts index 4fecdcd94d..c1417a8e07 100644 --- a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts +++ b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts @@ -10,6 +10,12 @@ import { contactOperations, contactFields } from './ContactDescription'; + +import { + companyOperations, + companyFields +} from './CompanyDescription'; + import { agileCrmApiRequest, validateJSON, agileCrmApiRequestUpdate} from './GenericFunctions'; import { IContact, IProperty, IContactUpdate } from './ContactInterface'; @@ -45,7 +51,11 @@ export class AgileCrm implements INodeType { { name: 'Contact', value: 'contact' - } + }, + { + name: 'Company', + value: 'company' + }, ], default: 'contact', description: 'Resource to consume.', @@ -53,6 +63,10 @@ export class AgileCrm implements INodeType { // CONTACT ...contactOperations, ...contactFields, + + // COMPANY + ...companyOperations, + ...companyFields ], }; @@ -70,10 +84,11 @@ export class AgileCrm implements INodeType { for (let i = 0; i < length; i++) { - if(resource === 'contact'){ + if(resource === 'contact' || resource === 'company'){ + let idGetter = resource === 'contact' ? 'contactId' : 'companyId'; if(operation === 'get'){ - const contactId = this.getNodeParameter('contactId', i) as string; + const contactId = this.getNodeParameter(idGetter, i) as string; const endpoint = `api/contacts/${contactId}`; responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); @@ -81,7 +96,7 @@ export class AgileCrm implements INodeType { } if(operation === 'delete'){ - const contactId = this.getNodeParameter('contactId', i) as string; + const contactId = this.getNodeParameter(idGetter, i) as string; const endpoint = `api/contacts/${contactId}`; responseData = await agileCrmApiRequest.call(this, 'DELETE', endpoint, {}); @@ -91,14 +106,26 @@ export class AgileCrm implements INodeType { if(operation === 'getAll'){ const returnAll = this.getNodeParameter('returnAll', i) as boolean; - if (returnAll) { - const endpoint = `api/contacts`; - responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); + if(resource === 'contact'){ + if (returnAll) { + const endpoint = `api/contacts`; + responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); + } else { + const limit = this.getNodeParameter('limit', i) as number; + const endpoint = `api/contacts?page_size=${limit}`; + responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); + } } else { - const limit = this.getNodeParameter('limit', i) as number; - const endpoint = `api/contacts?page_size=${limit}`; - responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); + if (returnAll) { + const endpoint = `api/contacts/companies/list`; + responseData = await agileCrmApiRequest.call(this, 'POST', endpoint, {}); + } else { + const limit = this.getNodeParameter('limit', i) as number; + const endpoint = `api/contacts/companies/list?page_size=${limit}`; + responseData = await agileCrmApiRequest.call(this, 'POST', endpoint, {}); + } } + } if(operation === 'create'){ @@ -124,6 +151,10 @@ export class AgileCrm implements INodeType { const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + // if company, add 'company' as type. default is person + if(resource === 'company'){ + body.type = 'COMPANY'; + } if (additionalFields.starValue) { body.star_value = additionalFields.starValue as string; } @@ -133,56 +164,98 @@ export class AgileCrm implements INodeType { if (additionalFields.tags) { body.tags = additionalFields.tags as string[]; } - if(additionalFields.firstName){ - properties.push({ - type: 'SYSTEM', - name: 'first_name', - value: additionalFields.firstName as string - } as IDataObject); - } - if(additionalFields.lastName){ - properties.push({ - type: 'SYSTEM', - name: 'last_name', - value: additionalFields.lastName as string - } as IDataObject); - } - if(additionalFields.company){ - properties.push({ - type: 'SYSTEM', - name: 'company', - value: additionalFields.company as string - } as IDataObject); - } - if(additionalFields.title){ - properties.push({ - type: 'SYSTEM', - name: 'title', - value: additionalFields.title as string - } as IDataObject); - } - if(additionalFields.emailOptions){ - //@ts-ignore - additionalFields.emailOptions.emailProperties.map(property => { + + // Contact specific properties + if(resource === 'contact'){ + if(additionalFields.firstName){ + properties.push({ + type: 'SYSTEM', + name: 'first_name', + value: additionalFields.firstName as string + } as IDataObject); + } + if(additionalFields.lastName){ + properties.push({ + type: 'SYSTEM', + name: 'last_name', + value: additionalFields.lastName as string + } as IDataObject); + } + if(additionalFields.company){ + properties.push({ + type: 'SYSTEM', + name: 'company', + value: additionalFields.company as string + } as IDataObject); + } + if(additionalFields.title){ + properties.push({ + type: 'SYSTEM', + name: 'title', + value: additionalFields.title as string + } as IDataObject); + } + if(additionalFields.emailOptions){ + //@ts-ignore + additionalFields.emailOptions.emailProperties.map(property => { + properties.push({ + type: 'SYSTEM', + subtype: property.subtype as string, + name: 'email', + value: property.email as string + } as IDataObject); + }) + } + if(additionalFields.addressOptions){ + //@ts-ignore + additionalFields.addressOptions.addressProperties.map(property => { + properties.push({ + type: 'SYSTEM', + subtype: property.subtype as string, + name: 'address', + value: property.address as string + } as IDataObject); + }) + } + + if(additionalFields.phoneOptions){ + //@ts-ignore + additionalFields.phoneOptions.phoneProperties.map(property => { + properties.push({ + type: 'SYSTEM', + subtype: property.subtype as string, + name: 'phone', + value: property.number as string + } as IDataObject); + }) + } + } else if (resource === 'company') { + if(additionalFields.email){ properties.push({ type: 'SYSTEM', - subtype: property.subtype as string, name: 'email', - value: property.email as string + value: additionalFields.email as string } as IDataObject); - }) - } - if(additionalFields.addressOptions){ - //@ts-ignore - additionalFields.addressOptions.addressProperties.map(property => { + } + + if(additionalFields.address){ properties.push({ type: 'SYSTEM', - subtype: property.subtype as string, name: 'address', - value: property.address as string + value: additionalFields.address as string } as IDataObject); - }) + } + + if(additionalFields.phone){ + properties.push({ + type: 'SYSTEM', + name: 'phone', + value: additionalFields.phone as string + } as IDataObject); + } + } + if(additionalFields.websiteOptions){ //@ts-ignore additionalFields.websiteOptions.websiteProperties.map(property => { @@ -194,17 +267,7 @@ export class AgileCrm implements INodeType { } as IDataObject); }) } - if(additionalFields.phoneOptions){ - //@ts-ignore - additionalFields.phoneOptions.phoneProperties.map(property => { - properties.push({ - type: 'SYSTEM', - subtype: property.subtype as string, - name: 'phone', - value: property.number as string - } as IDataObject); - }) - } + if(additionalFields.customProperties){ //@ts-ignore additionalFields.customProperties.customProperty.map(property => { @@ -223,8 +286,8 @@ export class AgileCrm implements INodeType { responseData = await agileCrmApiRequest.call(this, 'POST', endpoint, body); } - if(operation === "update") { - const contactId = this.getNodeParameter('contactId', i) as string; + if(operation === 'update') { + const contactId = this.getNodeParameter(idGetter, i) as string; let contactUpdatePayload : IContactUpdate = {id: contactId}; const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; const body: IContact = {}; @@ -255,56 +318,98 @@ export class AgileCrm implements INodeType { if (additionalFields.tags) { body.tags = additionalFields.tags as string[]; } - if(additionalFields.firstName){ - properties.push({ - type: 'SYSTEM', - name: 'first_name', - value: additionalFields.firstName as string - } as IDataObject); - } - if(additionalFields.lastName){ - properties.push({ - type: 'SYSTEM', - name: 'last_name', - value: additionalFields.lastName as string - } as IDataObject); - } - if(additionalFields.company){ - properties.push({ - type: 'SYSTEM', - name: 'company', - value: additionalFields.company as string - } as IDataObject); - } - if(additionalFields.title){ - properties.push({ - type: 'SYSTEM', - name: 'title', - value: additionalFields.title as string - } as IDataObject); - } - if(additionalFields.emailOptions){ - //@ts-ignore - additionalFields.emailOptions.emailProperties.map(property => { + + // Contact specific properties + if(resource === 'contact'){ + if(additionalFields.firstName){ + properties.push({ + type: 'SYSTEM', + name: 'first_name', + value: additionalFields.firstName as string + } as IDataObject); + } + if(additionalFields.lastName){ + properties.push({ + type: 'SYSTEM', + name: 'last_name', + value: additionalFields.lastName as string + } as IDataObject); + } + if(additionalFields.company){ + properties.push({ + type: 'SYSTEM', + name: 'company', + value: additionalFields.company as string + } as IDataObject); + } + if(additionalFields.title){ + properties.push({ + type: 'SYSTEM', + name: 'title', + value: additionalFields.title as string + } as IDataObject); + } + if(additionalFields.emailOptions){ + //@ts-ignore + additionalFields.emailOptions.emailProperties.map(property => { + properties.push({ + type: 'SYSTEM', + subtype: property.subtype as string, + name: 'email', + value: property.email as string + } as IDataObject); + }) + } + if(additionalFields.addressOptions){ + //@ts-ignore + additionalFields.addressOptions.addressProperties.map(property => { + properties.push({ + type: 'SYSTEM', + subtype: property.subtype as string, + name: 'address', + value: property.address as string + } as IDataObject); + }) + } + + if(additionalFields.phoneOptions){ + //@ts-ignore + additionalFields.phoneOptions.phoneProperties.map(property => { + properties.push({ + type: 'SYSTEM', + subtype: property.subtype as string, + name: 'phone', + value: property.number as string + } as IDataObject); + }) + } + } else if (resource === 'company') { + if(additionalFields.email){ properties.push({ type: 'SYSTEM', - subtype: property.subtype as string, name: 'email', - value: property.email as string + value: additionalFields.email as string } as IDataObject); - }) - } - if(additionalFields.addressOptions){ - //@ts-ignore - additionalFields.addressOptions.addressProperties.map(property => { + } + + if(additionalFields.address){ properties.push({ type: 'SYSTEM', - subtype: property.subtype as string, name: 'address', - value: property.address as string + value: additionalFields.address as string } as IDataObject); - }) + } + + if(additionalFields.phone){ + properties.push({ + type: 'SYSTEM', + name: 'phone', + value: additionalFields.phone as string + } as IDataObject); + } + } + if(additionalFields.websiteOptions){ //@ts-ignore additionalFields.websiteOptions.websiteProperties.map(property => { @@ -316,17 +421,6 @@ export class AgileCrm implements INodeType { } as IDataObject); }) } - if(additionalFields.phoneOptions){ - //@ts-ignore - additionalFields.phoneOptions.phoneProperties.map(property => { - properties.push({ - type: 'SYSTEM', - subtype: property.subtype as string, - name: 'phone', - value: property.number as string - } as IDataObject); - }) - } if(additionalFields.customProperties){ //@ts-ignore additionalFields.customProperties.customProperty.map(property => { @@ -339,9 +433,6 @@ export class AgileCrm implements INodeType { }) } body.properties = properties; - - - } Object.assign(contactUpdatePayload, body); @@ -356,7 +447,7 @@ export class AgileCrm implements INodeType { returnData.push(responseData as IDataObject); } } - + } return [this.helpers.returnJsonArray(returnData)]; diff --git a/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts b/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts new file mode 100644 index 0000000000..56db0f4abc --- /dev/null +++ b/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts @@ -0,0 +1,732 @@ +import { + INodeProperties, + } from 'n8n-workflow'; + +export const companyOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'company', + ], + }, + }, + options: [ + { + name: 'Get', + value: 'get', + description: 'Get a company', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all companies', + }, + { + name: 'Create', + value: 'create', + description: 'Create a new company', + }, + { + name: 'Update', + value: 'update', + description: 'Update company properties', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a company', + }, + ], + default: 'get', + description: 'The operation to perform.', + }, +] as INodeProperties[]; + +export const companyFields = [ +/* -------------------------------------------------------------------------- */ +/* company:get */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'company ID', + name: 'companyId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'get', + ], + }, + }, + default: '', + description: 'Unique identifier for a particular company', + }, + + +/* -------------------------------------------------------------------------- */ +/* company:get all */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'getAll', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + default: 20, + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + } + }, + +/* -------------------------------------------------------------------------- */ +/* company:create */ +/* -------------------------------------------------------------------------- */ + +{ + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'create', + ], + }, + }, +}, +{ + displayName: ' Additional Fields', + name: 'additionalFieldsJson', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'create', + ], + jsonParameters: [ + true, + ], + }, + }, + + description: `Object of values to set as described here.`, +}, + +{ + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'create', + ], + jsonParameters: [ + false, + ], + }, + }, + options: [ + { + displayName: 'Star Value', + name: 'starValue', + type: 'options', + default: '', + required: false, + description: 'Rating of company (Max value 5). This is not applicable for companies.', + options: [ + { + name: '0', + value: 0 + }, + { + name: '1', + value: 1 + }, + { + name: '2', + value: 2 + }, + { + name: '3', + value: 3 + }, + { + name: '4', + value: 4 + }, + { + name: '5', + value: 5 + }, + ] + }, + { + displayName: 'Lead Score', + name: 'leadScore', + type: 'number', + default: '', + description: 'Score of company. This is not applicable for companies.', + required: false, + typeOptions: { + minValue: 0 + } + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + typeOptions: { + multipleValues: true, + multipleValueButtonText: 'Add Tag', + }, + default: [], + placeholder: 'Tag', + description: 'Unique identifiers added to company, for easy management of companys. This is not applicable for companies.', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + required: false, + default: "", + placeholder: 'Company name', + description: 'Company name.', + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + required: false, + default: '', + placeholder: 'Company email', + description: 'Company email.', + }, + { + displayName: 'Address', + name: 'email', + type: 'string', + required: false, + default: '', + placeholder: 'Company address', + description: 'Company address.', + }, + { + displayName: 'Website', + name: 'websiteOptions', + type: 'fixedCollection', + required: false, + description: 'companys websites.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Website properties.', + name: 'websiteProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: "", + placeholder: '', + description: 'Type of website.', + options: [ + { + name: 'URL', + value: 'url', + }, + { + name: 'SKYPE', + value: 'skype', + }, + { + name: 'TWITTER', + value: 'twitter', + }, + { + name: 'LINKEDIN', + value: 'linkedin', + }, + { + name: 'FACEBOOK', + value: 'facebook', + }, + { + name: 'XING', + value: 'xing', + }, + { + name: 'FEED', + value: 'feed', + }, + { + name: 'GOOGLE_PLUS', + value: 'googlePlus', + }, + { + name: 'FLICKR', + value: 'flickr', + }, + { + name: 'GITHUB', + value: 'github', + }, + { + name: 'YOUTUBE', + value: 'youtube', + }, + ] + }, + { + displayName: 'URL', + name: 'url', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Website URL', + } + ] + }, + + ] + }, + { + displayName: 'Phone', + name: 'phone', + type: 'string', + required: false, + default: '', + placeholder: 'Company phone', + description: 'Company phone.', + }, + { + displayName: 'Custom Properties', + name: 'customProperties', + type: 'fixedCollection', + required: false, + description: 'Custom Properties', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Property', + name: 'customProperty', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Property name.' + }, + { + displayName: 'Sub Type', + name: 'subtype', + type: 'string', + required: false, + default: "", + placeholder: '', + description: 'Property sub type.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + required: false, + default: "", + placeholder: '', + description: 'Property value.', + } + ] + }, + + ] + }, + ], +}, +/* -------------------------------------------------------------------------- */ +/* company:delete */ +/* -------------------------------------------------------------------------- */ +{ + displayName: 'company ID', + name: 'companyId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'delete', + ], + }, + }, + default: '', + description: 'Unique identifier for a particular company', +}, +/* -------------------------------------------------------------------------- */ +/* company:update */ +/* -------------------------------------------------------------------------- */ +{ + displayName: 'company ID', + name: 'companyId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'update', + ], + }, + }, + default: '', + description: 'Unique identifier for a particular company', +}, +{ + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'update', + ], + }, + }, +}, +{ + displayName: ' Additional Fields', + name: 'additionalFieldsJson', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'update', + ], + jsonParameters: [ + true, + ], + }, + }, + + description: `Object of values to set as described here.`, +}, + +{ + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'update', + ], + jsonParameters: [ + false, + ], + }, + }, + options: [ + { + displayName: 'Star Value', + name: 'starValue', + type: 'options', + default: '', + required: false, + description: 'Rating of company (Max value 5). This is not applicable for companies.', + options: [ + { + name: '0', + value: 0 + }, + { + name: '1', + value: 1 + }, + { + name: '2', + value: 2 + }, + { + name: '3', + value: 3 + }, + { + name: '4', + value: 4 + }, + { + name: '5', + value: 5 + }, + ] + }, + { + displayName: 'Lead Score', + name: 'leadScore', + type: 'number', + default: '', + description: 'Score of company. This is not applicable for companies.', + required: false, + typeOptions: { + minValue: 0 + } + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + typeOptions: { + multipleValues: true, + multipleValueButtonText: 'Add Tag', + }, + default: [], + placeholder: 'Tag', + description: 'Unique identifiers added to company, for easy management of companys. This is not applicable for companies.', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + required: false, + default: "", + placeholder: 'Company name', + description: 'Company name.', + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + required: false, + default: '', + placeholder: 'Company email', + description: 'Company email.', + }, + { + displayName: 'Address', + name: 'email', + type: 'string', + required: false, + default: '', + placeholder: 'Company address', + description: 'Company address.', + }, + { + displayName: 'Website', + name: 'websiteOptions', + type: 'fixedCollection', + required: false, + description: 'companys websites.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Website properties.', + name: 'websiteProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: "", + placeholder: '', + description: 'Type of website.', + options: [ + { + name: 'URL', + value: 'url', + }, + { + name: 'SKYPE', + value: 'skype', + }, + { + name: 'TWITTER', + value: 'twitter', + }, + { + name: 'LINKEDIN', + value: 'linkedin', + }, + { + name: 'FACEBOOK', + value: 'facebook', + }, + { + name: 'XING', + value: 'xing', + }, + { + name: 'FEED', + value: 'feed', + }, + { + name: 'GOOGLE_PLUS', + value: 'googlePlus', + }, + { + name: 'FLICKR', + value: 'flickr', + }, + { + name: 'GITHUB', + value: 'github', + }, + { + name: 'YOUTUBE', + value: 'youtube', + }, + ] + }, + { + displayName: 'URL', + name: 'url', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Website URL', + } + ] + }, + + ] + }, + { + displayName: 'Phone', + name: 'phone', + type: 'string', + required: false, + default: '', + placeholder: 'Company phone', + description: 'Company phone.', + }, + { + displayName: 'Custom Properties', + name: 'customProperties', + type: 'fixedCollection', + required: false, + description: 'Custom Properties', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Property', + name: 'customProperty', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Property name.' + }, + { + displayName: 'Sub Type', + name: 'subtype', + type: 'string', + required: false, + default: "", + placeholder: '', + description: 'Property sub type.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + required: false, + default: "", + placeholder: '', + description: 'Property value.', + } + ] + }, + + ] + }, + ], +}, + +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts index e37dc65e38..96d0dfd3d0 100644 --- a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts @@ -111,7 +111,7 @@ export const contactFields = [ }, /* -------------------------------------------------------------------------- */ -/* ticket:create */ +/* contact:create */ /* -------------------------------------------------------------------------- */ { diff --git a/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts b/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts index ae384df943..656b95d3ac 100644 --- a/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts +++ b/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts @@ -10,6 +10,7 @@ import { } export interface IContact { + type?: string, star_value?: string; lead_score?: string; tags?: string[]; From b2b6656d8d4398d793869dbf56cfdb01cf49a015 Mon Sep 17 00:00:00 2001 From: Rupenieks Date: Tue, 5 May 2020 16:03:53 +0200 Subject: [PATCH 09/15] Deal frontend --- .../nodes/AgileCrm/AgileCrm.node.ts | 58 +- .../nodes/AgileCrm/DealDescription.ts | 547 ++++++++++++++++++ 2 files changed, 598 insertions(+), 7 deletions(-) create mode 100644 packages/nodes-base/nodes/AgileCrm/DealDescription.ts diff --git a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts index c1417a8e07..dbdf00ee1f 100644 --- a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts +++ b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts @@ -16,6 +16,11 @@ import { companyFields } from './CompanyDescription'; +import { + dealOperations, + dealFields +} from './DealDescription'; + import { agileCrmApiRequest, validateJSON, agileCrmApiRequestUpdate} from './GenericFunctions'; import { IContact, IProperty, IContactUpdate } from './ContactInterface'; @@ -48,13 +53,17 @@ export class AgileCrm implements INodeType { name: 'resource', type: 'options', options: [ + { + name: 'Company', + value: 'company' + }, { name: 'Contact', value: 'contact' }, { - name: 'Company', - value: 'company' + name: 'Deal', + value: 'deal' }, ], default: 'contact', @@ -66,7 +75,11 @@ export class AgileCrm implements INodeType { // COMPANY ...companyOperations, - ...companyFields + ...companyFields, + + // DEAL + ...dealOperations, + ...dealFields ], }; @@ -441,11 +454,42 @@ export class AgileCrm implements INodeType { } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + } + if(resource === 'deal'){ + + if(operation === 'get'){ + const dealId = this.getNodeParameter('dealId', i) as string; + + const endpoint = `api/opportunity/${dealId}`; + responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); } + + if(operation === 'delete'){ + const contactId = this.getNodeParameter('dealId', i) as string; + + const endpoint = `api/opportunity/${contactId}`; + responseData = await agileCrmApiRequest.call(this, 'DELETE', endpoint, {}); + } + + if(operation === 'getAll'){ + const returnAll = this.getNodeParameter('returnAll', i) as boolean; + + if (returnAll) { + const endpoint = `api/opportunity`; + responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); + } else { + const limit = this.getNodeParameter('limit', i) as number; + const endpoint = `api/opportunity?page_size=${limit}`; + responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); + } + } + } + + + if (Array.isArray(responseData)) { + returnData.push.apply(returnData, responseData as IDataObject[]); + } else { + returnData.push(responseData as IDataObject); } } diff --git a/packages/nodes-base/nodes/AgileCrm/DealDescription.ts b/packages/nodes-base/nodes/AgileCrm/DealDescription.ts new file mode 100644 index 0000000000..232eb0a799 --- /dev/null +++ b/packages/nodes-base/nodes/AgileCrm/DealDescription.ts @@ -0,0 +1,547 @@ +import { + INodeProperties, + } from 'n8n-workflow'; + +export const dealOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'deal', + ], + }, + }, + options: [ + { + name: 'Get', + value: 'get', + description: 'Get a deal', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Get all deals', + }, + { + name: 'Create', + value: 'create', + description: 'Create a new deal', + }, + { + name: 'Update', + value: 'update', + description: 'Update deal properties', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a deal', + }, + ], + default: 'get', + description: 'The operation to perform.', + }, +] as INodeProperties[]; + +export const dealFields = [ +/* -------------------------------------------------------------------------- */ +/* deal:get */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Deal ID', + name: 'dealId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'get', + ], + }, + }, + default: '', + description: 'Unique identifier for a particular deal', + }, + + +/* -------------------------------------------------------------------------- */ +/* deal:get all */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'getAll', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + default: 20, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + } + }, + +/* -------------------------------------------------------------------------- */ +/* deal:create */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Close Date', + name: 'closeDate', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + default: '', + description: 'Closing date of deal.', + }, + { + displayName: 'Expected Value', + name: 'expectedValue', + type: 'number', + required: true, + typeOptions: { + minValue: 0, + maxValue: 1000000000000 + }, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + default: 1, + description: 'Expected Value of deal.', + }, + { + displayName: 'Milestone', + name: 'milestone', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + default: '', + description: 'Milestone of deal.', + }, + { + displayName: 'Probability', + name: 'probability', + type: 'number', + required: true, + typeOptions: { + minValue: 0, + maxValue: 100 + }, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + default: 50, + description: 'Expected probability.', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + default: '', + description: 'Name of deal.', + }, + { + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: ' Additional Fields', + name: 'additionalFieldsJson', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + jsonParameters: [ + true, + ], + }, + }, + + description: `Object of values to set as described here.`, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + jsonParameters: [ + false, + ], + }, + }, + options: [ + { + displayName: 'Contact Ids', + name: 'contactIds', + type: 'string', + typeOptions: { + multipleValues: true, + multipleValueButtonText: 'Add ID', + }, + default: [], + placeholder: 'ID', + description: 'Unique contact identifiers.', + }, + { + displayName: 'Custom Data', + name: 'customData', + type: 'fixedCollection', + required: false, + description: 'Custom Data', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Property', + name: 'customProperty', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Property name.' + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + required: false, + default: "", + placeholder: '', + description: 'Property value.', + } + ] + }, + + ] + }, + ] + }, + + + +/* -------------------------------------------------------------------------- */ +/* deal:update */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Close Date', + name: 'closeDate', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + }, + }, + default: '', + description: 'Closing date of deal.', + }, + { + displayName: 'Expected Value', + name: 'expectedValue', + type: 'number', + required: true, + typeOptions: { + minValue: 0, + maxValue: 10000 + }, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + }, + }, + default: '', + description: 'Expected Value of deal.', + }, + { + displayName: 'Milestone', + name: 'milestone', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + }, + }, + default: '', + description: 'Milestone of deal.', + }, + { + displayName: 'Probability', + name: 'probability', + type: 'number', + required: true, + typeOptions: { + minValue: 0, + maxValue: 100 + }, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + }, + }, + default: 50, + description: 'Expected Value of deal.', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + }, + }, + default: '', + description: 'Name of deal.', + }, + { + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: ' Additional Fields', + name: 'additionalFieldsJson', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + jsonParameters: [ + true, + ], + }, + }, + + description: `Object of values to set as described here.`, + }, + { + displayName: 'Contact IDs', + name: 'contactIds', + type: 'string', + typeOptions: { + multipleValues: true, + multipleValueButtonText: 'Add Contact ID', + }, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + jsonParameters: [ + false, + ], + }, + }, + default: [], + placeholder: 'Id', + description: 'Id numbers of contacts.', + }, + { + displayName: 'Custom Data', + name: 'customData', + type: 'fixedCollection', + required: false, + description: 'Custom Data.', + typeOptions: { + multipleValues: true, + }, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + jsonParameters: [ + false, + ], + }, + }, + options: [ + { + displayName: 'Data Properties', + name: 'customDataProperties', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + default: "", + placeholder: 'name', + description: 'Name of property', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Value of property', + } + ] + }, + + ] + }, + +] as INodeProperties[]; From 08220195a25ef1a61739ff7919f2f3bc30abd8ea Mon Sep 17 00:00:00 2001 From: Rupenieks Date: Tue, 5 May 2020 17:44:02 +0200 Subject: [PATCH 10/15] Deal Get / Getall / Delete / update / create --- .../nodes/AgileCrm/AgileCrm.node.ts | 94 +++++++ .../nodes/AgileCrm/DealDescription.ts | 260 ++++++++---------- .../nodes/AgileCrm/DealInterface.ts | 19 ++ .../nodes/AgileCrm/GenericFunctions.ts | 1 + 4 files changed, 236 insertions(+), 138 deletions(-) create mode 100644 packages/nodes-base/nodes/AgileCrm/DealInterface.ts diff --git a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts index dbdf00ee1f..50d0cc548a 100644 --- a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts +++ b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts @@ -23,6 +23,7 @@ import { import { agileCrmApiRequest, validateJSON, agileCrmApiRequestUpdate} from './GenericFunctions'; import { IContact, IProperty, IContactUpdate } from './ContactInterface'; +import { IDeal } from './DealInterface'; export class AgileCrm implements INodeType { @@ -483,6 +484,99 @@ export class AgileCrm implements INodeType { responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); } } + + if(operation === 'create'){ + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + + const body: IDeal = {}; + + if (jsonParameters) { + const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; + + if (additionalFieldsJson !== '' ) { + + if (validateJSON(additionalFieldsJson) !== undefined) { + + Object.assign(body, JSON.parse(additionalFieldsJson)); + + } else { + throw new Error('Additional fields must be a valid JSON'); + } + } + + } else { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + body.close_date = new Date(this.getNodeParameter('closeDate', i) as string).getTime(); + body.expected_value = this.getNodeParameter('expectedValue', i) as number; + body.milestone = this.getNodeParameter('milestone', i) as string; + body.probability = this.getNodeParameter('probability', i) as number; + body.name = this.getNodeParameter('name', i) as string; + + if(additionalFields.contactIds){ + body.contactIds = additionalFields.contactIds as string[]; + } + + if(additionalFields.customData){ + // @ts-ignore + body.customData = additionalFields.customData.customProperty as IDealCustomProperty[]; + } + + } + + let endpoint = 'api/opportunity' + responseData = await agileCrmApiRequest.call(this, 'POST', endpoint, body); + } + + if(operation === 'update'){ + const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; + + const body: IDeal = {}; + + if (jsonParameters) { + const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; + + if (additionalFieldsJson !== '' ) { + + if (validateJSON(additionalFieldsJson) !== undefined) { + + Object.assign(body, JSON.parse(additionalFieldsJson)); + + } else { + throw new Error('Additional fields must be a valid JSON'); + } + } + + } else { + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + body.id = this.getNodeParameter('dealId', i) as number; + + if(additionalFields.expectedValue){ + body.expected_value = additionalFields.expectedValue as number; + } + + if(additionalFields.name){ + body.name = additionalFields.name as string; + } + + if(additionalFields.probability){ + body.probability = additionalFields.probability as number; + } + + if(additionalFields.contactIds){ + body.contactIds = additionalFields.contactIds as string[]; + } + + if(additionalFields.customData){ + // @ts-ignore + body.customData = additionalFields.customData.customProperty as IDealCustomProperty[]; + } + + } + + let endpoint = 'api/opportunity/partial-update' + responseData = await agileCrmApiRequest.call(this, 'PUT', endpoint, body); + } } diff --git a/packages/nodes-base/nodes/AgileCrm/DealDescription.ts b/packages/nodes-base/nodes/AgileCrm/DealDescription.ts index 232eb0a799..4b947bda62 100644 --- a/packages/nodes-base/nodes/AgileCrm/DealDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/DealDescription.ts @@ -116,7 +116,7 @@ export const dealFields = [ { displayName: 'Close Date', name: 'closeDate', - type: 'string', + type: 'dateTime', required: true, displayOptions: { show: { @@ -126,6 +126,9 @@ export const dealFields = [ operation: [ 'create', ], + jsonParameters: [ + false, + ], }, }, default: '', @@ -148,6 +151,9 @@ export const dealFields = [ operation: [ 'create', ], + jsonParameters: [ + false, + ], }, }, default: 1, @@ -166,6 +172,9 @@ export const dealFields = [ operation: [ 'create', ], + jsonParameters: [ + false, + ], }, }, default: '', @@ -188,6 +197,9 @@ export const dealFields = [ operation: [ 'create', ], + jsonParameters: [ + false, + ], }, }, default: 50, @@ -206,6 +218,9 @@ export const dealFields = [ operation: [ 'create', ], + jsonParameters: [ + false, + ], }, }, default: '', @@ -324,14 +339,34 @@ export const dealFields = [ ] }, - +/* -------------------------------------------------------------------------- */ +/* deal:delete */ +/* -------------------------------------------------------------------------- */ +{ + displayName: 'Deal ID', + name: 'dealId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'delete', + ], + }, + }, + default: '', + description: 'Unique identifier for a particular deal', +}, /* -------------------------------------------------------------------------- */ /* deal:update */ /* -------------------------------------------------------------------------- */ { - displayName: 'Close Date', - name: 'closeDate', + displayName: 'Deal ID', + name: 'dealId', type: 'string', required: true, displayOptions: { @@ -345,88 +380,9 @@ export const dealFields = [ }, }, default: '', - description: 'Closing date of deal.', - }, - { - displayName: 'Expected Value', - name: 'expectedValue', - type: 'number', - required: true, - typeOptions: { - minValue: 0, - maxValue: 10000 - }, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'update', - ], - }, - }, - default: '', - description: 'Expected Value of deal.', - }, - { - displayName: 'Milestone', - name: 'milestone', - type: 'string', - required: true, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'update', - ], - }, - }, - default: '', - description: 'Milestone of deal.', - }, - { - displayName: 'Probability', - name: 'probability', - type: 'number', - required: true, - typeOptions: { - minValue: 0, - maxValue: 100 - }, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'update', - ], - }, - }, - default: 50, - description: 'Expected Value of deal.', - }, - { - displayName: 'Name', - name: 'name', - type: 'string', - required: true, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'update', - ], - }, - }, - default: '', - description: 'Name of deal.', + description: 'Unique identifier for a particular deal', }, + { displayName: 'JSON Parameters', name: 'jsonParameters', @@ -469,39 +425,11 @@ export const dealFields = [ description: `Object of values to set as described here.`, }, { - displayName: 'Contact IDs', - name: 'contactIds', - type: 'string', - typeOptions: { - multipleValues: true, - multipleValueButtonText: 'Add Contact ID', - }, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'update', - ], - jsonParameters: [ - false, - ], - }, - }, - default: [], - placeholder: 'Id', - description: 'Id numbers of contacts.', - }, - { - displayName: 'Custom Data', - name: 'customData', - type: 'fixedCollection', - required: false, - description: 'Custom Data.', - typeOptions: { - multipleValues: true, - }, + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, displayOptions: { show: { resource: [ @@ -517,30 +445,86 @@ export const dealFields = [ }, options: [ { - displayName: 'Data Properties', - name: 'customDataProperties', - values: [ + displayName: 'Expected Value', + name: 'expectedValue', + type: 'number', + required: false, + typeOptions: { + minValue: 0, + maxValue: 10000 + }, + default: '', + description: 'Expected Value of deal.', + }, + { + displayName: 'Probability', + name: 'probability', + type: 'number', + required: false, + typeOptions: { + minValue: 0, + maxValue: 100 + }, + default: 50, + description: 'Expected Value of deal.', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + required: false, + default: '', + description: 'Name of deal.', + }, + { + displayName: 'Contact Ids', + name: 'contactIds', + type: 'string', + typeOptions: { + multipleValues: true, + multipleValueButtonText: 'Add ID', + }, + default: [], + placeholder: 'ID', + description: 'Unique contact identifiers.', + }, + { + displayName: 'Custom Data', + name: 'customData', + type: 'fixedCollection', + required: false, + description: 'Custom Data', + typeOptions: { + multipleValues: true, + }, + options: [ { - displayName: 'Name', - name: 'name', - type: 'string', - required: true, - default: "", - placeholder: 'name', - description: 'Name of property', + displayName: 'Property', + name: 'customProperty', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Property name.' + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + required: false, + default: "", + placeholder: '', + description: 'Property value.', + } + ] }, - { - displayName: 'Value', - name: 'value', - type: 'string', - required: true, - default: "", - placeholder: '', - description: 'Value of property', - } + ] }, - ] }, diff --git a/packages/nodes-base/nodes/AgileCrm/DealInterface.ts b/packages/nodes-base/nodes/AgileCrm/DealInterface.ts new file mode 100644 index 0000000000..797fddcb7a --- /dev/null +++ b/packages/nodes-base/nodes/AgileCrm/DealInterface.ts @@ -0,0 +1,19 @@ +import { + IDataObject, + } from 'n8n-workflow'; + + export interface IDealCustomProperty { + name: string; + value: string; +} + +export interface IDeal { + id?: number, + expected_value?: number, + probability?: number, + name?: string, + close_date?: number, + milestone?: string, + contactIds?: string[], + customData?: IDealCustomProperty[] +} \ No newline at end of file diff --git a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts index eb7497f2fa..897a17a3f0 100644 --- a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts +++ b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts @@ -35,6 +35,7 @@ export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunction if(method !== "GET" && method !== "DELETE"){ options.body = body; } + try { return await this.helpers.request!(options); From 7c4a588b70b2b944f6c47ddd6efa8c17c14089d0 Mon Sep 17 00:00:00 2001 From: Rupenieks Date: Wed, 6 May 2020 10:27:01 +0200 Subject: [PATCH 11/15] EsLint changes --- .eslintrc.json | 50 + package.json | 6 +- .../nodes/AgileCrm/AgileCrm.node.ts | 91 +- .../nodes/AgileCrm/CompanyDescription.ts | 1186 ++++++++--------- .../nodes/AgileCrm/ContactDescription.ts | 936 ++++++------- .../nodes/AgileCrm/ContactInterface.ts | 6 +- .../nodes/AgileCrm/DealInterface.ts | 22 +- .../nodes/AgileCrm/GenericFunctions.ts | 14 +- 8 files changed, 1180 insertions(+), 1131 deletions(-) create mode 100644 .eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000000..cce72ec974 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,50 @@ +{ + "env": { + "browser": true, + "es6": true + }, + "extends": [ + "eslint:recommended", + "plugin:vue/essential", + "tslint-eslint-rules" + ], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 2018, + "parser": "@typescript-eslint/parser", + "sourceType": "module" + }, + "plugins": [ + "vue", + "@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "rules": { + "indent": [ + "error", + "tab" + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "always" + ], + "sort-imports": ["error", { + "ignoreCase": false, + "ignoreMemberSort": false, + "memberSyntaxSortOrder": ["none", "all", "multiple", "single"] + }], + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": ["error"] + } +} \ No newline at end of file diff --git a/package.json b/package.json index b045830f51..0fd1747984 100644 --- a/package.json +++ b/package.json @@ -16,5 +16,9 @@ "lerna": "^3.13.1", "run-script-os": "^1.0.7" }, - "postcss": {} + "postcss": {}, + "dependencies": { + "@typescript-eslint/parser": "^2.31.0", + "tslint-eslint-rules": "^5.4.0" + } } diff --git a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts index 50d0cc548a..be217de2ed 100644 --- a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts +++ b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts @@ -1,36 +1,36 @@ import { IExecuteFunctions } from 'n8n-core'; import { + IDataObject, INodeExecutionData, INodeType, - INodeTypeDescription, - IDataObject + INodeTypeDescription } from 'n8n-workflow'; import { - contactOperations, - contactFields + contactFields, + contactOperations } from './ContactDescription'; import { - companyOperations, - companyFields + companyFields, + companyOperations } from './CompanyDescription'; import { - dealOperations, - dealFields + dealFields, + dealOperations } from './DealDescription'; -import { agileCrmApiRequest, validateJSON, agileCrmApiRequestUpdate} from './GenericFunctions'; -import { IContact, IProperty, IContactUpdate } from './ContactInterface'; +import { IContact, IContactUpdate } from './ContactInterface'; +import { agileCrmApiRequest, agileCrmApiRequestUpdate, validateJSON} from './GenericFunctions'; import { IDeal } from './DealInterface'; export class AgileCrm implements INodeType { description: INodeTypeDescription = { displayName: 'AgileCRM', - name: 'agileCrm', - icon: 'file:agilecrm.png', + name: 'agileCrm', + icon: 'file:agilecrm.png', group: ['transform'], version: 1, description: 'Consume AgileCRM API', @@ -39,8 +39,8 @@ export class AgileCrm implements INodeType { color: '#772244', }, inputs: ['main'], - outputs: ['main'], - credentials: [ + outputs: ['main'], + credentials: [ { name: 'agileCrmApi', required: true, @@ -52,21 +52,21 @@ export class AgileCrm implements INodeType { { displayName: 'Resource', name: 'resource', - type: 'options', - options: [ + type: 'options', + options: [ { - name: 'Company', - value: 'company' - }, - { - name: 'Contact', - value: 'contact' + name: 'Company', + value: 'company' }, { - name: 'Deal', - value: 'deal' - }, - ], + name: 'Contact', + value: 'contact' + }, + { + name: 'Deal', + value: 'deal' + }, + ], default: 'contact', description: 'Resource to consume.', }, @@ -92,14 +92,13 @@ export class AgileCrm implements INodeType { const returnData: IDataObject[] = []; const length = items.length as unknown as number; let responseData; - const qs: IDataObject = {}; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { if(resource === 'contact' || resource === 'company'){ - let idGetter = resource === 'contact' ? 'contactId' : 'companyId'; + const idGetter = resource === 'contact' ? 'contactId' : 'companyId'; if(operation === 'get'){ const contactId = this.getNodeParameter(idGetter, i) as string; @@ -122,7 +121,7 @@ export class AgileCrm implements INodeType { if(resource === 'contact'){ if (returnAll) { - const endpoint = `api/contacts`; + const endpoint = 'api/contacts'; responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); } else { const limit = this.getNodeParameter('limit', i) as number; @@ -131,7 +130,7 @@ export class AgileCrm implements INodeType { } } else { if (returnAll) { - const endpoint = `api/contacts/companies/list`; + const endpoint = 'api/contacts/companies/list'; responseData = await agileCrmApiRequest.call(this, 'POST', endpoint, {}); } else { const limit = this.getNodeParameter('limit', i) as number; @@ -145,7 +144,7 @@ export class AgileCrm implements INodeType { if(operation === 'create'){ const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; const body: IContact = {}; - let properties : IDataObject[] = []; + const properties : IDataObject[] = []; if (jsonParameters) { const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; @@ -218,7 +217,7 @@ export class AgileCrm implements INodeType { name: 'email', value: property.email as string } as IDataObject); - }) + }); } if(additionalFields.addressOptions){ //@ts-ignore @@ -229,7 +228,7 @@ export class AgileCrm implements INodeType { name: 'address', value: property.address as string } as IDataObject); - }) + }); } if(additionalFields.phoneOptions){ @@ -241,7 +240,7 @@ export class AgileCrm implements INodeType { name: 'phone', value: property.number as string } as IDataObject); - }) + }); } } else if (resource === 'company') { if(additionalFields.email){ @@ -279,7 +278,7 @@ export class AgileCrm implements INodeType { name: 'webiste', value: property.url as string } as IDataObject); - }) + }); } if(additionalFields.customProperties){ @@ -291,7 +290,7 @@ export class AgileCrm implements INodeType { name: property.name, value: property.value as string } as IDataObject); - }) + }); } body.properties = properties; @@ -302,10 +301,10 @@ export class AgileCrm implements INodeType { if(operation === 'update') { const contactId = this.getNodeParameter(idGetter, i) as string; - let contactUpdatePayload : IContactUpdate = {id: contactId}; + const contactUpdatePayload : IContactUpdate = {id: contactId}; const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; const body: IContact = {}; - let properties : IDataObject[] = []; + const properties : IDataObject[] = []; if (jsonParameters) { const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; @@ -372,7 +371,7 @@ export class AgileCrm implements INodeType { name: 'email', value: property.email as string } as IDataObject); - }) + }); } if(additionalFields.addressOptions){ //@ts-ignore @@ -383,7 +382,7 @@ export class AgileCrm implements INodeType { name: 'address', value: property.address as string } as IDataObject); - }) + }); } if(additionalFields.phoneOptions){ @@ -395,7 +394,7 @@ export class AgileCrm implements INodeType { name: 'phone', value: property.number as string } as IDataObject); - }) + }); } } else if (resource === 'company') { if(additionalFields.email){ @@ -433,7 +432,7 @@ export class AgileCrm implements INodeType { name: 'webiste', value: property.url as string } as IDataObject); - }) + }); } if(additionalFields.customProperties){ //@ts-ignore @@ -444,7 +443,7 @@ export class AgileCrm implements INodeType { name: property.name, value: property.value as string } as IDataObject); - }) + }); } body.properties = properties; } @@ -476,7 +475,7 @@ export class AgileCrm implements INodeType { const returnAll = this.getNodeParameter('returnAll', i) as boolean; if (returnAll) { - const endpoint = `api/opportunity`; + const endpoint = 'api/opportunity'; responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); } else { const limit = this.getNodeParameter('limit', i) as number; @@ -524,7 +523,7 @@ export class AgileCrm implements INodeType { } - let endpoint = 'api/opportunity' + const endpoint = 'api/opportunity'; responseData = await agileCrmApiRequest.call(this, 'POST', endpoint, body); } @@ -574,7 +573,7 @@ export class AgileCrm implements INodeType { } - let endpoint = 'api/opportunity/partial-update' + const endpoint = 'api/opportunity/partial-update'; responseData = await agileCrmApiRequest.call(this, 'PUT', endpoint, body); } } diff --git a/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts b/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts index 56db0f4abc..066b33260c 100644 --- a/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts @@ -1,6 +1,6 @@ import { INodeProperties, - } from 'n8n-workflow'; +} from 'n8n-workflow'; export const companyOperations = [ { @@ -70,9 +70,9 @@ export const companyFields = [ }, -/* -------------------------------------------------------------------------- */ -/* company:get all */ -/* -------------------------------------------------------------------------- */ + /* -------------------------------------------------------------------------- */ + /* company:get all */ + /* -------------------------------------------------------------------------- */ { displayName: 'Return All', name: 'returnAll', @@ -110,623 +110,623 @@ export const companyFields = [ } }, -/* -------------------------------------------------------------------------- */ -/* company:create */ -/* -------------------------------------------------------------------------- */ + /* -------------------------------------------------------------------------- */ + /* company:create */ + /* -------------------------------------------------------------------------- */ -{ - displayName: 'JSON Parameters', - name: 'jsonParameters', - type: 'boolean', - default: false, - description: '', - displayOptions: { - show: { - resource: [ - 'company', - ], - operation: [ - 'create', - ], + { + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'create', + ], + }, }, }, -}, -{ - displayName: ' Additional Fields', - name: 'additionalFieldsJson', - type: 'json', - typeOptions: { - alwaysOpenEditWindow: true, - }, - default: '', - displayOptions: { - show: { - resource: [ - 'company', - ], - operation: [ - 'create', - ], - jsonParameters: [ - true, - ], + { + displayName: ' Additional Fields', + name: 'additionalFieldsJson', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'create', + ], + jsonParameters: [ + true, + ], + }, }, - }, - description: `Object of values to set as described here.`, -}, + description: 'Object of values to set as described here.', + }, -{ - displayName: 'Additional Fields', - name: 'additionalFields', - type: 'collection', - placeholder: 'Add Field', - default: {}, - displayOptions: { - show: { - resource: [ - 'company', - ], - operation: [ - 'create', - ], - jsonParameters: [ - false, - ], - }, - }, - options: [ - { - displayName: 'Star Value', - name: 'starValue', - type: 'options', - default: '', - required: false, - description: 'Rating of company (Max value 5). This is not applicable for companies.', - options: [ - { - name: '0', - value: 0 - }, - { - name: '1', - value: 1 - }, - { - name: '2', - value: 2 - }, - { - name: '3', - value: 3 - }, - { - name: '4', - value: 4 - }, - { - name: '5', - value: 5 - }, - ] - }, - { - displayName: 'Lead Score', - name: 'leadScore', - type: 'number', - default: '', - description: 'Score of company. This is not applicable for companies.', - required: false, - typeOptions: { - minValue: 0 - } - }, - { - displayName: 'Tags', - name: 'tags', - type: 'string', - typeOptions: { - multipleValues: true, - multipleValueButtonText: 'Add Tag', + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'create', + ], + jsonParameters: [ + false, + ], }, - default: [], - placeholder: 'Tag', - description: 'Unique identifiers added to company, for easy management of companys. This is not applicable for companies.', - }, - { - displayName: 'Name', - name: 'name', - type: 'string', - required: false, - default: "", - placeholder: 'Company name', - description: 'Company name.', }, - { - displayName: 'Email', - name: 'email', - type: 'string', - required: false, - default: '', - placeholder: 'Company email', - description: 'Company email.', - }, - { - displayName: 'Address', - name: 'email', - type: 'string', - required: false, - default: '', - placeholder: 'Company address', - description: 'Company address.', - }, - { - displayName: 'Website', - name: 'websiteOptions', - type: 'fixedCollection', - required: false, - description: 'companys websites.', - typeOptions: { - multipleValues: true, + options: [ + { + displayName: 'Star Value', + name: 'starValue', + type: 'options', + default: '', + required: false, + description: 'Rating of company (Max value 5). This is not applicable for companies.', + options: [ + { + name: '0', + value: 0 + }, + { + name: '1', + value: 1 + }, + { + name: '2', + value: 2 + }, + { + name: '3', + value: 3 + }, + { + name: '4', + value: 4 + }, + { + name: '5', + value: 5 + }, + ] }, - options: [ - { - displayName: 'Website properties.', - name: 'websiteProperties', - values: [ - { - displayName: 'Type', - name: 'subtype', - type: 'options', - required: true, - default: "", - placeholder: '', - description: 'Type of website.', - options: [ - { - name: 'URL', - value: 'url', - }, - { - name: 'SKYPE', - value: 'skype', - }, - { - name: 'TWITTER', - value: 'twitter', - }, - { - name: 'LINKEDIN', - value: 'linkedin', - }, - { - name: 'FACEBOOK', - value: 'facebook', - }, - { - name: 'XING', - value: 'xing', - }, - { - name: 'FEED', - value: 'feed', - }, - { - name: 'GOOGLE_PLUS', - value: 'googlePlus', - }, - { - name: 'FLICKR', - value: 'flickr', - }, - { - name: 'GITHUB', - value: 'github', - }, - { - name: 'YOUTUBE', - value: 'youtube', - }, - ] - }, - { - displayName: 'URL', - name: 'url', - type: 'string', - required: true, - default: "", - placeholder: '', - description: 'Website URL', - } - ] + { + displayName: 'Lead Score', + name: 'leadScore', + type: 'number', + default: '', + description: 'Score of company. This is not applicable for companies.', + required: false, + typeOptions: { + minValue: 0 + } + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + typeOptions: { + multipleValues: true, + multipleValueButtonText: 'Add Tag', }, + default: [], + placeholder: 'Tag', + description: 'Unique identifiers added to company, for easy management of companys. This is not applicable for companies.', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + required: false, + default: '', + placeholder: 'Company name', + description: 'Company name.', + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + required: false, + default: '', + placeholder: 'Company email', + description: 'Company email.', + }, + { + displayName: 'Address', + name: 'email', + type: 'string', + required: false, + default: '', + placeholder: 'Company address', + description: 'Company address.', + }, + { + displayName: 'Website', + name: 'websiteOptions', + type: 'fixedCollection', + required: false, + description: 'companys websites.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Website properties.', + name: 'websiteProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: '', + placeholder: '', + description: 'Type of website.', + options: [ + { + name: 'URL', + value: 'url', + }, + { + name: 'SKYPE', + value: 'skype', + }, + { + name: 'TWITTER', + value: 'twitter', + }, + { + name: 'LINKEDIN', + value: 'linkedin', + }, + { + name: 'FACEBOOK', + value: 'facebook', + }, + { + name: 'XING', + value: 'xing', + }, + { + name: 'FEED', + value: 'feed', + }, + { + name: 'GOOGLE_PLUS', + value: 'googlePlus', + }, + { + name: 'FLICKR', + value: 'flickr', + }, + { + name: 'GITHUB', + value: 'github', + }, + { + name: 'YOUTUBE', + value: 'youtube', + }, + ] + }, + { + displayName: 'URL', + name: 'url', + type: 'string', + required: true, + default: '', + placeholder: '', + description: 'Website URL', + } + ] + }, - ] - }, - { - displayName: 'Phone', - name: 'phone', - type: 'string', - required: false, - default: '', - placeholder: 'Company phone', - description: 'Company phone.', - }, - { - displayName: 'Custom Properties', - name: 'customProperties', - type: 'fixedCollection', - required: false, - description: 'Custom Properties', - typeOptions: { - multipleValues: true, + ] }, - options: [ - { - displayName: 'Property', - name: 'customProperty', - values: [ - { - displayName: 'Name', - name: 'name', - type: 'string', - required: true, - default: "", - placeholder: '', - description: 'Property name.' - }, - { - displayName: 'Sub Type', - name: 'subtype', - type: 'string', - required: false, - default: "", - placeholder: '', - description: 'Property sub type.', - }, - { - displayName: 'Value', - name: 'value', - type: 'string', - required: false, - default: "", - placeholder: '', - description: 'Property value.', - } - ] + { + displayName: 'Phone', + name: 'phone', + type: 'string', + required: false, + default: '', + placeholder: 'Company phone', + description: 'Company phone.', + }, + { + displayName: 'Custom Properties', + name: 'customProperties', + type: 'fixedCollection', + required: false, + description: 'Custom Properties', + typeOptions: { + multipleValues: true, }, + options: [ + { + displayName: 'Property', + name: 'customProperty', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + default: '', + placeholder: '', + description: 'Property name.' + }, + { + displayName: 'Sub Type', + name: 'subtype', + type: 'string', + required: false, + default: '', + placeholder: '', + description: 'Property sub type.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + required: false, + default: '', + placeholder: '', + description: 'Property value.', + } + ] + }, - ] + ] + }, + ], + }, + /* -------------------------------------------------------------------------- */ + /* company:delete */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'company ID', + name: 'companyId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'delete', + ], + }, }, - ], -}, -/* -------------------------------------------------------------------------- */ -/* company:delete */ -/* -------------------------------------------------------------------------- */ -{ - displayName: 'company ID', - name: 'companyId', - type: 'string', - required: true, - displayOptions: { - show: { - resource: [ - 'company', - ], - operation: [ - 'delete', - ], + default: '', + description: 'Unique identifier for a particular company', + }, + /* -------------------------------------------------------------------------- */ + /* company:update */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'company ID', + name: 'companyId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'update', + ], + }, + }, + default: '', + description: 'Unique identifier for a particular company', + }, + { + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'update', + ], + }, }, }, - default: '', - description: 'Unique identifier for a particular company', -}, -/* -------------------------------------------------------------------------- */ -/* company:update */ -/* -------------------------------------------------------------------------- */ -{ - displayName: 'company ID', - name: 'companyId', - type: 'string', - required: true, - displayOptions: { - show: { - resource: [ - 'company', - ], - operation: [ - 'update', - ], + { + displayName: ' Additional Fields', + name: 'additionalFieldsJson', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, }, - }, - default: '', - description: 'Unique identifier for a particular company', -}, -{ - displayName: 'JSON Parameters', - name: 'jsonParameters', - type: 'boolean', - default: false, - description: '', - displayOptions: { - show: { - resource: [ - 'company', - ], - operation: [ - 'update', - ], + default: '', + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'update', + ], + jsonParameters: [ + true, + ], + }, }, - }, -}, -{ - displayName: ' Additional Fields', - name: 'additionalFieldsJson', - type: 'json', - typeOptions: { - alwaysOpenEditWindow: true, - }, - default: '', - displayOptions: { - show: { - resource: [ - 'company', - ], - operation: [ - 'update', - ], - jsonParameters: [ - true, - ], - }, - }, - description: `Object of values to set as described here.`, -}, - -{ - displayName: 'Additional Fields', - name: 'additionalFields', - type: 'collection', - placeholder: 'Add Field', - default: {}, - displayOptions: { - show: { - resource: [ - 'company', - ], - operation: [ - 'update', - ], - jsonParameters: [ - false, - ], - }, + description: 'Object of values to set as described here.', }, - options: [ - { - displayName: 'Star Value', - name: 'starValue', - type: 'options', - default: '', - required: false, - description: 'Rating of company (Max value 5). This is not applicable for companies.', - options: [ - { - name: '0', - value: 0 - }, - { - name: '1', - value: 1 - }, - { - name: '2', - value: 2 - }, - { - name: '3', - value: 3 - }, - { - name: '4', - value: 4 - }, - { - name: '5', - value: 5 - }, - ] - }, - { - displayName: 'Lead Score', - name: 'leadScore', - type: 'number', - default: '', - description: 'Score of company. This is not applicable for companies.', - required: false, - typeOptions: { - minValue: 0 - } - }, - { - displayName: 'Tags', - name: 'tags', - type: 'string', - typeOptions: { - multipleValues: true, - multipleValueButtonText: 'Add Tag', + + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'company', + ], + operation: [ + 'update', + ], + jsonParameters: [ + false, + ], }, - default: [], - placeholder: 'Tag', - description: 'Unique identifiers added to company, for easy management of companys. This is not applicable for companies.', - }, - { - displayName: 'Name', - name: 'name', - type: 'string', - required: false, - default: "", - placeholder: 'Company name', - description: 'Company name.', }, - { - displayName: 'Email', - name: 'email', - type: 'string', - required: false, - default: '', - placeholder: 'Company email', - description: 'Company email.', - }, - { - displayName: 'Address', - name: 'email', - type: 'string', - required: false, - default: '', - placeholder: 'Company address', - description: 'Company address.', - }, - { - displayName: 'Website', - name: 'websiteOptions', - type: 'fixedCollection', - required: false, - description: 'companys websites.', - typeOptions: { - multipleValues: true, + options: [ + { + displayName: 'Star Value', + name: 'starValue', + type: 'options', + default: '', + required: false, + description: 'Rating of company (Max value 5). This is not applicable for companies.', + options: [ + { + name: '0', + value: 0 + }, + { + name: '1', + value: 1 + }, + { + name: '2', + value: 2 + }, + { + name: '3', + value: 3 + }, + { + name: '4', + value: 4 + }, + { + name: '5', + value: 5 + }, + ] }, - options: [ - { - displayName: 'Website properties.', - name: 'websiteProperties', - values: [ - { - displayName: 'Type', - name: 'subtype', - type: 'options', - required: true, - default: "", - placeholder: '', - description: 'Type of website.', - options: [ - { - name: 'URL', - value: 'url', - }, - { - name: 'SKYPE', - value: 'skype', - }, - { - name: 'TWITTER', - value: 'twitter', - }, - { - name: 'LINKEDIN', - value: 'linkedin', - }, - { - name: 'FACEBOOK', - value: 'facebook', - }, - { - name: 'XING', - value: 'xing', - }, - { - name: 'FEED', - value: 'feed', - }, - { - name: 'GOOGLE_PLUS', - value: 'googlePlus', - }, - { - name: 'FLICKR', - value: 'flickr', - }, - { - name: 'GITHUB', - value: 'github', - }, - { - name: 'YOUTUBE', - value: 'youtube', - }, - ] - }, - { - displayName: 'URL', - name: 'url', - type: 'string', - required: true, - default: "", - placeholder: '', - description: 'Website URL', - } - ] + { + displayName: 'Lead Score', + name: 'leadScore', + type: 'number', + default: '', + description: 'Score of company. This is not applicable for companies.', + required: false, + typeOptions: { + minValue: 0 + } + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + typeOptions: { + multipleValues: true, + multipleValueButtonText: 'Add Tag', }, + default: [], + placeholder: 'Tag', + description: 'Unique identifiers added to company, for easy management of companys. This is not applicable for companies.', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + required: false, + default: '', + placeholder: 'Company name', + description: 'Company name.', + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + required: false, + default: '', + placeholder: 'Company email', + description: 'Company email.', + }, + { + displayName: 'Address', + name: 'email', + type: 'string', + required: false, + default: '', + placeholder: 'Company address', + description: 'Company address.', + }, + { + displayName: 'Website', + name: 'websiteOptions', + type: 'fixedCollection', + required: false, + description: 'companys websites.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Website properties.', + name: 'websiteProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: '', + placeholder: '', + description: 'Type of website.', + options: [ + { + name: 'URL', + value: 'url', + }, + { + name: 'SKYPE', + value: 'skype', + }, + { + name: 'TWITTER', + value: 'twitter', + }, + { + name: 'LINKEDIN', + value: 'linkedin', + }, + { + name: 'FACEBOOK', + value: 'facebook', + }, + { + name: 'XING', + value: 'xing', + }, + { + name: 'FEED', + value: 'feed', + }, + { + name: 'GOOGLE_PLUS', + value: 'googlePlus', + }, + { + name: 'FLICKR', + value: 'flickr', + }, + { + name: 'GITHUB', + value: 'github', + }, + { + name: 'YOUTUBE', + value: 'youtube', + }, + ] + }, + { + displayName: 'URL', + name: 'url', + type: 'string', + required: true, + default: '', + placeholder: '', + description: 'Website URL', + } + ] + }, - ] - }, - { - displayName: 'Phone', - name: 'phone', - type: 'string', - required: false, - default: '', - placeholder: 'Company phone', - description: 'Company phone.', - }, - { - displayName: 'Custom Properties', - name: 'customProperties', - type: 'fixedCollection', - required: false, - description: 'Custom Properties', - typeOptions: { - multipleValues: true, + ] }, - options: [ - { - displayName: 'Property', - name: 'customProperty', - values: [ - { - displayName: 'Name', - name: 'name', - type: 'string', - required: true, - default: "", - placeholder: '', - description: 'Property name.' - }, - { - displayName: 'Sub Type', - name: 'subtype', - type: 'string', - required: false, - default: "", - placeholder: '', - description: 'Property sub type.', - }, - { - displayName: 'Value', - name: 'value', - type: 'string', - required: false, - default: "", - placeholder: '', - description: 'Property value.', - } - ] + { + displayName: 'Phone', + name: 'phone', + type: 'string', + required: false, + default: '', + placeholder: 'Company phone', + description: 'Company phone.', + }, + { + displayName: 'Custom Properties', + name: 'customProperties', + type: 'fixedCollection', + required: false, + description: 'Custom Properties', + typeOptions: { + multipleValues: true, }, + options: [ + { + displayName: 'Property', + name: 'customProperty', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + default: '', + placeholder: '', + description: 'Property name.' + }, + { + displayName: 'Sub Type', + name: 'subtype', + type: 'string', + required: false, + default: '', + placeholder: '', + description: 'Property sub type.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + required: false, + default: '', + placeholder: '', + description: 'Property value.', + } + ] + }, - ] - }, - ], -}, + ] + }, + ], + }, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts index 96d0dfd3d0..1ee01634a7 100644 --- a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts @@ -1,6 +1,6 @@ import { INodeProperties, - } from 'n8n-workflow'; +} from 'n8n-workflow'; export const contactOperations = [ { @@ -110,484 +110,484 @@ export const contactFields = [ } }, -/* -------------------------------------------------------------------------- */ -/* contact:create */ -/* -------------------------------------------------------------------------- */ + /* -------------------------------------------------------------------------- */ + /* contact:create */ + /* -------------------------------------------------------------------------- */ -{ - displayName: 'JSON Parameters', - name: 'jsonParameters', - type: 'boolean', - default: false, - description: '', - displayOptions: { - show: { - resource: [ - 'contact', - ], - operation: [ - 'create', - ], + { + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'create', + ], + }, }, }, -}, -{ - displayName: ' Additional Fields', - name: 'additionalFieldsJson', - type: 'json', - typeOptions: { - alwaysOpenEditWindow: true, - }, - default: '', - displayOptions: { - show: { - resource: [ - 'contact', - ], - operation: [ - 'create', - ], - jsonParameters: [ - true, - ], + { + displayName: ' Additional Fields', + name: 'additionalFieldsJson', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, }, + default: '', + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'create', + ], + jsonParameters: [ + true, + ], + }, + }, + + description: `Object of values to set as described here.`, }, - - description: `Object of values to set as described here.`, -}, -{ - displayName: 'Additional Fields', - name: 'additionalFields', - type: 'collection', - placeholder: 'Add Field', - default: {}, - displayOptions: { - show: { - resource: [ - 'contact', - ], - operation: [ - 'create', - ], - jsonParameters: [ - false, - ], + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'create', + ], + jsonParameters: [ + false, + ], + }, }, + options: [ + { + displayName: 'Star Value', + name: 'starValue', + type: 'options', + default: '', + required: false, + description: 'Rating of contact (Max value 5). This is not applicable for companies.', + options: [ + { + name: '0', + value: 0 + }, + { + name: '1', + value: 1 + }, + { + name: '2', + value: 2 + }, + { + name: '3', + value: 3 + }, + { + name: '4', + value: 4 + }, + { + name: '5', + value: 5 + }, + ] + }, + { + displayName: 'Lead Score', + name: 'leadScore', + type: 'number', + default: '', + description: 'Score of contact. This is not applicable for companies.', + required: false, + typeOptions: { + minValue: 0 + } + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + typeOptions: { + multipleValues: true, + multipleValueButtonText: 'Add Tag', + }, + default: [], + placeholder: 'Tag', + description: 'Unique identifiers added to contact, for easy management of contacts. This is not applicable for companies.', + }, + { + displayName: 'First Name', + name: 'firstName', + type: 'string', + required: false, + default: "", + placeholder: 'First Name', + description: 'Contact first name.', + }, + { + displayName: 'Last Name', + name: 'lastName', + type: 'string', + required: false, + default: "", + placeholder: 'Last Name', + description: 'Contact last name.', + }, + { + displayName: 'Company', + name: 'company', + type: 'string', + required: false, + default: "", + placeholder: 'Company', + description: 'Company Name.', + }, + { + displayName: 'Title', + name: 'title', + type: 'string', + required: false, + default: "", + placeholder: 'Title', + description: 'Professional title.', + }, + { + displayName: 'Email', + name: 'emailOptions', + type: 'fixedCollection', + required: false, + description: 'Contact email.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Email Properties', + name: 'emailProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: "", + placeholder: '', + description: 'Type of Email', + options: [ + { + name: 'Work', + value: 'work' + }, + { + name: 'Personal', + value: 'personal' + } + ] + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Email', + } + ] + }, + + ] + }, + { + displayName: 'Address', + name: 'addressOptions', + type: 'fixedCollection', + required: false, + description: 'Contacts address.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Address Properties', + name: 'addressProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: "", + placeholder: '', + description: 'Type of address.', + options: [ + { + name: 'Home', + value: 'home' + }, + { + name: 'Postal', + value: 'postal' + } + , + { + name: 'Office', + value: 'office' + } + ] + }, + { + displayName: 'Address', + name: 'address', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Full address.', + } + ] + }, + + ] + }, + { + displayName: 'Website', + name: 'websiteOptions', + type: 'fixedCollection', + required: false, + description: 'Contacts websites.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Website properties.', + name: 'websiteProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: "", + placeholder: '', + description: 'Type of website.', + options: [ + { + name: 'URL', + value: 'url', + }, + { + name: 'SKYPE', + value: 'skype', + }, + { + name: 'TWITTER', + value: 'twitter', + }, + { + name: 'LINKEDIN', + value: 'linkedin', + }, + { + name: 'FACEBOOK', + value: 'facebook', + }, + { + name: 'XING', + value: 'xing', + }, + { + name: 'FEED', + value: 'feed', + }, + { + name: 'GOOGLE_PLUS', + value: 'googlePlus', + }, + { + name: 'FLICKR', + value: 'flickr', + }, + { + name: 'GITHUB', + value: 'github', + }, + { + name: 'YOUTUBE', + value: 'youtube', + }, + ] + }, + { + displayName: 'URL', + name: 'url', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Website URL', + } + ] + }, + + ] + }, + { + displayName: 'Phone', + name: 'phoneOptions', + type: 'fixedCollection', + required: false, + description: 'Contacts phone.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Phone properties', + name: 'phoneProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: "", + placeholder: '', + description: 'Type of phone number.', + options: [ + { + name: 'Home', + value: 'home' + }, + { + name: 'Work', + value: 'work' + } + , + { + name: 'Mobile', + value: 'mobile' + }, + { + name: 'Main', + value: 'main' + }, + { + name: 'Home Fax', + value: 'homeFax' + }, + { + name: 'Work Fax', + value: 'workFax' + }, + { + name: 'Other', + value: 'other' + }, + ] + }, + { + displayName: 'Number', + name: 'number', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Phone number.', + } + ] + }, + + ] + }, + { + displayName: 'Custom Properties', + name: 'customProperties', + type: 'fixedCollection', + required: false, + description: 'Custom Properties', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Property', + name: 'customProperty', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + default: "", + placeholder: '', + description: 'Property name.' + }, + { + displayName: 'Sub Type', + name: 'subtype', + type: 'string', + required: false, + default: "", + placeholder: '', + description: 'Property sub type.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + required: false, + default: "", + placeholder: '', + description: 'Property value.', + } + ] + }, + + ] + }, + ], }, - options: [ - { - displayName: 'Star Value', - name: 'starValue', - type: 'options', - default: '', - required: false, - description: 'Rating of contact (Max value 5). This is not applicable for companies.', - options: [ - { - name: '0', - value: 0 - }, - { - name: '1', - value: 1 - }, - { - name: '2', - value: 2 - }, - { - name: '3', - value: 3 - }, - { - name: '4', - value: 4 - }, - { - name: '5', - value: 5 - }, - ] - }, - { - displayName: 'Lead Score', - name: 'leadScore', - type: 'number', - default: '', - description: 'Score of contact. This is not applicable for companies.', - required: false, - typeOptions: { - minValue: 0 - } - }, - { - displayName: 'Tags', - name: 'tags', - type: 'string', - typeOptions: { - multipleValues: true, - multipleValueButtonText: 'Add Tag', + /* -------------------------------------------------------------------------- */ + /* contact:delete */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Contact ID', + name: 'contactId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'delete', + ], }, - default: [], - placeholder: 'Tag', - description: 'Unique identifiers added to contact, for easy management of contacts. This is not applicable for companies.', - }, - { - displayName: 'First Name', - name: 'firstName', - type: 'string', - required: false, - default: "", - placeholder: 'First Name', - description: 'Contact first name.', - }, - { - displayName: 'Last Name', - name: 'lastName', - type: 'string', - required: false, - default: "", - placeholder: 'Last Name', - description: 'Contact last name.', - }, - { - displayName: 'Company', - name: 'company', - type: 'string', - required: false, - default: "", - placeholder: 'Company', - description: 'Company Name.', - }, - { - displayName: 'Title', - name: 'title', - type: 'string', - required: false, - default: "", - placeholder: 'Title', - description: 'Professional title.', - }, - { - displayName: 'Email', - name: 'emailOptions', - type: 'fixedCollection', - required: false, - description: 'Contact email.', - typeOptions: { - multipleValues: true, - }, - options: [ - { - displayName: 'Email Properties', - name: 'emailProperties', - values: [ - { - displayName: 'Type', - name: 'subtype', - type: 'options', - required: true, - default: "", - placeholder: '', - description: 'Type of Email', - options: [ - { - name: 'Work', - value: 'work' - }, - { - name: 'Personal', - value: 'personal' - } - ] - }, - { - displayName: 'Email', - name: 'email', - type: 'string', - required: true, - default: "", - placeholder: '', - description: 'Email', - } - ] - }, - - ] - }, - { - displayName: 'Address', - name: 'addressOptions', - type: 'fixedCollection', - required: false, - description: 'Contacts address.', - typeOptions: { - multipleValues: true, - }, - options: [ - { - displayName: 'Address Properties', - name: 'addressProperties', - values: [ - { - displayName: 'Type', - name: 'subtype', - type: 'options', - required: true, - default: "", - placeholder: '', - description: 'Type of address.', - options: [ - { - name: 'Home', - value: 'home' - }, - { - name: 'Postal', - value: 'postal' - } - , - { - name: 'Office', - value: 'office' - } - ] - }, - { - displayName: 'Address', - name: 'address', - type: 'string', - required: true, - default: "", - placeholder: '', - description: 'Full address.', - } - ] - }, - - ] - }, - { - displayName: 'Website', - name: 'websiteOptions', - type: 'fixedCollection', - required: false, - description: 'Contacts websites.', - typeOptions: { - multipleValues: true, - }, - options: [ - { - displayName: 'Website properties.', - name: 'websiteProperties', - values: [ - { - displayName: 'Type', - name: 'subtype', - type: 'options', - required: true, - default: "", - placeholder: '', - description: 'Type of website.', - options: [ - { - name: 'URL', - value: 'url', - }, - { - name: 'SKYPE', - value: 'skype', - }, - { - name: 'TWITTER', - value: 'twitter', - }, - { - name: 'LINKEDIN', - value: 'linkedin', - }, - { - name: 'FACEBOOK', - value: 'facebook', - }, - { - name: 'XING', - value: 'xing', - }, - { - name: 'FEED', - value: 'feed', - }, - { - name: 'GOOGLE_PLUS', - value: 'googlePlus', - }, - { - name: 'FLICKR', - value: 'flickr', - }, - { - name: 'GITHUB', - value: 'github', - }, - { - name: 'YOUTUBE', - value: 'youtube', - }, - ] - }, - { - displayName: 'URL', - name: 'url', - type: 'string', - required: true, - default: "", - placeholder: '', - description: 'Website URL', - } - ] - }, - - ] - }, - { - displayName: 'Phone', - name: 'phoneOptions', - type: 'fixedCollection', - required: false, - description: 'Contacts phone.', - typeOptions: { - multipleValues: true, - }, - options: [ - { - displayName: 'Phone properties', - name: 'phoneProperties', - values: [ - { - displayName: 'Type', - name: 'subtype', - type: 'options', - required: true, - default: "", - placeholder: '', - description: 'Type of phone number.', - options: [ - { - name: 'Home', - value: 'home' - }, - { - name: 'Work', - value: 'work' - } - , - { - name: 'Mobile', - value: 'mobile' - }, - { - name: 'Main', - value: 'main' - }, - { - name: 'Home Fax', - value: 'homeFax' - }, - { - name: 'Work Fax', - value: 'workFax' - }, - { - name: 'Other', - value: 'other' - }, - ] - }, - { - displayName: 'Number', - name: 'number', - type: 'string', - required: true, - default: "", - placeholder: '', - description: 'Phone number.', - } - ] - }, - - ] - }, - { - displayName: 'Custom Properties', - name: 'customProperties', - type: 'fixedCollection', - required: false, - description: 'Custom Properties', - typeOptions: { - multipleValues: true, - }, - options: [ - { - displayName: 'Property', - name: 'customProperty', - values: [ - { - displayName: 'Name', - name: 'name', - type: 'string', - required: true, - default: "", - placeholder: '', - description: 'Property name.' - }, - { - displayName: 'Sub Type', - name: 'subtype', - type: 'string', - required: false, - default: "", - placeholder: '', - description: 'Property sub type.', - }, - { - displayName: 'Value', - name: 'value', - type: 'string', - required: false, - default: "", - placeholder: '', - description: 'Property value.', - } - ] - }, - - ] - }, - ], -}, -/* -------------------------------------------------------------------------- */ -/* contact:delete */ -/* -------------------------------------------------------------------------- */ -{ - displayName: 'Contact ID', - name: 'contactId', - type: 'string', - required: true, - displayOptions: { - show: { - resource: [ - 'contact', - ], - operation: [ - 'delete', - ], }, + default: '', + description: 'Unique identifier for a particular contact', }, - default: '', - description: 'Unique identifier for a particular contact', -}, /* -------------------------------------------------------------------------- */ /* contact:update */ /* -------------------------------------------------------------------------- */ diff --git a/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts b/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts index 656b95d3ac..373786bafb 100644 --- a/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts +++ b/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts @@ -10,7 +10,7 @@ import { } export interface IContact { - type?: string, + type?: string; star_value?: string; lead_score?: string; tags?: string[]; @@ -18,8 +18,8 @@ import { } export interface IContactUpdate { - id: string, - properties?: IDataObject[], + id: string; + properties?: IDataObject[]; star_value?: string; lead_score?: string; tags?: string[]; diff --git a/packages/nodes-base/nodes/AgileCrm/DealInterface.ts b/packages/nodes-base/nodes/AgileCrm/DealInterface.ts index 797fddcb7a..930831a870 100644 --- a/packages/nodes-base/nodes/AgileCrm/DealInterface.ts +++ b/packages/nodes-base/nodes/AgileCrm/DealInterface.ts @@ -1,19 +1,15 @@ -import { - IDataObject, - } from 'n8n-workflow'; - - export interface IDealCustomProperty { +export interface IDealCustomProperty { name: string; value: string; } export interface IDeal { - id?: number, - expected_value?: number, - probability?: number, - name?: string, - close_date?: number, - milestone?: string, - contactIds?: string[], - customData?: IDealCustomProperty[] + id?: number; + expected_value?: number; + probability?: number; + name?: string; + close_date?: number; + milestone?: string; + contactIds?: string[]; + customData?: IDealCustomProperty[]; } \ No newline at end of file diff --git a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts index 897a17a3f0..a48c4e6860 100644 --- a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts +++ b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts @@ -1,5 +1,5 @@ import { - OptionsWithUri, + OptionsWithUri } from 'request'; import { @@ -12,7 +12,7 @@ import { import { IDataObject, } from 'n8n-workflow'; -import { IContactUpdate } from './ContactInterface'; +import { IContactUpdate, IProperty } from './ContactInterface'; export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: any = {}, query: IDataObject = {}, uri?: string): Promise { @@ -51,7 +51,7 @@ export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunction } -export async function agileCrmApiRequestUpdate(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string = 'PUT', endpoint?: string, body: any = {}, query: IDataObject = {}, uri?: string): Promise { +export async function agileCrmApiRequestUpdate(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method = 'PUT', endpoint?: string, body: any = {}, query: IDataObject = {}, uri?: string): Promise { const baseUri = 'https://n8nio.agilecrm.com/dev/'; const credentials = this.getCredentials('agileCrmApi'); const options: OptionsWithUri = { @@ -68,9 +68,9 @@ export async function agileCrmApiRequestUpdate(this: IHookFunctions | IExecuteFu json: true }; - let successfulUpdates = []; + const successfulUpdates = []; let lastSuccesfulUpdateReturn : any; - let payload : IContactUpdate = body; + const payload : IContactUpdate = body; try { // Due to API, we must update each property separately @@ -82,7 +82,7 @@ export async function agileCrmApiRequestUpdate(this: IHookFunctions | IExecuteFu // Iterate trough properties and show them as individial updates instead of only vague "properties" payload.properties?.map((property : any) => { successfulUpdates.push(`${property.name} `); - }) + }); delete options.body.properties; } @@ -102,7 +102,7 @@ export async function agileCrmApiRequestUpdate(this: IHookFunctions | IExecuteFu payload.tags?.map((tag : string) => { successfulUpdates.push(`(Tag) ${tag} `); - }) + }); delete options.body.tags; } From 0f86c59bf21add4bcb792be6d24ead9e996340e7 Mon Sep 17 00:00:00 2001 From: Rupenieks Date: Wed, 6 May 2020 11:58:46 +0200 Subject: [PATCH 12/15] removed useless keys --- .../nodes/AgileCrm/CompanyDescription.ts | 60 ++++++++-------- .../nodes/AgileCrm/ContactDescription.ts | 72 ++++++------------- .../nodes/AgileCrm/DealDescription.ts | 22 +++--- 3 files changed, 64 insertions(+), 90 deletions(-) diff --git a/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts b/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts index 066b33260c..8dd417bfe1 100644 --- a/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts @@ -181,7 +181,7 @@ export const companyFields = [ name: 'starValue', type: 'options', default: '', - required: false, + description: 'Rating of company (Max value 5). This is not applicable for companies.', options: [ { @@ -216,7 +216,7 @@ export const companyFields = [ type: 'number', default: '', description: 'Score of company. This is not applicable for companies.', - required: false, + typeOptions: { minValue: 0 } @@ -237,7 +237,7 @@ export const companyFields = [ displayName: 'Name', name: 'name', type: 'string', - required: false, + default: '', placeholder: 'Company name', description: 'Company name.', @@ -246,7 +246,7 @@ export const companyFields = [ displayName: 'Email', name: 'email', type: 'string', - required: false, + default: '', placeholder: 'Company email', description: 'Company email.', @@ -255,7 +255,7 @@ export const companyFields = [ displayName: 'Address', name: 'email', type: 'string', - required: false, + default: '', placeholder: 'Company address', description: 'Company address.', @@ -264,7 +264,7 @@ export const companyFields = [ displayName: 'Website', name: 'websiteOptions', type: 'fixedCollection', - required: false, + description: 'companys websites.', typeOptions: { multipleValues: true, @@ -280,7 +280,7 @@ export const companyFields = [ type: 'options', required: true, default: '', - placeholder: '', + description: 'Type of website.', options: [ { @@ -335,7 +335,7 @@ export const companyFields = [ type: 'string', required: true, default: '', - placeholder: '', + description: 'Website URL', } ] @@ -347,7 +347,7 @@ export const companyFields = [ displayName: 'Phone', name: 'phone', type: 'string', - required: false, + default: '', placeholder: 'Company phone', description: 'Company phone.', @@ -356,7 +356,7 @@ export const companyFields = [ displayName: 'Custom Properties', name: 'customProperties', type: 'fixedCollection', - required: false, + description: 'Custom Properties', typeOptions: { multipleValues: true, @@ -372,25 +372,25 @@ export const companyFields = [ type: 'string', required: true, default: '', - placeholder: '', + description: 'Property name.' }, { displayName: 'Sub Type', name: 'subtype', type: 'string', - required: false, + default: '', - placeholder: '', + description: 'Property sub type.', }, { displayName: 'Value', name: 'value', type: 'string', - required: false, + default: '', - placeholder: '', + description: 'Property value.', } ] @@ -509,7 +509,7 @@ export const companyFields = [ name: 'starValue', type: 'options', default: '', - required: false, + description: 'Rating of company (Max value 5). This is not applicable for companies.', options: [ { @@ -544,7 +544,7 @@ export const companyFields = [ type: 'number', default: '', description: 'Score of company. This is not applicable for companies.', - required: false, + typeOptions: { minValue: 0 } @@ -565,7 +565,7 @@ export const companyFields = [ displayName: 'Name', name: 'name', type: 'string', - required: false, + default: '', placeholder: 'Company name', description: 'Company name.', @@ -574,7 +574,7 @@ export const companyFields = [ displayName: 'Email', name: 'email', type: 'string', - required: false, + default: '', placeholder: 'Company email', description: 'Company email.', @@ -583,7 +583,7 @@ export const companyFields = [ displayName: 'Address', name: 'email', type: 'string', - required: false, + default: '', placeholder: 'Company address', description: 'Company address.', @@ -592,7 +592,7 @@ export const companyFields = [ displayName: 'Website', name: 'websiteOptions', type: 'fixedCollection', - required: false, + description: 'companys websites.', typeOptions: { multipleValues: true, @@ -608,7 +608,7 @@ export const companyFields = [ type: 'options', required: true, default: '', - placeholder: '', + description: 'Type of website.', options: [ { @@ -663,7 +663,7 @@ export const companyFields = [ type: 'string', required: true, default: '', - placeholder: '', + description: 'Website URL', } ] @@ -675,7 +675,7 @@ export const companyFields = [ displayName: 'Phone', name: 'phone', type: 'string', - required: false, + default: '', placeholder: 'Company phone', description: 'Company phone.', @@ -684,7 +684,7 @@ export const companyFields = [ displayName: 'Custom Properties', name: 'customProperties', type: 'fixedCollection', - required: false, + description: 'Custom Properties', typeOptions: { multipleValues: true, @@ -700,25 +700,25 @@ export const companyFields = [ type: 'string', required: true, default: '', - placeholder: '', + description: 'Property name.' }, { displayName: 'Sub Type', name: 'subtype', type: 'string', - required: false, + default: '', - placeholder: '', + description: 'Property sub type.', }, { displayName: 'Value', name: 'value', type: 'string', - required: false, + default: '', - placeholder: '', + description: 'Property value.', } ] diff --git a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts index 1ee01634a7..fe4a811b88 100644 --- a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts @@ -181,7 +181,6 @@ export const contactFields = [ name: 'starValue', type: 'options', default: '', - required: false, description: 'Rating of contact (Max value 5). This is not applicable for companies.', options: [ { @@ -216,7 +215,6 @@ export const contactFields = [ type: 'number', default: '', description: 'Score of contact. This is not applicable for companies.', - required: false, typeOptions: { minValue: 0 } @@ -237,7 +235,6 @@ export const contactFields = [ displayName: 'First Name', name: 'firstName', type: 'string', - required: false, default: "", placeholder: 'First Name', description: 'Contact first name.', @@ -246,7 +243,6 @@ export const contactFields = [ displayName: 'Last Name', name: 'lastName', type: 'string', - required: false, default: "", placeholder: 'Last Name', description: 'Contact last name.', @@ -255,7 +251,6 @@ export const contactFields = [ displayName: 'Company', name: 'company', type: 'string', - required: false, default: "", placeholder: 'Company', description: 'Company Name.', @@ -264,7 +259,6 @@ export const contactFields = [ displayName: 'Title', name: 'title', type: 'string', - required: false, default: "", placeholder: 'Title', description: 'Professional title.', @@ -273,7 +267,6 @@ export const contactFields = [ displayName: 'Email', name: 'emailOptions', type: 'fixedCollection', - required: false, description: 'Contact email.', typeOptions: { multipleValues: true, @@ -289,7 +282,7 @@ export const contactFields = [ type: 'options', required: true, default: "", - placeholder: '', + description: 'Type of Email', options: [ { @@ -308,7 +301,7 @@ export const contactFields = [ type: 'string', required: true, default: "", - placeholder: '', + description: 'Email', } ] @@ -320,7 +313,6 @@ export const contactFields = [ displayName: 'Address', name: 'addressOptions', type: 'fixedCollection', - required: false, description: 'Contacts address.', typeOptions: { multipleValues: true, @@ -336,7 +328,7 @@ export const contactFields = [ type: 'options', required: true, default: "", - placeholder: '', + description: 'Type of address.', options: [ { @@ -360,7 +352,7 @@ export const contactFields = [ type: 'string', required: true, default: "", - placeholder: '', + description: 'Full address.', } ] @@ -372,7 +364,6 @@ export const contactFields = [ displayName: 'Website', name: 'websiteOptions', type: 'fixedCollection', - required: false, description: 'Contacts websites.', typeOptions: { multipleValues: true, @@ -388,7 +379,7 @@ export const contactFields = [ type: 'options', required: true, default: "", - placeholder: '', + description: 'Type of website.', options: [ { @@ -443,7 +434,7 @@ export const contactFields = [ type: 'string', required: true, default: "", - placeholder: '', + description: 'Website URL', } ] @@ -455,7 +446,6 @@ export const contactFields = [ displayName: 'Phone', name: 'phoneOptions', type: 'fixedCollection', - required: false, description: 'Contacts phone.', typeOptions: { multipleValues: true, @@ -471,7 +461,7 @@ export const contactFields = [ type: 'options', required: true, default: "", - placeholder: '', + description: 'Type of phone number.', options: [ { @@ -511,7 +501,7 @@ export const contactFields = [ type: 'string', required: true, default: "", - placeholder: '', + description: 'Phone number.', } ] @@ -523,7 +513,6 @@ export const contactFields = [ displayName: 'Custom Properties', name: 'customProperties', type: 'fixedCollection', - required: false, description: 'Custom Properties', typeOptions: { multipleValues: true, @@ -539,25 +528,23 @@ export const contactFields = [ type: 'string', required: true, default: "", - placeholder: '', + description: 'Property name.' }, { displayName: 'Sub Type', name: 'subtype', type: 'string', - required: false, default: "", - placeholder: '', + description: 'Property sub type.', }, { displayName: 'Value', name: 'value', type: 'string', - required: false, default: "", - placeholder: '', + description: 'Property value.', } ] @@ -586,7 +573,7 @@ export const contactFields = [ }, }, default: '', - description: 'Unique identifier for a particular contact', + description: 'Id of contact to delete.', }, /* -------------------------------------------------------------------------- */ /* contact:update */ @@ -675,7 +662,6 @@ export const contactFields = [ name: 'starValue', type: 'options', default: '', - required: false, description: 'Rating of contact (Max value 5). This is not applicable for companies.', options: [ { @@ -710,7 +696,6 @@ export const contactFields = [ type: 'number', default: '', description: 'Score of contact. This is not applicable for companies.', - required: false, typeOptions: { minValue: 0 } @@ -731,7 +716,6 @@ export const contactFields = [ displayName: 'First Name', name: 'firstName', type: 'string', - required: false, default: "", placeholder: 'First Name', description: 'Contact first name.', @@ -740,7 +724,6 @@ export const contactFields = [ displayName: 'Last Name', name: 'lastName', type: 'string', - required: false, default: "", placeholder: 'Last Name', description: 'Contact last name.', @@ -749,7 +732,6 @@ export const contactFields = [ displayName: 'Company', name: 'company', type: 'string', - required: false, default: "", placeholder: 'Company', description: 'Company Name.', @@ -758,7 +740,6 @@ export const contactFields = [ displayName: 'Title', name: 'title', type: 'string', - required: false, default: "", placeholder: 'Title', description: 'Professional title.', @@ -767,7 +748,6 @@ export const contactFields = [ displayName: 'Email', name: 'emailOptions', type: 'fixedCollection', - required: false, description: 'Contact email.', typeOptions: { multipleValues: true, @@ -783,7 +763,7 @@ export const contactFields = [ type: 'options', required: true, default: "", - placeholder: '', + description: 'Type of Email', options: [ { @@ -802,7 +782,7 @@ export const contactFields = [ type: 'string', required: true, default: "", - placeholder: '', + description: 'Email', } ] @@ -814,7 +794,6 @@ export const contactFields = [ displayName: 'Address', name: 'addressOptions', type: 'fixedCollection', - required: false, description: 'Contacts address.', typeOptions: { multipleValues: true, @@ -830,7 +809,7 @@ export const contactFields = [ type: 'options', required: true, default: "", - placeholder: '', + description: 'Type of address.', options: [ { @@ -854,7 +833,7 @@ export const contactFields = [ type: 'string', required: true, default: "", - placeholder: '', + description: 'Full address.', } ] @@ -866,7 +845,6 @@ export const contactFields = [ displayName: 'Website', name: 'websiteOptions', type: 'fixedCollection', - required: false, description: 'Contacts websites.', typeOptions: { multipleValues: true, @@ -882,7 +860,7 @@ export const contactFields = [ type: 'options', required: true, default: "", - placeholder: '', + description: 'Type of website.', options: [ { @@ -937,7 +915,7 @@ export const contactFields = [ type: 'string', required: true, default: "", - placeholder: '', + description: 'Website URL', } ] @@ -949,7 +927,6 @@ export const contactFields = [ displayName: 'Phone', name: 'phoneOptions', type: 'fixedCollection', - required: false, description: 'Contacts phone.', typeOptions: { multipleValues: true, @@ -965,7 +942,7 @@ export const contactFields = [ type: 'options', required: true, default: "", - placeholder: '', + description: 'Type of phone number.', options: [ { @@ -1005,7 +982,7 @@ export const contactFields = [ type: 'string', required: true, default: "", - placeholder: '', + description: 'Phone number.', } ] @@ -1017,7 +994,6 @@ export const contactFields = [ displayName: 'Custom Properties', name: 'customProperties', type: 'fixedCollection', - required: false, description: 'Custom Properties', typeOptions: { multipleValues: true, @@ -1033,25 +1009,23 @@ export const contactFields = [ type: 'string', required: true, default: "", - placeholder: '', + description: 'Property name.' }, { displayName: 'Sub Type', name: 'subtype', type: 'string', - required: false, default: "", - placeholder: '', + description: 'Property sub type.', }, { displayName: 'Value', name: 'value', type: 'string', - required: false, default: "", - placeholder: '', + description: 'Property value.', } ] diff --git a/packages/nodes-base/nodes/AgileCrm/DealDescription.ts b/packages/nodes-base/nodes/AgileCrm/DealDescription.ts index 4b947bda62..f95cb02f05 100644 --- a/packages/nodes-base/nodes/AgileCrm/DealDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/DealDescription.ts @@ -303,7 +303,7 @@ export const dealFields = [ displayName: 'Custom Data', name: 'customData', type: 'fixedCollection', - required: false, + description: 'Custom Data', typeOptions: { multipleValues: true, @@ -319,16 +319,16 @@ export const dealFields = [ type: 'string', required: true, default: "", - placeholder: '', + description: 'Property name.' }, { displayName: 'Value', name: 'value', type: 'string', - required: false, + default: "", - placeholder: '', + description: 'Property value.', } ] @@ -448,7 +448,7 @@ export const dealFields = [ displayName: 'Expected Value', name: 'expectedValue', type: 'number', - required: false, + typeOptions: { minValue: 0, maxValue: 10000 @@ -460,7 +460,7 @@ export const dealFields = [ displayName: 'Probability', name: 'probability', type: 'number', - required: false, + typeOptions: { minValue: 0, maxValue: 100 @@ -472,7 +472,7 @@ export const dealFields = [ displayName: 'Name', name: 'name', type: 'string', - required: false, + default: '', description: 'Name of deal.', }, @@ -492,7 +492,7 @@ export const dealFields = [ displayName: 'Custom Data', name: 'customData', type: 'fixedCollection', - required: false, + description: 'Custom Data', typeOptions: { multipleValues: true, @@ -508,16 +508,16 @@ export const dealFields = [ type: 'string', required: true, default: "", - placeholder: '', + description: 'Property name.' }, { displayName: 'Value', name: 'value', type: 'string', - required: false, + default: "", - placeholder: '', + description: 'Property value.', } ] From 4e35a375acf7ace2911d68260968f8406c7309b0 Mon Sep 17 00:00:00 2001 From: Rupenieks Date: Wed, 6 May 2020 12:19:22 +0200 Subject: [PATCH 13/15] removed eslint file, removed empty lines --- .eslintrc.json | 50 ------------------- package.json | 3 +- .../nodes/AgileCrm/CompanyDescription.ts | 26 ---------- .../nodes/AgileCrm/ContactDescription.ts | 18 ------- .../nodes/AgileCrm/DealDescription.ts | 10 ---- .../nodes/AgileCrm/GenericFunctions.ts | 2 +- 6 files changed, 3 insertions(+), 106 deletions(-) delete mode 100644 .eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index cce72ec974..0000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "env": { - "browser": true, - "es6": true - }, - "extends": [ - "eslint:recommended", - "plugin:vue/essential", - "tslint-eslint-rules" - ], - "globals": { - "Atomics": "readonly", - "SharedArrayBuffer": "readonly" - }, - "parserOptions": { - "ecmaVersion": 2018, - "parser": "@typescript-eslint/parser", - "sourceType": "module" - }, - "plugins": [ - "vue", - "@typescript-eslint" - ], - "parser": "@typescript-eslint/parser", - "rules": { - "indent": [ - "error", - "tab" - ], - "linebreak-style": [ - "error", - "unix" - ], - "quotes": [ - "error", - "single" - ], - "semi": [ - "error", - "always" - ], - "sort-imports": ["error", { - "ignoreCase": false, - "ignoreMemberSort": false, - "memberSyntaxSortOrder": ["none", "all", "multiple", "single"] - }], - "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": ["error"] - } -} \ No newline at end of file diff --git a/package.json b/package.json index 0fd1747984..3b96e2de5d 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "postcss": {}, "dependencies": { "@typescript-eslint/parser": "^2.31.0", - "tslint-eslint-rules": "^5.4.0" + "tslint-eslint-rules": "^5.4.0", + "typescript-tslint-plugin": "^0.5.5" } } diff --git a/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts b/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts index 8dd417bfe1..08a7fa1df9 100644 --- a/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts @@ -1,7 +1,6 @@ import { INodeProperties, } from 'n8n-workflow'; - export const companyOperations = [ { displayName: 'Operation', @@ -45,7 +44,6 @@ export const companyOperations = [ description: 'The operation to perform.', }, ] as INodeProperties[]; - export const companyFields = [ /* -------------------------------------------------------------------------- */ /* company:get */ @@ -69,7 +67,6 @@ export const companyFields = [ description: 'Unique identifier for a particular company', }, - /* -------------------------------------------------------------------------- */ /* company:get all */ /* -------------------------------------------------------------------------- */ @@ -109,11 +106,9 @@ export const companyFields = [ }, } }, - /* -------------------------------------------------------------------------- */ /* company:create */ /* -------------------------------------------------------------------------- */ - { displayName: 'JSON Parameters', name: 'jsonParameters', @@ -155,7 +150,6 @@ export const companyFields = [ description: 'Object of values to set as described here.', }, - { displayName: 'Additional Fields', name: 'additionalFields', @@ -181,7 +175,6 @@ export const companyFields = [ name: 'starValue', type: 'options', default: '', - description: 'Rating of company (Max value 5). This is not applicable for companies.', options: [ { @@ -216,7 +209,6 @@ export const companyFields = [ type: 'number', default: '', description: 'Score of company. This is not applicable for companies.', - typeOptions: { minValue: 0 } @@ -237,7 +229,6 @@ export const companyFields = [ displayName: 'Name', name: 'name', type: 'string', - default: '', placeholder: 'Company name', description: 'Company name.', @@ -483,7 +474,6 @@ export const companyFields = [ description: 'Object of values to set as described here.', }, - { displayName: 'Additional Fields', name: 'additionalFields', @@ -509,7 +499,6 @@ export const companyFields = [ name: 'starValue', type: 'options', default: '', - description: 'Rating of company (Max value 5). This is not applicable for companies.', options: [ { @@ -544,7 +533,6 @@ export const companyFields = [ type: 'number', default: '', description: 'Score of company. This is not applicable for companies.', - typeOptions: { minValue: 0 } @@ -565,7 +553,6 @@ export const companyFields = [ displayName: 'Name', name: 'name', type: 'string', - default: '', placeholder: 'Company name', description: 'Company name.', @@ -574,7 +561,6 @@ export const companyFields = [ displayName: 'Email', name: 'email', type: 'string', - default: '', placeholder: 'Company email', description: 'Company email.', @@ -583,7 +569,6 @@ export const companyFields = [ displayName: 'Address', name: 'email', type: 'string', - default: '', placeholder: 'Company address', description: 'Company address.', @@ -592,7 +577,6 @@ export const companyFields = [ displayName: 'Website', name: 'websiteOptions', type: 'fixedCollection', - description: 'companys websites.', typeOptions: { multipleValues: true, @@ -608,7 +592,6 @@ export const companyFields = [ type: 'options', required: true, default: '', - description: 'Type of website.', options: [ { @@ -663,7 +646,6 @@ export const companyFields = [ type: 'string', required: true, default: '', - description: 'Website URL', } ] @@ -675,7 +657,6 @@ export const companyFields = [ displayName: 'Phone', name: 'phone', type: 'string', - default: '', placeholder: 'Company phone', description: 'Company phone.', @@ -684,7 +665,6 @@ export const companyFields = [ displayName: 'Custom Properties', name: 'customProperties', type: 'fixedCollection', - description: 'Custom Properties', typeOptions: { multipleValues: true, @@ -700,25 +680,20 @@ export const companyFields = [ type: 'string', required: true, default: '', - description: 'Property name.' }, { displayName: 'Sub Type', name: 'subtype', type: 'string', - default: '', - description: 'Property sub type.', }, { displayName: 'Value', name: 'value', type: 'string', - default: '', - description: 'Property value.', } ] @@ -728,5 +703,4 @@ export const companyFields = [ }, ], }, - ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts index fe4a811b88..fd7d652867 100644 --- a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts @@ -282,7 +282,6 @@ export const contactFields = [ type: 'options', required: true, default: "", - description: 'Type of Email', options: [ { @@ -301,7 +300,6 @@ export const contactFields = [ type: 'string', required: true, default: "", - description: 'Email', } ] @@ -352,7 +350,6 @@ export const contactFields = [ type: 'string', required: true, default: "", - description: 'Full address.', } ] @@ -379,7 +376,6 @@ export const contactFields = [ type: 'options', required: true, default: "", - description: 'Type of website.', options: [ { @@ -434,7 +430,6 @@ export const contactFields = [ type: 'string', required: true, default: "", - description: 'Website URL', } ] @@ -461,7 +456,6 @@ export const contactFields = [ type: 'options', required: true, default: "", - description: 'Type of phone number.', options: [ { @@ -501,7 +495,6 @@ export const contactFields = [ type: 'string', required: true, default: "", - description: 'Phone number.', } ] @@ -528,7 +521,6 @@ export const contactFields = [ type: 'string', required: true, default: "", - description: 'Property name.' }, { @@ -536,7 +528,6 @@ export const contactFields = [ name: 'subtype', type: 'string', default: "", - description: 'Property sub type.', }, { @@ -544,7 +535,6 @@ export const contactFields = [ name: 'value', type: 'string', default: "", - description: 'Property value.', } ] @@ -782,7 +772,6 @@ export const contactFields = [ type: 'string', required: true, default: "", - description: 'Email', } ] @@ -833,7 +822,6 @@ export const contactFields = [ type: 'string', required: true, default: "", - description: 'Full address.', } ] @@ -915,7 +903,6 @@ export const contactFields = [ type: 'string', required: true, default: "", - description: 'Website URL', } ] @@ -942,7 +929,6 @@ export const contactFields = [ type: 'options', required: true, default: "", - description: 'Type of phone number.', options: [ { @@ -982,7 +968,6 @@ export const contactFields = [ type: 'string', required: true, default: "", - description: 'Phone number.', } ] @@ -1009,7 +994,6 @@ export const contactFields = [ type: 'string', required: true, default: "", - description: 'Property name.' }, { @@ -1017,7 +1001,6 @@ export const contactFields = [ name: 'subtype', type: 'string', default: "", - description: 'Property sub type.', }, { @@ -1025,7 +1008,6 @@ export const contactFields = [ name: 'value', type: 'string', default: "", - description: 'Property value.', } ] diff --git a/packages/nodes-base/nodes/AgileCrm/DealDescription.ts b/packages/nodes-base/nodes/AgileCrm/DealDescription.ts index f95cb02f05..2ee7e9d1a2 100644 --- a/packages/nodes-base/nodes/AgileCrm/DealDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/DealDescription.ts @@ -319,16 +319,13 @@ export const dealFields = [ type: 'string', required: true, default: "", - description: 'Property name.' }, { displayName: 'Value', name: 'value', type: 'string', - default: "", - description: 'Property value.', } ] @@ -448,7 +445,6 @@ export const dealFields = [ displayName: 'Expected Value', name: 'expectedValue', type: 'number', - typeOptions: { minValue: 0, maxValue: 10000 @@ -460,7 +456,6 @@ export const dealFields = [ displayName: 'Probability', name: 'probability', type: 'number', - typeOptions: { minValue: 0, maxValue: 100 @@ -472,7 +467,6 @@ export const dealFields = [ displayName: 'Name', name: 'name', type: 'string', - default: '', description: 'Name of deal.', }, @@ -492,7 +486,6 @@ export const dealFields = [ displayName: 'Custom Data', name: 'customData', type: 'fixedCollection', - description: 'Custom Data', typeOptions: { multipleValues: true, @@ -508,16 +501,13 @@ export const dealFields = [ type: 'string', required: true, default: "", - description: 'Property name.' }, { displayName: 'Value', name: 'value', type: 'string', - default: "", - description: 'Property value.', } ] diff --git a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts index a48c4e6860..9a762044cd 100644 --- a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts +++ b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts @@ -73,7 +73,7 @@ export async function agileCrmApiRequestUpdate(this: IHookFunctions | IExecuteFu const payload : IContactUpdate = body; try { - // Due to API, we must update each property separately + // Due to API, we must update each property separately. For user it looks like one seamless update if(payload.properties){ options.body.properties = payload.properties; options.uri = baseUri + 'api/contacts/edit-properties'; From f66ed93b0ada3d0a00b14fcd9bf99a8dd76a01af Mon Sep 17 00:00:00 2001 From: Rupenieks Date: Wed, 6 May 2020 13:01:52 +0200 Subject: [PATCH 14/15] Alphabetically sorted options/properties --- .../nodes/AgileCrm/AgileCrm.node.ts | 11 +- .../nodes/AgileCrm/CompanyDescription.ts | 253 +++--- .../nodes/AgileCrm/ContactDescription.ts | 812 +++++++++--------- .../nodes/AgileCrm/DealDescription.ts | 118 +-- 4 files changed, 584 insertions(+), 610 deletions(-) diff --git a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts index be217de2ed..b26316f475 100644 --- a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts +++ b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts @@ -171,9 +171,6 @@ export class AgileCrm implements INodeType { if (additionalFields.starValue) { body.star_value = additionalFields.starValue as string; } - if (additionalFields.leadScore) { - body.lead_score = additionalFields.leadScore as string; - } if (additionalFields.tags) { body.tags = additionalFields.tags as string[]; } @@ -325,15 +322,17 @@ export class AgileCrm implements INodeType { if (additionalFields.starValue) { body.star_value = additionalFields.starValue as string; } - if (additionalFields.leadScore) { - body.lead_score = additionalFields.leadScore as string; - } if (additionalFields.tags) { body.tags = additionalFields.tags as string[]; } // Contact specific properties if(resource === 'contact'){ + + if (additionalFields.leadScore) { + body.lead_score = additionalFields.leadScore as string; + } + if(additionalFields.firstName){ properties.push({ type: 'SYSTEM', diff --git a/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts b/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts index 08a7fa1df9..a3bfaafc3f 100644 --- a/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts @@ -14,6 +14,16 @@ export const companyOperations = [ }, }, options: [ + { + name: 'Create', + value: 'create', + description: 'Create a new company', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a company', + }, { name: 'Get', value: 'get', @@ -24,21 +34,11 @@ export const companyOperations = [ value: 'getAll', description: 'Get all companies', }, - { - name: 'Create', - value: 'create', - description: 'Create a new company', - }, { name: 'Update', value: 'update', description: 'Update company properties', }, - { - name: 'Delete', - value: 'delete', - description: 'Delete a company', - }, ], default: 'get', description: 'The operation to perform.', @@ -170,6 +170,41 @@ export const companyFields = [ }, }, options: [ + { + displayName: 'Address', + name: 'email', + type: 'string', + + default: '', + placeholder: 'Company address', + description: 'Company address.', + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + + default: '', + placeholder: 'Company email', + description: 'Company email.', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + placeholder: 'Company name', + description: 'Company name.', + }, + { + displayName: 'Phone', + name: 'phone', + type: 'string', + + default: '', + placeholder: 'Company phone', + description: 'Company phone.', + }, { displayName: 'Star Value', name: 'starValue', @@ -203,16 +238,6 @@ export const companyFields = [ }, ] }, - { - displayName: 'Lead Score', - name: 'leadScore', - type: 'number', - default: '', - description: 'Score of company. This is not applicable for companies.', - typeOptions: { - minValue: 0 - } - }, { displayName: 'Tags', name: 'tags', @@ -225,38 +250,12 @@ export const companyFields = [ placeholder: 'Tag', description: 'Unique identifiers added to company, for easy management of companys. This is not applicable for companies.', }, - { - displayName: 'Name', - name: 'name', - type: 'string', - default: '', - placeholder: 'Company name', - description: 'Company name.', - }, - { - displayName: 'Email', - name: 'email', - type: 'string', - - default: '', - placeholder: 'Company email', - description: 'Company email.', - }, - { - displayName: 'Address', - name: 'email', - type: 'string', - - default: '', - placeholder: 'Company address', - description: 'Company address.', - }, { displayName: 'Website', name: 'websiteOptions', type: 'fixedCollection', - description: 'companys websites.', + description: 'Companies websites.', typeOptions: { multipleValues: true, }, @@ -271,12 +270,31 @@ export const companyFields = [ type: 'options', required: true, default: '', - description: 'Type of website.', options: [ { - name: 'URL', - value: 'url', + name: 'FACEBOOK', + value: 'facebook', + }, + { + name: 'FEED', + value: 'feed', + }, + { + name: 'FLICKR', + value: 'flickr', + }, + { + name: 'LINKEDIN', + value: 'linkedin', + }, + { + name: 'GITHUB', + value: 'github', + }, + { + name: 'GOOGLE_PLUS', + value: 'googlePlus', }, { name: 'SKYPE', @@ -287,33 +305,13 @@ export const companyFields = [ value: 'twitter', }, { - name: 'LINKEDIN', - value: 'linkedin', - }, - { - name: 'FACEBOOK', - value: 'facebook', + name: 'URL', + value: 'url', }, { name: 'XING', value: 'xing', }, - { - name: 'FEED', - value: 'feed', - }, - { - name: 'GOOGLE_PLUS', - value: 'googlePlus', - }, - { - name: 'FLICKR', - value: 'flickr', - }, - { - name: 'GITHUB', - value: 'github', - }, { name: 'YOUTUBE', value: 'youtube', @@ -334,15 +332,6 @@ export const companyFields = [ ] }, - { - displayName: 'Phone', - name: 'phone', - type: 'string', - - default: '', - placeholder: 'Company phone', - description: 'Company phone.', - }, { displayName: 'Custom Properties', name: 'customProperties', @@ -386,7 +375,6 @@ export const companyFields = [ } ] }, - ] }, ], @@ -410,7 +398,7 @@ export const companyFields = [ }, }, default: '', - description: 'Unique identifier for a particular company', + description: 'ID of company to delete', }, /* -------------------------------------------------------------------------- */ /* company:update */ @@ -494,6 +482,22 @@ export const companyFields = [ }, }, options: [ + { + displayName: 'Address', + name: 'email', + type: 'string', + default: '', + placeholder: 'Company address', + description: 'Company address.', + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + default: '', + placeholder: 'Company email', + description: 'Company email.', + }, { displayName: 'Star Value', name: 'starValue', @@ -527,16 +531,6 @@ export const companyFields = [ }, ] }, - { - displayName: 'Lead Score', - name: 'leadScore', - type: 'number', - default: '', - description: 'Score of company. This is not applicable for companies.', - typeOptions: { - minValue: 0 - } - }, { displayName: 'Tags', name: 'tags', @@ -558,20 +552,12 @@ export const companyFields = [ description: 'Company name.', }, { - displayName: 'Email', - name: 'email', + displayName: 'Phone', + name: 'phone', type: 'string', default: '', - placeholder: 'Company email', - description: 'Company email.', - }, - { - displayName: 'Address', - name: 'email', - type: 'string', - default: '', - placeholder: 'Company address', - description: 'Company address.', + placeholder: 'Company phone', + description: 'Company phone.', }, { displayName: 'Website', @@ -595,8 +581,28 @@ export const companyFields = [ description: 'Type of website.', options: [ { - name: 'URL', - value: 'url', + name: 'FACEBOOK', + value: 'facebook', + }, + { + name: 'FEED', + value: 'feed', + }, + { + name: 'FLICKR', + value: 'flickr', + }, + { + name: 'LINKEDIN', + value: 'linkedin', + }, + { + name: 'GITHUB', + value: 'github', + }, + { + name: 'GOOGLE_PLUS', + value: 'googlePlus', }, { name: 'SKYPE', @@ -607,33 +613,13 @@ export const companyFields = [ value: 'twitter', }, { - name: 'LINKEDIN', - value: 'linkedin', - }, - { - name: 'FACEBOOK', - value: 'facebook', + name: 'URL', + value: 'url', }, { name: 'XING', value: 'xing', }, - { - name: 'FEED', - value: 'feed', - }, - { - name: 'GOOGLE_PLUS', - value: 'googlePlus', - }, - { - name: 'FLICKR', - value: 'flickr', - }, - { - name: 'GITHUB', - value: 'github', - }, { name: 'YOUTUBE', value: 'youtube', @@ -650,17 +636,8 @@ export const companyFields = [ } ] }, - ] }, - { - displayName: 'Phone', - name: 'phone', - type: 'string', - default: '', - placeholder: 'Company phone', - description: 'Company phone.', - }, { displayName: 'Custom Properties', name: 'customProperties', diff --git a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts index fd7d652867..88b38c403d 100644 --- a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts @@ -15,6 +15,16 @@ export const contactOperations = [ }, }, options: [ + { + name: 'Create', + value: 'create', + description: 'Create a new contact', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a contact', + }, { name: 'Get', value: 'get', @@ -25,21 +35,11 @@ export const contactOperations = [ value: 'getAll', description: 'Get all contacts', }, - { - name: 'Create', - value: 'create', - description: 'Create a new contact', - }, { name: 'Update', value: 'update', description: 'Update contact properties', }, - { - name: 'Delete', - value: 'delete', - description: 'Delete a contact', - }, ], default: 'get', description: 'The operation to perform.', @@ -68,28 +68,9 @@ export const contactFields = [ default: '', description: 'Unique identifier for a particular contact', }, - - /* -------------------------------------------------------------------------- */ /* contact:get all */ /* -------------------------------------------------------------------------- */ - { - displayName: 'Return All', - name: 'returnAll', - type: 'boolean', - displayOptions: { - show: { - resource: [ - 'contact', - ], - operation: [ - 'getAll', - ], - }, - }, - default: false, - description: 'If all results should be returned or only up to a given limit.', - }, { displayName: 'Limit', name: 'limit', @@ -109,6 +90,23 @@ export const contactFields = [ }, } }, + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'getAll', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, /* -------------------------------------------------------------------------- */ /* contact:create */ @@ -176,137 +174,6 @@ export const contactFields = [ }, }, options: [ - { - displayName: 'Star Value', - name: 'starValue', - type: 'options', - default: '', - description: 'Rating of contact (Max value 5). This is not applicable for companies.', - options: [ - { - name: '0', - value: 0 - }, - { - name: '1', - value: 1 - }, - { - name: '2', - value: 2 - }, - { - name: '3', - value: 3 - }, - { - name: '4', - value: 4 - }, - { - name: '5', - value: 5 - }, - ] - }, - { - displayName: 'Lead Score', - name: 'leadScore', - type: 'number', - default: '', - description: 'Score of contact. This is not applicable for companies.', - typeOptions: { - minValue: 0 - } - }, - { - displayName: 'Tags', - name: 'tags', - type: 'string', - typeOptions: { - multipleValues: true, - multipleValueButtonText: 'Add Tag', - }, - default: [], - placeholder: 'Tag', - description: 'Unique identifiers added to contact, for easy management of contacts. This is not applicable for companies.', - }, - { - displayName: 'First Name', - name: 'firstName', - type: 'string', - default: "", - placeholder: 'First Name', - description: 'Contact first name.', - }, - { - displayName: 'Last Name', - name: 'lastName', - type: 'string', - default: "", - placeholder: 'Last Name', - description: 'Contact last name.', - }, - { - displayName: 'Company', - name: 'company', - type: 'string', - default: "", - placeholder: 'Company', - description: 'Company Name.', - }, - { - displayName: 'Title', - name: 'title', - type: 'string', - default: "", - placeholder: 'Title', - description: 'Professional title.', - }, - { - displayName: 'Email', - name: 'emailOptions', - type: 'fixedCollection', - description: 'Contact email.', - typeOptions: { - multipleValues: true, - }, - options: [ - { - displayName: 'Email Properties', - name: 'emailProperties', - values: [ - { - displayName: 'Type', - name: 'subtype', - type: 'options', - required: true, - default: "", - description: 'Type of Email', - options: [ - { - name: 'Work', - value: 'work' - }, - { - name: 'Personal', - value: 'personal' - } - ] - }, - { - displayName: 'Email', - name: 'email', - type: 'string', - required: true, - default: "", - description: 'Email', - } - ] - }, - - ] - }, { displayName: 'Address', name: 'addressOptions', @@ -357,6 +224,202 @@ export const contactFields = [ ] }, + { + displayName: 'Company', + name: 'company', + type: 'string', + default: "", + placeholder: 'Company', + description: 'Company Name.', + }, + { + displayName: 'Email', + name: 'emailOptions', + type: 'fixedCollection', + description: 'Contact email.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Email Properties', + name: 'emailProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: "", + description: 'Type of Email', + options: [ + { + name: 'Work', + value: 'work' + }, + { + name: 'Personal', + value: 'personal' + } + ] + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + required: true, + default: "", + description: 'Email', + } + ] + }, + + ] + }, + { + displayName: 'First Name', + name: 'firstName', + type: 'string', + default: "", + placeholder: 'First Name', + description: 'Contact first name.', + }, + { + displayName: 'Last Name', + name: 'lastName', + type: 'string', + default: "", + placeholder: 'Last Name', + description: 'Contact last name.', + }, + { + displayName: 'Lead Score', + name: 'leadScore', + type: 'number', + default: '', + description: 'Lead score of contact', + typeOptions: { + minValue: 0 + } + }, + { + displayName: 'Star Value', + name: 'starValue', + type: 'options', + default: '', + description: 'Rating of contact (Max value 5). This is not applicable for companies.', + options: [ + { + name: '0', + value: 0 + }, + { + name: '1', + value: 1 + }, + { + name: '2', + value: 2 + }, + { + name: '3', + value: 3 + }, + { + name: '4', + value: 4 + }, + { + name: '5', + value: 5 + }, + ] + }, + { + displayName: 'Phone', + name: 'phoneOptions', + type: 'fixedCollection', + description: 'Contacts phone.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Phone properties', + name: 'phoneProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: "", + description: 'Type of phone number.', + options: [ + { + name: 'Home', + value: 'home' + }, + { + name: 'Work', + value: 'work' + } + , + { + name: 'Mobile', + value: 'mobile' + }, + { + name: 'Main', + value: 'main' + }, + { + name: 'Home Fax', + value: 'homeFax' + }, + { + name: 'Work Fax', + value: 'workFax' + }, + { + name: 'Other', + value: 'other' + }, + ] + }, + { + displayName: 'Number', + name: 'number', + type: 'string', + required: true, + default: "", + description: 'Phone number.', + } + ] + }, + + ] + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + typeOptions: { + multipleValues: true, + multipleValueButtonText: 'Add Tag', + }, + default: [], + placeholder: 'Tag', + description: 'Unique identifiers added to contact, for easy management of contacts. This is not applicable for companies.', + }, + { + displayName: 'Title', + name: 'title', + type: 'string', + default: "", + placeholder: 'Title', + description: 'Professional title.', + }, { displayName: 'Website', name: 'websiteOptions', @@ -437,71 +500,6 @@ export const contactFields = [ ] }, - { - displayName: 'Phone', - name: 'phoneOptions', - type: 'fixedCollection', - description: 'Contacts phone.', - typeOptions: { - multipleValues: true, - }, - options: [ - { - displayName: 'Phone properties', - name: 'phoneProperties', - values: [ - { - displayName: 'Type', - name: 'subtype', - type: 'options', - required: true, - default: "", - description: 'Type of phone number.', - options: [ - { - name: 'Home', - value: 'home' - }, - { - name: 'Work', - value: 'work' - } - , - { - name: 'Mobile', - value: 'mobile' - }, - { - name: 'Main', - value: 'main' - }, - { - name: 'Home Fax', - value: 'homeFax' - }, - { - name: 'Work Fax', - value: 'workFax' - }, - { - name: 'Other', - value: 'other' - }, - ] - }, - { - displayName: 'Number', - name: 'number', - type: 'string', - required: true, - default: "", - description: 'Phone number.', - } - ] - }, - - ] - }, { displayName: 'Custom Properties', name: 'customProperties', @@ -647,138 +645,6 @@ export const contactFields = [ }, }, options: [ - { - displayName: 'Star Value', - name: 'starValue', - type: 'options', - default: '', - description: 'Rating of contact (Max value 5). This is not applicable for companies.', - options: [ - { - name: '0', - value: 0 - }, - { - name: '1', - value: 1 - }, - { - name: '2', - value: 2 - }, - { - name: '3', - value: 3 - }, - { - name: '4', - value: 4 - }, - { - name: '5', - value: 5 - }, - ] - }, - { - displayName: 'Lead Score', - name: 'leadScore', - type: 'number', - default: '', - description: 'Score of contact. This is not applicable for companies.', - typeOptions: { - minValue: 0 - } - }, - { - displayName: 'Tags', - name: 'tags', - type: 'string', - typeOptions: { - multipleValues: true, - multipleValueButtonText: 'Add Tag', - }, - default: [], - placeholder: 'Tag', - description: 'Unique identifiers added to contact, for easy management of contacts. This is not applicable for companies.', - }, - { - displayName: 'First Name', - name: 'firstName', - type: 'string', - default: "", - placeholder: 'First Name', - description: 'Contact first name.', - }, - { - displayName: 'Last Name', - name: 'lastName', - type: 'string', - default: "", - placeholder: 'Last Name', - description: 'Contact last name.', - }, - { - displayName: 'Company', - name: 'company', - type: 'string', - default: "", - placeholder: 'Company', - description: 'Company Name.', - }, - { - displayName: 'Title', - name: 'title', - type: 'string', - default: "", - placeholder: 'Title', - description: 'Professional title.', - }, - { - displayName: 'Email', - name: 'emailOptions', - type: 'fixedCollection', - description: 'Contact email.', - typeOptions: { - multipleValues: true, - }, - options: [ - { - displayName: 'Email Properties', - name: 'emailProperties', - values: [ - { - displayName: 'Type', - name: 'subtype', - type: 'options', - required: true, - default: "", - - description: 'Type of Email', - options: [ - { - name: 'Work', - value: 'work' - }, - { - name: 'Personal', - value: 'personal' - } - ] - }, - { - displayName: 'Email', - name: 'email', - type: 'string', - required: true, - default: "", - description: 'Email', - } - ] - }, - - ] - }, { displayName: 'Address', name: 'addressOptions', @@ -830,17 +696,25 @@ export const contactFields = [ ] }, { - displayName: 'Website', - name: 'websiteOptions', + displayName: 'Company', + name: 'company', + type: 'string', + default: "", + placeholder: 'Company', + description: 'Company Name.', + }, + { + displayName: 'Email', + name: 'emailOptions', type: 'fixedCollection', - description: 'Contacts websites.', + description: 'Contact email.', typeOptions: { multipleValues: true, }, options: [ { - displayName: 'Website properties.', - name: 'websiteProperties', + displayName: 'Email Properties', + name: 'emailProperties', values: [ { displayName: 'Type', @@ -848,68 +722,90 @@ export const contactFields = [ type: 'options', required: true, default: "", - - description: 'Type of website.', + description: 'Type of Email', options: [ { - name: 'URL', - value: 'url', + name: 'Work', + value: 'work' }, { - name: 'SKYPE', - value: 'skype', - }, - { - name: 'TWITTER', - value: 'twitter', - }, - { - name: 'LINKEDIN', - value: 'linkedin', - }, - { - name: 'FACEBOOK', - value: 'facebook', - }, - { - name: 'XING', - value: 'xing', - }, - { - name: 'FEED', - value: 'feed', - }, - { - name: 'GOOGLE_PLUS', - value: 'googlePlus', - }, - { - name: 'FLICKR', - value: 'flickr', - }, - { - name: 'GITHUB', - value: 'github', - }, - { - name: 'YOUTUBE', - value: 'youtube', - }, + name: 'Personal', + value: 'personal' + } ] }, { - displayName: 'URL', - name: 'url', + displayName: 'Email', + name: 'email', type: 'string', required: true, default: "", - description: 'Website URL', + description: 'Email', } ] }, ] }, + { + displayName: 'First Name', + name: 'firstName', + type: 'string', + default: "", + placeholder: 'First Name', + description: 'Contact first name.', + }, + { + displayName: 'Last Name', + name: 'lastName', + type: 'string', + default: "", + placeholder: 'Last Name', + description: 'Contact last name.', + }, + { + displayName: 'Lead Score', + name: 'leadScore', + type: 'number', + default: '', + description: 'Lead score of contact', + typeOptions: { + minValue: 0 + } + }, + { + displayName: 'Star Value', + name: 'starValue', + type: 'options', + default: '', + description: 'Rating of contact (Max value 5). This is not applicable for companies.', + options: [ + { + name: '0', + value: 0 + }, + { + name: '1', + value: 1 + }, + { + name: '2', + value: 2 + }, + { + name: '3', + value: 3 + }, + { + name: '4', + value: 4 + }, + { + name: '5', + value: 5 + }, + ] + }, { displayName: 'Phone', name: 'phoneOptions', @@ -975,6 +871,106 @@ export const contactFields = [ ] }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + typeOptions: { + multipleValues: true, + multipleValueButtonText: 'Add Tag', + }, + default: [], + placeholder: 'Tag', + description: 'Unique identifiers added to contact, for easy management of contacts. This is not applicable for companies.', + }, + { + displayName: 'Title', + name: 'title', + type: 'string', + default: "", + placeholder: 'Title', + description: 'Professional title.', + }, + { + displayName: 'Website', + name: 'websiteOptions', + type: 'fixedCollection', + description: 'Contacts websites.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Website properties.', + name: 'websiteProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: "", + description: 'Type of website.', + options: [ + { + name: 'URL', + value: 'url', + }, + { + name: 'SKYPE', + value: 'skype', + }, + { + name: 'TWITTER', + value: 'twitter', + }, + { + name: 'LINKEDIN', + value: 'linkedin', + }, + { + name: 'FACEBOOK', + value: 'facebook', + }, + { + name: 'XING', + value: 'xing', + }, + { + name: 'FEED', + value: 'feed', + }, + { + name: 'GOOGLE_PLUS', + value: 'googlePlus', + }, + { + name: 'FLICKR', + value: 'flickr', + }, + { + name: 'GITHUB', + value: 'github', + }, + { + name: 'YOUTUBE', + value: 'youtube', + }, + ] + }, + { + displayName: 'URL', + name: 'url', + type: 'string', + required: true, + default: "", + description: 'Website URL', + } + ] + }, + + ] + }, { displayName: 'Custom Properties', name: 'customProperties', diff --git a/packages/nodes-base/nodes/AgileCrm/DealDescription.ts b/packages/nodes-base/nodes/AgileCrm/DealDescription.ts index 2ee7e9d1a2..673fe68524 100644 --- a/packages/nodes-base/nodes/AgileCrm/DealDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/DealDescription.ts @@ -15,6 +15,16 @@ export const dealOperations = [ }, }, options: [ + { + name: 'Create', + value: 'create', + description: 'Create a new deal', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a deal', + }, { name: 'Get', value: 'get', @@ -25,21 +35,12 @@ export const dealOperations = [ value: 'getAll', description: 'Get all deals', }, - { - name: 'Create', - value: 'create', - description: 'Create a new deal', - }, { name: 'Update', value: 'update', description: 'Update deal properties', }, - { - name: 'Delete', - value: 'delete', - description: 'Delete a deal', - }, + ], default: 'get', description: 'The operation to perform.', @@ -73,23 +74,6 @@ export const dealFields = [ /* -------------------------------------------------------------------------- */ /* deal:get all */ /* -------------------------------------------------------------------------- */ - { - displayName: 'Return All', - name: 'returnAll', - type: 'boolean', - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'getAll', - ], - }, - }, - default: false, - description: 'If all results should be returned or only up to a given limit.', - }, { displayName: 'Limit', name: 'limit', @@ -109,6 +93,24 @@ export const dealFields = [ }, } }, + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'getAll', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + /* -------------------------------------------------------------------------- */ /* deal:create */ @@ -180,6 +182,27 @@ export const dealFields = [ default: '', description: 'Milestone of deal.', }, + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + jsonParameters: [ + false, + ], + }, + }, + default: '', + description: 'Name of deal.', + }, { displayName: 'Probability', name: 'probability', @@ -205,27 +228,6 @@ export const dealFields = [ default: 50, description: 'Expected probability.', }, - { - displayName: 'Name', - name: 'name', - type: 'string', - required: true, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'create', - ], - jsonParameters: [ - false, - ], - }, - }, - default: '', - description: 'Name of deal.', - }, { displayName: 'JSON Parameters', name: 'jsonParameters', @@ -355,7 +357,7 @@ export const dealFields = [ }, }, default: '', - description: 'Unique identifier for a particular deal', + description: 'ID of deal to delete', }, /* -------------------------------------------------------------------------- */ @@ -377,7 +379,7 @@ export const dealFields = [ }, }, default: '', - description: 'Unique identifier for a particular deal', + description: 'Id of deal to update', }, { @@ -398,7 +400,7 @@ export const dealFields = [ }, }, { - displayName: ' Additional Fields', + displayName: 'Additional Fields', name: 'additionalFieldsJson', type: 'json', typeOptions: { @@ -452,6 +454,13 @@ export const dealFields = [ default: '', description: 'Expected Value of deal.', }, + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + description: 'Name of deal.', + }, { displayName: 'Probability', name: 'probability', @@ -463,13 +472,6 @@ export const dealFields = [ default: 50, description: 'Expected Value of deal.', }, - { - displayName: 'Name', - name: 'name', - type: 'string', - default: '', - description: 'Name of deal.', - }, { displayName: 'Contact Ids', name: 'contactIds', From 7b4980690f3f916607c131218f339b6ae8e10817 Mon Sep 17 00:00:00 2001 From: Jan Oberhauser Date: Mon, 11 May 2020 20:22:31 +0200 Subject: [PATCH 15/15] :zap: Improve AgileCrm-Node --- package.json | 7 +- .../nodes/AgileCrm/AgileCrm.node.ts | 141 +-- .../nodes/AgileCrm/CompanyDescription.ts | 135 +- .../nodes/AgileCrm/ContactDescription.ts | 1122 ++++++++--------- .../nodes/AgileCrm/ContactInterface.ts | 41 +- .../nodes/AgileCrm/DealDescription.ts | 898 +++++++------ .../nodes/AgileCrm/DealInterface.ts | 22 +- .../nodes/AgileCrm/GenericFunctions.ts | 70 +- .../nodes-base/nodes/AgileCrm/agilecrm.png | Bin 20236 -> 1218 bytes 9 files changed, 1173 insertions(+), 1263 deletions(-) diff --git a/package.json b/package.json index 3b96e2de5d..b045830f51 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,5 @@ "lerna": "^3.13.1", "run-script-os": "^1.0.7" }, - "postcss": {}, - "dependencies": { - "@typescript-eslint/parser": "^2.31.0", - "tslint-eslint-rules": "^5.4.0", - "typescript-tslint-plugin": "^0.5.5" - } + "postcss": {} } diff --git a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts index b26316f475..6090aa7796 100644 --- a/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts +++ b/packages/nodes-base/nodes/AgileCrm/AgileCrm.node.ts @@ -22,7 +22,7 @@ import { } from './DealDescription'; import { IContact, IContactUpdate } from './ContactInterface'; -import { agileCrmApiRequest, agileCrmApiRequestUpdate, validateJSON} from './GenericFunctions'; +import { agileCrmApiRequest, agileCrmApiRequestUpdate, validateJSON } from './GenericFunctions'; import { IDeal } from './DealInterface'; @@ -90,36 +90,31 @@ export class AgileCrm implements INodeType { const items = this.getInputData(); const returnData: IDataObject[] = []; - const length = items.length as unknown as number; 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++) { + for (let i = 0; i < items.length; i++) { - if(resource === 'contact' || resource === 'company'){ + if (resource === 'contact' || resource === 'company') { const idGetter = resource === 'contact' ? 'contactId' : 'companyId'; - if(operation === 'get'){ + if (operation === 'get') { const contactId = this.getNodeParameter(idGetter, i) as string; const endpoint = `api/contacts/${contactId}`; responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); - - } - if(operation === 'delete'){ + } else if (operation === 'delete') { const contactId = this.getNodeParameter(idGetter, i) as string; const endpoint = `api/contacts/${contactId}`; responseData = await agileCrmApiRequest.call(this, 'DELETE', endpoint, {}); - - } - if(operation === 'getAll'){ + } else if (operation === 'getAll') { const returnAll = this.getNodeParameter('returnAll', i) as boolean; - - if(resource === 'contact'){ + + if (resource === 'contact') { if (returnAll) { const endpoint = 'api/contacts'; responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); @@ -139,17 +134,15 @@ export class AgileCrm implements INodeType { } } - } - - if(operation === 'create'){ + } else if (operation === 'create') { const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; const body: IContact = {}; - const properties : IDataObject[] = []; + const properties: IDataObject[] = []; if (jsonParameters) { const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - if (additionalFieldsJson !== '' ) { + if (additionalFieldsJson !== '') { if (validateJSON(additionalFieldsJson) !== undefined) { @@ -165,7 +158,7 @@ export class AgileCrm implements INodeType { const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; // if company, add 'company' as type. default is person - if(resource === 'company'){ + if (resource === 'company') { body.type = 'COMPANY'; } if (additionalFields.starValue) { @@ -176,36 +169,36 @@ export class AgileCrm implements INodeType { } // Contact specific properties - if(resource === 'contact'){ - if(additionalFields.firstName){ + if (resource === 'contact') { + if (additionalFields.firstName) { properties.push({ type: 'SYSTEM', name: 'first_name', value: additionalFields.firstName as string } as IDataObject); } - if(additionalFields.lastName){ + if (additionalFields.lastName) { properties.push({ type: 'SYSTEM', name: 'last_name', value: additionalFields.lastName as string } as IDataObject); } - if(additionalFields.company){ + if (additionalFields.company) { properties.push({ type: 'SYSTEM', name: 'company', value: additionalFields.company as string } as IDataObject); } - if(additionalFields.title){ + if (additionalFields.title) { properties.push({ type: 'SYSTEM', name: 'title', value: additionalFields.title as string } as IDataObject); } - if(additionalFields.emailOptions){ + if (additionalFields.emailOptions) { //@ts-ignore additionalFields.emailOptions.emailProperties.map(property => { properties.push({ @@ -216,7 +209,7 @@ export class AgileCrm implements INodeType { } as IDataObject); }); } - if(additionalFields.addressOptions){ + if (additionalFields.addressOptions) { //@ts-ignore additionalFields.addressOptions.addressProperties.map(property => { properties.push({ @@ -228,7 +221,7 @@ export class AgileCrm implements INodeType { }); } - if(additionalFields.phoneOptions){ + if (additionalFields.phoneOptions) { //@ts-ignore additionalFields.phoneOptions.phoneProperties.map(property => { properties.push({ @@ -240,7 +233,7 @@ export class AgileCrm implements INodeType { }); } } else if (resource === 'company') { - if(additionalFields.email){ + if (additionalFields.email) { properties.push({ type: 'SYSTEM', name: 'email', @@ -248,7 +241,7 @@ export class AgileCrm implements INodeType { } as IDataObject); } - if(additionalFields.address){ + if (additionalFields.address) { properties.push({ type: 'SYSTEM', name: 'address', @@ -256,7 +249,7 @@ export class AgileCrm implements INodeType { } as IDataObject); } - if(additionalFields.phone){ + if (additionalFields.phone) { properties.push({ type: 'SYSTEM', name: 'phone', @@ -266,7 +259,7 @@ export class AgileCrm implements INodeType { } - if(additionalFields.websiteOptions){ + if (additionalFields.websiteOptions) { //@ts-ignore additionalFields.websiteOptions.websiteProperties.map(property => { properties.push({ @@ -278,7 +271,7 @@ export class AgileCrm implements INodeType { }); } - if(additionalFields.customProperties){ + if (additionalFields.customProperties) { //@ts-ignore additionalFields.customProperties.customProperty.map(property => { properties.push({ @@ -294,19 +287,18 @@ export class AgileCrm implements INodeType { } const endpoint = 'api/contacts'; responseData = await agileCrmApiRequest.call(this, 'POST', endpoint, body); - } - if(operation === 'update') { + } else if (operation === 'update') { const contactId = this.getNodeParameter(idGetter, i) as string; - const contactUpdatePayload : IContactUpdate = {id: contactId}; + const contactUpdatePayload: IContactUpdate = { id: contactId }; const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; const body: IContact = {}; - const properties : IDataObject[] = []; + const properties: IDataObject[] = []; if (jsonParameters) { const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - if (additionalFieldsJson !== '' ) { + if (additionalFieldsJson !== '') { if (validateJSON(additionalFieldsJson) !== undefined) { @@ -327,41 +319,41 @@ export class AgileCrm implements INodeType { } // Contact specific properties - if(resource === 'contact'){ + if (resource === 'contact') { if (additionalFields.leadScore) { body.lead_score = additionalFields.leadScore as string; } - - if(additionalFields.firstName){ + + if (additionalFields.firstName) { properties.push({ type: 'SYSTEM', name: 'first_name', value: additionalFields.firstName as string } as IDataObject); } - if(additionalFields.lastName){ + if (additionalFields.lastName) { properties.push({ type: 'SYSTEM', name: 'last_name', value: additionalFields.lastName as string } as IDataObject); } - if(additionalFields.company){ + if (additionalFields.company) { properties.push({ type: 'SYSTEM', name: 'company', value: additionalFields.company as string } as IDataObject); } - if(additionalFields.title){ + if (additionalFields.title) { properties.push({ type: 'SYSTEM', name: 'title', value: additionalFields.title as string } as IDataObject); } - if(additionalFields.emailOptions){ + if (additionalFields.emailOptions) { //@ts-ignore additionalFields.emailOptions.emailProperties.map(property => { properties.push({ @@ -372,7 +364,7 @@ export class AgileCrm implements INodeType { } as IDataObject); }); } - if(additionalFields.addressOptions){ + if (additionalFields.addressOptions) { //@ts-ignore additionalFields.addressOptions.addressProperties.map(property => { properties.push({ @@ -384,7 +376,7 @@ export class AgileCrm implements INodeType { }); } - if(additionalFields.phoneOptions){ + if (additionalFields.phoneOptions) { //@ts-ignore additionalFields.phoneOptions.phoneProperties.map(property => { properties.push({ @@ -396,7 +388,7 @@ export class AgileCrm implements INodeType { }); } } else if (resource === 'company') { - if(additionalFields.email){ + if (additionalFields.email) { properties.push({ type: 'SYSTEM', name: 'email', @@ -404,7 +396,7 @@ export class AgileCrm implements INodeType { } as IDataObject); } - if(additionalFields.address){ + if (additionalFields.address) { properties.push({ type: 'SYSTEM', name: 'address', @@ -412,7 +404,7 @@ export class AgileCrm implements INodeType { } as IDataObject); } - if(additionalFields.phone){ + if (additionalFields.phone) { properties.push({ type: 'SYSTEM', name: 'phone', @@ -422,7 +414,7 @@ export class AgileCrm implements INodeType { } - if(additionalFields.websiteOptions){ + if (additionalFields.websiteOptions) { //@ts-ignore additionalFields.websiteOptions.websiteProperties.map(property => { properties.push({ @@ -433,7 +425,7 @@ export class AgileCrm implements INodeType { } as IDataObject); }); } - if(additionalFields.customProperties){ + if (additionalFields.customProperties) { //@ts-ignore additionalFields.customProperties.customProperty.map(property => { properties.push({ @@ -453,26 +445,23 @@ export class AgileCrm implements INodeType { } - } - if(resource === 'deal'){ + } else if (resource === 'deal') { - if(operation === 'get'){ + if (operation === 'get') { const dealId = this.getNodeParameter('dealId', i) as string; const endpoint = `api/opportunity/${dealId}`; responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); - } - if(operation === 'delete'){ + } else if (operation === 'delete') { const contactId = this.getNodeParameter('dealId', i) as string; const endpoint = `api/opportunity/${contactId}`; responseData = await agileCrmApiRequest.call(this, 'DELETE', endpoint, {}); - } - if(operation === 'getAll'){ + } else if (operation === 'getAll') { const returnAll = this.getNodeParameter('returnAll', i) as boolean; - + if (returnAll) { const endpoint = 'api/opportunity'; responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); @@ -481,9 +470,8 @@ export class AgileCrm implements INodeType { const endpoint = `api/opportunity?page_size=${limit}`; responseData = await agileCrmApiRequest.call(this, 'GET', endpoint, {}); } - } - if(operation === 'create'){ + } else if (operation === 'create') { const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; const body: IDeal = {}; @@ -491,12 +479,9 @@ export class AgileCrm implements INodeType { if (jsonParameters) { const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - if (additionalFieldsJson !== '' ) { - + if (additionalFieldsJson !== '') { if (validateJSON(additionalFieldsJson) !== undefined) { - Object.assign(body, JSON.parse(additionalFieldsJson)); - } else { throw new Error('Additional fields must be a valid JSON'); } @@ -504,18 +489,18 @@ export class AgileCrm implements INodeType { } else { const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - + body.close_date = new Date(this.getNodeParameter('closeDate', i) as string).getTime(); body.expected_value = this.getNodeParameter('expectedValue', i) as number; body.milestone = this.getNodeParameter('milestone', i) as string; body.probability = this.getNodeParameter('probability', i) as number; body.name = this.getNodeParameter('name', i) as string; - if(additionalFields.contactIds){ + if (additionalFields.contactIds) { body.contactIds = additionalFields.contactIds as string[]; } - if(additionalFields.customData){ + if (additionalFields.customData) { // @ts-ignore body.customData = additionalFields.customData.customProperty as IDealCustomProperty[]; } @@ -524,9 +509,8 @@ export class AgileCrm implements INodeType { const endpoint = 'api/opportunity'; responseData = await agileCrmApiRequest.call(this, 'POST', endpoint, body); - } - if(operation === 'update'){ + } else if (operation === 'update') { const jsonParameters = this.getNodeParameter('jsonParameters', i) as boolean; const body: IDeal = {}; @@ -534,14 +518,14 @@ export class AgileCrm implements INodeType { if (jsonParameters) { const additionalFieldsJson = this.getNodeParameter('additionalFieldsJson', i) as string; - if (additionalFieldsJson !== '' ) { + if (additionalFieldsJson !== '') { if (validateJSON(additionalFieldsJson) !== undefined) { Object.assign(body, JSON.parse(additionalFieldsJson)); } else { - throw new Error('Additional fields must be a valid JSON'); + throw new Error('Additional fields must be valid JSON'); } } @@ -549,23 +533,23 @@ export class AgileCrm implements INodeType { const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; body.id = this.getNodeParameter('dealId', i) as number; - if(additionalFields.expectedValue){ + if (additionalFields.expectedValue) { body.expected_value = additionalFields.expectedValue as number; } - if(additionalFields.name){ + if (additionalFields.name) { body.name = additionalFields.name as string; } - if(additionalFields.probability){ + if (additionalFields.probability) { body.probability = additionalFields.probability as number; } - if(additionalFields.contactIds){ + if (additionalFields.contactIds) { body.contactIds = additionalFields.contactIds as string[]; } - if(additionalFields.customData){ + if (additionalFields.customData) { // @ts-ignore body.customData = additionalFields.customData.customProperty as IDealCustomProperty[]; } @@ -577,7 +561,6 @@ export class AgileCrm implements INodeType { } } - if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]); } else { @@ -588,5 +571,5 @@ export class AgileCrm implements INodeType { return [this.helpers.returnJsonArray(returnData)]; } - + } diff --git a/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts b/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts index a3bfaafc3f..08b45d2090 100644 --- a/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/CompanyDescription.ts @@ -45,11 +45,11 @@ export const companyOperations = [ }, ] as INodeProperties[]; export const companyFields = [ -/* -------------------------------------------------------------------------- */ -/* company:get */ -/* -------------------------------------------------------------------------- */ + /* -------------------------------------------------------------------------- */ + /* company:get */ + /* -------------------------------------------------------------------------- */ { - displayName: 'company ID', + displayName: 'Company ID', name: 'companyId', type: 'string', required: true, @@ -66,7 +66,7 @@ export const companyFields = [ default: '', description: 'Unique identifier for a particular company', }, - + /* -------------------------------------------------------------------------- */ /* company:get all */ /* -------------------------------------------------------------------------- */ @@ -147,7 +147,6 @@ export const companyFields = [ ], }, }, - description: 'Object of values to set as described here.', }, { @@ -174,18 +173,14 @@ export const companyFields = [ displayName: 'Address', name: 'email', type: 'string', - default: '', - placeholder: 'Company address', description: 'Company address.', }, { displayName: 'Email', name: 'email', type: 'string', - default: '', - placeholder: 'Company email', description: 'Company email.', }, { @@ -193,16 +188,13 @@ export const companyFields = [ name: 'name', type: 'string', default: '', - placeholder: 'Company name', description: 'Company name.', }, { displayName: 'Phone', name: 'phone', type: 'string', - default: '', - placeholder: 'Company phone', description: 'Company phone.', }, { @@ -247,14 +239,12 @@ export const companyFields = [ multipleValueButtonText: 'Add Tag', }, default: [], - placeholder: 'Tag', description: 'Unique identifiers added to company, for easy management of companys. This is not applicable for companies.', }, { displayName: 'Website', name: 'websiteOptions', type: 'fixedCollection', - description: 'Companies websites.', typeOptions: { multipleValues: true, @@ -273,35 +263,35 @@ export const companyFields = [ description: 'Type of website.', options: [ { - name: 'FACEBOOK', + name: 'Facebook', value: 'facebook', }, { - name: 'FEED', + name: 'Feed', value: 'feed', }, { - name: 'FLICKR', + name: 'Flickr', value: 'flickr', }, { - name: 'LINKEDIN', - value: 'linkedin', - }, - { - name: 'GITHUB', + name: 'Github', value: 'github', }, { - name: 'GOOGLE_PLUS', + name: 'Google Plus', value: 'googlePlus', }, { - name: 'SKYPE', + name: 'LinkedIn', + value: 'linkedin', + }, + { + name: 'Skype', value: 'skype', }, { - name: 'TWITTER', + name: 'Twitter', value: 'twitter', }, { @@ -309,14 +299,14 @@ export const companyFields = [ value: 'url', }, { - name: 'XING', + name: 'Xing', value: 'xing', }, { - name: 'YOUTUBE', + name: 'YouTube', value: 'youtube', }, - ] + ], }, { displayName: 'URL', @@ -324,19 +314,16 @@ export const companyFields = [ type: 'string', required: true, default: '', - description: 'Website URL', - } - ] + }, + ], }, - - ] + ], }, { displayName: 'Custom Properties', name: 'customProperties', type: 'fixedCollection', - description: 'Custom Properties', typeOptions: { multipleValues: true, @@ -352,33 +339,29 @@ export const companyFields = [ type: 'string', required: true, default: '', - description: 'Property name.' }, { displayName: 'Sub Type', name: 'subtype', type: 'string', - default: '', - description: 'Property sub type.', }, { displayName: 'Value', name: 'value', type: 'string', - default: '', - description: 'Property value.', - } - ] + }, + ], }, - ] + ], }, ], }, + /* -------------------------------------------------------------------------- */ /* company:delete */ /* -------------------------------------------------------------------------- */ @@ -400,11 +383,12 @@ export const companyFields = [ default: '', description: 'ID of company to delete', }, + /* -------------------------------------------------------------------------- */ /* company:update */ /* -------------------------------------------------------------------------- */ { - displayName: 'company ID', + displayName: 'Company ID', name: 'companyId', type: 'string', required: true, @@ -459,7 +443,6 @@ export const companyFields = [ ], }, }, - description: 'Object of values to set as described here.', }, { @@ -487,7 +470,6 @@ export const companyFields = [ name: 'email', type: 'string', default: '', - placeholder: 'Company address', description: 'Company address.', }, { @@ -495,7 +477,6 @@ export const companyFields = [ name: 'email', type: 'string', default: '', - placeholder: 'Company email', description: 'Company email.', }, { @@ -507,29 +488,29 @@ export const companyFields = [ options: [ { name: '0', - value: 0 + value: 0, }, { name: '1', - value: 1 + value: 1, }, { name: '2', - value: 2 + value: 2, }, { name: '3', - value: 3 + value: 3, }, { name: '4', - value: 4 + value: 4, }, { name: '5', - value: 5 + value: 5, }, - ] + ], }, { displayName: 'Tags', @@ -540,7 +521,6 @@ export const companyFields = [ multipleValueButtonText: 'Add Tag', }, default: [], - placeholder: 'Tag', description: 'Unique identifiers added to company, for easy management of companys. This is not applicable for companies.', }, { @@ -548,7 +528,6 @@ export const companyFields = [ name: 'name', type: 'string', default: '', - placeholder: 'Company name', description: 'Company name.', }, { @@ -556,14 +535,13 @@ export const companyFields = [ name: 'phone', type: 'string', default: '', - placeholder: 'Company phone', description: 'Company phone.', }, { displayName: 'Website', name: 'websiteOptions', type: 'fixedCollection', - description: 'companys websites.', + description: 'Companys websites.', typeOptions: { multipleValues: true, }, @@ -581,35 +559,35 @@ export const companyFields = [ description: 'Type of website.', options: [ { - name: 'FACEBOOK', + name: 'Facebook', value: 'facebook', }, { - name: 'FEED', + name: 'Feed', value: 'feed', }, { - name: 'FLICKR', + name: 'Flickr', value: 'flickr', }, { - name: 'LINKEDIN', - value: 'linkedin', - }, - { - name: 'GITHUB', + name: 'Github', value: 'github', }, { - name: 'GOOGLE_PLUS', + name: 'Google Plus', value: 'googlePlus', }, { - name: 'SKYPE', + name: 'LinkedIn', + value: 'linkedin', + }, + { + name: 'Skype', value: 'skype', }, { - name: 'TWITTER', + name: 'Twitter', value: 'twitter', }, { @@ -617,14 +595,14 @@ export const companyFields = [ value: 'url', }, { - name: 'XING', + name: 'Xing', value: 'xing', }, { - name: 'YOUTUBE', + name: 'YouTube', value: 'youtube', }, - ] + ], }, { displayName: 'URL', @@ -633,10 +611,10 @@ export const companyFields = [ required: true, default: '', description: 'Website URL', - } - ] + }, + ], }, - ] + ], }, { displayName: 'Custom Properties', @@ -657,7 +635,7 @@ export const companyFields = [ type: 'string', required: true, default: '', - description: 'Property name.' + description: 'Property name.', }, { displayName: 'Sub Type', @@ -672,10 +650,9 @@ export const companyFields = [ type: 'string', default: '', description: 'Property value.', - } - ] + }, + ], }, - ] }, ], diff --git a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts index 88b38c403d..5043e05b4a 100644 --- a/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/ContactDescription.ts @@ -47,9 +47,9 @@ export const contactOperations = [ ] as INodeProperties[]; export const contactFields = [ -/* -------------------------------------------------------------------------- */ -/* contact:get */ -/* -------------------------------------------------------------------------- */ + /* -------------------------------------------------------------------------- */ + /* contact:get */ + /* -------------------------------------------------------------------------- */ { displayName: 'Contact ID', name: 'contactId', @@ -68,9 +68,9 @@ export const contactFields = [ default: '', description: 'Unique identifier for a particular contact', }, -/* -------------------------------------------------------------------------- */ -/* contact:get all */ -/* -------------------------------------------------------------------------- */ + /* -------------------------------------------------------------------------- */ + /* contact:get all */ + /* -------------------------------------------------------------------------- */ { displayName: 'Limit', name: 'limit', @@ -88,7 +88,7 @@ export const contactFields = [ false, ], }, - } + }, }, { displayName: 'Return All', @@ -150,7 +150,7 @@ export const contactFields = [ ], }, }, - + description: `Object of values to set as described here.`, }, @@ -192,44 +192,40 @@ export const contactFields = [ name: 'subtype', type: 'options', required: true, - default: "", - + default: '', description: 'Type of address.', options: [ { name: 'Home', - value: 'home' + value: 'home', }, { name: 'Postal', - value: 'postal' - } - , + value: 'postal', + }, { name: 'Office', value: 'office' - } - ] + }, + ], }, { displayName: 'Address', name: 'address', type: 'string', required: true, - default: "", + default: '', description: 'Full address.', - } - ] + }, + ], }, - - ] + ], }, { displayName: 'Company', name: 'company', type: 'string', - default: "", - placeholder: 'Company', + default: '', description: 'Company Name.', }, { @@ -250,46 +246,43 @@ export const contactFields = [ name: 'subtype', type: 'options', required: true, - default: "", + default: '', description: 'Type of Email', options: [ { name: 'Work', - value: 'work' + value: 'work', }, { name: 'Personal', - value: 'personal' - } - ] + value: 'personal', + }, + ], }, { displayName: 'Email', name: 'email', type: 'string', required: true, - default: "", + default: '', description: 'Email', - } - ] + }, + ], }, - - ] + ], }, { displayName: 'First Name', name: 'firstName', type: 'string', - default: "", - placeholder: 'First Name', + default: '', description: 'Contact first name.', }, { displayName: 'Last Name', name: 'lastName', type: 'string', - default: "", - placeholder: 'Last Name', + default: '', description: 'Contact last name.', }, { @@ -299,8 +292,8 @@ export const contactFields = [ default: '', description: 'Lead score of contact', typeOptions: { - minValue: 0 - } + minValue: 0, + }, }, { displayName: 'Star Value', @@ -311,29 +304,29 @@ export const contactFields = [ options: [ { name: '0', - value: 0 + value: 0, }, { name: '1', - value: 1 + value: 1, }, { name: '2', - value: 2 + value: 2, }, { name: '3', - value: 3 + value: 3, }, { name: '4', - value: 4 + value: 4, }, { name: '5', - value: 5 + value: 5, }, - ] + ], }, { displayName: 'Phone', @@ -353,52 +346,50 @@ export const contactFields = [ name: 'subtype', type: 'options', required: true, - default: "", + default: '', description: 'Type of phone number.', options: [ { name: 'Home', - value: 'home' - }, - { - name: 'Work', - value: 'work' - } - , - { - name: 'Mobile', - value: 'mobile' - }, - { - name: 'Main', - value: 'main' + value: 'home', }, { name: 'Home Fax', - value: 'homeFax' + value: 'homeFax', }, { - name: 'Work Fax', - value: 'workFax' + name: 'Main', + value: 'main', + }, + { + name: 'Mobile', + value: 'mobile', }, { name: 'Other', - value: 'other' + value: 'other', }, - ] + { + name: 'Work Fax', + value: 'workFax', + }, + { + name: 'Work', + value: 'work', + }, + ], }, { displayName: 'Number', name: 'number', type: 'string', required: true, - default: "", + default: '', description: 'Phone number.', - } - ] + }, + ], }, - - ] + ], }, { displayName: 'Tags', @@ -409,15 +400,13 @@ export const contactFields = [ multipleValueButtonText: 'Add Tag', }, default: [], - placeholder: 'Tag', description: 'Unique identifiers added to contact, for easy management of contacts. This is not applicable for companies.', - }, + }, { displayName: 'Title', name: 'title', type: 'string', - default: "", - placeholder: 'Title', + default: '', description: 'Professional title.', }, { @@ -438,67 +427,66 @@ export const contactFields = [ name: 'subtype', type: 'options', required: true, - default: "", + default: '', description: 'Type of website.', options: [ + { + name: 'Facebook', + value: 'facebook', + }, + { + name: 'Feed', + value: 'feed', + }, + { + name: 'Flickr', + value: 'flickr', + }, + { + name: 'Github', + value: 'github', + }, + { + name: 'Google Plus', + value: 'googlePlus', + }, + { + name: 'LinkedIn', + value: 'linkedin', + }, + { + name: 'Skype', + value: 'skype', + }, + { + name: 'Twitter', + value: 'twitter', + }, { name: 'URL', value: 'url', }, { - name: 'SKYPE', - value: 'skype', - }, - { - name: 'TWITTER', - value: 'twitter', - }, - { - name: 'LINKEDIN', - value: 'linkedin', - }, - { - name: 'FACEBOOK', - value: 'facebook', - }, - { - name: 'XING', + name: 'Xing', value: 'xing', }, { - name: 'FEED', - value: 'feed', - }, - { - name: 'GOOGLE_PLUS', - value: 'googlePlus', - }, - { - name: 'FLICKR', - value: 'flickr', - }, - { - name: 'GITHUB', - value: 'github', - }, - { - name: 'YOUTUBE', + name: 'YouTube', value: 'youtube', }, - ] + ], }, { displayName: 'URL', name: 'url', type: 'string', required: true, - default: "", + default: '', description: 'Website URL', - } - ] + }, + ], }, - - ] + ], }, { displayName: 'Custom Properties', @@ -518,30 +506,30 @@ export const contactFields = [ name: 'name', type: 'string', required: true, - default: "", - description: 'Property name.' + default: '', + description: 'Property name.', }, { displayName: 'Sub Type', name: 'subtype', type: 'string', - default: "", + default: '', description: 'Property sub type.', }, { displayName: 'Value', name: 'value', type: 'string', - default: "", + default: '', description: 'Property value.', - } - ] + }, + ], }, - - ] + ], }, ], }, + /* -------------------------------------------------------------------------- */ /* contact:delete */ /* -------------------------------------------------------------------------- */ @@ -563,455 +551,441 @@ export const contactFields = [ default: '', description: 'Id of contact to delete.', }, -/* -------------------------------------------------------------------------- */ -/* contact:update */ -/* -------------------------------------------------------------------------- */ -{ - displayName: 'Contact ID', - name: 'contactId', - type: 'string', - required: true, - displayOptions: { - show: { - resource: [ - 'contact', - ], - operation: [ - 'update', - ], - }, - }, - default: '', - description: 'Unique identifier for a particular contact', -}, -{ - displayName: 'JSON Parameters', - name: 'jsonParameters', - type: 'boolean', - default: false, - description: '', - displayOptions: { - show: { - resource: [ - 'contact', - ], - operation: [ - 'update', - ], - }, - }, -}, -{ - displayName: ' Additional Fields', - name: 'additionalFieldsJson', - type: 'json', - typeOptions: { - alwaysOpenEditWindow: true, - }, - default: '', - displayOptions: { - show: { - resource: [ - 'contact', - ], - operation: [ - 'update', - ], - jsonParameters: [ - true, - ], - }, - }, - - description: `Object of values to set as described here.`, -}, -{ - displayName: 'Additional Fields', - name: 'additionalFields', - type: 'collection', - placeholder: 'Add Field', - default: {}, - displayOptions: { - show: { - resource: [ - 'contact', - ], - operation: [ - 'update', - ], - jsonParameters: [ - false, - ], - }, - }, - options: [ - { - displayName: 'Address', - name: 'addressOptions', - type: 'fixedCollection', - description: 'Contacts address.', - typeOptions: { - multipleValues: true, - }, - options: [ - { - displayName: 'Address Properties', - name: 'addressProperties', - values: [ - { - displayName: 'Type', - name: 'subtype', - type: 'options', - required: true, - default: "", - - description: 'Type of address.', - options: [ - { - name: 'Home', - value: 'home' - }, - { - name: 'Postal', - value: 'postal' - } - , - { - name: 'Office', - value: 'office' - } - ] - }, - { - displayName: 'Address', - name: 'address', - type: 'string', - required: true, - default: "", - description: 'Full address.', - } - ] - }, - - ] - }, - { - displayName: 'Company', - name: 'company', - type: 'string', - default: "", - placeholder: 'Company', - description: 'Company Name.', - }, - { - displayName: 'Email', - name: 'emailOptions', - type: 'fixedCollection', - description: 'Contact email.', - typeOptions: { - multipleValues: true, - }, - options: [ - { - displayName: 'Email Properties', - name: 'emailProperties', - values: [ - { - displayName: 'Type', - name: 'subtype', - type: 'options', - required: true, - default: "", - description: 'Type of Email', - options: [ - { - name: 'Work', - value: 'work' - }, - { - name: 'Personal', - value: 'personal' - } - ] - }, - { - displayName: 'Email', - name: 'email', - type: 'string', - required: true, - default: "", - description: 'Email', - } - ] - }, - - ] - }, - { - displayName: 'First Name', - name: 'firstName', - type: 'string', - default: "", - placeholder: 'First Name', - description: 'Contact first name.', - }, - { - displayName: 'Last Name', - name: 'lastName', - type: 'string', - default: "", - placeholder: 'Last Name', - description: 'Contact last name.', - }, - { - displayName: 'Lead Score', - name: 'leadScore', - type: 'number', - default: '', - description: 'Lead score of contact', - typeOptions: { - minValue: 0 - } - }, - { - displayName: 'Star Value', - name: 'starValue', - type: 'options', - default: '', - description: 'Rating of contact (Max value 5). This is not applicable for companies.', - options: [ - { - name: '0', - value: 0 - }, - { - name: '1', - value: 1 - }, - { - name: '2', - value: 2 - }, - { - name: '3', - value: 3 - }, - { - name: '4', - value: 4 - }, - { - name: '5', - value: 5 - }, - ] - }, - { - displayName: 'Phone', - name: 'phoneOptions', - type: 'fixedCollection', - description: 'Contacts phone.', - typeOptions: { - multipleValues: true, - }, - options: [ - { - displayName: 'Phone properties', - name: 'phoneProperties', - values: [ - { - displayName: 'Type', - name: 'subtype', - type: 'options', - required: true, - default: "", - description: 'Type of phone number.', - options: [ - { - name: 'Home', - value: 'home' - }, - { - name: 'Work', - value: 'work' - } - , - { - name: 'Mobile', - value: 'mobile' - }, - { - name: 'Main', - value: 'main' - }, - { - name: 'Home Fax', - value: 'homeFax' - }, - { - name: 'Work Fax', - value: 'workFax' - }, - { - name: 'Other', - value: 'other' - }, - ] - }, - { - displayName: 'Number', - name: 'number', - type: 'string', - required: true, - default: "", - description: 'Phone number.', - } - ] - }, - - ] - }, - { - displayName: 'Tags', - name: 'tags', - type: 'string', - typeOptions: { - multipleValues: true, - multipleValueButtonText: 'Add Tag', - }, - default: [], - placeholder: 'Tag', - description: 'Unique identifiers added to contact, for easy management of contacts. This is not applicable for companies.', - }, - { - displayName: 'Title', - name: 'title', - type: 'string', - default: "", - placeholder: 'Title', - description: 'Professional title.', - }, - { - displayName: 'Website', - name: 'websiteOptions', - type: 'fixedCollection', - description: 'Contacts websites.', - typeOptions: { - multipleValues: true, - }, - options: [ - { - displayName: 'Website properties.', - name: 'websiteProperties', - values: [ - { - displayName: 'Type', - name: 'subtype', - type: 'options', - required: true, - default: "", - description: 'Type of website.', - options: [ - { - name: 'URL', - value: 'url', - }, - { - name: 'SKYPE', - value: 'skype', - }, - { - name: 'TWITTER', - value: 'twitter', - }, - { - name: 'LINKEDIN', - value: 'linkedin', - }, - { - name: 'FACEBOOK', - value: 'facebook', - }, - { - name: 'XING', - value: 'xing', - }, - { - name: 'FEED', - value: 'feed', - }, - { - name: 'GOOGLE_PLUS', - value: 'googlePlus', - }, - { - name: 'FLICKR', - value: 'flickr', - }, - { - name: 'GITHUB', - value: 'github', - }, - { - name: 'YOUTUBE', - value: 'youtube', - }, - ] - }, - { - displayName: 'URL', - name: 'url', - type: 'string', - required: true, - default: "", - description: 'Website URL', - } - ] - }, - - ] - }, - { - displayName: 'Custom Properties', - name: 'customProperties', - type: 'fixedCollection', - description: 'Custom Properties', - typeOptions: { - multipleValues: true, - }, - options: [ - { - displayName: 'Property', - name: 'customProperty', - values: [ - { - displayName: 'Name', - name: 'name', - type: 'string', - required: true, - default: "", - description: 'Property name.' - }, - { - displayName: 'Sub Type', - name: 'subtype', - type: 'string', - default: "", - description: 'Property sub type.', - }, - { - displayName: 'Value', - name: 'value', - type: 'string', - default: "", - description: 'Property value.', - } - ] - }, - - ] - }, - ], -}, + /* -------------------------------------------------------------------------- */ + /* contact:update */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Contact ID', + name: 'contactId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'update', + ], + }, + }, + default: '', + description: 'Unique identifier for a particular contact', + }, + { + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: ' Additional Fields', + name: 'additionalFieldsJson', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'update', + ], + jsonParameters: [ + true, + ], + }, + }, + description: `Object of values to set as described here.`, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'contact', + ], + operation: [ + 'update', + ], + jsonParameters: [ + false, + ], + }, + }, + options: [ + { + displayName: 'Address', + name: 'addressOptions', + type: 'fixedCollection', + description: 'Contacts address.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Address Properties', + name: 'addressProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: '', + description: 'Type of address.', + options: [ + { + name: 'Home', + value: 'home' + }, + { + name: 'Office', + value: 'office' + }, + { + name: 'Postal', + value: 'postal' + }, + ], + }, + { + displayName: 'Address', + name: 'address', + type: 'string', + required: true, + default: '', + description: 'Full address.', + }, + ], + }, + ], + }, + { + displayName: 'Company', + name: 'company', + type: 'string', + default: '', + description: 'Company Name.', + }, + { + displayName: 'Email', + name: 'emailOptions', + type: 'fixedCollection', + description: 'Contact email.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Email Properties', + name: 'emailProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: '', + description: 'Type of Email', + options: [ + { + name: 'Work', + value: 'work', + }, + { + name: 'Personal', + value: 'personal', + } + ] + }, + { + displayName: 'Email', + name: 'email', + type: 'string', + required: true, + default: '', + description: 'Email', + }, + ], + }, + ], + }, + { + displayName: 'First Name', + name: 'firstName', + type: 'string', + default: '', + description: 'Contact first name.', + }, + { + displayName: 'Last Name', + name: 'lastName', + type: 'string', + default: '', + description: 'Contact last name.', + }, + { + displayName: 'Lead Score', + name: 'leadScore', + type: 'number', + default: '', + description: 'Lead score of contact', + typeOptions: { + minValue: 0, + } + }, + { + displayName: 'Star Value', + name: 'starValue', + type: 'options', + default: '', + description: 'Rating of contact (Max value 5). This is not applicable for companies.', + options: [ + { + name: '0', + value: 0, + }, + { + name: '1', + value: 1, + }, + { + name: '2', + value: 2, + }, + { + name: '3', + value: 3, + }, + { + name: '4', + value: 4, + }, + { + name: '5', + value: 5, + }, + ], + }, + { + displayName: 'Phone', + name: 'phoneOptions', + type: 'fixedCollection', + description: 'Contacts phone.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Phone properties', + name: 'phoneProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: '', + description: 'Type of phone number.', + options: [ + { + name: 'Home', + value: 'home', + }, + { + name: 'Home Fax', + value: 'homeFax', + }, + { + name: 'Main', + value: 'main', + }, + { + name: 'Mobile', + value: 'mobile', + }, + { + name: 'Other', + value: 'other', + }, + { + name: 'Work Fax', + value: 'workFax', + }, + { + name: 'Work', + value: 'work', + }, + ], + }, + { + displayName: 'Number', + name: 'number', + type: 'string', + required: true, + default: '', + description: 'Phone number.', + }, + ], + }, + ], + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + typeOptions: { + multipleValues: true, + multipleValueButtonText: 'Add Tag', + }, + default: [], + description: 'Unique identifiers added to contact, for easy management of contacts. This is not applicable for companies.', + }, + { + displayName: 'Title', + name: 'title', + type: 'string', + default: '', + description: 'Professional title.', + }, + { + displayName: 'Website', + name: 'websiteOptions', + type: 'fixedCollection', + description: 'Contacts websites.', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Website properties.', + name: 'websiteProperties', + values: [ + { + displayName: 'Type', + name: 'subtype', + type: 'options', + required: true, + default: '', + description: 'Type of website.', + options: [ + { + name: 'Facebook', + value: 'facebook', + }, + { + name: 'Feed', + value: 'feed', + }, + { + name: 'Flickr', + value: 'flickr', + }, + { + name: 'Github', + value: 'github', + }, + { + name: 'Google Plus', + value: 'googlePlus', + }, + { + name: 'LinkedIn', + value: 'linkedin', + }, + { + name: 'Skype', + value: 'skype', + }, + { + name: 'Twitter', + value: 'twitter', + }, + { + name: 'URL', + value: 'url', + }, + { + name: 'Xing', + value: 'xing', + }, + { + name: 'YouTube', + value: 'youtube', + }, + ], + }, + { + displayName: 'URL', + name: 'url', + type: 'string', + required: true, + default: '', + description: 'Website URL', + }, + ], + }, + ], + }, + { + displayName: 'Custom Properties', + name: 'customProperties', + type: 'fixedCollection', + description: 'Custom Properties', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Property', + name: 'customProperty', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + default: '', + description: 'Property name.' + }, + { + displayName: 'Sub Type', + name: 'subtype', + type: 'string', + default: '', + description: 'Property sub type.', + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Property value.', + }, + ], + }, + ], + }, + ], + }, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts b/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts index 373786bafb..3a18ed3e15 100644 --- a/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts +++ b/packages/nodes-base/nodes/AgileCrm/ContactInterface.ts @@ -1,27 +1,26 @@ import { IDataObject, - } from 'n8n-workflow'; +} from 'n8n-workflow'; - export interface IProperty { - type: string; - name: string; - subtype?: string; - value?: string; +export interface IProperty { + type: string; + name: string; + subtype?: string; + value?: string; } - export interface IContact { - type?: string; - star_value?: string; - lead_score?: string; - tags?: string[]; - properties?: IDataObject[]; - } - - export interface IContactUpdate { - id: string; - properties?: IDataObject[]; - star_value?: string; - lead_score?: string; - tags?: string[]; - } +export interface IContact { + type?: string; + star_value?: string; + lead_score?: string; + tags?: string[]; + properties?: IDataObject[]; +} +export interface IContactUpdate { + id: string; + properties?: IDataObject[]; + star_value?: string; + lead_score?: string; + tags?: string[]; +} diff --git a/packages/nodes-base/nodes/AgileCrm/DealDescription.ts b/packages/nodes-base/nodes/AgileCrm/DealDescription.ts index 673fe68524..443017cfd6 100644 --- a/packages/nodes-base/nodes/AgileCrm/DealDescription.ts +++ b/packages/nodes-base/nodes/AgileCrm/DealDescription.ts @@ -1,6 +1,6 @@ import { INodeProperties, - } from 'n8n-workflow'; +} from 'n8n-workflow'; export const dealOperations = [ { @@ -15,12 +15,12 @@ export const dealOperations = [ }, }, options: [ - { + { name: 'Create', value: 'create', description: 'Create a new deal', - }, - { + }, + { name: 'Delete', value: 'delete', description: 'Delete a deal', @@ -48,9 +48,9 @@ export const dealOperations = [ ] as INodeProperties[]; export const dealFields = [ -/* -------------------------------------------------------------------------- */ -/* deal:get */ -/* -------------------------------------------------------------------------- */ + /* -------------------------------------------------------------------------- */ + /* deal:get */ + /* -------------------------------------------------------------------------- */ { displayName: 'Deal ID', name: 'dealId', @@ -69,455 +69,447 @@ export const dealFields = [ default: '', description: 'Unique identifier for a particular deal', }, - - -/* -------------------------------------------------------------------------- */ -/* deal:get all */ -/* -------------------------------------------------------------------------- */ - { - displayName: 'Limit', - name: 'limit', - type: 'number', - default: 20, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'getAll', - ], - returnAll: [ - false, - ], - }, - } - }, - { - displayName: 'Return All', - name: 'returnAll', - type: 'boolean', - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'getAll', - ], - }, - }, - default: false, - description: 'If all results should be returned or only up to a given limit.', - }, -/* -------------------------------------------------------------------------- */ -/* deal:create */ -/* -------------------------------------------------------------------------- */ - { - displayName: 'Close Date', - name: 'closeDate', - type: 'dateTime', - required: true, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'create', - ], - jsonParameters: [ - false, - ], - }, - }, - default: '', - description: 'Closing date of deal.', - }, - { - displayName: 'Expected Value', - name: 'expectedValue', - type: 'number', - required: true, - typeOptions: { - minValue: 0, - maxValue: 1000000000000 - }, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'create', - ], - jsonParameters: [ - false, - ], - }, - }, - default: 1, - description: 'Expected Value of deal.', - }, - { - displayName: 'Milestone', - name: 'milestone', - type: 'string', - required: true, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'create', - ], - jsonParameters: [ - false, - ], - }, - }, - default: '', - description: 'Milestone of deal.', - }, - { - displayName: 'Name', - name: 'name', - type: 'string', - required: true, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'create', - ], - jsonParameters: [ - false, - ], - }, - }, - default: '', - description: 'Name of deal.', - }, - { - displayName: 'Probability', - name: 'probability', - type: 'number', - required: true, - typeOptions: { - minValue: 0, - maxValue: 100 - }, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'create', - ], - jsonParameters: [ - false, - ], - }, - }, - default: 50, - description: 'Expected probability.', - }, - { - displayName: 'JSON Parameters', - name: 'jsonParameters', - type: 'boolean', - default: false, - description: '', - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'create', - ], - }, - }, - }, - { - displayName: ' Additional Fields', - name: 'additionalFieldsJson', - type: 'json', - typeOptions: { - alwaysOpenEditWindow: true, - }, - default: '', - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'create', - ], - jsonParameters: [ - true, - ], - }, - }, - - description: `Object of values to set as described here.`, - }, - { - displayName: 'Additional Fields', - name: 'additionalFields', - type: 'collection', - placeholder: 'Add Field', - default: {}, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'create', - ], - jsonParameters: [ - false, - ], - }, - }, - options: [ - { - displayName: 'Contact Ids', - name: 'contactIds', - type: 'string', - typeOptions: { - multipleValues: true, - multipleValueButtonText: 'Add ID', - }, - default: [], - placeholder: 'ID', - description: 'Unique contact identifiers.', - }, - { - displayName: 'Custom Data', - name: 'customData', - type: 'fixedCollection', - - description: 'Custom Data', - typeOptions: { - multipleValues: true, - }, - options: [ - { - displayName: 'Property', - name: 'customProperty', - values: [ - { - displayName: 'Name', - name: 'name', - type: 'string', - required: true, - default: "", - description: 'Property name.' - }, - { - displayName: 'Value', - name: 'value', - type: 'string', - default: "", - description: 'Property value.', - } - ] - }, - - ] - }, - ] - }, + /* -------------------------------------------------------------------------- */ + /* deal:get all */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Limit', + name: 'limit', + type: 'number', + default: 20, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'getAll', + ], + returnAll: [ + false, + ], + }, + }, + }, + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'getAll', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, -/* -------------------------------------------------------------------------- */ -/* deal:delete */ -/* -------------------------------------------------------------------------- */ -{ - displayName: 'Deal ID', - name: 'dealId', - type: 'string', - required: true, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'delete', - ], - }, - }, - default: '', - description: 'ID of deal to delete', -}, - -/* -------------------------------------------------------------------------- */ -/* deal:update */ -/* -------------------------------------------------------------------------- */ - { - displayName: 'Deal ID', - name: 'dealId', - type: 'string', - required: true, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'update', - ], - }, - }, - default: '', - description: 'Id of deal to update', - }, - { - displayName: 'JSON Parameters', - name: 'jsonParameters', - type: 'boolean', - default: false, - description: '', - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'update', - ], - }, - }, - }, - { - displayName: 'Additional Fields', - name: 'additionalFieldsJson', - type: 'json', - typeOptions: { - alwaysOpenEditWindow: true, - }, - default: '', - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'update', - ], - jsonParameters: [ - true, - ], - }, - }, - - description: `Object of values to set as described here.`, - }, - { - displayName: 'Additional Fields', - name: 'additionalFields', - type: 'collection', - placeholder: 'Add Field', - default: {}, - displayOptions: { - show: { - resource: [ - 'deal', - ], - operation: [ - 'update', - ], - jsonParameters: [ - false, - ], - }, - }, - options: [ - { - displayName: 'Expected Value', - name: 'expectedValue', - type: 'number', - typeOptions: { - minValue: 0, - maxValue: 10000 - }, - default: '', - description: 'Expected Value of deal.', - }, - { - displayName: 'Name', - name: 'name', - type: 'string', - default: '', - description: 'Name of deal.', - }, - { - displayName: 'Probability', - name: 'probability', - type: 'number', - typeOptions: { - minValue: 0, - maxValue: 100 - }, - default: 50, - description: 'Expected Value of deal.', - }, - { - displayName: 'Contact Ids', - name: 'contactIds', - type: 'string', - typeOptions: { - multipleValues: true, - multipleValueButtonText: 'Add ID', - }, - default: [], - placeholder: 'ID', - description: 'Unique contact identifiers.', - }, - { - displayName: 'Custom Data', - name: 'customData', - type: 'fixedCollection', - description: 'Custom Data', - typeOptions: { - multipleValues: true, - }, - options: [ - { - displayName: 'Property', - name: 'customProperty', - values: [ - { - displayName: 'Name', - name: 'name', - type: 'string', - required: true, - default: "", - description: 'Property name.' - }, - { - displayName: 'Value', - name: 'value', - type: 'string', - default: "", - description: 'Property value.', - } - ] - }, - - ] - }, - ] - }, + /* -------------------------------------------------------------------------- */ + /* deal:create */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Close Date', + name: 'closeDate', + type: 'dateTime', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + jsonParameters: [ + false, + ], + }, + }, + default: '', + description: 'Closing date of deal.', + }, + { + displayName: 'Expected Value', + name: 'expectedValue', + type: 'number', + required: true, + typeOptions: { + minValue: 0, + maxValue: 1000000000000 + }, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + jsonParameters: [ + false, + ], + }, + }, + default: 1, + description: 'Expected Value of deal.', + }, + { + displayName: 'Milestone', + name: 'milestone', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + jsonParameters: [ + false, + ], + }, + }, + default: '', + description: 'Milestone of deal.', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + jsonParameters: [ + false, + ], + }, + }, + default: '', + description: 'Name of deal.', + }, + { + displayName: 'Probability', + name: 'probability', + type: 'number', + required: true, + typeOptions: { + minValue: 0, + maxValue: 100 + }, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + jsonParameters: [ + false, + ], + }, + }, + default: 50, + description: 'Expected probability.', + }, + { + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + }, + }, + }, + { + displayName: ' Additional Fields', + name: 'additionalFieldsJson', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + jsonParameters: [ + true, + ], + }, + }, + description: `Object of values to set as described here.`, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'create', + ], + jsonParameters: [ + false, + ], + }, + }, + options: [ + { + displayName: 'Contact Ids', + name: 'contactIds', + type: 'string', + typeOptions: { + multipleValues: true, + multipleValueButtonText: 'Add ID', + }, + default: [], + description: 'Unique contact identifiers.', + }, + { + displayName: 'Custom Data', + name: 'customData', + type: 'fixedCollection', + description: 'Custom Data', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Property', + name: 'customProperty', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + default: '', + description: 'Property name.' + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Property value.', + }, + ], + }, + ], + }, + ], + }, + /* -------------------------------------------------------------------------- */ + /* deal:delete */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Deal ID', + name: 'dealId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'delete', + ], + }, + }, + default: '', + description: 'ID of deal to delete', + }, + + /* -------------------------------------------------------------------------- */ + /* deal:update */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Deal ID', + name: 'dealId', + type: 'string', + required: true, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + }, + }, + default: '', + description: 'Id of deal to update', + }, + { + displayName: 'JSON Parameters', + name: 'jsonParameters', + type: 'boolean', + default: false, + description: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + }, + }, + }, + { + displayName: 'Additional Fields', + name: 'additionalFieldsJson', + type: 'json', + typeOptions: { + alwaysOpenEditWindow: true, + }, + default: '', + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + jsonParameters: [ + true, + ], + }, + }, + + description: `Object of values to set as described here.`, + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + resource: [ + 'deal', + ], + operation: [ + 'update', + ], + jsonParameters: [ + false, + ], + }, + }, + options: [ + { + displayName: 'Expected Value', + name: 'expectedValue', + type: 'number', + typeOptions: { + minValue: 0, + maxValue: 10000 + }, + default: '', + description: 'Expected Value of deal.', + }, + { + displayName: 'Name', + name: 'name', + type: 'string', + default: '', + description: 'Name of deal.', + }, + { + displayName: 'Probability', + name: 'probability', + type: 'number', + typeOptions: { + minValue: 0, + maxValue: 100 + }, + default: 50, + description: 'Expected Value of deal.', + }, + { + displayName: 'Contact Ids', + name: 'contactIds', + type: 'string', + typeOptions: { + multipleValues: true, + multipleValueButtonText: 'Add ID', + }, + default: [], + description: 'Unique contact identifiers.', + }, + { + displayName: 'Custom Data', + name: 'customData', + type: 'fixedCollection', + description: 'Custom Data', + typeOptions: { + multipleValues: true, + }, + options: [ + { + displayName: 'Property', + name: 'customProperty', + values: [ + { + displayName: 'Name', + name: 'name', + type: 'string', + required: true, + default: '', + description: 'Property name.' + }, + { + displayName: 'Value', + name: 'value', + type: 'string', + default: '', + description: 'Property value.', + }, + ], + }, + ], + }, + ] + }, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/AgileCrm/DealInterface.ts b/packages/nodes-base/nodes/AgileCrm/DealInterface.ts index 930831a870..5b34f9fb7d 100644 --- a/packages/nodes-base/nodes/AgileCrm/DealInterface.ts +++ b/packages/nodes-base/nodes/AgileCrm/DealInterface.ts @@ -1,15 +1,15 @@ export interface IDealCustomProperty { - name: string; - value: string; + name: string; + value: string; } export interface IDeal { - id?: number; - expected_value?: number; - probability?: number; - name?: string; - close_date?: number; - milestone?: string; - contactIds?: string[]; - customData?: IDealCustomProperty[]; -} \ No newline at end of file + id?: number; + expected_value?: number; + probability?: number; + name?: string; + close_date?: number; + milestone?: string; + contactIds?: string[]; + customData?: IDealCustomProperty[]; +} diff --git a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts index 9a762044cd..8be59de7f5 100644 --- a/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts +++ b/packages/nodes-base/nodes/AgileCrm/GenericFunctions.ts @@ -1,6 +1,6 @@ import { OptionsWithUri - } from 'request'; +} from 'request'; import { IExecuteFunctions, @@ -12,81 +12,74 @@ import { import { IDataObject, } from 'n8n-workflow'; -import { IContactUpdate, IProperty } from './ContactInterface'; +import { IContactUpdate } from './ContactInterface'; -export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: any = {}, query: IDataObject = {}, uri?: string): Promise { +export async function agileCrmApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string, endpoint: string, body: any = {}, query: IDataObject = {}, uri?: string): Promise { // tslint:disable-line:no-any - const credentials = this.getCredentials('agileCrmApi'); + const credentials = this.getCredentials('agileCrmApi'); const options: OptionsWithUri = { method, headers: { 'Accept': 'application/json', }, - auth: { + auth: { username: credentials!.email as string, password: credentials!.apiKey as string }, uri: uri || `https://n8nio.agilecrm.com/dev/${endpoint}`, - json: true + json: true, }; // Only add Body property if method not GET or DELETE to avoid 400 response - if(method !== "GET" && method !== "DELETE"){ + if (method !== 'GET' && method !== 'DELETE') { options.body = body; } - try { return await this.helpers.request!(options); } catch (error) { - - if (error.response && error.response.body && error.response.body.errors) { - const errorMessages = error.response.body.errors.map((e: IDataObject) => e.message); - throw new Error(`AgileCRM error response [${error.statusCode}]: ${errorMessages.join(' | ')}`); - } - - throw error; + throw new Error(`AgileCRM error response: ${error.message}`); } } -export async function agileCrmApiRequestUpdate(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method = 'PUT', endpoint?: string, body: any = {}, query: IDataObject = {}, uri?: string): Promise { +export async function agileCrmApiRequestUpdate(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method = 'PUT', endpoint?: string, body: any = {}, query: IDataObject = {}, uri?: string): Promise { // tslint:disable-line:no-any const baseUri = 'https://n8nio.agilecrm.com/dev/'; - const credentials = this.getCredentials('agileCrmApi'); + const credentials = this.getCredentials('agileCrmApi'); const options: OptionsWithUri = { method, headers: { 'Accept': 'application/json', }, - body: {id: body.id}, - auth: { + body: { id: body.id }, + auth: { username: credentials!.email as string, - password: credentials!.apiKey as string + password: credentials!.apiKey as string, }, uri: uri || baseUri, - json: true + json: true, }; - const successfulUpdates = []; - let lastSuccesfulUpdateReturn : any; - const payload : IContactUpdate = body; - + const successfulUpdates = []; + let lastSuccesfulUpdateReturn: any; // tslint:disable-line:no-any + const payload: IContactUpdate = body; + try { // Due to API, we must update each property separately. For user it looks like one seamless update - if(payload.properties){ + if (payload.properties) { options.body.properties = payload.properties; options.uri = baseUri + 'api/contacts/edit-properties'; lastSuccesfulUpdateReturn = await this.helpers.request!(options); // Iterate trough properties and show them as individial updates instead of only vague "properties" - payload.properties?.map((property : any) => { - successfulUpdates.push(`${property.name} `); + payload.properties?.map((property: any) => { // tslint:disable-line:no-any + successfulUpdates.push(`${property.name}`); }); delete options.body.properties; } - if(payload.lead_score){ + if (payload.lead_score) { options.body.lead_score = payload.lead_score; options.uri = baseUri + 'api/contacts/edit/lead-score'; lastSuccesfulUpdateReturn = await this.helpers.request!(options); @@ -95,18 +88,18 @@ export async function agileCrmApiRequestUpdate(this: IHookFunctions | IExecuteFu delete options.body.lead_score; } - if(body.tags){ + if (body.tags) { options.body.tags = payload.tags; options.uri = baseUri + 'api/contacts/edit/tags'; lastSuccesfulUpdateReturn = await this.helpers.request!(options); - payload.tags?.map((tag : string) => { - successfulUpdates.push(`(Tag) ${tag} `); + payload.tags?.map((tag: string) => { + successfulUpdates.push(`(Tag) ${tag}`); }); delete options.body.tags; } - if(body.star_value){ + if (body.star_value) { options.body.star_value = payload.star_value; options.uri = baseUri + 'api/contacts/edit/add-star'; lastSuccesfulUpdateReturn = await this.helpers.request!(options); @@ -119,13 +112,11 @@ export async function agileCrmApiRequestUpdate(this: IHookFunctions | IExecuteFu return lastSuccesfulUpdateReturn; } catch (error) { - - if (error.response && error.response.body && error.response.body.errors) { - const errorMessages = error.response.body.errors.map((e: IDataObject) => e.message); - throw new Error(`AgileCRM error response [${error.statusCode}]: ${errorMessages.join(' | ')}`); + if (successfulUpdates.length === 0) { + throw new Error(`AgileCRM error response: ${error.message}`); + } else { + throw new Error(`Not all properties updated. Updated properties: ${successfulUpdates.join(', ')} \n \nAgileCRM error response: ${error.message}`); } - - throw new Error(`Not all items updated. Updated items: ${successfulUpdates.join(' , ')} \n \n` + error); } } @@ -139,4 +130,3 @@ export function validateJSON(json: string | undefined): any { // tslint:disable- } return result; } - diff --git a/packages/nodes-base/nodes/AgileCrm/agilecrm.png b/packages/nodes-base/nodes/AgileCrm/agilecrm.png index ef6ac995a32b776d569b203cbdd1969d99aa977b..711d2dc3b14cf5bab8dc1c4a234b9b1e1583ace4 100644 GIT binary patch delta 1210 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 UrKTU<{!