Skip to content

feat(dashboard): a workspace for managing an event - #355

Merged
harshtandiya merged 9 commits into
developfrom
version-2-dashboard-events-manage
Aug 26, 2026
Merged

feat(dashboard): a workspace for managing an event#355
harshtandiya merged 9 commits into
developfrom
version-2-dashboard-events-manage

Conversation

@harshtandiya

@harshtandiya harshtandiya commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Rebased onto develop now that #354 has merged.

What changed

An event card's Manage button had nowhere to go. It now opens the event inside the
manager shell at /manage/events/<id>, where the sidebar carries the event's own
destinations — back out, Details, Attendees, Talks — in place of the personal and team
ones. No second layout: ManagerLayout swaps its item list when the route names an
event. Attendees and Talks land on the existing work-in-progress placeholder. On a
team's own events page every event is manageable, so those cards drop the per-card
button and become the link themselves.

Details holds the banner, name, short description, about, when it runs and where. Edits
are kept locally and written in one go, so Save only appears once something changed.
Where is asked in two steps: toggles pick the medium, then the page asks for what that
medium needs — a venue and its address, or a meeting link with a copy button. The old
combobox folded both into one list, which meant picking Zoom to say an event was virtual.

Worth a look during review:

  • The public address sits beside the name, host fixed and only the route editable.
    check_event_route counts unpublished events when deciding whether a route is free —
    an event holds its route whether or not anyone can see it yet — and refuses the
    reserved segments so an event cannot shadow /b/account.
  • Buzz Event gains meeting_link (Data/URL, shown when medium is Online).
    zoom_meeting belongs to an app the site may not have installed, and an organiser
    with a link of their own had nowhere to put it. get_event falls back to the booked
    Zoom meeting's link when none was typed.
  • get_event is guarded on write, so a Viewer gets a 403. Saves go through
    frappe.client.set_value — the team permission hooks already guard Buzz Event, so
    there is no bespoke write endpoint.
  • EventBanner.vue is the create page's banner block, extracted and now shared with
    Details. It takes the disabled prop the create page's viewer state needs.

Not done: Details has no viewer state of its own — get_event refuses a Viewer with a
403 rather than showing a read-only form, unlike the create page. BookingEventInfo.vue:8
still links to /events/<route>, which 404s on this site; the page that serves an event
is /b/register/<route>. Both pre-existing and outside this branch.

Demo

image

Testing

  • buzz.api.events.test_events — 29 pass, 1 skipped (Zoom), 11 of them new across
    get_event and check_event_route: payload shape, venue resolution, viewer /
    non-member / unknown-event refusals, taken and reserved routes, and an event not
    blocking its own.
  • buzz.events.doctype.buzz_event.test_buzz_event — 53 pass.
  • e2e/tests/manage-event.spec.ts — 9 new specs: opening on Details, a real save
    round-trip, the public-address chip, the virtual/in-person swap, sidebar contents,
    moving between sections, backing out, route availability, and the card entry point.
  • e2e/tests/create-event.spec.ts — new, guards the create page after the extraction.
  • Dashboard yarn typecheck, yarn test:unit (103 pass) and yarn build all clean.

@greptile-apps

greptile-apps Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds an event-management workspace with editable event details, event-specific navigation, route availability checks, and support for manual online meeting links.

  • Adds manager routes, sidebar destinations, and linked event cards.
  • Adds event detail and route-availability APIs with team write-access enforcement.
  • Adds shared banner, medium, location, and public-route editing components.
  • Adds the Buzz Event meeting_link field and server-side location cleanup.

Confidence Score: 4/5

The PR should not merge until switching a Zoom-backed event to in-person also removes the obsolete Zoom session references.

The prior-thread reply marked stale-location cleanup fixed, but the current cleanup only removes meeting_link; retained zoom_meeting and zoom_webinar references can still drive attendee Zoom registration and can repopulate the old meeting URL.

Files Needing Attention: buzz/events/doctype/buzz_event/buzz_event.py, buzz/api/events/services.py, buzz/ticketing/doctype/event_ticket/event_ticket.py

Important Files Changed

