Skip to content

Commit

Permalink
Make it possible to remove users added to meeting (SEA-1595).
Browse files Browse the repository at this point in the history
  • Loading branch information
cyrillkuettel committed Nov 9, 2024
1 parent f78ef35 commit a3084fa
Show file tree
Hide file tree
Showing 12 changed files with 206 additions and 175 deletions.
58 changes: 34 additions & 24 deletions src/privatim/forms/meeting_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@
from privatim.models.association_tables import AttendanceStatus
from privatim.models import MeetingUserAttendance

from typing import TYPE_CHECKING, Any

from privatim.utils import attendance_status
from typing import TYPE_CHECKING, Any, NamedTuple
from privatim.utils import status_is_checked
if TYPE_CHECKING:
from wtforms import Field
from pyramid.interfaces import IRequest
Expand Down Expand Up @@ -46,6 +45,11 @@ class AttendanceForm(Form):
render_kw={'class': 'no-white-background'},
default=False
)
remove = CheckboxField(
_('Remove'),
render_kw={'class': 'no-white-background'},
default=False
)


class MeetingForm(Form):
Expand Down Expand Up @@ -154,7 +158,7 @@ def handle_process_edit(self, obj: Meeting) -> None:
self.attendance.append_entry(
{
'user_id': str(attendance_record.user_id),
'fullname': attendance_record.user.fullname,
'fullname': attendance_record.user.fullname_without_abbrev,
'status': status
}
)
Expand Down Expand Up @@ -186,38 +190,44 @@ def sync_meeting_attendance_records(
""" Searches in request.POST to manually get data and find the status
for each user and map it to MeetingUserAttendance."""

def find_attendance_in_form(user_id: str) -> bool:
class AttendanceValues(NamedTuple):
is_present: bool
should_remove: bool

def find_attendance_in_form(user_id: str) -> AttendanceValues:
""" Returns the values of the status and remove checkboxes, in that
order """
for f in form._fields.get('attendance', ()): # type:ignore
if f.user_id.data == user_id:
# XXX this is kind of crude, but I couldn't find a way to do
# it otherwise. Request.POST is somehow is not mapped to the
# 'status' field in AttendanceForm.
# We have to get it manually as a workaround
return attendance_status(post_data, user_id)

return False
return AttendanceValues(
is_present=status_is_checked(post_data, user_id),
should_remove=bool(f.remove.data)
)
return AttendanceValues(is_present=False, should_remove=False)

assert isinstance(form.attendees, SearchableMultiSelectField)

# Extract user IDs and statuses from the attendance FieldList
attendance_data = {
entry.data['user_id']: entry.data['status']
for entry in form.attendance.entries
}
# Get user IDs from the attendees field
# Collect unique user IDs from attendees and attendance entries
entries = form.attendance.entries
attendance_user_ids = {entry.data['user_id'] for entry in entries}
attendee_ids = set(form.attendees.data or [])

# Combine user IDs from attendance and attendees, removing duplicates
all_user_ids = set(attendance_data.keys()) | attendee_ids

# Merge both sets of user IDs
all_user_ids = attendance_user_ids | attendee_ids
stmt = select(User).where(User.id.in_(all_user_ids))
users_for_edited_meeting = session.execute(stmt).scalars().all()

obj.attendance_records = []
for user in users_for_edited_meeting:
actual_status = AttendanceStatus.INVITED
if find_attendance_in_form(user.id) is True:
actual_status = AttendanceStatus.ATTENDED
attendance = MeetingUserAttendance(
meeting=obj, user=user, status=actual_status
)
obj.attendance_records.append(attendance)
attended, remove = find_attendance_in_form(user.id)
if not remove: # Only add if not marked for removal
obj.attendance_records.append(MeetingUserAttendance(
meeting=obj,
user=user,
status=AttendanceStatus.ATTENDED
if attended else AttendanceStatus.INVITED,
))
17 changes: 10 additions & 7 deletions src/privatim/layouts/macros.pt
Original file line number Diff line number Diff line change
Expand Up @@ -269,15 +269,19 @@
<tal:block metal:define-macro="render_attendance_field">
<div class="attendance-container">
<div class="attendance-list">
<div class="attendance-header">
<span>Name</span>
<span>Anwesend</span>
<div class="attendance-header d-flex justify-content-between align-items-center border-bottom pb-2 mb-3">
<span class="col-6" i18n:translate="">Name</span>
<span class="col-3 text-center" i18n:translate="">Attended</span>
<span class="col-3 text-center" i18n:translate="">Remove</span>
</div>
<tal:block tal:repeat="subfield field">
<div class="attendance-row">
<div class="attendance-row d-flex justify-content-between align-items-center mb-2">
${subfield.user_id(type='hidden')}
<span class="attendee-name">${subfield.fullname(disabled='disabled')}</span>
<span class="attendee-status">${subfield.status()}</span>
<span class="attendee-name col-6">${subfield.fullname(disabled='disabled', class_='form-control-plaintext')}</span>
<span class="attendee-status col-3 text-center">${subfield.status(class_='form-check-input')}</span>
<span class="attendee-remove col-3 text-center">
${subfield.remove(class_='form-check-input text-danger')}
</span>
</div>
</tal:block>
</div>
Expand All @@ -287,7 +291,6 @@




<tal:block metal:define-macro="the-modals">
<div class="modal fade" id="delete-xhr" tabindex="-1" aria-labelledby="delete-xhr-title" aria-hidden="true" tal:condition="exists:delete_title">
<div class="modal-dialog modal-dialog-centered">
Expand Down
Binary file modified src/privatim/locale/de/LC_MESSAGES/privatim.mo
Binary file not shown.
87 changes: 46 additions & 41 deletions src/privatim/locale/de/LC_MESSAGES/privatim.po
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE 1.0\n"
"POT-Creation-Date: 2024-09-10 11:47+0200\n"
"POT-Creation-Date: 2024-11-08 22:02+0100\n"
"PO-Revision-Date: 2024-05-21 21:20+0200\n"
"Last-Translator: cyrill <[email protected]>\n"
"Language-Team: German <[email protected]>\n"
Expand Down Expand Up @@ -100,6 +100,22 @@ msgstr "K"
msgid "URL"
msgstr "URL"

#: src/privatim/layouts/macros.pt src/privatim/views/templates/working_group.pt
#: src/privatim/views/templates/profile.pt
#: src/privatim/views/templates/people.pt src/privatim/forms/meeting_form.py
#: src/privatim/forms/working_group_forms.py
msgid "Name"
msgstr "Name"

#: src/privatim/layouts/macros.pt src/privatim/views/meetings.py
#: src/privatim/forms/meeting_form.py
msgid "Attended"
msgstr "Anwesend"

#: src/privatim/layouts/macros.pt src/privatim/forms/meeting_form.py
msgid "Remove"
msgstr "Entfernen"

#: src/privatim/layouts/macros.pt
msgid "Do you really wish to delete \"${item_title}\"?"
msgstr "Möchten Sie \"${item_title}\" wirklich löschen?"
Expand Down Expand Up @@ -203,29 +219,6 @@ msgstr "Anmeldung fehlgeschlagen."
msgid "Successfully deleted file \"${title}\""
msgstr "Datei \"${title}\" erfolgreich gelöscht"

#: src/privatim/views/meetings.py src/privatim/forms/agenda_item_form.py
msgid "Edit Agenda Item"
msgstr "Traktandum bearbeiten"

#: src/privatim/views/meetings.py
msgid "Delete Agenda Item"
msgstr "Traktandum löschen"

#: src/privatim/views/meetings.py src/privatim/forms/working_group_forms.py
msgid "Members"
msgstr "Mitglieder"

#: src/privatim/views/meetings.py src/privatim/views/templates/meeting.pt
msgid "Expand All"
msgstr "Alle ausklappen"

#: src/privatim/views/meetings.py
msgid "Collapse All"
msgstr "Alle einklappen"

#: src/privatim/views/meetings.py
msgid "Edit Meeting"
msgstr "Sitzung bearbeiten"

#: src/privatim/views/meetings.py
msgid "Copy"
Expand All @@ -247,9 +240,25 @@ msgstr "Protokoll drucken"
msgid "Delete Meeting"
msgstr "Sitzung löschen"

#: src/privatim/views/meetings.py src/privatim/forms/meeting_form.py
msgid "Attended"
msgstr "Anwesend"
#: src/privatim/views/meetings.py src/privatim/forms/agenda_item_form.py
msgid "Edit Agenda Item"
msgstr "Traktandum bearbeiten"

#: src/privatim/views/meetings.py
msgid "Delete Agenda Item"
msgstr "Traktandum löschen"

#: src/privatim/views/meetings.py src/privatim/forms/working_group_forms.py
msgid "Members"
msgstr "Mitglieder"

#: src/privatim/views/meetings.py src/privatim/views/templates/meeting.pt
msgid "Expand All"
msgstr "Alle ausklappen"

#: src/privatim/views/meetings.py
msgid "Collapse All"
msgstr "Alle einklappen"

#: src/privatim/views/meetings.py
msgid "Invited"
Expand All @@ -259,18 +268,18 @@ msgstr "Abwesend"
msgid "Meeting Report"
msgstr "Sitzungsbericht"

#: src/privatim/views/meetings.py src/privatim/views/templates/working_group.pt
msgid "Participants"
msgstr "Mitglieder"
#: src/privatim/views/meetings.py src/privatim/views/working_groups.py
#: src/privatim/forms/working_group_forms.py
msgid "Edit Working Group"
msgstr "Gremium bearbeiten"

#: src/privatim/views/meetings.py
msgid "Delete Working Group"
msgstr "Gremium löschen"

#: src/privatim/views/meetings.py src/privatim/views/working_groups.py
#: src/privatim/forms/working_group_forms.py
msgid "Edit Working Group"
msgstr "Gremium bearbeiten"
#: src/privatim/views/meetings.py src/privatim/views/templates/working_group.pt
msgid "Participants"
msgstr "Mitglieder"

#: src/privatim/views/meetings.py
#, python-format
Expand Down Expand Up @@ -566,13 +575,6 @@ msgid ""
"meeting\" to get started."
msgstr "Hier können Sie Sitzungen dieses Gremiums hinzufügen."

#: src/privatim/views/templates/working_group.pt
#: src/privatim/views/templates/profile.pt
#: src/privatim/views/templates/people.pt src/privatim/forms/meeting_form.py
#: src/privatim/forms/working_group_forms.py
msgid "Name"
msgstr "Name"

#: src/privatim/views/templates/working_group.pt
msgid "Date and Time"
msgstr "Datum und Zeit"
Expand Down Expand Up @@ -1049,3 +1051,6 @@ msgstr "Gremium:"
#: src/privatim/reporting/template/report.pt
msgid "Attendees:"
msgstr "Teilnehmende:"

#~ msgid "Edit Meeting"
#~ msgstr "Sitzung bearbeiten"
Binary file modified src/privatim/locale/fr/LC_MESSAGES/privatim.mo
Binary file not shown.
Loading

0 comments on commit a3084fa

Please sign in to comment.