Work in progress
This commit is contained in:
71
client/stores/app.js
vendored
Normal file
71
client/stores/app.js
vendored
Normal file
@@ -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.loader._timer = timerVal
|
||||
},
|
||||
loaderPause () {
|
||||
clearInterval(this.loader._timer)
|
||||
},
|
||||
loaderHide () {
|
||||
this.loaderPause()
|
||||
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))
|
||||
}
|
||||
}
|
||||
})
|
||||
70
client/stores/auth.js
vendored
Normal file
70
client/stores/auth.js
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
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
|
||||
},
|
||||
|
||||
load
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
})
|
||||
15
client/stores/errors.js
vendored
Normal file
15
client/stores/errors.js
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useErrorsStore = defineStore('errors', {
|
||||
state: () => ({
|
||||
content: null
|
||||
}),
|
||||
actions: {
|
||||
set (error) {
|
||||
this.content = error
|
||||
},
|
||||
clear () {
|
||||
this.content = null
|
||||
}
|
||||
}
|
||||
})
|
||||
82
client/stores/forms.js
vendored
Normal file
82
client/stores/forms.js
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import axios from 'axios'
|
||||
|
||||
export const formsEndpoint = '/api/open/workspaces/{workspaceId}/forms'
|
||||
export let currentPage = 1
|
||||
|
||||
export const useFormsStore = defineStore('forms', {
|
||||
state: () => ({
|
||||
content: [],
|
||||
loading: false
|
||||
}),
|
||||
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)
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
set (items) {
|
||||
this.content = items
|
||||
},
|
||||
append (items) {
|
||||
this.content = this.content.concat(items)
|
||||
},
|
||||
addOrUpdate (item) {
|
||||
this.content = this.content.filter((val) => val.id !== item.id)
|
||||
this.content.push(item)
|
||||
},
|
||||
remove (item) {
|
||||
this.content = this.content.filter((val) => val.id !== item.id)
|
||||
},
|
||||
startLoading () {
|
||||
this.loading = true
|
||||
},
|
||||
stopLoading () {
|
||||
this.loading = false
|
||||
},
|
||||
resetState () {
|
||||
this.set([])
|
||||
this.stopLoading()
|
||||
currentPage = 1
|
||||
},
|
||||
load (workspaceId) {
|
||||
this.startLoading()
|
||||
return axios.get(formsEndpoint.replace('{workspaceId}', workspaceId)+'?page='+currentPage).then((response) => {
|
||||
if (currentPage == 1) {
|
||||
this.set(response.data.data)
|
||||
} else {
|
||||
this.append(response.data.data)
|
||||
}
|
||||
if (currentPage < response.data.meta.last_page) {
|
||||
currentPage += 1
|
||||
this.load(workspaceId)
|
||||
} else {
|
||||
this.stopLoading()
|
||||
currentPage = 1
|
||||
}
|
||||
})
|
||||
},
|
||||
loadIfEmpty (workspaceId) {
|
||||
if (this.content.length === 0) {
|
||||
return this.load(workspaceId)
|
||||
}
|
||||
this.stopLoading()
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
})
|
||||
49
client/stores/records.js
vendored
Normal file
49
client/stores/records.js
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const namespaced = true
|
||||
|
||||
/**
|
||||
* Loads records from database
|
||||
*/
|
||||
export const useRecordsStore = defineStore('records', {
|
||||
state: () => ({
|
||||
content: [],
|
||||
loading: false
|
||||
}),
|
||||
getters: {
|
||||
getById: (state) => (id) => {
|
||||
if (state.content.length === 0) return null
|
||||
return state.content.find(item => item.submission_id === id)
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
set (items) {
|
||||
this.content = items
|
||||
},
|
||||
addOrUpdate (item) {
|
||||
this.content = this.content.filter((val) => val.id !== item.id)
|
||||
this.content.push(item)
|
||||
},
|
||||
remove (itemId) {
|
||||
this.content = this.content.filter((val) => val.id !== itemId)
|
||||
},
|
||||
startLoading () {
|
||||
this.loading = true
|
||||
},
|
||||
stopLoading () {
|
||||
this.loading = false
|
||||
},
|
||||
resetState () {
|
||||
this.set([])
|
||||
this.stopLoading()
|
||||
},
|
||||
loadRecord (request) {
|
||||
this.set([])
|
||||
this.startLoading()
|
||||
return request.then((data) => {
|
||||
this.addOrUpdate(data)
|
||||
this.stopLoading()
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
120
client/stores/templates.js
vendored
Normal file
120
client/stores/templates.js
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const templatesEndpoint = '/api/templates'
|
||||
|
||||
|
||||
export const useTemplatesStore = defineStore('templates', {
|
||||
state: () => ({
|
||||
content: [],
|
||||
industries: {},
|
||||
types: {},
|
||||
allLoaded: false,
|
||||
loading: false
|
||||
}),
|
||||
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 })
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
set (items) {
|
||||
this.content = items
|
||||
this.allLoaded = true
|
||||
},
|
||||
append (items) {
|
||||
const ids = items.map((item) => { return item.id })
|
||||
this.content = this.content.filter((val) => !ids.includes(val.id))
|
||||
this.content = this.content.concat(items)
|
||||
},
|
||||
addOrUpdate (item) {
|
||||
this.content = this.content.filter((val) => val.id !== item.id)
|
||||
this.content.push(item)
|
||||
},
|
||||
remove (item) {
|
||||
this.content = this.content.filter((val) => val.id !== item.id)
|
||||
},
|
||||
startLoading () {
|
||||
this.loading = true
|
||||
},
|
||||
stopLoading () {
|
||||
this.loading = false
|
||||
},
|
||||
setAllLoaded (val) {
|
||||
this.allLoaded = val
|
||||
},
|
||||
resetState () {
|
||||
this.set([])
|
||||
this.stopLoading()
|
||||
},
|
||||
loadTypesAndIndustries () {
|
||||
if (Object.keys(this.industries).length === 0) {
|
||||
import('@/data/forms/templates/industries.json').then((module) => {
|
||||
this.industries = module.default
|
||||
})
|
||||
}
|
||||
if (Object.keys(this.types).length === 0) {
|
||||
import('@/data/forms/templates/types.json').then((module) => {
|
||||
this.types = module.default
|
||||
})
|
||||
}
|
||||
},
|
||||
loadTemplate (slug) {
|
||||
this.startLoading()
|
||||
this.loadTypesAndIndustries()
|
||||
|
||||
if (this.getBySlug(slug)) {
|
||||
this.stopLoading()
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
return axios.get(templatesEndpoint + '/' + slug).then((response) => {
|
||||
this.addOrUpdate(response.data)
|
||||
this.stopLoading()
|
||||
}).catch((error) => {
|
||||
this.stopLoading()
|
||||
})
|
||||
},
|
||||
loadAll (options=null) {
|
||||
this.startLoading()
|
||||
this.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){
|
||||
this.set(response.data)
|
||||
this.setAllLoaded(false)
|
||||
} else {
|
||||
this.append(response.data)
|
||||
this.setAllLoaded(true)
|
||||
}
|
||||
this.stopLoading()
|
||||
}).catch((error) => {
|
||||
this.stopLoading()
|
||||
})
|
||||
},
|
||||
loadIfEmpty () {
|
||||
if (!this.allLoaded) {
|
||||
return this.loadAll()
|
||||
}
|
||||
this.stopLoading()
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
})
|
||||
50
client/stores/working_form.js
vendored
Normal file
50
client/stores/working_form.js
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
|
||||
|
||||
export const useWorkingFormStore = defineStore('working_form', {
|
||||
state: () => ({
|
||||
content: null,
|
||||
|
||||
// Field being edited
|
||||
selectedFieldIndex: null,
|
||||
showEditFieldSidebar: null,
|
||||
showAddFieldSidebar: null
|
||||
}),
|
||||
actions: {
|
||||
set (form) {
|
||||
this.content = form
|
||||
},
|
||||
setProperties (properties) {
|
||||
this.content.properties = properties
|
||||
},
|
||||
openSettingsForField (index) {
|
||||
// If field is passed, compute index
|
||||
if (typeof index === 'object') {
|
||||
index = this.content.properties.findIndex(prop => prop.id === index.id)
|
||||
}
|
||||
this.selectedFieldIndex = index
|
||||
this.showEditFieldSidebar = true
|
||||
this.showAddFieldSidebar = false
|
||||
},
|
||||
closeEditFieldSidebar () {
|
||||
this.selectedFieldIndex = null
|
||||
this.showEditFieldSidebar = false
|
||||
this.showAddFieldSidebar = false
|
||||
},
|
||||
openAddFieldSidebar (index) {
|
||||
// If field is passed, compute index
|
||||
if (index !== null && typeof index === 'object') {
|
||||
index = this.content.properties.findIndex(prop => prop.id === index.id)
|
||||
}
|
||||
this.selectedFieldIndex = index
|
||||
this.showAddFieldSidebar = true
|
||||
this.showEditFieldSidebar = false
|
||||
},
|
||||
closeAddFieldSidebar () {
|
||||
this.selectedFieldIndex = null
|
||||
this.showAddFieldSidebar = false
|
||||
this.showEditFieldSidebar = false
|
||||
}
|
||||
}
|
||||
})
|
||||
95
client/stores/workspaces.js
vendored
Normal file
95
client/stores/workspaces.js
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
import axios from 'axios'
|
||||
import { defineStore } from 'pinia'
|
||||
export const workspaceEndpoint = '/api/open/workspaces/'
|
||||
|
||||
const localStorageCurrentWorkspaceKey = 'currentWorkspace'
|
||||
|
||||
export const useWorkspacesStore = defineStore('workspaces', {
|
||||
state: () => ({
|
||||
content: [],
|
||||
currentId: null,
|
||||
loading: false
|
||||
}),
|
||||
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)
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
set (items) {
|
||||
this.content = items
|
||||
if (this.currentId == null && this.content.length > 0) {
|
||||
// If one only, set it
|
||||
if (this.content.length === 1) {
|
||||
this.currentId = items[0].id
|
||||
localStorage.setItem(localStorageCurrentWorkspaceKey, this.currentId)
|
||||
} else if (localStorage.getItem(localStorageCurrentWorkspaceKey) && this.content.find(item => item.id === parseInt(localStorage.getItem(localStorageCurrentWorkspaceKey)))) {
|
||||
// Check local storage for current workspace, or take first
|
||||
this.currentId = parseInt(localStorage.getItem(localStorageCurrentWorkspaceKey))
|
||||
localStorage.setItem(localStorageCurrentWorkspaceKey, this.currentId)
|
||||
} else {
|
||||
// Else, take first
|
||||
this.currentId = items[0].id
|
||||
localStorage.setItem(localStorageCurrentWorkspaceKey, this.currentId)
|
||||
}
|
||||
} else {
|
||||
localStorage.removeItem(localStorageCurrentWorkspaceKey)
|
||||
}
|
||||
},
|
||||
setCurrentId (id) {
|
||||
this.currentId = id
|
||||
localStorage.setItem(localStorageCurrentWorkspaceKey, id)
|
||||
},
|
||||
addOrUpdate (item) {
|
||||
this.content = this.content.filter((val) => val.id !== item.id)
|
||||
this.content.push(item)
|
||||
if (this.currentId == null) {
|
||||
this.currentId = item.id
|
||||
localStorage.setItem(localStorageCurrentWorkspaceKey, this.currentId)
|
||||
}
|
||||
},
|
||||
remove (itemId) {
|
||||
this.content = this.content.filter((val) => val.id !== itemId)
|
||||
if (this.currentId === itemId) {
|
||||
this.currentId = this.content.length > 0 ? this.content[0].id : null
|
||||
localStorage.setItem(localStorageCurrentWorkspaceKey, this.currentId)
|
||||
}
|
||||
},
|
||||
startLoading () {
|
||||
this.loading = true
|
||||
},
|
||||
stopLoading () {
|
||||
this.loading = false
|
||||
},
|
||||
resetState () {
|
||||
this.set([])
|
||||
this.stopLoading()
|
||||
},
|
||||
load () {
|
||||
this.set([])
|
||||
this.startLoading()
|
||||
return axios.get(workspaceEndpoint).then((response) => {
|
||||
this.set(response.data)
|
||||
this.stopLoading()
|
||||
})
|
||||
},
|
||||
loadIfEmpty () {
|
||||
if (this.content.length === 0) {
|
||||
return this.load()
|
||||
}
|
||||
return Promise.resolve()
|
||||
},
|
||||
delete (id) {
|
||||
this.startLoading()
|
||||
return axios.delete(workspaceEndpoint + id).then((response) => {
|
||||
this.remove(response.data.workspace_id)
|
||||
this.stopLoading()
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user