From f49fd863b7a8c7385b1e089889fc058f26c2cf09 Mon Sep 17 00:00:00 2001 From: CSantosM <4a.santos@gmail.com> Date: Mon, 2 Mar 2026 18:19:38 +0100 Subject: [PATCH] frontend: implement room deletion service with confirmation dialog and error handling --- .../rooms-lists/rooms-lists.component.ts | 2 +- .../step-indicator.component.ts | 10 +- .../room-detail/room-detail.component.ts | 175 ++++++++++++++---- .../rooms/pages/rooms/rooms.component.ts | 103 +---------- .../src/lib/domains/rooms/services/index.ts | 1 + .../rooms/services/room-deletion.service.ts | 130 +++++++++++++ 6 files changed, 289 insertions(+), 132 deletions(-) create mode 100644 meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/room-deletion.service.ts diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/components/rooms-lists/rooms-lists.component.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/components/rooms-lists/rooms-lists.component.ts index a2d9e56a..8f03f948 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/components/rooms-lists/rooms-lists.component.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/components/rooms-lists/rooms-lists.component.ts @@ -15,7 +15,7 @@ import { MatSortModule, Sort } from '@angular/material/sort'; import { MatTableModule } from '@angular/material/table'; import { MatToolbarModule } from '@angular/material/toolbar'; import { MatTooltipModule } from '@angular/material/tooltip'; -import { MEET_ROOM_SORT_FIELDS, MeetRoom, MeetRoomSortField, MeetRoomStatus, SortOrder } from '@openvidu-meet/typings'; +import { MeetRoom, MeetRoomSortField, MeetRoomStatus, SortOrder } from '@openvidu-meet/typings'; import { setsAreEqual } from '../../../../shared/utils/array.utils'; import { RoomUiUtils } from '../../utils/ui'; diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/components/step-indicator/step-indicator.component.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/components/step-indicator/step-indicator.component.ts index d483a035..a52899e0 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/components/step-indicator/step-indicator.component.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/components/step-indicator/step-indicator.component.ts @@ -4,15 +4,15 @@ import { CommonModule } from '@angular/common'; import { Component, computed, input, output } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { MatStepperModule } from '@angular/material/stepper'; -import { WizardStep } from '../../models'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; +import { WizardStep } from '../../models'; @Component({ - selector: 'ov-step-indicator', - imports: [CommonModule, MatStepperModule, ReactiveFormsModule], - templateUrl: './step-indicator.component.html', - styleUrl: './step-indicator.component.scss' + selector: 'ov-step-indicator', + imports: [CommonModule, MatStepperModule, ReactiveFormsModule], + templateUrl: './step-indicator.component.html', + styleUrl: './step-indicator.component.scss' }) export class StepIndicatorComponent { steps = input.required(); diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-detail/room-detail.component.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-detail/room-detail.component.ts index e7a54846..29810bb4 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-detail/room-detail.component.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-detail/room-detail.component.ts @@ -3,13 +3,19 @@ import { Component, OnInit, signal } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { MatChipsModule } from '@angular/material/chips'; -import { MatDialog } from '@angular/material/dialog'; import { MatIconModule } from '@angular/material/icon'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatTabsModule } from '@angular/material/tabs'; import { MatTooltipModule } from '@angular/material/tooltip'; import { ActivatedRoute, Router, RouterModule } from '@angular/router'; -import { MeetRecordingInfo, MeetRoom, MeetRoomMember, MeetRoomStatus, SortOrder } from '@openvidu-meet/typings'; +import { + MeetRecordingInfo, + MeetRoom, + MeetRoomDeletionSuccessCode, + MeetRoomMember, + MeetRoomStatus, + SortOrder +} from '@openvidu-meet/typings'; import { ILogger, LoggerService } from 'openvidu-components-angular'; import { BreadcrumbComponent, BreadcrumbItem } from '../../../../shared/components/breadcrumb/breadcrumb.component'; import { NavigationService } from '../../../../shared/services/navigation.service'; @@ -17,8 +23,13 @@ import { NotificationService } from '../../../../shared/services/notification.se import { RecordingListsComponent } from '../../../recordings/components/recording-lists/recording-lists.component'; import { RecordingTableAction, RecordingTableFilter } from '../../../recordings/models/recording-list.model'; import { RecordingService } from '../../../recordings/services/recording.service'; +import { + MemberTableAction, + MemberTableFilter, + RoomMembersListsComponent +} from '../../../room-members/components/room-members-list/room-members-list.component'; import { RoomMemberService } from '../../../room-members/services/room-member.service'; -import { DeleteRoomDialogComponent } from '../../components/delete-room-dialog/delete-room-dialog.component'; +import { RoomDeletionService } from '../../services/room-deletion.service'; import { RoomService } from '../../services/room.service'; import { RoomUiUtils } from '../../utils/ui'; @@ -34,7 +45,8 @@ import { RoomUiUtils } from '../../utils/ui'; MatTabsModule, RouterModule, BreadcrumbComponent, - RecordingListsComponent + RecordingListsComponent, + RoomMembersListsComponent ], templateUrl: './room-detail.component.html', styleUrl: './room-detail.component.scss' @@ -47,6 +59,8 @@ export class RoomDetailComponent implements OnInit { // Room Members tab roomMembers = signal([]); loadingMembers = signal(false); + hasMoreMembers = false; + private nextMembersPageToken?: string; // Recordings tab recordings = signal([]); @@ -66,12 +80,12 @@ export class RoomDetailComponent implements OnInit { private route: ActivatedRoute, private router: Router, private roomService: RoomService, + private roomDeletionService: RoomDeletionService, private roomMemberService: RoomMemberService, private recordingService: RecordingService, private notificationService: NotificationService, protected navigationService: NavigationService, private clipboard: Clipboard, - private dialog: MatDialog, protected loggerService: LoggerService ) { this.log = this.loggerService.get('OpenVidu Meet - RoomDetailComponent'); @@ -106,7 +120,7 @@ export class RoomDetailComponent implements OnInit { ]); // Load initial data for tabs - await Promise.all([this.loadRoomMembers(roomId), this.loadRecordings(roomId)]); + await Promise.all([this.loadRoomMembers(roomId, undefined), this.loadRecordings(roomId)]); } catch (error) { this.log.e('Error loading room details:', error); this.notificationService.showSnackbar('Failed to load room details'); @@ -116,15 +130,26 @@ export class RoomDetailComponent implements OnInit { } } - private async loadRoomMembers(roomId: string) { + private async loadRoomMembers(roomId: string, filters?: MemberTableFilter, refresh = false) { try { this.loadingMembers.set(true); const response = await this.roomMemberService.listRoomMembers(roomId, { - maxItems: 100, - sortField: 'membershipDate', - sortOrder: SortOrder.DESC + maxItems: 50, + nextPageToken: !refresh ? this.nextMembersPageToken : undefined, + sortField: filters?.sortField ?? 'membershipDate', + sortOrder: filters?.sortOrder ?? SortOrder.DESC, + ...(filters?.nameFilter ? { name: filters.nameFilter } : {}) }); - this.roomMembers.set(response.members); + + if (!refresh) { + const currentMembers = this.roomMembers(); + this.roomMembers.set([...currentMembers, ...response.members]); + } else { + this.roomMembers.set(response.members); + } + + this.nextMembersPageToken = response.pagination.nextPageToken; + this.hasMoreMembers = response.pagination.isTruncated; } catch (error) { this.log.e('Error loading room members:', error); this.notificationService.showSnackbar('Failed to load room members'); @@ -133,6 +158,89 @@ export class RoomDetailComponent implements OnInit { } } + async loadMoreRoomMembers(filters: MemberTableFilter) { + if (!this.hasMoreMembers || this.loadingMembers()) return; + const roomId = this.room()?.roomId; + if (roomId) { + await this.loadRoomMembers(roomId, filters); + } + } + + async refreshRoomMembers(filters: MemberTableFilter) { + const roomId = this.room()?.roomId; + if (roomId) { + this.nextMembersPageToken = undefined; + await this.loadRoomMembers(roomId, filters, true); + } + } + + async onMemberAction(action: MemberTableAction) { + switch (action.action) { + case 'copyLink': { + const member = action.members[0]; + if (member?.accessUrl) { + this.clipboard.copy(member.accessUrl); + this.notificationService.showSnackbar('Member access URL copied to clipboard'); + } + break; + } + case 'delete': { + const member = action.members[0]; + if (!member) break; + this.notificationService.showDialog({ + title: 'Remove Member', + icon: 'person_remove', + message: `Are you sure you want to remove ${member.name} from this room?`, + confirmText: 'Remove', + cancelText: 'Cancel', + confirmCallback: async () => { + try { + const roomId = this.room()?.roomId; + if (!roomId) return; + await this.roomMemberService.deleteRoomMember(roomId, member.memberId); + this.roomMembers.set(this.roomMembers().filter((m) => m.memberId !== member.memberId)); + this.notificationService.showSnackbar('Member removed successfully'); + } catch (error) { + this.log.e('Error removing member:', error); + this.notificationService.showSnackbar('Failed to remove member'); + } + } + }); + break; + } + case 'bulkDelete': { + const memberIds = action.members.map((m) => m.memberId); + const roomId = this.room()?.roomId; + if (!roomId || memberIds.length === 0) break; + this.notificationService.showDialog({ + title: 'Remove Members', + icon: 'group_remove', + message: `Are you sure you want to remove ${memberIds.length} members from this room?`, + confirmText: 'Remove all', + cancelText: 'Cancel', + confirmCallback: async () => { + try { + await this.roomMemberService.bulkDeleteRoomMembers(roomId, memberIds); + this.roomMembers.set(this.roomMembers().filter((m) => !memberIds.includes(m.memberId))); + this.notificationService.showSnackbar('Members removed successfully'); + } catch (error) { + this.log.e('Error removing members:', error); + this.notificationService.showSnackbar('Failed to remove members'); + } + } + }); + break; + } + } + } + + async onAddMember(): Promise { + const roomId = this.room()?.roomId; + if (roomId) { + await this.navigationService.navigateTo(`/rooms/${roomId}/members/new`); + } + } + private async loadRecordings(roomId: string, refresh = false) { try { this.loadingRecordings.set(true); @@ -219,31 +327,34 @@ export class RoomDetailComponent implements OnInit { await this.navigationService.navigateTo(`/rooms/${room.roomId}/edit`); } - async deleteRoom() { + deleteRoom() { const room = this.room(); if (!room) return; - const dialogRef = this.dialog.open(DeleteRoomDialogComponent, { - data: { - rooms: [room], - hasMeetings: room.status === MeetRoomStatus.ACTIVE_MEETING, - hasRecordings: false // You may need to check this separately - }, - width: '500px', - disableClose: true - }); - - const result = await dialogRef.afterClosed().toPromise(); - - if (result?.confirmed) { - try { - await this.roomService.deleteRoom(room.roomId, result.deletionPolicy); - this.notificationService.showSnackbar('Room deleted successfully'); - await this.navigationService.navigateTo('/rooms'); - } catch (error) { - this.log.e('Error deleting room:', error); - this.notificationService.showSnackbar('Failed to delete room'); + this.roomDeletionService.deleteRoomWithConfirmation({ + roomId: room.roomId, + log: this.log, + onSuccess: async ({ successCode, message, room: updatedRoom }) => { + await this.handleSuccessfulDeletion(successCode, message, updatedRoom); } + }); + } + + private async handleSuccessfulDeletion( + successCode: MeetRoomDeletionSuccessCode, + message: string, + updatedRoom?: MeetRoom + ) { + if (updatedRoom) { + // Room was not deleted but updated (e.g., closed due to active meeting) + if (successCode === MeetRoomDeletionSuccessCode.ROOM_WITH_ACTIVE_MEETING_CLOSED) { + updatedRoom.status = MeetRoomStatus.CLOSED; + } + this.room.set(updatedRoom); + } else { + // Room was deleted, navigate back to the rooms list + await this.navigationService.navigateTo('/rooms'); } + this.notificationService.showSnackbar(this.roomDeletionService.removeRoomIdFromMessage(message)); } } diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/rooms/rooms.component.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/rooms/rooms.component.ts index 079e0963..0a5479d9 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/rooms/rooms.component.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/rooms/rooms.component.ts @@ -17,7 +17,6 @@ import { MatTooltipModule } from '@angular/material/tooltip'; import { RouterModule } from '@angular/router'; import { MeetRoom, - MeetRoomDeletionErrorCode, MeetRoomDeletionPolicyWithMeeting, MeetRoomDeletionPolicyWithRecordings, MeetRoomDeletionSuccessCode, @@ -36,6 +35,7 @@ import { RoomTableAction, RoomTableFilter } from '../../components/rooms-lists/rooms-lists.component'; +import { RoomDeletionService } from '../../services/room-deletion.service'; import { RoomService } from '../../services/room.service'; @Component({ @@ -84,6 +84,7 @@ export class RoomsComponent implements OnInit { constructor( protected loggerService: LoggerService, private roomService: RoomService, + private roomDeletionService: RoomDeletionService, private notificationService: NotificationService, protected navigationService: NavigationService, private clipboard: Clipboard, @@ -270,7 +271,7 @@ export class RoomsComponent implements OnInit { // Update room in the list this.rooms.set(this.rooms().map((r) => (r.roomId === updatedRoom.roomId ? updatedRoom : r))); - this.notificationService.showSnackbar(this.removeRoomIdFromMessage(message)); + this.notificationService.showSnackbar(this.roomDeletionService.removeRoomIdFromMessage(message)); } catch (error) { this.notificationService.showSnackbar('Failed to close room'); this.log.e('Error closing room:', error); @@ -278,39 +279,12 @@ export class RoomsComponent implements OnInit { } private deleteRoom({ roomId }: MeetRoom) { - const deleteCallback = async () => { - try { - const { - successCode, - message, - room: updatedRoom - } = await this.roomService.deleteRoom( - roomId, - MeetRoomDeletionPolicyWithMeeting.FAIL, - MeetRoomDeletionPolicyWithRecordings.FAIL - ); + this.roomDeletionService.deleteRoomWithConfirmation({ + roomId, + log: this.log, + onSuccess: ({ room: updatedRoom, successCode, message }) => { this.handleSuccessfulDeletion(roomId, successCode, message, updatedRoom); - } catch (error: any) { - // Check if errorCode exists and is a valid MeetRoomDeletionErrorCode - const errorCode = error.error?.error; - if (errorCode && this.isValidMeetRoomDeletionErrorCode(errorCode)) { - const errorMessage = this.removeRoomIdFromMessage(error.error.message); - this.showDeletionErrorDialogWithOptions(roomId, errorMessage); - } else { - this.notificationService.showSnackbar('Failed to delete room'); - this.log.e('Error deleting room:', error); - return; - } } - }; - - this.notificationService.showDialog({ - title: 'Delete Room', - icon: 'delete_outline', - message: `Are you sure you want to delete the room ${roomId}?`, - confirmText: 'Delete', - cancelText: 'Cancel', - confirmCallback: deleteCallback }); } @@ -332,40 +306,7 @@ export class RoomsComponent implements OnInit { this.rooms.set(this.rooms().filter((r) => r.roomId !== roomId)); } - this.notificationService.showSnackbar(this.removeRoomIdFromMessage(message)); - } - - private showDeletionErrorDialogWithOptions(roomId: string, errorMessage: string) { - const deleteWithPoliciesCallback = async ( - meetingPolicy: MeetRoomDeletionPolicyWithMeeting, - recordingPolicy: MeetRoomDeletionPolicyWithRecordings - ) => { - try { - const { - successCode, - message, - room: updatedRoom - } = await this.roomService.deleteRoom(roomId, meetingPolicy, recordingPolicy); - this.handleSuccessfulDeletion(roomId, successCode, message, updatedRoom); - } catch (error) { - // If it fails again, just show a snackbar - this.notificationService.showSnackbar('Failed to delete room'); - this.log.e('Error in second deletion attempt:', error); - } - }; - - const dialogOptions: DeleteRoomDialogOptions = { - title: 'Error Deleting Room', - message: errorMessage, - confirmText: 'Delete with Options', - showWithMeetingPolicy: true, - showWithRecordingsPolicy: true, - confirmCallback: deleteWithPoliciesCallback - }; - this.dialog.open(DeleteRoomDialogComponent, { - data: dialogOptions, - disableClose: true - }); + this.notificationService.showSnackbar(this.roomDeletionService.removeRoomIdFromMessage(message)); } private bulkDeleteRooms(rooms: MeetRoom[]) { @@ -390,7 +331,7 @@ export class RoomsComponent implements OnInit { this.handleSuccessfulBulkDeletion(successful); const hasRoomDeletionError = failed.some((result) => - this.isValidMeetRoomDeletionErrorCode(result.error) + this.roomDeletionService.isValidDeletionErrorCode(result.error) ); if (hasRoomDeletionError) { this.showBulkDeletionErrorDialogWithOptions(failed, errorMessage); @@ -507,30 +448,4 @@ export class RoomsComponent implements OnInit { }); } - private isValidMeetRoomDeletionErrorCode(errorCode: string): boolean { - const validErrorCodes = [ - MeetRoomDeletionErrorCode.ROOM_HAS_ACTIVE_MEETING, - MeetRoomDeletionErrorCode.ROOM_HAS_RECORDINGS, - MeetRoomDeletionErrorCode.ROOM_WITH_ACTIVE_MEETING_HAS_RECORDINGS, - MeetRoomDeletionErrorCode.ROOM_WITH_ACTIVE_MEETING_HAS_RECORDINGS_CANNOT_SCHEDULE_DELETION, - MeetRoomDeletionErrorCode.ROOM_WITH_RECORDINGS_HAS_ACTIVE_MEETING - ]; - return validErrorCodes.includes(errorCode as MeetRoomDeletionErrorCode); - } - - /** - * Removes the room ID from API response messages to create generic messages. - * - * @param message - The original message from the API response - * @returns The message without the specific room ID - */ - private removeRoomIdFromMessage(message: string): string { - // Pattern to match room ID in single quotes: 'room-id' - const roomIdPattern = /'[^']+'/g; - let filteredMessage = message.replace(roomIdPattern, ''); - - // Clean up any double spaces that might result from the replacement - filteredMessage = filteredMessage.replace(/\s+/g, ' ').trim(); - return filteredMessage; - } } diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/index.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/index.ts index cbf6af18..0cf8aa6a 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/index.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/index.ts @@ -1,3 +1,4 @@ +export * from './room-deletion.service'; export * from './room-feature.service'; export * from './room.service'; export * from './wizard-state.service'; diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/room-deletion.service.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/room-deletion.service.ts new file mode 100644 index 00000000..0c736de2 --- /dev/null +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/services/room-deletion.service.ts @@ -0,0 +1,130 @@ +import { Injectable } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { + MeetRoom, + MeetRoomDeletionErrorCode, + MeetRoomDeletionPolicyWithMeeting, + MeetRoomDeletionPolicyWithRecordings, + MeetRoomDeletionSuccessCode +} from '@openvidu-meet/typings'; +import { ILogger } from 'openvidu-components-angular'; +import { DeleteRoomDialogOptions } from '../../../shared/models/notification.model'; +import { NotificationService } from '../../../shared/services/notification.service'; +import { DeleteRoomDialogComponent } from '../components/delete-room-dialog/delete-room-dialog.component'; +import { RoomService } from './room.service'; + +interface RoomDeletionResult { + roomId: string; + successCode: MeetRoomDeletionSuccessCode; + message: string; + room?: MeetRoom; +} + +interface RoomDeletionOptions { + roomId: string; + log: ILogger; + onSuccess: (result: RoomDeletionResult) => void | Promise; +} + +@Injectable({ + providedIn: 'root' +}) +export class RoomDeletionService { + constructor( + private roomService: RoomService, + private notificationService: NotificationService, + private dialog: MatDialog + ) {} + + deleteRoomWithConfirmation({ roomId, log, onSuccess }: RoomDeletionOptions): void { + const deleteCallback = async () => { + await this.deleteRoomWithDefaultPolicies(roomId, log, onSuccess); + }; + + this.notificationService.showDialog({ + title: 'Delete Room', + icon: 'delete_outline', + message: `Are you sure you want to delete the room ${roomId}?`, + confirmText: 'Delete', + cancelText: 'Cancel', + confirmCallback: deleteCallback + }); + } + + isValidDeletionErrorCode(errorCode: string): boolean { + const validErrorCodes = [ + MeetRoomDeletionErrorCode.ROOM_HAS_ACTIVE_MEETING, + MeetRoomDeletionErrorCode.ROOM_HAS_RECORDINGS, + MeetRoomDeletionErrorCode.ROOM_WITH_ACTIVE_MEETING_HAS_RECORDINGS, + MeetRoomDeletionErrorCode.ROOM_WITH_ACTIVE_MEETING_HAS_RECORDINGS_CANNOT_SCHEDULE_DELETION, + MeetRoomDeletionErrorCode.ROOM_WITH_RECORDINGS_HAS_ACTIVE_MEETING + ]; + return validErrorCodes.includes(errorCode as MeetRoomDeletionErrorCode); + } + + removeRoomIdFromMessage(message: string): string { + const roomIdPattern = /'[^']+'/g; + let filteredMessage = message.replace(roomIdPattern, ''); + filteredMessage = filteredMessage.replace(/\s+/g, ' ').trim(); + return filteredMessage; + } + + private async deleteRoomWithDefaultPolicies( + roomId: string, + log: ILogger, + onSuccess: (result: RoomDeletionResult) => void | Promise + ) { + try { + const { successCode, message, room } = await this.roomService.deleteRoom( + roomId, + MeetRoomDeletionPolicyWithMeeting.FAIL, + MeetRoomDeletionPolicyWithRecordings.FAIL + ); + + await onSuccess({ roomId, successCode, message, room }); + } catch (error: any) { + const errorCode = error.error?.error; + if (errorCode && this.isValidDeletionErrorCode(errorCode)) { + const errorMessage = this.removeRoomIdFromMessage(error.error.message); + this.showDeletionErrorDialogWithOptions(roomId, errorMessage, log, onSuccess); + } else { + this.notificationService.showSnackbar('Failed to delete room'); + log.e('Error deleting room:', error); + } + } + } + + private showDeletionErrorDialogWithOptions( + roomId: string, + errorMessage: string, + log: ILogger, + onSuccess: (result: RoomDeletionResult) => void | Promise + ): void { + const deleteWithPoliciesCallback = async ( + meetingPolicy: MeetRoomDeletionPolicyWithMeeting, + recordingPolicy: MeetRoomDeletionPolicyWithRecordings + ) => { + try { + const { successCode, message, room } = await this.roomService.deleteRoom(roomId, meetingPolicy, recordingPolicy); + await onSuccess({ roomId, successCode, message, room }); + } catch (error) { + this.notificationService.showSnackbar('Failed to delete room'); + log.e('Error in second deletion attempt:', error); + } + }; + + const dialogOptions: DeleteRoomDialogOptions = { + title: 'Error Deleting Room', + message: errorMessage, + confirmText: 'Delete with Options', + showWithMeetingPolicy: true, + showWithRecordingsPolicy: true, + confirmCallback: deleteWithPoliciesCallback + }; + + this.dialog.open(DeleteRoomDialogComponent, { + data: dialogOptions, + disableClose: true + }); + } +} \ No newline at end of file