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

Import Airtable gallery view

This commit is contained in:
Bram Wiepjes 2025-03-24 12:24:01 +00:00
parent f0cab56b9b
commit 421770ecf2
7 changed files with 480 additions and 25 deletions
backend
src/baserow/contrib/database
tests/baserow/contrib/database/airtable
changelog/entries/unreleased/feature

View file

@ -1,6 +1,22 @@
from typing import Optional
from baserow.contrib.database.airtable.constants import (
AIRTABLE_GALLERY_VIEW_COVER_CROP_TYPE,
)
from baserow.contrib.database.airtable.import_report import (
ERROR_TYPE_UNSUPPORTED_FEATURE,
SCOPE_VIEW,
AirtableImportReport,
)
from baserow.contrib.database.airtable.registry import AirtableViewType
from baserow.contrib.database.views.models import GridView, GridViewFieldOptions
from baserow.contrib.database.views.view_types import GridViewType
from baserow.contrib.database.fields.field_types import FileFieldType
from baserow.contrib.database.views.models import (
GalleryView,
GalleryViewFieldOptions,
GridView,
GridViewFieldOptions,
)
from baserow.contrib.database.views.view_types import GalleryViewType, GridViewType
from baserow.core.utils import get_value_at_path
@ -54,3 +70,113 @@ class GridAirtableViewType(AirtableViewType):
view.get_field_options = lambda *args, **kwargs: field_options
return view
class GalleryAirtableViewType(AirtableViewType):
type = "gallery"
baserow_view_type = GalleryViewType.type
def get_cover_column(
self,
field_mapping: dict,
view: GalleryView,
raw_airtable_table: dict,
raw_airtable_view_data: dict,
import_report: AirtableImportReport,
) -> Optional[str]:
"""
Checks if the chosen coverColumnId is set, if the field exist, and if the
field is compatible with the cover type Baserow. If all is True, it returns
the referenced field id.
"""
cover_column_id = get_value_at_path(
raw_airtable_view_data, "metadata.gallery.coverColumnId", None
)
if not cover_column_id:
return
cover_column = field_mapping.get(cover_column_id, None)
if cover_column is None:
import_report.add_failed(
view.name,
SCOPE_VIEW,
raw_airtable_table["name"],
ERROR_TYPE_UNSUPPORTED_FEATURE,
f'View "{view.name}" cover column with id '
f'"{cover_column_id}" is not found.',
)
return
if cover_column["baserow_field_type"].type != FileFieldType.type:
import_report.add_failed(
view.name,
SCOPE_VIEW,
raw_airtable_table["name"],
ERROR_TYPE_UNSUPPORTED_FEATURE,
f'View "{view.name}" cover column with id '
f'"{cover_column_id}" is not a file field.',
)
return
return cover_column_id
def prepare_view_object(
self,
field_mapping,
view: GalleryView,
raw_airtable_table,
raw_airtable_view,
raw_airtable_view_data,
config,
import_report,
):
cover_column_id = self.get_cover_column(
field_mapping,
view,
raw_airtable_table,
raw_airtable_view_data,
import_report,
)
view.card_cover_image_field_id = cover_column_id
cover_fit_type = get_value_at_path(
raw_airtable_view_data, "metadata.gallery.coverFitType", None
)
if (
cover_column_id
and cover_fit_type
and cover_fit_type != AIRTABLE_GALLERY_VIEW_COVER_CROP_TYPE
):
import_report.add_failed(
view.name,
SCOPE_VIEW,
raw_airtable_table["name"],
ERROR_TYPE_UNSUPPORTED_FEATURE,
f'View "{view.name}" cover fit type "{cover_fit_type}" is not '
f'supported, so it defaulted to "crop"',
)
# Map the columnOrder entries to the matching `GalleryViewFieldOptions`,
# and set that as `get_field_options`, so that it's correctly serialized
# exported.
field_options = []
column_orders = raw_airtable_view_data.get("columnOrder", None) or []
for index, column_order in enumerate(column_orders):
if column_order["columnId"] not in field_mapping:
continue
field_options.append(
GalleryViewFieldOptions(
id=f"{raw_airtable_view['id']}_columnOrder_{index}",
gallery_view_id=view.id,
field_id=column_order["columnId"],
hidden=not column_order.get("visibility", True),
order=index + 1,
)
)
view.get_field_options = lambda *args, **kwargs: field_options
return view

