1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-04-07 14:25:37 +00:00

Fix reactivity problems in widget configuration forms

This commit is contained in:
Petr Stribny 2025-02-24 12:08:02 +01:00
parent f98e72156a
commit 2ef2d2d299
5 changed files with 62 additions and 52 deletions
enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source
web-frontend/modules
core/mixins
dashboard/components

View file

@ -10,9 +10,9 @@
class="margin-bottom-2"
>
<Dropdown
v-model="values.aggregation_type"
:value="values.aggregation_type"
:error="fieldHasErrors('aggregation_type')"
@change="v$.values.aggregation_type.$touch"
@change="aggregationTypeChanged"
>
<DropdownItem
v-for="aggregation in groupedAggregationTypes"
@ -90,7 +90,7 @@ export default {
field_id: null,
aggregation_type: null,
},
emitValuesOnReset: false,
skipFirstValuesEmit: true,
}
},
computed: {
@ -116,32 +116,6 @@ export default {
return this.compatibleFields.map((field) => field.id)
},
},
watch: {
'values.aggregation_type': {
handler(aggregationType) {
if (
aggregationType !== null &&
aggregationType !== this.defaultValues.aggregation_type &&
this.values.field_id !== null
) {
// If both the field and aggregation type
// are selected, check if they are still
// compatible.
const aggType = this.$registry.get(
'groupedAggregation',
aggregationType
)
const field = this.tableFields.filter(
(field) => field.id === this.values.field_id
)
if (!aggType.fieldIsCompatible(field)) {
this.values.field_id = null
}
}
},
immediate: true,
},
},
mounted() {
this.v$.$touch()
},
@ -171,6 +145,17 @@ export default {
const fieldType = this.$registry.get('field', field.type)
return fieldType.iconClass
},
aggregationTypeChanged(aggregationType) {
this.values.aggregation_type = aggregationType
const aggType = this.$registry.get('groupedAggregation', aggregationType)
const field = this.tableFields.find(
(field) => field.id === this.values.field_id
)
if (field && !aggType.fieldIsCompatible(field)) {
this.values.field_id = null
}
this.v$.values.aggregation_type.$touch()
},
},
}
</script>

View file

@ -172,7 +172,7 @@ export default {
},
tableLoading: false,
databaseSelectedId: null,
emitValuesOnReset: false,
skipFirstValuesEmit: true,
}
},
computed: {
@ -230,12 +230,15 @@ export default {
watch: {
dataSource: {
async handler(values) {
this.setEmitValues(false)
// Reset the form to set default values
// again after a different widget is selected
await this.reset(true)
// Run form validation so that
// problems are highlighted immediately
this.v$.$touch()
await this.$nextTick()
this.setEmitValues(true)
},
deep: true,
},

View file

@ -23,11 +23,15 @@ export default {
return {
// A list of values that the form allows. If null all values are allowed.
allowedValues: null,
// By setting emitValuesOnReset to false in the form's component
// the values changed event won't be sent right after resetting the
// form
emitValuesOnReset: true,
isAfterReset: true,
// Setting to false make it possible to temporarily
// prevent emitting values when they change.
// Use setEmitValues(value) method to include children
// forms.
emitValues: true,
// Setting to true makes it possible to not
// emit values the first time values are set in
// the form.
skipFirstValuesEmit: false,
}
},
mounted() {
@ -38,7 +42,13 @@ export default {
watch: {
values: {
handler(newValues) {
this.emitChange(newValues)
if (this.skipFirstValuesEmit) {
this.skipFirstValuesEmit = false
return
}
if (this.emitValues) {
this.emitChange(newValues)
}
},
deep: true,
},
@ -207,8 +217,6 @@ export default {
* first level of children.
*/
async reset(deep = false) {
this.isAfterReset = true
for (const [key, value] of Object.entries(this.getDefaultValues())) {
this.values[key] = value
}
@ -224,6 +232,15 @@ export default {
child.reset()
)
},
/**
* Sets emitValues property also to child forms.
*/
setEmitValues(value) {
this.emitValues = value
this.getChildForms((child) => 'setEmitValues' in child, true).forEach(
(child) => child.setEmitValues(value)
)
},
/**
* Returns if a child form has indicated it handled the error, false otherwise.
*/
@ -241,13 +258,7 @@ export default {
return childHandledIt
},
emitChange(newValues) {
if (this.emitValuesOnReset === true || this.isAfterReset === false) {
this.$emit('values-changed', newValues)
}
if (this.isAfterReset) {
this.isAfterReset = false
}
this.$emit('values-changed', newValues)
},
},
}

View file

@ -170,7 +170,7 @@ export default {
},
tableLoading: false,
databaseSelectedId: null,
emitValuesOnReset: false,
skipFirstValuesEmit: true,
}
},
computed: {
@ -227,13 +227,16 @@ export default {
},
watch: {
dataSource: {
handler(values) {
async handler(values) {
this.setEmitValues(false)
// Reset the form to set default values
// again after a different widget is selected
this.reset(true)
await this.reset(true)
// Run form validation so that
// problems are highlighted immediately
this.v$.$validate()
this.v$.$touch()
await this.$nextTick()
this.setEmitValues(true)
},
deep: true,
},

View file

@ -71,7 +71,7 @@ export default {
title: '',
description: '',
},
emitValuesOnReset: false,
skipFirstValuesEmit: true,
}
},
validations() {
@ -98,8 +98,16 @@ export default {
},
watch: {
widget: {
handler(value) {
this.reset(true)
async handler(value) {
this.setEmitValues(false)
// Reset the form to set default values
// again after a different widget is selected
await this.reset(true)
// Run form validation so that
// problems are highlighted immediately
this.v$.$touch()
await this.$nextTick()
this.setEmitValues(true)
},
deep: true,
},