Improve Integration Cards (#643)

* Add integration action components and update integration JSON files

- Introduced new action components for Email, Slack, Discord, Webhook, and Google Sheets integrations, enhancing the user interface for managing these integrations.
- Updated the `integrations.json` files to include `actions_file_name` for each integration, linking them to their respective action components.
- Improved the `GoogleSheetsIntegrationActions.vue` component by replacing direct provider information display with a badge for better UI consistency.

These changes aim to streamline integration management and improve the overall user experience.

* Minor UI fixes

---------

Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
Chirag Chhatrala
2024-12-18 17:37:19 +05:30
committed by GitHub
parent 49c2d6bf04
commit c1ee072b71
9 changed files with 235 additions and 9 deletions

View File

@@ -0,0 +1,46 @@
<template>
<div class="flex flex-1 items-center">
<div
v-if="integration"
class="hidden md:block space-y-1"
>
<UBadge
:label="mentionAsText(integration.data.message)"
color="gray"
size="xs"
class="max-w-[300px] truncate"
/>
</div>
</div>
</template>
<script setup>
import { mentionAsText } from '~/lib/utils.js'
const props = defineProps({
integration: {
type: Object,
required: true,
},
form: {
type: Object,
required: true,
}
})
const formIntegrationsStore = useFormIntegrationsStore()
let interval = null
onMounted(() => {
if (!props.integration.data || props.integration.data.length === 0) {
interval = setInterval(() => formIntegrationsStore.fetchFormIntegrations(props.form.id), 3000)
setTimeout(() => { clearInterval(interval) }, 30000)
}
})
onBeforeUnmount(() => {
if (interval) {
clearInterval(interval)
}
})
</script>

View File

@@ -0,0 +1,70 @@
<template>
<div class="flex flex-1 items-center">
<div
v-if="integration"
class="hidden md:block space-y-1"
>
<UBadge
:label="mentionAsText(integration.data.subject)"
color="gray"
size="xs"
class="max-w-[300px] block truncate"
/>
<div class="flex items-center gap-1">
<UBadge
:label="firstEmail"
color="white"
size="xs"
class="max-w-[300px] block truncate"
/>
<UBadge
v-if="additionalEmailsCount > 0"
:label="`+${additionalEmailsCount}`"
color="white"
size="xs"
/>
</div>
</div>
</div>
</template>
<script setup>
import { mentionAsText } from '~/lib/utils.js'
const props = defineProps({
integration: {
type: Object,
required: true,
},
form: {
type: Object,
required: true,
}
})
const formIntegrationsStore = useFormIntegrationsStore()
let interval = null
onMounted(() => {
if (!props.integration.data || props.integration.data.length === 0) {
interval = setInterval(() => formIntegrationsStore.fetchFormIntegrations(props.form.id), 3000)
setTimeout(() => { clearInterval(interval) }, 30000)
}
})
onBeforeUnmount(() => {
if (interval) {
clearInterval(interval)
}
})
const firstEmail = computed(() => {
const emails = mentionAsText(props.integration.data.send_to).split('\n').filter(Boolean)
return emails[0] || ''
})
const additionalEmailsCount = computed(() => {
const emails = mentionAsText(props.integration.data.send_to).split('\n').filter(Boolean)
return Math.max(0, emails.length - 1)
})
</script>

View File

@@ -4,14 +4,12 @@
v-if="integration.provider"
class="hidden md:block space-y-1"
>
<div
class="font-medium mr-2"
>
{{ integration.provider.name }}
</div>
<div class="text-sm">
{{ integration.provider.email }}
</div>
<UBadge
:label="mentionAsText(integration.provider.email)"
color="gray"
size="xs"
class="max-w-[300px] truncate"
/>
</div>
<div
@@ -39,6 +37,8 @@
</template>
<script setup>
import { mentionAsText } from '~/lib/utils.js'
const props = defineProps({
integration: {
type: Object,

View File

@@ -3,7 +3,7 @@
class="text-gray-500 border shadow rounded-md p-5 mt-4 relative flex items-center"
>
<div
class="flex items-center"
class="flex items-center w-full md:max-w-[240px]"
:class="{'flex-grow': !actionsComponent}"
>
<div

View File

@@ -0,0 +1,46 @@
<template>
<div class="flex flex-1 items-center">
<div
v-if="integration"
class="hidden md:block space-y-1"
>
<UBadge
:label="mentionAsText(integration.data.message)"
color="gray"
size="xs"
class="max-w-[300px] block truncate"
/>
</div>
</div>
</template>
<script setup>
import { mentionAsText } from '~/lib/utils.js'
const props = defineProps({
integration: {
type: Object,
required: true,
},
form: {
type: Object,
required: true,
}
})
const formIntegrationsStore = useFormIntegrationsStore()
let interval = null
onMounted(() => {
if (!props.integration.data || props.integration.data.length === 0) {
interval = setInterval(() => formIntegrationsStore.fetchFormIntegrations(props.form.id), 3000)
setTimeout(() => { clearInterval(interval) }, 30000)
}
})
onBeforeUnmount(() => {
if (interval) {
clearInterval(interval)
}
})
</script>

View File

@@ -0,0 +1,44 @@
<template>
<div class="flex flex-1 items-center">
<div
v-if="integration"
class="hidden md:block space-y-1"
>
<UBadge
:label="integration.data.webhook_url"
color="gray"
size="xs"
class="max-w-[300px] block truncate"
/>
</div>
</div>
</template>
<script setup>
const props = defineProps({
integration: {
type: Object,
required: true,
},
form: {
type: Object,
required: true,
}
})
const formIntegrationsStore = useFormIntegrationsStore()
let interval = null
onMounted(() => {
if (!props.integration.data || props.integration.data.length === 0) {
interval = setInterval(() => formIntegrationsStore.fetchFormIntegrations(props.form.id), 3000)
setTimeout(() => { clearInterval(interval) }, 30000)
}
})
onBeforeUnmount(() => {
if (interval) {
clearInterval(interval)
}
})
</script>