mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-04-11 07:51:20 +00:00
Merge branch '132-fix-the-table-x-not-found-in-the-store' into 'develop'
Resolve "Fix "The table X not found in the store."" Closes #132 See merge request bramw/baserow!91
This commit is contained in:
commit
97a8d90045
8 changed files with 85 additions and 31 deletions
backend
src/baserow/contrib/database/fields
tests/baserow/contrib/database/field
web-frontend/modules
core/components
database
|
@ -245,7 +245,10 @@ class LinkRowFieldType(FieldType):
|
|||
model_class = LinkRowField
|
||||
allowed_fields = ['link_row_table', 'link_row_related_field',
|
||||
'link_row_relation_id']
|
||||
serializer_field_names = ['link_row_table']
|
||||
serializer_field_names = ['link_row_table', 'link_row_related_field']
|
||||
serializer_field_overrides = {
|
||||
'link_row_related_field': serializers.PrimaryKeyRelatedField(read_only=True)
|
||||
}
|
||||
api_exceptions_map = {
|
||||
LinkRowTableNotProvided: ERROR_LINK_ROW_TABLE_NOT_PROVIDED,
|
||||
LinkRowTableNotInSameDatabase: ERROR_LINK_ROW_TABLE_NOT_IN_SAME_DATABASE
|
||||
|
|
|
@ -426,7 +426,10 @@ def test_link_row_field_type_api_views(api_client, data_fixture):
|
|||
{
|
||||
'name': 'Link 1',
|
||||
'type': 'link_row',
|
||||
'link_row_table': customers_table.id
|
||||
'link_row_table': customers_table.id,
|
||||
# The `link_row_related_field` is a read_only field so we deliberately set
|
||||
# an unknown id to see if it is ignored.
|
||||
'link_row_related_field': 999999,
|
||||
},
|
||||
format='json',
|
||||
HTTP_AUTHORIZATION=f'JWT {token}'
|
||||
|
@ -442,6 +445,9 @@ def test_link_row_field_type_api_views(api_client, data_fixture):
|
|||
field = LinkRowField.objects.all().order_by('id').first()
|
||||
related_field = LinkRowField.objects.all().order_by('id').last()
|
||||
|
||||
assert response_json['link_row_related_field'] == related_field.id
|
||||
assert response_json['link_row_related_field'] != 999999
|
||||
|
||||
# Check if the correct fields are correctly linked.
|
||||
assert field.table.id == table.id
|
||||
assert field.link_row_table.id == customers_table.id
|
||||
|
@ -459,6 +465,7 @@ def test_link_row_field_type_api_views(api_client, data_fixture):
|
|||
assert response_json['name'] == 'Link 1'
|
||||
assert response_json['type'] == 'link_row'
|
||||
assert response_json['link_row_table'] == customers_table.id
|
||||
assert response_json['link_row_related_field'] == related_field.id
|
||||
|
||||
# Just fetching the related field and check if is has the correct values.
|
||||
response = api_client.get(
|
||||
|
@ -469,6 +476,7 @@ def test_link_row_field_type_api_views(api_client, data_fixture):
|
|||
assert response.status_code == HTTP_200_OK
|
||||
assert response_json['name'] == 'Example'
|
||||
assert response_json['link_row_table'] == table.id
|
||||
assert response_json['link_row_related_field'] == field.id
|
||||
|
||||
# Only updating the name of the field without changing anything else
|
||||
response = api_client.patch(
|
||||
|
@ -482,8 +490,23 @@ def test_link_row_field_type_api_views(api_client, data_fixture):
|
|||
assert response_json['name'] == 'Link new name'
|
||||
assert response_json['type'] == 'link_row'
|
||||
assert response_json['link_row_table'] == customers_table.id
|
||||
assert response_json['link_row_related_field'] == related_field.id
|
||||
|
||||
# Only try to update the link_row_related_field, but this is a read only field so
|
||||
# nothing should happen.
|
||||
response = api_client.patch(
|
||||
reverse('api:database:fields:item', kwargs={'field_id': field_id}),
|
||||
{'link_row_related_field': 9999},
|
||||
format='json',
|
||||
HTTP_AUTHORIZATION=f'JWT {token}'
|
||||
)
|
||||
response_json = response.json()
|
||||
assert response.status_code == HTTP_200_OK
|
||||
assert response_json['name'] == 'Link new name'
|
||||
assert response_json['type'] == 'link_row'
|
||||
assert response_json['link_row_table'] == customers_table.id
|
||||
assert response_json['link_row_related_field'] == related_field.id
|
||||
|
||||
# Only updating the name of the field without changing anything else
|
||||
response = api_client.patch(
|
||||
reverse('api:database:fields:item', kwargs={'field_id': field_id}),
|
||||
{'link_row_table': cars_table.id},
|
||||
|
@ -495,6 +518,7 @@ def test_link_row_field_type_api_views(api_client, data_fixture):
|
|||
assert response_json['name'] == 'Link new name'
|
||||
assert response_json['type'] == 'link_row'
|
||||
assert response_json['link_row_table'] == cars_table.id
|
||||
assert response_json['link_row_related_field'] == related_field.id
|
||||
|
||||
field.refresh_from_db()
|
||||
related_field.refresh_from_db()
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
|
||||
* Prevent adding a new line to the long text field in the grid view when selecting the
|
||||
cell by pressing the enter key.
|
||||
* Fixed The table X is not found in the store error.
|
||||
* Fixed bug where the selected name of the dropdown was not updated when that name was
|
||||
changed.
|
||||
* Fixed bug where the link row field is not removed from the store when the related
|
||||
table is deleted.
|
||||
|
||||
## Released (2020-09-02)
|
||||
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
<a class="dropdown__selected" @click="show()">
|
||||
<template v-if="hasValue()">
|
||||
<i
|
||||
v-if="icon"
|
||||
v-if="selectedIcon"
|
||||
class="dropdown__selected-icon fas"
|
||||
:class="'fa-' + icon"
|
||||
:class="'fa-' + selectedIcon"
|
||||
></i>
|
||||
{{ name }}
|
||||
{{ selectedName }}
|
||||
</template>
|
||||
<template v-if="!hasValue()">
|
||||
Make a choice
|
||||
|
@ -51,6 +51,14 @@ export default {
|
|||
default: 'Search',
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
selectedName() {
|
||||
return this.getSelectedProperty(this.value, 'name')
|
||||
},
|
||||
selectedIcon() {
|
||||
return this.getSelectedProperty(this.value, 'icon')
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
open: false,
|
||||
|
@ -59,23 +67,6 @@ export default {
|
|||
query: '',
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
/**
|
||||
* If the value changes we have to update the visible name and icon.
|
||||
*/
|
||||
value(newValue) {
|
||||
this.setDisplayValue(newValue)
|
||||
},
|
||||
},
|
||||
/**
|
||||
* When the dropdown first loads we have to check if there already is a value, if
|
||||
* there is, we have to update the displayed name and icon.
|
||||
*/
|
||||
mounted() {
|
||||
if (this.hasValue()) {
|
||||
this.setDisplayValue(this.value)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* Returns true if there is a value.
|
||||
|
@ -141,15 +132,17 @@ export default {
|
|||
})
|
||||
},
|
||||
/**
|
||||
* Changes the selected name and icon of the dropdown based on the provided value.
|
||||
* Loops over all children to see if any of the values match with given value. If
|
||||
* so the requested property of the child is returned
|
||||
*/
|
||||
setDisplayValue(value) {
|
||||
this.$children.forEach((item) => {
|
||||
getSelectedProperty(value, property) {
|
||||
for (const i in this.$children) {
|
||||
const item = this.$children[i]
|
||||
if (item.value === value) {
|
||||
this.name = item.name
|
||||
this.icon = item.icon
|
||||
return item[property]
|
||||
}
|
||||
})
|
||||
}
|
||||
return ''
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
throw new Error(`The table ${tableId} is not found in the store.`)
|
||||
return []
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
|
|
@ -151,6 +151,13 @@ export class FieldType extends Registerable {
|
|||
prepareValueForUpdate(field, value) {
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
* A hook that is called when a table is deleted. Some fields depend on other tables
|
||||
* than the table that they belong to. So action might be required when that table
|
||||
* is deleted.
|
||||
*/
|
||||
tableDeleted(context, field, table, database) {}
|
||||
}
|
||||
|
||||
export class TextFieldType extends FieldType {
|
||||
|
@ -257,6 +264,17 @@ export class LinkRowFieldType extends FieldType {
|
|||
prepareValueForUpdate(field, value) {
|
||||
return value.map((item) => (typeof item === 'object' ? item.id : item))
|
||||
}
|
||||
|
||||
/**
|
||||
* When a table is deleted it might be the case that this is the related table of
|
||||
* the field. If so it means that this field has already been deleted and it needs
|
||||
* to be removed from the store without making an API call.
|
||||
*/
|
||||
tableDeleted({ dispatch }, field, table, database) {
|
||||
if (field.link_row_table === table.id) {
|
||||
dispatch('field/forceDelete', field, { root: true })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class NumberFieldType extends FieldType {
|
||||
|
|
|
@ -203,6 +203,9 @@ export const getters = {
|
|||
get: (state) => (id) => {
|
||||
return state.items.find((item) => item.id === id)
|
||||
},
|
||||
getAll(state) {
|
||||
return state.items
|
||||
},
|
||||
}
|
||||
|
||||
export default {
|
||||
|
|
|
@ -98,7 +98,15 @@ export const actions = {
|
|||
* Delete the table from the store only. It will not send a request for deleting
|
||||
* to the server.
|
||||
*/
|
||||
forceDelete({ commit, dispatch }, { database, table }) {
|
||||
forceDelete(context, { database, table }) {
|
||||
const { commit, rootGetters } = context
|
||||
|
||||
// Call the table deleted event on all fields.
|
||||
rootGetters['field/getAll'].forEach((field) => {
|
||||
const fieldType = this.$registry.get('field', field.type)
|
||||
fieldType.tableDeleted(context, field, table, database)
|
||||
})
|
||||
|
||||
if (table._.selected) {
|
||||
// Redirect back to the dashboard because the table doesn't exist anymore.
|
||||
this.$router.push({ name: 'dashboard' })
|
||||
|
|
Loading…
Add table
Reference in a new issue