From 8a6ce607f1ab9c2115b64632394c1a75fad76d23 Mon Sep 17 00:00:00 2001 From: Gasper Grom Date: Thu, 20 Jul 2023 15:52:25 +0200 Subject: [PATCH 01/42] Automation refactoring --- .../automation/components/automation-form.vue | 6 ++ .../config/automation-types/hubspot.ts | 16 ++++ .../config/automation-types/index.ts | 27 +++++++ .../config/automation-types/slack.ts | 35 +++++++++ .../config/automation-types/webhook.ts | 12 +++ .../automation/pages/automation-list-page.vue | 76 ++++++++----------- 6 files changed, 127 insertions(+), 45 deletions(-) create mode 100644 frontend/src/modules/automation/config/automation-types/hubspot.ts create mode 100644 frontend/src/modules/automation/config/automation-types/index.ts create mode 100644 frontend/src/modules/automation/config/automation-types/slack.ts create mode 100644 frontend/src/modules/automation/config/automation-types/webhook.ts diff --git a/frontend/src/modules/automation/components/automation-form.vue b/frontend/src/modules/automation/components/automation-form.vue index 41ed5d35ac..7e03d3ccaa 100644 --- a/frontend/src/modules/automation/components/automation-form.vue +++ b/frontend/src/modules/automation/components/automation-form.vue @@ -18,6 +18,12 @@ Slack notification

+
+ HubSpot +

+ HubSpot +

+

Add automation

diff --git a/frontend/src/modules/automation/config/automation-types/hubspot.ts b/frontend/src/modules/automation/config/automation-types/hubspot.ts new file mode 100644 index 0000000000..4590cc2690 --- /dev/null +++ b/frontend/src/modules/automation/config/automation-types/hubspot.ts @@ -0,0 +1,16 @@ +import { AutomationTypeConfig } from '@/modules/automation/config/automation-types/index'; +import { CrowdIntegrations } from '@/integrations/integrations-config'; + +export const hubspot: AutomationTypeConfig = { + name: 'HubSpot', + description: 'Send members or organizations to HubSpot', + icon: '/images/integrations/hubspot.png', + canCreate(store) { + const hubspot = CrowdIntegrations.getMappedConfig('hubspot', store); + return hubspot.status === 'done'; + }, + disabled(store) { + const hubspot = CrowdIntegrations.getMappedConfig('hubspot', store); + return hubspot.status !== 'done'; + }, +}; diff --git a/frontend/src/modules/automation/config/automation-types/index.ts b/frontend/src/modules/automation/config/automation-types/index.ts new file mode 100644 index 0000000000..d34fa70e93 --- /dev/null +++ b/frontend/src/modules/automation/config/automation-types/index.ts @@ -0,0 +1,27 @@ +import { webhook } from './webhook'; +import { slack } from './slack'; +import { hubspot } from './hubspot'; + +interface AutomationTypeAction { + label: string; + action: () => void; +} + +export interface AutomationTypeConfig { + name: string; + description: string; + icon: string; + canCreate: (store: any) => boolean; + actionButton?: (store: any) => AutomationTypeAction | null; + disabled?: (store: any) => boolean; + emptyScreen?: { + title: string; + body: string; + } +} + +export const automationTypes: Record = { + hubspot, + slack, + webhook, +}; diff --git a/frontend/src/modules/automation/config/automation-types/slack.ts b/frontend/src/modules/automation/config/automation-types/slack.ts new file mode 100644 index 0000000000..bc48bb36b7 --- /dev/null +++ b/frontend/src/modules/automation/config/automation-types/slack.ts @@ -0,0 +1,35 @@ +import { AutomationTypeConfig } from '@/modules/automation/config/automation-types/index'; +import config from '@/config'; +import { AuthToken } from '@/modules/auth/auth-token'; + +export const slack: AutomationTypeConfig = { + name: 'Slack notification', + description: 'Send notifications to your Slack workspace', + icon: 'https://cdn-icons-png.flaticon.com/512/3800/3800024.png', + emptyScreen: { + title: 'No Slack notifications yet', + body: 'Send Slack notifications when a new activity happens, or a new member joins your community', + }, + canCreate(store) { + const tenant = store.getters['auth/currentTenant']; + return !!tenant.settings[0].slackWebHook; + }, + actionButton(store) { + const tenant = store.getters['auth/currentTenant']; + const slackConnected = !!tenant.settings[0].slackWebHook; + if (slackConnected) { + return null; + } + return { + label: 'Install app', + action: () => { + const redirectUrl = `${window.location.protocol}//${window.location.host}${window.location.pathname}?activeTab=automations&success=true`; + const slackConnectUrl = `${config.backendUrl}/tenant/${ + tenant.id + }/automation/slack?redirectUrl=${redirectUrl}&crowdToken=${AuthToken.get()}`; + + window.open(slackConnectUrl, '_self'); + }, + }; + }, +}; diff --git a/frontend/src/modules/automation/config/automation-types/webhook.ts b/frontend/src/modules/automation/config/automation-types/webhook.ts new file mode 100644 index 0000000000..1078b3e87f --- /dev/null +++ b/frontend/src/modules/automation/config/automation-types/webhook.ts @@ -0,0 +1,12 @@ +import { AutomationTypeConfig } from '@/modules/automation/config/automation-types/index'; + +export const webhook: AutomationTypeConfig = { + name: 'Webhook', + description: 'Send webhook payloads to automate workflows', + icon: '/images/automation/webhook.png', + emptyScreen: { + title: 'No Webhooks yet', + body: 'Create webhook actions when a new activity happens, or a new member joins your community', + }, + canCreate: () => true, +}; diff --git a/frontend/src/modules/automation/pages/automation-list-page.vue b/frontend/src/modules/automation/pages/automation-list-page.vue index c0ba3a6064..ab207ae838 100644 --- a/frontend/src/modules/automation/pages/automation-list-page.vue +++ b/frontend/src/modules/automation/pages/automation-list-page.vue @@ -31,43 +31,34 @@ -
-
-
- Webhook -
-
-
- Webhook -
-

