diff --git a/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/AggregationSeriesForm.vue b/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/AggregationSeriesForm.vue index ecdee18d9..b931c6273 100644 --- a/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/AggregationSeriesForm.vue +++ b/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/AggregationSeriesForm.vue @@ -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> diff --git a/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/GroupedAggregateRowsDataSourceForm.vue b/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/GroupedAggregateRowsDataSourceForm.vue index 133da433d..49eeb73fa 100644 --- a/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/GroupedAggregateRowsDataSourceForm.vue +++ b/enterprise/web-frontend/modules/baserow_enterprise/dashboard/components/data_source/GroupedAggregateRowsDataSourceForm.vue @@ -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, }, diff --git a/web-frontend/modules/core/mixins/form.js b/web-frontend/modules/core/mixins/form.js index 68431bbe6..1ec7b8841 100644 --- a/web-frontend/modules/core/mixins/form.js +++ b/web-frontend/modules/core/mixins/form.js @@ -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) }, }, } diff --git a/web-frontend/modules/dashboard/components/data_source/AggregateRowsDataSourceForm.vue b/web-frontend/modules/dashboard/components/data_source/AggregateRowsDataSourceForm.vue index 71f548e5f..a94b6d1f3 100644 --- a/web-frontend/modules/dashboard/components/data_source/AggregateRowsDataSourceForm.vue +++ b/web-frontend/modules/dashboard/components/data_source/AggregateRowsDataSourceForm.vue @@ -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, }, diff --git a/web-frontend/modules/dashboard/components/widget/WidgetSettingsBaseForm.vue b/web-frontend/modules/dashboard/components/widget/WidgetSettingsBaseForm.vue index 18c96d4df..c5d91d740 100644 --- a/web-frontend/modules/dashboard/components/widget/WidgetSettingsBaseForm.vue +++ b/web-frontend/modules/dashboard/components/widget/WidgetSettingsBaseForm.vue @@ -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, },