Skip to content

feat(teams): teams page and team workspace - #551

Merged
harshtandiya merged 9 commits into
developfrom
feat/dashboard-teams-page
Oct 8, 2026
Merged

harshtandiya merged 9 commits into
developfrom
feat/dashboard-teams-page

Conversation

@harshtandiya

@harshtandiya harshtandiya commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

What changed

Teams get their own place in the dashboard: /manage/teams lists the user's teams and communities, and opening one turns the sidebar into a team workspace.

  • Events: the events timeline filtered to the team.
  • Members: role guide and roster, with Add member for Owner/Admin.
  • Payments: the team's tax details (legal name, tax ID, billing address). Owner/Admin edit; other members read only.
  • Settings: Display (logo, name, short description, visibility, public URL, links) and Options (community submissions). The public URL is checked as it is typed, and Save is held while it is taken.
  • On a phone: Settings lists its sections and opens each full screen; Discard takes the back button's place while edits are unsaved; the header links to the public team page.

Server side: get_my_teams adds slug, is_published, is_a_community, short_description and an upcoming event count; update_public_page takes an editable slug; new check_team_slug shares one slug check with the save; new update_tax_details, which the event ticket flow now shares; BuzzTeam refuses community submissions on a private team. Non-members get the not-found page on any team URL.

Demo

Teams Team events
teams.png team-events.png
Members Payments
team-members.png team-payments.png
Settings: Display Settings: URL already taken
team-settings-display.png team-settings-url-taken.png
Settings: Options
team-settings-options.png

On a phone:

phone-team-events phone-settings-list phone-settings-display

Testing

test_teams, test_buzz_team and test_taxes pass; dashboard typecheck, nav unit tests, production build and pre-commit are clean. Checked in the browser on desktop and phone: team list, filtered events, member search, payments, settings save and discard, Cmd+S, the live URL check, and the phone settings flow.

Add /manage/teams with a card per team, split into communities and teams.
Opening a team turns the sidebar into a team workspace with Details,
Team Members, Community Submissions (communities only) and More.

get_my_teams now returns is_a_community, short_description and the
number of upcoming events per team, counted in one query.

The name and logo form and the role guide move out of ManageTeamPanel
into their own components so the settings panel and the new pages share
them. The sidebar header takes a generic workspace instead of event props.
Drop the Details, Members, Submissions and More pages from the team
workspace. Its one page is Events, the same timeline as /manage/events
filtered to the team through get_my_events' team filter.

A non-member opening a team URL gets the not-found page. Opening a team
makes it the current team, so Create Event files the event under it.
Add People beside Events in the team workspace: the role guide and the
member roster, with Add member on the search row for owners and admins.
A search with no matches shows the shared empty state.

Team pages share a breadcrumb header (team / section), so the team's
Events page now names the team it belongs to.
The home sidebar keeps Events, Talk Proposals and Sponsorship together and
sets Teams apart below a divider. A nav item flagged startsGroup gets the
divider on desktop.

The team's People page is now Members, at /manage/teams/:teamId/members,
with the same icon and title heading as the Events page.
Add Settings to the team workspace, with vertical tabs:

- Display: logo, name and short description, an Access card (visibility
  as a dropdown and an editable public URL), and the team's links.
- Options: community submissions, which only a public team can turn on.

Save appears once the form changes, Cmd+S saves, and leaving the site
with unsaved edits warns. The Team Page button opens the saved page.

update_public_page now takes a slug: it is cleaned like a generated one,
refused when another team has it, and the route follows it even while
the team is private. BuzzTeam refuses community submissions on a
private team.

Team page links are built from the current origin, as event links are,
and the dev proxy forwards /community to the bench. A vertical tab list
keeps frappe-ui's own gap instead of the global horizontal one.
@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Backend test coverage: 91%

Commit c1e6423. Test modules are excluded.

