From 17916f29f6bbcd44b9c5ea90d1e2e66bb12a8887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C4=B1dvan=20Akca?= Date: Thu, 5 Oct 2023 14:03:05 +0300 Subject: [PATCH] feat(pipedrive): add create lead action --- .../pipedrive/actions/create-lead/index.ts | 199 ++++++++++++++++++ .../src/apps/pipedrive/actions/index.ts | 3 +- .../src/apps/pipedrive/dynamic-data/index.ts | 2 + .../dynamic-data/list-lead-labels/index.ts | 34 +++ packages/docs/pages/apps/pipedrive/actions.md | 10 +- .../web/src/components/DynamicField/index.tsx | 57 +++-- .../web/src/components/InputCreator/index.tsx | 1 + 7 files changed, 280 insertions(+), 26 deletions(-) create mode 100644 packages/backend/src/apps/pipedrive/actions/create-lead/index.ts create mode 100644 packages/backend/src/apps/pipedrive/dynamic-data/list-lead-labels/index.ts diff --git a/packages/backend/src/apps/pipedrive/actions/create-lead/index.ts b/packages/backend/src/apps/pipedrive/actions/create-lead/index.ts new file mode 100644 index 00000000..a8929cd9 --- /dev/null +++ b/packages/backend/src/apps/pipedrive/actions/create-lead/index.ts @@ -0,0 +1,199 @@ +import defineAction from '../../../../helpers/define-action'; + +type LabelIds = { __id: string; leadLabelId: string }[]; + +type LabelValue = { amount?: number; currency?: string }; + +function filterProvidedFields(body: Record) { + return Object.keys(body).reduce>((result, key) => { + if (body[key]) { + result[key] = body[key]; + } + return result; + }, {}); +} + +export default defineAction({ + name: 'Create lead', + key: 'createLead', + description: 'Creates a new lead.', + arguments: [ + { + label: 'Title', + key: 'title', + type: 'string' as const, + required: true, + description: '', + variables: true, + }, + { + label: 'Person', + key: 'personId', + type: 'dropdown' as const, + required: false, + description: + 'Lead must be associated with at least one person or organization.', + variables: true, + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listPersons', + }, + ], + }, + }, + { + label: 'Organization', + key: 'organizationId', + type: 'dropdown' as const, + required: false, + description: + 'Lead must be associated with at least one person or organization.', + variables: true, + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listOrganizations', + }, + ], + }, + }, + { + label: 'Owner', + key: 'ownerId', + type: 'dropdown' as const, + required: false, + description: + 'Select user who will be marked as the owner of this lead. If omitted, the authorized user will be used.', + variables: true, + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listUsers', + }, + ], + }, + }, + { + label: 'Lead Labels', + key: 'labelIds', + type: 'dynamic' as const, + required: false, + description: '', + fields: [ + { + label: 'Label', + key: 'leadLabelId', + type: 'dropdown' as const, + required: false, + variables: true, + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listLeadLabels', + }, + ], + }, + }, + ], + }, + { + label: 'Expected Close Date', + key: 'expectedCloseDate', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Lead Value', + key: 'value', + type: 'string' as const, + required: false, + description: '', + variables: true, + }, + { + label: 'Lead Value Currency', + key: 'currency', + type: 'dropdown' as const, + required: false, + description: 'This field is required if a Lead Value amount is provided.', + variables: true, + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listCurrencies', + }, + ], + }, + }, + ], + + async run($) { + const { + title, + personId, + organizationId, + ownerId, + labelIds, + expectedCloseDate, + value, + currency, + } = $.step.parameters; + + const onlyLabelIds = (labelIds as LabelIds) + .map((labelId) => labelId.leadLabelId) + .filter(Boolean); + + const labelValue: LabelValue = {}; + + if (value) { + labelValue.amount = Number(value); + } + if (currency) { + labelValue.currency = currency as string; + } + + const fields = { + title: title as string, + person_id: Number(personId), + organization_id: Number(organizationId), + owner_id: Number(ownerId), + expected_close_date: expectedCloseDate as string, + }; + + const body = filterProvidedFields(fields); + + if (onlyLabelIds.length) { + body.label_ids = onlyLabelIds; + } + + if (Object.keys(labelValue).length) { + body.value = labelValue; + } + + const { + data: { data }, + } = await $.http.post(`${$.auth.data.apiDomain}/api/v1/leads`, body); + + $.setActionItem({ + raw: data, + }); + }, +}); diff --git a/packages/backend/src/apps/pipedrive/actions/index.ts b/packages/backend/src/apps/pipedrive/actions/index.ts index 23450a7b..ecc301fd 100644 --- a/packages/backend/src/apps/pipedrive/actions/index.ts +++ b/packages/backend/src/apps/pipedrive/actions/index.ts @@ -1,5 +1,6 @@ import createActivity from './create-activity'; import createDeal from './create-deal'; +import createLead from './create-lead'; import createNote from './create-note'; -export default [createActivity, createDeal, createNote]; +export default [createActivity, createDeal, createLead, createNote]; diff --git a/packages/backend/src/apps/pipedrive/dynamic-data/index.ts b/packages/backend/src/apps/pipedrive/dynamic-data/index.ts index f10ab0e8..11f5ff52 100644 --- a/packages/backend/src/apps/pipedrive/dynamic-data/index.ts +++ b/packages/backend/src/apps/pipedrive/dynamic-data/index.ts @@ -2,6 +2,7 @@ import listActivityTypes from './list-activity-types'; import listCurrencies from './list-currencies'; import listDeals from './list-deals'; import listLeads from './list-leads'; +import listLeadLabels from './list-lead-labels'; import listOrganizations from './list-organizations'; import listPersons from './list-persons'; import listUsers from './list-users'; @@ -11,6 +12,7 @@ export default [ listCurrencies, listDeals, listLeads, + listLeadLabels, listOrganizations, listPersons, listUsers, diff --git a/packages/backend/src/apps/pipedrive/dynamic-data/list-lead-labels/index.ts b/packages/backend/src/apps/pipedrive/dynamic-data/list-lead-labels/index.ts new file mode 100644 index 00000000..1b98e1ec --- /dev/null +++ b/packages/backend/src/apps/pipedrive/dynamic-data/list-lead-labels/index.ts @@ -0,0 +1,34 @@ +import { IGlobalVariable, IJSONObject } from '@automatisch/types'; + +export default { + name: 'List lead labels', + key: 'listLeadLabels', + + async run($: IGlobalVariable) { + const leadLabels: { + data: IJSONObject[]; + } = { + data: [], + }; + + const { data } = await $.http.get( + `${$.auth.data.apiDomain}/api/v1/leadLabels` + ); + + if (!data?.data) { + return { data: [] }; + } + + if (data.data.length) { + for (const leadLabel of data.data) { + const name = `${leadLabel.name} (${leadLabel.color})`; + leadLabels.data.push({ + value: leadLabel.id, + name, + }); + } + } + + return leadLabels; + }, +}; diff --git a/packages/docs/pages/apps/pipedrive/actions.md b/packages/docs/pages/apps/pipedrive/actions.md index d10197ee..58a047d9 100644 --- a/packages/docs/pages/apps/pipedrive/actions.md +++ b/packages/docs/pages/apps/pipedrive/actions.md @@ -1,12 +1,14 @@ --- favicon: /favicons/pipedrive.svg items: - - name: Create deal - desc: Creates a new deal. - - name: Create note - desc: Creates a new note. - name: Create activity desc: Creates a new activity. + - name: Create deal + desc: Creates a new deal. + - name: Create lead + desc: Creates a new lead. + - name: Create note + desc: Creates a new note. ---