Skip to content

feat(meetings): add the v2 rsvp card - #3348

Merged
nunoeufrasio merged 3 commits into
feat/meeting-details-v2from
feat/issue-2881
Oct 7, 2026
Merged

nunoeufrasio merged 3 commits into
feat/meeting-details-v2from
feat/issue-2881

Conversation

@nunoeufrasio

Copy link
Copy Markdown
Contributor

Closes #2881 · epic #1765 · targets the integration branch feat/meeting-details-v2

Summary

E2-05 adds the prototype's "Will you attend?" RSVP card, the action slot's rsvp kind (FR-023 / FR-024). It replaces the one-line placeholder from E2-04.

  • Answers: Yes, I'll attend / Maybe / Can't attend. They are 42px pills outlined in the answer's colour and filled once it is the answer (aria-pressed). RSVP is a three-value enum; "pending" is the absence of a record.

  • Confirmation: once answered, the card shows the answer ("You're going", "You replied maybe", "You can't attend") with Change. While changing, Keep my answer backs out.

  • Series scope (FR-024): when meeting.recurrence is set, the card asks All occurrences / This occurrence only / This and following occurrences before saving, using lfx-radio-button with a reactive form. A single meeting saves scope: 'all' silently.

  • Saving, as V1's lfx-rsvp-button-group does:

    • the same request, with occurrence_id for single and this_and_following;
    • the same "RSVP Updated" / "RSVP Failed" toasts;
    • the same 404 copy, "Only invited users are allowed to RSVP to this meeting.", plus the BFF's message or V1's generic fallback otherwise.

    The saved RSVP goes to MeetingDetailsStateService.setMyRsvp (E2-04), so the status pill and the card update at once, ahead of the indexer.

  • An organizer who isn't invited still gets this card from the resolver, but the page only loads an invitee's own answer. The card therefore keeps the answer it saved, so a save never looks like it didn't happen.

  • Accessibility:

    • Every step change moves focus to the step's control: the current answer, the checked scope, the opening answer on cancel, or Change after a save.
    • A save is announced once, through a persistent polite live region.
    • The error is role="alert".
    • The step state resets when the page moves to another meeting or occurrence (linkedSignal).
  • Testids: meeting-rsvp-card* rows added to testid-contract.md. data-my-rsvp moves from the placeholder line to the card.

Deviation from the issue

The issue asks to restyle the scope modal. The scope question is instead a step inside the card:

  • V1's RsvpScopeModalComponent is shared with V1 and the meeting cards (and carries V1's testids), so restyling it would change V1.
  • A new V2 dialog would be appended to <body>, outside the page's scoped --md-* design tokens.

The options, words and behaviour are V1's.