View file

@ -104,3 +104,4 @@ AIRTABLE_DATE_FILTER_VALUE_MAP = {
"tomorrow": "{timeZone}??tomorrow",
"yesterday": "{timeZone}??yesterday",
}
AIRTABLE_GALLERY_VIEW_COVER_CROP_TYPE = "crop"

View file

@ -19,6 +19,7 @@ from baserow.contrib.database.airtable.import_report import (
ERROR_TYPE_DATA_TYPE_MISMATCH,
ERROR_TYPE_UNSUPPORTED_FEATURE,
SCOPE_FIELD,
SCOPE_VIEW,
SCOPE_VIEW_COLOR,
SCOPE_VIEW_FILTER,
SCOPE_VIEW_GROUP_BY,
@ -681,6 +682,36 @@ class AirtableViewType(Instance):
else:
return []
def _check_personal_or_locked(
self,
view_name: str,
raw_airtable_view: dict,
raw_airtable_table: dict,
import_report: AirtableImportReport,
) -> str:
if raw_airtable_view.get("personalForUserId", ""):
import_report.add_failed(
view_name,
SCOPE_VIEW,
raw_airtable_table["name"],
ERROR_TYPE_UNSUPPORTED_FEATURE,
f'View "{view_name}" is personal, but was made collaborative because '
f"it can't be linked to a user. (Personal) was added to the name.",
)
view_name += " (Personal)"
if raw_airtable_view.get("lock", None):
import_report.add_failed(
view_name,
SCOPE_VIEW,
raw_airtable_table["name"],
ERROR_TYPE_UNSUPPORTED_FEATURE,
f'View "{view_name}" is locked, but was made collaborative because '
f"it Baserow does not support this yet.",
)
return view_name
def to_serialized_baserow_view(
self,
field_mapping,
@ -696,11 +727,16 @@ class AirtableViewType(Instance):
"The `baserow_view_type` must be implemented for the AirtableViewType."
)
view_name = raw_airtable_view["name"]
view_name = self._check_personal_or_locked(
view_name, raw_airtable_view, raw_airtable_table, import_report
)
view_type = view_type_registry.get(self.baserow_view_type)
view = view_type.model_class(
id=raw_airtable_view["id"],
pk=raw_airtable_view["id"],
name=raw_airtable_view["name"],
name=view_name,
order=raw_airtable_table["viewOrder"].index(raw_airtable_view["id"]) + 1,
)

View file

@ -652,9 +652,13 @@ class DatabaseConfig(AppConfig):
airtable_column_type_registry.register(CountAirtableColumnType())
airtable_column_type_registry.register(AutoNumberAirtableColumnType())
from .airtable.airtable_view_types import GridAirtableViewType
from .airtable.airtable_view_types import (
GalleryAirtableViewType,
GridAirtableViewType,
)
airtable_view_type_registry.register(GridAirtableViewType())
airtable_view_type_registry.register(GalleryAirtableViewType())
from .airtable.airtable_filter_operators import (
AirtableContainsOperator,

View file

@ -427,8 +427,8 @@ class GalleryViewType(ViewType):
serialized = super().export_serialized(gallery, cache, files_zip, storage)
if gallery.card_cover_image_field:
serialized["card_cover_image_field_id"] = gallery.card_cover_image_field.id
if gallery.card_cover_image_field_id:
serialized["card_cover_image_field_id"] = gallery.card_cover_image_field_id
serialized_field_options = []
for field_option in gallery.get_field_options():

View file

@ -6,14 +6,15 @@ import pytest
from baserow.contrib.database.airtable.config import AirtableImportConfig
from baserow.contrib.database.airtable.import_report import (
SCOPE_VIEW,
SCOPE_VIEW_COLOR,
SCOPE_VIEW_GROUP_BY,
SCOPE_VIEW_SORT,
AirtableImportReport,
)
from baserow.contrib.database.airtable.registry import airtable_view_type_registry
from baserow.contrib.database.fields.field_types import TextFieldType
from baserow.contrib.database.fields.models import TextField
from baserow.contrib.database.fields.field_types import FileFieldType, TextFieldType
from baserow.contrib.database.fields.models import FileField, TextField
RAW_AIRTABLE_VIEW = {
"id": "viwcpYeEpAs6kZspktV",
@ -62,7 +63,7 @@ FIELD_MAPPING = {
"airtable_column_type": None,
},
}
RAW_AIRTABLE_VIEW_DATA = {
RAW_AIRTABLE_GRID_VIEW_DATA = {
"id": "viwcpYeEpAs6kZspktV",
"frozenColumnCount": 1,
"columnOrder": [
@ -85,6 +86,29 @@ RAW_AIRTABLE_VIEW_DATA = {
{"rowId": "rec2O9BdjKJO6dgj6QF", "visibility": True},
],
}
RAW_AIRTABLE_GALLERY_VIEW_DATA = {
"id": "viwcpYeEpAs6kZspktV",
"frozenColumnCount": 1,
"columnOrder": [
{"columnId": "fldwSc9PqedIhTSqhi1", "visibility": True},
{"columnId": "fldwSc9PqedIhTSqhi2", "visibility": False},
],
"filters": None,
"lastSortsApplied": None,
"groupLevels": None,
"colorConfig": None,
"sharesById": {},
"metadata": {"gallery": {"coverColumnId": None, "coverFitType": "fit"}},
"description": None,
"createdByUserId": "usrdGm7k7NIVWhK7W7L",
"applicationTransactionNumber": 284,
"rowOrder": [
{"rowId": "recAAA5JwFXBk4swkfB", "visibility": True},
{"rowId": "rec9Imz1INvNXgRIXn1", "visibility": True},
{"rowId": "recyANUudYjDqIXdq9Z", "visibility": True},
{"rowId": "rec2O9BdjKJO6dgj6QF", "visibility": True},
],
}
RAW_VIEW_DATA_FILTERS = {
"filterSet": [
{
@ -199,7 +223,7 @@ def test_import_grid_view():
ROW_ID_MAPPING,
RAW_AIRTABLE_TABLE,
RAW_AIRTABLE_VIEW,
RAW_AIRTABLE_VIEW_DATA,
RAW_AIRTABLE_GRID_VIEW_DATA,
AirtableImportConfig(),
AirtableImportReport(),
)
@ -244,8 +268,67 @@ def test_import_grid_view():
}
def test_import_personal_view():
raw_airtable_table = deepcopy(RAW_AIRTABLE_TABLE)
raw_airtable_table["views"][0]["personalForUserId"] = "usr1234"
raw_airtable_view = raw_airtable_table["views"][0]
airtable_view_type = airtable_view_type_registry.get("grid")
import_report = AirtableImportReport()
serialized_view = airtable_view_type.to_serialized_baserow_view(
FIELD_MAPPING,
ROW_ID_MAPPING,
raw_airtable_table,
raw_airtable_view,
RAW_AIRTABLE_GRID_VIEW_DATA,
AirtableImportConfig(),
import_report,
)
assert len(import_report.items) == 1
assert import_report.items[0].object_name == "Grid view"
assert import_report.items[0].scope == SCOPE_VIEW
assert import_report.items[0].table == "Data"
assert serialized_view["name"] == "Grid view (Personal)"
def test_import_locked_view():
raw_airtable_table = deepcopy(RAW_AIRTABLE_TABLE)
raw_airtable_table["views"][0]["lock"] = {
"lockLevelToEditViewName": "locked",
"lockLevelToEditViewDescription": "locked",
"lockLevelToEditViewLayout": "locked",
"lockLevelToEditViewConfig": "locked",
"lockLevelToCreateShareLink": "locked",
"lockLevelToDestroyView": "locked",
"allowFormSubmitterToIgnoreLockLevel": False,
"shouldWorkflowsRespectLockLevel": False,
"userId": "usripyu12348WK3n",
"description": None,
}
raw_airtable_view = raw_airtable_table["views"][0]
import_report = AirtableImportReport()
airtable_view_type = airtable_view_type_registry.get("grid")
serialized_view = airtable_view_type.to_serialized_baserow_view(
FIELD_MAPPING,
ROW_ID_MAPPING,
raw_airtable_table,
raw_airtable_view,
RAW_AIRTABLE_GRID_VIEW_DATA,
AirtableImportConfig(),
import_report,
)
assert len(import_report.items) == 1
assert import_report.items[0].object_name == "Grid view"
assert import_report.items[0].scope == SCOPE_VIEW
assert import_report.items[0].table == "Data"
assert serialized_view["name"] == "Grid view"
def test_import_grid_view_xlarge_row_height():
view_data = deepcopy(RAW_AIRTABLE_VIEW_DATA)
view_data = deepcopy(RAW_AIRTABLE_GRID_VIEW_DATA)
view_data["metadata"]["grid"]["rowHeight"] = "xlarge"
airtable_view_type = airtable_view_type_registry.get("grid")
@ -263,7 +346,7 @@ def test_import_grid_view_xlarge_row_height():
def test_import_grid_view_unknown_row_height():
view_data = deepcopy(RAW_AIRTABLE_VIEW_DATA)
view_data = deepcopy(RAW_AIRTABLE_GRID_VIEW_DATA)
view_data["metadata"]["grid"]["rowHeight"] = "unknown"
airtable_view_type = airtable_view_type_registry.get("grid")
@ -281,7 +364,7 @@ def test_import_grid_view_unknown_row_height():
def test_import_grid_view_sorts():
view_data = deepcopy(RAW_AIRTABLE_VIEW_DATA)
view_data = deepcopy(RAW_AIRTABLE_GRID_VIEW_DATA)
view_data["lastSortsApplied"] = RAW_VIEW_DATA_SORTS
airtable_view_type = airtable_view_type_registry.get("grid")
serialized_view = airtable_view_type.to_serialized_baserow_view(
@ -314,7 +397,7 @@ def test_import_grid_view_sorts():
def test_import_grid_view_sort_field_not_found():
view_data = deepcopy(RAW_AIRTABLE_VIEW_DATA)
view_data = deepcopy(RAW_AIRTABLE_GRID_VIEW_DATA)
view_data["lastSortsApplied"] = RAW_VIEW_DATA_SORTS
airtable_view_type = airtable_view_type_registry.get("grid")
import_report = AirtableImportReport()
@ -338,7 +421,7 @@ def test_import_grid_view_sort_field_not_found():
def test_import_grid_view_sort_field_unsupported():
view_data = deepcopy(RAW_AIRTABLE_VIEW_DATA)
view_data = deepcopy(RAW_AIRTABLE_GRID_VIEW_DATA)
field_mapping = deepcopy(FIELD_MAPPING)
field_mapping["fldwSc9PqedIhTSqhi1"]["baserow_field_type"]._can_order_by_types = []
@ -365,7 +448,7 @@ def test_import_grid_view_sort_field_unsupported():
def test_import_grid_view_group_bys():
view_data = deepcopy(RAW_AIRTABLE_VIEW_DATA)
view_data = deepcopy(RAW_AIRTABLE_GRID_VIEW_DATA)
view_data["groupLevels"] = RAW_VIEW_DATA_GROUPS
airtable_view_type = airtable_view_type_registry.get("grid")
serialized_view = airtable_view_type.to_serialized_baserow_view(
@ -398,7 +481,7 @@ def test_import_grid_view_group_bys():
def test_import_grid_view_group_by_field_not_found():
view_data = deepcopy(RAW_AIRTABLE_VIEW_DATA)
view_data = deepcopy(RAW_AIRTABLE_GRID_VIEW_DATA)
view_data["groupLevels"] = RAW_VIEW_DATA_GROUPS
airtable_view_type = airtable_view_type_registry.get("grid")
import_report = AirtableImportReport()
@ -422,7 +505,7 @@ def test_import_grid_view_group_by_field_not_found():
def test_import_grid_view_group_by_field_unsupported():
view_data = deepcopy(RAW_AIRTABLE_VIEW_DATA)
view_data = deepcopy(RAW_AIRTABLE_GRID_VIEW_DATA)
field_mapping = deepcopy(FIELD_MAPPING)
field_mapping["fldwSc9PqedIhTSqhi1"]["baserow_field_type"]._can_group_by = False
@ -449,7 +532,7 @@ def test_import_grid_view_group_by_field_unsupported():
def test_import_grid_view_group_by_order_unsupported():
view_data = deepcopy(RAW_AIRTABLE_VIEW_DATA)
view_data = deepcopy(RAW_AIRTABLE_GRID_VIEW_DATA)
field_mapping = deepcopy(FIELD_MAPPING)
view_data["groupLevels"] = RAW_VIEW_DATA_GROUPS
airtable_view_type = airtable_view_type_registry.get("grid")
@ -476,7 +559,7 @@ def test_import_grid_view_group_by_order_unsupported():
def test_import_grid_view_field_order_and_visibility():
view_data = deepcopy(RAW_AIRTABLE_VIEW_DATA)
view_data = deepcopy(RAW_AIRTABLE_GRID_VIEW_DATA)
field_mapping = deepcopy(FIELD_MAPPING)
airtable_view_type = airtable_view_type_registry.get("grid")
@ -515,7 +598,7 @@ def test_import_grid_view_field_order_and_visibility():
@pytest.mark.django_db
def test_import_grid_view_filters_and_groups():
view_data = deepcopy(RAW_AIRTABLE_VIEW_DATA)
view_data = deepcopy(RAW_AIRTABLE_GRID_VIEW_DATA)
field_mapping = deepcopy(FIELD_MAPPING)
for field_object in field_mapping.values():
field_object["baserow_field"].content_type = ContentType.objects.get_for_model(
@ -569,7 +652,7 @@ def test_import_grid_view_filters_and_groups():
@pytest.mark.django_db
def test_import_grid_view_empty_filters():
view_data = deepcopy(RAW_AIRTABLE_VIEW_DATA)
view_data = deepcopy(RAW_AIRTABLE_GRID_VIEW_DATA)
field_mapping = deepcopy(FIELD_MAPPING)
for field_object in field_mapping.values():
field_object["baserow_field"].content_type = ContentType.objects.get_for_model(
@ -598,7 +681,7 @@ def test_import_grid_view_empty_filters():
@pytest.mark.django_db
def test_import_grid_view_color_config_select_column_not_existing_column():
view_data = deepcopy(RAW_AIRTABLE_VIEW_DATA)
view_data = deepcopy(RAW_AIRTABLE_GRID_VIEW_DATA)
field_mapping = deepcopy(FIELD_MAPPING)
for field_object in field_mapping.values():
field_object["baserow_field"].content_type = ContentType.objects.get_for_model(
@ -627,7 +710,7 @@ def test_import_grid_view_color_config_select_column_not_existing_column():
@pytest.mark.django_db
def test_import_grid_view_color_config_select_column():
view_data = deepcopy(RAW_AIRTABLE_VIEW_DATA)
view_data = deepcopy(RAW_AIRTABLE_GRID_VIEW_DATA)
field_mapping = deepcopy(FIELD_MAPPING)
for field_object in field_mapping.values():
field_object["baserow_field"].content_type = ContentType.objects.get_for_model(
@ -662,7 +745,7 @@ def test_import_grid_view_color_config_select_column():
@pytest.mark.django_db
def test_import_grid_view_color_config_color_definitions():
view_data = deepcopy(RAW_AIRTABLE_VIEW_DATA)
view_data = deepcopy(RAW_AIRTABLE_GRID_VIEW_DATA)
field_mapping = deepcopy(FIELD_MAPPING)
for field_object in field_mapping.values():
field_object["baserow_field"].content_type = ContentType.objects.get_for_model(
@ -748,3 +831,200 @@ def test_import_grid_view_color_config_color_definitions():
"order": 1,
}
]
def test_import_gallery_view():
view_data = deepcopy(RAW_AIRTABLE_GALLERY_VIEW_DATA)
field_mapping = deepcopy(FIELD_MAPPING)
airtable_view_type = airtable_view_type_registry.get("gallery")
raw_airtable_view = deepcopy(RAW_AIRTABLE_VIEW)
raw_airtable_view["name"] = "Gallery view"
raw_airtable_view["type"] = "gallery"
import_report = AirtableImportReport()
serialized_view = airtable_view_type.to_serialized_baserow_view(
field_mapping,
ROW_ID_MAPPING,
RAW_AIRTABLE_TABLE,
raw_airtable_view,
view_data,
AirtableImportConfig(),
import_report,
)
assert len(import_report.items) == 0
assert serialized_view == {
"id": "viwcpYeEpAs6kZspktV",
"type": "gallery",
"name": "Gallery view",
"order": 1,
"ownership_type": "collaborative",
"owned_by": None,
"filter_type": "AND",
"filters_disabled": False,
"filters": [],
"filter_groups": [],
"sortings": [],
"decorations": [],
"public": False,
"field_options": [
{
"id": "viwcpYeEpAs6kZspktV_columnOrder_0",
"field_id": "fldwSc9PqedIhTSqhi1",
"hidden": False,
"order": 1,
},
{
"id": "viwcpYeEpAs6kZspktV_columnOrder_1",
"field_id": "fldwSc9PqedIhTSqhi2",
"hidden": True,
"order": 2,
},
],
}
def test_import_gallery_view_with_cover_column():
airtable_view_type = airtable_view_type_registry.get("gallery")
view_data = deepcopy(RAW_AIRTABLE_GALLERY_VIEW_DATA)
view_data["metadata"]["gallery"]["coverColumnId"] = "fldwSc9PqedIhTSqhi3"
view_data["metadata"]["gallery"]["coverFitType"] = "crop"
raw_airtable_view = deepcopy(RAW_AIRTABLE_VIEW)
raw_airtable_view["name"] = "Gallery view"
raw_airtable_view["type"] = "gallery"
raw_airtable_table = deepcopy(RAW_AIRTABLE_TABLE)
raw_airtable_table["columns"].append(
{"id": "fldwSc9PqedIhTSqhi3", "name": "File", "type": "multipleAttachment"},
)
field_mapping = deepcopy(FIELD_MAPPING)
field_mapping["fldwSc9PqedIhTSqhi3"] = {
"baserow_field": FileField(
id="fldwSc9PqedIhTSqhi3", pk="fldwSc9PqedIhTSqhi3", name="File"
),
"baserow_field_type": FileFieldType(),
"raw_airtable_column": raw_airtable_table["columns"][2],
"airtable_column_type": None,
}
import_report = AirtableImportReport()
serialized_view = airtable_view_type.to_serialized_baserow_view(
field_mapping,
ROW_ID_MAPPING,
raw_airtable_table,
raw_airtable_view,
view_data,
AirtableImportConfig(),
import_report,
)
assert len(import_report.items) == 0
assert serialized_view["card_cover_image_field_id"] == "fldwSc9PqedIhTSqhi3"
def test_import_gallery_view_with_unknown_cover_column():
airtable_view_type = airtable_view_type_registry.get("gallery")
view_data = deepcopy(RAW_AIRTABLE_GALLERY_VIEW_DATA)
view_data["metadata"]["gallery"]["coverColumnId"] = "fldwSc9PqedIhTSqhi3"
raw_airtable_view = deepcopy(RAW_AIRTABLE_VIEW)
raw_airtable_view["name"] = "Gallery view"
raw_airtable_view["type"] = "gallery"
raw_airtable_table = deepcopy(RAW_AIRTABLE_TABLE)
import_report = AirtableImportReport()
serialized_view = airtable_view_type.to_serialized_baserow_view(
FIELD_MAPPING,
ROW_ID_MAPPING,
raw_airtable_table,
raw_airtable_view,
view_data,
AirtableImportConfig(),
import_report,
)
assert "card_cover_image_field_id" not in serialized_view
assert len(import_report.items) == 1
assert import_report.items[0].object_name == "Gallery view"
assert import_report.items[0].scope == SCOPE_VIEW
assert import_report.items[0].table == "Data"
def test_import_gallery_view_with_incompatible_cover_column():
airtable_view_type = airtable_view_type_registry.get("gallery")
view_data = deepcopy(RAW_AIRTABLE_GALLERY_VIEW_DATA)
view_data["metadata"]["gallery"]["coverColumnId"] = "fldwSc9PqedIhTSqhi2"
raw_airtable_view = deepcopy(RAW_AIRTABLE_VIEW)
raw_airtable_view["name"] = "Gallery view"
raw_airtable_view["type"] = "gallery"
raw_airtable_table = deepcopy(RAW_AIRTABLE_TABLE)
import_report = AirtableImportReport()
serialized_view = airtable_view_type.to_serialized_baserow_view(
FIELD_MAPPING,
ROW_ID_MAPPING,
raw_airtable_table,
raw_airtable_view,
view_data,
AirtableImportConfig(),
import_report,
)
assert "card_cover_image_field_id" not in serialized_view
assert len(import_report.items) == 1
assert import_report.items[0].object_name == "Gallery view"
assert import_report.items[0].scope == SCOPE_VIEW
assert import_report.items[0].table == "Data"
def test_import_gallery_view_with_cover_column_type_fit():
airtable_view_type = airtable_view_type_registry.get("gallery")
view_data = deepcopy(RAW_AIRTABLE_GALLERY_VIEW_DATA)
view_data["metadata"]["gallery"]["coverColumnId"] = "fldwSc9PqedIhTSqhi3"
view_data["metadata"]["gallery"]["coverFitType"] = "fit"
raw_airtable_view = deepcopy(RAW_AIRTABLE_VIEW)
raw_airtable_view["name"] = "Gallery view"
raw_airtable_view["type"] = "gallery"
raw_airtable_table = deepcopy(RAW_AIRTABLE_TABLE)
raw_airtable_table["columns"].append(
{"id": "fldwSc9PqedIhTSqhi3", "name": "File", "type": "multipleAttachment"},
)
field_mapping = deepcopy(FIELD_MAPPING)
field_mapping["fldwSc9PqedIhTSqhi3"] = {
"baserow_field": FileField(
id="fldwSc9PqedIhTSqhi3", pk="fldwSc9PqedIhTSqhi3", name="File"
),
"baserow_field_type": FileFieldType(),
"raw_airtable_column": raw_airtable_table["columns"][2],
"airtable_column_type": None,
}
import_report = AirtableImportReport()
serialized_view = airtable_view_type.to_serialized_baserow_view(
field_mapping,
ROW_ID_MAPPING,
raw_airtable_table,
raw_airtable_view,
view_data,
AirtableImportConfig(),
import_report,
)
assert len(import_report.items) == 1
assert import_report.items[0].object_name == "Gallery view"
assert import_report.items[0].scope == SCOPE_VIEW
assert import_report.items[0].table == "Data"
assert serialized_view["card_cover_image_field_id"] == "fldwSc9PqedIhTSqhi3"

View file

@ -0,0 +1,8 @@
{
"type": "feature",
"message": "Import Airtable gallery view.",
"domain": "database",
"issue_number": 793,
"bullet_points": [],
"created_at": "2025-03-17"
}