mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-04-14 09:08:32 +00:00
Merge branch '3448-multiple-collaborator-group-by-support' into 'develop'
Multiple collaborators field group by support Closes #3448 See merge request baserow/baserow!3181
This commit is contained in:
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
|
@ -6008,7 +6008,10 @@ class LookupFieldType(FormulaFieldType):
|
||||||
|
|
||||||
|
|
||||||
class MultipleCollaboratorsFieldType(
|
class MultipleCollaboratorsFieldType(
|
||||||
CollationSortMixin, ManyToManyFieldTypeSerializeToInputValueMixin, FieldType
|
CollationSortMixin,
|
||||||
|
ManyToManyFieldTypeSerializeToInputValueMixin,
|
||||||
|
ManyToManyGroupByMixin,
|
||||||
|
FieldType,
|
||||||
):
|
):
|
||||||
type = "multiple_collaborators"
|
type = "multiple_collaborators"
|
||||||
model_class = MultipleCollaboratorsField
|
model_class = MultipleCollaboratorsField
|
||||||
|
@ -6024,6 +6027,7 @@ class MultipleCollaboratorsFieldType(
|
||||||
"notify_user_when_added": serializers.BooleanField(required=False),
|
"notify_user_when_added": serializers.BooleanField(required=False),
|
||||||
}
|
}
|
||||||
is_many_to_many_field = True
|
is_many_to_many_field = True
|
||||||
|
_can_group_by = True
|
||||||
|
|
||||||
def get_serializer_field(self, instance, **kwargs):
|
def get_serializer_field(self, instance, **kwargs):
|
||||||
required = kwargs.pop("required", False)
|
required = kwargs.pop("required", False)
|
||||||
|
|
|
@ -65,7 +65,8 @@ def test_serialize_group_by_metadata(api_client, data_fixture):
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_serialize_group_by_metadata_on_all_fields_in_interesting_table(data_fixture):
|
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()
|
model = table.get_model()
|
||||||
queryset = model.objects.all()
|
queryset = model.objects.all()
|
||||||
rows = list(queryset)
|
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": [], "count": 1},
|
||||||
{"field_decimal_link_row": [1, 2, 3], "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():
|
for key, actual_value in actual_result_per_field_name.items():
|
||||||
expected_value = expected_result.get(key, None)
|
expected_value = expected_result.get(key, None)
|
||||||
|
|
|
@ -5,9 +5,11 @@ from django.apps.registry import apps
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.test.utils import CaptureQueriesContext
|
from django.test.utils import CaptureQueriesContext
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from faker import Faker
|
from faker import Faker
|
||||||
|
from pytest_unordered import unordered
|
||||||
|
|
||||||
from baserow.contrib.database.fields.field_types import MultipleCollaboratorsFieldType
|
from baserow.contrib.database.fields.field_types import MultipleCollaboratorsFieldType
|
||||||
from baserow.contrib.database.fields.handler import FieldHandler
|
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)
|
export_row(row)
|
||||||
|
|
||||||
assert len(queries_for_all_others.captured_queries) == 0
|
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,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"type": "feature",
|
||||||
|
"message": "Multiple collaborator field group by support.",
|
||||||
|
"issue_number": 3447,
|
||||||
|
"bullet_points": [],
|
||||||
|
"created_at": "2025-02-25"
|
||||||
|
}
|
|
@ -4335,6 +4335,27 @@ export class MultipleCollaboratorsFieldType extends FieldType {
|
||||||
canBeReferencedByFormulaField() {
|
canBeReferencedByFormulaField() {
|
||||||
return true
|
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 {
|
export class UUIDFieldType extends FieldType {
|
||||||
|
|
Loading…
Add table
Reference in a new issue