The issue's "RSVP not tracked" presentation is N-01's (#3263); it is not in this PR.

Validation

  • Tests: meetings 948 (card spec 16). yarn build, a forced check-types, lint:check (0 errors) and format:check are green.
  • Coverage:
    • each answer;
    • Change and Keep my answer;
    • the single meeting's silent all;
    • each scope, and occurrence_id only for single and this_and_following;
    • cancel;
    • saving disabled;
    • the 404, BFF and generic copy;
    • the announcement;
    • focus after each step;
    • the uninvited-organizer fallback;
    • the reset when the occurrence changes.
  • Pre-PR review: one round with the general, repo-code and learnings reviewers. Fixed in 4b60d6f:
    • focus handling;
    • a persistent live region;
    • the uninvited-organizer save not showing;
    • Change having no way back, and its state surviving an occurrence change;
    • the raw radio replaced with lfx-radio-button.
  • /lfx-self-serve-pr-readiness (against the integration branch) READY; /preflight passes.

🤖 Generated with Claude Code

Closes #2881

Signed-off-by: Nuno Eufrásio <nmeufrasio@gmail.com>
Refs #2881

Signed-off-by: Nuno Eufrásio <nmeufrasio@gmail.com>
@nunoeufrasio
nunoeufrasio requested a review from a team as a code owner October 7, 2026 11:29
Copilot AI balanced review requested due to automatic review settings October 7, 2026 11:29
@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: c84830e5-2475-4f93-8036-d3873e6b8526

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@cursor

cursor Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

PR Summary

Medium Risk
New user-facing RSVP writes and recurring scope behavior on meeting details; mitigated by reusing V1 API/contracts and broad unit tests, but still touches invite-only and occurrence-keyed state.

Overview
Replaces the meeting details action slot’s one-line RSVP placeholder (E2-04) with a full lfx-meeting-rsvp-card for the rsvp kind (E2-05, FR-023 / FR-024). The slot no longer builds rsvpMessage or data-my-rsvp on meeting-action-message; that lives on the card.

The new card offers Yes / Maybe / Can’t attend, shows a confirmation with Change / Keep my answer, and for recurring meetings adds an in-card scope step (all / this occurrence / this and following) instead of V1’s modal. Saves use the existing createMeetingRsvp API and setMyRsvp, with V1 toasts and error copy, guards for navigation mid-save, focus management, and a live region for announcements.

Tests and testid-contract.md are updated: action-slot specs assert the card stub; the card has a dedicated spec suite.

Reviewed by Cursor Bugbot for commit ff50ca1. Bugbot is set up for automated code reviews on this repo. Configure here.

dealako commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

@nunoeufrasio I'm starting review 1 of this pull request now (started 2026-10-07 11:40 UTC). This usually takes a few minutes — I'll update this comment with the summary when I'm done.


Hi @nunoeufrasio, thanks for the PR. The V2 RSVP card is well scoped: it reuses V1's request, toasts and copy, and keeping the scope question inside the card rather than restyling the shared V1 modal is a sound call. The focus handling, persistent live region and linkedSignal resets are careful, and the spec covers the behaviours the description lists.

🟡 Minor: 1 issue: A save that finishes after an occurrence switch writes into the new occurrence's state
⚪ Nit: 1 issue: Import order in the spec

✅ Approved with minor comments

➡️ This auto-review agent is a preview. Please send feedback to @dealako.

@dealako dealako 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.

Approved: no blocking, security or privacy findings. One minor (stale save after an occurrence switch) and one nit are inline.


Generated by Claude Code

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Pending saves can mutate a newly selected occurrence, and several loading and announcement edge cases remain.

Review effort: Balanced
Findings: 3 Medium severity

Open (3)
What changed in this PR

Adds the Meeting Details V2 RSVP card and recurring-series scope workflow.

Changes:

  • Adds RSVP selection, confirmation, saving, errors, focus management, and announcements.
  • Integrates the card into the action slot.
  • Adds unit coverage and test-ID documentation.
File Description
specs/​.../​testid-contract.md Documents RSVP card test IDs.
rsvp-card.component.ts Implements RSVP state and persistence.
rsvp-card.component.html Renders the accessible card workflow.
rsvp-card.component.spec.ts Tests RSVP behavior.
action-slot.component.ts Imports the RSVP card.
action-slot.component.html Renders the card for RSVP slots.
action-slot.component.spec.ts Tests action-slot integration.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4b60d6f. Configure here.

Refs #2881

Signed-off-by: Nuno Eufrásio <nmeufrasio@gmail.com>
Copilot AI balanced review requested due to automatic review settings October 7, 2026 11:40

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

RSVP fallback and concurrent-save handling remain incorrect, and the card bypasses the required shared button wrapper.

Review effort: Balanced
Findings: None

Resolved since last review (3)
Previously missed (2)

In code that hasn't changed since last review

Medium severity Preserve saved RSVP responses across occurrence changes

apps/​lfx-one/​src/​app/​modules/​meetings/​meeting-details-page/​components/​rsvp-card/​rsvp-card.component.ts:83

savedResponse is reset whenever rsvpKey changes. For the uninvited-organizer path this fallback exists to support, state.myRsvp() stays unknown, so saving on occurrence A, visiting B, and returning to A shows an unanswered card again; an all-scope save is likewise forgotten on the next occurrence. Preserve successful responses by their applicable meeting/occurrence scope instead of discarding them on every key transition.

This issue also appears in the following locations of the same file:

  • line 91
  • line 167
Low severity Use lfx-button controls instead of native buttons

apps/​lfx-one/​src/​app/​modules/​meetings/​meeting-details-page/​components/​rsvp-card/​rsvp-card.component.html:70

The meeting-details epic explicitly requires existing lfx-* controls and says not to rebuild buttons. The shared ButtonComponent already supports loading, disabled, styleClass, and ariaPressed, but this card introduces native buttons for the answers and the Change/Save/Cancel/Keep controls. Use lfx-button throughout (extending the wrapper only if a capability is genuinely missing) to preserve the stated component-reuse boundary.

@nunoeufrasio
nunoeufrasio merged commit ab9b044 into feat/meeting-details-v2 Oct 7, 2026
10 checks passed
@nunoeufrasio
nunoeufrasio deleted the feat/issue-2881 branch October 7, 2026 11:55
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.

3 participants