Notification & Integrations refactoring (#346)

* Integrations Refactoring - WIP

* integrations list & edit - WIP

* Fix integration store binding issue

* integrations refactor - WIP

* Form integration - WIP

* Form integration Edit - WIP

* Integration Refactor - Slack - WIP

* Integration Refactor - Discord - WIP

* Integration Refactor - Webhook - WIP

* Integration Refactor - Send Submission Confirmation - WIP

* Integration Refactor - Backend handler - WIP

* Form Integration Status field

* Integration Refactor - Backend SubmissionConfirmation - WIP

* IntegrationMigration Command

* skip confirmation email test case

* Small refactoring

* FormIntegration status active/inactive

* formIntegrationData to integrationData

* Rename file name with Integration suffix for integration realted files

* Loader on form integrations

* WIP

* form integration test case

* WIP

* Added Integration card - working on refactoring

* change location for IntegrationCard and update package file

* Form Integration Create/Edit in single Modal

* Remove integration extra pages

* crisp_help_page_slug for integration json

* integration logic as collapse

* UI improvements

* WIP

* Trying to debug vue devtools

* WIP for integrations

* getIntegrationHandler change namespace name

* useForm for integration fields + validation structure

* Integration Test case & apply validation rules

* Apply useform changes to integration other files

* validation rules for FormNotificationsMessageActions fields

* Zapier integration as coming soon

* Update FormCleaner

* set default settings for confirmation integration

* WIP

* Finish validation for all integrations

* Updated purify, added integration formatData

* Fix testcase

* Ran pint; working on integration errors

* Handle integration events

* command for Delete Old Integration Events

* Display Past Events in Modal

* on Integration event create with status error send email to form creator

* Polish styling

* Minor improvements

* Finish badge and integration status

* Fix tests and add an integration event test

* Lint

---------

Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
formsdev
2024-03-28 22:44:30 +05:30
committed by GitHub
parent d9996e0d9d
commit 6f61faa9ef
84 changed files with 6121 additions and 2205 deletions

View File

@@ -0,0 +1,50 @@
<template>
<div :class="classes">
<Icon v-if="beforeIcon" :name="beforeIcon" :class="iconClasses"/>
<slot></slot>
<Icon v-if="afterIcon" :name="afterIcon" :class="iconClasses"/>
</div>
</template>
<script setup>
const props = defineProps({
color: {
type: String,
default: 'green'
},
beforeIcon: {
type: String,
default: null
},
afterIcon: {
type: String,
default: null
}
})
const baseClasses = {
'green': ['bg-green-100', 'border', 'border-green-300', 'text-green-700'],
'red': ['bg-red-100', 'border', 'border-red-300', 'text-red-700'],
'gray': ['bg-gray-100', 'border', 'border-gray-300', 'text-gray-700'],
}
const iconBaseClasses = {
'green': ['text-green-500'],
'red': ['text-red-500'],
'gray': ['text-gray-500'],
}
const activeColor = computed(() => {
return Object.hasOwn(baseClasses, props.color) ? props.color : 'gray'
})
const classes = computed(() => {
const classes = ['border', 'text-xs', 'px-2', 'inline-flex', 'items-center', 'rounded-full'].concat(baseClasses[activeColor.value])
return classes.join(' ')
})
const iconClasses = computed(() => {
return iconBaseClasses[activeColor.value].concat(['w-2 h-2 mr-1']).join(' ')
})
</script>

View File

@@ -7,7 +7,7 @@
@click.self="close"
>
<div ref="content"
class="self-start bg-white dark:bg-notion-dark w-full relative p-4 md:p-6 my-6 rounded-xl shadow-xl"
class="self-start bg-white dark:bg-notion-dark w-full relative my-6 rounded-xl shadow-xl"
:class="maxWidthClass"
>
<div v-if="closeable" class="absolute top-4 right-4">
@@ -19,15 +19,17 @@
</svg>
</button>
</div>
<div class="sm:flex sm:flex-col sm:items-start">
<div v-if="$slots.hasOwnProperty('icon')" class="flex w-full justify-center mb-4">
<div class="flex border-b pb-4"
v-if="$slots.hasOwnProperty('icon') || $slots.hasOwnProperty('title')"
:class="[{'flex-col sm:items-start':!compactHeader, 'items-center justify-center py-6 gap-x-4':compactHeader},headerInnerPadding]">
<div v-if="$slots.hasOwnProperty('icon')" :class="{'w-full mb-4 flex justify-center':!compactHeader}">
<div class="w-14 h-14 rounded-full flex justify-center items-center"
:class="'bg-'+iconColor+'-100 text-'+iconColor+'-600'"
>
<slot name="icon"/>
</div>
</div>
<div class="mt-3 text-center sm:mt-0 w-full">
<div class="mt-3 text-center sm:mt-0" :class="{'w-full':!compactHeader}">
<h2 v-if="$slots.hasOwnProperty('title')"
class="text-2xl font-semibold text-center text-gray-900"
>
@@ -36,11 +38,11 @@
</div>
</div>
<div class="w-full">
<div class="w-full" :class="innerPadding">
<slot/>
</div>
<div v-if="$slots.hasOwnProperty('footer')" class="px-6 py-4 bg-gray-100 text-right">
<div v-if="$slots.hasOwnProperty('footer')" class="bg-gray-50 border-t rounded-b-xl text-right" :class="footerInnerPadding">
<slot name="footer"/>
</div>
</div>
@@ -66,19 +68,34 @@ const props = defineProps({
maxWidth: {
default: '2xl'
},
innerPadding: {
default: 'p-6'
},
headerInnerPadding: {
default: 'p-6'
},
footerInnerPadding: {
default: 'p-6'
},
closeable: {
default: true
}
},
compactHeader: {
default: false,
type: Boolean
},
})
const emit = defineEmits(['close'])
useHead({
bodyAttrs: {
class: {
'overflow-hidden': props.show
bodyAttrs: computed(() => {
return {
class: {
'overflow-hidden': props.show
}
}
}
})
})
const closeOnEscape = (e) => {
@@ -146,7 +163,8 @@ const motionSlideBottom = {
}
const onLeave = (el, done) => {
contentMotion.value.leave(()=>{})
contentMotion.value.leave(() => {
})
backdropMotion.value.leave(done)
}

View File

@@ -1,43 +1,45 @@
<template>
<div class="inline" v-if="shouldDisplayProTag">
<div class="bg-nt-blue text-white px-2 text-xs uppercase inline rounded-full font-semibold cursor-pointer"
@click.prevent="showPremiumModal=true"
>
PRO
</div>
<modal :show="showPremiumModal" @close="showPremiumModal=false">
<h2 class="text-nt-blue">
OpnForm PRO
</h2>
<h4 v-if="user && user.is_subscribed" class="text-center mt-5">
We're happy to have you as a Pro customer. If you're having any issue with OpnForm, or if you have a
feature request, please <a href="mailto:contact@opnform.com">contact us</a>.
</h4>
<div v-if="!user || !user.is_subscribed" class="mt-4">
<p>
All the features with a<span
class="bg-nt-blue text-white px-2 text-xs uppercase inline rounded-full font-semibold mx-1"
>
<UTooltip text="Upgrade to use this feature">
<div role="button" class="bg-nt-blue text-white px-2 text-xs uppercase inline rounded-full font-semibold cursor-pointer"
@click="showPremiumModal=true">
PRO
</div>
<modal :show="showPremiumModal" @close="showPremiumModal=false">
<h2 class="text-nt-blue">
OpnForm PRO
</h2>
<h4 v-if="user && user.is_subscribed" class="text-center mt-5">
We're happy to have you as a Pro customer. If you're having any issue with OpnForm, or if you have a
feature request, please <a href="mailto:contact@opnform.com">contact us</a>.
</h4>
<div v-if="!user || !user.is_subscribed" class="mt-4">
<p>
All the features with a<span
class="bg-nt-blue text-white px-2 text-xs uppercase inline rounded-full font-semibold mx-1"
>
PRO
</span> tag are available in the Pro plan of OpnForm. <b>You can play around and try all Pro features
within
the form editor, but you can't use them in your real forms</b>. You can subscribe now to gain unlimited access
to
all our pro features!
</p>
</div>
within
the form editor, but you can't use them in your real forms</b>. You can subscribe now to gain unlimited
access
to
all our pro features!
</p>
</div>
<div class="my-4 text-center">
<v-button color="white" @click="showPremiumModal=false">
Close
</v-button>
</div>
</modal>
<div class="my-4 text-center">
<v-button color="white" @click="showPremiumModal=false">
Close
</v-button>
</div>
</modal>
</UTooltip>
</div>
</template>
<script setup>
import { computed } from 'vue'
import {computed} from 'vue'
const authStore = useAuthStore()
const workspacesStore = useWorkspacesStore()

View File

@@ -19,7 +19,7 @@
</template>
<script>
import throttle from 'lodash.throttle'
import throttle from 'lodash/throttle'
function newResizeObserver (callback) {
// Skip this feature for browsers which
// do not support ResizeObserver.