Coverage by file
Name Stmts Miss Cover
buzz/__init__.py 5 5 0%
buzz/api/account/__init__.py 30 2 93%
buzz/api/account/exceptions.py 8 0 100%
buzz/api/account/schemas.py 4 0 100%
buzz/api/account/services.py 15 1 93%
buzz/api/auth/__init__.py 11 0 100%
buzz/api/auth/schemas.py 3 0 100%
buzz/api/booking/__init__.py 30 1 97%
buzz/api/booking/coupons.py 30 3 90%
buzz/api/booking/details.py 93 7 92%
buzz/api/booking/event_data.py 42 4 90%
buzz/api/booking/exceptions.py 21 0 100%
buzz/api/booking/guests.py 71 10 86%
buzz/api/booking/my_bookings.py 9 3 67%
buzz/api/booking/schemas.py 38 0 100%
buzz/api/booking/services.py 212 19 91%
buzz/api/campaigns/__init__.py 34 19 44%
buzz/api/campaigns/exceptions.py 11 0 100%
buzz/api/campaigns/schemas.py 2 0 100%
buzz/api/checkin/__init__.py 9 0 100%
buzz/api/checkin/exceptions.py 14 0 100%
buzz/api/checkin/schemas.py 8 0 100%
buzz/api/checkin/services.py 62 1 98%
buzz/api/communications/__init__.py 16 0 100%
buzz/api/communications/exceptions.py 11 0 100%
buzz/api/communications/schemas.py 6 0 100%
buzz/api/communications/services.py 65 1 98%
buzz/api/communities/__init__.py 39 0 100%
buzz/api/communities/exceptions.py 12 0 100%
buzz/api/communities/notifications.py 20 1 95%
buzz/api/communities/queries.py 14 0 100%
buzz/api/communities/reviews.py 36 1 97%
buzz/api/communities/schemas.py 7 0 100%
buzz/api/communities/submissions.py 43 1 98%
buzz/api/events/__init__.py 49 0 100%
buzz/api/events/exceptions.py 20 0 100%
buzz/api/events/schemas.py 85 0 100%
buzz/api/events/services.py 221 13 94%
buzz/api/events/taxes.py 19 0 100%
buzz/api/events/ticket_types.py 43 0 100%
buzz/api/events/zoom.py 15 1 93%
buzz/api/exceptions.py 23 0 100%
buzz/api/filters/conditions.py 99 2 98%
buzz/api/filters/exceptions.py 5 0 100%
buzz/api/filters/schemas.py 6 0 100%
buzz/api/forms/__init__.py 24 0 100%
buzz/api/forms/answers.py 77 14 82%
buzz/api/forms/exceptions.py 27 0 100%
buzz/api/forms/fields.py 82 3 96%
buzz/api/forms/schemas.py 7 0 100%
buzz/api/forms/services.py 119 1 99%
buzz/api/maps/__init__.py 16 0 100%
buzz/api/maps/exceptions.py 11 0 100%
buzz/api/maps/schemas.py 9 0 100%
buzz/api/maps/services.py 57 0 100%
buzz/api/payments/__init__.py 10 1 90%
buzz/api/payments/currencies.py 7 2 71%
buzz/api/payments/schemas.py 2 0 100%
buzz/api/proposals/__init__.py 18 0 100%
buzz/api/proposals/exceptions.py 5 0 100%
buzz/api/proposals/schemas.py 26 0 100%
buzz/api/proposals/services.py 104 1 99%
buzz/api/schemas.py 13 0 100%
buzz/api/sponsorships/__init__.py 37 0 100%
buzz/api/sponsorships/enquiries.py 74 2 97%
buzz/api/sponsorships/exceptions.py 22 0 100%
buzz/api/sponsorships/forms.py 64 2 97%
buzz/api/sponsorships/manage.py 21 1 95%
buzz/api/sponsorships/schemas.py 18 0 100%
buzz/api/sponsorships/services.py 67 1 99%
buzz/api/teams/__init__.py 44 2 95%
buzz/api/teams/exceptions.py 24 0 100%
buzz/api/teams/invitations.py 34 0 100%
buzz/api/teams/public_page.py 26 15 42%
buzz/api/teams/schemas.py 9 0 100%
buzz/api/teams/services.py 100 1 99%
buzz/api/tickets/__init__.py 15 0 100%
buzz/api/tickets/emails.py 14 9 36%
buzz/api/tickets/exceptions.py 29 0 100%
buzz/api/tickets/schemas.py 4 0 100%
buzz/api/tickets/services.py 85 0 100%
buzz/api/tickets/windows.py 12 0 100%
buzz/buzz/doctype/buzz_custom_field/buzz_custom_field.py 20 4 80%
buzz/buzz/web_form/apply_for_sponsorship/apply_for_sponsorship.py 3 3 0%
buzz/buzz/web_form/propose_a_talk/propose_a_talk.py 3 3 0%
buzz/buzz_marketing/doctype/buzz_campaign/buzz_campaign.py 21 7 67%
buzz/emails.py 29 3 90%
buzz/events/banner_pattern.py 35 0 100%
buzz/events/doctype/additional_event_page/additional_event_page.py 15 1 93%
buzz/events/doctype/buzz_event/buzz_event.py 267 23 91%
buzz/events/doctype/buzz_event_form/buzz_event_form.py 11 4 64%
buzz/events/doctype/buzz_form_field/buzz_form_field.py 3 0 100%
buzz/events/doctype/buzz_price/buzz_price.py 10 0 100%
buzz/events/doctype/buzz_settings/buzz_settings.py 13 2 85%
buzz/events/doctype/buzz_team/buzz_team.py 75 3 96%
buzz/events/doctype/buzz_team/team_map.py 23 0 100%
buzz/events/doctype/buzz_team/team_page.py 69 2 97%
buzz/events/doctype/buzz_team_membership/buzz_team_membership.py 59 0 100%
buzz/events/doctype/buzz_team_settings/buzz_team_settings.py 44 0 100%
buzz/events/doctype/buzz_theme/buzz_theme.py 42 2 95%
buzz/events/doctype/buzz_theme/tokens.py 29 1 97%
buzz/events/doctype/buzz_theme_token/buzz_theme_token.py 3 0 100%
buzz/events/doctype/community_event_request/community_event_request.py 40 9 78%
buzz/events/doctype/event_category/event_category.py 9 0 100%
buzz/events/doctype/event_check_in/event_check_in.py 10 1 90%
buzz/events/doctype/event_cohost/event_cohost.py 4 0 100%
buzz/events/doctype/event_communication/event_communication.py 16 0 100%
buzz/events/doctype/event_external_link/event_external_link.py 4 0 100%
buzz/events/doctype/event_featured_speaker/event_featured_speaker.py 4 0 100%
buzz/events/doctype/event_feedback/event_feedback.py 4 4 0%
buzz/events/doctype/event_host/event_host.py 4 0 100%
buzz/events/doctype/event_payment_gateway/event_payment_gateway.py 4 0 100%
buzz/events/doctype/event_sponsor/event_sponsor.py 15 3 80%
buzz/events/doctype/event_talk/event_talk.py 8 0 100%
buzz/events/doctype/event_template/event_template.py 38 4 89%
buzz/events/doctype/event_template_add_on/event_template_add_on.py 4 0 100%
buzz/events/doctype/event_template_custom_field/event_template_custom_field.py 4 0 100%
buzz/events/doctype/event_template_ticket_type/event_template_ticket_type.py 4 0 100%
buzz/events/doctype/event_track/event_track.py 4 4 0%
buzz/events/doctype/event_user_preferences/event_user_preferences.py 4 4 0%
buzz/events/doctype/event_venue/event_venue.py 53 1 98%
buzz/events/doctype/event_venue/geocode.py 69 9 87%
buzz/events/doctype/event_venue/map_link.py 106 5 95%
buzz/events/doctype/offline_payment_method/offline_payment_method.py 11 0 100%
buzz/events/doctype/schedule_item/schedule_item.py 4 0 100%
buzz/events/doctype/social_media_link/social_media_link.py 3 0 100%
buzz/events/doctype/speaker_profile/speaker_profile.py 8 1 88%
buzz/events/doctype/sponsor_enquiry_form/sponsor_enquiry_form.py 54 5 91%
buzz/events/doctype/sponsorship_tier/sponsorship_tier.py 27 1 96%
buzz/events/doctype/talk_speaker/talk_speaker.py 3 0 100%
buzz/events/doctype/utm_parameter/utm_parameter.py 4 0 100%
buzz/events/og_image.py 141 7 95%
buzz/events/og_text.py 66 1 98%
buzz/events/online_meeting.py 42 1 98%
buzz/events/report/event_attendance_summary/event_attendance_summary.py 61 61 0%
buzz/events/report/event_overview/event_overview.py 25 25 0%
buzz/hooks.py 28 0 100%
buzz/install.py 60 28 53%
buzz/integrations/zoom.py 3 3 0%
buzz/payments.py 96 33 66%
buzz/permissions.py 137 12 91%
buzz/proposals/doctype/event_proposal/event_proposal.py 71 5 93%
buzz/proposals/doctype/proposal_speaker/proposal_speaker.py 4 0 100%
buzz/proposals/doctype/sponsorship_deck_item/sponsorship_deck_item.py 4 0 100%
buzz/proposals/doctype/sponsorship_enquiry/sponsorship_enquiry.py 81 5 94%
buzz/proposals/doctype/talk_proposal/talk_proposal.py 92 6 93%
buzz/proposals/doctype/talk_proposal_status/talk_proposal_status.py 4 0 100%
buzz/tasks.py 4 4 0%
buzz/telemetry.py 46 0 100%
buzz/telemetry_scan.py 55 8 85%
buzz/ticketing/doctype/additional_field/additional_field.py 4 0 100%
buzz/ticketing/doctype/attendee_ticket_add_on/attendee_ticket_add_on.py 3 0 100%
buzz/ticketing/doctype/buzz_coupon_code/buzz_coupon_code.py 99 4 96%
buzz/ticketing/doctype/coupon_free_add_on/coupon_free_add_on.py 3 0 100%
buzz/ticketing/doctype/event_booking/event_booking.py 355 28 92%
buzz/ticketing/doctype/event_booking_attendee/event_booking_attendee.py 20 7 65%
buzz/ticketing/doctype/event_booking_refund/event_booking_refund.py 56 0 100%
buzz/ticketing/doctype/event_booking_refund_ticket/event_booking_refund_ticket.py 4 0 100%
buzz/ticketing/doctype/event_payment/event_payment.py 4 0 100%
buzz/ticketing/doctype/event_ticket/event_ticket.py 80 10 88%
buzz/ticketing/doctype/event_ticket_type/event_ticket_type.py 69 0 100%
buzz/ticketing/doctype/ticket_add_on/ticket_add_on.py 9 1 89%
buzz/ticketing/doctype/ticket_add_on_value/ticket_add_on_value.py 3 0 100%
buzz/ticketing/doctype/ticket_cancellation_item/ticket_cancellation_item.py 4 0 100%
buzz/ticketing/doctype/ticket_cancellation_request/ticket_cancellation_request.py 19 1 95%
buzz/ticketing/report/detailed_event_registrations/detailed_event_registrations.py 111 5 95%
buzz/ticketing/report/event_add_ons_overview/event_add_ons_overview.py 20 20 0%
buzz/uninstall.py 10 2 80%
buzz/utils.py 138 22 84%
buzz/www/dashboard.py 24 3 88%
buzz/www/event/date_range.py 42 16 62%
buzz/www/event/index.py 140 8 94%
buzz/www/event/link_icons.py 1 0 100%
buzz/www/event/meta.py 65 6 91%
buzz/www/event/venue_map.py 35 1 97%
buzz/www/events.py 69 6 91%
buzz/www/site_header.py 25 0 100%
TOTAL 6657 598 91%

