Fix submissions download

This commit is contained in:
Julien Nahum 2024-01-30 09:42:33 +01:00
parent d0a7c4d2c3
commit 7348605327
1 changed files with 45 additions and 29 deletions

View File

@ -10,8 +10,12 @@
<modal :show="showColumnsModal" @close="showColumnsModal=false"> <modal :show="showColumnsModal" @close="showColumnsModal=false">
<template #icon> <template #icon>
<svg class="w-8 h-8" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg class="w-8 h-8" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 5H8C4.13401 5 1 8.13401 1 12C1 15.866 4.13401 19 8 19H16C19.866 19 23 15.866 23 12C23 8.13401 19.866 5 16 5Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> <path
<path d="M8 15C9.65685 15 11 13.6569 11 12C11 10.3431 9.65685 9 8 9C6.34315 9 5 10.3431 5 12C5 13.6569 6.34315 15 8 15Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> d="M16 5H8C4.13401 5 1 8.13401 1 12C1 15.866 4.13401 19 8 19H16C19.866 19 23 15.866 23 12C23 8.13401 19.866 5 16 5Z"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path
d="M8 15C9.65685 15 11 13.6569 11 12C11 10.3431 9.65685 9 8 9C6.34315 9 5 10.3431 5 12C5 13.6569 6.34315 15 8 15Z"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg> </svg>
</template> </template>
<template #title> <template #title>
@ -24,11 +28,13 @@
Form Fields Form Fields
</h4> </h4>
<div class="border border-gray-300 rounded-md"> <div class="border border-gray-300 rounded-md">
<div v-for="(field,index) in form.properties" :key="field.id" class="p-2 border-gray-300 flex items-center" :class="{'border-t':index!=0}"> <div v-for="(field,index) in form.properties" :key="field.id" class="p-2 border-gray-300 flex items-center"
:class="{'border-t':index!=0}">
<p class="flex-grow truncate"> <p class="flex-grow truncate">
{{ field.name }} {{ field.name }}
</p> </p>
<v-switch v-model="displayColumns[field.id]" class="float-right" @update:model-value="onChangeDisplayColumns" /> <v-switch v-model="displayColumns[field.id]" class="float-right"
@update:model-value="onChangeDisplayColumns"/>
</div> </div>
</div> </div>
</template> </template>
@ -37,22 +43,24 @@
Removed Fields Removed Fields
</h4> </h4>
<div class="border border-gray-300 rounded-md"> <div class="border border-gray-300 rounded-md">
<div v-for="(field,index) in removed_properties" :key="field.id" class="p-2 border-gray-300 flex items-center" :class="{'border-t':index!=0}"> <div v-for="(field,index) in removed_properties" :key="field.id"
class="p-2 border-gray-300 flex items-center" :class="{'border-t':index!=0}">
<p class="flex-grow truncate"> <p class="flex-grow truncate">
{{ field.name }} {{ field.name }}
</p> </p>
<v-switch v-model="displayColumns[field.id]" class="float-right" @update:model-value="onChangeDisplayColumns" /> <v-switch v-model="displayColumns[field.id]" class="float-right"
@update:model-value="onChangeDisplayColumns"/>
</div> </div>
</div> </div>
</template> </template>
</div> </div>
</modal> </modal>
<Loader v-if="!form || !formInitDone" class="h-6 w-6 text-nt-blue mx-auto" /> <Loader v-if="!form || !formInitDone" class="h-6 w-6 text-nt-blue mx-auto"/>
<div v-else> <div v-else>
<div v-if="form && tableData.length > 0" class="flex flex-wrap items-end"> <div v-if="form && tableData.length > 0" class="flex flex-wrap items-end">
<div class="flex-grow"> <div class="flex-grow">
<text-input class="w-64" :form="searchForm" name="search" placeholder="Search..." /> <text-input class="w-64" :form="searchForm" name="search" placeholder="Search..."/>
</div> </div>
<div class="font-semibold flex gap-4"> <div class="font-semibold flex gap-4">
<p class="float-right text-xs uppercase mb-2"> <p class="float-right text-xs uppercase mb-2">
@ -94,13 +102,14 @@ import Fuse from 'fuse.js'
import clonedeep from 'clone-deep' import clonedeep from 'clone-deep'
import VSwitch from '../../../forms/components/VSwitch.vue' import VSwitch from '../../../forms/components/VSwitch.vue'
import OpenTable from '../../tables/OpenTable.vue' import OpenTable from '../../tables/OpenTable.vue'
import {now} from "@vueuse/core";
export default { export default {
name: 'FormSubmissions', name: 'FormSubmissions',
components: { OpenTable, VSwitch }, components: {OpenTable, VSwitch},
props: {}, props: {},
setup () { setup() {
const workingFormStore = useWorkingFormStore() const workingFormStore = useWorkingFormStore()
return { return {
workingFormStore, workingFormStore,
@ -108,7 +117,7 @@ export default {
} }
}, },
data () { data() {
return { return {
formInitDone: false, formInitDone: false,
isLoading: false, isLoading: false,
@ -126,20 +135,20 @@ export default {
}, },
computed: { computed: {
form: { form: {
get () { get() {
return this.workingFormStore.content return this.workingFormStore.content
}, },
set (value) { set(value) {
this.workingFormStore.set(value) this.workingFormStore.set(value)
} }
}, },
exportUrl () { exportUrl() {
if (!this.form) { if (!this.form) {
return '' return ''
} }
return this.runtimeConfig.public.apiBase + '/open/forms/' + this.form.id + '/submissions/export' return this.runtimeConfig.public.apiBase + '/open/forms/' + this.form.id + '/submissions/export'
}, },
filteredData () { filteredData() {
if (!this.tableData) return [] if (!this.tableData) return []
const filteredData = clonedeep(this.tableData) const filteredData = clonedeep(this.tableData)
@ -159,7 +168,7 @@ export default {
} }
}, },
watch: { watch: {
'form.id' () { 'form.id'() {
if (this.form === null) { if (this.form === null) {
return return
} }
@ -167,12 +176,12 @@ export default {
this.getSubmissionsData() this.getSubmissionsData()
} }
}, },
mounted () { mounted() {
this.initFormStructure() this.initFormStructure()
this.getSubmissionsData() this.getSubmissionsData()
}, },
methods: { methods: {
initFormStructure () { initFormStructure() {
if (!this.form || !this.form.properties || this.formInitDone) { if (!this.form || !this.form.properties || this.formInitDone) {
return return
} }
@ -183,7 +192,7 @@ export default {
if (property.id === 'created_at') { if (property.id === 'created_at') {
return true return true
} }
}) ) { })) {
// Add a "created at" column // Add a "created at" column
this.properties.push({ this.properties.push({
name: 'Created at', name: 'Created at',
@ -206,7 +215,7 @@ export default {
}) })
} }
}, },
getSubmissionsData () { getSubmissionsData() {
if (!this.form || this.fullyLoaded) { if (!this.form || this.fullyLoaded) {
return return
} }
@ -227,7 +236,7 @@ export default {
this.isLoading = false this.isLoading = false
}) })
}, },
dataChanged () { dataChanged() {
if (this.$refs.shadows) { if (this.$refs.shadows) {
this.$refs.shadows.toggleShadow() this.$refs.shadows.toggleShadow()
this.$refs.shadows.calcDimensions() this.$refs.shadows.calcDimensions()
@ -236,24 +245,31 @@ export default {
onColumnUpdated(columns) { onColumnUpdated(columns) {
this.properties = columns this.properties = columns
}, },
onChangeDisplayColumns () { onChangeDisplayColumns() {
if (!process.client) return if (!process.client) return
window.localStorage.setItem('display-columns-formid-' + this.form.id, JSON.stringify(this.displayColumns)) window.localStorage.setItem('display-columns-formid-' + this.form.id, JSON.stringify(this.displayColumns))
this.properties = clonedeep(this.form.properties).concat(this.removed_properties).filter((field) => { this.properties = clonedeep(this.form.properties).concat(this.removed_properties).filter((field) => {
return this.displayColumns[field.id] === true return this.displayColumns[field.id] === true
}) })
}, },
onDeleteRecord () { onDeleteRecord() {
this.fullyLoaded = false this.fullyLoaded = false
this.tableData = [] this.tableData = []
this.getSubmissionsData() this.getSubmissionsData()
}, },
downloadAsCsv() { downloadAsCsv() {
opnFetch(this.exportUrl, { responseType: "blob" }) opnFetch(this.exportUrl, {responseType: "blob"})
.then( blob => { .then(blob => {
var file = window.URL.createObjectURL(blob); const filename = `${this.form.slug}-${Date.now()}-submissions.csv`
window.location.assign(file); let a = document.createElement("a")
}).catch((error)=>{ document.body.appendChild(a)
a.style = "display: none"
const url = window.URL.createObjectURL(blob)
a.href = url
a.download = filename
a.click()
window.URL.revokeObjectURL(url)
}).catch((error) => {
console.error(error) console.error(error)
}) })
} }