- Send webhook payloads to automate workflows -

-
-
-
+
- Slack +
- Slack notification + {{ automationType.name }}

- Send notifications to your Slack workspace + {{ automationType.description }}

- Install app + {{ automationType.actionButton(store).label }}
@@ -89,16 +80,10 @@ - ({ + label: config.name, + value: key, + }))), ]); const openAutomationForm = ref(false); const automationFormType = ref(null); @@ -162,6 +146,8 @@ const { getAutomations, changeAutomationFilter } = automationStore; const { currentTenant } = mapGetters('auth'); +const store = useStore(); + /** * Check if tenant has feature flag enabled */ @@ -183,6 +169,10 @@ const canAddAutomation = () => { // Executions drawer const createAutomation = (type) => { + if (!automationTypes[type].canCreate(store)) { + return; + } + if (!canAddAutomation()) { return; } @@ -215,10 +205,6 @@ const authenticateSlack = () => { const createSlackAutomation = () => { if (slackConnected.value) { - if (!canAddAutomation()) { - return; - } - createAutomation('slack'); } }; From 9d1333a054807b2210afb8c68fbb7464949a0376 Mon Sep 17 00:00:00 2001 From: Gasper Grom Date: Fri, 21 Jul 2023 11:02:29 +0200 Subject: [PATCH 02/42] Split to configuration --- frontend/public/icons/crowd-icons.svg | 2 +- .../components/discourse-connect-drawer.vue | 2 +- .../slack/components/slack-connect.vue | 2 +- .../automation/components/automation-form.vue | 90 ++++-------------- .../executions/automation-execution.vue | 2 +- .../config/automation-types/hubspot.ts | 16 ---- .../config/automation-types/hubspot/config.ts | 24 +++++ .../hubspot/hubspot-action.vue | 73 +++++++++++++++ .../hubspot/hubspot-trigger.vue | 91 +++++++++++++++++++ .../config/automation-types/index.ts | 36 +++++--- .../new-activity-filter-options.vue | 0 .../new-member-filter-options.vue | 0 .../shared/trigger-member-activity.vue | 53 +++++++++++ .../{slack.ts => slack/config.ts} | 9 +- .../automation-types/slack}/slack-action.vue | 0 .../config/automation-types/webhook.ts | 12 --- .../config/automation-types/webhook/config.ts | 19 ++++ .../webhook}/webhook-action.vue | 0 .../automation/pages/automation-list-page.vue | 4 +- 19 files changed, 315 insertions(+), 120 deletions(-) delete mode 100644 frontend/src/modules/automation/config/automation-types/hubspot.ts create mode 100644 frontend/src/modules/automation/config/automation-types/hubspot/config.ts create mode 100644 frontend/src/modules/automation/config/automation-types/hubspot/hubspot-action.vue create mode 100644 frontend/src/modules/automation/config/automation-types/hubspot/hubspot-trigger.vue rename frontend/src/modules/automation/{components => config/automation-types/shared}/filter-options/new-activity-filter-options.vue (100%) rename frontend/src/modules/automation/{components => config/automation-types/shared}/filter-options/new-member-filter-options.vue (100%) create mode 100644 frontend/src/modules/automation/config/automation-types/shared/trigger-member-activity.vue rename frontend/src/modules/automation/config/automation-types/{slack.ts => slack/config.ts} (72%) rename frontend/src/modules/automation/{components/action => config/automation-types/slack}/slack-action.vue (100%) delete mode 100644 frontend/src/modules/automation/config/automation-types/webhook.ts create mode 100644 frontend/src/modules/automation/config/automation-types/webhook/config.ts rename frontend/src/modules/automation/{components/action => config/automation-types/webhook}/webhook-action.vue (100%) diff --git a/frontend/public/icons/crowd-icons.svg b/frontend/public/icons/crowd-icons.svg index 9c3fd0b8ee..20954faa40 100644 --- a/frontend/public/icons/crowd-icons.svg +++ b/frontend/public/icons/crowd-icons.svg @@ -30,7 +30,7 @@ - + diff --git a/frontend/src/integrations/discourse/components/discourse-connect-drawer.vue b/frontend/src/integrations/discourse/components/discourse-connect-drawer.vue index 56536ba330..9cb1222560 100644 --- a/frontend/src/integrations/discourse/components/discourse-connect-drawer.vue +++ b/frontend/src/integrations/discourse/components/discourse-connect-drawer.vue @@ -144,7 +144,7 @@
- Verify webhook + Verify config
diff --git a/frontend/src/integrations/slack/components/slack-connect.vue b/frontend/src/integrations/slack/components/slack-connect.vue index bc13d4fe2c..48bc712bdf 100644 --- a/frontend/src/integrations/slack/components/slack-connect.vue +++ b/frontend/src/integrations/slack/components/slack-connect.vue @@ -19,7 +19,7 @@ defineProps({ const connectUrl = computed(() => { const redirectUrl = `${window.location.protocol}//${window.location.host}${window.location.pathname}?success=true`; - return `${config.backendUrl}/slack/${ + return `${config.backendUrl}/config/${ store.getters['auth/currentTenant'].id }/connect?redirectUrl=${redirectUrl}&crowdToken=${AuthToken.get()}`; }); diff --git a/frontend/src/modules/automation/components/automation-form.vue b/frontend/src/modules/automation/components/automation-form.vue index 7e03d3ccaa..518ccf7b4d 100644 --- a/frontend/src/modules/automation/components/automation-form.vue +++ b/frontend/src/modules/automation/components/automation-form.vue @@ -1,27 +1,16 @@ +