Skip to content

Conversation

@asithade
Copy link
Contributor

Summary

  • Add OrganizationSearchComponent with search and manual input modes
  • Integrate organization API backend with debounced search via microservice proxy
  • Update member and registrant forms to use new search component
  • Enhance autocomplete component with template projection and appendTo
  • Add URL validation utilities for domain normalization

Technical Details

  • Organization Search Component: Reusable component with typeahead search and manual fallback mode
  • Microservice Integration: Uses microservice proxy to call /query/orgs/suggest?v=1&query=<term>
  • URL Normalization: Added normalizeToUrl() and isValidDomain() utilities for consistent URL handling
  • Form Integration: Updated member and registrant forms to use the new search component
  • Enhanced Autocomplete: Added template projection and appendTo support for better UX

API Integration

  • Endpoint: /api/organizations/search
  • Backend calls: /query/orgs/suggest?v=1&query=<searchTerm>
  • Response format: { suggestions: [{ name: string, domain: string }] }
  • Includes fallback to mock data when API is unavailable

Testing

  • Added comprehensive data-testid attributes for E2E testing
  • Build passes with full lint and type checking
  • Maintains existing test structure and patterns

JIRA References

  • LFXV2-575: Organization search component implementation
  • LFXV2-576: URL validation and normalization utilities
  • LFXV2-577: Autocomplete component enhancements

🤖 Generated with Claude Code

- Add OrganizationSearchComponent with search and manual input modes
- Integrate organization API backend with debounced search via microservice proxy
- Update member and registrant forms to use new search component
- Enhance autocomplete component with template projection and appendTo
- Add URL validation utilities for domain normalization
- Create organization service, controller, and interfaces using microservice proxy pattern
- Add comprehensive data-testid attributes for E2E testing

References: LFXV2-575, LFXV2-576, LFXV2-577

