1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-04-04 21:25:24 +00:00

Merge branch '3448-multiple-collaborator-group-by-support' into 'develop'

Multiple collaborators field group by support

Closes 

See merge request 
This commit is contained in:
Bram Wiepjes 2025-03-10 17:04:03 +00:00
commit 85ec619869
5 changed files with 206 additions and 2 deletions
backend
src/baserow/contrib/database/fields
tests/baserow/contrib/database
changelog/entries/unreleased/feature
web-frontend/modules/database

View file

@ -6008,7 +6008,10 @@ class LookupFieldType(FormulaFieldType):
class MultipleCollaboratorsFieldType(
CollationSortMixin, ManyToManyFieldTypeSerializeToInputValueMixin, FieldType
CollationSortMixin,
ManyToManyFieldTypeSerializeToInputValueMixin,
ManyToManyGroupByMixin,
FieldType,
):
type = "multiple_collaborators"
model_class = MultipleCollaboratorsField
@ -6024,6 +6027,7 @@ class MultipleCollaboratorsFieldType(
"notify_user_when_added": serializers.BooleanField(required=False),
}
is_many_to_many_field = True
_can_group_by = True
def get_serializer_field(self, instance, **kwargs):
required = kwargs.pop("required", False)

View file

@ -65,7 +65,8 @@ def test_serialize_group_by_metadata(api_client, data_fixture):
@pytest.mark.django_db
def test_serialize_group_by_metadata_on_all_fields_in_interesting_table(data_fixture):
table, *_ = setup_interesting_test_table(data_fixture)
table, _, _, _, context = setup_interesting_test_table(data_fixture)
user2, user3 = context["user2"], context["user3"]
model = table.get_model()
queryset = model.objects.all()
rows = list(queryset)
@ -284,6 +285,14 @@ def test_serialize_group_by_metadata_on_all_fields_in_interesting_table(data_fix
{"field_decimal_link_row": [], "count": 1},
{"field_decimal_link_row": [1, 2, 3], "count": 1},
],
"multiple_collaborators_link_row": [
{"field_multiple_collaborators_link_row": [], "count": 1},
{"field_multiple_collaborators_link_row": [1, 2], "count": 1},
],
"multiple_collaborators": [
{"field_multiple_collaborators": [], "count": 1},
{"field_multiple_collaborators": [user2.id, user3.id], "count": 1},
],
}
for key, actual_value in actual_result_per_field_name.items():
expected_value = expected_result.get(key, None)

View file

