frontend: add auto-deletion policies selection when creating new rooms
This commit is contained in:
parent
87594dfe17
commit
0b3c0e9e42
@ -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 {
|
||||
|
||||
@ -4,9 +4,7 @@
|
||||
<mat-icon class="ov-room-icon step-icon">video_chat</mat-icon>
|
||||
<div class="step-title-group">
|
||||
<h3 class="step-title">Room Details</h3>
|
||||
<p class="step-description">
|
||||
Configure your room's details including name and automatic deletion date
|
||||
</p>
|
||||
<p class="step-description">Configure your room's details including name and automatic deletion date</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@ -59,8 +57,8 @@
|
||||
<mat-hint>Optional. Room will be automatically deleted on this date and time.</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
@if (hasDateSelected) {
|
||||
<!-- Time Selection (only shown when date is selected) -->
|
||||
@if (roomDetailsForm.get('autoDeletionDate')?.value) {
|
||||
<div class="time-selection-container">
|
||||
<div class="time-selection-row">
|
||||
<mat-form-field appearance="outline" class="time-field">
|
||||
@ -89,6 +87,7 @@
|
||||
<mat-icon matSuffix class="ov-settings-icon">access_time</mat-icon>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
@if (!roomDetailsForm.hasError('minFutureDateTime')) {
|
||||
<div class="time-hint">
|
||||
<mat-icon class="hint-icon material-symbols-outlined material-icons">auto_delete</mat-icon>
|
||||
@ -97,6 +96,46 @@
|
||||
} @else {
|
||||
<mat-error> Deletion date and time must be at least one hour in the future </mat-error>
|
||||
}
|
||||
|
||||
<!-- Auto-deletion Policies Section -->
|
||||
<div class="auto-deletion-policies">
|
||||
<h4 class="policies-title">
|
||||
<mat-icon class="policies-icon">policy</mat-icon>
|
||||
Auto-deletion Policies
|
||||
</h4>
|
||||
<p class="policies-description">
|
||||
Configure how the room should be handled during auto-deletion if there are active meetings
|
||||
or recordings.
|
||||
</p>
|
||||
|
||||
<div class="policies-row">
|
||||
<mat-form-field appearance="outline" class="policy-field">
|
||||
<mat-label>With Active Meeting Policy</mat-label>
|
||||
<mat-select formControlName="autoDeletionPolicyWithMeeting">
|
||||
@for (option of meetingPolicyOptions; track option.value) {
|
||||
<mat-option [value]="option.value">
|
||||
{{ option.label }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
<mat-icon matSuffix class="ov-settings-icon">groups</mat-icon>
|
||||
<mat-hint>{{ getMeetingPolicyDescription() }}</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" class="policy-field">
|
||||
<mat-label>With Recordings Policy</mat-label>
|
||||
<mat-select formControlName="autoDeletionPolicyWithRecordings">
|
||||
@for (option of recordingPolicyOptions; track option.value) {
|
||||
<mat-option [value]="option.value">
|
||||
{{ option.label }}
|
||||
</mat-option>
|
||||
}
|
||||
</mat-select>
|
||||
<mat-icon matSuffix class="ov-settings-icon">video_library</mat-icon>
|
||||
<mat-hint>{{ getRecordingPolicyDescription() }}</mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</form>
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<void>();
|
||||
|
||||
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<MeetRoomOptions> = {
|
||||
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 || '';
|
||||
}
|
||||
}
|
||||
|
||||
@ -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':
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user