feat(committees): allow direct member add without invite (LFXV2-2227)#953
feat(committees): allow direct member add without invite (LFXV2-2227)#953andrest50 wants to merge 1 commit into
Conversation
Writers can choose between adding members directly to the roster or sending a pending invite from the Add Member dialog. Signed-off-by: Andres Tobon <andrest2455@gmail.com>
WalkthroughThe add-member dialog gains a two-mode submission flow: "Send invite" (existing behavior) and "Add directly to roster" (new). Shared contracts ( ChangesAdd-member dialog dual-mode support
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. Comment |
There was a problem hiding this comment.
Pull request overview
This PR updates the Committees “Add Member” dialog to support two writer-controlled submission modes: adding members directly to the roster (via createCommitteeMember) or sending pending invites (existing createCommitteeInvite fan-out), with optional enrichment of direct-add payloads using search-selected profile data.
Changes:
- Introduces an
AddMemberActionModetype and corresponding UI option constants for the dialog mode toggle. - Updates the Add Member dialog UI/logic to switch between invite flow and direct-add flow on submit.
- Adds payload enrichment for direct-adds using cached search result profiles (username/name/job title) when available.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| packages/shared/src/interfaces/committee.interface.ts | Adds AddMemberActionMode union type for dialog submission behavior. |
| packages/shared/src/constants/committees.constants.ts | Adds ADD_MEMBER_ACTION_OPTIONS used by the new mode toggle UI. |
| apps/lfx-one/src/app/modules/committees/components/add-member-dialog/add-member-dialog.component.ts | Implements mode-driven submit behavior (invite vs direct add) and direct-add request building/toast summaries. |
| apps/lfx-one/src/app/modules/committees/components/add-member-dialog/add-member-dialog.component.html | Adds the mode toggle UI and updates copy/preview/button label+icon based on selected mode. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| @if (!searchLoading() && searchResults().length === 0 && queryValue().length >= 2) { | ||
| <p class="text-xs text-gray-400">No matches for "{{ queryValue() }}". You can still invite them by typing their email below.</p> | ||
| <p class="text-xs text-gray-400">No matches for "{{ queryValue() }}". You can still add them by typing their email below.</p> |
| public readonly form = new FormGroup({ | ||
| actionMode: new FormControl<AddMemberActionMode>('add_directly', { nonNullable: true }), | ||
| emails: new FormControl<string>('', { nonNullable: true }), | ||
| role: new FormControl<string | null>(null), | ||
| }); |
| private buildMemberRequest(email: string, role: string | null): CreateCommitteeMemberRequest { | ||
| const profile = this.emailProfiles().get(email); | ||
| return { | ||
| email, | ||
| username: profile?.username ?? null, | ||
| first_name: profile?.first_name ?? null, | ||
| last_name: profile?.last_name ?? null, | ||
| job_title: profile?.job_title ?? null, | ||
| role: role ? { name: role as CommitteeMemberRole, start_date: null, end_date: null } : null, | ||
| }; | ||
| } |
| private addFailureReason(err: HttpErrorResponse): string { | ||
| if (err.status === 409) { | ||
| return 'already a member'; | ||
| } | ||
| const upstream = typeof err.error?.message === 'string' ? err.error.message : null; | ||
| return upstream ?? 'add failed'; | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
apps/lfx-one/src/app/modules/committees/components/add-member-dialog/add-member-dialog.component.ts (1)
14-27: ⚡ Quick winUse direct shared-module imports instead of shared barrel imports in this standalone component.
Line 14 and Line 17 currently import from barrel paths (
@lfx-one/shared/constants,@lfx-one/shared/interfaces). Please switch these to direct shared module paths to match the standalone import rule.♻️ Suggested import update
-import { ADD_MEMBER_ACTION_OPTIONS, COMMITTEE_INVITE_CONCURRENCY, MEMBER_ROLES } from '`@lfx-one/shared/constants`'; -import { CommitteeMemberRole } from '`@lfx-one/shared/enums`'; +import { ADD_MEMBER_ACTION_OPTIONS, COMMITTEE_INVITE_CONCURRENCY, MEMBER_ROLES } from '`@lfx-one/shared/constants/committees.constants`'; +import { CommitteeMemberRole } from '`@lfx-one/shared/enums/committee-member.enum`'; import { AddMemberActionMode, CategorizedCommitteeEmails, Committee, CommitteeInvite, CommitteeInviteResult, CommitteeMember, CreateCommitteeMemberRequest, DecoratedCommitteeSearchResult, EmailListParseResult, UserSearchResult, -} from '`@lfx-one/shared/interfaces`'; +} from '`@lfx-one/shared/interfaces/committee.interface`';As per coding guidelines:
**/*.{ts,tsx}should use direct imports for standalone components (no barrel exports) and use@lfx-one/shared/*direct paths.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/lfx-one/src/app/modules/committees/components/add-member-dialog/add-member-dialog.component.ts` around lines 14 - 27, The add-member-dialog.component.ts file is a standalone component that is currently using barrel imports from `@lfx-one/shared/constants` and `@lfx-one/shared/interfaces`, which violates the standalone component import rule. Replace the barrel imports for ADD_MEMBER_ACTION_OPTIONS, COMMITTEE_INVITE_CONCURRENCY, MEMBER_ROLES (from `@lfx-one/shared/constants`) and all the interface imports like AddMemberActionMode, CategorizedCommitteeEmails, Committee, CommitteeInvite, CommitteeInviteResult, CommitteeMember, CreateCommitteeMemberRequest, DecoratedCommitteeSearchResult, EmailListParseResult, UserSearchResult (from `@lfx-one/shared/interfaces`) with direct shared module paths following the `@lfx-one/shared/`* convention as required for standalone components.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In
`@apps/lfx-one/src/app/modules/committees/components/add-member-dialog/add-member-dialog.component.ts`:
- Around line 14-27: The add-member-dialog.component.ts file is a standalone
component that is currently using barrel imports from `@lfx-one/shared/constants`
and `@lfx-one/shared/interfaces`, which violates the standalone component import
rule. Replace the barrel imports for ADD_MEMBER_ACTION_OPTIONS,
COMMITTEE_INVITE_CONCURRENCY, MEMBER_ROLES (from `@lfx-one/shared/constants`) and
all the interface imports like AddMemberActionMode, CategorizedCommitteeEmails,
Committee, CommitteeInvite, CommitteeInviteResult, CommitteeMember,
CreateCommitteeMemberRequest, DecoratedCommitteeSearchResult,
EmailListParseResult, UserSearchResult (from `@lfx-one/shared/interfaces`) with
direct shared module paths following the `@lfx-one/shared/`* convention as
required for standalone components.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3afcd716-4aec-4200-90cc-d4005ae61c9d
📒 Files selected for processing (4)
apps/lfx-one/src/app/modules/committees/components/add-member-dialog/add-member-dialog.component.htmlapps/lfx-one/src/app/modules/committees/components/add-member-dialog/add-member-dialog.component.tspackages/shared/src/constants/committees.constants.tspackages/shared/src/interfaces/committee.interface.ts
🚀 Deployment StatusYour branch has been deployed to: https://ui-pr-953.dev.v2.cluster.linuxfound.info Deployment Details:
The deployment will be automatically removed when this PR is closed. |
Summary
createCommitteeMember; invite mode preserves the existingcreateCommitteeInvitebulk behaviorTest plan
Made with Cursor