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 UI and backend support to cancel individual occurrences of recurring meetings: new dialogs to pick delete scope and confirm occurrence cancellation, frontend cancelOccurrence API call and service method, backend DELETE endpoint/service, MeetingOccurrence.is_cancelled field, and utilities to ignore cancelled occurrences.

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 state) 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; if 'occurrence' chosen, open cancel-occurrence dialog; handle modal results (check 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 getActiveOccurrences(...) to iterate only non-cancelled occurrences for today and upcoming meeting computations.
Frontend service
apps/lfx-one/src/app/shared/services/meeting.service.ts
Added cancelOccurrence(meetingId, occurrenceId): Observable<void> 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 method cancelOccurrence (validation, logging, 204 on success), and MeetingService.cancelOccurrence (fetch with ETag then 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(...) util, and update occurrence-selection 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 Meeting 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: dialog result handling in meeting-card.component.ts, error mapping and state handling in MeetingCancelOccurrenceConfirmationComponent.
  • Shared utils: correct filtering by is_cancelled and edge cases when all occurrences are cancelled.

Possibly related PRs

Pre-merge checks and finishing touches

✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and concisely describes the main feature addition: ability to cancel meeting occurrences, which aligns with the primary objective of this changeset.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, covering frontend, backend, and shared package changes with clear technical details and test verification steps.
Linked Issues check ✅ Passed The PR fully implements the core objective from LFXV2-650: ability to cancel individual occurrences in recurring meetings. New modals allow users to choose between cancelling occurrence or deleting series LFXV2-650. Cancelled occurrences are filtered from displays LFXV2-650. Backend API with ETag concurrency control is implemented LFXV2-650.
Out of Scope Changes check ✅ Passed All changes are directly scoped to supporting occurrence cancellation. Button type fixes in meeting-delete-confirmation are minimal UI corrections supporting the feature flow without introducing unrelated functionality.
✨ 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

📜 Recent 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 eecc2b6 and cce6222.

📒 Files selected for processing (6)
  • apps/lfx-one/src/app/modules/dashboards/components/my-meetings/my-meetings.component.ts (3 hunks)
  • apps/lfx-one/src/app/shared/services/meeting.service.ts (1 hunks)
  • apps/lfx-one/src/server/controllers/meeting.controller.ts (1 hunks)
  • apps/lfx-one/src/server/routes/meetings.route.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/server/routes/meetings.route.ts
  • apps/lfx-one/src/app/shared/services/meeting.service.ts
  • packages/shared/src/interfaces/meeting.interface.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/modules/dashboards/components/my-meetings/my-meetings.component.ts
  • apps/lfx-one/src/server/controllers/meeting.controller.ts
  • apps/lfx-one/src/server/services/meeting.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/modules/dashboards/components/my-meetings/my-meetings.component.ts
  • apps/lfx-one/src/server/controllers/meeting.controller.ts
  • apps/lfx-one/src/server/services/meeting.service.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not nest ternary expressions

Files:

  • apps/lfx-one/src/app/modules/dashboards/components/my-meetings/my-meetings.component.ts
  • apps/lfx-one/src/server/controllers/meeting.controller.ts
  • apps/lfx-one/src/server/services/meeting.service.ts
🧠 Learnings (1)
📚 Learning: 2025-10-21T21:19:13.599Z
Learnt from: andrest50
Repo: linuxfoundation/lfx-v2-ui PR: 125
File: apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts:345-350
Timestamp: 2025-10-21T21:19:13.599Z
Learning: In the Angular meeting card component (apps/lfx-one/src/app/modules/project/meetings/components/meeting-card/meeting-card.component.ts), when selecting between `summary.summary_data.edited_content` and `summary.summary_data.content`, the logical OR operator (`||`) is intentionally used instead of nullish coalescing (`??`) because empty string edited_content should fall back to the original content rather than being displayed as empty.

Applied to files:

  • apps/lfx-one/src/app/modules/dashboards/components/my-meetings/my-meetings.component.ts
🧬 Code graph analysis (2)
apps/lfx-one/src/app/modules/dashboards/components/my-meetings/my-meetings.component.ts (1)
packages/shared/src/utils/meeting.utils.ts (1)
  • getActiveOccurrences (111-113)
apps/lfx-one/src/server/services/meeting.service.ts (1)
packages/shared/src/interfaces/meeting.interface.ts (1)
  • Meeting (75-150)
⏰ 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: build-and-push
🔇 Additional comments (5)
apps/lfx-one/src/app/modules/dashboards/components/my-meetings/my-meetings.component.ts (3)

11-11: LGTM!

The import is correctly added and properly utilized in both computed signals.


42-45: LGTM!

The filtering logic correctly excludes cancelled occurrences from today's meetings. The existing guard check at line 41 ensures meeting.occurrences is valid before calling getActiveOccurrences, and the implementation properly handles the case where all occurrences are cancelled (resulting in an empty array and no meetings shown).


96-99: LGTM!

The filtering logic correctly excludes cancelled occurrences from upcoming meetings, mirroring the approach used in todayMeetings. The implementation is clean and consistent.

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

222-240: Well-implemented ETag-based concurrency control.

The method correctly follows the two-step pattern: fetch the meeting to obtain the ETag, then use that ETag when deleting the occurrence. This prevents race conditions where the meeting might be modified between read and write operations. The implementation is consistent with deleteMeeting and other mutation methods in this service.

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

288-347: Excellent validation and error handling.

The controller method properly validates both parameters, delegates to the service layer, and follows established patterns from similar methods like deleteMeeting and resendMeetingInvitation. The use of 204 No Content for successful deletion is appropriate, and the comprehensive logging at all decision points will aid in debugging and monitoring.


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

github-actions bot commented Oct 28, 2025

🚀 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.

asithade
asithade previously approved these changes Nov 5, 2025
Signed-off-by: Asitha de Silva <asithade@gmail.com>
@asithade asithade merged commit b1d34fb into main Nov 5, 2025
5 of 6 checks passed
@asithade asithade deleted the andrest50/cancel-meeting-occurrence branch November 5, 2025 18:40
@github-actions
Copy link

github-actions bot commented Nov 5, 2025

🧹 Deployment Removed

The deployment for PR #132 has been removed.

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