From 0b3c0e9e429137c0849f4ded82ac315cfb62723f Mon Sep 17 00:00:00 2001 From: juancarmore Date: Wed, 3 Sep 2025 12:22:51 +0200 Subject: [PATCH] frontend: add auto-deletion policies selection when creating new rooms --- .../room-wizard/room-wizard.component.scss | 9 ++- .../room-details/room-details.component.html | 49 ++++++++++++++-- .../room-details/room-details.component.scss | 52 +++++++++++++++++ .../room-details/room-details.component.ts | 58 ++++++++++++++++++- .../src/lib/services/wizard-state.service.ts | 27 ++++++++- 5 files changed, 185 insertions(+), 10 deletions(-) diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.scss b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.scss index 548c478..022dd2e 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.scss +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/room-wizard.component.scss @@ -32,9 +32,16 @@ max-width: 600px; min-height: 450px; max-height: 450px; + overflow-y: auto; display: flex; flex-direction: column; - justify-content: center; + justify-content: flex-start; +} + +.step-content > :first-child { + margin: auto 0; + width: 100%; + min-height: min-content; } .wizard-footer { diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-details/room-details.component.html b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-details/room-details.component.html index 54de660..6365f8e 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-details/room-details.component.html +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-details/room-details.component.html @@ -4,9 +4,7 @@ video_chat

Room Details

-

- Configure your room's details including name and automatic deletion date -

+

Configure your room's details including name and automatic deletion date

@@ -59,8 +57,8 @@ Optional. Room will be automatically deleted on this date and time. - - @if (roomDetailsForm.get('autoDeletionDate')?.value) { + @if (hasDateSelected) { +
@@ -89,6 +87,7 @@ access_time
+ @if (!roomDetailsForm.hasError('minFutureDateTime')) {
auto_delete @@ -97,6 +96,46 @@ } @else { Deletion date and time must be at least one hour in the future } + + +
+

+ policy + Auto-deletion Policies +

+

+ Configure how the room should be handled during auto-deletion if there are active meetings + or recordings. +

+ +
+ + With Active Meeting Policy + + @for (option of meetingPolicyOptions; track option.value) { + + {{ option.label }} + + } + + groups + {{ getMeetingPolicyDescription() }} + + + + With Recordings Policy + + @for (option of recordingPolicyOptions; track option.value) { + + {{ option.label }} + + } + + video_library + {{ getRecordingPolicyDescription() }} + +
+
} diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-details/room-details.component.scss b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-details/room-details.component.scss index cc1f22d..41a78ea 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-details/room-details.component.scss +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-details/room-details.component.scss @@ -108,6 +108,51 @@ } } + // Auto-deletion policies styling + .auto-deletion-policies { + margin-top: var(--ov-meet-spacing-lg); + + .policies-title { + display: flex; + align-items: center; + gap: var(--ov-meet-spacing-xs); + margin: 0 0 var(--ov-meet-spacing-xs) 0; + font-size: var(--ov-meet-font-size-md); + font-weight: var(--ov-meet-font-weight-medium); + color: var(--ov-meet-text-primary); + + .policies-icon { + @include ov-icon(sm); + color: var(--ov-meet-primary); + } + } + + .policies-description { + margin: 0 0 var(--ov-meet-spacing-md) 0; + font-size: var(--ov-meet-font-size-sm); + color: var(--ov-meet-text-secondary); + line-height: var(--ov-meet-line-height-relaxed); + } + + .policies-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--ov-meet-spacing-md); + + .policy-field { + width: 100%; + + ::ng-deep { + .mat-mdc-form-field-hint { + font-size: var(--ov-meet-font-size-xs); + color: var(--ov-meet-text-hint); + line-height: var(--ov-meet-line-height-tight); + } + } + } + } + } + .time-hint { display: flex; align-items: center; @@ -163,6 +208,13 @@ display: none; // Hide separator in mobile vertical layout } } + + .auto-deletion-policies { + .policies-row { + grid-template-columns: 1fr; + gap: var(--ov-meet-spacing-sm); + } + } } } } diff --git a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-details/room-details.component.ts b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-details/room-details.component.ts index 7705bc7..f22a266 100644 --- a/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-details/room-details.component.ts +++ b/frontend/projects/shared-meet-components/src/lib/pages/console/rooms/room-wizard/steps/room-details/room-details.component.ts @@ -9,7 +9,12 @@ import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { MatTooltipModule } from '@angular/material/tooltip'; import { RoomWizardStateService } from '@lib/services'; -import { MeetRoomOptions } from '@lib/typings/ce'; +import { + MeetRoomAutoDeletionPolicy, + MeetRoomDeletionPolicyWithMeeting, + MeetRoomDeletionPolicyWithRecordings, + MeetRoomOptions +} from '@lib/typings/ce'; import { Subject, takeUntil } from 'rxjs'; @Component({ @@ -36,6 +41,32 @@ export class RoomWizardRoomDetailsComponent implements OnDestroy { hours = Array.from({ length: 24 }, (_, i) => ({ value: i, display: i.toString().padStart(2, '0') })); minutes = Array.from({ length: 60 }, (_, i) => ({ value: i, display: i.toString().padStart(2, '0') })); + meetingPolicyOptions = [ + { + value: MeetRoomDeletionPolicyWithMeeting.FORCE, + label: 'Force', + description: + 'The meeting will be ended, and the room will be deleted without waiting for participants to leave.' + }, + { + value: MeetRoomDeletionPolicyWithMeeting.WHEN_MEETING_ENDS, + label: 'When meeting ends', + description: 'The room will be deleted when the meeting ends.' + } + ]; + recordingPolicyOptions = [ + { + value: MeetRoomDeletionPolicyWithRecordings.FORCE, + label: 'Force', + description: 'The room and its recordings will be deleted.' + }, + { + value: MeetRoomDeletionPolicyWithRecordings.CLOSE, + label: 'Close', + description: 'The room will be closed instead of deleted, maintaining its recordings.' + } + ]; + private destroy$ = new Subject(); constructor(private wizardService: RoomWizardStateService) { @@ -54,20 +85,29 @@ export class RoomWizardRoomDetailsComponent implements OnDestroy { private saveFormData(formValue: any) { let autoDeletionDateTime: number | undefined = undefined; + let autoDeletionPolicy: MeetRoomAutoDeletionPolicy | undefined = undefined; - // If date is selected, combine it with time + // If date is selected if (formValue.autoDeletionDate) { + // Combine date with time const date = new Date(formValue.autoDeletionDate); date.setHours(formValue.autoDeletionHour || 23); date.setMinutes(formValue.autoDeletionMinute || 59); date.setSeconds(0); date.setMilliseconds(0); autoDeletionDateTime = date.getTime(); + + // Set auto deletion policy + autoDeletionPolicy = { + withMeeting: formValue.autoDeletionPolicyWithMeeting, + withRecordings: formValue.autoDeletionPolicyWithRecordings + }; } const stepData: Partial = { roomName: formValue.roomName, - autoDeletionDate: autoDeletionDateTime + autoDeletionDate: autoDeletionDateTime, + autoDeletionPolicy }; // Always save to wizard state (including when values are cleared) @@ -115,4 +155,16 @@ export class RoomWizardRoomDetailsComponent implements OnDestroy { autoDeletionMinute: 59 }); } + + getMeetingPolicyDescription(): string { + const selectedValue = this.roomDetailsForm.get('autoDeletionPolicyWithMeeting')?.value; + const option = this.meetingPolicyOptions.find((opt) => opt.value === selectedValue); + return option?.description || ''; + } + + getRecordingPolicyDescription(): string { + const selectedValue = this.roomDetailsForm.get('autoDeletionPolicyWithRecordings')?.value; + const option = this.recordingPolicyOptions.find((opt) => opt.value === selectedValue); + return option?.description || ''; + } } diff --git a/frontend/projects/shared-meet-components/src/lib/services/wizard-state.service.ts b/frontend/projects/shared-meet-components/src/lib/services/wizard-state.service.ts index 5e8fa47..8fdab93 100644 --- a/frontend/projects/shared-meet-components/src/lib/services/wizard-state.service.ts +++ b/frontend/projects/shared-meet-components/src/lib/services/wizard-state.service.ts @@ -1,7 +1,13 @@ import { computed, Injectable, signal } from '@angular/core'; import { AbstractControl, FormBuilder, ValidationErrors, Validators } from '@angular/forms'; import { WizardNavigationConfig, WizardStep } from '@lib/models'; -import { MeetRecordingAccess, MeetRoomOptions, MeetRoomPreferences } from '@lib/typings/ce'; +import { + MeetRecordingAccess, + MeetRoomDeletionPolicyWithMeeting, + MeetRoomDeletionPolicyWithRecordings, + MeetRoomOptions, + MeetRoomPreferences +} from '@lib/typings/ce'; // Default room preferences following the app's defaults const DEFAULT_PREFERENCES: MeetRoomPreferences = { @@ -101,6 +107,22 @@ export class RoomWizardStateService { disabled: editMode }, editMode ? [] : [Validators.min(0), Validators.max(59)] + ], + autoDeletionPolicyWithMeeting: [ + { + value: + initialRoomOptions.autoDeletionPolicy?.withMeeting || + MeetRoomDeletionPolicyWithMeeting.WHEN_MEETING_ENDS, + disabled: editMode + } + ], + autoDeletionPolicyWithRecordings: [ + { + value: + initialRoomOptions.autoDeletionPolicy?.withRecordings || + MeetRoomDeletionPolicyWithRecordings.CLOSE, + disabled: editMode + } ] }, { @@ -204,6 +226,9 @@ export class RoomWizardStateService { if ('autoDeletionDate' in stepData) { updatedOptions.autoDeletionDate = stepData.autoDeletionDate; } + if ('autoDeletionPolicy' in stepData) { + updatedOptions.autoDeletionPolicy = stepData.autoDeletionPolicy; + } break; case 'recording':