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

Fix broken record selector after hidden data merge

This commit is contained in:
Jérémie Pardou 2024-10-10 13:58:41 +00:00 committed by Afonso Silva
parent d83c269b18
commit c22cf12c6d
5 changed files with 122 additions and 0 deletions
backend
src/baserow
contrib
builder/elements
integrations/local_baserow
core/services
test_utils/fixtures
tests/baserow/contrib/builder/elements

View file

@ -488,6 +488,35 @@ class RecordSelectorElementType(
"option_name_suffix",
]
def extract_formula_properties(
self, instance: Element, element_map: Dict[BaserowFormula, Element], **kwargs
) -> Dict[int, List[BaserowFormula]]:
"""
For the record selector we always need the `id` and the row name property.
"""
properties = super().extract_formula_properties(instance, element_map, **kwargs)
if instance.data_source_id and instance.data_source.service_id:
service = instance.data_source.service.specific
# We need the id for the element
id_property = service.get_type().get_id_property(service)
if id_property not in properties.setdefault(
instance.data_source.service_id, []
):
properties[instance.data_source.service_id].append(id_property)
primary_property = service.get_type().get_name_property(service)
if (
primary_property is not None
and primary_property not in properties[instance.data_source.service_id]
):
# And we also need at least the name that identifies the row
properties[instance.data_source.service_id].append(primary_property)
return properties
def import_context_addition(self, instance):
return {"data_source_id": instance.data_source_id}

View file

@ -696,6 +696,17 @@ class LocalBaserowListRowsUserServiceType(
):
pass
def get_name_property(self, service: ServiceSubClass) -> Optional[str]:
"""
Returns the primary field name.
"""
if service.table_id:
primary_field = service.table.field_set.filter(primary=True).first()
return getattr(primary_field, "db_column", None)
else:
return None
def import_path(self, path, id_mapping):
"""
Updates the field ids in the path.

View file

@ -300,6 +300,29 @@ class ListServiceTypeMixin:
returns_list = True
def get_id_property(self, service: Service) -> str:
"""
Returns the property name that contains the unique `ID` of a row for this
service.
:param service: the instance of the service.
:return: a string identifying the ID property name.
"""
# Sane default
return "id"
def get_name_property(self, service: Service) -> Optional[str]:
"""
We need the name of the records for some elements (like the record selector).
This method returns it depending on the service.
:param service: the instance of the service.
:return: a string identifying the name property name.
"""
return None
@abstractmethod
def get_record_names(
self,

View file

@ -10,6 +10,7 @@ from baserow.contrib.builder.elements.models import (
ImageElement,
InputTextElement,
LinkElement,
RecordSelectorElement,
RepeatElement,
TableElement,
TextElement,
@ -105,6 +106,16 @@ class ElementFixtures:
element = self.create_builder_element(RepeatElement, user, page, **kwargs)
return element
def create_builder_record_selector_element(self, user=None, page=None, **kwargs):
if "data_source" not in kwargs:
kwargs[
"data_source"
] = self.create_builder_local_baserow_list_rows_data_source(page=page)
element = self.create_builder_element(
RecordSelectorElement, user, page, **kwargs
)
return element
def create_builder_element(self, model_class, user=None, page=None, **kwargs):
if user is None:
user = self.create_user()

View file

@ -0,0 +1,48 @@
import pytest
from baserow.contrib.builder.elements.element_types import RecordSelectorElementType
@pytest.mark.django_db
def test_record_selector_element_extract_formula_properties(data_fixture):
user = data_fixture.create_user()
element_type = RecordSelectorElementType()
# If the record selector has no data source, then the formula properties are empty
element = data_fixture.create_builder_record_selector_element(data_source=None)
properties = element_type.extract_formula_properties(element, {})
assert properties == {}
# If the record selector has a data source *without* a table then the
# formula properties just include "id"
data_source = data_fixture.create_builder_local_baserow_list_rows_data_source()
element = data_fixture.create_builder_record_selector_element(
data_source=data_source
)
properties = element_type.extract_formula_properties(element, {})
assert properties == {element.data_source.service_id: ["id"]}
# If the record selector has a data source *with* a table that does not
# define a name property, then the formula properties just include "id"
table = data_fixture.create_database_table(user=user)
data_source = data_fixture.create_builder_local_baserow_list_rows_data_source(
table=table
)
element = data_fixture.create_builder_record_selector_element(
data_source=data_source
)
properties = element_type.extract_formula_properties(element, {})
assert properties == {data_source.service_id: ["id"]}
# If the record selector has a data source whose table defines a name property
# then the formula properties includes the "id" and the field name
table = data_fixture.create_database_table(user=user)
field = data_fixture.create_text_field(name="Name", table=table, primary=True)
data_source = data_fixture.create_builder_local_baserow_list_rows_data_source(
table=table
)
element = data_fixture.create_builder_record_selector_element(
data_source=data_source
)
properties = element_type.extract_formula_properties(element, {})
assert properties == {data_source.service_id: ["id", field.db_column]}