diff --git a/client/src/app/site/agenda/components/list-of-speakers/list-of-speakers.component.ts b/client/src/app/site/agenda/components/list-of-speakers/list-of-speakers.component.ts index 764d702e4..e03151b4e 100644 --- a/client/src/app/site/agenda/components/list-of-speakers/list-of-speakers.component.ts +++ b/client/src/app/site/agenda/components/list-of-speakers/list-of-speakers.component.ts @@ -154,7 +154,7 @@ export class ListOfSpeakersComponent extends BaseViewComponent implements OnInit private config: ConfigService ) { super(title, translate, snackBar); - this.addSpeakerForm = new FormGroup({ user_id: new FormControl([]) }); + this.addSpeakerForm = new FormGroup({ user_id: new FormControl() }); } /** @@ -201,6 +201,7 @@ export class ListOfSpeakersComponent extends BaseViewComponent implements OnInit } }) ); + this.subscriptions.push( this.config.get('agenda_present_speakers_only').subscribe(() => { this.filterUsers(); diff --git a/client/src/app/site/assignments/components/assignment-detail/assignment-detail.component.html b/client/src/app/site/assignments/components/assignment-detail/assignment-detail.component.html index eb82c8f25..a07b22c7e 100644 --- a/client/src/app/site/assignments/components/assignment-detail/assignment-detail.component.html +++ b/client/src/app/site/assignments/components/assignment-detail/assignment-detail.component.html @@ -142,7 +142,7 @@ diff --git a/openslides/agenda/apps.py b/openslides/agenda/apps.py index 75d532715..88baf1fb8 100644 --- a/openslides/agenda/apps.py +++ b/openslides/agenda/apps.py @@ -64,7 +64,7 @@ class AgendaAppConfig(AppConfig): yield self.get_model("ListOfSpeakers") -def required_users(element: Dict[str, Any]) -> Set[int]: +async def required_users(element: Dict[str, Any]) -> Set[int]: """ Returns all user ids that are displayed as speaker in the given element. """ diff --git a/openslides/assignments/apps.py b/openslides/assignments/apps.py index 17ce86b14..0a0256cd1 100644 --- a/openslides/assignments/apps.py +++ b/openslides/assignments/apps.py @@ -72,16 +72,26 @@ class AssignmentsAppConfig(AppConfig): yield self.get_model(model_name) -def required_users(element: Dict[str, Any]) -> Set[int]: +async def required_users(element: Dict[str, Any]) -> Set[int]: """ Returns all user ids that are displayed as candidates (including poll options) in the assignment element. - - TODO: Adapt this method for new poll structure!! """ + from openslides.assignments.models import AssignmentPoll, AssignmentOption + from openslides.utils.cache import element_cache + candidates = set( related_user["user_id"] for related_user in element["assignment_related_users"] ) - for poll in element["polls"]: - candidates.update(option["candidate_id"] for option in poll["options"]) + for poll_id in element["polls_id"]: + poll = await element_cache.get_element_data( + AssignmentPoll.get_collection_string(), poll_id + ) + if poll: + for option_id in poll["options_id"]: + option = await element_cache.get_element_data( + AssignmentOption.get_collection_string(), option_id + ) + if option: + candidates.add(option["user_id"]) return candidates diff --git a/openslides/assignments/models.py b/openslides/assignments/models.py index aebca37f5..440ec2672 100644 --- a/openslides/assignments/models.py +++ b/openslides/assignments/models.py @@ -86,6 +86,7 @@ class AssignmentManager(BaseManager): "lists_of_speakers", "tags", "attachments", + "polls", ) ) diff --git a/openslides/assignments/serializers.py b/openslides/assignments/serializers.py index f6ba0f725..bcdd31f12 100644 --- a/openslides/assignments/serializers.py +++ b/openslides/assignments/serializers.py @@ -9,6 +9,7 @@ from openslides.poll.serializers import ( from openslides.utils.rest_api import ( BooleanField, DecimalField, + IdPrimaryKeyRelatedField, IntegerField, ModelSerializer, ValidationError, @@ -150,6 +151,7 @@ class AssignmentSerializer(ModelSerializer): write_only=True, required=False, min_value=1, max_value=3, allow_null=True ) agenda_parent_id = IntegerField(write_only=True, required=False, min_value=1) + polls = IdPrimaryKeyRelatedField(many=True, read_only=True) class Meta: model = Assignment @@ -169,6 +171,7 @@ class AssignmentSerializer(ModelSerializer): "tags", "attachments", "number_poll_candidates", + "polls", ) validators = (posts_validator,) diff --git a/openslides/motions/apps.py b/openslides/motions/apps.py index 193c66c8f..78593fa24 100644 --- a/openslides/motions/apps.py +++ b/openslides/motions/apps.py @@ -107,7 +107,7 @@ class MotionsAppConfig(AppConfig): yield self.get_model(model_name) -def required_users(element: Dict[str, Any]) -> Set[int]: +async def required_users(element: Dict[str, Any]) -> Set[int]: """ Returns all user ids that are displayed as as submitter or supporter in any motion if request_user can see motions. This function may return an diff --git a/openslides/utils/access_permissions.py b/openslides/utils/access_permissions.py index 1fb547e13..f055da290 100644 --- a/openslides/utils/access_permissions.py +++ b/openslides/utils/access_permissions.py @@ -1,4 +1,4 @@ -from typing import Any, Callable, Dict, List, Set +from typing import Any, Callable, Coroutine, Dict, List, Set from asgiref.sync import async_to_sync @@ -59,7 +59,7 @@ class RequiredUsers: Helper class to find all users that are required by another element. """ - callables: Dict[str, Callable[[Dict[str, Any]], Set[int]]] = {} + callables: Dict[str, Callable[[Dict[str, Any]], Coroutine[Any, Any, Set[int]]]] = {} def get_collection_strings(self) -> Set[str]: """ @@ -68,7 +68,9 @@ class RequiredUsers: return set(self.callables.keys()) def add_collection_string( - self, collection_string: str, callable: Callable[[Dict[str, Any]], Set[int]] + self, + collection_string: str, + callable: Callable[[Dict[str, Any]], Coroutine[Any, Any, Set[int]]], ) -> None: """ Add a callable for a collection_string to get the required users of the @@ -94,7 +96,7 @@ class RequiredUsers: continue for element in collection_data.values(): - user_ids.update(get_user_ids(element)) + user_ids.update(await get_user_ids(element)) return user_ids diff --git a/tests/integration/assignments/test_viewset.py b/tests/integration/assignments/test_viewset.py index db874641e..57817a9b3 100644 --- a/tests/integration/assignments/test_viewset.py +++ b/tests/integration/assignments/test_viewset.py @@ -23,6 +23,7 @@ def test_assignment_db_queries(): * 1 request to get the list of speakers, * 1 request to get the tags, * 1 request to get the attachments and + * 1 Request to get the polls of the assignment """ for index in range(10): assignment = Assignment.objects.create(title=f"assignment{index}", open_posts=1) @@ -34,7 +35,7 @@ def test_assignment_db_queries(): type=AssignmentPoll.TYPE_NAMED, ) - assert count_queries(Assignment.get_elements)() == 6 + assert count_queries(Assignment.get_elements)() == 7 class CreateAssignment(TestCase):