feat(committees): import meeting registrants into add-member flow - #1081
feat(committees): import meeting registrants into add-member flow#1081manishdixitlfx wants to merge 3 commits into
Conversation
Add an optional "Import from a meeting" picker to the committee AddMemberDialog so a group manager can pull a meeting's registrant emails straight into the invite list instead of re-typing them (LFXV2-2607). The picker lists meetings in the committee's project via the existing getMeetingsByProject endpoint; on Import, getMeetingRegistrants returns the full roster (the BFF auto-pages) and a new shared util extractRegistrantEmails trims, de-dupes case-insensitively, and counts registrants with no email. Those emails are appended to the existing emails textarea, so they flow through the existing parse/dedupe/preview and bounded-concurrency invite fan-out unchanged. No new BFF routes. Invite-based only (direct add is LFXV2-2227); no role/org prefill from registrant records in v1; registrants without an email are skipped and surfaced in the import summary. Signed-off-by: Manish Dixit <mdixit@linuxfoundation.org>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
- Restore MeetingRegistrant's JSDoc (the new interfaces had split it from its declaration); place MeetingSelectOption/RegistrantEmailExtraction above it. - Guard the meeting sort comparator against unparseable start_time (NaN → 0). - Clear a stale import summary when a registrant fetch fails. Signed-off-by: Manish Dixit <mdixit@linuxfoundation.org>
There was a problem hiding this comment.
Pull request overview
This PR adds an optional "Import from a meeting" picker to the committee AddMemberDialogComponent, letting a group manager pull a meeting's registrant emails into the add-member flow instead of re-typing them. It reuses existing endpoints (getMeetingsByProject, getMeetingRegistrants) and feeds imported emails into the dialog's existing parse → dedupe → preview → invite fan-out, so no invite logic is duplicated. A new shared util extractRegistrantEmails trims, case-insensitively de-dupes, and counts email-less registrants.
Changes:
- New shared util
extractRegistrantEmails(+ two supporting interfacesMeetingSelectOption/RegistrantEmailExtraction) with Vitest coverage. - Import picker wiring in
AddMemberDialogComponent(meeting fetch/sort, registrant import, dedupe against already-listed emails, human-readable summary). - Template section rendering the meeting select + Import button and summary line.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/shared/src/utils/meeting.utils.ts | Adds extractRegistrantEmails to trim/dedupe emails and count skipped registrants |
| packages/shared/src/utils/meeting.utils.spec.ts | Vitest cases covering mixed/blank/case-insensitive/nullish inputs |
| packages/shared/src/interfaces/meeting.interface.ts | Adds MeetingSelectOption and RegistrantEmailExtraction; insertion orphans the MeetingRegistrant JSDoc |
| apps/lfx-one/src/app/modules/committees/components/add-member-dialog/add-member-dialog.component.ts | Import picker logic: meeting options, registrant fetch, dedupe append, summary |
| apps/lfx-one/src/app/modules/committees/components/add-member-dialog/add-member-dialog.component.html | Renders the import section (select + button + summary) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /** | ||
| * Dropdown option for the "import registrants from a meeting" picker (LFXV2-2607). | ||
| * `label` is the display string (title + date); `title` is kept separately so | ||
| * import summaries can name the meeting cleanly. | ||
| */ | ||
| export interface MeetingSelectOption { | ||
| /** Meeting id passed to the registrants fetch */ | ||
| value: string; | ||
| /** Display label, e.g. "Q3 Roadmap — Jul 3, 2026" */ | ||
| label: string; | ||
| /** Bare meeting title, for summary copy */ | ||
| title: string; | ||
| } | ||
|
|
||
| /** | ||
| * Result of pulling invite-ready emails off a meeting's registrant list. | ||
| * `emails` is de-duplicated (case-insensitive, first-seen casing preserved); | ||
| * `skippedNoEmail` counts registrants that carried no usable email. | ||
| */ | ||
| export interface RegistrantEmailExtraction { | ||
| /** Unique, trimmed registrant emails ready to feed the invite flow */ | ||
| emails: string[]; | ||
| /** Count of registrants skipped because they had no email */ | ||
| skippedNoEmail: number; | ||
| } |
Bind the Import button's disabled state to importForm.value.meeting instead
of importForm.get('meeting')!.value, removing a non-null assertion from the
template (preflight type-safety check).
Signed-off-by: Manish Dixit <mdixit@linuxfoundation.org>
jordane
left a comment
There was a problem hiding this comment.
This should be implemented with a proper async request in the backend, rather than relying on the UI/BFF to implement it. Similar UI+BFF-only implementations in PCC have been notoriously problematic.
LFXV2-2607 — Import meeting registrants into a group
Lets a group manager pull a meeting's registrants into the group instead of re-typing them. Today linking is one-way only (committee → meeting via
MeetingCommitteeManagerComponent); there was no registrants → group path. A real manager (Connie, Velocity Engine) built the meeting roster first and faced full manual re-entry into the group.What changed
Adds an optional "Import from a meeting" picker to the committee
AddMemberDialogComponent:MeetingService.getMeetingsByProjectendpoint.getMeetingRegistrantsreturns the full roster (the BFF auto-pages internally), and a new shared utilextractRegistrantEmailstrims, de-dupes case-insensitively, and counts registrants with no email.emailstextarea, so they flow through the existing parse → dedupe (already-member / already-invited / invalid) → preview → bounded-concurrency invite fan-out unchanged. No invite logic is duplicated.Decisions (per ticket)
getMeetingsByProjectandgetMeetingRegistrants.No 2606 / commit 9d497dc dependency
The ticket noted
existingInvitesmight depend on a pendinggetCommitteeInvites()from PR #1078 (feat/LFXV2-2606-wizard-bulk-invite). That does not apply to this surface:getCommitteeInvites()is already onmainand this dialog's member+invite dedupe was already wired. Commit9d497dcis a separate dedupe fix incommittee-members-manager.component.ts, unrelated here. No rebase or cherry-pick.Tests
extractRegistrantEmails(mixed valid/blank, case-insensitive dedupe, all-blank, empty/nullish).yarn check-types,yarn lint,yarn build(SSR bundle) all pass.Draft: pending integration validation before marking ready for review.