Vue3: migrating from vuex to Pinia (#249)
* Vue3: migrating from vuex to Pinia * toggle input fixes * update configureCompat --------- Co-authored-by: Forms Dev <chirag+new@notionforms.io>
This commit is contained in:
parent
af30067eda
commit
47653ebe64
File diff suppressed because it is too large
Load Diff
|
@ -21,6 +21,7 @@
|
||||||
"js-cookie": "^2.2.1",
|
"js-cookie": "^2.2.1",
|
||||||
"js-sha256": "^0.9.0",
|
"js-sha256": "^0.9.0",
|
||||||
"libphonenumber-js": "^1.10.44",
|
"libphonenumber-js": "^1.10.44",
|
||||||
|
"pinia": "^2.1.7",
|
||||||
"prismjs": "^1.24.1",
|
"prismjs": "^1.24.1",
|
||||||
"qrcode": "^1.5.1",
|
"qrcode": "^1.5.1",
|
||||||
"query-builder-vue": "^1.2.0",
|
"query-builder-vue": "^1.2.0",
|
||||||
|
@ -38,8 +39,7 @@
|
||||||
"vue-signature-pad": "^3.0.2",
|
"vue-signature-pad": "^3.0.2",
|
||||||
"vue3-editor": "^0.1.1",
|
"vue3-editor": "^0.1.1",
|
||||||
"vue3-vt-notifications": "^1.0.0",
|
"vue3-vt-notifications": "^1.0.0",
|
||||||
"vuedraggable": "^4.1.0",
|
"vuedraggable": "^4.1.0"
|
||||||
"vuex": "^4.1.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.20.12",
|
"@babel/core": "^7.20.12",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { createApp, configureCompat, ref } from 'vue'
|
import { createApp, configureCompat, ref } from 'vue'
|
||||||
import store from '~/store'
|
import { createPinia } from 'pinia'
|
||||||
import router from '~/router'
|
import router from '~/router'
|
||||||
import App from '~/components/App.vue'
|
import App from '~/components/App.vue'
|
||||||
import Base from './base.js'
|
import Base from './base.js'
|
||||||
|
@ -11,9 +11,10 @@ import '~/components'
|
||||||
|
|
||||||
import '../sass/app.scss'
|
import '../sass/app.scss'
|
||||||
|
|
||||||
|
const pinia = createPinia()
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
.use(router)
|
.use(router)
|
||||||
.use(store)
|
.use(pinia)
|
||||||
.mixin(Base)
|
.mixin(Base)
|
||||||
|
|
||||||
registerPlugin(app)
|
registerPlugin(app)
|
||||||
|
@ -25,7 +26,9 @@ configureCompat({
|
||||||
// GLOBAL_MOUNT: false,
|
// GLOBAL_MOUNT: false,
|
||||||
COMPONENT_V_MODEL: false,
|
COMPONENT_V_MODEL: false,
|
||||||
INSTANCE_SET: false,
|
INSTANCE_SET: false,
|
||||||
INSTANCE_DELETE: false
|
INSTANCE_DELETE: false,
|
||||||
|
ATTR_FALSE_VALUE: false,
|
||||||
|
WATCH_ARRAY: false
|
||||||
})
|
})
|
||||||
|
|
||||||
router.app = app
|
router.app = app
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useAppStore } from '../stores/app'
|
||||||
import Loading from './Loading.vue'
|
import Loading from './Loading.vue'
|
||||||
import Hotjar from './service/Hotjar.vue'
|
import Hotjar from './service/Hotjar.vue'
|
||||||
import Amplitude from './service/Amplitude.vue'
|
import Amplitude from './service/Amplitude.vue'
|
||||||
|
@ -44,7 +46,6 @@ import Crisp from './service/Crisp.vue'
|
||||||
import StopImpersonation from './pages/StopImpersonation.vue'
|
import StopImpersonation from './pages/StopImpersonation.vue'
|
||||||
import Notifications from './common/Notifications.vue'
|
import Notifications from './common/Notifications.vue'
|
||||||
import SeoMeta from '../mixins/seo-meta.js'
|
import SeoMeta from '../mixins/seo-meta.js'
|
||||||
import { mapState } from 'vuex'
|
|
||||||
|
|
||||||
// Load layout components dynamically.
|
// Load layout components dynamically.
|
||||||
const requireContext = import.meta.glob('../layouts/**.vue', { eager: true })
|
const requireContext = import.meta.glob('../layouts/**.vue', { eager: true })
|
||||||
|
@ -74,6 +75,13 @@ export default {
|
||||||
|
|
||||||
mixins: [SeoMeta],
|
mixins: [SeoMeta],
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const appStore = useAppStore()
|
||||||
|
return {
|
||||||
|
layout : computed(() => appStore.layout)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
metaTitle: 'OpnForm',
|
metaTitle: 'OpnForm',
|
||||||
metaDescription: 'Create beautiful forms for free. Unlimited fields, unlimited submissions. It\'s free and it takes less than 1 minute to create your first form.',
|
metaDescription: 'Create beautiful forms for free. Unlimited fields, unlimited submissions. It\'s free and it takes less than 1 minute to create your first form.',
|
||||||
|
@ -95,9 +103,6 @@ export default {
|
||||||
isOnboardingPage () {
|
isOnboardingPage () {
|
||||||
return this.$route.name === 'onboarding'
|
return this.$route.name === 'onboarding'
|
||||||
},
|
},
|
||||||
...mapState({
|
|
||||||
layout: state => state.app.layout
|
|
||||||
}),
|
|
||||||
layoutComponent () {
|
layoutComponent () {
|
||||||
return layouts[this.layout]
|
return layouts[this.layout]
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// https://github.com/nuxt/nuxt.js/blob/master/lib/app/components/nuxt-loading.vue
|
// https://github.com/nuxt/nuxt.js/blob/master/lib/app/components/nuxt-loading.vue
|
||||||
import { mapState } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAppStore } from '../stores/app';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: () => ({
|
data: () => ({
|
||||||
|
@ -19,12 +20,13 @@ export default {
|
||||||
failedColor: 'red'
|
failedColor: 'red'
|
||||||
}),
|
}),
|
||||||
|
|
||||||
computed: {
|
setup () {
|
||||||
...mapState({
|
const appStore = useAppStore()
|
||||||
percent: state => state.app.loader.percent,
|
return {
|
||||||
canSuccess: state => state.app.loader.canSuccess,
|
percent : computed(() => appStore.loader.percent),
|
||||||
show: state => state.app.loader.show
|
canSuccess : computed(() => appStore.loader.canSuccess),
|
||||||
})
|
show : computed(() => appStore.loader.show)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -14,9 +14,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useAuthStore } from '../stores/auth'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'LoginWithGithub',
|
name: 'LoginWithGithub',
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
authStore
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
githubAuth: () => window.config.githubAuth,
|
githubAuth: () => window.config.githubAuth,
|
||||||
url: () => '/api/oauth/github'
|
url: () => '/api/oauth/github'
|
||||||
|
@ -34,9 +43,7 @@ export default {
|
||||||
async login () {
|
async login () {
|
||||||
const newWindow = openWindow('', 'Login')
|
const newWindow = openWindow('', 'Login')
|
||||||
|
|
||||||
const url = await this.$store.dispatch('auth/fetchOauthUrl', {
|
const url = await this.authStore.fetchOauthUrl('github')
|
||||||
provider: 'github'
|
|
||||||
})
|
|
||||||
|
|
||||||
newWindow.location.href = url
|
newWindow.location.href = url
|
||||||
},
|
},
|
||||||
|
@ -49,9 +56,7 @@ export default {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$store.dispatch('auth/saveToken', {
|
this.authStore.saveToken(e.data.token)
|
||||||
token: e.data.token
|
|
||||||
})
|
|
||||||
|
|
||||||
this.$router.push({ name: 'home' })
|
this.$router.push({ name: 'home' })
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../stores/auth';
|
||||||
|
import { useFormsStore } from '../stores/forms';
|
||||||
|
import { useWorkspacesStore } from '../stores/workspaces';
|
||||||
import Dropdown from './common/Dropdown.vue'
|
import Dropdown from './common/Dropdown.vue'
|
||||||
import WorkspaceDropdown from './WorkspaceDropdown.vue'
|
import WorkspaceDropdown from './WorkspaceDropdown.vue'
|
||||||
|
|
||||||
|
@ -142,6 +145,18 @@ export default {
|
||||||
Dropdown
|
Dropdown
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const formsStore = useFormsStore()
|
||||||
|
const workspacesStore = useWorkspacesStore()
|
||||||
|
return {
|
||||||
|
authStore,
|
||||||
|
formsStore,
|
||||||
|
workspacesStore,
|
||||||
|
user : computed(() => authStore.user)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
appName: window.config.appName
|
appName: window.config.appName
|
||||||
}),
|
}),
|
||||||
|
@ -151,12 +166,12 @@ export default {
|
||||||
helpUrl: () => window.config.links.help_url,
|
helpUrl: () => window.config.links.help_url,
|
||||||
form () {
|
form () {
|
||||||
if (this.$route.name && this.$route.name.startsWith('forms.show_public')) {
|
if (this.$route.name && this.$route.name.startsWith('forms.show_public')) {
|
||||||
return this.$store.getters['open/forms/getBySlug'](this.$route.params.slug)
|
return this.formsStore.getBySlug(this.$route.params.slug)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
},
|
},
|
||||||
workspace () {
|
workspace () {
|
||||||
return this.$store.getters['open/workspaces/getCurrent']()
|
return this.workspacesStore.getCurrent()
|
||||||
},
|
},
|
||||||
paidPlansEnabled () {
|
paidPlansEnabled () {
|
||||||
return window.config.paid_plans_enabled
|
return window.config.paid_plans_enabled
|
||||||
|
@ -182,9 +197,6 @@ export default {
|
||||||
isIframe () {
|
isIframe () {
|
||||||
return window.location !== window.parent.location || window.frameElement
|
return window.location !== window.parent.location || window.frameElement
|
||||||
},
|
},
|
||||||
...mapGetters({
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
userOnboarded () {
|
userOnboarded () {
|
||||||
return this.user && this.user.workspaces_count > 0
|
return this.user && this.user.workspaces_count > 0
|
||||||
},
|
},
|
||||||
|
@ -196,11 +208,11 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
async logout () {
|
async logout () {
|
||||||
// Log out the user.
|
// Log out the user.
|
||||||
await this.$store.dispatch('auth/logout')
|
await this.authStore.logout()
|
||||||
|
|
||||||
// Reset store
|
// Reset store
|
||||||
this.$store.dispatch('open/workspaces/resetState')
|
this.workspacesStore.resetState()
|
||||||
this.$store.dispatch('open/forms/resetState')
|
this.formsStore.resetState()
|
||||||
|
|
||||||
// Redirect to login.
|
// Redirect to login.
|
||||||
this.$router.push({ name: 'login' })
|
this.$router.push({ name: 'login' })
|
||||||
|
|
|
@ -41,8 +41,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../stores/auth'
|
||||||
|
import { useFormsStore } from '../stores/forms'
|
||||||
|
import { useWorkspacesStore } from '../stores/workspaces'
|
||||||
import Dropdown from './common/Dropdown.vue'
|
import Dropdown from './common/Dropdown.vue'
|
||||||
import { mapGetters, mapState } from 'vuex'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
|
@ -51,20 +54,26 @@ export default {
|
||||||
Dropdown
|
Dropdown
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const formsStore = useFormsStore()
|
||||||
|
const workspacesStore = useWorkspacesStore()
|
||||||
|
return {
|
||||||
|
formsStore,
|
||||||
|
workspacesStore,
|
||||||
|
user : computed(() => authStore.user),
|
||||||
|
workspaces : computed(() => workspacesStore.content),
|
||||||
|
loading : computed(() => workspacesStore.loading)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
appName: window.config.appName
|
appName: window.config.appName
|
||||||
}),
|
}),
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
|
||||||
workspaces: state => state['open/workspaces'].content,
|
|
||||||
loading: state => state['open/workspaces'].loading
|
|
||||||
}),
|
|
||||||
...mapGetters({
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
workspace () {
|
workspace () {
|
||||||
return this.$store.getters['open/workspaces/getCurrent']()
|
return this.workspacesStore.getCurrent()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -76,12 +85,12 @@ export default {
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
switchWorkspace (workspace) {
|
switchWorkspace (workspace) {
|
||||||
this.$store.commit('open/workspaces/setCurrentId', workspace.id)
|
this.workspacesStore.setCurrentId(workspace.id)
|
||||||
this.$refs.dropdown.close()
|
this.$refs.dropdown.close()
|
||||||
if (this.$route.name !== 'home') {
|
if (this.$route.name !== 'home') {
|
||||||
this.$router.push({ name: 'home' })
|
this.$router.push({ name: 'home' })
|
||||||
}
|
}
|
||||||
this.$store.dispatch('open/forms/load', workspace.id)
|
this.formsStore.load(workspace.id)
|
||||||
},
|
},
|
||||||
isUrl (str) {
|
isUrl (str) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -54,7 +54,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../stores/auth';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Breadcrumb',
|
name: 'Breadcrumb',
|
||||||
|
@ -66,20 +67,22 @@ export default {
|
||||||
path: { type: Array }
|
path: { type: Array }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
authenticated : computed(() => authStore.check)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
displayHome: true
|
displayHome: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {},
|
||||||
...mapGetters({
|
|
||||||
authenticated: 'auth/check'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted () {
|
mounted () {},
|
||||||
},
|
|
||||||
|
|
||||||
methods: {}
|
methods: {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { computed } from 'vue'
|
||||||
import Modal from '../Modal.vue'
|
import Modal from '../Modal.vue'
|
||||||
import {mapGetters} from 'vuex'
|
import { useAuthStore } from '../../stores/auth';
|
||||||
|
import { useWorkspacesStore } from '../../stores/workspaces';
|
||||||
import PricingTable from "../pages/pricing/PricingTable.vue";
|
import PricingTable from "../pages/pricing/PricingTable.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -46,6 +48,15 @@ export default {
|
||||||
components: {PricingTable, Modal},
|
components: {PricingTable, Modal},
|
||||||
props: {},
|
props: {},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const workspacesStore = useWorkspacesStore()
|
||||||
|
return {
|
||||||
|
user : computed(() => authStore.user),
|
||||||
|
currentWorkSpace : computed(() => workspacesStore.getCurrent())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
showPremiumModal: false,
|
showPremiumModal: false,
|
||||||
|
@ -54,10 +65,6 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
|
||||||
user: 'auth/user',
|
|
||||||
currentWorkSpace: 'open/workspaces/getCurrent',
|
|
||||||
}),
|
|
||||||
shouldDisplayProTag() {
|
shouldDisplayProTag() {
|
||||||
if (!window.config.paid_plans_enabled) return false
|
if (!window.config.paid_plans_enabled) return false
|
||||||
if (!this.user || !this.currentWorkSpace) return true
|
if (!this.user || !this.currentWorkSpace) return true
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
:data="countries"
|
:data="countries"
|
||||||
:disabled="disabled || countries.length===1" :searchable="true" :search-keys="['name']" :option-key="'code'" :color="color"
|
:disabled="disabled || countries.length===1" :searchable="true" :search-keys="['name']" :option-key="'code'" :color="color"
|
||||||
:has-error="hasValidation && form.errors.has(name)"
|
:has-error="hasValidation && form.errors.has(name)"
|
||||||
:placeholder="'Select a country'" :uppercase-labels="true" :theme="theme" @input="onChangeCountryCode"
|
:placeholder="'Select a country'" :uppercase-labels="true" :theme="theme" @update:model-value="onChangeCountryCode"
|
||||||
>
|
>
|
||||||
<template #option="props">
|
<template #option="props">
|
||||||
<div class="flex items-center space-x-2 hover:text-white">
|
<div class="flex items-center space-x-2 hover:text-white">
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
</v-select>
|
</v-select>
|
||||||
<input v-model="inputVal" type="text" class="inline-flex-grow !border-l-0 !rounded-l-none" :disabled="disabled"
|
<input v-model="inputVal" type="text" class="inline-flex-grow !border-l-0 !rounded-l-none" :disabled="disabled"
|
||||||
:class="[theme.default.input, { '!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200': disabled }]"
|
:class="[theme.default.input, { '!ring-red-500 !ring-2': hasValidation && form.errors.has(name), '!cursor-not-allowed !bg-gray-200': disabled }]"
|
||||||
:placeholder="placeholder" :style="inputStyle" @input="onInput"
|
:placeholder="placeholder" :style="inputStyle" @update:model-value="onInput"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
</input-help>
|
</input-help>
|
||||||
</slot>
|
</slot>
|
||||||
<slot name="error">
|
<slot name="error">
|
||||||
<has-error v-if="hasValidation" :form="form" :field="name" />
|
<has-error v-if="hasValidation && form" :form="form" :field="name" />
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState } from 'vuex'
|
|
||||||
import store from '~/store'
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -62,6 +62,9 @@
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useRecordsStore } from '../../../stores/records'
|
||||||
|
import { useWorkingFormStore } from '../../../stores/working_form'
|
||||||
import OpenFormButton from './OpenFormButton.vue'
|
import OpenFormButton from './OpenFormButton.vue'
|
||||||
import clonedeep from 'clone-deep'
|
import clonedeep from 'clone-deep'
|
||||||
import FormLogicPropertyResolver from '../../../forms/FormLogicPropertyResolver.js'
|
import FormLogicPropertyResolver from '../../../forms/FormLogicPropertyResolver.js'
|
||||||
|
@ -100,6 +103,16 @@ export default {
|
||||||
},
|
},
|
||||||
adminPreview: { type: Boolean, default: false } // If used in FormEditorPreview
|
adminPreview: { type: Boolean, default: false } // If used in FormEditorPreview
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const recordsStore = useRecordsStore()
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
recordsStore,
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
dataForm: null,
|
dataForm: null,
|
||||||
|
@ -154,8 +167,8 @@ export default {
|
||||||
newFields.push(...group)
|
newFields.push(...group)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// set the properties on working_form vuex
|
// set the properties on working_form store
|
||||||
this.$store.commit('open/working_form/setProperties', newFields)
|
this.workingFormStore.setProperties(newFields)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
@ -293,12 +306,12 @@ export default {
|
||||||
if (!this.form || !this.form.editable_submissions || !this.form.submission_id) {
|
if (!this.form || !this.form.editable_submissions || !this.form.submission_id) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
await this.$store.dispatch('open/records/loadRecord',
|
await this.recordsStore.loadRecord(
|
||||||
axios.get('/api/forms/' + this.form.slug + '/submissions/' + this.form.submission_id).then((response) => {
|
axios.get('/api/forms/' + this.form.slug + '/submissions/' + this.form.submission_id).then((response) => {
|
||||||
return { submission_id: this.form.submission_id, ...response.data.data }
|
return { submission_id: this.form.submission_id, ...response.data.data }
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
return this.$store.getters['open/records/getById'](this.form.submission_id)
|
return this.recordsStore.getById(this.form.submission_id)
|
||||||
},
|
},
|
||||||
async initForm () {
|
async initForm () {
|
||||||
if (this.isPublicFormPage && this.form.editable_submissions) {
|
if (this.isPublicFormPage && this.form.editable_submissions) {
|
||||||
|
|
|
@ -78,9 +78,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useWorkingFormStore } from '../../../stores/working_form';
|
||||||
import FormLogicPropertyResolver from '../../../forms/FormLogicPropertyResolver.js'
|
import FormLogicPropertyResolver from '../../../forms/FormLogicPropertyResolver.js'
|
||||||
import FormPendingSubmissionKey from '../../../mixins/forms/form-pending-submission-key.js'
|
import FormPendingSubmissionKey from '../../../mixins/forms/form-pending-submission-key.js'
|
||||||
import {mapState} from "vuex";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'OpenFormField',
|
name: 'OpenFormField',
|
||||||
|
@ -113,15 +114,21 @@ export default {
|
||||||
},
|
},
|
||||||
adminPreview: {type: Boolean, default: false} // If used in FormEditorPreview
|
adminPreview: {type: Boolean, default: false} // If used in FormEditorPreview
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore,
|
||||||
|
selectedFieldIndex : computed(() => workingFormStore.selectedFieldIndex),
|
||||||
|
showEditFieldSidebar : computed(() => workingFormStore.showEditFieldSidebar)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
|
||||||
selectedFieldIndex: state => state['open/working_form'].selectedFieldIndex,
|
|
||||||
showEditFieldSidebar: state => state['open/working_form'].showEditFieldSidebar
|
|
||||||
}),
|
|
||||||
fieldComponents() {
|
fieldComponents() {
|
||||||
return {
|
return {
|
||||||
text: 'TextInput',
|
text: 'TextInput',
|
||||||
|
@ -214,10 +221,10 @@ export default {
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
editFieldOptions() {
|
editFieldOptions() {
|
||||||
this.$store.commit('open/working_form/openSettingsForField', this.field)
|
this.workingFormStore.openSettingsForField(this.field)
|
||||||
},
|
},
|
||||||
openAddFieldSidebar() {
|
openAddFieldSidebar() {
|
||||||
this.$store.commit('open/working_form/openAddFieldSidebar', this.field)
|
this.workingFormStore.openAddFieldSidebar(this.field)
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Get the right input component for the field/options combination
|
* Get the right input component for the field/options combination
|
||||||
|
|
|
@ -13,12 +13,12 @@
|
||||||
label="Hide Form Title"
|
label="Hide Form Title"
|
||||||
:disabled="form.hide_title===true"
|
:disabled="form.hide_title===true"
|
||||||
:help="hideTitleHelp"
|
:help="hideTitleHelp"
|
||||||
@input="onChangeHideTitle"
|
@update:model-value="onChangeHideTitle"
|
||||||
/>
|
/>
|
||||||
<toggle-switch-input :value="value.auto_submit" name="auto_submit" class="mt-4"
|
<toggle-switch-input :value="value.auto_submit" name="auto_submit" class="mt-4"
|
||||||
label="Auto Submit Form"
|
label="Auto Submit Form"
|
||||||
help="Form will auto submit immediate after open URL"
|
help="Form will auto submit immediate after open URL"
|
||||||
@input="onChangeAutoSubmit"
|
@update:model-value="onChangeAutoSubmit"
|
||||||
/>
|
/>
|
||||||
</collapse>
|
</collapse>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -85,7 +85,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../../../stores/auth';
|
||||||
|
import { useFormsStore } from '../../../../stores/forms';
|
||||||
|
import { useWorkingFormStore } from '../../../../stores/working_form';
|
||||||
|
import { useWorkspacesStore } from '../../../../stores/workspaces';
|
||||||
import AddFormBlockSidebar from './form-components/AddFormBlockSidebar.vue'
|
import AddFormBlockSidebar from './form-components/AddFormBlockSidebar.vue'
|
||||||
import FormFieldEditSidebar from '../fields/FormFieldEditSidebar.vue'
|
import FormFieldEditSidebar from '../fields/FormFieldEditSidebar.vue'
|
||||||
import FormErrorModal from './form-components/FormErrorModal.vue'
|
import FormErrorModal from './form-components/FormErrorModal.vue'
|
||||||
|
@ -143,6 +147,19 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const formsStore = useFormsStore()
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
const workspacesStore = useWorkspacesStore()
|
||||||
|
return {
|
||||||
|
formsStore,
|
||||||
|
workingFormStore,
|
||||||
|
workspacesStore,
|
||||||
|
user : computed(() => authStore.user)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
showFormErrorModal: false,
|
showFormErrorModal: false,
|
||||||
|
@ -153,23 +170,20 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
createdForm () {
|
createdForm () {
|
||||||
return this.$store.getters['open/forms/getById'](this.createdFormId)
|
return this.formsStore.getById(this.createdFormId)
|
||||||
},
|
},
|
||||||
workspace () {
|
workspace () {
|
||||||
return this.$store.getters['open/workspaces/getCurrent']()
|
return this.workspacesStore.getCurrent()
|
||||||
},
|
},
|
||||||
steps () {
|
steps () {
|
||||||
return [
|
return [
|
||||||
|
@ -245,7 +259,7 @@ export default {
|
||||||
this.validationErrorResponse = null
|
this.validationErrorResponse = null
|
||||||
this.form.put('/api/open/forms/{id}/'.replace('{id}', this.form.id)).then((response) => {
|
this.form.put('/api/open/forms/{id}/'.replace('{id}', this.form.id)).then((response) => {
|
||||||
const data = response.data
|
const data = response.data
|
||||||
this.$store.commit('open/forms/addOrUpdate', data.form)
|
this.formsStore.addOrUpdate(data.form)
|
||||||
this.$emit('on-save')
|
this.$emit('on-save')
|
||||||
this.$router.push({ name: 'forms.show', params: { slug: this.form.slug } })
|
this.$router.push({ name: 'forms.show', params: { slug: this.form.slug } })
|
||||||
this.$logEvent('form_saved', { form_id: this.form.id, form_slug: this.form.slug })
|
this.$logEvent('form_saved', { form_id: this.form.id, form_slug: this.form.slug })
|
||||||
|
@ -266,7 +280,7 @@ export default {
|
||||||
|
|
||||||
this.updateFormLoading = true
|
this.updateFormLoading = true
|
||||||
this.form.post('/api/open/forms').then((response) => {
|
this.form.post('/api/open/forms').then((response) => {
|
||||||
this.$store.commit('open/forms/addOrUpdate', response.data.form)
|
this.formsStore.addOrUpdate(response.data.form)
|
||||||
this.$emit('on-save')
|
this.$emit('on-save')
|
||||||
this.createdFormId = response.data.form.id
|
this.createdFormId = response.data.form.id
|
||||||
|
|
||||||
|
|
|
@ -166,6 +166,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useWorkingFormStore } from '../../../../stores/working_form'
|
||||||
import draggable from 'vuedraggable'
|
import draggable from 'vuedraggable'
|
||||||
import ProTag from '../../../common/ProTag.vue'
|
import ProTag from '../../../common/ProTag.vue'
|
||||||
import clonedeep from 'clone-deep'
|
import clonedeep from 'clone-deep'
|
||||||
|
@ -182,6 +184,13 @@ export default {
|
||||||
EditableDiv
|
EditableDiv
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
formFields: [],
|
formFields: [],
|
||||||
|
@ -192,11 +201,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -313,7 +322,7 @@ export default {
|
||||||
return type
|
return type
|
||||||
},
|
},
|
||||||
editOptions (index) {
|
editOptions (index) {
|
||||||
this.$store.commit('open/working_form/openSettingsForField', index)
|
this.workingFormStore.openSettingsForField(index)
|
||||||
},
|
},
|
||||||
removeBlock (blockIndex) {
|
removeBlock (blockIndex) {
|
||||||
const newFields = clonedeep(this.formFields)
|
const newFields = clonedeep(this.formFields)
|
||||||
|
@ -322,10 +331,10 @@ export default {
|
||||||
this.closeSidebar()
|
this.closeSidebar()
|
||||||
},
|
},
|
||||||
closeSidebar () {
|
closeSidebar () {
|
||||||
this.$store.commit('open/working_form/closeEditFieldSidebar')
|
this.workingFormStore.closeEditFieldSidebar()
|
||||||
},
|
},
|
||||||
openAddFieldSidebar () {
|
openAddFieldSidebar () {
|
||||||
this.$store.commit('open/working_form/openAddFieldSidebar', null)
|
this.workingFormStore.openAddFieldSidebar(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
</h4>
|
</h4>
|
||||||
<div v-for="field in properties" :key="field.id" class="p-2 border">
|
<div v-for="field in properties" :key="field.id" class="p-2 border">
|
||||||
{{ field.name }}
|
{{ field.name }}
|
||||||
<v-switch v-model="displayColumns[field.id]" class="float-right" @input="onChangeDisplayColumns" />
|
<v-switch v-model="displayColumns[field.id]" class="float-right" @update:model-value="onChangeDisplayColumns" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="removed_properties.length > 0">
|
<template v-if="removed_properties.length > 0">
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
</h4>
|
</h4>
|
||||||
<div v-for="field in removed_properties" :key="field.id" class="p-2 border">
|
<div v-for="field in removed_properties" :key="field.id" class="p-2 border">
|
||||||
{{ field.name }}
|
{{ field.name }}
|
||||||
<v-switch v-model="displayColumns[field.id]" class="float-right" @input="onChangeDisplayColumns" />
|
<v-switch v-model="displayColumns[field.id]" class="float-right" @update:model-value="onChangeDisplayColumns" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
@ -83,6 +83,7 @@
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import Fuse from 'fuse.js'
|
import Fuse from 'fuse.js'
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
|
import { useWorkingFormStore } from '../../../../stores/working_form'
|
||||||
import ScrollShadow from '../../../common/ScrollShadow.vue'
|
import ScrollShadow from '../../../common/ScrollShadow.vue'
|
||||||
import OpenTable from '../../tables/OpenTable.vue'
|
import OpenTable from '../../tables/OpenTable.vue'
|
||||||
import clonedeep from 'clone-deep'
|
import clonedeep from 'clone-deep'
|
||||||
|
@ -92,6 +93,15 @@ export default {
|
||||||
name: 'FormSubmissions',
|
name: 'FormSubmissions',
|
||||||
components: { ScrollShadow, OpenTable, VSwitch },
|
components: { ScrollShadow, OpenTable, VSwitch },
|
||||||
props: {},
|
props: {},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
formInitDone: false,
|
formInitDone: false,
|
||||||
|
@ -111,10 +121,10 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
exportUrl () {
|
exportUrl () {
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<div class="mx-auto">
|
<div class="mx-auto">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24"
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24"
|
||||||
stroke="currentColor" stroke-width="2" v-html="block.icon"
|
stroke="currentColor" stroke-width="2" v-html="block.icon"
|
||||||
/>
|
></svg>
|
||||||
</div>
|
</div>
|
||||||
<p class="w-full text-xs text-gray-500 uppercase text-center font-semibold mt-1">
|
<p class="w-full text-xs text-gray-500 uppercase text-center font-semibold mt-1">
|
||||||
{{ block.title }}
|
{{ block.title }}
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
<div class="mx-auto">
|
<div class="mx-auto">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24"
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24"
|
||||||
stroke="currentColor" stroke-width="2" v-html="block.icon"
|
stroke="currentColor" stroke-width="2" v-html="block.icon"
|
||||||
/>
|
></svg>
|
||||||
</div>
|
</div>
|
||||||
<p class="w-full text-xs text-gray-500 uppercase text-center font-semibold mt-1">
|
<p class="w-full text-xs text-gray-500 uppercase text-center font-semibold mt-1">
|
||||||
{{ block.title }}
|
{{ block.title }}
|
||||||
|
@ -63,14 +63,26 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState } from 'vuex'
|
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
import clonedeep from 'clone-deep'
|
import clonedeep from 'clone-deep'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useWorkingFormStore } from '../../../../../stores/working_form'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AddFormBlockSidebar',
|
name: 'AddFormBlockSidebar',
|
||||||
components: {},
|
components: {},
|
||||||
props: {},
|
props: {},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore,
|
||||||
|
selectedFieldIndex : computed(() => workingFormStore.selectedFieldIndex),
|
||||||
|
showAddFieldSidebar : computed(() => workingFormStore.showAddFieldSidebar)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
blockForm: null,
|
blockForm: null,
|
||||||
|
@ -162,17 +174,13 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
|
||||||
selectedFieldIndex: state => state['open/working_form'].selectedFieldIndex,
|
|
||||||
showAddFieldSidebar: state => state['open/working_form'].showAddFieldSidebar
|
|
||||||
}),
|
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
showSidebar () {
|
showSidebar () {
|
||||||
|
@ -209,7 +217,7 @@ export default {
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
closeSidebar () {
|
closeSidebar () {
|
||||||
this.$store.commit('open/working_form/closeAddFieldSidebar')
|
this.workingFormStore.closeAddFieldSidebar()
|
||||||
},
|
},
|
||||||
reset () {
|
reset () {
|
||||||
this.blockForm = new Form({
|
this.blockForm = new Form({
|
||||||
|
@ -231,12 +239,12 @@ export default {
|
||||||
const newFields = clonedeep(this.form.properties)
|
const newFields = clonedeep(this.form.properties)
|
||||||
newFields.push(newBlock)
|
newFields.push(newBlock)
|
||||||
this.form.properties = newFields
|
this.form.properties = newFields
|
||||||
this.$store.commit('open/working_form/openSettingsForField', this.form.properties.length - 1)
|
this.workingFormStore.openSettingsForField(this.form.properties.length - 1)
|
||||||
} else {
|
} else {
|
||||||
const newFields = clonedeep(this.form.properties)
|
const newFields = clonedeep(this.form.properties)
|
||||||
newFields.splice(this.selectedFieldIndex + 1, 0, newBlock)
|
newFields.splice(this.selectedFieldIndex + 1, 0, newBlock)
|
||||||
this.form.properties = newFields
|
this.form.properties = newFields
|
||||||
this.$store.commit('open/working_form/openSettingsForField', this.selectedFieldIndex + 1)
|
this.workingFormStore.openSettingsForField(this.selectedFieldIndex + 1)
|
||||||
}
|
}
|
||||||
this.reset()
|
this.reset()
|
||||||
},
|
},
|
||||||
|
|
|
@ -129,6 +129,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useWorkingFormStore } from '../../../../../stores/working_form'
|
||||||
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
||||||
import ProTag from '../../../../common/ProTag.vue'
|
import ProTag from '../../../../common/ProTag.vue'
|
||||||
import VTransition from '../../../../common/transitions/VTransition.vue'
|
import VTransition from '../../../../common/transitions/VTransition.vue'
|
||||||
|
@ -136,6 +137,12 @@ import VTransition from '../../../../common/transitions/VTransition.vue'
|
||||||
export default {
|
export default {
|
||||||
components: {EditorOptionsPanel, ProTag, VTransition},
|
components: {EditorOptionsPanel, ProTag, VTransition},
|
||||||
props: {},
|
props: {},
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
submissionOptions: {}
|
submissionOptions: {}
|
||||||
|
@ -145,11 +152,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -38,11 +38,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useWorkingFormStore } from '../../../../../stores/working_form'
|
||||||
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { EditorOptionsPanel },
|
components: { EditorOptionsPanel },
|
||||||
props: {},
|
props: {},
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
}
|
}
|
||||||
|
@ -50,11 +57,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -17,12 +17,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useWorkingFormStore } from '../../../../../stores/working_form'
|
||||||
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
||||||
import CodeInput from '../../../../forms/CodeInput.vue'
|
import CodeInput from '../../../../forms/CodeInput.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { EditorOptionsPanel, CodeInput },
|
components: { EditorOptionsPanel, CodeInput },
|
||||||
props: {
|
props: {},
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -32,11 +38,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,11 +23,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useWorkingFormStore } from '../../../../../stores/working_form'
|
||||||
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { EditorOptionsPanel },
|
components: { EditorOptionsPanel },
|
||||||
props: {},
|
props: {},
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
}
|
}
|
||||||
|
@ -35,11 +42,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -71,7 +71,7 @@
|
||||||
/>
|
/>
|
||||||
<toggle-switch-input name="confetti_on_submission" :form="form" class="mt-4"
|
<toggle-switch-input name="confetti_on_submission" :form="form" class="mt-4"
|
||||||
label="Confetti on successful submisison"
|
label="Confetti on successful submisison"
|
||||||
@input="onChangeConfettiOnSubmission"
|
@update:model-value="onChangeConfettiOnSubmission"
|
||||||
/>
|
/>
|
||||||
<toggle-switch-input name="auto_save" :form="form"
|
<toggle-switch-input name="auto_save" :form="form"
|
||||||
label="Auto save form response"
|
label="Auto save form response"
|
||||||
|
@ -81,6 +81,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useWorkingFormStore } from '../../../../../stores/working_form'
|
||||||
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
||||||
import ProTag from '../../../../common/ProTag.vue'
|
import ProTag from '../../../../common/ProTag.vue'
|
||||||
|
|
||||||
|
@ -88,6 +89,12 @@ export default {
|
||||||
components: { EditorOptionsPanel, ProTag },
|
components: { EditorOptionsPanel, ProTag },
|
||||||
props: {
|
props: {
|
||||||
},
|
},
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
isMounted: false
|
isMounted: false
|
||||||
|
@ -97,11 +104,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -59,12 +59,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useWorkingFormStore } from '../../../../../stores/working_form'
|
||||||
import VSwitch from '../../../../forms/components/VSwitch.vue'
|
import VSwitch from '../../../../forms/components/VSwitch.vue'
|
||||||
import OpenCompleteForm from '../../OpenCompleteForm.vue'
|
import OpenCompleteForm from '../../OpenCompleteForm.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { OpenCompleteForm, VSwitch },
|
components: { OpenCompleteForm, VSwitch },
|
||||||
props: {
|
props: {},
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -75,11 +81,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
creating () { // returns true if we are creating a form
|
creating () { // returns true if we are creating a form
|
||||||
|
|
|
@ -66,14 +66,27 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import clonedeep from 'clone-deep'
|
||||||
|
import { useFormsStore } from '../../../../../stores/forms'
|
||||||
|
import { useWorkingFormStore } from '../../../../../stores/working_form'
|
||||||
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
||||||
import SelectInput from '../../../../forms/SelectInput.vue'
|
import SelectInput from '../../../../forms/SelectInput.vue'
|
||||||
import { mapState } from 'vuex'
|
|
||||||
import clonedeep from 'clone-deep'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { SelectInput, EditorOptionsPanel },
|
components: { SelectInput, EditorOptionsPanel },
|
||||||
props: {},
|
props: {},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const formsStore = useFormsStore()
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
formsStore,
|
||||||
|
workingFormStore,
|
||||||
|
forms : computed(() => formsStore.content)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
showCopyFormSettingsModal: false,
|
showCopyFormSettingsModal: false,
|
||||||
|
@ -106,20 +119,17 @@ export default {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
...mapState({
|
|
||||||
forms: state => state['open/forms'].content
|
|
||||||
}),
|
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
allTagsOptions () {
|
allTagsOptions () {
|
||||||
return this.$store.getters['open/forms/getAllTags'].map((tagname) => {
|
return this.formsStore.getAllTags.map((tagname) => {
|
||||||
return {
|
return {
|
||||||
name: tagname,
|
name: tagname,
|
||||||
value: tagname
|
value: tagname
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useWorkingFormStore } from '../../../../../stores/working_form'
|
||||||
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
||||||
import FormNotificationsOption from './components/FormNotificationsOption.vue'
|
import FormNotificationsOption from './components/FormNotificationsOption.vue'
|
||||||
import FormNotificationsSlack from './components/FormNotificationsSlack.vue'
|
import FormNotificationsSlack from './components/FormNotificationsSlack.vue'
|
||||||
|
@ -40,7 +41,12 @@ import FormNotificationsWebhook from './components/FormNotificationsWebhook.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { FormNotificationsSubmissionConfirmation, FormNotificationsSlack, FormNotificationsDiscord, FormNotificationsOption, EditorOptionsPanel, FormNotificationsWebhook },
|
components: { FormNotificationsSubmissionConfirmation, FormNotificationsSlack, FormNotificationsDiscord, FormNotificationsOption, EditorOptionsPanel, FormNotificationsWebhook },
|
||||||
props: {
|
props: {},
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -50,11 +56,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
zapierUrl: () => window.config.links.zapier_integration
|
zapierUrl: () => window.config.links.zapier_integration
|
||||||
|
|
|
@ -17,11 +17,17 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useWorkingFormStore } from '../../../../../stores/working_form'
|
||||||
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { EditorOptionsPanel },
|
components: { EditorOptionsPanel },
|
||||||
props: {
|
props: {},
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -30,11 +36,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -11,12 +11,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useWorkingFormStore } from '../../../../../stores/working_form'
|
||||||
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
import EditorOptionsPanel from '../../../editors/EditorOptionsPanel.vue'
|
||||||
import FormFieldsEditor from '../FormFieldsEditor.vue'
|
import FormFieldsEditor from '../FormFieldsEditor.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { EditorOptionsPanel, FormFieldsEditor },
|
components: { EditorOptionsPanel, FormFieldsEditor },
|
||||||
props: {
|
props: {},
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -26,11 +32,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,12 +46,19 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useWorkingFormStore } from '../../../../../../stores/working_form'
|
||||||
import ProTag from '../../../../../common/ProTag.vue'
|
import ProTag from '../../../../../common/ProTag.vue'
|
||||||
import FormNotificationsMessageActions from './FormNotificationsMessageActions.vue'
|
import FormNotificationsMessageActions from './FormNotificationsMessageActions.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { ProTag, FormNotificationsMessageActions },
|
components: { ProTag, FormNotificationsMessageActions },
|
||||||
props: {},
|
props: {},
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
showModal: false
|
showModal: false
|
||||||
|
@ -61,11 +68,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -50,11 +50,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useWorkingFormStore } from '../../../../../../stores/working_form'
|
||||||
import ProTag from '../../../../../common/ProTag.vue'
|
import ProTag from '../../../../../common/ProTag.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { ProTag },
|
components: { ProTag },
|
||||||
props: {},
|
props: {},
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
showModal: false
|
showModal: false
|
||||||
|
@ -64,11 +71,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
replayToEmailField () {
|
replayToEmailField () {
|
||||||
|
|
|
@ -47,12 +47,19 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useWorkingFormStore } from '../../../../../../stores/working_form'
|
||||||
import ProTag from '../../../../../common/ProTag.vue'
|
import ProTag from '../../../../../common/ProTag.vue'
|
||||||
import FormNotificationsMessageActions from './FormNotificationsMessageActions.vue'
|
import FormNotificationsMessageActions from './FormNotificationsMessageActions.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { ProTag, FormNotificationsMessageActions },
|
components: { ProTag, FormNotificationsMessageActions },
|
||||||
props: {},
|
props: {},
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
showModal: false
|
showModal: false
|
||||||
|
@ -62,11 +69,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -62,11 +62,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useWorkingFormStore } from '../../../../../../stores/working_form'
|
||||||
import ProTag from '../../../../../common/ProTag.vue'
|
import ProTag from '../../../../../common/ProTag.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { ProTag },
|
components: { ProTag },
|
||||||
props: {},
|
props: {},
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
showModal: false
|
showModal: false
|
||||||
|
@ -76,11 +83,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emailSubmissionConfirmationField () {
|
emailSubmissionConfirmationField () {
|
||||||
|
|
|
@ -43,11 +43,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useWorkingFormStore } from '../../../../../../stores/working_form'
|
||||||
import ProTag from '../../../../../common/ProTag.vue'
|
import ProTag from '../../../../../common/ProTag.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { ProTag },
|
components: { ProTag },
|
||||||
props: {},
|
props: {},
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
showModal: false
|
showModal: false
|
||||||
|
@ -57,11 +64,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
:multiple="true" class="mt-1" placeholder="Actions..."
|
:multiple="true" class="mt-1" placeholder="Actions..."
|
||||||
help="Action(s) triggerred when above conditions are true"
|
help="Action(s) triggerred when above conditions are true"
|
||||||
:options="actionOptions"
|
:options="actionOptions"
|
||||||
@input="onActionInput"
|
@update:model-value="onActionInput"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<modal :show="showCopyFormModal" @close="showCopyFormModal = false">
|
<modal :show="showCopyFormModal" @close="showCopyFormModal = false">
|
||||||
|
|
|
@ -72,10 +72,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Form from 'vform'
|
|
||||||
import store from '~/store'
|
|
||||||
import { mapState, mapGetters } from 'vuex'
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import Form from 'vform'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../../../../stores/auth'
|
||||||
|
import { useTemplatesStore } from '../../../../../stores/templates'
|
||||||
import QuestionsEditor from './QuestionsEditor.vue'
|
import QuestionsEditor from './QuestionsEditor.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -87,6 +88,18 @@ export default {
|
||||||
template: { type: Object, required: false, default: () => {} }
|
template: { type: Object, required: false, default: () => {} }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const templatesStore = useTemplatesStore()
|
||||||
|
return {
|
||||||
|
templatesStore,
|
||||||
|
user : computed(() => authStore.user),
|
||||||
|
templates : computed(() => templatesStore.content),
|
||||||
|
industries : computed(() => templatesStore.industries),
|
||||||
|
types : computed(() => templatesStore.types)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
templateForm: null
|
templateForm: null
|
||||||
}),
|
}),
|
||||||
|
@ -104,18 +117,10 @@ export default {
|
||||||
related_templates: null,
|
related_templates: null,
|
||||||
questions: []
|
questions: []
|
||||||
})
|
})
|
||||||
store.dispatch('open/templates/loadIfEmpty')
|
this.templatesStore.loadIfEmpty()
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
|
||||||
templates: state => state['open/templates'].content,
|
|
||||||
industries: state => state['open/templates'].industries,
|
|
||||||
types: state => state['open/templates'].types
|
|
||||||
}),
|
|
||||||
...mapGetters({
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
typesOptions () {
|
typesOptions () {
|
||||||
return Object.values(this.types).map((type) => {
|
return Object.values(this.types).map((type) => {
|
||||||
return {
|
return {
|
||||||
|
@ -156,7 +161,7 @@ export default {
|
||||||
if (response.data.message) {
|
if (response.data.message) {
|
||||||
this.alertSuccess(response.data.message)
|
this.alertSuccess(response.data.message)
|
||||||
}
|
}
|
||||||
this.$store.commit('open/templates/addOrUpdate', response.data.data)
|
this.templatesStore.addOrUpdate(response.data.data)
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -166,7 +171,7 @@ export default {
|
||||||
if (response.data.message) {
|
if (response.data.message) {
|
||||||
this.alertSuccess(response.data.message)
|
this.alertSuccess(response.data.message)
|
||||||
}
|
}
|
||||||
this.$store.commit('open/templates/addOrUpdate', response.data.data)
|
this.templatesStore.addOrUpdate(response.data.data)
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -177,7 +182,7 @@ export default {
|
||||||
this.alertSuccess(response.data.message)
|
this.alertSuccess(response.data.message)
|
||||||
}
|
}
|
||||||
this.$router.push({ name: 'templates' })
|
this.$router.push({ name: 'templates' })
|
||||||
this.$store.commit('open/templates/remove', this.template)
|
this.templatesStore.remove(this.template)
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,8 +70,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState } from 'vuex'
|
import { computed } from 'vue'
|
||||||
import clonedeep from 'clone-deep'
|
import clonedeep from 'clone-deep'
|
||||||
|
import { useWorkingFormStore } from '../../../../stores/working_form'
|
||||||
import ChangeFieldType from './components/ChangeFieldType.vue'
|
import ChangeFieldType from './components/ChangeFieldType.vue'
|
||||||
import FieldOptions from './components/FieldOptions.vue'
|
import FieldOptions from './components/FieldOptions.vue'
|
||||||
import BlockOptions from './components/BlockOptions.vue'
|
import BlockOptions from './components/BlockOptions.vue'
|
||||||
|
@ -80,6 +81,14 @@ export default {
|
||||||
name: 'FormFieldEditSidebar',
|
name: 'FormFieldEditSidebar',
|
||||||
components: { ChangeFieldType, FieldOptions, BlockOptions },
|
components: { ChangeFieldType, FieldOptions, BlockOptions },
|
||||||
props: {},
|
props: {},
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore,
|
||||||
|
selectedFieldIndex : computed(() => workingFormStore.selectedFieldIndex),
|
||||||
|
showEditFieldSidebar : computed(() => workingFormStore.showEditFieldSidebar)
|
||||||
|
}
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
|
||||||
|
@ -87,17 +96,13 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
|
||||||
selectedFieldIndex: state => state['open/working_form'].selectedFieldIndex,
|
|
||||||
showEditFieldSidebar: state => state['open/working_form'].showEditFieldSidebar
|
|
||||||
}),
|
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
field () {
|
field () {
|
||||||
|
@ -145,7 +150,7 @@ export default {
|
||||||
this.closeSidebar()
|
this.closeSidebar()
|
||||||
},
|
},
|
||||||
closeSidebar () {
|
closeSidebar () {
|
||||||
this.$store.commit('open/working_form/closeEditFieldSidebar')
|
this.workingFormStore.closeEditFieldSidebar()
|
||||||
},
|
},
|
||||||
generateUUID () {
|
generateUUID () {
|
||||||
let d = new Date().getTime()// Timestamp
|
let d = new Date().getTime()// Timestamp
|
||||||
|
|
|
@ -186,7 +186,7 @@
|
||||||
<text-area-input v-model="optionsText" :name="field.id+'_options_text'" class="mt-3"
|
<text-area-input v-model="optionsText" :name="field.id+'_options_text'" class="mt-3"
|
||||||
label="Set selection options"
|
label="Set selection options"
|
||||||
help="Add one option per line"
|
help="Add one option per line"
|
||||||
@input="onFieldOptionsChange"
|
@update:model-value="onFieldOptionsChange"
|
||||||
/>
|
/>
|
||||||
<v-checkbox v-model="field.allow_creation"
|
<v-checkbox v-model="field.allow_creation"
|
||||||
name="allow_creation" help="" @update:model-value="onFieldAllowCreationChange"
|
name="allow_creation" help="" @update:model-value="onFieldAllowCreationChange"
|
||||||
|
|
|
@ -78,6 +78,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useWorkingFormStore } from '../../../stores/working_form'
|
||||||
import OpenText from './components/OpenText.vue'
|
import OpenText from './components/OpenText.vue'
|
||||||
import OpenUrl from './components/OpenUrl.vue'
|
import OpenUrl from './components/OpenUrl.vue'
|
||||||
import OpenSelect from './components/OpenSelect.vue'
|
import OpenSelect from './components/OpenSelect.vue'
|
||||||
|
@ -119,6 +120,13 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
return {
|
||||||
|
workingFormStore
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
tableHash: null,
|
tableHash: null,
|
||||||
|
@ -129,10 +137,11 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hasActions () {
|
hasActions () {
|
||||||
|
|
|
@ -31,18 +31,23 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../stores/auth'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
user : computed(() => authStore.user)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
appName: window.config.appName,
|
appName: window.config.appName,
|
||||||
currYear: new Date().getFullYear(),
|
currYear: new Date().getFullYear(),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
helpUrl: () => window.config.links.help_url,
|
helpUrl: () => window.config.links.help_url,
|
||||||
githubUrl: () => window.config.links.github_url,
|
githubUrl: () => window.config.links.github_url,
|
||||||
forumUrl: () => window.config.links.github_forum_url,
|
forumUrl: () => window.config.links.github_forum_url,
|
||||||
|
|
|
@ -24,28 +24,34 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../stores/auth';
|
||||||
|
import { useWorkspacesStore } from '../../stores/workspaces';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const workspacesStore = useWorkspacesStore()
|
||||||
|
return {
|
||||||
|
authStore,
|
||||||
|
workspacesStore,
|
||||||
|
isImpersonating : computed(() => authStore.isImpersonating),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
loading: false
|
loading: false
|
||||||
}),
|
}),
|
||||||
|
|
||||||
computed: {
|
computed: {},
|
||||||
...mapGetters({
|
|
||||||
isImpersonating: 'auth/isImpersonating'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted () {
|
mounted () {},
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
reverseImpersonation () {
|
reverseImpersonation () {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
this.$store.dispatch('auth/stopImpersonating')
|
this.authStore.stopImpersonating().then(() => {
|
||||||
.then(() => {
|
this.workspacesStore.set([])
|
||||||
this.$store.commit('open/workspaces/set', [])
|
|
||||||
this.$router.push({ name: 'settings.admin' })
|
this.$router.push({ name: 'settings.admin' })
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
|
|
|
@ -62,14 +62,22 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { computed } from 'vue'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { mapGetters } from 'vuex'
|
import { useAuthStore } from '../../../stores/auth';
|
||||||
import VTransition from '../../common/transitions/VTransition.vue'
|
import VTransition from '../../common/transitions/VTransition.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { VTransition },
|
components: { VTransition },
|
||||||
props: {},
|
props: {},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
user : computed(() => authStore.user)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
changelogEntries: [],
|
changelogEntries: [],
|
||||||
showNewFeatures: false
|
showNewFeatures: false
|
||||||
|
@ -80,9 +88,6 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
requestFeatureLink () {
|
requestFeatureLink () {
|
||||||
return window.config.links.feature_requests
|
return window.config.links.feature_requests
|
||||||
},
|
},
|
||||||
|
|
|
@ -122,8 +122,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { computed } from 'vue'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import {mapGetters, mapState} from 'vuex'
|
import { useAuthStore } from '../../../../stores/auth'
|
||||||
|
import { useFormsStore } from '../../../../stores/forms'
|
||||||
import Dropdown from '../../../common/Dropdown.vue'
|
import Dropdown from '../../../common/Dropdown.vue'
|
||||||
import FormTemplateModal from '../../../open/forms/components/templates/FormTemplateModal.vue'
|
import FormTemplateModal from '../../../open/forms/components/templates/FormTemplateModal.vue'
|
||||||
|
|
||||||
|
@ -135,6 +137,15 @@ export default {
|
||||||
isMainPage: { type: Boolean, required: false, default: false }
|
isMainPage: { type: Boolean, required: false, default: false }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const formsStore = useFormsStore()
|
||||||
|
return {
|
||||||
|
formsStore,
|
||||||
|
user : computed(() => authStore.user)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
loadingDuplicate: false,
|
loadingDuplicate: false,
|
||||||
loadingDelete: false,
|
loadingDelete: false,
|
||||||
|
@ -143,9 +154,6 @@ export default {
|
||||||
}),
|
}),
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
formEndpoint: () => '/api/open/forms/{id}',
|
formEndpoint: () => '/api/open/forms/{id}',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -163,7 +171,7 @@ export default {
|
||||||
if (this.loadingDuplicate) return
|
if (this.loadingDuplicate) return
|
||||||
this.loadingDuplicate = true
|
this.loadingDuplicate = true
|
||||||
axios.post(this.formEndpoint.replace('{id}', this.form.id) + '/duplicate').then((response) => {
|
axios.post(this.formEndpoint.replace('{id}', this.form.id) + '/duplicate').then((response) => {
|
||||||
this.$store.commit('open/forms/addOrUpdate', response.data.new_form)
|
this.formsStore.addOrUpdate(response.data.new_form)
|
||||||
this.$router.push({name: 'forms.show', params: {slug: response.data.new_form.slug}})
|
this.$router.push({name: 'forms.show', params: {slug: response.data.new_form.slug}})
|
||||||
this.alertSuccess('Form was successfully duplicated.')
|
this.alertSuccess('Form was successfully duplicated.')
|
||||||
this.loadingDuplicate = false
|
this.loadingDuplicate = false
|
||||||
|
@ -173,7 +181,7 @@ export default {
|
||||||
if (this.loadingDelete) return
|
if (this.loadingDelete) return
|
||||||
this.loadingDelete = true
|
this.loadingDelete = true
|
||||||
axios.delete(this.formEndpoint.replace('{id}', this.form.id)).then(() => {
|
axios.delete(this.formEndpoint.replace('{id}', this.form.id)).then(() => {
|
||||||
this.$store.commit('open/forms/remove', this.form)
|
this.formsStore.remove(this.form)
|
||||||
this.$router.push({name: 'home'})
|
this.$router.push({name: 'home'})
|
||||||
this.alertSuccess('Form was deleted.')
|
this.alertSuccess('Form was deleted.')
|
||||||
this.loadingDelete = false
|
this.loadingDelete = false
|
||||||
|
|
|
@ -72,7 +72,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { computed } from 'vue'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import { useFormsStore } from '../../../../stores/forms'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'RegenerateFormLink',
|
name: 'RegenerateFormLink',
|
||||||
|
@ -81,6 +83,13 @@ export default {
|
||||||
form: { type: Object, required: true }
|
form: { type: Object, required: true }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const formsStore = useFormsStore()
|
||||||
|
return {
|
||||||
|
formsStore
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
loadingNewLink: false,
|
loadingNewLink: false,
|
||||||
showGenerateFormLinkModal: false,
|
showGenerateFormLinkModal: false,
|
||||||
|
@ -95,7 +104,7 @@ export default {
|
||||||
if (this.loadingNewLink) return
|
if (this.loadingNewLink) return
|
||||||
this.loadingNewLink = true
|
this.loadingNewLink = true
|
||||||
axios.put(this.formEndpoint.replace('{id}', this.form.id) + '/regenerate-link/' + option).then((response) => {
|
axios.put(this.formEndpoint.replace('{id}', this.form.id) + '/regenerate-link/' + option).then((response) => {
|
||||||
this.$store.commit('open/forms/addOrUpdate', response.data.form)
|
this.formsStore.addOrUpdate(response.data.form)
|
||||||
this.$router.push({name: 'forms.show', params: {slug: response.data.form.slug}})
|
this.$router.push({name: 'forms.show', params: {slug: response.data.form.slug}})
|
||||||
this.alertSuccess(response.data.message)
|
this.alertSuccess(response.data.message)
|
||||||
this.loadingNewLink = false
|
this.loadingNewLink = false
|
||||||
|
|
|
@ -11,14 +11,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { computed } from 'vue'
|
||||||
import TextInput from '../../forms/TextInput.vue'
|
|
||||||
import Form from 'vform'
|
|
||||||
import VButton from '../../common/Button.vue'
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import Form from 'vform'
|
||||||
|
import { useAuthStore } from '../../../stores/auth'
|
||||||
|
import TextInput from '../../forms/TextInput.vue'
|
||||||
|
import VButton from '../../common/Button.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
components: { VButton, TextInput },
|
components: { VButton, TextInput },
|
||||||
props: {
|
props: {
|
||||||
show: {
|
show: {
|
||||||
|
@ -34,6 +34,14 @@ export default {
|
||||||
default: true
|
default: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
user : computed(() => authStore.user)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
form: new Form({
|
form: new Form({
|
||||||
name: '',
|
name: '',
|
||||||
|
@ -88,10 +96,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {}
|
||||||
...mapGetters({
|
|
||||||
user: 'auth/user'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -107,7 +107,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../../stores/auth'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import MonthlyYearlySelector from './MonthlyYearlySelector.vue'
|
import MonthlyYearlySelector from './MonthlyYearlySelector.vue'
|
||||||
import CheckoutDetailsModal from './CheckoutDetailsModal.vue'
|
import CheckoutDetailsModal from './CheckoutDetailsModal.vue'
|
||||||
|
@ -127,6 +128,13 @@ export default {
|
||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
authenticated : computed(() => authStore.check),
|
||||||
|
user : computed(() => authStore.user)
|
||||||
|
}
|
||||||
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
isYearly: true,
|
isYearly: true,
|
||||||
selectedPlan: 'pro',
|
selectedPlan: 'pro',
|
||||||
|
@ -160,11 +168,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {}
|
||||||
...mapGetters({
|
|
||||||
authenticated: 'auth/check',
|
|
||||||
user: 'auth/user'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -39,7 +39,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import store from '~/store'
|
import { computed } from 'vue'
|
||||||
|
import { useTemplatesStore } from '../../../stores/templates'
|
||||||
import TemplateTags from './TemplateTags.vue'
|
import TemplateTags from './TemplateTags.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -52,22 +53,29 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const templatesStore = useTemplatesStore()
|
||||||
|
return {
|
||||||
|
templatesStore
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({}),
|
data: () => ({}),
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
template () {
|
template () {
|
||||||
return this.$store.getters['open/templates/getBySlug'](this.slug)
|
return this.templatesStore.getBySlug(this.slug)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
slug () {
|
slug () {
|
||||||
store.dispatch('open/templates/loadTemplate', this.slug)
|
this.templatesStore.loadTemplate(this.slug)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted () {
|
mounted () {
|
||||||
store.dispatch('open/templates/loadTemplate', this.slug)
|
this.templatesStore.loadTemplate(this.slug)
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -41,6 +41,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useTemplatesStore } from '../../../stores/templates'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
slug: {
|
slug: {
|
||||||
|
@ -53,19 +56,26 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const templatesStore = useTemplatesStore()
|
||||||
|
return {
|
||||||
|
templatesStore
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({}),
|
data: () => ({}),
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
template () {
|
template () {
|
||||||
return this.$store.getters['open/templates/getBySlug'](this.slug)
|
return this.templatesStore.getBySlug(this.slug)
|
||||||
},
|
},
|
||||||
types () {
|
types () {
|
||||||
if (!this.template) return null
|
if (!this.template) return null
|
||||||
return this.$store.getters['open/templates/getTemplateTypes'](this.template.types)
|
return this.templatesStore.getTemplateTypes(this.template.types)
|
||||||
},
|
},
|
||||||
industries () {
|
industries () {
|
||||||
if (!this.template) return null
|
if (!this.template) return null
|
||||||
return this.$store.getters['open/templates/getTemplateIndustries'](this.template.industries)
|
return this.templatesStore.getTemplateIndustries(this.template.industries)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -79,24 +79,25 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import store from '~/store'
|
import { computed } from 'vue'
|
||||||
import { mapGetters, mapState } from 'vuex'
|
import { useAuthStore } from '../../../stores/auth'
|
||||||
|
import { useTemplatesStore } from '../../../stores/templates'
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
import Fuse from 'fuse.js'
|
import Fuse from 'fuse.js'
|
||||||
import SingleTemplate from './SingleTemplate.vue'
|
import SingleTemplate from './SingleTemplate.vue'
|
||||||
|
|
||||||
const loadTemplates = function (onlyMy) {
|
const loadTemplates = function (onlyMy) {
|
||||||
|
const templatesStore = useTemplatesStore()
|
||||||
if(onlyMy){
|
if(onlyMy){
|
||||||
store.dispatch('open/templates/loadAll', {'onlymy':true})
|
templatesStore.loadAll({'onlymy':true})
|
||||||
} else {
|
} else {
|
||||||
store.dispatch('open/templates/loadIfEmpty')
|
templatesStore.loadIfEmpty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TemplatesList',
|
name: 'TemplatesList',
|
||||||
components: { SingleTemplate },
|
components: { SingleTemplate },
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
onlyMy: {
|
onlyMy: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@ -104,6 +105,18 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const templatesStore = useTemplatesStore()
|
||||||
|
return {
|
||||||
|
user : computed(() => authStore.user),
|
||||||
|
templates : computed(() => templatesStore.content),
|
||||||
|
templatesLoading : computed(() => templatesStore.loading),
|
||||||
|
industries : computed(() => templatesStore.industries),
|
||||||
|
types : computed(() => templatesStore.types)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
selectedType: 'all',
|
selectedType: 'all',
|
||||||
selectedIndustry: 'all',
|
selectedIndustry: 'all',
|
||||||
|
@ -119,15 +132,6 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
|
||||||
templates: state => state['open/templates'].content,
|
|
||||||
templatesLoading: state => state['open/templates'].loading,
|
|
||||||
industries: state => state['open/templates'].industries,
|
|
||||||
types: state => state['open/templates'].types
|
|
||||||
}),
|
|
||||||
...mapGetters({
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
industriesOptions () {
|
industriesOptions () {
|
||||||
return [{ name: 'All Industries', value: 'all' }].concat(Object.values(this.industries).map((industry) => {
|
return [{ name: 'All Industries', value: 'all' }].concat(Object.values(this.industries).map((industry) => {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -87,16 +87,19 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {mapGetters} from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../../stores/auth'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
authenticated : computed(() => authStore.check)
|
||||||
|
}
|
||||||
|
},
|
||||||
props: {},
|
props: {},
|
||||||
data: () => ({}),
|
data: () => ({}),
|
||||||
computed: {
|
computed: {},
|
||||||
...mapGetters({
|
|
||||||
authenticated: 'auth/check'
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
methods: {}
|
methods: {}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -36,19 +36,23 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import store from '~/store'
|
import { computed } from 'vue'
|
||||||
import { mapGetters, mapState } from 'vuex'
|
import { useTemplatesStore } from '../../../stores/templates'
|
||||||
import SingleTemplate from '../templates/SingleTemplate.vue'
|
import SingleTemplate from '../templates/SingleTemplate.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { SingleTemplate },
|
components: { SingleTemplate },
|
||||||
props: { },
|
props: { },
|
||||||
|
setup () {
|
||||||
|
const templatesStore = useTemplatesStore()
|
||||||
|
return {
|
||||||
|
templatesStore,
|
||||||
|
templates : computed(() => templatesStore.content)
|
||||||
|
}
|
||||||
|
},
|
||||||
data: () => ({}),
|
data: () => ({}),
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
|
||||||
templates: state => state['open/templates'].content
|
|
||||||
}),
|
|
||||||
sliderTemplates () {
|
sliderTemplates () {
|
||||||
return this.templates.slice(0, 20)
|
return this.templates.slice(0, 20)
|
||||||
}
|
}
|
||||||
|
@ -66,7 +70,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
store.dispatch('open/templates/loadAll', { limit: 20 })
|
this.templatesStore.loadAll({ limit: 20 })
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -1,12 +1,21 @@
|
||||||
<template />
|
<template />
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../stores/auth'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
name: 'Amplitude',
|
name: 'Amplitude',
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
authStore,
|
||||||
|
authenticated : computed(() => authStore.check),
|
||||||
|
user : computed(() => authStore.user)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
loaded: false,
|
loaded: false,
|
||||||
|
@ -14,12 +23,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {},
|
||||||
...mapGetters({
|
|
||||||
authenticated: 'auth/check',
|
|
||||||
user: 'auth/user'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
$route () {
|
$route () {
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
<template />
|
<template />
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../stores/auth'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
name: 'Hotjar',
|
name: 'Hotjar',
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
authenticated : computed(() => authStore.check),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
authenticated () {
|
authenticated () {
|
||||||
if (this.authenticated) {
|
if (this.authenticated) {
|
||||||
|
@ -38,9 +45,6 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
|
||||||
authenticated: 'auth/check'
|
|
||||||
}),
|
|
||||||
isIframe () {
|
isIframe () {
|
||||||
return window.location !== window.parent.location || window.frameElement
|
return window.location !== window.parent.location || window.frameElement
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,23 +21,27 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../../stores/auth'
|
||||||
import VButton from '../../common/Button.vue'
|
import VButton from '../../common/Button.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
name: 'AppSumoBilling',
|
name: 'AppSumoBilling',
|
||||||
components: { VButton },
|
components: { VButton },
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
user : computed(() => authStore.user),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
licenseTier () {
|
licenseTier () {
|
||||||
return this.user?.active_license?.meta?.tier
|
return this.user?.active_license?.meta?.tier
|
||||||
},
|
},
|
||||||
|
@ -67,10 +71,9 @@ export default {
|
||||||
|
|
||||||
mounted () {},
|
mounted () {},
|
||||||
|
|
||||||
created () {
|
created () {},
|
||||||
},
|
|
||||||
destroyed () {
|
destroyed () {},
|
||||||
},
|
|
||||||
|
|
||||||
methods: {}
|
methods: {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import store from '~/store'
|
import { useAuthStore } from '../stores/auth';
|
||||||
|
|
||||||
export default (to, from, next) => {
|
export default (to, from, next) => {
|
||||||
if (!store.getters['auth/user'].admin) {
|
const authStore = useAuthStore()
|
||||||
|
if (!authStore.user?.admin) {
|
||||||
next({ name: 'home' })
|
next({ name: 'home' })
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import store from '~/store'
|
import { useAuthStore } from '../stores/auth';
|
||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
|
|
||||||
export default async (to, from, next) => {
|
export default async (to, from, next) => {
|
||||||
if (!store.getters['auth/check']) {
|
const authStore = useAuthStore()
|
||||||
|
if (!authStore.check) {
|
||||||
Cookies.set('intended_url', to.path)
|
Cookies.set('intended_url', to.path)
|
||||||
|
|
||||||
next({ name: 'login' })
|
next({ name: 'login' })
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import store from '~/store'
|
import { useAuthStore } from '../stores/auth';
|
||||||
import * as Sentry from '@sentry/vue'
|
import * as Sentry from '@sentry/vue'
|
||||||
|
|
||||||
export function initCrisp (user) {
|
export function initCrisp (user) {
|
||||||
|
@ -36,12 +36,13 @@ export function initSentry (user) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async (to, from, next) => {
|
export default async (to, from, next) => {
|
||||||
if (!store.getters['auth/check'] &&
|
const authStore = useAuthStore()
|
||||||
store.getters['auth/token'] !== null &&
|
if (!authStore.check &&
|
||||||
store.getters['auth/token'] !== undefined
|
authStore.token !== null &&
|
||||||
|
authStore.token !== undefined
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
store.dispatch('auth/fetchUser').then((user) => {
|
authStore.fetchUser().then((user) => {
|
||||||
initCrisp(user)
|
initCrisp(user)
|
||||||
initSentry(user)
|
initSentry(user)
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import store from '~/store'
|
import { useAuthStore } from '../stores/auth';
|
||||||
|
|
||||||
export default (to, from, next) => {
|
export default (to, from, next) => {
|
||||||
if (store.getters['auth/check']) {
|
const authStore = useAuthStore()
|
||||||
|
if (authStore.check) {
|
||||||
next({ name: 'home' })
|
next({ name: 'home' })
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import store from '~/store'
|
import { useAuthStore } from '../stores/auth';
|
||||||
|
|
||||||
export default async (to, from, next) => {
|
export default async (to, from, next) => {
|
||||||
if (store.getters['auth/check'] && store.getters['auth/user'].workspaces_count === 0) {
|
const authStore = useAuthStore()
|
||||||
|
if (authStore.check && authStore.user?.workspaces_count === 0) {
|
||||||
if ([
|
if ([
|
||||||
'forms.create',
|
'forms.create',
|
||||||
'forms.show',
|
'forms.show',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import store from '~/store'
|
import { useAuthStore } from '../stores/auth';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is middleware to check the current user role.
|
* This is middleware to check the current user role.
|
||||||
|
@ -7,14 +7,13 @@ import store from '~/store'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default (to, from, next, roles) => {
|
export default (to, from, next, roles) => {
|
||||||
// Grab the user
|
const authStore = useAuthStore()
|
||||||
const user = store.getters['auth/user']
|
|
||||||
|
|
||||||
// Split roles into an array
|
// Split roles into an array
|
||||||
roles = roles.split(',')
|
roles = roles.split(',')
|
||||||
|
|
||||||
// Check if the user has one of the required roles...
|
// Check if the user has one of the required roles...
|
||||||
if (!roles.includes(user.role)) {
|
if (!roles.includes(authStore.user?.role)) {
|
||||||
next('/unauthorized')
|
next('/unauthorized')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import store from '~/store'
|
import { useAuthStore } from '../stores/auth';
|
||||||
|
|
||||||
export default (to, from, next) => {
|
export default (to, from, next) => {
|
||||||
if (!store.getters['auth/user'].is_subscribed) {
|
const authStore = useAuthStore()
|
||||||
|
if (!authStore.user?.is_subscribed) {
|
||||||
next({ name: 'pricing' })
|
next({ name: 'pricing' })
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
|
|
|
@ -476,7 +476,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {mapGetters} from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../stores/auth'
|
||||||
import OpenFormFooter from '../components/pages/OpenFormFooter.vue'
|
import OpenFormFooter from '../components/pages/OpenFormFooter.vue'
|
||||||
import SeoMeta from '../mixins/seo-meta.js'
|
import SeoMeta from '../mixins/seo-meta.js'
|
||||||
|
|
||||||
|
@ -484,6 +485,14 @@ export default {
|
||||||
components: {OpenFormFooter},
|
components: {OpenFormFooter},
|
||||||
layout: 'default',
|
layout: 'default',
|
||||||
mixins: [SeoMeta],
|
mixins: [SeoMeta],
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
authenticated : computed(() => authStore.check),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
title: window.config.appName,
|
title: window.config.appName,
|
||||||
metaTitle: 'AI form builder for free',
|
metaTitle: 'AI form builder for free',
|
||||||
|
@ -494,9 +503,6 @@ export default {
|
||||||
methods: {},
|
methods: {},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
|
||||||
authenticated: 'auth/check'
|
|
||||||
}),
|
|
||||||
configLinks: () => window.config.links
|
configLinks: () => window.config.links
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,8 +41,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { computed } from 'vue'
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
|
import { useAuthStore } from '../../../stores/auth'
|
||||||
import OpenFormFooter from '../../../components/pages/OpenFormFooter.vue'
|
import OpenFormFooter from '../../../components/pages/OpenFormFooter.vue'
|
||||||
import Testimonials from '../../../components/pages/welcome/Testimonials.vue'
|
import Testimonials from '../../../components/pages/welcome/Testimonials.vue'
|
||||||
import ForgotPasswordModal from '../ForgotPasswordModal.vue'
|
import ForgotPasswordModal from '../ForgotPasswordModal.vue'
|
||||||
|
@ -62,6 +64,13 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
authStore
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
form: new Form({
|
form: new Form({
|
||||||
email: '',
|
email: '',
|
||||||
|
@ -77,13 +86,10 @@ export default {
|
||||||
const { data } = await this.form.post('/api/login')
|
const { data } = await this.form.post('/api/login')
|
||||||
|
|
||||||
// Save the token.
|
// Save the token.
|
||||||
this.$store.dispatch('auth/saveToken', {
|
this.authStore.saveToken(data.token, this.remember)
|
||||||
token: data.token,
|
|
||||||
remember: this.remember
|
|
||||||
})
|
|
||||||
|
|
||||||
// Fetch the user.
|
// Fetch the user.
|
||||||
await this.$store.dispatch('auth/fetchUser')
|
await this.authStore.fetchUser()
|
||||||
|
|
||||||
// Redirect home.
|
// Redirect home.
|
||||||
this.redirect()
|
this.redirect()
|
||||||
|
|
|
@ -48,7 +48,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { computed } from 'vue'
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
|
import { useAuthStore } from '../../../stores/auth'
|
||||||
import { initCrisp } from '../../../middleware/check-auth.js'
|
import { initCrisp } from '../../../middleware/check-auth.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -62,6 +64,13 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
authStore
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
form: new Form({
|
form: new Form({
|
||||||
name: '',
|
name: '',
|
||||||
|
@ -112,10 +121,10 @@ export default {
|
||||||
const { data: { token } } = await this.form.post('/api/login')
|
const { data: { token } } = await this.form.post('/api/login')
|
||||||
|
|
||||||
// Save the token.
|
// Save the token.
|
||||||
this.$store.dispatch('auth/saveToken', { token })
|
this.authStore.saveToken(token)
|
||||||
|
|
||||||
// Update the user.
|
// Update the user.
|
||||||
await this.$store.dispatch('auth/updateUser', { user: data })
|
await this.authStore.updateUser(data)
|
||||||
|
|
||||||
// Track event
|
// Track event
|
||||||
this.$logEvent('register', { source: this.form.hear_about_us })
|
this.$logEvent('register', { source: this.form.hear_about_us })
|
||||||
|
|
|
@ -24,18 +24,21 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import store from '~/store'
|
import { computed } from 'vue'
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
import { mapState, mapActions } from 'vuex'
|
import { useTemplatesStore } from '../../stores/templates'
|
||||||
|
import { useWorkingFormStore } from '../../stores/working_form'
|
||||||
|
import { useWorkspacesStore } from '../../stores/workspaces'
|
||||||
import QuickRegister from '../auth/components/QuickRegister.vue'
|
import QuickRegister from '../auth/components/QuickRegister.vue'
|
||||||
import initForm from '../../mixins/form_editor/initForm.js'
|
import initForm from '../../mixins/form_editor/initForm.js'
|
||||||
import SeoMeta from '../../mixins/seo-meta.js'
|
import SeoMeta from '../../mixins/seo-meta.js'
|
||||||
import CreateFormBaseModal from '../../components/pages/forms/create/CreateFormBaseModal.vue'
|
import CreateFormBaseModal from '../../components/pages/forms/create/CreateFormBaseModal.vue'
|
||||||
|
|
||||||
const loadTemplates = function () {
|
const loadTemplates = function () {
|
||||||
store.commit('open/templates/startLoading')
|
const templatesStore = useTemplatesStore()
|
||||||
store.dispatch('open/templates/loadIfEmpty').then(() => {
|
templatesStore.startLoading()
|
||||||
store.commit('open/templates/stopLoading')
|
templatesStore.loadIfEmpty().then(() => {
|
||||||
|
templatesStore.stopLoading()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,13 +48,25 @@ export default {
|
||||||
QuickRegister, CreateFormBaseModal
|
QuickRegister, CreateFormBaseModal
|
||||||
},
|
},
|
||||||
mixins: [initForm, SeoMeta],
|
mixins: [initForm, SeoMeta],
|
||||||
|
middleware: 'guest',
|
||||||
|
|
||||||
beforeRouteEnter (to, from, next) {
|
beforeRouteEnter (to, from, next) {
|
||||||
loadTemplates()
|
loadTemplates()
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
|
|
||||||
middleware: 'guest',
|
setup () {
|
||||||
|
const templatesStore = useTemplatesStore()
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
const workspacesStore = useWorkspacesStore()
|
||||||
|
return {
|
||||||
|
templatesStore,
|
||||||
|
workingFormStore,
|
||||||
|
workspacesStore,
|
||||||
|
workspaces : computed(() => workspacesStore.content),
|
||||||
|
workspacesLoading : computed(() => workspacesStore.loading)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -66,21 +81,17 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
|
||||||
workspaces: state => state['open/workspaces'].content,
|
|
||||||
workspacesLoading: state => state['open/workspaces'].loading
|
|
||||||
}),
|
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
workspace () {
|
workspace () {
|
||||||
return this.$store.getters['open/workspaces/getCurrent']()
|
return this.workspacesStore.getCurrent()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -100,12 +111,12 @@ export default {
|
||||||
is_enterprise: false,
|
is_enterprise: false,
|
||||||
is_pro: false
|
is_pro: false
|
||||||
}
|
}
|
||||||
this.$store.commit('open/workspaces/set', [guestWorkspace])
|
this.workspacesStore.set([guestWorkspace])
|
||||||
this.$store.commit('open/workspaces/setCurrentId', guestWorkspace.id)
|
this.workspacesStore.setCurrentId(guestWorkspace.id)
|
||||||
|
|
||||||
this.initForm()
|
this.initForm()
|
||||||
if (this.$route.query.template !== undefined && this.$route.query.template) {
|
if (this.$route.query.template !== undefined && this.$route.query.template) {
|
||||||
const template = this.$store.getters['open/templates/getBySlug'](this.$route.query.template)
|
const template = this.templatesStore.getBySlug(this.$route.query.template)
|
||||||
if (template && template.structure) {
|
if (template && template.structure) {
|
||||||
this.form = new Form({ ...this.form.data(), ...template.structure })
|
this.form = new Form({ ...this.form.data(), ...template.structure })
|
||||||
}
|
}
|
||||||
|
@ -121,16 +132,13 @@ export default {
|
||||||
unmounted () {},
|
unmounted () {},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions({
|
|
||||||
loadWorkspaces: 'open/workspaces/load'
|
|
||||||
}),
|
|
||||||
openRegister () {
|
openRegister () {
|
||||||
this.registerModal = true
|
this.registerModal = true
|
||||||
},
|
},
|
||||||
afterLogin () {
|
afterLogin () {
|
||||||
this.registerModal = false
|
this.registerModal = false
|
||||||
this.isGuest = false
|
this.isGuest = false
|
||||||
this.loadWorkspaces()
|
this.workspacesStore.load()
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.$refs.editor) {
|
if (this.$refs.editor) {
|
||||||
this.$refs.editor.saveFormCreate()
|
this.$refs.editor.saveFormCreate()
|
||||||
|
|
|
@ -19,17 +19,21 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import store from '~/store'
|
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
import { mapState, mapActions } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../stores/auth'
|
||||||
|
import { useTemplatesStore } from '../../stores/templates'
|
||||||
|
import { useWorkingFormStore } from '../../stores/working_form'
|
||||||
|
import { useWorkspacesStore } from '../../stores/workspaces'
|
||||||
import initForm from '../../mixins/form_editor/initForm.js'
|
import initForm from '../../mixins/form_editor/initForm.js'
|
||||||
import SeoMeta from '../../mixins/seo-meta.js'
|
import SeoMeta from '../../mixins/seo-meta.js'
|
||||||
import CreateFormBaseModal from '../../components/pages/forms/create/CreateFormBaseModal.vue'
|
import CreateFormBaseModal from '../../components/pages/forms/create/CreateFormBaseModal.vue'
|
||||||
|
|
||||||
const loadTemplates = function () {
|
const loadTemplates = function () {
|
||||||
store.commit('open/templates/startLoading')
|
const templatesStore = useTemplatesStore()
|
||||||
store.dispatch('open/templates/loadIfEmpty').then(() => {
|
templatesStore.startLoading()
|
||||||
store.commit('open/templates/stopLoading')
|
templatesStore.loadIfEmpty().then(() => {
|
||||||
|
templatesStore.stopLoading()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +42,7 @@ export default {
|
||||||
components: { CreateFormBaseModal },
|
components: { CreateFormBaseModal },
|
||||||
|
|
||||||
mixins: [initForm, SeoMeta],
|
mixins: [initForm, SeoMeta],
|
||||||
|
middleware: 'auth',
|
||||||
|
|
||||||
beforeRouteEnter (to, from, next) {
|
beforeRouteEnter (to, from, next) {
|
||||||
loadTemplates()
|
loadTemplates()
|
||||||
|
@ -54,7 +59,20 @@ export default {
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
|
|
||||||
middleware: 'auth',
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const templatesStore = useTemplatesStore()
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
const workspacesStore = useWorkspacesStore()
|
||||||
|
return {
|
||||||
|
templatesStore,
|
||||||
|
workingFormStore,
|
||||||
|
workspacesStore,
|
||||||
|
user: computed(() => authStore.user),
|
||||||
|
workspaces : computed(() => workspacesStore.content),
|
||||||
|
workspacesLoading : computed(() => workspacesStore.loading)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -68,22 +86,17 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
|
||||||
workspaces: state => state['open/workspaces'].content,
|
|
||||||
workspacesLoading: state => state['open/workspaces'].loading,
|
|
||||||
user: state => state.auth.user
|
|
||||||
}),
|
|
||||||
form: {
|
form: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
workspace () {
|
workspace () {
|
||||||
return this.$store.getters['open/workspaces/getCurrent']()
|
return this.workspacesStore.getCurrent()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -108,7 +121,7 @@ export default {
|
||||||
this.initForm()
|
this.initForm()
|
||||||
this.formInitialHash = this.hashString(JSON.stringify(this.form.data()))
|
this.formInitialHash = this.hashString(JSON.stringify(this.form.data()))
|
||||||
if (this.$route.query.template !== undefined && this.$route.query.template) {
|
if (this.$route.query.template !== undefined && this.$route.query.template) {
|
||||||
const template = this.$store.getters['open/templates/getBySlug'](this.$route.query.template)
|
const template = this.templatesStore.getBySlug(this.$route.query.template)
|
||||||
if (template && template.structure) {
|
if (template && template.structure) {
|
||||||
this.form = new Form({ ...this.form.data(), ...template.structure })
|
this.form = new Form({ ...this.form.data(), ...template.structure })
|
||||||
}
|
}
|
||||||
|
@ -117,7 +130,7 @@ export default {
|
||||||
this.showInitialFormModal = true
|
this.showInitialFormModal = true
|
||||||
}
|
}
|
||||||
this.closeAlert()
|
this.closeAlert()
|
||||||
this.loadWorkspaces()
|
this.workspacesStore.loadIfEmpty()
|
||||||
|
|
||||||
this.stateReady = this.user !== null
|
this.stateReady = this.user !== null
|
||||||
},
|
},
|
||||||
|
@ -126,9 +139,6 @@ export default {
|
||||||
unmounted () {},
|
unmounted () {},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions({
|
|
||||||
loadWorkspaces: 'open/workspaces/loadIfEmpty'
|
|
||||||
}),
|
|
||||||
formGenerated (form) {
|
formGenerated (form) {
|
||||||
this.form = new Form({ ...this.form.data(), ...form })
|
this.form = new Form({ ...this.form.data(), ...form })
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,17 +14,20 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios'
|
import { computed } from 'vue'
|
||||||
import store from '~/store'
|
|
||||||
import Breadcrumb from '../../components/common/Breadcrumb.vue'
|
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
import { mapState } from 'vuex'
|
import { useFormsStore } from '../../stores/forms'
|
||||||
|
import { useWorkingFormStore } from '../../stores/working_form'
|
||||||
|
import { useWorkspacesStore } from '../../stores/workspaces'
|
||||||
|
import Breadcrumb from '../../components/common/Breadcrumb.vue'
|
||||||
import SeoMeta from '../../mixins/seo-meta.js'
|
import SeoMeta from '../../mixins/seo-meta.js'
|
||||||
|
|
||||||
const loadForms = function () {
|
const loadForms = function () {
|
||||||
store.commit('open/forms/startLoading')
|
const formsStore = useFormsStore()
|
||||||
store.dispatch('open/workspaces/loadIfEmpty').then(() => {
|
const workspacesStore = useWorkspacesStore()
|
||||||
store.dispatch('open/forms/load', store.state['open/workspaces'].currentId)
|
formsStore.startLoading()
|
||||||
|
workspacesStore.loadIfEmpty().then(() => {
|
||||||
|
formsStore.load(workspacesStore.currentId)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,12 +35,15 @@ export default {
|
||||||
name: 'EditForm',
|
name: 'EditForm',
|
||||||
components: { Breadcrumb },
|
components: { Breadcrumb },
|
||||||
mixins: [SeoMeta],
|
mixins: [SeoMeta],
|
||||||
|
middleware: 'auth',
|
||||||
|
|
||||||
beforeRouteEnter (to, from, next) {
|
beforeRouteEnter (to, from, next) {
|
||||||
if (!store.getters['open/forms/getBySlug'](to.params.slug)) {
|
const formsStore = useFormsStore()
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
if (!formsStore.getBySlug(to.params.slug)) {
|
||||||
loadForms()
|
loadForms()
|
||||||
}
|
}
|
||||||
store.commit('open/working_form/set', null) // Reset old working form
|
workingFormStore.set(null) // Reset old working form
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -51,7 +57,17 @@ export default {
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
|
|
||||||
middleware: 'auth',
|
setup () {
|
||||||
|
const formsStore = useFormsStore()
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
const workspacesStore = useWorkspacesStore()
|
||||||
|
return {
|
||||||
|
formsStore,
|
||||||
|
workingFormStore,
|
||||||
|
workspacesStore,
|
||||||
|
formsLoading : computed(() => formsStore.loading)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -62,20 +78,17 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
|
||||||
formsLoading: state => state['open/forms'].loading
|
|
||||||
}),
|
|
||||||
updatedForm: {
|
updatedForm: {
|
||||||
get () {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
/* We add a setter */
|
/* We add a setter */
|
||||||
set (value) {
|
set (value) {
|
||||||
this.$store.commit('open/working_form/set', value)
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
form () {
|
form () {
|
||||||
return this.$store.getters['open/forms/getBySlug'](this.$route.params.slug)
|
return this.formsStore.getBySlug(this.$route.params.slug)
|
||||||
},
|
},
|
||||||
pageLoaded () {
|
pageLoaded () {
|
||||||
return !this.loading && this.updatedForm !== null
|
return !this.loading && this.updatedForm !== null
|
||||||
|
|
|
@ -50,8 +50,9 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import store from '~/store'
|
import { computed } from 'vue'
|
||||||
import { mapState } from 'vuex'
|
import { useFormsStore } from '../../stores/forms'
|
||||||
|
import { useRecordsStore } from '../../stores/records'
|
||||||
import OpenCompleteForm from '../../components/open/forms/OpenCompleteForm.vue'
|
import OpenCompleteForm from '../../components/open/forms/OpenCompleteForm.vue'
|
||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
import sha256 from 'js-sha256'
|
import sha256 from 'js-sha256'
|
||||||
|
@ -93,11 +94,12 @@ function handleTransparentMode (form) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadForm (slug) {
|
function loadForm (slug) {
|
||||||
if (store.state['open/forms'].loading) return
|
const formsStore = useFormsStore()
|
||||||
store.commit('open/forms/startLoading')
|
if (formsStore.loading) return
|
||||||
|
formsStore.startLoading()
|
||||||
return axios.get('/api/forms/' + slug).then((response) => {
|
return axios.get('/api/forms/' + slug).then((response) => {
|
||||||
const form = response.data
|
const form = response.data
|
||||||
store.commit('open/forms/set', [response.data])
|
formsStore.set([response.data])
|
||||||
|
|
||||||
// Custom code injection
|
// Custom code injection
|
||||||
if (form.custom_code) {
|
if (form.custom_code) {
|
||||||
|
@ -108,9 +110,9 @@ function loadForm (slug) {
|
||||||
handleDarkMode(form)
|
handleDarkMode(form)
|
||||||
handleTransparentMode(form)
|
handleTransparentMode(form)
|
||||||
|
|
||||||
store.commit('open/forms/stopLoading')
|
formsStore.stopLoading()
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
store.commit('open/forms/stopLoading')
|
formsStore.stopLoading()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +134,17 @@ export default {
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const formsStore = useFormsStore()
|
||||||
|
const recordsStore = useRecordsStore()
|
||||||
|
return {
|
||||||
|
formsStore,
|
||||||
|
forms : computed(() => formsStore.content),
|
||||||
|
formLoading : computed(() => formsStore.loading),
|
||||||
|
recordLoading : computed(() => recordsStore.loading)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
submitted: false
|
submitted: false
|
||||||
|
@ -166,16 +179,11 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
|
||||||
forms: state => state['open/forms'].content,
|
|
||||||
formLoading: state => state['open/forms'].loading,
|
|
||||||
recordLoading: state => state['open/records'].loading
|
|
||||||
}),
|
|
||||||
formSlug () {
|
formSlug () {
|
||||||
return this.$route.params.slug
|
return this.$route.params.slug
|
||||||
},
|
},
|
||||||
form () {
|
form () {
|
||||||
return this.$store.getters['open/forms/getBySlug'](this.formSlug)
|
return this.formsStore.getBySlug(this.formSlug)
|
||||||
},
|
},
|
||||||
isIframe () {
|
isIframe () {
|
||||||
return window.location !== window.parent.location || window.frameElement
|
return window.location !== window.parent.location || window.frameElement
|
||||||
|
|
|
@ -116,10 +116,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios'
|
import { computed } from 'vue'
|
||||||
import store from '~/store'
|
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
import {mapGetters, mapState} from 'vuex'
|
import { useAuthStore } from '../../../stores/auth'
|
||||||
|
import { useFormsStore } from '../../../stores/forms'
|
||||||
|
import { useWorkingFormStore } from '../../../stores/working_form'
|
||||||
|
import { useWorkspacesStore } from '../../../stores/workspaces'
|
||||||
import ProTag from '../../../components/common/ProTag.vue'
|
import ProTag from '../../../components/common/ProTag.vue'
|
||||||
import VButton from "../../../components/common/Button.vue";
|
import VButton from "../../../components/common/Button.vue";
|
||||||
import ExtraMenu from '../../../components/pages/forms/show/ExtraMenu.vue'
|
import ExtraMenu from '../../../components/pages/forms/show/ExtraMenu.vue'
|
||||||
|
@ -127,9 +129,11 @@ import SeoMeta from '../../../mixins/seo-meta.js'
|
||||||
import FormCleanings from '../../../components/pages/forms/show/FormCleanings.vue'
|
import FormCleanings from '../../../components/pages/forms/show/FormCleanings.vue'
|
||||||
|
|
||||||
const loadForms = function () {
|
const loadForms = function () {
|
||||||
store.commit('open/forms/startLoading')
|
const formsStore = useFormsStore()
|
||||||
store.dispatch('open/workspaces/loadIfEmpty').then(() => {
|
const workspacesStore = useWorkspacesStore()
|
||||||
store.dispatch('open/forms/loadIfEmpty', store.state['open/workspaces'].currentId)
|
formsStore.startLoading()
|
||||||
|
workspacesStore.loadIfEmpty().then(() => {
|
||||||
|
formsStore.loadIfEmpty(workspacesStore.currentId)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +158,21 @@ export default {
|
||||||
},
|
},
|
||||||
middleware: 'auth',
|
middleware: 'auth',
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const formsStore = useFormsStore()
|
||||||
|
const workingFormStore = useWorkingFormStore()
|
||||||
|
const workspacesStore = useWorkspacesStore()
|
||||||
|
return {
|
||||||
|
formsStore,
|
||||||
|
workingFormStore,
|
||||||
|
workspacesStore,
|
||||||
|
user : computed(() => authStore.user),
|
||||||
|
formsLoading : computed(() => formsStore.loading),
|
||||||
|
workspacesLoading : computed(() => workspacesStore.loading)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
metaTitle: 'Home',
|
metaTitle: 'Home',
|
||||||
|
@ -175,27 +194,21 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
...mapState({
|
|
||||||
formsLoading: state => state['open/forms'].loading,
|
|
||||||
workspacesLoading: state => state['open/workspaces'].loading
|
|
||||||
}),
|
|
||||||
workingForm: {
|
workingForm: {
|
||||||
get() {
|
get () {
|
||||||
return this.$store.state['open/working_form'].content
|
return this.workingFormStore.content
|
||||||
},
|
},
|
||||||
set(value) {
|
/* We add a setter */
|
||||||
this.$store.commit('open/working_form/set', value)
|
set (value) {
|
||||||
|
this.workingFormStore.set(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
workspace() {
|
workspace() {
|
||||||
if (!this.form) return null
|
if (!this.form) return null
|
||||||
return this.$store.getters['open/workspaces/getById'](this.form.workspace_id)
|
return this.workspacesStore.getById(this.form.workspace_id)
|
||||||
},
|
},
|
||||||
form() {
|
form() {
|
||||||
return this.$store.getters['open/forms/getBySlug'](this.$route.params.slug)
|
return this.formsStore.getBySlug(this.$route.params.slug)
|
||||||
},
|
},
|
||||||
formEndpoint: () => '/api/open/forms/{id}',
|
formEndpoint: () => '/api/open/forms/{id}',
|
||||||
loading() {
|
loading() {
|
||||||
|
|
|
@ -104,8 +104,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import store from '~/store'
|
import { computed } from 'vue'
|
||||||
import { mapGetters, mapState } from 'vuex'
|
import { useAuthStore } from '../stores/auth';
|
||||||
|
import { useFormsStore } from '../stores/forms';
|
||||||
|
import { useWorkspacesStore } from '../stores/workspaces';
|
||||||
import Fuse from 'fuse.js'
|
import Fuse from 'fuse.js'
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
import TextInput from '../components/forms/TextInput.vue'
|
import TextInput from '../components/forms/TextInput.vue'
|
||||||
|
@ -113,9 +115,11 @@ import OpenFormFooter from '../components/pages/OpenFormFooter.vue'
|
||||||
import ExtraMenu from '../components/pages/forms/show/ExtraMenu.vue'
|
import ExtraMenu from '../components/pages/forms/show/ExtraMenu.vue'
|
||||||
|
|
||||||
const loadForms = function () {
|
const loadForms = function () {
|
||||||
store.commit('open/forms/startLoading')
|
const formsStore = useFormsStore()
|
||||||
store.dispatch('open/workspaces/loadIfEmpty').then(() => {
|
const workspacesStore = useWorkspacesStore()
|
||||||
store.dispatch('open/forms/loadIfEmpty', store.state['open/workspaces'].currentId)
|
formsStore.startLoading()
|
||||||
|
workspacesStore.loadIfEmpty().then(() => {
|
||||||
|
formsStore.loadIfEmpty(workspacesStore.currentId)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +137,19 @@ export default {
|
||||||
metaDescription: { type: String, default: 'All of your OpnForm are here. Create new forms, or update your existing one!' }
|
metaDescription: { type: String, default: 'All of your OpnForm are here. Create new forms, or update your existing one!' }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const formsStore = useFormsStore()
|
||||||
|
const workspacesStore = useWorkspacesStore()
|
||||||
|
return {
|
||||||
|
formsStore,
|
||||||
|
workspacesStore,
|
||||||
|
user : computed(() => authStore.user),
|
||||||
|
forms : computed(() => formsStore.content),
|
||||||
|
formsLoading : computed(() => formsStore.loading)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
showEditFormModal: false,
|
showEditFormModal: false,
|
||||||
|
@ -165,19 +182,12 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
...mapState({
|
|
||||||
forms: state => state['open/forms'].content,
|
|
||||||
formsLoading: state => state['open/forms'].loading
|
|
||||||
}),
|
|
||||||
isFilteringForms () {
|
isFilteringForms () {
|
||||||
return (this.searchForm.search !== '' && this.searchForm.search !== null) || this.selectedTags.length > 0
|
return (this.searchForm.search !== '' && this.searchForm.search !== null) || this.selectedTags.length > 0
|
||||||
},
|
},
|
||||||
enrichedForms () {
|
enrichedForms () {
|
||||||
let enrichedForms = this.forms.map((form) => {
|
let enrichedForms = this.forms.map((form) => {
|
||||||
form.workspace = this.$store.getters['open/workspaces/getById'](form.workspace_id)
|
form.workspace = this.workspacesStore.getById(form.workspace_id)
|
||||||
return form
|
return form
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -206,7 +216,7 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
allTags () {
|
allTags () {
|
||||||
return this.$store.getters['open/forms/getAllTags']
|
return this.formsStore.getAllTags
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,14 +236,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {mapGetters} from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../stores/auth';
|
||||||
import OpenFormFooter from '../components/pages/OpenFormFooter.vue'
|
import OpenFormFooter from '../components/pages/OpenFormFooter.vue'
|
||||||
import PricingTable from '../components/pages/pricing/PricingTable.vue'
|
import PricingTable from '../components/pages/pricing/PricingTable.vue'
|
||||||
import SeoMeta from '../mixins/seo-meta.js'
|
import SeoMeta from '../mixins/seo-meta.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {OpenFormFooter, PricingTable},
|
components: {OpenFormFooter, PricingTable},
|
||||||
|
|
||||||
mixins: [SeoMeta],
|
mixins: [SeoMeta],
|
||||||
layout: 'default',
|
layout: 'default',
|
||||||
|
|
||||||
|
@ -257,20 +257,23 @@ export default {
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
user : computed(() => authStore.user),
|
||||||
|
authenticated : computed(() => authStore.check)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
metaTitle: 'Pricing',
|
metaTitle: 'Pricing',
|
||||||
metaDescription: 'All of our core features are free, and there is no quantity limit. You can also created more advanced and customized forms with OpnForms Pro.',
|
metaDescription: 'All of our core features are free, and there is no quantity limit. You can also created more advanced and customized forms with OpnForms Pro.',
|
||||||
}),
|
}),
|
||||||
|
|
||||||
mounted() {
|
mounted() {},
|
||||||
},
|
|
||||||
|
computed: {},
|
||||||
|
|
||||||
computed: {
|
|
||||||
...mapGetters({
|
|
||||||
authenticated: 'auth/check',
|
|
||||||
user: 'auth/user'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
contactUs() {
|
contactUs() {
|
||||||
window.$crisp.push(['do', 'chat:show'])
|
window.$crisp.push(['do', 'chat:show'])
|
||||||
|
|
|
@ -18,12 +18,20 @@
|
||||||
<script>
|
<script>
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import { useAuthStore } from '../../stores/auth'
|
||||||
import SeoMeta from '../../mixins/seo-meta.js'
|
import SeoMeta from '../../mixins/seo-meta.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
scrollToTop: false,
|
scrollToTop: false,
|
||||||
mixins: [SeoMeta],
|
mixins: [SeoMeta],
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
authStore
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
metaTitle: 'Account',
|
metaTitle: 'Account',
|
||||||
form: new Form({
|
form: new Form({
|
||||||
|
@ -39,7 +47,7 @@ export default {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
this.alertSuccess(response.data.message)
|
this.alertSuccess(response.data.message)
|
||||||
// Log out the user.
|
// Log out the user.
|
||||||
await this.$store.dispatch('auth/logout')
|
await this.authStore.logout()
|
||||||
|
|
||||||
// Redirect to login.
|
// Redirect to login.
|
||||||
this.$router.push({ name: 'login' })
|
this.$router.push({ name: 'login' })
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
<script>
|
<script>
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import { useAuthStore } from '../../stores/auth'
|
||||||
|
import { useWorkspacesStore } from '../../stores/workspaces'
|
||||||
import SeoMeta from '../../mixins/seo-meta.js'
|
import SeoMeta from '../../mixins/seo-meta.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -45,6 +47,15 @@ export default {
|
||||||
scrollToTop: false,
|
scrollToTop: false,
|
||||||
mixins: [SeoMeta],
|
mixins: [SeoMeta],
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const workspacesStore = useWorkspacesStore()
|
||||||
|
return {
|
||||||
|
authStore,
|
||||||
|
workspacesStore
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
metaTitle: 'Admin',
|
metaTitle: 'Admin',
|
||||||
form: new Form({
|
form: new Form({
|
||||||
|
@ -56,21 +67,18 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
async impersonate () {
|
async impersonate () {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
this.$store.commit('auth/startImpersonating')
|
this.authStore.startImpersonating()
|
||||||
axios.get('/api/admin/impersonate/' + encodeURI(this.form.identifier)).then(async (response) => {
|
axios.get('/api/admin/impersonate/' + encodeURI(this.form.identifier)).then(async (response) => {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
|
|
||||||
// Save the token.
|
// Save the token.
|
||||||
this.$store.dispatch('auth/saveToken', {
|
this.authStore.saveToken(response.data.token, false)
|
||||||
token: response.data.token,
|
|
||||||
remember: false
|
|
||||||
})
|
|
||||||
|
|
||||||
// Fetch the user.
|
// Fetch the user.
|
||||||
await this.$store.dispatch('auth/fetchUser')
|
await this.authStore.fetchUser()
|
||||||
|
|
||||||
// Redirect to the dashboard.
|
// Redirect to the dashboard.
|
||||||
this.$store.commit('open/workspaces/set', [])
|
this.workspacesStore.set([])
|
||||||
this.$router.push({ name: 'home' })
|
this.$router.push({ name: 'home' })
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
this.alertError(error.response.data.message)
|
this.alertError(error.response.data.message)
|
||||||
|
|
|
@ -21,9 +21,10 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../stores/auth'
|
||||||
import VButton from '../../components/common/Button.vue'
|
import VButton from '../../components/common/Button.vue'
|
||||||
import SeoMeta from '../../mixins/seo-meta.js'
|
import SeoMeta from '../../mixins/seo-meta.js'
|
||||||
import { mapGetters } from 'vuex'
|
|
||||||
import AppSumoBilling from '../../components/vendor/appsumo/AppSumoBilling.vue'
|
import AppSumoBilling from '../../components/vendor/appsumo/AppSumoBilling.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -31,6 +32,13 @@ export default {
|
||||||
mixins: [SeoMeta],
|
mixins: [SeoMeta],
|
||||||
scrollToTop: false,
|
scrollToTop: false,
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
user : computed(() => authStore.user)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
metaTitle: 'Billing',
|
metaTitle: 'Billing',
|
||||||
billingLoading: false
|
billingLoading: false
|
||||||
|
@ -50,10 +58,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {}
|
||||||
...mapGetters({
|
|
||||||
user: 'auth/user'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -38,20 +38,25 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../stores/auth'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
middleware: 'auth',
|
middleware: 'auth',
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
user : computed(() => authStore.user)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
tabsList () {
|
tabsList () {
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,13 +24,22 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
import { mapGetters } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../stores/auth'
|
||||||
import SeoMeta from '../../mixins/seo-meta.js'
|
import SeoMeta from '../../mixins/seo-meta.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [SeoMeta],
|
mixins: [SeoMeta],
|
||||||
scrollToTop: false,
|
scrollToTop: false,
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
authStore,
|
||||||
|
user : computed(() => authStore.user)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
metaTitle: 'Profile',
|
metaTitle: 'Profile',
|
||||||
form: new Form({
|
form: new Form({
|
||||||
|
@ -39,10 +48,6 @@ export default {
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
|
|
||||||
computed: mapGetters({
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
|
|
||||||
created () {
|
created () {
|
||||||
// Fill the form with user data.
|
// Fill the form with user data.
|
||||||
this.form.keys().forEach(key => {
|
this.form.keys().forEach(key => {
|
||||||
|
@ -54,7 +59,7 @@ export default {
|
||||||
async update () {
|
async update () {
|
||||||
const { data } = await this.form.patch('/api/settings/profile')
|
const { data } = await this.form.patch('/api/settings/profile')
|
||||||
|
|
||||||
this.$store.dispatch('auth/updateUser', { user: data })
|
this.authStore.updateUser(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,8 +73,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { computed } from 'vue'
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
import {mapActions, mapState} from 'vuex'
|
import { useFormsStore } from '../../stores/forms'
|
||||||
|
import { useWorkspacesStore } from '../../stores/workspaces'
|
||||||
import SeoMeta from '../../mixins/seo-meta.js'
|
import SeoMeta from '../../mixins/seo-meta.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -82,6 +84,17 @@ export default {
|
||||||
scrollToTop: false,
|
scrollToTop: false,
|
||||||
mixins: [SeoMeta],
|
mixins: [SeoMeta],
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const formsStore = useFormsStore()
|
||||||
|
const workspacesStore = useWorkspacesStore()
|
||||||
|
return {
|
||||||
|
formsStore,
|
||||||
|
workspacesStore,
|
||||||
|
workspaces: computed(() => workspacesStore.content),
|
||||||
|
loading: computed(() => workspacesStore.loading)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
metaTitle: 'Workspaces',
|
metaTitle: 'Workspaces',
|
||||||
form: new Form({
|
form: new Form({
|
||||||
|
@ -92,28 +105,20 @@ export default {
|
||||||
}),
|
}),
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.loadWorkspaces()
|
this.workspacesStore.loadIfEmpty()
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {},
|
||||||
...mapState({
|
|
||||||
workspaces: state => state['open/workspaces'].content,
|
|
||||||
loading: state => state['open/workspaces'].loading
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions({
|
|
||||||
loadWorkspaces: 'open/workspaces/loadIfEmpty'
|
|
||||||
}),
|
|
||||||
switchWorkspace(workspace) {
|
switchWorkspace(workspace) {
|
||||||
this.$store.commit('open/workspaces/setCurrentId', workspace.id)
|
this.workspacesStore.setCurrentId(workspace.id)
|
||||||
this.$router.push({name: 'home'})
|
this.$router.push({name: 'home'})
|
||||||
this.$store.dispatch('open/forms/load', workspace.id)
|
this.formsStore.load(workspace.id)
|
||||||
},
|
},
|
||||||
deleteWorkspace(workspace) {
|
deleteWorkspace(workspace) {
|
||||||
this.alertConfirm('Do you really want to delete this workspace? All forms created in this workspace will be removed.', () => {
|
this.alertConfirm('Do you really want to delete this workspace? All forms created in this workspace will be removed.', () => {
|
||||||
this.$store.dispatch('open/workspaces/delete', workspace.id).then(() => {
|
this.workspacesStore.delete(workspace.id).then(() => {
|
||||||
this.alertSuccess('Workspace successfully removed.')
|
this.alertSuccess('Workspace successfully removed.')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -129,7 +134,7 @@ export default {
|
||||||
},
|
},
|
||||||
async createWorkspace() {
|
async createWorkspace() {
|
||||||
const {data} = await this.form.post('/api/open/workspaces/create')
|
const {data} = await this.form.post('/api/open/workspaces/create')
|
||||||
this.$store.dispatch('open/workspaces/load')
|
this.workspacesStore.load()
|
||||||
this.workspaceModal = false
|
this.workspaceModal = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
<template />
|
<template />
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../stores/auth'
|
||||||
import SeoMeta from '../../mixins/seo-meta.js'
|
import SeoMeta from '../../mixins/seo-meta.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -10,6 +11,13 @@ export default {
|
||||||
middleware: 'auth',
|
middleware: 'auth',
|
||||||
mixins: [SeoMeta],
|
mixins: [SeoMeta],
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
authenticated : computed(() => authStore.check),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
metaTitle: 'Error',
|
metaTitle: 'Error',
|
||||||
}),
|
}),
|
||||||
|
@ -19,10 +27,6 @@ export default {
|
||||||
this.alertError('Unfortunately we could not confirm your subscription. Please try again and contact us if the issue persists.')
|
this.alertError('Unfortunately we could not confirm your subscription. Please try again and contact us if the issue persists.')
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {}
|
||||||
...mapGetters({
|
|
||||||
authenticated: 'auth/check'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../stores/auth'
|
||||||
import OpenFormFooter from '../../components/pages/OpenFormFooter.vue'
|
import OpenFormFooter from '../../components/pages/OpenFormFooter.vue'
|
||||||
import SeoMeta from '../../mixins/seo-meta.js'
|
import SeoMeta from '../../mixins/seo-meta.js'
|
||||||
|
|
||||||
|
@ -26,6 +27,15 @@ export default {
|
||||||
layout: 'default',
|
layout: 'default',
|
||||||
middleware: 'auth',
|
middleware: 'auth',
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
authStore,
|
||||||
|
authenticated : computed(() => authStore.check),
|
||||||
|
user : computed(() => authStore.user)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
metaTitle: 'Subscription Success',
|
metaTitle: 'Subscription Success',
|
||||||
interval: null
|
interval: null
|
||||||
|
@ -43,7 +53,7 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
async checkSubscription () {
|
async checkSubscription () {
|
||||||
// Fetch the user.
|
// Fetch the user.
|
||||||
await this.$store.dispatch('auth/fetchUser')
|
await this.authStore.fetchUser()
|
||||||
this.redirectIfSubscribed()
|
this.redirectIfSubscribed()
|
||||||
},
|
},
|
||||||
redirectIfSubscribed () {
|
redirectIfSubscribed () {
|
||||||
|
@ -63,11 +73,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {}
|
||||||
...mapGetters({
|
|
||||||
authenticated: 'auth/check',
|
|
||||||
user: 'auth/user'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -93,19 +93,21 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import store from '~/store'
|
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
import Fuse from 'fuse.js'
|
import Fuse from 'fuse.js'
|
||||||
import { mapGetters, mapState } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../stores/auth'
|
||||||
|
import { useTemplatesStore } from '../../stores/templates'
|
||||||
import SeoMeta from '../../mixins/seo-meta.js'
|
import SeoMeta from '../../mixins/seo-meta.js'
|
||||||
import OpenFormFooter from '../../components/pages/OpenFormFooter.vue'
|
import OpenFormFooter from '../../components/pages/OpenFormFooter.vue'
|
||||||
import Breadcrumb from '../../components/common/Breadcrumb.vue'
|
import Breadcrumb from '../../components/common/Breadcrumb.vue'
|
||||||
import SingleTemplate from '../../components/pages/templates/SingleTemplate.vue'
|
import SingleTemplate from '../../components/pages/templates/SingleTemplate.vue'
|
||||||
|
|
||||||
const loadTemplates = function () {
|
const loadTemplates = function () {
|
||||||
store.commit('open/templates/startLoading')
|
const templatesStore = useTemplatesStore()
|
||||||
store.dispatch('open/templates/loadIfEmpty').then(() => {
|
templatesStore.startLoading()
|
||||||
store.commit('open/templates/stopLoading')
|
templatesStore.loadIfEmpty().then(() => {
|
||||||
|
templatesStore.stopLoading()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +120,20 @@ export default {
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const templatesStore = useTemplatesStore()
|
||||||
|
return {
|
||||||
|
authStore,
|
||||||
|
authenticated : computed(() => authStore.check),
|
||||||
|
user : computed(() => authStore.user),
|
||||||
|
templates : computed(() => templatesStore.content),
|
||||||
|
templatesLoading : computed(() => templatesStore.loading),
|
||||||
|
industries : computed(() => templatesStore.industries),
|
||||||
|
types : computed(() => templatesStore.types)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
selectedType: 'all',
|
selectedType: 'all',
|
||||||
|
@ -130,16 +146,6 @@ export default {
|
||||||
mounted () {},
|
mounted () {},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
|
||||||
authenticated: 'auth/check',
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
...mapState({
|
|
||||||
templates: state => state['open/templates'].content,
|
|
||||||
templatesLoading: state => state['open/templates'].loading,
|
|
||||||
industries: state => state['open/templates'].industries,
|
|
||||||
types: state => state['open/templates'].types
|
|
||||||
}),
|
|
||||||
breadcrumbs () {
|
breadcrumbs () {
|
||||||
if (!this.industry) {
|
if (!this.industry) {
|
||||||
return [{ route: { name: 'templates' }, label: 'Templates' }]
|
return [{ route: { name: 'templates' }, label: 'Templates' }]
|
||||||
|
|
|
@ -196,9 +196,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import store from '~/store'
|
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
import { mapGetters, mapState } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../stores/auth'
|
||||||
|
import { useTemplatesStore } from '../../stores/templates'
|
||||||
import OpenFormFooter from '../../components/pages/OpenFormFooter.vue'
|
import OpenFormFooter from '../../components/pages/OpenFormFooter.vue'
|
||||||
import OpenCompleteForm from '../../components/open/forms/OpenCompleteForm.vue'
|
import OpenCompleteForm from '../../components/open/forms/OpenCompleteForm.vue'
|
||||||
import Breadcrumb from '../../components/common/Breadcrumb.vue'
|
import Breadcrumb from '../../components/common/Breadcrumb.vue'
|
||||||
|
@ -213,21 +214,32 @@ export default {
|
||||||
mixins: [SeoMeta],
|
mixins: [SeoMeta],
|
||||||
|
|
||||||
beforeRouteEnter (to, from, next) {
|
beforeRouteEnter (to, from, next) {
|
||||||
|
const templatesStore = useTemplatesStore()
|
||||||
if (to.params?.slug) {
|
if (to.params?.slug) {
|
||||||
store.dispatch('open/templates/loadTemplate', to.params?.slug)
|
templatesStore.loadTemplate(to.params?.slug)
|
||||||
store.dispatch('open/templates/loadTypesAndIndustries')
|
templatesStore.loadTypesAndIndustries()
|
||||||
}
|
}
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const templatesStore = useTemplatesStore()
|
||||||
|
return {
|
||||||
|
templatesStore,
|
||||||
|
authenticated : computed(() => authStore.check),
|
||||||
|
user : computed(() => authStore.user),
|
||||||
|
templatesLoading : computed(() => templatesStore.loading)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
showFormTemplateModal: false
|
showFormTemplateModal: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted () {
|
mounted () {},
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
cleanQuotes (str) {
|
cleanQuotes (str) {
|
||||||
|
@ -247,13 +259,6 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
|
||||||
authenticated: 'auth/check',
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
...mapState({
|
|
||||||
templatesLoading: state => state['open/templates'].loading
|
|
||||||
}),
|
|
||||||
breadcrumbs () {
|
breadcrumbs () {
|
||||||
if (!this.template) {
|
if (!this.template) {
|
||||||
return [{ route: { name: 'templates' }, label: 'Templates' }]
|
return [{ route: { name: 'templates' }, label: 'Templates' }]
|
||||||
|
@ -261,7 +266,7 @@ export default {
|
||||||
return [{ route: { name: 'templates' }, label: 'Templates' }, { label: this.template.name }]
|
return [{ route: { name: 'templates' }, label: 'Templates' }, { label: this.template.name }]
|
||||||
},
|
},
|
||||||
template () {
|
template () {
|
||||||
return this.$store.getters['open/templates/getBySlug'](this.$route.params.slug)
|
return this.templatesStore.getBySlug(this.$route.params.slug)
|
||||||
},
|
},
|
||||||
form () {
|
form () {
|
||||||
return this.template ? new Form(this.template.structure) : null
|
return this.template ? new Form(this.template.structure) : null
|
||||||
|
|
|
@ -93,19 +93,21 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import store from '~/store'
|
|
||||||
import Form from 'vform'
|
import Form from 'vform'
|
||||||
import Fuse from 'fuse.js'
|
import Fuse from 'fuse.js'
|
||||||
import { mapGetters, mapState } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../../stores/auth'
|
||||||
|
import { useTemplatesStore } from '../../stores/templates'
|
||||||
import SeoMeta from '../../mixins/seo-meta.js'
|
import SeoMeta from '../../mixins/seo-meta.js'
|
||||||
import OpenFormFooter from '../../components/pages/OpenFormFooter.vue'
|
import OpenFormFooter from '../../components/pages/OpenFormFooter.vue'
|
||||||
import Breadcrumb from '../../components/common/Breadcrumb.vue'
|
import Breadcrumb from '../../components/common/Breadcrumb.vue'
|
||||||
import SingleTemplate from '../../components/pages/templates/SingleTemplate.vue'
|
import SingleTemplate from '../../components/pages/templates/SingleTemplate.vue'
|
||||||
|
|
||||||
const loadTemplates = function () {
|
const loadTemplates = function () {
|
||||||
store.commit('open/templates/startLoading')
|
const templatesStore = useTemplatesStore()
|
||||||
store.dispatch('open/templates/loadIfEmpty').then(() => {
|
templatesStore.startLoading()
|
||||||
store.commit('open/templates/stopLoading')
|
templatesStore.loadIfEmpty().then(() => {
|
||||||
|
templatesStore.stopLoading()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +120,19 @@ export default {
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const templatesStore = useTemplatesStore()
|
||||||
|
return {
|
||||||
|
authenticated : computed(() => authStore.check),
|
||||||
|
user : computed(() => authStore.user),
|
||||||
|
templates : computed(() => templatesStore.content),
|
||||||
|
templatesLoading : computed(() => templatesStore.loading),
|
||||||
|
industries : computed(() => templatesStore.industries),
|
||||||
|
types : computed(() => templatesStore.types)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
selectedIndustry: 'all',
|
selectedIndustry: 'all',
|
||||||
|
@ -130,16 +145,6 @@ export default {
|
||||||
mounted () {},
|
mounted () {},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
|
||||||
authenticated: 'auth/check',
|
|
||||||
user: 'auth/user'
|
|
||||||
}),
|
|
||||||
...mapState({
|
|
||||||
templates: state => state['open/templates'].content,
|
|
||||||
templatesLoading: state => state['open/templates'].loading,
|
|
||||||
industries: state => state['open/templates'].industries,
|
|
||||||
types: state => state['open/templates'].types
|
|
||||||
}),
|
|
||||||
breadcrumbs () {
|
breadcrumbs () {
|
||||||
if (!this.type) {
|
if (!this.type) {
|
||||||
return [{ route: { name: 'templates' }, label: 'Templates' }]
|
return [{ route: { name: 'templates' }, label: 'Templates' }]
|
||||||
|
|
|
@ -181,7 +181,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex'
|
import { computed } from 'vue'
|
||||||
|
import { useAuthStore } from '../stores/auth'
|
||||||
import Features from '~/components/pages/welcome/Features.vue'
|
import Features from '~/components/pages/welcome/Features.vue'
|
||||||
import MoreFeatures from '~/components/pages/welcome/MoreFeatures.vue'
|
import MoreFeatures from '~/components/pages/welcome/MoreFeatures.vue'
|
||||||
import PricingTable from '../components/pages/pricing/PricingTable.vue'
|
import PricingTable from '../components/pages/pricing/PricingTable.vue'
|
||||||
|
@ -193,11 +194,16 @@ import SeoMeta from '../mixins/seo-meta.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { Testimonials, OpenFormFooter, Features, MoreFeatures, PricingTable, AiFeature, TemplatesSlider },
|
components: { Testimonials, OpenFormFooter, Features, MoreFeatures, PricingTable, AiFeature, TemplatesSlider },
|
||||||
|
|
||||||
mixins: [SeoMeta],
|
mixins: [SeoMeta],
|
||||||
|
|
||||||
layout: 'default',
|
layout: 'default',
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
return {
|
||||||
|
authenticated : computed(() => authStore.check)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
title: window.config.appName,
|
title: window.config.appName,
|
||||||
metaTitle: 'Create beautiful & open-source forms for free'
|
metaTitle: 'Create beautiful & open-source forms for free'
|
||||||
|
@ -215,9 +221,6 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
|
||||||
authenticated: 'auth/check'
|
|
||||||
}),
|
|
||||||
configLinks: () => window.config.links,
|
configLinks: () => window.config.links,
|
||||||
paidPlansEnabled () {
|
paidPlansEnabled () {
|
||||||
return window.config.paid_plans_enabled
|
return window.config.paid_plans_enabled
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import store from '~/store'
|
import { useAuthStore } from '../stores/auth';
|
||||||
import router from '~/router'
|
import router from '~/router'
|
||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
|
|
||||||
|
@ -17,16 +17,13 @@ function addPasswordToFormRequest (request) {
|
||||||
|
|
||||||
// Request interceptor
|
// Request interceptor
|
||||||
axios.interceptors.request.use(request => {
|
axios.interceptors.request.use(request => {
|
||||||
const token = store.getters['auth/token']
|
const authStore = useAuthStore()
|
||||||
|
const token = authStore.token
|
||||||
if (token) {
|
if (token) {
|
||||||
request.headers.common.Authorization = `Bearer ${token}`
|
request.headers.common.Authorization = `Bearer ${token}`
|
||||||
}
|
}
|
||||||
|
|
||||||
const locale = store.getters['lang/locale']
|
request.headers.common['Accept-Language'] = 'en-US'
|
||||||
if (locale) {
|
|
||||||
request.headers.common['Accept-Language'] = locale
|
|
||||||
}
|
|
||||||
|
|
||||||
// request.headers['X-Socket-Id'] = Echo.socketId()
|
// request.headers['X-Socket-Id'] = Echo.socketId()
|
||||||
|
|
||||||
request = addPasswordToFormRequest(request)
|
request = addPasswordToFormRequest(request)
|
||||||
|
@ -36,14 +33,14 @@ axios.interceptors.request.use(request => {
|
||||||
|
|
||||||
// Response interceptor
|
// Response interceptor
|
||||||
axios.interceptors.response.use(response => response, error => {
|
axios.interceptors.response.use(response => response, error => {
|
||||||
|
const authStore = useAuthStore()
|
||||||
const { status } = error.response
|
const { status } = error.response
|
||||||
if (status >= 500) {
|
if (status >= 500) {
|
||||||
console.log(status)
|
console.log(status)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status === 401 && store.getters['auth/check']) {
|
if (status === 401 && authStore.check) {
|
||||||
store.commit('auth/LOGOUT')
|
authStore.logout()
|
||||||
|
|
||||||
router.push({ name: 'login' })
|
router.push({ name: 'login' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import routes from './routes'
|
import routes from './routes'
|
||||||
import { createWebHistory, createRouter } from 'vue-router'
|
import { createWebHistory, createRouter } from 'vue-router'
|
||||||
import * as Sentry from '@sentry/vue'
|
import * as Sentry from '@sentry/vue'
|
||||||
import store from '../store'
|
import { useAppStore } from '../stores/app'
|
||||||
import { defineComponent, nextTick } from 'vue'
|
import { defineComponent, nextTick } from 'vue'
|
||||||
|
|
||||||
// The middleware for every page of the application.
|
// The middleware for every page of the application.
|
||||||
|
@ -45,6 +45,8 @@ async function getMatchedComponents (to) {
|
||||||
* @param {Function} next
|
* @param {Function} next
|
||||||
*/
|
*/
|
||||||
async function beforeEach (to, from, next) {
|
async function beforeEach (to, from, next) {
|
||||||
|
const appStore = useAppStore()
|
||||||
|
|
||||||
// Sentry tracking
|
// Sentry tracking
|
||||||
if (window.config.sentry_dsn) {
|
if (window.config.sentry_dsn) {
|
||||||
Sentry.configureScope((scope) => scope.setTransactionName(to?.name || 'Unknown route name'))
|
Sentry.configureScope((scope) => scope.setTransactionName(to?.name || 'Unknown route name'))
|
||||||
|
@ -75,7 +77,7 @@ async function beforeEach (to, from, next) {
|
||||||
|
|
||||||
// Start the loading bar.
|
// Start the loading bar.
|
||||||
if (components[components.length - 1].loading !== false) {
|
if (components[components.length - 1].loading !== false) {
|
||||||
nextTick(() => store.commit('app/loaderStart'))
|
nextTick(() => appStore.loaderStart())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the middleware for all the matched components.
|
// Get the middleware for all the matched components.
|
||||||
|
@ -86,11 +88,11 @@ async function beforeEach (to, from, next) {
|
||||||
// Set the application layout only if "next()" was called with no args.
|
// Set the application layout only if "next()" was called with no args.
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
if (components[0].layout) {
|
if (components[0].layout) {
|
||||||
store.commit('app/setLayout', components[0].layout)
|
appStore.setLayout(components[0].layout)
|
||||||
} else if (components[0].default && components[0].default.layout) {
|
} else if (components[0].default && components[0].default.layout) {
|
||||||
store.commit('app/setLayout', components[0].default.layout)
|
appStore.setLayout(components[0].default.layout)
|
||||||
} else {
|
} else {
|
||||||
store.commit('app/setLayout', null)
|
appStore.setLayout(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +108,8 @@ async function beforeEach (to, from, next) {
|
||||||
* @param {Function} next
|
* @param {Function} next
|
||||||
*/
|
*/
|
||||||
async function afterEach (to, from, next) {
|
async function afterEach (to, from, next) {
|
||||||
nextTick(() => store.commit('app/loaderFinish'))
|
const appStore = useAppStore()
|
||||||
|
nextTick(() => appStore.loaderFinish())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,13 +121,14 @@ async function afterEach (to, from, next) {
|
||||||
* @param {Function} next
|
* @param {Function} next
|
||||||
*/
|
*/
|
||||||
function callMiddleware (middleware, to, from, next) {
|
function callMiddleware (middleware, to, from, next) {
|
||||||
|
const appStore = useAppStore()
|
||||||
const stack = middleware.reverse()
|
const stack = middleware.reverse()
|
||||||
|
|
||||||
const _next = (...args) => {
|
const _next = (...args) => {
|
||||||
// Stop if "_next" was called with an argument or the stack is empty.
|
// Stop if "_next" was called with an argument or the stack is empty.
|
||||||
if (args.length > 0 || stack.length === 0) {
|
if (args.length > 0 || stack.length === 0) {
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
store.commit('app/loaderFinish')
|
appStore.loaderFinish()
|
||||||
}
|
}
|
||||||
|
|
||||||
return next(...args)
|
return next(...args)
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
import Vue from 'vue'
|
|
||||||
import Vuex from 'vuex'
|
|
||||||
|
|
||||||
Vue.use(Vuex)
|
|
||||||
|
|
||||||
// Load store modules dynamically.
|
|
||||||
const requireContext = import.meta.glob('./modules/**/*.js', {eager: true})
|
|
||||||
const modules = Object.keys(requireContext)
|
|
||||||
|
|
||||||
.map(file =>
|
|
||||||
[file.replace(/(^.\/)|(\.js$)/g, '').replace('modules/',''), requireContext[file]]
|
|
||||||
)
|
|
||||||
.reduce((modules, [name, module]) => {
|
|
||||||
if (module.namespaced === undefined) {
|
|
||||||
module = {...module, namespaced: true}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { ...modules, [name]: module }
|
|
||||||
}, {})
|
|
||||||
export default new Vuex.Store({
|
|
||||||
modules
|
|
||||||
})
|
|
|
@ -1,73 +0,0 @@
|
||||||
import { nextTick } from 'vue'
|
|
||||||
|
|
||||||
export const state = {
|
|
||||||
layout: 'default',
|
|
||||||
|
|
||||||
// App Loader
|
|
||||||
loader: {
|
|
||||||
percent: 0,
|
|
||||||
show: false,
|
|
||||||
canSuccess: true,
|
|
||||||
duration: 3000,
|
|
||||||
_timer: null,
|
|
||||||
_cut: null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const mutations = {
|
|
||||||
setLayout (state, layout) {
|
|
||||||
state.layout = layout ?? 'default'
|
|
||||||
},
|
|
||||||
loaderStart (state) {
|
|
||||||
state.loader.show = true
|
|
||||||
state.loader.canSuccess = true
|
|
||||||
if (state.loader._timer) {
|
|
||||||
clearInterval(state.loader._timer)
|
|
||||||
state.loader.percent = 0
|
|
||||||
}
|
|
||||||
state.loader._cut = 10000 / Math.floor(state.loader.duration)
|
|
||||||
},
|
|
||||||
loaderIncrease (state, num) {
|
|
||||||
state.loader.percent = state.loader.percent + Math.floor(num)
|
|
||||||
},
|
|
||||||
loaderDecrease (state, num) {
|
|
||||||
state.loader.percent = state.loader.percent - Math.floor(num)
|
|
||||||
},
|
|
||||||
loaderFinish (state) {
|
|
||||||
state.loader.percent = 100
|
|
||||||
mutations.loaderHide(state)
|
|
||||||
},
|
|
||||||
loaderSetTimer (state, timerVal) {
|
|
||||||
state._timer = timerVal
|
|
||||||
},
|
|
||||||
loaderPause (state) {
|
|
||||||
clearInterval(state.loader._timer)
|
|
||||||
},
|
|
||||||
loaderHide (state) {
|
|
||||||
clearInterval(state.loader._timer)
|
|
||||||
state.loader._timer = null
|
|
||||||
setTimeout(() => {
|
|
||||||
state.loader.show = false
|
|
||||||
nextTick(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
state.loader.percent = 0
|
|
||||||
}, 200)
|
|
||||||
})
|
|
||||||
}, 500)
|
|
||||||
},
|
|
||||||
loaderFail () {
|
|
||||||
state.loader.canSuccess = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const actions = {
|
|
||||||
loaderStart ({ commit, dispatch }) {
|
|
||||||
mutations.loaderStart()
|
|
||||||
mutations.loaderSetTimer(setInterval(() => {
|
|
||||||
mutations.loaderIncrease(state.loader._cut * Math.random())
|
|
||||||
if (state.loader.percent > 95) {
|
|
||||||
mutations.loaderFinish()
|
|
||||||
}
|
|
||||||
}, 100))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,104 +0,0 @@
|
||||||
import axios from 'axios'
|
|
||||||
import Cookies from 'js-cookie'
|
|
||||||
import * as types from '../mutation-types'
|
|
||||||
|
|
||||||
// state
|
|
||||||
export const state = {
|
|
||||||
user: null,
|
|
||||||
token: Cookies.get('token'),
|
|
||||||
|
|
||||||
// For admin impersonation
|
|
||||||
admin_token: Cookies.get('admin_token') ?? null
|
|
||||||
}
|
|
||||||
|
|
||||||
// getters
|
|
||||||
export const getters = {
|
|
||||||
user: state => state.user,
|
|
||||||
token: state => state.token,
|
|
||||||
check: state => state.user !== null,
|
|
||||||
isImpersonating: state => state.admin_token !== null
|
|
||||||
}
|
|
||||||
|
|
||||||
// mutations
|
|
||||||
export const mutations = {
|
|
||||||
[types.SAVE_TOKEN] (state, { token, remember }) {
|
|
||||||
state.token = token
|
|
||||||
Cookies.set('token', token, { expires: remember ? 365 : null })
|
|
||||||
},
|
|
||||||
|
|
||||||
[types.FETCH_USER_SUCCESS] (state, { user }) {
|
|
||||||
state.user = user
|
|
||||||
},
|
|
||||||
|
|
||||||
[types.FETCH_USER_FAILURE] (state) {
|
|
||||||
state.token = null
|
|
||||||
Cookies.remove('token')
|
|
||||||
},
|
|
||||||
|
|
||||||
[types.LOGOUT] (state) {
|
|
||||||
state.user = null
|
|
||||||
state.token = null
|
|
||||||
|
|
||||||
Cookies.remove('token')
|
|
||||||
},
|
|
||||||
|
|
||||||
[types.UPDATE_USER] (state, { user }) {
|
|
||||||
state.user = user
|
|
||||||
},
|
|
||||||
|
|
||||||
// Stores admin token temporarily for impersonation
|
|
||||||
startImpersonating (state) {
|
|
||||||
state.admin_token = state.token
|
|
||||||
Cookies.set('admin_token', state.token, { expires: 365 })
|
|
||||||
},
|
|
||||||
|
|
||||||
// Stores admin token temporarily for impersonation
|
|
||||||
stopImpersonating (state) {
|
|
||||||
state.token = state.admin_token
|
|
||||||
state.admin_token = null
|
|
||||||
Cookies.set('token', state.token, { expires: 365 })
|
|
||||||
Cookies.remove('admin_token')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions
|
|
||||||
export const actions = {
|
|
||||||
saveToken ({ commit, dispatch }, payload) {
|
|
||||||
commit(types.SAVE_TOKEN, payload)
|
|
||||||
},
|
|
||||||
|
|
||||||
async fetchUser ({ commit }) {
|
|
||||||
try {
|
|
||||||
const { data } = await axios.get('/api/user')
|
|
||||||
|
|
||||||
commit(types.FETCH_USER_SUCCESS, { user: data })
|
|
||||||
return data
|
|
||||||
} catch (e) {
|
|
||||||
commit(types.FETCH_USER_FAILURE)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
updateUser ({ commit }, payload) {
|
|
||||||
commit(types.UPDATE_USER, payload)
|
|
||||||
},
|
|
||||||
|
|
||||||
async logout ({ commit }) {
|
|
||||||
try {
|
|
||||||
await axios.post('/api/logout')
|
|
||||||
} catch (e) { }
|
|
||||||
|
|
||||||
commit(types.LOGOUT)
|
|
||||||
},
|
|
||||||
|
|
||||||
async fetchOauthUrl (ctx, { provider }) {
|
|
||||||
const { data } = await axios.post(`/api/oauth/${provider}`)
|
|
||||||
|
|
||||||
return data.url
|
|
||||||
},
|
|
||||||
|
|
||||||
// Reverse admin impersonation
|
|
||||||
stopImpersonating ({ commit, dispatch }, payload) {
|
|
||||||
commit('stopImpersonating')
|
|
||||||
return dispatch('fetchUser')
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
import Vue from 'vue'
|
|
||||||
|
|
||||||
export const namespaced = true
|
|
||||||
|
|
||||||
// state
|
|
||||||
export const state = {
|
|
||||||
content: []
|
|
||||||
}
|
|
||||||
|
|
||||||
// getters
|
|
||||||
export const getters = {
|
|
||||||
getById: (state) => (id) => {
|
|
||||||
if (state.content.length === 0) return null
|
|
||||||
return state.content.find(item => item.id === id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mutations
|
|
||||||
export const mutations = {
|
|
||||||
set (state, items) {
|
|
||||||
state.content = items
|
|
||||||
},
|
|
||||||
addOrUpdate (state, item) {
|
|
||||||
state.content = state.content.filter((val) => val.id !== item.id)
|
|
||||||
state.content.push(item)
|
|
||||||
},
|
|
||||||
remove (state, item) {
|
|
||||||
state.content = state.content.filter((val) => val.id !== item.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions
|
|
||||||
export const actions = {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
import Vue from 'vue'
|
|
||||||
|
|
||||||
export const namespaced = true
|
|
||||||
|
|
||||||
// state
|
|
||||||
export const state = {
|
|
||||||
content: null
|
|
||||||
}
|
|
||||||
|
|
||||||
// getters
|
|
||||||
export const getters = {
|
|
||||||
}
|
|
||||||
|
|
||||||
// mutations
|
|
||||||
export const mutations = {
|
|
||||||
set (state, error) {
|
|
||||||
state.content = error
|
|
||||||
},
|
|
||||||
clear (state) {
|
|
||||||
state.content = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions
|
|
||||||
export const actions = {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
import axios from 'axios'
|
|
||||||
|
|
||||||
export const formsEndpoint = '/api/open/workspaces/{workspaceId}/forms'
|
|
||||||
export const namespaced = true
|
|
||||||
export let currentPage = 1
|
|
||||||
|
|
||||||
// state
|
|
||||||
export const state = {
|
|
||||||
content: [],
|
|
||||||
loading: false
|
|
||||||
}
|
|
||||||
|
|
||||||
// getters
|
|
||||||
export const getters = {
|
|
||||||
getById: (state) => (id) => {
|
|
||||||
if (state.content.length === 0) return null
|
|
||||||
return state.content.find(item => item.id === id)
|
|
||||||
},
|
|
||||||
getBySlug: (state) => (slug) => {
|
|
||||||
if (state.content.length === 0) return null
|
|
||||||
return state.content.find(item => item.slug === slug)
|
|
||||||
},
|
|
||||||
getAllTags: (state) => {
|
|
||||||
if (state.content.length === 0) return []
|
|
||||||
let allTags = []
|
|
||||||
state.content.forEach(form => {
|
|
||||||
if(form.tags && form.tags.length > 0){
|
|
||||||
allTags = allTags.concat(form.tags)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return allTags.filter((item, i, ar) => ar.indexOf(item) === i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mutations
|
|
||||||
export const mutations = {
|
|
||||||
set (state, items) {
|
|
||||||
state.content = items
|
|
||||||
},
|
|
||||||
append (state, items) {
|
|
||||||
state.content = state.content.concat(items)
|
|
||||||
},
|
|
||||||
addOrUpdate (state, item) {
|
|
||||||
state.content = state.content.filter((val) => val.id !== item.id)
|
|
||||||
state.content.push(item)
|
|
||||||
},
|
|
||||||
remove (state, item) {
|
|
||||||
state.content = state.content.filter((val) => val.id !== item.id)
|
|
||||||
},
|
|
||||||
startLoading (state) {
|
|
||||||
state.loading = true
|
|
||||||
},
|
|
||||||
stopLoading (state) {
|
|
||||||
state.loading = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions
|
|
||||||
export const actions = {
|
|
||||||
resetState (context) {
|
|
||||||
context.commit('set', [])
|
|
||||||
context.commit('stopLoading')
|
|
||||||
currentPage = 1
|
|
||||||
},
|
|
||||||
load (context, workspaceId) {
|
|
||||||
context.commit('startLoading')
|
|
||||||
return axios.get(formsEndpoint.replace('{workspaceId}', workspaceId)+'?page='+currentPage).then((response) => {
|
|
||||||
context.commit((currentPage == 1) ? 'set' : 'append', response.data.data)
|
|
||||||
if (currentPage < response.data.meta.last_page) {
|
|
||||||
currentPage += 1
|
|
||||||
context.dispatch('load', workspaceId)
|
|
||||||
} else {
|
|
||||||
context.commit('stopLoading')
|
|
||||||
currentPage = 1
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
loadIfEmpty (context, workspaceId) {
|
|
||||||
if (context.state.content.length === 0) {
|
|
||||||
return context.dispatch('load', workspaceId)
|
|
||||||
}
|
|
||||||
context.commit('stopLoading')
|
|
||||||
return Promise.resolve()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
import axios from 'axios'
|
|
||||||
|
|
||||||
export const namespaced = true
|
|
||||||
export const workspaceEndpoint = '/api/open/records/'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads records from database
|
|
||||||
*/
|
|
||||||
|
|
||||||
// state
|
|
||||||
export const state = {
|
|
||||||
content: [],
|
|
||||||
loading: false
|
|
||||||
}
|
|
||||||
|
|
||||||
// getters
|
|
||||||
export const getters = {
|
|
||||||
getById: (state) => (id) => {
|
|
||||||
if (state.content.length === 0) return null
|
|
||||||
return state.content.find(item => item.submission_id === id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mutations
|
|
||||||
export const mutations = {
|
|
||||||
set (state, items) {
|
|
||||||
state.content = items
|
|
||||||
},
|
|
||||||
addOrUpdate (state, item) {
|
|
||||||
state.content = state.content.filter((val) => val.id !== item.id)
|
|
||||||
state.content.push(item)
|
|
||||||
},
|
|
||||||
remove (state, itemId) {
|
|
||||||
state.content = state.content.filter((val) => val.id !== itemId)
|
|
||||||
},
|
|
||||||
startLoading () {
|
|
||||||
state.loading = true
|
|
||||||
},
|
|
||||||
stopLoading () {
|
|
||||||
state.loading = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions
|
|
||||||
export const actions = {
|
|
||||||
resetState (context) {
|
|
||||||
context.commit('set', [])
|
|
||||||
context.commit('stopLoading')
|
|
||||||
},
|
|
||||||
loadRecord (context, request) {
|
|
||||||
context.commit('set', [])
|
|
||||||
context.commit('startLoading')
|
|
||||||
return request.then((data) => {
|
|
||||||
context.commit('addOrUpdate', data)
|
|
||||||
context.commit('stopLoading')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,126 +0,0 @@
|
||||||
import axios from 'axios'
|
|
||||||
|
|
||||||
export const templatesEndpoint = '/api/templates'
|
|
||||||
export const namespaced = true
|
|
||||||
|
|
||||||
// state
|
|
||||||
export const state = {
|
|
||||||
content: [],
|
|
||||||
industries: {},
|
|
||||||
types: {},
|
|
||||||
allLoaded: false,
|
|
||||||
loading: false
|
|
||||||
}
|
|
||||||
|
|
||||||
// getters
|
|
||||||
export const getters = {
|
|
||||||
getBySlug: (state) => (slug) => {
|
|
||||||
if (state.content.length === 0) return null
|
|
||||||
return state.content.find(item => item.slug === slug)
|
|
||||||
},
|
|
||||||
getTemplateTypes: (state) => (slugs) => {
|
|
||||||
if (state.types.length === 0) return null
|
|
||||||
return Object.values(state.types).filter((val) => slugs.includes(val.slug)).map((item) => { return item.name })
|
|
||||||
},
|
|
||||||
getTemplateIndustries: (state) => (slugs) => {
|
|
||||||
if (state.industries.length === 0) return null
|
|
||||||
return Object.values(state.industries).filter((val) => slugs.includes(val.slug)).map((item) => { return item.name })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mutations
|
|
||||||
export const mutations = {
|
|
||||||
set (state, items) {
|
|
||||||
state.content = items
|
|
||||||
state.allLoaded = true
|
|
||||||
},
|
|
||||||
append (state, items) {
|
|
||||||
const ids = items.map((item) => { return item.id })
|
|
||||||
state.content = state.content.filter((val) => !ids.includes(val.id))
|
|
||||||
state.content = state.content.concat(items)
|
|
||||||
},
|
|
||||||
addOrUpdate (state, item) {
|
|
||||||
state.content = state.content.filter((val) => val.id !== item.id)
|
|
||||||
state.content.push(item)
|
|
||||||
},
|
|
||||||
remove (state, item) {
|
|
||||||
state.content = state.content.filter((val) => val.id !== item.id)
|
|
||||||
},
|
|
||||||
startLoading (state) {
|
|
||||||
state.loading = true
|
|
||||||
},
|
|
||||||
stopLoading (state) {
|
|
||||||
state.loading = false
|
|
||||||
},
|
|
||||||
setAllLoaded (state, val) {
|
|
||||||
state.allLoaded = val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions
|
|
||||||
export const actions = {
|
|
||||||
resetState (context) {
|
|
||||||
context.commit('set', [])
|
|
||||||
context.commit('stopLoading')
|
|
||||||
},
|
|
||||||
loadTypesAndIndustries (context) {
|
|
||||||
if (Object.keys(context.state.industries).length === 0) {
|
|
||||||
import('@/data/forms/templates/industries.json').then((module) => {
|
|
||||||
context.state.industries = module.default
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (Object.keys(context.state.types).length === 0) {
|
|
||||||
import('@/data/forms/templates/types.json').then((module) => {
|
|
||||||
context.state.types = module.default
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
loadTemplate (context, slug) {
|
|
||||||
context.commit('startLoading')
|
|
||||||
context.dispatch('loadTypesAndIndustries')
|
|
||||||
|
|
||||||
if (context.getters.getBySlug(slug)) {
|
|
||||||
context.commit('stopLoading')
|
|
||||||
return Promise.resolve()
|
|
||||||
}
|
|
||||||
|
|
||||||
return axios.get(templatesEndpoint + '/' + slug).then((response) => {
|
|
||||||
context.commit('addOrUpdate', response.data)
|
|
||||||
context.commit('stopLoading')
|
|
||||||
}).catch((error) => {
|
|
||||||
context.commit('stopLoading')
|
|
||||||
})
|
|
||||||
},
|
|
||||||
loadAll (context, options=null) {
|
|
||||||
context.commit('startLoading')
|
|
||||||
context.dispatch('loadTypesAndIndustries')
|
|
||||||
|
|
||||||
// Prepare with options
|
|
||||||
let queryStr = ''
|
|
||||||
if(options !== null){
|
|
||||||
for (const [key, value] of Object.entries(options)) {
|
|
||||||
queryStr += '&' + encodeURIComponent(key) + '=' + encodeURIComponent(value)
|
|
||||||
}
|
|
||||||
queryStr = queryStr.slice(1)
|
|
||||||
}
|
|
||||||
return axios.get((queryStr) ? templatesEndpoint + '?' + queryStr : templatesEndpoint).then((response) => {
|
|
||||||
if(options !== null){
|
|
||||||
context.commit('set', response.data)
|
|
||||||
context.commit('setAllLoaded', false)
|
|
||||||
} else {
|
|
||||||
context.commit('append', response.data)
|
|
||||||
context.commit('setAllLoaded', true)
|
|
||||||
}
|
|
||||||
context.commit('stopLoading')
|
|
||||||
}).catch((error) => {
|
|
||||||
context.commit('stopLoading')
|
|
||||||
})
|
|
||||||
},
|
|
||||||
loadIfEmpty (context) {
|
|
||||||
if (!context.state.allLoaded) {
|
|
||||||
return context.dispatch('loadAll')
|
|
||||||
}
|
|
||||||
context.commit('stopLoading')
|
|
||||||
return Promise.resolve()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
export const namespaced = true
|
|
||||||
|
|
||||||
// state
|
|
||||||
export const state = {
|
|
||||||
content: null,
|
|
||||||
|
|
||||||
// Field being edited
|
|
||||||
selectedFieldIndex: null,
|
|
||||||
showEditFieldSidebar: null,
|
|
||||||
showAddFieldSidebar: null
|
|
||||||
}
|
|
||||||
|
|
||||||
// mutations
|
|
||||||
export const mutations = {
|
|
||||||
set (state, form) {
|
|
||||||
state.content = form
|
|
||||||
},
|
|
||||||
setProperties (state, properties) {
|
|
||||||
state.content.properties = properties
|
|
||||||
},
|
|
||||||
openSettingsForField (state, index) {
|
|
||||||
// If field is passed, compute index
|
|
||||||
if (typeof index === 'object') {
|
|
||||||
index = state.content.properties.findIndex(prop => prop.id === index.id)
|
|
||||||
}
|
|
||||||
state.selectedFieldIndex = index
|
|
||||||
state.showEditFieldSidebar = true
|
|
||||||
state.showAddFieldSidebar = false
|
|
||||||
},
|
|
||||||
closeEditFieldSidebar (state) {
|
|
||||||
state.selectedFieldIndex = null
|
|
||||||
state.showEditFieldSidebar = false
|
|
||||||
state.showAddFieldSidebar = false
|
|
||||||
},
|
|
||||||
openAddFieldSidebar (state, index) {
|
|
||||||
// If field is passed, compute index
|
|
||||||
if (index !== null && typeof index === 'object') {
|
|
||||||
index = state.content.properties.findIndex(prop => prop.id === index.id)
|
|
||||||
}
|
|
||||||
state.selectedFieldIndex = index
|
|
||||||
state.showAddFieldSidebar = true
|
|
||||||
state.showEditFieldSidebar = false
|
|
||||||
},
|
|
||||||
closeAddFieldSidebar (state) {
|
|
||||||
state.selectedFieldIndex = null
|
|
||||||
state.showAddFieldSidebar = false
|
|
||||||
state.showEditFieldSidebar = false
|
|
||||||
},
|
|
||||||
}
|
|
|
@ -1,100 +0,0 @@
|
||||||
import Vue from 'vue'
|
|
||||||
import axios from 'axios'
|
|
||||||
|
|
||||||
export const namespaced = true
|
|
||||||
export const workspaceEndpoint = '/api/open/workspaces/'
|
|
||||||
|
|
||||||
const localStorageCurrentWorkspaceKey = 'currentWorkspace'
|
|
||||||
|
|
||||||
// state
|
|
||||||
export const state = {
|
|
||||||
content: [],
|
|
||||||
currentId: null,
|
|
||||||
loading: false
|
|
||||||
}
|
|
||||||
|
|
||||||
// getters
|
|
||||||
export const getters = {
|
|
||||||
getById: (state) => (id) => {
|
|
||||||
if (state.content.length === 0) return null
|
|
||||||
return state.content.find(item => item.id === id)
|
|
||||||
},
|
|
||||||
getCurrent: (state) => () => {
|
|
||||||
if (state.content.length === 0 || state.currentId === null) return null
|
|
||||||
return state.content.find(item => item.id === state.currentId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mutations
|
|
||||||
export const mutations = {
|
|
||||||
set (state, items) {
|
|
||||||
state.content = items
|
|
||||||
if (state.currentId == null && state.content.length > 0) {
|
|
||||||
// If one only, set it
|
|
||||||
if (state.content.length === 1) {
|
|
||||||
state.currentId = items[0].id
|
|
||||||
localStorage.setItem(localStorageCurrentWorkspaceKey, state.currentId)
|
|
||||||
} else if (localStorage.getItem(localStorageCurrentWorkspaceKey) && state.content.find(item => item.id === parseInt(localStorage.getItem(localStorageCurrentWorkspaceKey)))) {
|
|
||||||
// Check local storage for current workspace, or take first
|
|
||||||
state.currentId = parseInt(localStorage.getItem(localStorageCurrentWorkspaceKey))
|
|
||||||
localStorage.setItem(localStorageCurrentWorkspaceKey, state.currentId)
|
|
||||||
} else {
|
|
||||||
// Else, take first
|
|
||||||
state.currentId = items[0].id
|
|
||||||
localStorage.setItem(localStorageCurrentWorkspaceKey, state.currentId)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
localStorage.removeItem(localStorageCurrentWorkspaceKey)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setCurrentId (state, id) {
|
|
||||||
state.currentId = id
|
|
||||||
localStorage.setItem(localStorageCurrentWorkspaceKey, id)
|
|
||||||
},
|
|
||||||
addOrUpdate (state, item) {
|
|
||||||
state.content = state.content.filter((val) => val.id !== item.id)
|
|
||||||
state.content.push(item)
|
|
||||||
if (state.currentId == null) {
|
|
||||||
state.currentId = item.id
|
|
||||||
localStorage.setItem(localStorageCurrentWorkspaceKey, state.currentId)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
remove (state, itemId) {
|
|
||||||
state.content = state.content.filter((val) => val.id !== itemId)
|
|
||||||
},
|
|
||||||
startLoading () {
|
|
||||||
state.loading = true
|
|
||||||
},
|
|
||||||
stopLoading () {
|
|
||||||
state.loading = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions
|
|
||||||
export const actions = {
|
|
||||||
resetState (context) {
|
|
||||||
context.commit('set', [])
|
|
||||||
context.commit('stopLoading')
|
|
||||||
},
|
|
||||||
load (context) {
|
|
||||||
context.commit('set', [])
|
|
||||||
context.commit('startLoading')
|
|
||||||
return axios.get(workspaceEndpoint).then((response) => {
|
|
||||||
context.commit('set', response.data)
|
|
||||||
context.commit('stopLoading')
|
|
||||||
})
|
|
||||||
},
|
|
||||||
loadIfEmpty ({ context, dispatch, state }) {
|
|
||||||
if (state.content.length === 0) {
|
|
||||||
return dispatch('load')
|
|
||||||
}
|
|
||||||
return Promise.resolve()
|
|
||||||
},
|
|
||||||
delete ({ commit, dispatch, state }, id) {
|
|
||||||
commit('startLoading')
|
|
||||||
return axios.delete(workspaceEndpoint + id).then((response) => {
|
|
||||||
commit('remove', response.data.workspace_id)
|
|
||||||
commit('stopLoading')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
// auth.js
|
|
||||||
export const LOGOUT = 'LOGOUT'
|
|
||||||
export const SAVE_TOKEN = 'SAVE_TOKEN'
|
|
||||||
export const FETCH_USER = 'FETCH_USER'
|
|
||||||
export const FETCH_USER_SUCCESS = 'FETCH_USER_SUCCESS'
|
|
||||||
export const FETCH_USER_FAILURE = 'FETCH_USER_FAILURE'
|
|
||||||
export const UPDATE_USER = 'UPDATE_USER'
|
|
||||||
|
|
||||||
// lang.js
|
|
||||||
export const SET_LOCALE = 'SET_LOCALE'
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import { nextTick } from 'vue'
|
||||||
|
|
||||||
|
export const useAppStore = defineStore('app', {
|
||||||
|
state: () => ({
|
||||||
|
layout: 'default',
|
||||||
|
|
||||||
|
// App Loader
|
||||||
|
loader: {
|
||||||
|
percent: 0,
|
||||||
|
show: false,
|
||||||
|
canSuccess: true,
|
||||||
|
duration: 3000,
|
||||||
|
_timer: null,
|
||||||
|
_cut: null
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
setLayout (layout) {
|
||||||
|
this.layout = layout ?? 'default'
|
||||||
|
},
|
||||||
|
loaderIncrease (num) {
|
||||||
|
this.loader.percent = this.loader.percent + Math.floor(num)
|
||||||
|
},
|
||||||
|
loaderDecrease (num) {
|
||||||
|
this.loader.percent = this.loader.percent - Math.floor(num)
|
||||||
|
},
|
||||||
|
loaderFinish () {
|
||||||
|
this.loader.percent = 100
|
||||||
|
this.loaderHide()
|
||||||
|
},
|
||||||
|
loaderSetTimer (timerVal) {
|
||||||
|
this._timer = timerVal
|
||||||
|
},
|
||||||
|
loaderPause () {
|
||||||
|
clearInterval(this.loader._timer)
|
||||||
|
},
|
||||||
|
loaderHide () {
|
||||||
|
clearInterval(this.loader._timer)
|
||||||
|
this.loader._timer = null
|
||||||
|
setTimeout(() => {
|
||||||
|
this.loader.show = false
|
||||||
|
nextTick(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.loader.percent = 0
|
||||||
|
}, 200)
|
||||||
|
})
|
||||||
|
}, 500)
|
||||||
|
},
|
||||||
|
loaderFail () {
|
||||||
|
this.loader.canSuccess = false
|
||||||
|
},
|
||||||
|
loaderStart () {
|
||||||
|
this.loader.show = true
|
||||||
|
this.loader.canSuccess = true
|
||||||
|
if (this.loader._timer) {
|
||||||
|
clearInterval(this.loader._timer)
|
||||||
|
this.loader.percent = 0
|
||||||
|
}
|
||||||
|
this.loader._cut = 10000 / Math.floor(this.loader.duration)
|
||||||
|
|
||||||
|
this.loaderSetTimer(setInterval(() => {
|
||||||
|
this.loaderIncrease(this.loader._cut * Math.random())
|
||||||
|
if (this.loader.percent > 95) {
|
||||||
|
this.loaderFinish()
|
||||||
|
}
|
||||||
|
}, 100))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,67 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import axios from 'axios'
|
||||||
|
import Cookies from 'js-cookie'
|
||||||
|
|
||||||
|
export const useAuthStore = defineStore('auth', {
|
||||||
|
state: () => ({
|
||||||
|
user: null,
|
||||||
|
token: Cookies.get('token'),
|
||||||
|
|
||||||
|
// For admin impersonation
|
||||||
|
admin_token: Cookies.get('admin_token') ?? null
|
||||||
|
}),
|
||||||
|
getters: {
|
||||||
|
check: (state) => (state.user !== null && state.user !== undefined),
|
||||||
|
isImpersonating: (state) => (state.admin_token !== null && state.admin_token !== undefined)
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
// Stores admin token temporarily for impersonation
|
||||||
|
startImpersonating () {
|
||||||
|
this.admin_token = this.token
|
||||||
|
Cookies.set('admin_token', this.token, { expires: 365 })
|
||||||
|
},
|
||||||
|
// Stop admin impersonation
|
||||||
|
stopImpersonating () {
|
||||||
|
this.token = this.admin_token
|
||||||
|
this.admin_token = null
|
||||||
|
Cookies.set('token', this.token, { expires: 365 })
|
||||||
|
Cookies.remove('admin_token')
|
||||||
|
this.fetchUser()
|
||||||
|
},
|
||||||
|
|
||||||
|
saveToken (token, remember) {
|
||||||
|
this.token = token
|
||||||
|
Cookies.set('token', token, { expires: remember ? 365 : null })
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchUser () {
|
||||||
|
try {
|
||||||
|
const { data } = await axios.get('/api/user')
|
||||||
|
this.user = data
|
||||||
|
return data
|
||||||
|
} catch (e) {
|
||||||
|
this.token = null
|
||||||
|
Cookies.remove('token')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateUser (payload) {
|
||||||
|
this.user = payload
|
||||||
|
},
|
||||||
|
|
||||||
|
async logout () {
|
||||||
|
try {
|
||||||
|
await axios.post('/api/logout')
|
||||||
|
} catch (e) { }
|
||||||
|
|
||||||
|
this.user = null
|
||||||
|
this.token = null
|
||||||
|
Cookies.remove('token')
|
||||||
|
},
|
||||||
|
|
||||||
|
async fetchOauthUrl (provider) {
|
||||||
|
const { data } = await axios.post(`/api/oauth/${provider}`)
|
||||||
|
return data.url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const namespaced = true
|
||||||
|
|
||||||
|
export const useErrorsStore = defineStore('errors', {
|
||||||
|
state: () => ({
|
||||||
|
content: null
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
set (error) {
|
||||||
|
this.content = error
|
||||||
|
},
|
||||||
|
clear () {
|
||||||
|
this.content = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue