Enable pricing (#151)
* Enable Pro plan - WIP * no pricing page if have no paid plans * Set pricing ids in env * views & submissions FREE for all * extra param for env * form password FREE for all * Custom Code is PRO feature * Replace codeinput prism with codemirror * Better form Cleaning message * Added risky user email spam protection * fix form cleaning * Pricing page new UI * form cleaner * Polish changes * Fixed tests --------- Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
@@ -49,23 +49,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="getFormCleaningsMsg"
|
||||
class="border shadow-sm p-2 my-4 flex items-center rounded-md bg-yellow-100 border-yellow-500"
|
||||
>
|
||||
<div class="flex-grow">
|
||||
<p class="mb-0 py-2 px-4 text-yellow-600">
|
||||
You're seeing this because you are an owner of this form. <br>
|
||||
All your Pro features are de-activated when sharing this form: <br>
|
||||
|
||||
<span v-html="getFormCleaningsMsg" />
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<v-button color="yellow" shade="light" @click="form.cleanings=false">
|
||||
Close
|
||||
</v-button>
|
||||
</div>
|
||||
</div>
|
||||
<form-cleanings v-if="!adminPreview" :hideable="true" class="mb-4 mx-2" :form="form" :specify-form-owner="true" />
|
||||
|
||||
<transition
|
||||
v-if="!form.is_password_protected && (!isPublicFormPage || (!form.is_closed && !form.max_number_of_submissions_reached && form.visibility!='closed'))"
|
||||
@@ -131,9 +115,10 @@ import { themes } from '~/config/form-themes.js'
|
||||
import VButton from '../../common/Button.vue'
|
||||
import VTransition from '../../common/transitions/VTransition.vue'
|
||||
import FormPendingSubmissionKey from '../../../mixins/forms/form-pending-submission-key.js'
|
||||
import FormCleanings from '../../pages/forms/show/FormCleanings.vue'
|
||||
|
||||
export default {
|
||||
components: { VTransition, VButton, OpenFormButton, OpenForm },
|
||||
components: { VTransition, VButton, OpenFormButton, OpenForm, FormCleanings },
|
||||
|
||||
props: {
|
||||
form: { type: Object, required: true },
|
||||
@@ -166,22 +151,6 @@ export default {
|
||||
theme () {
|
||||
return this.themes[this.themes.hasOwnProperty(this.form.theme) ? this.form.theme : 'default']
|
||||
},
|
||||
getFormCleaningsMsg () {
|
||||
if (this.form.cleanings && Object.keys(this.form.cleanings).length > 0) {
|
||||
let message = ''
|
||||
Object.keys(this.form.cleanings).forEach((key) => {
|
||||
const fieldName = key.charAt(0).toUpperCase() + key.slice(1)
|
||||
let fieldInfo = '<br/>' + fieldName + "<br/><ul class='list-disc list-inside'>"
|
||||
this.form.cleanings[key].forEach((msg) => {
|
||||
fieldInfo = fieldInfo + '<li>' + msg + '</li>'
|
||||
})
|
||||
message = message + fieldInfo + '<ul/>'
|
||||
})
|
||||
|
||||
return message
|
||||
}
|
||||
return false
|
||||
},
|
||||
isPublicFormPage () {
|
||||
return this.$route.name === 'forms.show_public'
|
||||
},
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
<form v-else-if="dataForm" @submit.prevent="">
|
||||
<transition name="fade" mode="out-in" appear>
|
||||
<template v-for="group, groupIndex in fieldGroups">
|
||||
<div v-if="currentFieldGroupIndex===groupIndex"
|
||||
:key="groupIndex"
|
||||
<div v-if="currentFieldGroupIndex===groupIndex"
|
||||
:key="groupIndex"
|
||||
class="form-group flex flex-wrap w-full">
|
||||
|
||||
<draggable v-model="currentFields"
|
||||
|
||||
@@ -52,11 +52,6 @@
|
||||
</p>
|
||||
</template>
|
||||
</div>
|
||||
<!-- Field options -->
|
||||
|
||||
<!-- <div class="flex-grow" v-if="['files'].includes(field.type) || field.type.startsWith('nf-')">-->
|
||||
<!-- <pro-tag/>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<template v-if="removing == field.id">
|
||||
<div class="flex text-sm items-center">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="border border-nt-blue-light bg-blue-50 dark:bg-notion-dark-light rounded-md p-4 mb-5 w-full mx-auto mt-4 select-all">
|
||||
<div v-if="!form.is_pro" class="relative">
|
||||
<div v-if="false" class="relative">
|
||||
<div class="absolute inset-0 z-10">
|
||||
<div class="p-5 max-w-md mx-auto mt-5">
|
||||
<p class="text-center">
|
||||
@@ -102,7 +102,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getChartData () {
|
||||
if (!this.form || !this.form.is_pro) { return null }
|
||||
if (!this.form) { return null }
|
||||
this.isLoading = true
|
||||
axios.get('/api/open/workspaces/' + this.form.workspace_id + '/form-stats/' + this.form.id).then((response) => {
|
||||
const statsData = response.data
|
||||
|
||||
@@ -21,8 +21,13 @@
|
||||
/>
|
||||
|
||||
<toggle-switch-input name="editable_submissions" :form="form" class="mt-4"
|
||||
label="Allow users to edit their submission"
|
||||
/>
|
||||
help="Gives user a unique url to update their submission"
|
||||
>
|
||||
<template #label>
|
||||
Editable submissions
|
||||
<pro-tag class="ml-1" />
|
||||
</template>
|
||||
</toggle-switch-input>
|
||||
<text-input v-if="form.editable_submissions" name="editable_submissions_button_text"
|
||||
:form="form"
|
||||
label="Text of editable submissions button"
|
||||
@@ -111,7 +116,6 @@
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<pro-tag class="float-right"/>
|
||||
<toggle-switch-input name="re_fillable" :form="form" class="mt-4"
|
||||
label="Allow users to fill the form again"
|
||||
/>
|
||||
|
||||
@@ -12,10 +12,7 @@
|
||||
</h3>
|
||||
</template>
|
||||
<p class="mt-4">
|
||||
The code will be injected in the <span class="font-semibold">head</span> section of your form page. <a href="#" class="text-gray-500"
|
||||
@click.prevent="$crisp.push(['do', 'helpdesk:article:open', ['en', 'how-to-inject-custom-code-in-my-form-1amadj3']])"
|
||||
>Click
|
||||
here to get an example CSS code.</a>
|
||||
The code will be injected in the <span class="font-semibold">head</span> section of your form page.
|
||||
</p>
|
||||
<code-input name="custom_code" class="mt-4"
|
||||
:form="form" help="Custom code cannot be previewed in our editor. Please test your code using
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
</svg>
|
||||
|
||||
Customization
|
||||
<pro-tag />
|
||||
</h3>
|
||||
</template>
|
||||
|
||||
@@ -62,9 +61,12 @@
|
||||
<toggle-switch-input name="hide_title" :form="form" class="mt-4"
|
||||
label="Hide Title"
|
||||
/>
|
||||
<toggle-switch-input name="no_branding" :form="form" class="mt-4"
|
||||
label="Remove OpnForm Branding"
|
||||
/>
|
||||
<toggle-switch-input name="no_branding" :form="form" class="mt-4">
|
||||
<template #label>
|
||||
Remove OpnForm Branding
|
||||
<pro-tag class="ml-1" />
|
||||
</template>
|
||||
</toggle-switch-input>
|
||||
<toggle-switch-input name="uppercase_labels" :form="form" class="mt-4"
|
||||
label="Uppercase Input Labels"
|
||||
/>
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
label="Protect your form with a Captcha"
|
||||
help="If enabled we will make sure respondant is a human"
|
||||
/>
|
||||
<pro-tag class="float-right" />
|
||||
<text-input name="password" :form="form" class="mt-4"
|
||||
label="Form Password" help="Leave empty to disable password"
|
||||
/>
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
<div v-if="logic" :key="resetKey" class="-mx-4 sm:-mx-6 p-5 border-b">
|
||||
<h3 class="font-semibold block text-lg">
|
||||
Logic
|
||||
<pro-tag/>
|
||||
</h3>
|
||||
<p class="text-gray-400 text-xs mb-5">
|
||||
Add some logic to this block. Start by adding some conditions, and then add some actions.
|
||||
|
||||
@@ -99,7 +99,6 @@
|
||||
<div v-if="field.type === 'number'" class="-mx-4 sm:-mx-6 p-5 border-b">
|
||||
<h3 class="font-semibold block text-lg">
|
||||
Number Options
|
||||
<pro-tag/>
|
||||
</h3>
|
||||
<v-checkbox v-model="field.is_rating" class="mt-4"
|
||||
:name="field.id+'_is_rating'" @input="initRating"
|
||||
@@ -136,7 +135,6 @@
|
||||
<div v-if="field.type === 'date'" class="-mx-4 sm:-mx-6 p-5 border-b">
|
||||
<h3 class="font-semibold block text-lg">
|
||||
Date Options
|
||||
<pro-tag/>
|
||||
</h3>
|
||||
<v-checkbox v-model="field.date_range" class="mt-4"
|
||||
:name="field.id+'_date_range'"
|
||||
@@ -191,7 +189,6 @@
|
||||
<div v-if="['select','multi_select'].includes(field.type)" class="-mx-4 sm:-mx-6 p-5 border-b">
|
||||
<h3 class="font-semibold block text-lg">
|
||||
Select Options
|
||||
<pro-tag/>
|
||||
</h3>
|
||||
<p class="text-gray-400 mb-5 text-xs">
|
||||
Advanced options for your select/multiselect fields.
|
||||
@@ -218,7 +215,6 @@
|
||||
<div v-if="displayBasedOnAdvanced" class="-mx-4 sm:-mx-6 p-5 border-b">
|
||||
<h3 class="font-semibold block text-lg">
|
||||
Customization
|
||||
<pro-tag/>
|
||||
</h3>
|
||||
|
||||
<p class="text-gray-400 mb-5 text-xs">
|
||||
@@ -322,7 +318,6 @@
|
||||
<div v-if="field.type === 'text'" class="-mx-4 sm:-mx-6 p-5 border-b">
|
||||
<h3 class="font-semibold block text-lg">
|
||||
Advanced Options
|
||||
<pro-tag/>
|
||||
</h3>
|
||||
|
||||
<v-checkbox v-model="field.generates_uuid"
|
||||
|
||||
Reference in New Issue
Block a user