89 empty files skipped.

Payments sits between Members and Settings in the team sidebar and edits
the legal name, tax ID and billing address kept on Buzz Team Settings.
Owners and admins can change them; everyone else on the team sees them
read-only. The event ticket flow now saves through the same team service.

Team pages drop their big icon-and-title block: the breadcrumb header
names the page, and the Team Page link moves up into it. On phones, team
Events uses the same floating Create Event button as the main Events page.
@harshtandiya
harshtandiya marked this pull request as ready for review October 8, 2026 11:56

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

The team's public URL is checked as it is typed, as an event route is: a
"Checking availability" line from the first keystroke, then whether the URL
is free. Save is disabled while it is taken. One slug check serves both
the new check_team_slug endpoint and the save, so the two always agree.

On a phone, Settings lists its sections and opens each on its own screen
without the bottom nav, titled "Team · Section", with back returning to
the list. Discard takes the back button's place while edits are unsaved.
The header links to the public page on every team screen on a phone and
on Settings on desktop, and steps aside while there are unsaved edits.
get_my_teams now returns slug and is_published for that link.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

A failed URL check no longer leaves "Checking availability" up, and a URL
that cleans down to nothing asks for letters, numbers and hyphens instead of
reporting it taken. Plainer names for the selected tab and the phone slide
classes, and comments that only restated the code are gone.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@harshtandiya
harshtandiya merged commit e2618a2 into develop Oct 8, 2026
10 checks passed
@harshtandiya
harshtandiya deleted the feat/dashboard-teams-page branch October 8, 2026 13:04
@harshtandiya harshtandiya mentioned this pull request Oct 12, 2026
4 of 8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant