feat: flache sortierbare Kalenderliste (Drag&Drop) + Fixes
- Sidebar: eine flache Kalenderliste statt Quellen-Gruppen; Quelle/Konto klein-grau inline rechts neben dem Namen; per Drag&Drop sortierbar (Reihenfolge pro Geraet in localStorage). - Gruppenkalender serverseitig auch beim Besitzer als group:true markiert -> erscheint nicht mehr in der "Fuer Gruppen sichtbar"-Auswahl und nicht in der normalen Kalenderliste (nur unter Gruppen). - Settings-URL-State: uiSettingsOpen wird beim Init aus der URL gesetzt, bevor das erste writeUrlState() es ueberschreibt -> Reload bleibt jetzt wirklich in den Einstellungen. - Auswahl-Markierungen (Mitglieder/Gruppen-Sichtbar) in Akzentfarbe, CSS-gezeichnet statt blauer Emoji. Version v28. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -91,13 +91,34 @@ def list_calendars(
|
||||
db: Session = Depends(get_db),
|
||||
current_user: models.User = Depends(get_current_user),
|
||||
):
|
||||
# Map calendar_id -> group name for every group the user belongs to, so we
|
||||
# can flag group calendars as such even when the user owns them (the creator
|
||||
# owns the group calendar — it must still be marked group:true).
|
||||
group_cal_map = {
|
||||
cal_id: name
|
||||
for cal_id, name in (
|
||||
db.query(models.GroupCalendar.calendar_id, models.Group.name)
|
||||
.join(models.Group, models.Group.id == models.GroupCalendar.group_id)
|
||||
.join(models.GroupMember, models.GroupMember.group_id == models.GroupCalendar.group_id)
|
||||
.filter(models.GroupMember.user_id == current_user.id)
|
||||
.all()
|
||||
)
|
||||
}
|
||||
|
||||
# Own calendars
|
||||
own = (
|
||||
db.query(models.LocalCalendar)
|
||||
.filter(models.LocalCalendar.user_id == current_user.id)
|
||||
.all()
|
||||
)
|
||||
result = [_cal_dict(c, owned=True) for c in own]
|
||||
result = []
|
||||
for c in own:
|
||||
d = _cal_dict(c, owned=True)
|
||||
if c.id in group_cal_map:
|
||||
d["group"] = True
|
||||
result.append(d)
|
||||
|
||||
seen_ids = {c.id for c in own}
|
||||
|
||||
# Calendars shared with this user
|
||||
shares = (
|
||||
@@ -105,33 +126,30 @@ def list_calendars(
|
||||
.filter(models.CalendarShare.user_id == current_user.id)
|
||||
.all()
|
||||
)
|
||||
seen_ids = {c.id for c in own}
|
||||
for share in shares:
|
||||
cal = share.calendar
|
||||
if cal is None or cal.id in seen_ids:
|
||||
continue
|
||||
seen_ids.add(cal.id)
|
||||
owner = db.query(models.User).filter(models.User.id == cal.user_id).first()
|
||||
result.append(_cal_dict(
|
||||
d = _cal_dict(
|
||||
cal, owned=False,
|
||||
shared_by=owner.username if owner else None,
|
||||
permission=share.permission,
|
||||
))
|
||||
)
|
||||
if cal.id in group_cal_map:
|
||||
d["group"] = True
|
||||
result.append(d)
|
||||
|
||||
# Group calendars the user can reach via membership (read_write), so members
|
||||
# can select the group calendar in the editor and see it in their list.
|
||||
group_cals = (
|
||||
db.query(models.LocalCalendar, models.Group.name)
|
||||
.join(models.GroupCalendar, models.GroupCalendar.calendar_id == models.LocalCalendar.id)
|
||||
.join(models.Group, models.Group.id == models.GroupCalendar.group_id)
|
||||
.join(models.GroupMember, models.GroupMember.group_id == models.GroupCalendar.group_id)
|
||||
.filter(models.GroupMember.user_id == current_user.id)
|
||||
.all()
|
||||
)
|
||||
for cal, group_name in group_cals:
|
||||
if cal.id in seen_ids:
|
||||
# Group calendars reached via membership (read_write) that aren't already
|
||||
# listed, so members can select/see the group calendar.
|
||||
for cal_id, group_name in group_cal_map.items():
|
||||
if cal_id in seen_ids:
|
||||
continue
|
||||
seen_ids.add(cal.id)
|
||||
cal = db.query(models.LocalCalendar).filter(models.LocalCalendar.id == cal_id).first()
|
||||
if not cal:
|
||||
continue
|
||||
seen_ids.add(cal_id)
|
||||
d = _cal_dict(cal, owned=False, shared_by=group_name, permission="read_write")
|
||||
d["group"] = True
|
||||
result.append(d)
|
||||
|
||||
Reference in New Issue
Block a user