Improve google sheet integration (#437)
* fix integration modal error * Provider card icon dynamic * Google Sheets Integration Actions fetch integration data till interval * fix show form tablist - params slug issue * validation on delete connection --------- Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
parent
17476107df
commit
ca0864d0c0
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Integration\FormIntegration;
|
||||
use App\Models\OAuthProvider;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
|
@ -57,6 +58,10 @@ class OAuthProviderPolicy
|
|||
*/
|
||||
public function delete(User $user, OAuthProvider $provider)
|
||||
{
|
||||
$integrations = FormIntegration::where('oauth_id', $provider->id)->get();
|
||||
if ($integrations->count() > 0) {
|
||||
return $this->denyWithStatus(400, 'This connection cannot be removed because there is already an integration using it.');
|
||||
}
|
||||
return $provider->user()->is($user);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,10 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ml-auto">
|
||||
<div
|
||||
v-if="integration.data"
|
||||
class="ml-auto"
|
||||
>
|
||||
<v-button
|
||||
:href="integration.data.url"
|
||||
target="_blank"
|
||||
|
|
@ -27,7 +30,30 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
integration: Object,
|
||||
const props = defineProps({
|
||||
integration: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
}
|
||||
})
|
||||
|
||||
const formIntegrationsStore = useFormIntegrationsStore()
|
||||
let interval = null
|
||||
|
||||
onMounted(() => {
|
||||
if (!props.integration.data) {
|
||||
interval = setInterval(() => formIntegrationsStore.fetchFormIntegrations(props.form.id), 3000)
|
||||
setTimeout(() => { clearInterval(interval) }, 30000)
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (interval) {
|
||||
clearInterval(interval)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
:is="actionsComponent"
|
||||
v-if="actionsComponent"
|
||||
:integration="integration"
|
||||
:form="form"
|
||||
/>
|
||||
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -50,8 +50,7 @@ const props = defineProps({
|
|||
form: { type: Object, required: true },
|
||||
integrationKey: { type: String, required: true },
|
||||
integration: { type: Object, required: true },
|
||||
formIntegrationId: { type: Number, required: false, default: null },
|
||||
providers: { type: Array, required: true }
|
||||
formIntegrationId: { type: Number, required: false, default: null }
|
||||
})
|
||||
|
||||
const alert = useAlert()
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
class="mr-4 text-blue-500"
|
||||
>
|
||||
<Icon
|
||||
name="mdi:google"
|
||||
:name="service?.icon"
|
||||
size="32px"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -87,6 +87,7 @@ const props = defineProps({
|
|||
})
|
||||
|
||||
const providersStore = useOAuthProvidersStore()
|
||||
const service = computed(() => providersStore.getService(props.provider?.provider))
|
||||
const alert = useAlert()
|
||||
|
||||
function disconnect() {
|
||||
|
|
|
|||
|
|
@ -65,15 +65,7 @@ defineProps({
|
|||
const emit = defineEmits(['close'])
|
||||
|
||||
const providersStore = useOAuthProvidersStore()
|
||||
|
||||
const services = [
|
||||
{
|
||||
name: 'google',
|
||||
title: 'Google',
|
||||
icon: 'mdi:google',
|
||||
enabled: true
|
||||
},
|
||||
]
|
||||
const services = computed(() => providersStore.services)
|
||||
|
||||
function connect(service) {
|
||||
providersStore.connect(service.name)
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@
|
|||
class="mr-6"
|
||||
>
|
||||
<nuxt-link
|
||||
:to="{ name: tab.route }"
|
||||
:to="{ name: tab.route, params: tab.params ?? {} }"
|
||||
class="hover:no-underline inline-block py-4 rounded-t-lg border-b-2 text-gray-500 hover:text-gray-600"
|
||||
active-class="text-blue-600 hover:text-blue-900 dark:text-blue-500 dark:hover:text-blue-500 border-blue-600 dark:border-blue-500"
|
||||
>
|
||||
|
|
@ -277,18 +277,22 @@ const tabsList = [
|
|||
{
|
||||
name: "Submissions",
|
||||
route: "forms-slug-show-submissions",
|
||||
params: { 'slug': slug }
|
||||
},
|
||||
{
|
||||
name: "Integrations",
|
||||
route: "forms-slug-show-integrations",
|
||||
params: { 'slug': slug }
|
||||
},
|
||||
{
|
||||
name: "Analytics",
|
||||
route: "forms-slug-show-stats",
|
||||
params: { 'slug': slug }
|
||||
},
|
||||
{
|
||||
name: "Share",
|
||||
route: "forms-slug-show-share",
|
||||
params: { 'slug': slug }
|
||||
},
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,21 @@ export const useOAuthProvidersStore = defineStore("oauth_providers", () => {
|
|||
const contentStore = useContentStore()
|
||||
const alert = useAlert()
|
||||
|
||||
const services = computed(() => {
|
||||
return [
|
||||
{
|
||||
name: 'google',
|
||||
title: 'Google',
|
||||
icon: 'mdi:google',
|
||||
enabled: true
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
const getService = (service) => {
|
||||
return services.value.find((item) => item.name === service)
|
||||
}
|
||||
|
||||
const fetchOAuthProviders = () => {
|
||||
contentStore.resetState()
|
||||
contentStore.startLoading()
|
||||
|
|
@ -50,6 +65,8 @@ export const useOAuthProvidersStore = defineStore("oauth_providers", () => {
|
|||
|
||||
return {
|
||||
...contentStore,
|
||||
services,
|
||||
getService,
|
||||
fetchOAuthProviders,
|
||||
providers,
|
||||
connect
|
||||
|
|
|
|||
Loading…
Reference in New Issue