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:
parent
39292cec85
commit
17db839dac
6 changed files with 135 additions and 107 deletions
changelog/entries/unreleased/bug
web-frontend/modules
core/mixins
database
components
mixins
8
changelog/entries/unreleased/bug/3443_.json
Normal file
8
changelog/entries/unreleased/bug/3443_.json
Normal 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"
|
||||
}
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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>
|
||||
|
|
106
web-frontend/modules/database/mixins/lookupFieldSubForm.js
Normal file
106
web-frontend/modules/database/mixins/lookupFieldSubForm.js
Normal 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
|
||||
},
|
||||
},
|
||||
}
|
Loading…
Add table
Reference in a new issue