Generated with [Claude Code](https://claude.ai/code)

Signed-off-by: Asitha de Silva <[email protected]>
@asithade asithade requested a review from jordane as a code owner September 24, 2025 00:09
Copilot AI review requested due to automatic review settings September 24, 2025 00:09
@coderabbitai
Copy link

coderabbitai bot commented Sep 24, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds an organization search UI with autocomplete and manual-entry; replaces direct org name/URL inputs in member and registrant forms with OrganizationSearchComponent; adds client/server org search services, controller/routes, shared interfaces and URL utilities, autocomplete enhancements, and a normalize URL pipe.

Changes

Cohort / File(s) Summary
Member form integration
apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.html, apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.ts
Replaced organization name/URL inputs and cross-field validator with lfx-organization-search; removed URL pattern validator and related validator imports; added OrganizationSearchComponent to standalone imports.
Registrant form integration
apps/lfx-one/src/app/modules/project/meetings/components/registrant-form/registrant-form.component.html, apps/lfx-one/src/app/modules/project/meetings/components/registrant-form/registrant-form.component.ts
Replaced org name input with lfx-organization-search and added OrganizationSearchComponent to imports; no other logic changes.
Autocomplete enhancements
apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.html, apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.ts
Added appendTo input and support for an empty template via ContentChild; included CommonModule and ngTemplateOutlet to render empty-state template.
New OrganizationSearch component
apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.html, apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.ts
New component: autocomplete-backed org search with manual-entry mode; inputs for parent form and control names, styling props, dataTestId, disabled; emits selection; syncs with parent controls and normalizes domain to URL.
Client service
apps/lfx-one/src/app/shared/services/organization.service.ts
New Angular service calling /api/organizations/search?query=..., validates input length, maps response to OrganizationSuggestion[], and returns empty array on error.
Normalize URL pipe
apps/lfx-one/src/app/shared/pipes/normalize-url.pipe.ts
New standalone normalizeUrl pipe delegating to shared normalizeToUrl; returns null for falsy input.
Server API: controller & routes
apps/lfx-one/src/server/controllers/organization.controller.ts, apps/lfx-one/src/server/routes/organizations.route.ts, apps/lfx-one/src/server/server.ts
New controller handling GET /organizations/search with validation and error propagation; new route mounted at /api/organizations and wired into server.
Server service (microservice proxy)
apps/lfx-one/src/server/services/organization.service.ts
New server-side service proxying to LFX_V2_SERVICE /query/orgs/suggest endpoint and returning suggestions.
Shared interfaces
packages/shared/src/interfaces/organization.interface.ts, packages/shared/src/interfaces/index.ts
Added OrganizationSuggestion and OrganizationSuggestionsResponse interfaces and re-exported them from interfaces index.
URL utilities
packages/shared/src/utils/url.utils.ts
Added isValidDomain and normalizeToUrl helpers for domain validation and normalization; reused existing URL utilities.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant MF as Member/Registrant Form
  participant OSC as OrganizationSearchComponent
  participant AC as Autocomplete
  participant FE as Client OrgService
  participant API as /api/organizations
  participant CTRL as OrgController
  participant SVC as Server OrgService
  participant MS as LFX_V2_SERVICE

  U->>OSC: Type query
  OSC->>AC: Set autocomplete value
  AC-->>OSC: complete event (debounced)
  OSC->>FE: searchOrganizations(query)
  FE->>API: GET /organizations/search?query=...
  API->>CTRL: route
  CTRL->>SVC: searchOrganizations(req, query)
  SVC->>MS: GET /query/orgs/suggest?q=...
  MS-->>SVC: suggestions[]
  SVC-->>CTRL: suggestions[]
  CTRL-->>API: JSON { suggestions }
  API-->>FE: suggestions[]
  FE-->>OSC: suggestions[]
  OSC-->>AC: render suggestions
  U->>AC: Select organization
  AC-->>OSC: select event
  note over OSC: Update parent form controls (nameControl, domainControl normalized)
  OSC-->>MF: Emit onOrganizationSelect (optional)

  alt Manual mode
    U->>OSC: Switch to manual
    OSC->>MF: Populate name control from current search
    note over OSC: Manual fields rendered
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning Most coding objectives from the linked issues are implemented: the OrganizationSearchComponent with manual mode, name/domain controls and debounced search plus client/server integration and interfaces were added LFXV2-575, URL utilities and a NormalizeUrlPipe were implemented [LFXV2-576], and the Autocomplete component gained ContentChild empty-template projection and appendTo support [LFXV2-577]; however, the MemberFormComponent summary shows removal of the previous cross-field and organization_url pattern validators and the changes do not clearly show equivalent validation being enforced for manual domain entry in the new component, leaving the "proper form validation" acceptance criterion unverified. Restore or explicitly reimplement form validation for organization name/domain either on the parent form or inside OrganizationSearchComponent (use normalizeToUrl/isValidDomain to set validation errors), add unit and E2E tests that cover manual-entry and selection flows, and update the PR to show where validators are applied so the acceptance criterion is verifiably satisfied.
Out of Scope Changes Check ❓ Inconclusive All modified files are directly related to implementing organization search, its server route/service, shared interfaces, utilities and the autocomplete enhancement, so there are no obvious unrelated feature changes; the notable deviation is the removal of cross-field and pattern validators from MemberFormComponent which may be an intended refactor but should be confirmed as it could be an out-of-scope regression if unintentional. Confirm whether removal of the MemberFormComponent validators was intentional as part of the refactor; if it was unintended, revert or reintroduce equivalent validation (or move it into OrganizationSearchComponent) and include tests demonstrating expected validation behavior.
✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title is a concise, single sentence that accurately summarizes the primary change (adding an organization search with typeahead) and follows the conventional commit style "feat(ui):", making it clear and relevant to the changeset.
Description Check ✅ Passed The pull request description is detailed and directly related to the changeset, documenting the OrganizationSearchComponent, backend API route and proxy integration, URL utilities and pipe, autocomplete enhancements, form updates, and relevant JIRA references, so it provides useful context for reviewers.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/LFXV2-575

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

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements an organization search component with typeahead functionality, allowing users to search for organizations via a microservice API and fall back to manual entry when needed.

  • Organization search component with debounced API integration and manual entry fallback
  • Backend API endpoints for organization search using microservice proxy
  • URL validation utilities for domain normalization and validation

Reviewed Changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/shared/src/utils/url.utils.ts Added URL validation and normalization utility functions
packages/shared/src/interfaces/organization.interface.ts Defined organization search interfaces
packages/shared/src/interfaces/index.ts Exported organization interfaces
apps/lfx-one/src/server/services/organization.service.ts Backend service for organization search via microservice proxy
apps/lfx-one/src/server/server.ts Added organizations router to server
apps/lfx-one/src/server/routes/organizations.route.ts API route for organization search endpoint
apps/lfx-one/src/server/controllers/organization.controller.ts Controller handling organization search requests
apps/lfx-one/src/app/shared/services/organization.service.ts Frontend service for organization API calls
apps/lfx-one/src/app/shared/pipes/normalize-url.pipe.ts Angular pipe for URL normalization
apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.ts Main organization search component with typeahead
apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.html Template for organization search component
apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.ts Enhanced autocomplete with template projection
apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.html Added empty template support
apps/lfx-one/src/app/modules/project/meetings/components/registrant-form/registrant-form.component.ts Updated to use organization search
apps/lfx-one/src/app/modules/project/meetings/components/registrant-form/registrant-form.component.html Replaced input with organization search component
apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.ts Updated to use organization search and removed custom validation
apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.html Replaced organization fields with search component

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@github-actions
Copy link

github-actions bot commented Sep 24, 2025

✅ E2E Tests Passed

Browser: chromium
Status: passed

All E2E tests passed successfully.

Test Configuration

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.ts (1)

62-66: Potential NPE: committee() may be undefined before accessing uid.

Directly accessing this.committee().uid can throw. Use optional chaining.

-      const committeeId = this.committee().uid;
+      const committeeId = this.committee()?.uid;
🧹 Nitpick comments (8)
apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.ts (1)

32-32: Narrow appendTo typing

PrimeNG accepts string | HTMLElement. Prefer a precise type for better DX.

Apply this diff:

- public appendTo = input<any>(undefined);
+ public appendTo = input<string | HTMLElement | null>(null);
apps/lfx-one/src/server/server.ts (1)

22-23: Route wiring looks correct; consider resiliency controls

Mounting /api/organizations after auth is correct.

Ensure the downstream org-suggest call uses:

  • Per-request timeout and abort (e.g., 2–5s)
  • Bounded retries with jittered backoff
  • Circuit breaker or cache fallback for transient outages

If not already in OrganizationService, add these to avoid request thread starvation during upstream latency spikes.

Also applies to: 203-204

apps/lfx-one/src/app/modules/project/meetings/components/registrant-form/registrant-form.component.html (1)

68-77: Associate label with the actual input for a11y

for="org_name" won’t bind to the inner input generated by lfx-organization-search. Consider adding an inputId input to the search component that forwards to its internal input, then set for to that id.

apps/lfx-one/src/server/controllers/organization.controller.ts (1)

14-15: Inject the service for testability (avoid hard new).

Direct instantiation makes the controller harder to unit test/mocks. Prefer constructor injection with a sensible default.

-export class OrganizationController {
-  private organizationService: OrganizationService = new OrganizationService();
+export class OrganizationController {
+  private readonly organizationService: OrganizationService;
+
+  public constructor(organizationService?: OrganizationService) {
+    this.organizationService = organizationService ?? new OrganizationService();
+  }
apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.html (1)

48-61: Optional: Set appendTo to avoid overlay clipping.

If OrganizationSearchComponent forwards appendTo to the underlying dropdown, consider appendTo="body" to prevent z-index/overflow issues in dialogs.

-        panelStyleClass="text-sm w-full"
+        panelStyleClass="text-sm w-full"
+        appendTo="body"
apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.ts (2)

95-101: Normalize organization URL before submit.

Apply normalizeToUrl() so servers receive a normalized URL (https prefix, etc.). It returns null for invalid inputs.

-                website: formValue.organization_url || null,
+                website: normalizeToUrl(formValue.organization_url) || null,

Add the import (outside this hunk):

// update existing import
import { formatDateToISOString, parseISODateString, normalizeToUrl } from '@lfx-one/shared/utils';

157-173: Optional: adopt typed reactive forms.

Defining a FormGroup with typed controls will improve safety over FormControl access and reduce runtime casts.

apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.ts (1)

73-85: Sync effect doesn’t clear the inner field when parent name is cleared.

Add an else branch to reset organizationSearch so modes stay in sync.

       if (parentForm && nameControlName) {
         const nameControlValue = parentForm.get(nameControlName)?.value;
 
-        if (nameControlValue && nameControlValue.trim()) {
-          this.organizationForm.get('organizationSearch')?.setValue(nameControlValue, { emitEvent: false });
-        }
+        const searchCtrl = this.organizationForm.get('organizationSearch');
+        if (nameControlValue && nameControlValue.trim()) {
+          searchCtrl?.setValue(nameControlValue, { emitEvent: false });
+        } else {
+          searchCtrl?.setValue('', { emitEvent: false });
+        }
       }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a08bc3a and 5396737.

📒 Files selected for processing (17)
  • apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.ts (3 hunks)
  • apps/lfx-one/src/app/modules/project/meetings/components/registrant-form/registrant-form.component.html (1 hunks)
  • apps/lfx-one/src/app/modules/project/meetings/components/registrant-form/registrant-form.component.ts (1 hunks)
  • apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.html (1 hunks)
  • apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.ts (2 hunks)
  • apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.html (1 hunks)
  • apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.ts (1 hunks)
  • apps/lfx-one/src/app/shared/pipes/normalize-url.pipe.ts (1 hunks)
  • apps/lfx-one/src/app/shared/services/organization.service.ts (1 hunks)
  • apps/lfx-one/src/server/controllers/organization.controller.ts (1 hunks)
  • apps/lfx-one/src/server/routes/organizations.route.ts (1 hunks)
  • apps/lfx-one/src/server/server.ts (2 hunks)
  • apps/lfx-one/src/server/services/organization.service.ts (1 hunks)
  • packages/shared/src/interfaces/index.ts (1 hunks)
  • packages/shared/src/interfaces/organization.interface.ts (1 hunks)
  • packages/shared/src/utils/url.utils.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript interfaces instead of union types for better maintainability
When defining PrimeNG-related types, reference the official PrimeNG component interfaces

Files:

  • apps/lfx-one/src/server/server.ts
  • apps/lfx-one/src/app/modules/project/meetings/components/registrant-form/registrant-form.component.ts
  • apps/lfx-one/src/server/services/organization.service.ts
  • packages/shared/src/interfaces/organization.interface.ts
  • packages/shared/src/interfaces/index.ts
  • apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.ts
  • apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.ts
  • apps/lfx-one/src/app/shared/pipes/normalize-url.pipe.ts
  • apps/lfx-one/src/server/routes/organizations.route.ts
  • apps/lfx-one/src/server/controllers/organization.controller.ts
  • apps/lfx-one/src/app/shared/services/organization.service.ts
  • apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.ts
  • packages/shared/src/utils/url.utils.ts
**/*.{ts,tsx,js,jsx,mjs,cjs,html,css,scss}

📄 CodeRabbit inference engine (CLAUDE.md)

Include required license headers on all source files

Files:

  • apps/lfx-one/src/server/server.ts
  • apps/lfx-one/src/app/modules/project/meetings/components/registrant-form/registrant-form.component.ts
  • apps/lfx-one/src/app/modules/project/meetings/components/registrant-form/registrant-form.component.html
  • apps/lfx-one/src/server/services/organization.service.ts
  • packages/shared/src/interfaces/organization.interface.ts
  • packages/shared/src/interfaces/index.ts
  • apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.ts
  • apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.ts
  • apps/lfx-one/src/app/shared/pipes/normalize-url.pipe.ts
  • apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.html
  • apps/lfx-one/src/server/routes/organizations.route.ts
  • apps/lfx-one/src/server/controllers/organization.controller.ts
  • apps/lfx-one/src/app/shared/services/organization.service.ts
  • apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.ts
  • packages/shared/src/utils/url.utils.ts
  • apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.html
  • apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.html
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not nest ternary expressions

Files:

  • apps/lfx-one/src/server/server.ts
  • apps/lfx-one/src/app/modules/project/meetings/components/registrant-form/registrant-form.component.ts
  • apps/lfx-one/src/server/services/organization.service.ts
  • packages/shared/src/interfaces/organization.interface.ts
  • packages/shared/src/interfaces/index.ts
  • apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.ts
  • apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.ts
  • apps/lfx-one/src/app/shared/pipes/normalize-url.pipe.ts
  • apps/lfx-one/src/server/routes/organizations.route.ts
  • apps/lfx-one/src/server/controllers/organization.controller.ts
  • apps/lfx-one/src/app/shared/services/organization.service.ts
  • apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.ts
  • packages/shared/src/utils/url.utils.ts
apps/lfx-one/src/**/*.html

📄 CodeRabbit inference engine (CLAUDE.md)

apps/lfx-one/src/**/*.html: Always add data-testid attributes when creating new Angular components for reliable test targeting
Use data-testid naming convention [section]-[component]-[element]

Files:

  • apps/lfx-one/src/app/modules/project/meetings/components/registrant-form/registrant-form.component.html
  • apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.html
  • apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.html
  • apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.html
packages/shared/src/interfaces/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Place all TypeScript interfaces in the shared package at packages/shared/src/interfaces

Files:

  • packages/shared/src/interfaces/organization.interface.ts
  • packages/shared/src/interfaces/index.ts
**/index.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Do not use barrel exports; always use direct imports for standalone components

Files:

  • packages/shared/src/interfaces/index.ts
🧠 Learnings (1)
📚 Learning: 2025-09-16T03:32:46.518Z
Learnt from: CR
PR: linuxfoundation/lfx-v2-ui#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-16T03:32:46.518Z
Learning: Applies to packages/shared/src/interfaces/**/*.ts : Place all TypeScript interfaces in the shared package at packages/shared/src/interfaces

Applied to files:

  • packages/shared/src/interfaces/index.ts
🧬 Code graph analysis (8)
apps/lfx-one/src/app/modules/project/meetings/components/registrant-form/registrant-form.component.ts (1)
apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.ts (1)
  • Component (16-161)
apps/lfx-one/src/server/services/organization.service.ts (1)
packages/shared/src/interfaces/organization.interface.ts (2)
  • OrganizationSuggestion (8-13)
  • OrganizationSuggestionsResponse (19-22)
apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.ts (1)
apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.ts (1)
  • Component (16-161)
apps/lfx-one/src/app/shared/pipes/normalize-url.pipe.ts (1)
packages/shared/src/utils/url.utils.ts (1)
  • normalizeToUrl (152-171)
apps/lfx-one/src/server/routes/organizations.route.ts (1)
apps/lfx-one/src/server/controllers/organization.controller.ts (1)
  • OrganizationController (13-59)
apps/lfx-one/src/server/controllers/organization.controller.ts (1)
apps/lfx-one/src/server/services/organization.service.ts (1)
  • OrganizationService (9-32)
apps/lfx-one/src/app/shared/services/organization.service.ts (2)
apps/lfx-one/src/server/services/organization.service.ts (1)
  • OrganizationService (9-32)
packages/shared/src/interfaces/organization.interface.ts (1)
  • OrganizationSuggestionsResponse (19-22)
apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.ts (5)
apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.ts (1)
  • Component (19-174)
apps/lfx-one/src/app/modules/project/meetings/components/registrant-form/registrant-form.component.ts (1)
  • Component (12-22)
apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.ts (1)
  • Component (9-45)
packages/shared/src/interfaces/organization.interface.ts (1)
  • OrganizationSuggestion (8-13)
packages/shared/src/utils/url.utils.ts (1)
  • normalizeToUrl (152-171)
🔇 Additional comments (10)
apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.ts (1)

15-16: Confirm projected empty template is actually rendered

You capture #empty via @ContentChild('empty'), but ensure the component template renders it inside PrimeNG with something like:

  • <ng-template pTemplate="empty"><ng-container *ngTemplateOutlet="emptyTemplate"></ng-container></ng-template>
apps/lfx-one/src/app/modules/project/meetings/components/registrant-form/registrant-form.component.ts (1)

15-16: LGTM: proper integration of OrganizationSearchComponent

Standalone import is correct and minimal; no logic changes.

packages/shared/src/interfaces/index.ts (1)

13-15: Interface export added correctly

Exporting organization.interface here aligns with how this index already aggregates interfaces.

Note: Our guideline says avoid barrel exports in index.ts for standalone components. This file aggregates interfaces (not components). Confirm this is within team policy, else we can remove index barrels and use direct imports.

apps/lfx-one/src/server/routes/organizations.route.ts (1)

1-15: LGTM: minimal, clear router

License header present; binding with .bind avoids this loss.

apps/lfx-one/src/app/shared/pipes/normalize-url.pipe.ts (1)

7-24: LGTM: simple, safe wrapper around normalizeToUrl

Returns null for falsy input; license header present.

apps/lfx-one/src/server/controllers/organization.controller.ts (1)

51-57: Confirm ServiceValidationError -> HTTP 400 mapping.

Assuming your error middleware maps ServiceValidationError to a 400. Please verify to avoid returning 500 on invalid input.

apps/lfx-one/src/app/modules/project/committees/components/member-form/member-form.component.html (1)

48-61: Verify data-testid propagation.

You pass dataTestId; ensure the component renders data-testid attributes on its focusable input and panel elements following the [section]-[component]-[element] convention.

packages/shared/src/interfaces/organization.interface.ts (1)

8-22: LGTM — re-exported from interfaces barrel. Confirmed: packages/shared/src/interfaces/index.ts contains export * from './organization.interface'; (line 14).

apps/lfx-one/src/server/services/organization.service.ts (1)

22-31: LGTM — timeouts enforced (30s via AbortSignal.timeout in ApiClientService)

ApiClientService defaults timeout to 30000ms, sets requestInit.signal = AbortSignal.timeout(this.config.timeout) and maps AbortError to a 408 MicroserviceError; MicroserviceProxyService delegates to it, so outbound calls are aborted on timeout. (apps/lfx-one/src/server/services/api-client.service.ts)

apps/lfx-one/src/app/shared/components/autocomplete/autocomplete.component.html (1)

22-27: Append target + empty template usage is supported (PrimeNG ^19.1.4).

apps/lfx-one/package.json lists primeng ^19.1.4; v19 docs confirm p-autocomplete supports appendTo, autoHighlight and pTemplate="empty" — no changes required.

- Use case-insensitive protocol detection with /^https?:\/\//i regex
- Build HTTPS candidate from host (with optional path) when no protocol present
- Fix critical validation flaw where domains with ports/paths were rejected
- Improve type safety in OrganizationService and OrganizationSearchComponent
- Remove debounceTime from organization search (handled by autocomplete)

The previous validation incorrectly compared url.hostname to cleanDomain
containing ports/paths/query parameters, causing valid domains like
"example.com:8080/path" to be rejected.

Now properly handles:
- example.com:8080/path → https://example.com:8080/path ✅
- HTTPS://example.com → uses as-is ✅
- Http://example.com/path → uses as-is ✅
- example.com → https://example.com ✅

References: LFXV2-575, LFXV2-576

Generated with [Claude Code](https://claude.ai/code)

Signed-off-by: Asitha de Silva <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/lfx-one/src/app/shared/services/organization.service.ts (1)

14-14: Consider externalizing baseUrl to a config/token.
Helps with environment overrides and testing.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5396737 and 1b997bd.

📒 Files selected for processing (3)
  • apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.ts (1 hunks)
  • apps/lfx-one/src/app/shared/services/organization.service.ts (1 hunks)
  • packages/shared/src/utils/url.utils.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/lfx-one/src/app/shared/components/organization-search/organization-search.component.ts
  • packages/shared/src/utils/url.utils.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript interfaces instead of union types for better maintainability
When defining PrimeNG-related types, reference the official PrimeNG component interfaces

Files:

  • apps/lfx-one/src/app/shared/services/organization.service.ts
**/*.{ts,tsx,js,jsx,mjs,cjs,html,css,scss}

📄 CodeRabbit inference engine (CLAUDE.md)

Include required license headers on all source files

Files:

  • apps/lfx-one/src/app/shared/services/organization.service.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not nest ternary expressions

Files:

  • apps/lfx-one/src/app/shared/services/organization.service.ts
🧬 Code graph analysis (1)
apps/lfx-one/src/app/shared/services/organization.service.ts (2)
apps/lfx-one/src/server/services/organization.service.ts (1)
  • OrganizationService (9-32)
packages/shared/src/interfaces/organization.interface.ts (2)
  • OrganizationSuggestion (8-13)
  • OrganizationSuggestionsResponse (19-22)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: E2E Tests / Playwright E2E Tests
🔇 Additional comments (3)
apps/lfx-one/src/app/shared/services/organization.service.ts (3)

1-2: License header present and correct.
Meets the repo’s licensing requirement.


21-21: Strong typing for return type looks good.
Good change to Observable<OrganizationSuggestion[]>.


22-24: Trim before length check to avoid whitespace-only API calls.
Currently, " " (len >= 2) will call the API with an empty query after trim.

Apply this diff:

   public searchOrganizations(searchTerm: string): Observable<OrganizationSuggestion[]> {
-    if (!searchTerm || searchTerm.length < 2) {
+    const query = (searchTerm ?? '').trim();
+    if (!query || query.length < 2) {
       return of([]);
     }
 
     return this.http
       .get<OrganizationSuggestionsResponse>(`${this.baseUrl}/search`, {
-        params: { query: searchTerm.trim() },
+        params: { query },
       })
       .pipe(
         map((response) => response.suggestions || []),
         catchError((error) => {
           console.error('Error searching organizations:', error);
           return of([]);
         })
       );
   }

Also applies to: 28-28

@asithade asithade merged commit d144037 into main Sep 29, 2025
5 of 6 checks passed
@asithade asithade deleted the feat/LFXV2-575 branch September 29, 2025 18:15
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.

4 participants