Filename Overview
buzz/events/doctype/buzz_event/buzz_event.py Adds medium-specific location cleanup, but leaves Zoom integration references active when an event becomes in-person.
buzz/api/events/services.py Adds guarded event-detail and route-availability services; the meeting-link fallback can revive a retained Zoom reference.
dashboard/src/pages/manage/events/EventDetails.vue Implements the event details form, dirty-state tracking, aggregate persistence, and actionable save errors.
dashboard/src/components/dashboard/events/EventMedium.vue Implements medium switching and clears visible opposite-medium fields, but relies on incomplete server cleanup for persisted Zoom references.
dashboard/src/components/dashboard/events/EventRoute.vue Adds saved-route controls and debounced availability feedback with stale-response protection.
dashboard/src/layouts/ManagerLayout.vue Switches the manager sidebar to event-specific destinations when an event route is active.
dashboard/src/router.ts Adds event details and placeholder manager routes under the existing manager shell.

Fix all with Greploop Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
### Issue 1
buzz/events/doctype/buzz_event/buzz_event.py:112-116
**Zoom references survive medium changes**

When a Zoom-backed event is changed from Online to In Person, `clear_unused_location` clears only `meeting_link` and retains `zoom_meeting` or `zoom_webinar`, causing ticket submission to keep registering attendees with the obsolete Zoom session and allowing the old URL to reappear if the event is switched online again.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (8): Last reviewed commit: "fix(dashboard): show the server's own me..." | Re-trigger Greptile

Comment thread dashboard/src/components/dashboard/events/EventMedium.vue Outdated
Comment thread dashboard/src/components/dashboard/events/EventRoute.vue Outdated
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-create-event branch from b158200 to e28b2a2 Compare August 17, 2026 10:44
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-manage branch from f07ae4b to 3ed8280 Compare August 17, 2026 10:44
Comment thread dashboard/src/pages/manage/events/EventDetails.vue
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-create-event branch from e28b2a2 to 76c03ac Compare August 17, 2026 13:30
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-manage branch from 3ed8280 to a03d5d1 Compare August 17, 2026 13:30
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-create-event branch from 76c03ac to 45a5841 Compare August 19, 2026 06:14
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-manage branch from a03d5d1 to 42d87f1 Compare August 19, 2026 06:14
@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

UI Demo Check — a screenshot or demo is attached.

@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-manage branch from 42d87f1 to ef955eb Compare August 19, 2026 07:20
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-create-event branch from 45a5841 to a42088d Compare August 19, 2026 07:20
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-create-event branch from a42088d to f8b03af Compare August 19, 2026 14:33
Base automatically changed from version-2-dashboard-create-event to develop August 25, 2026 17:36
harshtandiya and others added 6 commits August 25, 2026 23:16
An event card's Manage button had nowhere to go. It now opens the event
into the manager shell at /manage/events/<id>, where the sidebar carries
the event's own destinations — back out, details, attendees, talks —
in place of the personal and team ones.

The sections have no pages yet, so they land on the work-in-progress
placeholder the other unbuilt destinations already use. Reusing the
layout rather than adding a second one keeps the shell, the team
switcher and the user menu identical on both sides of the switch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A team's events page lists nothing but events the viewer can manage, so a
Manage button on every card is noise. The card takes a routeToManage prop
instead: when it is set, the card itself becomes the link into the event
workspace and the button steps aside, since one link inside another is
neither valid nor clickable.

The prop only takes effect for a host, so a card the viewer merely holds a
ticket to stays inert either way.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The first real section of the event workspace. It carries the same page
header the team pages use, with a trail of the event and the section being
looked at, and nothing else yet — the content follows.

The event is named from the feed the dashboard already loads rather than a
second request, so the page reads the title straight out of the events
list it was opened from. Details also takes the receipt-text icon in the
sidebar.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The details page now carries the event itself: the banner, the name, a
short description under it, the long about, when it runs, and where. Edits
are held locally and written in one go, so Save only appears once something
has actually changed.

Where is now asked in two steps rather than one. A pair of toggles picks
the medium, and only then does the page ask for the answer that medium
needs — a venue and its address for an event in a room, a meeting link with
a copy button for one online. The old combobox folded both into a single
list, which meant picking Zoom to say the event was virtual.

Buzz Event gains meeting_link for that second case: the Zoom field belongs
to an app the site may not have, and an organiser with a link of their own
had nowhere to put it. get_event serves the page, resolving the venue's
address and falling back to the booked Zoom meeting's link. Writes go
through frappe.client.set_value, since the team permission hooks already
guard the doctype.

The banner moves into EventBanner, shared with the create page it came
from.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The details page shows the address the event answers to, beside its name:
the host as fixed text, the route after the slash as the only editable
part, then a way to open the page and a way to copy the link.

