Skip to content

Conversation

@andrest50
Copy link
Contributor

Summary

Implements the ability to cancel individual occurrences of recurring meetings through a two-step modal flow:

  • When deleting a recurring meeting, users are first presented with a choice modal to either:
    • Cancel just the selected occurrence
    • Delete the entire meeting series
  • Cancel occurrence flow shows occurrence details and permanent action warning
  • Cancelled occurrences are automatically filtered from all meeting displays
  • Backend API uses ETag-based concurrency control for safe cancellation

Changes

Frontend

  • New Components:

    • meeting-delete-type-selection: Modal for choosing between occurrence/series deletion
    • meeting-cancel-occurrence-confirmation: Modal showing occurrence details with cancellation confirmation
  • Updated Components:

    • meeting-card: Enhanced delete flow with modal chaining for recurring meetings
    • my-meetings: Filters out cancelled occurrences from dashboard displays
    • meeting-delete-confirmation: Fixed button types to prevent page refresh
  • Service Updates:

    • Added cancelOccurrence() method in meeting service
    • Proper error handling for 404, 403, 500, and network errors

Backend

  • New Endpoint: DELETE /meetings/:uid/occurrences/:occurrenceId
  • Controller: Added cancelOccurrence with validation and structured logging
  • Service: Implements ETag-based concurrency control (fetches meeting first, then cancels with ETag)

Shared Package

  • Interface: Added is_cancelled field to MeetingOccurrence
  • Utility: Added getActiveOccurrences() function for centralized filtering of cancelled occurrences
  • Updated: getCurrentOrNextOccurrence() to filter cancelled occurrences

Technical Details

  • Uses Angular 19 standalone components with signals
  • PrimeNG DynamicDialog for modal management
  • RxJS operators for proper cleanup and event handling
  • Comprehensive error handling with user-friendly messages
  • Structured logging throughout backend stack

Test Plan

  • Verify delete button on single meetings shows delete confirmation directly
  • Verify delete button on recurring meetings shows type selection modal first
  • Test canceling an occurrence updates the meeting list
  • Test cancelled occurrences don't appear in "Today's Meetings"
  • Test cancelled occurrences don't appear in "Upcoming Meetings"
  • Verify cancel button on modals doesn't refresh the page
  • Test error handling for network failures
  • Verify ETag concurrency control works correctly

Ticket

https://linuxfoundation.atlassian.net/browse/LFXV2-650

Generated with Claude Code

@andrest50 andrest50 requested a review from jordane as a code owner October 24, 2025 20:25
Copilot AI review requested due to automatic review settings October 24, 2025 20:25
@coderabbitai
Copy link

coderabbitai bot commented Oct 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 support to cancel individual occurrences of recurring meetings: new UI dialogs for delete-scope selection and occurrence cancellation, frontend cancelOccurrence API call, backend DELETE endpoint/service, a MeetingOccurrence.is_cancelled field, and utilities to ignore cancelled occurrences in scheduling logic.

Changes

