Update dirty forms editor (#119)

This commit is contained in:
Chirag Chhatrala 2023-05-21 23:04:47 +05:30 committed by GitHub
parent d2f4c1f358
commit 5087724847
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 76 additions and 3 deletions

View File

@ -98,7 +98,7 @@
<p class="text-gray-600 text-sm">{{notification.text}}</p> <p class="text-gray-600 text-sm">{{notification.text}}</p>
<div class="w-full flex gap-2 mt-1"> <div class="w-full flex gap-2 mt-1">
<v-button color="blue" size="small" @click.prevent="notification.success();close(notification.id)">Yes</v-button> <v-button color="blue" size="small" @click.prevent="notification.success();close(notification.id)">Yes</v-button>
<v-button color="transparent" size="small" @click.prevent="notification.failure();close(notification.id)">No</v-button> <v-button color="gray" shade="light" size="small" @click.prevent="notification.failure();close(notification.id)">No</v-button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -189,6 +189,7 @@ export default {
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.$store.commit('open/forms/addOrUpdate', data.form)
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})
this.displayFormModificationAlert(data) this.displayFormModificationAlert(data)
@ -209,6 +210,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.$store.commit('open/forms/addOrUpdate', response.data.form)
this.$emit('on-save')
this.createdFormId = response.data.form.id this.createdFormId = response.data.form.id
this.$logEvent('form_created', {form_id: response.data.form.id, form_slug: response.data.form.slug}) this.$logEvent('form_created', {form_id: response.data.form.id, form_slug: response.data.form.slug})

View File

@ -10,6 +10,7 @@
'max-height': editorMaxHeight + 'px' 'max-height': editorMaxHeight + 'px'
}" :error="error" }" :error="error"
@mounted="onResize" @mounted="onResize"
@on-save="formInitialHash=null"
/> />
<div v-else class="text-center mt-4 py-6"> <div v-else class="text-center mt-4 py-6">
<loader class="h-6 w-6 text-nt-blue mx-auto"/> <loader class="h-6 w-6 text-nt-blue mx-auto"/>
@ -45,6 +46,16 @@ export default {
next() next()
}, },
beforeRouteLeave (to, from, next) {
if (this.isDirty()) {
return this.alertConfirm('Changes you made may not be saved. Are you sure want to leave?', () => {
window.onbeforeunload = null
next()
}, () => {})
}
next()
},
middleware: 'auth', middleware: 'auth',
data() { data() {
@ -54,7 +65,8 @@ export default {
loading: false, loading: false,
error: '', error: '',
editorMaxHeight: 500, editorMaxHeight: 500,
showInitialFormModal: false showInitialFormModal: false,
formInitialHash: null
} }
}, },
@ -90,7 +102,14 @@ export default {
}, },
mounted() { mounted() {
window.onbeforeunload = () => {
if (this.isDirty()) {
return false
}
}
this.initForm() this.initForm()
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.$store.getters['open/templates/getBySlug'](this.$route.query.template)
if (template && template.structure) { if (template && template.structure) {
@ -127,6 +146,23 @@ export default {
}, },
formGenerated(form) { formGenerated(form) {
this.form = new Form({...this.form.data(), ...form}) this.form = new Form({...this.form.data(), ...form})
},
isDirty () {
return !this.loading && this.formInitialHash && this.formInitialHash !== this.hashString(JSON.stringify(this.form.data()))
},
hashString (str, seed = 0) {
let h1 = 0xdeadbeef ^ seed
let h2 = 0x41c6ce57 ^ seed
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i)
h1 = Math.imul(h1 ^ ch, 2654435761)
h2 = Math.imul(h2 ^ ch, 1597334677)
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909)
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909)
return 4294967296 * (2097151 & h2) + (h1 >>> 0)
} }
} }
} }

View File

@ -6,6 +6,7 @@
}" }"
:isEdit="true" :isEdit="true"
@mounted="onResize" @mounted="onResize"
@on-save="formInitialHash=null"
/> />
<div v-else-if="!loading && error" class="mt-4 rounded-lg max-w-xl mx-auto p-6 bg-red-100 text-red-500"> <div v-else-if="!loading && error" class="mt-4 rounded-lg max-w-xl mx-auto p-6 bg-red-100 text-red-500">
{{ error }} {{ error }}
@ -42,6 +43,17 @@ export default {
store.commit('open/working_form/set', null) // Reset old working form store.commit('open/working_form/set', null) // Reset old working form
next() next()
}, },
beforeRouteLeave (to, from, next) {
if (this.isDirty()) {
return this.alertConfirm('Changes you made may not be saved. Are you sure want to leave?', () => {
window.onbeforeunload = null
next()
}, () => {})
}
next()
},
middleware: 'auth', middleware: 'auth',
mixins: [SeoMeta], mixins: [SeoMeta],
@ -49,7 +61,8 @@ export default {
return { return {
loading: false, loading: false,
error: null, error: null,
editorMaxHeight: 500 editorMaxHeight: 500,
formInitialHash: null
} }
}, },
@ -91,11 +104,18 @@ export default {
}, },
mounted () { mounted () {
window.onbeforeunload = () => {
if (this.isDirty()) {
return false
}
}
this.closeAlert() this.closeAlert()
if (!this.form) { if (!this.form) {
loadForms() loadForms()
} else { } else {
this.updatedForm = new Form(this.form) this.updatedForm = new Form(this.form)
this.formInitialHash = this.hashString(JSON.stringify(this.updatedForm.data()))
} }
}, },
@ -107,6 +127,21 @@ export default {
if (this.$refs.editor) { if (this.$refs.editor) {
this.editorMaxHeight = Math.max(500, window.innerHeight - this.$refs.editor.$el.offsetTop) this.editorMaxHeight = Math.max(500, window.innerHeight - this.$refs.editor.$el.offsetTop)
} }
},
isDirty () {
return !this.loading && this.formInitialHash && this.formInitialHash !== this.hashString(JSON.stringify(this.updatedForm.data()))
},
hashString (str, seed = 0) {
let h1 = 0xdeadbeef ^ seed
let h2 = 0x41c6ce57 ^ seed
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i)
h1 = Math.imul(h1 ^ ch, 2654435761)
h2 = Math.imul(h2 ^ ch, 1597334677)
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909)
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909)
return 4294967296 * (2097151 & h2) + (h1 >>> 0)
} }
} }
} }