Routes are the public URL namespace and so are unique. check_event_route
answers whether one is free while it is being typed, counting unpublished
events too — an event holds its route whether or not anyone can see it yet
— and refusing the segments reserved so an event cannot shadow /b/account.
The verdict appears under the field rather than waiting for a failed save.

The chip reads host/route the way the address is spoken, while the link
and the copied text carry the /b/register prefix the page is actually
served under.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Green read as a status the chip does not have. The swap alone says the
link was copied.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-manage branch from ef955eb to ac11aeb Compare August 25, 2026 17:49
harshtandiya and others added 3 commits August 26, 2026 02:16
Switching an event between in person and online left the other side's value on
the record. `generate_ics_file` and the booking page both read `venue` without
consulting `medium`, so a leftover venue put a physical address on an online
event's calendar invite and registration page.

Cleared on the doctype so the Desk form and the dashboard are both covered, and
in the medium toggle as well so the form shows what was saved.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Each availability response replaced the field's state unconditionally, so a slow
answer for an earlier route could land last and describe a route the organiser
had already moved on from.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`FrappeError.message` is the URL and exception type joined; the text a user can
act on is in `messages`, which is where `_server_messages` lands. A refused save
read "frappe.client.set_value ValidationError" instead of naming the reason.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@harshtandiya
harshtandiya force-pushed the version-2-dashboard-events-manage branch from fbb2b22 to 870fe09 Compare August 25, 2026 20:47
Comment on lines +112 to +116
"""
if self.medium == "Online":
self.venue = None
else:
self.meeting_link = None

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.

P1 Zoom references survive medium changes

When a Zoom-backed event is changed from Online to In Person, clear_unused_location clears only meeting_link and retains zoom_meeting or zoom_webinar, causing ticket submission to keep registering attendees with the obsolete Zoom session and allowing the old URL to reappear if the event is switched online again.

Knowledge Base Used:

Prompt To Fix With AI
This is a comment left during a code review.
Path: buzz/events/doctype/buzz_event/buzz_event.py
Line: 112-116

Comment:
**Zoom references survive medium changes**

When a Zoom-backed event is changed from Online to In Person, `clear_unused_location` clears only `meeting_link` and retains `zoom_meeting` or `zoom_webinar`, causing ticket submission to keep registering attendees with the obsolete Zoom session and allowing the old URL to reappear if the event is switched online again.

**Knowledge Base Used:**
- [Event management domain](https://app.greptile.com/bwh-tech/-/custom-context/knowledge-base/bwhtech/buzz/-/docs/event-management.md)
- [Frappe application integration](https://app.greptile.com/bwh-tech/-/custom-context/knowledge-base/bwhtech/buzz/-/docs/frappe-application-integration.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The mechanism is real — create_zoom_registration_if_applicable (event_ticket.py:72-79) reads the link fields and consults neither medium nor category. But clearing them here would be the wrong fix.

medium is not what governs Zoom anywhere in this app. ZOOM_BACKED_CATEGORIES (utils.py:13) keys on category, and so do validate_zoom_last_names (booking/services.py:185) and dashboard/src/utils/zoomCategory.ts. Clearing zoom_meeting on a medium change would leave an event categorised Zoom Meeting with no meeting, which those two would then act on wrongly, and would orphan a live Zoom session that still holds registrants. Throwing instead would make already-mismatched rows unsaveable — the objection that deferred #375.

And the mismatch predates this branch. On a dev site: event 857, medium = In Person, category = Webinars, zoom_meeting set; In Person / Webinars and Online / Meetups rows both exist in aggregate. The two fields have been drifting since long before the medium was editable.

The real defect is that two independent fields both claim to say whether an event is a Zoom event. Filed as #376 — one has to be derived from the other, and the ticket-time registration should consult whichever survives. Out of scope here.

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.

You're right — this is a category-vs-medium mismatch, not something clear_unused_location can safely resolve. zoom_meeting and zoom_webinar are governed by category, so clearing them on a medium change could orphan an active Zoom session while leaving Zoom-specific validation and registration paths enabled. Given that mismatched legacy rows already exist, rejecting the save here would also be an inappropriate migration-by-validation fix. I'll withdraw this finding from the PR; #376 is the appropriate place to establish a single source of truth and update ticket-time registration.

@harshtandiya
harshtandiya merged commit 5960958 into develop Aug 26, 2026
9 checks passed
@harshtandiya
harshtandiya deleted the version-2-dashboard-events-manage branch August 26, 2026 19:22
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