@ -5,9 +5,11 @@ from django.apps.registry import apps
from django.contrib.auth import get_user_model
from django.db import connection
from django.test.utils import CaptureQueriesContext
from django.urls import reverse
import pytest
from faker import Faker
from pytest_unordered import unordered
from baserow.contrib.database.fields.field_types import MultipleCollaboratorsFieldType
from baserow.contrib.database.fields.handler import FieldHandler
@ -937,3 +939,164 @@ def test_multiple_collaborators_formula_field_cache_users_query(data_fixture):
export_row(row)
assert len(queries_for_all_others.captured_queries) == 0
@pytest.mark.django_db
def test_get_group_by_metadata_in_rows_with_multiple_collaborators_field(data_fixture):
user = data_fixture.create_user(first_name="A")
user_2 = data_fixture.create_user(first_name="B")
workspace = data_fixture.create_workspace(members=[user, user_2])
database = data_fixture.create_database_application(workspace=workspace)
table = data_fixture.create_database_table(database=database)
text_field = data_fixture.create_text_field(
table=table, order=0, name="Color", text_default="white"
)
multiple_collaborators_field = data_fixture.create_multiple_collaborators_field(
table=table
)
RowHandler().force_create_rows(
user=user,
table=table,
rows_values=[
{
f"field_{text_field.id}": "Row 1",
f"field_{multiple_collaborators_field.id}": [],
},
{
f"field_{text_field.id}": "Row 2",
f"field_{multiple_collaborators_field.id}": [],
},
{
f"field_{text_field.id}": "Row 3",
f"field_{multiple_collaborators_field.id}": [{"id": user.id}],
},
{
f"field_{text_field.id}": "Row 4",
f"field_{multiple_collaborators_field.id}": [{"id": user.id}],
},
{
f"field_{text_field.id}": "Row 5",
f"field_{multiple_collaborators_field.id}": [{"id": user_2.id}],
},
{
f"field_{text_field.id}": "Row 6",
f"field_{multiple_collaborators_field.id}": [{"id": user_2.id}],
},
{
f"field_{text_field.id}": "Row 7",
f"field_{multiple_collaborators_field.id}": [
{"id": user.id},
{"id": user_2.id},
],
},
{
f"field_{text_field.id}": "Row 8",
f"field_{multiple_collaborators_field.id}": [
{"id": user.id},
{"id": user_2.id},
],
},
{
f"field_{text_field.id}": "Row 9",
f"field_{multiple_collaborators_field.id}": [
{"id": user_2.id},
{"id": user.id},
],
},
],
)
model = table.get_model()
queryset = model.objects.all().enhance_by_fields()
rows = list(queryset)
handler = ViewHandler()
counts = handler.get_group_by_metadata_in_rows(
[multiple_collaborators_field], rows, queryset
)
# Resolve the queryset, so that we can do a comparison.
for c in counts.keys():
counts[c] = list(counts[c])
assert counts == {
multiple_collaborators_field: unordered(
[
{"count": 2, f"field_{multiple_collaborators_field.id}": []},
{
"count": 2,
f"field_{multiple_collaborators_field.id}": [user.id],
},
{
"count": 2,
f"field_{multiple_collaborators_field.id}": [
user.id,
user_2.id,
],
},
{
"count": 2,
f"field_{multiple_collaborators_field.id}": [user_2.id],
},
{
"count": 1,
f"field_{multiple_collaborators_field.id}": [
user_2.id,
user.id,
],
},
]
)
}
@pytest.mark.django_db
def test_list_rows_with_group_by_and_multiple_collaborators_field(
api_client, data_fixture
):
user, token = data_fixture.create_user_and_token(
email="test@test.nl", password="password", first_name="A"
)
user_2 = data_fixture.create_user(first_name="B")
user_3 = data_fixture.create_user(first_name="C")
workspace = data_fixture.create_workspace(members=[user, user_2, user_3])
database = data_fixture.create_database_application(workspace=workspace)
table = data_fixture.create_database_table(database=database)
multiple_collaborators_field = data_fixture.create_multiple_collaborators_field(
table=table
)
grid = data_fixture.create_grid_view(table=table)
data_fixture.create_view_group_by(view=grid, field=multiple_collaborators_field)
RowHandler().create_row(
user=user,
table=table,
values={
f"field_{multiple_collaborators_field.id}": [
{"id": user.id},
{"id": user_2.id},
{"id": user_3.id},
],
},
)
url = reverse("api:database:views:grid:list", kwargs={"view_id": grid.id})
response = api_client.get(url, **{"HTTP_AUTHORIZATION": f"JWT {token}"})
response_json = response.json()
assert response_json["group_by_metadata"] == {
f"field_{multiple_collaborators_field.id}": unordered(
[
{
f"field_{multiple_collaborators_field.id}": [
user.id,
user_2.id,
user_3.id,
],
"count": 1,
},
]
),
}

View file

@ -0,0 +1,7 @@
{
"type": "feature",
"message": "Multiple collaborator field group by support.",
"issue_number": 3447,
"bullet_points": [],
"created_at": "2025-02-25"
}

View file

@ -4335,6 +4335,27 @@ export class MultipleCollaboratorsFieldType extends FieldType {
canBeReferencedByFormulaField() {
return true
}
getCanGroupByInView(field) {
return true
}
getRowValueFromGroupValue(field, value) {
return value.map((optId) => {
return { id: optId }
})
}
getGroupValueFromRowValue(field, value) {
return value && value.map((o) => o.id)
}
isEqual(field, value1, value2) {
const value1Ids = value1.map((v) => v.id)
const value2Ids = value2.map((v) => v.id)
return _.isEqual(value1Ids, value2Ids)
}
}
export class UUIDFieldType extends FieldType {