1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-04-12 16:28:06 +00:00
bramw_baserow/web-frontend/modules/database/components/field/FieldLookupSubForm.vue
2021-12-08 12:43:44 +00:00

231 lines
6.8 KiB
Vue

<template>
<div>
<div class="control">
<div
v-if="linkRowFieldsInThisTable.length === 0"
class="alert alert--error context__alert"
>
<p class="alert__content">
{{ $t('fieldLookupSubForm.noTable') }}
</p>
</div>
<div v-if="linkRowFieldsInThisTable.length > 0">
<label class="control__label control__label--small">
{{ $t('fieldLookupSubForm.selectThroughFieldLabel') }}
</label>
<div class="control__elements">
<div class="control">
<Dropdown
v-model="values.through_field_id"
:class="{ 'dropdown--error': $v.values.through_field_id.$error }"
@hide="$v.values.through_field_id.$touch()"
@input="throughFieldSelected"
>
<DropdownItem
v-for="field in linkRowFieldsInThisTable"
:key="field.id"
:name="field.name"
:value="field.id"
:icon="field.icon"
></DropdownItem>
</Dropdown>
<div v-if="$v.values.through_field_id.$error" class="error">
{{ $t('error.requiredField') }}
</div>
</div>
<div v-if="loading" class="context--loading">
<div class="loading"></div>
</div>
<div v-else-if="fieldsInThroughTable.length > 0" class="control">
<label class="control__label control__label--small">
{{ $t('fieldLookupSubForm.selectTargetFieldLabel') }}
</label>
<Dropdown
v-model="values.target_field_id"
:class="{ 'dropdown--error': $v.values.target_field_id.$error }"
@hide="$v.values.target_field_id.$touch()"
>
<DropdownItem
v-for="field in fieldsInThroughTable"
:key="field.id"
:name="field.name"
:value="field.id"
:icon="field.icon"
></DropdownItem>
</Dropdown>
<div
v-if="values.through_field_id && $v.values.target_field_id.$error"
class="error"
>
{{ $t('error.requiredField') }}
</div>
</div>
<template v-if="values.target_field_id">
<FormulaTypeSubForms
:default-values="defaultValues"
:formula-type="targetFieldFormulaType"
:table="table"
>
</FormulaTypeSubForms>
</template>
<div v-if="errorFromServer" class="error formula-field__error">
{{ errorFromServer }}
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { required } from 'vuelidate/lib/validators'
import form from '@baserow/modules/core/mixins/form'
import fieldSubForm from '@baserow/modules/database/mixins/fieldSubForm'
import { notifyIf } from '@baserow/modules/core/utils/error'
import FieldService from '@baserow/modules/database/services/field'
import FormulaTypeSubForms from '@baserow/modules/database/components/formula/FormulaTypeSubForms'
export default {
name: 'FieldLookupSubForm',
components: {
FormulaTypeSubForms,
},
mixins: [form, fieldSubForm],
data() {
return {
allowedValues: ['through_field_id', 'target_field_id'],
values: {
through_field_id: null,
target_field_id: null,
},
loading: false,
errorFromServer: null,
fieldsInThroughTable: [],
}
},
computed: {
linkRowFieldsInThisTable() {
const fields = this.$store.getters['field/getAll']
return fields
.filter((f) => f.type === 'link_row')
.map((f) => {
const fieldType = this.$registry.get('field', f.type)
f.icon = fieldType.getIconClass()
return f
})
},
targetFieldFormulaType() {
if (this.values.target_field_id) {
const targetFieldIndex = this.fieldsInThroughTable.findIndex(
(f) => f.id === this.values.target_field_id
)
if (targetFieldIndex >= 0) {
const targetField = this.fieldsInThroughTable[targetFieldIndex]
return targetField.array_formula_type || targetField.type
}
}
return 'unknown'
},
},
watch: {
'defaultValues.through_field_id'() {
this.throughFieldSelected()
},
'values.through_field_id'() {
this.throughFieldSelected()
},
selectedField() {
this.throughFieldSelected()
},
},
created() {
this.throughFieldSelected()
},
validations: {
values: {
through_field_id: { required },
target_field_id: { required },
},
},
methods: {
async throughFieldSelected() {
if (!this.values.through_field_id) {
return
}
this.loading = true
this.fieldsInThroughTable = []
this.errorFromServer = null
try {
const selectedField = this.$store.getters['field/get'](
this.values.through_field_id
)
if (selectedField && selectedField.link_row_table) {
const { data } = await FieldService(this.$client).fetchAll(
selectedField.link_row_table
)
this.fieldsInThroughTable = data
.filter((f) => {
return this.$registry
.get('field', f.type)
.canBeReferencedByFormulaField()
})
.map((f) => {
const fieldType = this.$registry.get('field', f.type)
f.icon = fieldType.getIconClass()
return f
})
}
} catch (error) {
notifyIf(error, 'view')
}
this.loading = false
},
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
}
},
isValid() {
return (
form.methods.isValid().call(this) &&
this.linkRowFieldsInThisTable.length > 0
)
},
reset() {
form.methods.reset.call(this)
this.errorFromServer = null
},
},
}
</script>
<i18n>
{
"en": {
"fieldLookupSubForm": {
"noTable": "You need at least one link row field to create a lookup field.",
"selectThroughFieldLabel": "Select a link row field",
"selectTargetFieldLabel": "Select a field to lookup"
}
},
"fr": {
"fieldLookupSubForm": {
"noTable": "Vous devez créer au moins une autre table dans la même base de données pour pouvoir créer un lien.",
"selectThroughFieldLabel": "Sélectionnez le lien vers la table",
"selectTargetFieldLabel": "Sélectionnez le champ à rapporter"
}
}
}
</i18n>