Combine integrations & notifications sections (#229)

* Combine integrations & notifications sections

* New section Form Access
This commit is contained in:
formsdev 2023-10-26 16:52:16 +05:30 committed by GitHub
parent 8e5acab8bf
commit 8a2e071c56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 197 additions and 111 deletions

View File

@ -29,6 +29,7 @@ class FormResource extends JsonResource
'views_count' => $this->views_count, 'views_count' => $this->views_count,
'submissions_count' => $this->submissions_count, 'submissions_count' => $this->submissions_count,
'notifies' => $this->notifies, 'notifies' => $this->notifies,
'notifies_webhook' => $this->notifies_webhook,
'notifies_slack' => $this->notifies_slack, 'notifies_slack' => $this->notifies_slack,
'notifies_discord' => $this->notifies_discord, 'notifies_discord' => $this->notifies_discord,
'send_submission_confirmation' => $this->send_submission_confirmation, 'send_submission_confirmation' => $this->send_submission_confirmation,

View File

@ -279,6 +279,11 @@ class Form extends Model
} }
public function getNotifiesWebhookAttribute()
{
return !empty($this->webhook_url);
}
public function getNotifiesDiscordAttribute() public function getNotifiesDiscordAttribute()
{ {
return !empty($this->discord_webhook_url); return !empty($this->discord_webhook_url);

View File

@ -1,5 +1,8 @@
<template> <template>
<button v-if="!to" :type="nativeType" :disabled="loading" :class="btnClasses" <a v-if="href" :class="btnClasses" :href="href" :target="target">
<slot />
</a>
<button v-else-if="!to" :type="nativeType" :disabled="loading" :class="btnClasses"
@click="onClick($event)" @click="onClick($event)"
> >
<template v-if="!loading"> <template v-if="!loading">
@ -61,6 +64,11 @@ export default {
default: null default: null
}, },
href: {
type: String,
default: null
},
target: { target: {
type: String, type: String,
default: '_self' default: '_self'

View File

@ -58,12 +58,12 @@
<form-information/> <form-information/>
<form-structure/> <form-structure/>
<form-customization/> <form-customization/>
<form-about-submission/>
<form-notifications/> <form-notifications/>
<form-about-submission/>
<form-access />
<form-security-privacy/> <form-security-privacy/>
<form-custom-seo /> <form-custom-seo />
<form-custom-code/> <form-custom-code/>
<form-integrations/>
</div> </div>
<form-editor-preview/> <form-editor-preview/>
@ -95,10 +95,10 @@ import FormCustomization from './form-components/FormCustomization.vue'
import FormCustomCode from './form-components/FormCustomCode.vue' import FormCustomCode from './form-components/FormCustomCode.vue'
import FormAboutSubmission from './form-components/FormAboutSubmission.vue' import FormAboutSubmission from './form-components/FormAboutSubmission.vue'
import FormNotifications from './form-components/FormNotifications.vue' import FormNotifications from './form-components/FormNotifications.vue'
import FormIntegrations from './form-components/FormIntegrations.vue'
import FormEditorPreview from './form-components/FormEditorPreview.vue' import FormEditorPreview from './form-components/FormEditorPreview.vue'
import FormSecurityPrivacy from './form-components/FormSecurityPrivacy.vue' import FormSecurityPrivacy from './form-components/FormSecurityPrivacy.vue'
import FormCustomSeo from './form-components/FormCustomSeo.vue' import FormCustomSeo from './form-components/FormCustomSeo.vue'
import FormAccess from './form-components/FormAccess.vue'
import saveUpdateAlert from '../../../../mixins/forms/saveUpdateAlert.js' import saveUpdateAlert from '../../../../mixins/forms/saveUpdateAlert.js'
import fieldsLogic from '../../../../mixins/forms/fieldsLogic.js' import fieldsLogic from '../../../../mixins/forms/fieldsLogic.js'
@ -108,7 +108,6 @@ export default {
AddFormBlockSidebar, AddFormBlockSidebar,
FormFieldEditSidebar, FormFieldEditSidebar,
FormEditorPreview, FormEditorPreview,
FormIntegrations,
FormNotifications, FormNotifications,
FormAboutSubmission, FormAboutSubmission,
FormCustomCode, FormCustomCode,
@ -117,7 +116,8 @@ export default {
FormInformation, FormInformation,
FormErrorModal, FormErrorModal,
FormSecurityPrivacy, FormSecurityPrivacy,
FormCustomSeo FormCustomSeo,
FormAccess
}, },
mixins: [saveUpdateAlert, fieldsLogic], mixins: [saveUpdateAlert, fieldsLogic],
props: { props: {

View File

@ -129,30 +129,6 @@
label="Text After Submission" label="Text After Submission"
:required="false" :required="false"
/> />
<date-input :with-time="true" name="closes_at"
:form="form"
label="Closing Date"
help="If filled, then the form won't accept submissions after the given date"
:required="false"
/>
<rich-text-area-input v-if="form.closes_at || form.visibility=='closed'" name="closed_text"
:form="form"
label="Closed form text"
help="This message will be shown when the form will be closed"
:required="false"
/>
<text-input name="max_submissions_count" native-type="number" :min="1" :form="form"
label="Max. Number of Submissions"
help="If filled, the form will only accept X number of submissions"
:required="false"
/>
<rich-text-area-input v-if="form.max_submissions_count && form.max_submissions_count > 0"
name="max_submissions_reached_text"
:form="form"
label="Max Submissions reached text"
help="This message will be shown when the form will have the maximum number of submissions"
:required="false"
/>
</template> </template>
</collapse> </collapse>
</template> </template>

View File

@ -0,0 +1,74 @@
<template>
<collapse class="p-4 w-full border-b" v-model="isCollapseOpen">
<template #title>
<h3 class="font-semibold text-lg">
<svg class="h-5 w-5 inline mr-2 transition-colors"
:class="{'text-blue-600':isCollapseOpen, 'text-gray-500':!isCollapseOpen}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
>
<path stroke-linecap="round" stroke-linejoin="round"
d="M15.75 5.25a3 3 0 013 3m3 0a6 6 0 01-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1121.75 8.25z"
/>
</svg>
Form Access
</h3>
</template>
<pro-tag class="float-right" />
<text-input name="password" :form="form" class="mt-4"
label="Form Password" help="Leave empty to disable password"
/>
<date-input :with-time="true" name="closes_at" class="mt-4"
:form="form"
label="Close form on a scheduled date"
help="Leave empty to keep the form open"
:required="false"
/>
<rich-text-area-input v-if="form.closes_at || form.visibility=='closed'" name="closed_text"
:form="form" class="mt-4"
label="Closed form text"
help="This message will be shown when the form will be closed"
:required="false"
/>
<text-input name="max_submissions_count" native-type="number" :min="1" :form="form"
label="Limit number of submissions" placeholder="Max submissions" class="mt-4"
help="Leave empty for unlimited submissions"
:required="false"
/>
<rich-text-area-input v-if="form.max_submissions_count && form.max_submissions_count > 0"
name="max_submissions_reached_text" class="mt-4"
:form="form"
label="Max Submissions reached text"
help="This message will be shown when the form will have the maximum number of submissions"
:required="false"
/>
</collapse>
</template>
<script>
import Collapse from '../../../../common/Collapse.vue'
import ProTag from '../../../../common/ProTag.vue'
export default {
components: { Collapse, ProTag },
props: {},
data () {
return {
isCollapseOpen: false
}
},
computed: {
form: {
get () {
return this.$store.state['open/working_form'].content
},
/* We add a setter */
set (value) {
this.$store.commit('open/working_form/set', value)
}
}
},
watch: {},
mounted () {
},
methods: {}
}
</script>

View File

@ -1,74 +0,0 @@
<template>
<collapse class="p-4 w-full border-b" v-model="isCollapseOpen">
<template #title>
<h3 class="font-semibold text-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 inline mr-2 transition-colors"
:class="{'text-blue-600':isCollapseOpen, 'text-gray-500':!isCollapseOpen}"
fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M11 4a2 2 0 114 0v1a1 1 0 001 1h3a1 1 0 011 1v3a1 1 0 01-1 1h-1a2 2 0 100 4h1a1 1 0 011 1v3a1 1 0 01-1 1h-3a1 1 0 01-1-1v-1a2 2 0 10-4 0v1a1 1 0 01-1 1H7a1 1 0 01-1-1v-3a1 1 0 00-1-1H4a2 2 0 110-4h1a1 1 0 001-1V7a1 1 0 011-1h3a1 1 0 001-1V4z"/>
</svg>
Integrations
<pro-tag/>
</h3>
</template>
<text-input name="webhook_url" class="mt-4"
:form="form" help="We will post form submissions to this endpoint."
label="Webhook URL"
/>
<!-- <div>-->
<!-- <p>-->
<!-- <span class="text-uppercase font-semibold text-blue-500">NEW</span> - our Zapier integration is available for-->
<!-- beta testers!-->
<!-- </p>-->
<!-- <p class="w-full text-center mt-5">-->
<!-- <a :href="zapierUrl" target="_blank">-->
<!-- <v-button color="gray" shade="lighter">-->
<!-- <svg class="h-5 w-5 inline text-yellow-500" fill="currentColor" xmlns="http://www.w3.org/2000/svg"-->
<!-- viewBox="0 0 512 512"-->
<!-- >-->
<!-- <path-->
<!-- d="M318 256c0 19-4 36-10 52-16 7-34 10-52 10-19 0-36-3-52-9-7-17-10-34-10-53 0-18 3-36 10-52 16-6 33-10 52-10 18 0 36 4 52 10 6 16 10 34 10 52zm182-41H355l102-102c-8-11-17-22-26-32-10-9-21-18-32-26L297 157V12c-13-2-27-3-41-3s-28 1-41 3v145L113 55c-12 8-22 17-32 26-10 10-19 21-27 32l102 102H12s-3 27-3 41 1 28 3 41h144L54 399c16 23 36 43 59 59l102-102v144c13 2 27 3 41 3s28-1 41-3V356l102 102c11-8 22-17 32-27 9-10 18-20 26-32L355 297h145c2-13 3-27 3-41s-1-28-3-41z"-->
<!-- />-->
<!-- </svg>-->
<!-- Zapier Integration-->
<!-- </v-button>-->
<!-- </a>-->
<!-- </p>-->
<!-- </div>-->
</collapse>
</template>
<script>
import Collapse from '../../../../common/Collapse.vue'
import ProTag from '../../../../common/ProTag.vue'
export default {
components: {Collapse, ProTag},
props: {},
data() {
return {
isCollapseOpen: false
}
},
computed: {
form: {
get() {
return this.$store.state['open/working_form'].content
},
/* We add a setter */
set(value) {
this.$store.commit('open/working_form/set', value)
}
},
zapierUrl: () => window.config.links.zapier_integration
},
watch: {},
mounted() {},
}
</script>

View File

@ -6,8 +6,7 @@
:class="{'text-blue-600':isCollapseOpen, 'text-gray-500':!isCollapseOpen}" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> :class="{'text-blue-600':isCollapseOpen, 'text-gray-500':!isCollapseOpen}" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22 6C22 4.9 21.1 4 20 4H4C2.9 4 2 4.9 2 6M22 6V18C22 19.1 21.1 20 20 20H4C2.9 20 2 19.1 2 18V6M22 6L12 13L2 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M22 6C22 4.9 21.1 4 20 4H4C2.9 4 2 4.9 2 6M22 6V18C22 19.1 21.1 20 20 20H4C2.9 20 2 19.1 2 18V6M22 6L12 13L2 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg> </svg>
Notifications & Integrations
Notifications
<pro-tag /> <pro-tag />
</h3> </h3>
</template> </template>
@ -16,6 +15,22 @@
<form-notifications-submission-confirmation /> <form-notifications-submission-confirmation />
<form-notifications-slack /> <form-notifications-slack />
<form-notifications-discord /> <form-notifications-discord />
<form-notifications-webhook />
<v-button color="white"
class="flex items-center mt-3 cursor-pointer relative w-full rounded-lg flex-1 appearance-none border border-gray-300 dark:border-gray-600 w-full py-2 px-4 bg-white text-gray-700 dark:bg-notion-dark-light dark:text-gray-300 dark:placeholder-gray-500 placeholder-gray-400 shadow-sm text-base focus:outline-none focus:ring-2 focus:border-transparent focus:ring-opacity-100"
:href="zapierUrl" target="_blank"
>
<div class="flex-grow flex items-center">
<svg class="w-5 h-5 inline text-yellow-500" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path
d="M318 256c0 19-4 36-10 52-16 7-34 10-52 10-19 0-36-3-52-9-7-17-10-34-10-53 0-18 3-36 10-52 16-6 33-10 52-10 18 0 36 4 52 10 6 16 10 34 10 52zm182-41H355l102-102c-8-11-17-22-26-32-10-9-21-18-32-26L297 157V12c-13-2-27-3-41-3s-28 1-41 3v145L113 55c-12 8-22 17-32 26-10 10-19 21-27 32l102 102H12s-3 27-3 41 1 28 3 41h144L54 399c16 23 36 43 59 59l102-102v144c13 2 27 3 41 3s28-1 41-3V356l102 102c11-8 22-17 32-27 9-10 18-20 26-32L355 297h145c2-13 3-27 3-41s-1-28-3-41z"
/>
</svg>
<p class="flex-grow text-center font-normal">
Zapier Integration
</p>
</div>
</v-button>
</collapse> </collapse>
</template> </template>
@ -27,9 +42,10 @@ import FormNotificationsOption from './components/FormNotificationsOption.vue'
import FormNotificationsSlack from './components/FormNotificationsSlack.vue' import FormNotificationsSlack from './components/FormNotificationsSlack.vue'
import FormNotificationsDiscord from './components/FormNotificationsDiscord.vue' import FormNotificationsDiscord from './components/FormNotificationsDiscord.vue'
import FormNotificationsSubmissionConfirmation from './components/FormNotificationsSubmissionConfirmation.vue' import FormNotificationsSubmissionConfirmation from './components/FormNotificationsSubmissionConfirmation.vue'
import FormNotificationsWebhook from './components/FormNotificationsWebhook.vue'
export default { export default {
components: { FormNotificationsSubmissionConfirmation, FormNotificationsSlack, FormNotificationsDiscord, FormNotificationsOption, Collapse, ProTag }, components: { FormNotificationsSubmissionConfirmation, FormNotificationsSlack, FormNotificationsDiscord, FormNotificationsOption, Collapse, ProTag, FormNotificationsWebhook },
props: { props: {
}, },
data () { data () {
@ -47,7 +63,8 @@ export default {
set (value) { set (value) {
this.$store.commit('open/working_form/set', value) this.$store.commit('open/working_form/set', value)
} }
} },
zapierUrl: () => window.config.links.zapier_integration
}, },
watch: { watch: {

View File

@ -17,9 +17,6 @@
label="Protect your form with a Captcha" label="Protect your form with a Captcha"
help="If enabled we will make sure respondant is a human" help="If enabled we will make sure respondant is a human"
/> />
<text-input name="password" :form="form" class="mt-4"
label="Form Password" help="Leave empty to disable password"
/>
</collapse> </collapse>
</template> </template>

View File

@ -0,0 +1,82 @@
<template>
<div>
<button
class="flex items-center mt-3 cursor-pointer relative w-full rounded-lg flex-1 appearance-none border border-gray-300 dark:border-gray-600 w-full py-2 px-4 bg-white text-gray-700 dark:bg-notion-dark-light dark:text-gray-300 dark:placeholder-gray-500 placeholder-gray-400 shadow-sm text-base focus:outline-none focus:ring-2 focus:border-transparent focus:ring-opacity-100"
@click.prevent="showModal=true"
>
<div class="flex-grow flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
class="w-5 h-5 inline"
>
<path stroke-linecap="round" stroke-linejoin="round"
d="M14.25 6.087c0-.355.186-.676.401-.959.221-.29.349-.634.349-1.003 0-1.036-1.007-1.875-2.25-1.875s-2.25.84-2.25 1.875c0 .369.128.713.349 1.003.215.283.401.604.401.959v0a.64.64 0 01-.657.643 48.39 48.39 0 01-4.163-.3c.186 1.613.293 3.25.315 4.907a.656.656 0 01-.658.663v0c-.355 0-.676-.186-.959-.401a1.647 1.647 0 00-1.003-.349c-1.036 0-1.875 1.007-1.875 2.25s.84 2.25 1.875 2.25c.369 0 .713-.128 1.003-.349.283-.215.604-.401.959-.401v0c.31 0 .555.26.532.57a48.039 48.039 0 01-.642 5.056c1.518.19 3.058.309 4.616.354a.64.64 0 00.657-.643v0c0-.355-.186-.676-.401-.959a1.647 1.647 0 01-.349-1.003c0-1.035 1.008-1.875 2.25-1.875 1.243 0 2.25.84 2.25 1.875 0 .369-.128.713-.349 1.003-.215.283-.4.604-.4.959v0c0 .333.277.599.61.58a48.1 48.1 0 005.427-.63 48.05 48.05 0 00.582-4.717.532.532 0 00-.533-.57v0c-.355 0-.676.186-.959.401-.29.221-.634.349-1.003.349-1.035 0-1.875-1.007-1.875-2.25s.84-2.25 1.875-2.25c.37 0 .713.128 1.003.349.283.215.604.401.96.401v0a.656.656 0 00.658-.663 48.422 48.422 0 00-.37-5.36c-1.886.342-3.81.574-5.766.689a.578.578 0 01-.61-.58v0z"
/>
</svg>
<p class="flex-grow text-center">
Webhook Notifications
</p>
</div>
<div v-if="form.notifies_webhook">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
class="w-5 h-5 text-nt-blue"
>
<path stroke-linecap="round" stroke-linejoin="round"
d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
</div>
</button>
<modal :show="showModal" @close="showModal=false">
<h2 class="text-2xl font-bold z-10 truncate mb-5 text-nt-blue">
Webhook Notifications
<pro-tag />
</h2>
<toggle-switch-input name="notifies_webhook" :form="form" class="mt-4"
label="Trigger a webhook notification on form submission"
@change="onToggleChange"
/>
<text-input v-if="form.notifies_webhook" name="webhook_url" :form="form" class="mt-4"
label="Webhook url" help="We will post form submissions to this endpoint"
/>
</modal>
</div>
</template>
<script>
import ProTag from '../../../../../common/ProTag.vue'
export default {
components: { ProTag },
props: {},
data () {
return {
showModal: false
}
},
computed: {
form: {
get () {
return this.$store.state['open/working_form'].content
},
/* We add a setter */
set (value) {
this.$store.commit('open/working_form/set', value)
}
}
},
watch: {},
mounted () {
},
methods: {
onToggleChange () {
if (!this.form.notifies_webhook) {
this.form.webhook_url = ''
}
}
}
}
</script>