Skip to content

Commit cf5a88b

Browse files
authored
Feature/zapier frontend (#739)
1 parent f55518d commit cf5a88b

5 files changed

Lines changed: 178 additions & 61 deletions

File tree

frontend/src/assets/scss/typography.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ html body {
22
margin: 0;
33
padding: 0;
44
height: 100%;
5-
font-family: 'Inter', sans-serif;
5+
font-family: "Inter", sans-serif;
66
font-weight: 400;
77
-webkit-font-smoothing: antialiased;
88
}
99

1010
@supports (font-variation-settings: normal) {
1111
html {
12-
font-family: 'Inter var', sans-serif;
12+
font-family: "Inter var", sans-serif;
1313
}
1414
}
1515

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<template>
2+
<app-drawer
3+
v-model="isVisible"
4+
custom-class="integration-reddit-drawer"
5+
title="Zapier"
6+
size="600px"
7+
pre-title="Integration"
8+
:pre-title-img-src="logoUrl"
9+
pre-title-img-alt="Zapier logo"
10+
@close="isVisible = false"
11+
>
12+
<template #content>
13+
<div class="flex flex-row items-center justify-between w-full">
14+
<p class="font-bold text-base">Set up crowd.dev in Zapier</p>
15+
<a
16+
href="https://docs.crowd.dev/docs/zapier-integration"
17+
target="_blank"
18+
rel="noopener noreferrer"
19+
class="btn btn--bordered btn--md"
20+
><i class="ri-external-link-line mr-2" />Read our docs</a
21+
>
22+
</div>
23+
<div class="container mx-auto px-4 py-10">
24+
<ul class="list-none space-y-4">
25+
<li class="flex items-start">
26+
<span
27+
class="flex-none w-8 h-8 flex justify-center items-center rounded-full bg-gray-300 text-white font-bold"
28+
>1</span
29+
>
30+
<p class="ml-4 text-gray-900">
31+
Navigate to Settings >
32+
<a
33+
href="/settings?activeTab=api-keys"
34+
target="_blank"
35+
rel="noopener noreferrer"
36+
class="underline underline-offset-4"
37+
>API Keys</a
38+
>
39+
and get your workspace <b>Tenant ID</b> and <b>Auth token</b>
40+
</p>
41+
</li>
42+
<li class="flex items-start">
43+
<span
44+
class="flex-none w-8 h-8 flex justify-center items-center rounded-full bg-gray-300 text-white font-bold"
45+
>2</span
46+
>
47+
<p class="ml-4 text-gray-900">
48+
Go to
49+
<a
50+
href="https://zapier.com/developer/public-invite/180721/f94ad64f963359cd888fa22610c31875/"
51+
target="_blank"
52+
rel="noopener noreferrer"
53+
class="underline underline-offset-4"
54+
>Zapier</a
55+
>
56+
and connect your crowd.dev account using your workspace API Keys
57+
</p>
58+
</li>
59+
<li class="flex items-center">
60+
<span
61+
class="flex-none w-8 h-8 flex justify-center items-center rounded-full bg-gray-300 text-white font-bold"
62+
>3</span
63+
>
64+
<p class="ml-4 text-gray-900">
65+
Configure your Zaps using our
66+
<a
67+
href="https://docs.crowd.dev/docs/zapier-integration#supported-triggers"
68+
target="_blank"
69+
rel="noopener noreferrer"
70+
class="underline underline-offset-4"
71+
>supported triggers and actions</a
72+
>
73+
</p>
74+
</li>
75+
</ul>
76+
<!-- <a
77+
class="btn btn--md btn--primary mt-4 ml-12"
78+
href=""
79+
>Explore our Zap templates</a
80+
> -->
81+
</div>
82+
</template>
83+
</app-drawer>
84+
</template>
85+
86+
<script setup>
87+
import { computed, defineEmits, defineProps } from "vue";
88+
import { CrowdIntegrations } from "@/integrations/integrations-config";
89+
90+
const props = defineProps({
91+
modelValue: {
92+
type: Boolean,
93+
default: false,
94+
},
95+
});
96+
97+
const emit = defineEmits(["update:modelValue"]);
98+
99+
const logoUrl = CrowdIntegrations.getConfig("zapier").image;
100+
101+
const isVisible = computed({
102+
get() {
103+
return props.modelValue;
104+
},
105+
set(value) {
106+
return emit("update:modelValue", value);
107+
},
108+
});
109+
</script>
110+
111+
<script>
112+
export default {
113+
name: "AppZapierConnectDrawer",
114+
};
115+
</script>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<template>
2+
<slot :connect="connect" />
3+
<app-zapier-connect-drawer v-model="drawerVisible" />
4+
</template>
5+
6+
<script setup>
7+
import { ref } from "vue";
8+
import AppZapierConnectDrawer from "@/integrations/zapier/components/zapier-connect-drawer.vue";
9+
10+
const drawerVisible = ref(false);
11+
const connect = () => {
12+
drawerVisible.value = true;
13+
};
14+
</script>
15+
16+
<script>
17+
export default {
18+
name: "AppZapierConnect",
19+
};
20+
</script>
Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
import ZapierConnect from "./components/zapier-connect.vue";
2+
13
export default {
2-
enabled: false,
3-
name: 'Zapier',
4-
backgroundColor: '#FFFFFF',
5-
borderColor: '#FFFFFF',
4+
enabled: true,
5+
name: "Zapier",
6+
backgroundColor: "#FFFFFF",
7+
borderColor: "#FFFFFF",
68
description:
7-
"We're currently working on this integration.",
9+
"Enable the communication between crowd.dev and Zapier to automate workflows and tasks.",
810
image:
9-
'https://www.seekpng.com/png/full/67-672759_zapiers-new-cli-tool-for-creating-apps-zapier.png',
11+
"https://www.seekpng.com/png/full/67-672759_zapiers-new-cli-tool-for-creating-apps-zapier.png",
12+
connectComponent: ZapierConnect,
1013
};

frontend/src/modules/integration/components/integration-list-item.vue

Lines changed: 32 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,13 @@
11
<template>
22
<div class="s panel" :class="computedClass">
33
<div class="flex items-center justify-between">
4-
<img
5-
:alt="integration.name"
6-
:src="integration.image"
7-
class="h-6 mb-4"
8-
/>
9-
<span
10-
v-if="isDone"
11-
class="badge badge--green"
12-
>Connected</span>
13-
<div
14-
v-else-if="isError"
15-
class="text-red-500 flex items-center text-sm"
16-
>
17-
<i class="ri-error-warning-line mr-1" /> Failed to
18-
connect
4+
<img :alt="integration.name" :src="integration.image" class="h-6 mb-4" />
5+
<span v-if="isDone" class="badge badge--green">Connected</span>
6+
<div v-else-if="isError" class="text-red-500 flex items-center text-sm">
7+
<i class="ri-error-warning-line mr-1" /> Failed to connect
198
</div>
20-
<div
21-
v-else-if="isNoData"
22-
class="text-red-500 flex items-center text-sm"
23-
>
24-
<i class="ri-error-warning-line mr-1" /> Not
25-
receiving activities
9+
<div v-else-if="isNoData" class="text-red-500 flex items-center text-sm">
10+
<i class="ri-error-warning-line mr-1" /> Not receiving activities
2611
</div>
2712
<div
2813
v-else-if="isWaitingForAction"
@@ -34,13 +19,9 @@
3419
v-else-if="isWaitingApproval"
3520
class="text-gray-500 flex items-center text-sm"
3621
>
37-
<i class="ri-time-line mr-1" /> Waiting for
38-
approval
22+
<i class="ri-time-line mr-1" /> Waiting for approval
3923
</div>
40-
<div
41-
v-else-if="isConnected"
42-
class="flex items-center"
43-
>
24+
<div v-else-if="isConnected" class="flex items-center">
4425
<div
4526
v-loading="true"
4627
class="app-page-spinner !relative h-4 !w-4 mr-2 !min-h-fit"
@@ -57,13 +38,10 @@
5738
</div>
5839
<div>
5940
<div class="flex mb-2">
60-
<span class="block font-semibold">{{
61-
integration.name
41+
<span class="block font-semibold">{{ integration.name }}</span>
42+
<span v-if="integration.premium" class="text-2xs text-brand-500 ml-1">{{
43+
FeatureFlag.premiumFeatureCopy()
6244
}}</span>
63-
<span
64-
v-if="integration.premium"
65-
class="text-2xs text-brand-500 ml-1"
66-
>{{ FeatureFlag.premiumFeatureCopy() }}</span>
6745
</div>
6846
<span class="block mb-6 text-xs text-gray-500">{{
6947
integration.description
@@ -85,10 +63,11 @@
8563
@click="connect"
8664
>
8765
{{
88-
integration.premium === true
89-
&& !hasIntegration
90-
? 'Upgrade Plan'
91-
: 'Connect'
66+
integration.premium === true && !hasIntegration
67+
? "Upgrade Plan"
68+
: integration.platform === "zapier"
69+
? "Learn how to connect"
70+
: "Connect"
9271
}}
9372
</el-button>
9473
<el-button
@@ -114,10 +93,10 @@
11493
</template>
11594

11695
<script setup>
117-
import { useStore } from 'vuex';
118-
import { defineProps, computed, ref } from 'vue';
119-
import { FeatureFlag } from '@/featureFlag';
120-
import AppIntegrationConnect from '@/modules/integration/components/integration-connect.vue';
96+
import { useStore } from "vuex";
97+
import { defineProps, computed, ref } from "vue";
98+
import { FeatureFlag } from "@/featureFlag";
99+
import AppIntegrationConnect from "@/modules/integration/components/integration-connect.vue";
121100
122101
const store = useStore();
123102
const props = defineProps({
@@ -128,37 +107,37 @@ const props = defineProps({
128107
});
129108
130109
const computedClass = computed(() => ({
131-
'integration-custom':
132-
props.integration.platform === 'custom',
110+
"integration-custom": props.integration.platform === "custom",
133111
}));
134112
135113
const isConnected = computed(() => props.integration.status !== undefined);
136114
137-
const isDone = computed(() => props.integration.status === 'done');
115+
const isDone = computed(() => props.integration.status === "done");
138116
139-
const isError = computed(() => props.integration.status === 'error');
117+
const isError = computed(() => props.integration.status === "error");
140118
141-
const isNoData = computed(() => props.integration.status === 'no-data');
119+
const isNoData = computed(() => props.integration.status === "no-data");
142120
143-
const isWaitingForAction = computed(() => props.integration.status === 'pending-action');
121+
const isWaitingForAction = computed(
122+
() => props.integration.status === "pending-action"
123+
);
144124
145-
const isWaitingApproval = computed(() => props.integration.status === 'waiting-approval');
125+
const isWaitingApproval = computed(
126+
() => props.integration.status === "waiting-approval"
127+
);
146128
147129
const loadingDisconnect = ref(false);
148130
149131
const handleDisconnect = async () => {
150132
loadingDisconnect.value = true;
151-
await store.dispatch(
152-
'integration/doDestroy',
153-
props.integration.id,
154-
);
133+
await store.dispatch("integration/doDestroy", props.integration.id);
155134
loadingDisconnect.value = false;
156135
};
157136
</script>
158137

159138
<script>
160139
export default {
161-
name: 'AppIntegrationListItem',
140+
name: "AppIntegrationListItem",
162141
};
163142
</script>
164143

0 commit comments

Comments
 (0)