1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-04-04 13:15:24 +00:00

Resolve "Fix number formatting to the rollup field to a formula number field"

This commit is contained in:
Davide Silvestri 2025-03-17 11:08:41 +01:00
parent 39292cec85
commit 17db839dac
6 changed files with 135 additions and 107 deletions
changelog/entries/unreleased/bug
web-frontend/modules

View file

@ -0,0 +1,8 @@
{
"type": "bug",
"message": "Fix field formatting options in rollup fields targeting formula fields",
"domain": "database",
"issue_number": 3443,
"bullet_points": [],
"created_at": "2025-03-13"
}

View file

@ -210,6 +210,12 @@ export default {
})
)
},
isDirty() {
for (const [key, value] of Object.entries(this.getDefaultValues())) {
if (this.values[key] !== value) return true
}
return false
},
/**
* Resets the form and the child forms to its original state.
*

View file

@ -16,6 +16,7 @@
></FieldSelectTargetFieldSubForm>
<template v-if="selectedTargetField">
<FormulaTypeSubForms
ref="subForm"
:default-values="subFormDefaultValues"
:formula-type="targetFieldFormulaType"
:table="table"
@ -31,6 +32,7 @@
<script>
import form from '@baserow/modules/core/mixins/form'
import fieldSubForm from '@baserow/modules/database/mixins/fieldSubForm'
import lookupFieldSubForm from '@baserow/modules/database/mixins/lookupFieldSubForm'
import FormulaTypeSubForms from '@baserow/modules/database/components/formula/FormulaTypeSubForms'
import FieldSelectThroughFieldSubForm from '@baserow/modules/database/components/field/FieldSelectThroughFieldSubForm'
import FieldSelectTargetFieldSubForm from '@baserow/modules/database/components/field/FieldSelectTargetFieldSubForm'
@ -42,77 +44,6 @@ export default {
FieldSelectTargetFieldSubForm,
FormulaTypeSubForms,
},
mixins: [form, fieldSubForm],
data() {
return {
selectedThroughField: null,
selectedTargetField: null,
allowedValues: [],
values: {},
errorFromServer: null,
subFormDefaultValues: {},
}
},
computed: {
targetFieldFormulaType() {
if (this.selectedTargetField) {
return this.getFormulaType(this.selectedTargetField)
}
return 'unknown'
},
},
watch: {
defaultValues: {
handler(newDefaultValues) {
this.subFormDefaultValues = { ...newDefaultValues }
},
immediate: true,
},
selectedTargetField: {
handler(newTargetField) {
if (!newTargetField) {
return
}
const fieldType = this.$registry.get('field', newTargetField.type)
const formulaType = fieldType.toBaserowFormulaType(newTargetField)
const formulaTypeChanged =
formulaType && this.getFormulaType(this.defaultValues) !== formulaType
// New field or different type, use the relevant settings from the target field
const fieldValues = this.defaultValues
if (!fieldValues.id || formulaTypeChanged) {
for (const key in this.selectedTargetField) {
if (key.startsWith(formulaType)) {
this.subFormDefaultValues[key] = this.selectedTargetField[key]
}
}
}
},
},
},
methods: {
getFormulaType(field) {
return field.array_formula_type || field.formula_type || field.type
},
handleErrorByForm(error) {
if (
[
'ERROR_WITH_FORMULA',
'ERROR_FIELD_SELF_REFERENCE',
'ERROR_FIELD_CIRCULAR_REFERENCE',
].includes(error.handler.code)
) {
this.errorFromServer = error.handler.detail
return true
} else {
return false
}
},
reset() {
form.methods.reset.call(this)
this.errorFromServer = null
},
},
mixins: [form, fieldSubForm, lookupFieldSubForm],
}
</script>

View file

@ -39,7 +39,8 @@
</FormGroup>
<FormulaTypeSubForms
:default-values="defaultValues"
ref="subForm"
:default-values="subFormDefaultValues"
:formula-type="targetFieldFormulaType"
:table="table"
:view="view"
@ -60,6 +61,7 @@ import { required } from '@vuelidate/validators'
import form from '@baserow/modules/core/mixins/form'
import fieldSubForm from '@baserow/modules/database/mixins/fieldSubForm'
import lookupFieldSubForm from '@baserow/modules/database/mixins/lookupFieldSubForm'
import FormulaTypeSubForms from '@baserow/modules/database/components/formula/FormulaTypeSubForms'
import FieldSelectThroughFieldSubForm from '@baserow/modules/database/components/field/FieldSelectThroughFieldSubForm'
import FieldSelectTargetFieldSubForm from '@baserow/modules/database/components/field/FieldSelectTargetFieldSubForm'
@ -71,58 +73,25 @@ export default {
FieldSelectTargetFieldSubForm,
FormulaTypeSubForms,
},
mixins: [form, fieldSubForm],
mixins: [form, fieldSubForm, lookupFieldSubForm],
setup() {
return { v$: useVuelidate({ $lazy: true }) }
},
data() {
return {
selectedThroughField: null,
selectedTargetField: null,
allowedValues: ['rollup_function'],
values: {
rollup_function: null,
},
errorFromServer: null,
}
},
computed: {
targetFieldFormulaType() {
if (this.selectedTargetField) {
return (
this.selectedTargetField.array_formula_type ||
this.selectedTargetField.type
)
}
return 'unknown'
},
rollupFunctions() {
return Object.values(this.$registry.getAll('formula_function')).filter(
(f) => f.isRollupCompatible(this.targetFieldFormulaType)
)
},
},
methods: {
handleErrorByForm(error) {
if (
[
'ERROR_WITH_FORMULA',
'ERROR_FIELD_SELF_REFERENCE',
'ERROR_FIELD_CIRCULAR_REFERENCE',
].includes(error.handler.code)
) {
this.errorFromServer = error.handler.detail
return true
} else {
return false
}
},
reset() {
form.methods.reset.call(this)
this.errorFromServer = null
},
},
validations() {
return {
values: {

View file

@ -1,6 +1,7 @@
<template>
<FieldNumberSubForm
v-if="formulaType === 'number'"
ref="subForm"
:default-values="defaultValues"
:table="table"
:view="view"
@ -12,6 +13,7 @@
</FieldNumberSubForm>
<FieldDateSubForm
v-else-if="['date', 'last_modified', 'created_on'].includes(formulaType)"
ref="subForm"
:default-values="defaultValues"
:table="table"
:view="view"
@ -22,6 +24,7 @@
</FieldDateSubForm>
<FieldDurationSubForm
v-else-if="formulaType === 'duration'"
ref="subForm"
:default-values="defaultValues"
:table="table"
:view="view"
@ -67,5 +70,10 @@ export default {
values: {},
}
},
methods: {
isDirty() {
return this.$refs.subForm?.isDirty()
},
},
}
</script>

View file

@ -0,0 +1,106 @@
import form from '@baserow/modules/core/mixins/form'
export default {
data() {
return {
selectedThroughField: null,
selectedTargetField: null,
allowedValues: [],
values: {},
errorFromServer: null,
subFormDefaultValues: {},
}
},
computed: {
targetFieldFormulaType() {
if (this.selectedTargetField) {
return this.getFormulaType(this.selectedTargetField)
}
return 'unknown'
},
},
watch: {
defaultValues: {
handler(newDefaultValues) {
this.subFormDefaultValues = { ...newDefaultValues }
},
immediate: true,
},
selectedTargetField: {
/**
* Updates sub form defaults based on the selected target field.
* For new fields with untouched forms, always suggest target field settings.
* For existing fields, suggest settings only if the formula type changes.
*/
handler(newTargetField, oldTargetField) {
if (!newTargetField) {
return
}
const fieldId = this.defaultValues.id
const newField = !fieldId
const cleanForm = !this.$refs.subForm?.isDirty()
const newFieldCleanFormAndNewTarget =
newField && cleanForm && newTargetField?.id !== oldTargetField?.id
const existingFieldButDifferentType =
!newField && !this.matchTargetFieldType(newTargetField)
const shouldSuggestDefaults =
newFieldCleanFormAndNewTarget || existingFieldButDifferentType
const fieldType = this.$registry.get('field', newTargetField.type)
const formulaType = fieldType.toBaserowFormulaType(newTargetField)
// New field or different type, use the relevant settings from the target field
if (shouldSuggestDefaults) {
const defaults = {}
for (const key in this.selectedTargetField) {
if (key.startsWith(formulaType)) {
defaults[key] = this.selectedTargetField[key]
}
}
this.subFormDefaultValues = {
...this.subFormDefaultValues,
...defaults,
}
this.$nextTick(() => this.$refs.subForm.reset())
}
},
},
},
methods: {
/**
* Verify if the final formula type match the target field type.
*/
matchTargetFieldType(targetField) {
const field = this.defaultValues
return (
field?.type === this.fieldType &&
(field?.formula_type === targetField?.type ||
field?.array_formula_type === targetField?.type)
)
},
getFormulaType(field) {
return field.array_formula_type || field.formula_type || field.type
},
handleErrorByForm(error) {
if (
[
'ERROR_WITH_FORMULA',
'ERROR_FIELD_SELF_REFERENCE',
'ERROR_FIELD_CIRCULAR_REFERENCE',
].includes(error.handler.code)
) {
this.errorFromServer = error.handler.detail
return true
} else {
return false
}
},
reset() {
form.methods.reset.call(this)
this.errorFromServer = null
},
},
}