Cohort / File(s) Summary
Occurrence cancellation UI
apps/lfx-one/src/app/modules/project/meetings/components/meeting-cancel-occurrence-confirmation/meeting-cancel-occurrence-confirmation.component.ts, apps/lfx-one/src/app/modules/project/meetings/components/meeting-cancel-occurrence-confirmation/meeting-cancel-occurrence-confirmation.component.html, apps/lfx-one/src/app/modules/project/meetings/components/meeting-delete-type-selection/meeting-delete-type-selection.component.ts, apps/lfx-one/src/app/modules/project/meetings/components/meeting-delete-type-selection/meeting-delete-type-selection.component.html
New components: MeetingCancelOccurrenceConfirmationComponent (dialog, cancel call, error mapping, isCanceling signal) and MeetingDeleteTypeSelectionComponent (choose 'occurrence' or 'series', result interface).
Meeting card / delete flow
apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts
Update delete flow for recurring meetings: open delete-type selector, optionally open cancel-occurrence dialog, handle results with result?.confirmed, emit meetingDeleted and show success/error messages.
Dashboard occurrence filtering
apps/lfx-one/src/app/modules/dashboards/components/my-meetings/my-meetings.component.ts
Use new getActiveOccurrences(...) to iterate only non-cancelled occurrences for today/upcoming computations.
Frontend service
apps/lfx-one/src/app/shared/services/meeting.service.ts
Added cancelOccurrence(meetingId, occurrenceId): Observable issuing DELETE /api/meetings/{meetingId}/occurrences/{occurrenceId}.
Backend API & service
apps/lfx-one/src/server/controllers/meeting.controller.ts, apps/lfx-one/src/server/routes/meetings.route.ts, apps/lfx-one/src/server/services/meeting.service.ts
Added route DELETE /meetings/:uid/occurrences/:occurrenceId, controller.cancelOccurrence (validation, logging, 204 on success), and MeetingService.cancelOccurrence (fetch with ETag and delete occurrence).
Shared interfaces & utils
packages/shared/src/interfaces/meeting.interface.ts, packages/shared/src/utils/meeting.utils.ts
Add is_cancelled?: boolean to MeetingOccurrence, new MeetingCancelOccurrenceResult interface, new getActiveOccurrences(occurrences) util, and update getCurrentOrNextOccurrence and related helpers to operate on active (non-cancelled) occurrences.
Minor UI fix
apps/lfx-one/src/app/modules/project/meetings/components/meeting-delete-confirmation/meeting-delete-confirmation.component.html
Add type="button" to Cancel and Delete buttons to prevent default form submission.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Card as Meeting Card UI
    participant TypeModal as Delete Type Selection
    participant CancelModal as Cancel Occurrence Confirmation
    participant Client as Frontend Meeting Service
    participant API as Backend API

    User->>Card: Click "Delete" on recurring meeting
    Card->>TypeModal: Open delete-type selection
    User->>TypeModal: Select "Cancel This Occurrence"
    TypeModal-->>Card: Return {deleteType:'occurrence'}
    Card->>CancelModal: Open cancel-occurrence confirmation
    User->>CancelModal: Confirm
    CancelModal->>Client: cancelOccurrence(meetingId, occurrenceId)
    Client->>API: DELETE /meetings/{uid}/occurrences/{occurrenceId}
    alt success (204)
        API-->>Client: 204 No Content
        Client-->>CancelModal: success
        CancelModal-->>User: close {confirmed:true}
        Card->>Card: emit meetingDeleted -> refresh list
    else error (404/403/500/0)
        API-->>Client: error
        Client-->>CancelModal: mapped error
        CancelModal-->>User: close {confirmed:false,error}
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Potential focus areas:

  • Backend: ETag usage and delete semantics in MeetingService.cancelOccurrence, controller validation and error propagation.
  • Frontend: DynamicDialog result handling, error mapping in MeetingCancelOccurrenceConfirmationComponent, and meetingDeleted emission points.
  • Shared utils: Correct integration of getActiveOccurrences with existing occurrence-selection logic and edge cases when all occurrences are cancelled.

Possibly related PRs

Suggested labels

deploy-preview

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "feat(meetings): add ability to cancel meeting occurrences" is clear, concise, and directly related to the main change in the changeset. The title accurately summarizes the primary objective, which is to implement the ability to cancel individual occurrences of recurring meetings. The title uses a standard commit convention (feat) and avoids vague or generic terms, making it meaningful for someone reviewing the project history.
Linked Issues Check ✅ Passed The pull request successfully addresses all primary objectives from LFXV2-650. The changes support cancelling individual occurrences within recurring meetings through a new two-step modal flow (meeting-delete-type-selection and meeting-cancel-occurrence-confirmation components LFXV2-650). The implementation ensures cancelled occurrences are excluded from user-facing meeting lists via the new getActiveOccurrences() utility applied in my-meetings and other display components LFXV2-650. The backend API endpoint DELETE /meetings/:uid/occurrences/:occurrenceId with ETag-based concurrency control is implemented in the server-side controller and service LFXV2-650. Error handling for various HTTP status codes (404, 403, 500) and network failures is integrated throughout the frontend service and component layers LFXV2-650.
Out of Scope Changes Check ✅ Passed All changes in the pull request are directly related to the objective of adding the ability to cancel meeting occurrences. The frontend changes include new cancellation components, updates to the meeting-card delete flow with modal chaining, filtering of cancelled occurrences in my-meetings, and improved error handling in the meeting service. Backend changes add the required cancellation endpoint with ETag-based concurrency control. Shared package updates add the is_cancelled field and getActiveOccurrences utility necessary for filtering. A minor fix to meeting-delete-confirmation adding type="button" is a preventive enhancement to the existing delete flow. No out-of-scope changes are identified.
Description Check ✅ Passed The pull request description is comprehensive and directly related to the changeset. It provides a clear summary of what was implemented, details the frontend and backend changes, outlines technical decisions, and includes a test plan. The description aligns with the actual code changes across all modified files, explaining the two-step modal flow, cancellation filtering, and ETag-based concurrency control. The level of detail is appropriate and helps understanding of the changes without being overly verbose.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch andrest50/cancel-meeting-occurrence

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 the ability to cancel individual occurrences of recurring meetings through a two-step modal flow. Users can now choose between canceling a single occurrence or deleting the entire meeting series, with cancelled occurrences automatically filtered from all displays.

Key Changes:

  • Added backend endpoint and service methods for canceling meeting occurrences with ETag-based concurrency control
  • Implemented frontend modal components for occurrence cancellation with comprehensive error handling
  • Added filtering logic to hide cancelled occurrences from all meeting displays

Reviewed Changes

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

Show a summary per file
File Description
packages/shared/src/interfaces/meeting.interface.ts Added is_cancelled field to MeetingOccurrence interface
packages/shared/src/utils/meeting.utils.ts Added getActiveOccurrences() utility and updated getCurrentOrNextOccurrence() to filter cancelled occurrences
apps/lfx-one/src/server/routes/meetings.route.ts Added DELETE endpoint for canceling meeting occurrences
apps/lfx-one/src/server/controllers/meeting.controller.ts Added cancelOccurrence controller method with validation
apps/lfx-one/src/server/services/meeting.service.ts Implemented cancelOccurrence service method with ETag concurrency control
apps/lfx-one/src/app/shared/services/meeting.service.ts Added frontend cancelOccurrence method with error handling
apps/lfx-one/src/app/modules/project/meetings/components/meeting-delete-type-selection/* New component for choosing between occurrence/series deletion
apps/lfx-one/src/app/modules/project/meetings/components/meeting-cancel-occurrence-confirmation/* New component for confirming occurrence cancellation
apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts Enhanced delete flow with modal chaining for recurring meetings
apps/lfx-one/src/app/modules/project/meetings/components/meeting-delete-confirmation/meeting-delete-confirmation.component.html Fixed button types to prevent page refresh
apps/lfx-one/src/app/modules/dashboards/components/my-meetings/my-meetings.component.ts Filters cancelled occurrences from dashboard displays
apps/lfx-one/src/server/server.ts Removed update:current_user_metadata scope from Auth0 configuration

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Implement modal flow to cancel individual occurrences of recurring meetings:
- Add delete type selection modal for recurring meetings
- Add cancel occurrence confirmation modal with occurrence details
- Implement ETag-based concurrency control for cancellation API
- Filter cancelled occurrences from all meeting displays
- Add centralized getActiveOccurrences utility function in shared package
- Update frontend service with cancelOccurrence method
- Add backend route, controller, and service for cancel occurrence API
- Fix modal subscription logic to prevent unintended page refreshes

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

Signed-off-by: Andres Tobon <andrest2455@gmail.com>
@andrest50 andrest50 force-pushed the andrest50/cancel-meeting-occurrence branch from 67b0433 to 46e6cd9 Compare October 24, 2025 20:33
import { MeetingTimePipe } from '@pipes/meeting-time.pipe';
import { HttpErrorResponse } from '@angular/common/http';

export interface MeetingCancelOccurrenceResult {
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be in the shared package under meeting interfaces

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That makes sense. Done.

<div class="space-y-3 mb-6">
<div
class="border rounded-lg p-4 cursor-pointer transition-all"
[class.border-blue-500]="selectedType === 'occurrence'"
Copy link
Contributor

Choose a reason for hiding this comment

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

Use ngclass instead of individual [class.] values.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good. Done.

Comment on lines 23 to 26
[class.fa-circle-dot]="selectedType === 'occurrence'"
[class.fa-circle]="selectedType !== 'occurrence'"
[class.text-blue-500]="selectedType === 'occurrence'"
[class.text-gray-400]="selectedType !== 'occurrence'"></i>
Copy link
Contributor

Choose a reason for hiding this comment

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

Use ngClass instead

Comment on lines 37 to 39
[class.border-blue-500]="selectedType === 'series'"
[class.bg-blue-50]="selectedType === 'series'"
[class.border-gray-200]="selectedType !== 'series'"
Copy link
Contributor

Choose a reason for hiding this comment

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

Use ngclass

Comment on lines 46 to 49
[class.fa-circle-dot]="selectedType === 'series'"
[class.fa-circle]="selectedType !== 'series'"
[class.text-blue-500]="selectedType === 'series'"
[class.text-gray-400]="selectedType !== 'series'"></i>
Copy link
Contributor

Choose a reason for hiding this comment

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

Use ngclass

Comment on lines 202 to 205
catchError((error) => {
console.error(`Failed to cancel occurrence ${occurrenceId} for meeting ${meetingId}:`, error);
return throwError(() => error);
})
Copy link
Contributor

Choose a reason for hiding this comment

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

Catch error should be handled by caller

Minor improvements to the cancel occurrence feature:
- Move MeetingCancelOccurrenceResult interface to shared package
- Refactor delete type selection to use ngClass instead of individual class bindings
- Remove error handling from cancelOccurrence service method (handled in component)
- Update imports to use shared interface

These changes improve code organization and maintainability.

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

Signed-off-by: Andres Tobon <andrest2455@gmail.com>
Signed-off-by: Andres Tobon <andrest2455@gmail.com>
@andrest50 andrest50 requested a review from asithade October 28, 2025 21:10
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: 2

♻️ Duplicate comments (1)
apps/lfx-one/src/app/shared/services/meeting.service.ts (1)

202-204: API method looks good; keep errors bubbling to caller.

Returning the raw DELETE observable with take(1) matches the prior guidance to let callers handle errors. Keep it consistent with the new confirmation dialog’s error mapping.

🧹 Nitpick comments (2)
apps/lfx-one/src/app/modules/project/meetings/components/meeting-cancel-occurrence-confirmation/meeting-cancel-occurrence-confirmation.component.ts (2)

25-27: Harden dialog data handling (type + runtime guard).

Accessing config.data.* at property init can throw if data is missing. Cast once and guard to avoid runtime errors.

Apply this diff locally and add a constructor guard:

-  public readonly meeting: Meeting = this.config.data.meeting;
-  public readonly occurrence: MeetingOccurrence = this.config.data.occurrence;
+  private readonly data = this.config.data as Partial<{ meeting: Meeting; occurrence: MeetingOccurrence }>;
+  public readonly meeting: Meeting | undefined = this.data?.meeting;
+  public readonly occurrence: MeetingOccurrence | undefined = this.data?.occurrence;
+
+  public constructor() {
+    if (!this.meeting || !this.occurrence) {
+      this.dialogRef.close({ confirmed: false, error: 'Invalid dialog data.' });
+    }
+  }

33-58: Use finalize to avoid duplicate state toggles; map concurrency errors.

Simplify spinner handling and cover 409/412 responses.

Apply this diff:

   public onConfirm(): void {
     this.isCanceling.set(true);

-    this.meetingService.cancelOccurrence(this.meeting.uid, this.occurrence.occurrence_id).subscribe({
-      next: () => {
-        this.isCanceling.set(false);
-        this.dialogRef.close({ confirmed: true });
-      },
-      error: (error: HttpErrorResponse) => {
-        this.isCanceling.set(false);
+    this.meetingService
+      .cancelOccurrence(this.meeting!.uid, this.occurrence!.occurrence_id)
+      .pipe(finalize(() => this.isCanceling.set(false)))
+      .subscribe({
+        next: () => {
+          this.dialogRef.close({ confirmed: true });
+        },
+        error: (error: HttpErrorResponse) => {
           let errorMessage = 'Failed to cancel occurrence. Please try again.';
 
         if (error.status === 404) {
           errorMessage = 'Meeting occurrence not found.';
         } else if (error.status === 403) {
           errorMessage = 'You do not have permission to cancel this occurrence.';
+        } else if (error.status === 409 || error.status === 412) {
+          errorMessage = 'Conflict detected. This occurrence may have changed or was already canceled. Please refresh and try again.';
         } else if (error.status === 500) {
           errorMessage = 'Server error occurred while canceling occurrence.';
         } else if (error.status === 0) {
           errorMessage = 'Network error. Please check your connection.';
         }
 
         this.dialogRef.close({ confirmed: false, error: errorMessage });
-      },
-    });
+        },
+      });
   }

Additionally, import finalize:

- import { Component, inject, signal } from '@angular/core';
+ import { Component, inject, signal } from '@angular/core';
+ import { finalize } from 'rxjs';
📜 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 46e6cd9 and 96d289e.

📒 Files selected for processing (6)
  • apps/lfx-one/src/app/modules/project/meetings/components/meeting-cancel-occurrence-confirmation/meeting-cancel-occurrence-confirmation.component.ts (1 hunks)
  • apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts (4 hunks)
  • apps/lfx-one/src/app/modules/project/meetings/components/meeting-delete-type-selection/meeting-delete-type-selection.component.html (1 hunks)
  • apps/lfx-one/src/app/shared/services/meeting.service.ts (1 hunks)
  • apps/lfx-one/src/server/services/meeting.service.ts (1 hunks)
  • packages/shared/src/interfaces/meeting.interface.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/lfx-one/src/app/modules/project/meetings/components/meeting-delete-type-selection/meeting-delete-type-selection.component.html
  • packages/shared/src/interfaces/meeting.interface.ts
  • apps/lfx-one/src/server/services/meeting.service.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/meeting.service.ts
  • apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts
  • apps/lfx-one/src/app/modules/project/meetings/components/meeting-cancel-occurrence-confirmation/meeting-cancel-occurrence-confirmation.component.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/meeting.service.ts
  • apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts
  • apps/lfx-one/src/app/modules/project/meetings/components/meeting-cancel-occurrence-confirmation/meeting-cancel-occurrence-confirmation.component.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not nest ternary expressions

Files:

  • apps/lfx-one/src/app/shared/services/meeting.service.ts
  • apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts
  • apps/lfx-one/src/app/modules/project/meetings/components/meeting-cancel-occurrence-confirmation/meeting-cancel-occurrence-confirmation.component.ts
🧬 Code graph analysis (2)
apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts (3)
apps/lfx-one/src/app/modules/project/meetings/components/meeting-delete-type-selection/meeting-delete-type-selection.component.ts (1)
  • MeetingDeleteTypeResult (10-12)
packages/shared/src/interfaces/meeting.interface.ts (2)
  • Meeting (75-150)
  • MeetingCancelOccurrenceResult (556-559)
packages/shared/src/utils/meeting.utils.ts (1)
  • getCurrentOrNextOccurrence (120-154)
apps/lfx-one/src/app/modules/project/meetings/components/meeting-cancel-occurrence-confirmation/meeting-cancel-occurrence-confirmation.component.ts (2)
apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts (1)
  • Component (52-854)
packages/shared/src/interfaces/meeting.interface.ts (2)
  • Meeting (75-150)
  • MeetingOccurrence (156-169)
🪛 Biome (2.1.2)
apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts

[error] 43-44: Expected a statement but instead found '<<<<<<< HEAD'.

Expected a statement here.

(parse)


[error] 45-46: Expected a statement but instead found '======='.

Expected a statement here.

(parse)


[error] 47-48: Expected a statement but instead found '>>>>>>> 42e9854'.

Expected a statement here.

(parse)


[error] 48-48: numbers cannot be followed by identifiers directly after

an identifier cannot appear here

(parse)

🔇 Additional comments (1)
apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts (1)

565-567: LGTM: confirm delete result checked before emit.

Guarding on result?.confirmed avoids false positives when dialog closes without confirmation.

…ogic

- Remove merge conflict markers from meeting-card component imports
- Fix cancel occurrence to use current/selected occurrence instead of always using next occurrence
- Add fallback to next occurrence if no specific occurrence is selected

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

Signed-off-by: Andres Tobon <andrest2455@gmail.com>
@github-actions
Copy link

🚀 Deployment Status

Your branch has been deployed to: https://ui-pr-132.dev.v2.cluster.linuxfound.info

Deployment Details:

  • Environment: Development
  • Namespace: ui-pr-132
  • ArgoCD App: ui-pr-132

The deployment will be automatically removed when this PR is closed.

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 (2)
apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts (2)

504-546: Good occurrence selection; harden destructive-confirm UX.

Logic correctly prefers selected occurrence and falls back to next active. For a permanent action, consider disabling mask-click dismissal to avoid accidental closes:

-        closable: true,
-        dismissableMask: true,
+        closable: true,
+        dismissableMask: false,

470-502: Event naming is misleading but functionally correct; refactoring optional.

All consumers of meetingDeleted handle both occurrence cancellation and series deletion equally:

  • Dashboard refreshes the meeting list in both cases
  • Modal simply closes the dialog

The naming is semantically imprecise (emitting "Deleted" for occurrence cancellation), but no consumer assumes full deletion semantics. Renaming to meetingChanged or meetingUpdated would improve clarity, though the current implementation causes no functional issues.

📜 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 96d289e and eecc2b6.

📒 Files selected for processing (1)
  • apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts (4 hunks)
🧰 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/modules/project/meetings/components/meeting-card/meeting-card.component.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/modules/project/meetings/components/meeting-card/meeting-card.component.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not nest ternary expressions

Files:

  • apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts
🧬 Code graph analysis (1)
apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts (3)
apps/lfx-one/src/app/modules/project/meetings/components/meeting-delete-type-selection/meeting-delete-type-selection.component.ts (1)
  • MeetingDeleteTypeResult (10-12)
packages/shared/src/interfaces/meeting.interface.ts (2)
  • Meeting (75-150)
  • MeetingCancelOccurrenceResult (556-559)
packages/shared/src/utils/meeting.utils.ts (1)
  • getCurrentOrNextOccurrence (120-154)
🔇 Additional comments (3)
apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts (3)

23-23: LGTM: typed dialog result import is correct.

Importing MeetingCancelOccurrenceResult aligns the onClose result typing.


41-45: Imports resolved and correct.

Both MeetingCancelOccurrenceConfirmationComponent and MeetingDeleteTypeSelectionComponent are properly imported; prior merge conflict is clean.


562-562: LGTM: explicit result?.confirmed check.

Prevents truthy misfires on dialog close without confirmation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants