frontend: Refactors recording list component to use signals
Migrates the recording list component to use Angular signals for input properties and data binding. This improves performance and simplifies the component's change detection. - Converts input properties to input signals. - Uses computed signals for derived values. - Introduces effect for side effects related to recordings changes. - Moves recording list model interfaces to shared location.
This commit is contained in:
parent
b24992ad24
commit
520816b983
@ -1,11 +1,11 @@
|
||||
@if (!loading && recordings.length === 0 && !showEmptyFilterMessage) {
|
||||
@if (!loading() && recordings().length === 0 && !showEmptyFilterMessage) {
|
||||
<!-- Empty State -->
|
||||
<div class="no-recordings-state">
|
||||
<div class="empty-content">
|
||||
<h3>No recordings yet</h3>
|
||||
@if (roomName) {
|
||||
@if (roomName()) {
|
||||
<p>
|
||||
No recordings found for <strong>{{ roomName }}</strong
|
||||
No recordings found for <strong>{{ roomName() }}</strong
|
||||
>. Start a recording in this room to see them listed here.
|
||||
</p>
|
||||
} @else {
|
||||
@ -25,7 +25,7 @@
|
||||
<!-- Left Section: Search -->
|
||||
@if (!isMobileView()) {
|
||||
<div class="toolbar-left">
|
||||
@if (showSearchBox) {
|
||||
@if (showSearchBox()) {
|
||||
<mat-form-field class="search-field" appearance="outline">
|
||||
<mat-label>Search recordings</mat-label>
|
||||
<input
|
||||
@ -39,7 +39,7 @@
|
||||
matSuffix
|
||||
class="search-btn"
|
||||
(click)="triggerSearch()"
|
||||
[disabled]="loading || !nameFilterControl.value"
|
||||
[disabled]="loading() || !nameFilterControl.value"
|
||||
matTooltip="Search"
|
||||
>
|
||||
<mat-icon>search</mat-icon>
|
||||
@ -50,15 +50,15 @@
|
||||
}
|
||||
|
||||
<!-- Center Section: Bulk Actions (visible when items selected) -->
|
||||
@if (showSelection && selectedRecordings().size > 0) {
|
||||
@if (showSelection() && selectedRecordings().size > 0) {
|
||||
<div class="toolbar-center">
|
||||
<div class="batch-actions">
|
||||
@if (canDeleteRecordings) {
|
||||
@if (canDeleteRecordings()) {
|
||||
<button
|
||||
mat-icon-button
|
||||
color="warn"
|
||||
(click)="bulkDeleteSelected()"
|
||||
[disabled]="loading"
|
||||
[disabled]="loading()"
|
||||
matTooltip="Delete selected recordings"
|
||||
>
|
||||
<mat-icon [matBadge]="selectedRecordings().size" matBadgePosition="below after">
|
||||
@ -70,7 +70,7 @@
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="bulkDownloadSelected()"
|
||||
[disabled]="loading"
|
||||
[disabled]="loading()"
|
||||
matTooltip="Download selected recordings"
|
||||
>
|
||||
<mat-icon [matBadge]="selectedRecordings().size" matBadgePosition="below after">
|
||||
@ -88,7 +88,7 @@
|
||||
mat-icon-button
|
||||
class="clear-btn"
|
||||
(click)="clearFilters()"
|
||||
[disabled]="loading"
|
||||
[disabled]="loading()"
|
||||
matTooltip="Clear all filters"
|
||||
>
|
||||
<mat-icon>filter_alt_off</mat-icon>
|
||||
@ -99,13 +99,13 @@
|
||||
mat-icon-button
|
||||
class="refresh-btn"
|
||||
(click)="refreshRecordings()"
|
||||
[disabled]="loading"
|
||||
[disabled]="loading()"
|
||||
matTooltip="Refresh recordings"
|
||||
>
|
||||
<mat-icon>refresh</mat-icon>
|
||||
</button>
|
||||
|
||||
@if (showFilters) {
|
||||
@if (showFilters()) {
|
||||
<button mat-icon-button [matMenuTriggerFor]="filtersMenu" matTooltip="Filter recordings">
|
||||
<mat-icon>tune</mat-icon>
|
||||
</button>
|
||||
@ -128,12 +128,12 @@
|
||||
</mat-toolbar>
|
||||
|
||||
<!-- Loading Spinner -->
|
||||
@if (loading) {
|
||||
@if (loading()) {
|
||||
<div class="loading-container">
|
||||
<mat-spinner diameter="40"></mat-spinner>
|
||||
<span>Loading recordings...</span>
|
||||
</div>
|
||||
} @else if (recordings.length === 0 && showEmptyFilterMessage) {
|
||||
} @else if (recordings().length === 0 && showEmptyFilterMessage) {
|
||||
<!-- No recordings match the current filters -->
|
||||
<div class="no-recordings-state">
|
||||
<div class="empty-content">
|
||||
@ -151,12 +151,12 @@
|
||||
@if (isMobileView()) {
|
||||
<!-- Mobile Cards View -->
|
||||
<div class="cards-container">
|
||||
@for (recording of recordings; track recording.recordingId) {
|
||||
@for (recording of recordings(); track recording.recordingId) {
|
||||
<div class="recording-card" [class.selected-card]="isRecordingSelected(recording)">
|
||||
<!-- Card Header with Selection and Status -->
|
||||
<div class="card-header">
|
||||
<div class="card-header-left">
|
||||
@if (showSelection && canSelectRecording(recording)) {
|
||||
@if (showSelection() && canSelectRecording(recording)) {
|
||||
<mat-checkbox
|
||||
[checked]="isRecordingSelected(recording)"
|
||||
(change)="toggleRecordingSelection(recording)"
|
||||
@ -167,7 +167,7 @@
|
||||
</mat-checkbox>
|
||||
}
|
||||
|
||||
@if (showRoomInfo) {
|
||||
@if (showRoomInfo()) {
|
||||
<div class="room-info">
|
||||
<div class="room-name">{{ recording.roomName }}</div>
|
||||
<div class="room-id">{{ recording.recordingId }}</div>
|
||||
@ -233,7 +233,7 @@
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="playRecording(recording)"
|
||||
[disabled]="loading"
|
||||
[disabled]="loading()"
|
||||
class="action-button play-button"
|
||||
matTooltip="Play Recording"
|
||||
id="play-recording-btn-{{ recording.recordingId }}"
|
||||
@ -246,7 +246,7 @@
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="downloadRecording(recording)"
|
||||
[disabled]="loading"
|
||||
[disabled]="loading()"
|
||||
class="action-button download-button"
|
||||
matTooltip="Download Recording"
|
||||
id="download-recording-btn-{{ recording.recordingId }}"
|
||||
@ -259,7 +259,7 @@
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="deleteRecording(recording)"
|
||||
[disabled]="loading"
|
||||
[disabled]="loading()"
|
||||
class="action-button delete-button"
|
||||
matTooltip="Delete Recording"
|
||||
id="delete-recording-btn-{{ recording.recordingId }}"
|
||||
@ -270,7 +270,7 @@
|
||||
<button
|
||||
mat-icon-button
|
||||
[matMenuTriggerFor]="cardActionsMenu"
|
||||
[disabled]="loading"
|
||||
[disabled]="loading()"
|
||||
class="action-button more-button"
|
||||
matTooltip="More Actions"
|
||||
id="more-actions-btn-{{ recording.recordingId }}"
|
||||
@ -310,7 +310,7 @@
|
||||
<div class="table-container">
|
||||
<table
|
||||
mat-table
|
||||
[dataSource]="recordings"
|
||||
[dataSource]="recordings()"
|
||||
matSort
|
||||
matSortDisableClear
|
||||
[matSortActive]="currentSortField"
|
||||
@ -319,14 +319,14 @@
|
||||
class="recordings-table"
|
||||
>
|
||||
<!-- Selection Column -->
|
||||
@if (showSelection) {
|
||||
@if (showSelection()) {
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef class="select-header">
|
||||
<mat-checkbox
|
||||
[checked]="allSelected()"
|
||||
[indeterminate]="someSelected()"
|
||||
(change)="toggleAllSelection()"
|
||||
[disabled]="loading"
|
||||
[disabled]="loading()"
|
||||
[attr.aria-label]="allSelected() ? 'Deselect all' : 'Select all'"
|
||||
>
|
||||
</mat-checkbox>
|
||||
@ -336,7 +336,7 @@
|
||||
<mat-checkbox
|
||||
[checked]="isRecordingSelected(recording)"
|
||||
(change)="toggleRecordingSelection(recording)"
|
||||
[disabled]="loading"
|
||||
[disabled]="loading()"
|
||||
[attr.aria-label]="'Select recording ' + recording.recordingId"
|
||||
>
|
||||
</mat-checkbox>
|
||||
@ -346,7 +346,7 @@
|
||||
}
|
||||
|
||||
<!-- Room Info Column -->
|
||||
@if (showRoomInfo) {
|
||||
@if (showRoomInfo()) {
|
||||
<ng-container matColumnDef="roomInfo">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header="roomName" class="room-header">
|
||||
Room
|
||||
@ -416,35 +416,26 @@
|
||||
matTooltip="Play Recording"
|
||||
class="action-button play-button"
|
||||
(click)="playRecording(recording)"
|
||||
[disabled]="loading"
|
||||
id="play-recording-btn-{{ recording.recordingId }}"
|
||||
>
|
||||
<mat-icon>play_arrow</mat-icon>
|
||||
</button>
|
||||
}
|
||||
[disabled]="loading()"
|
||||
id="play-recording-btn-{{ recording.recordingId }}"
|
||||
>
|
||||
<mat-icon>play_arrow</mat-icon>
|
||||
</button>
|
||||
}
|
||||
|
||||
<!-- Download Button -->
|
||||
@if (canDownloadRecording(recording)) {
|
||||
<button
|
||||
mat-icon-button
|
||||
matTooltip="Download Recording"
|
||||
class="action-button download-button"
|
||||
(click)="downloadRecording(recording)"
|
||||
[disabled]="loading"
|
||||
id="download-recording-btn-{{ recording.recordingId }}"
|
||||
>
|
||||
<mat-icon>download</mat-icon>
|
||||
</button>
|
||||
}
|
||||
|
||||
@if (isRecordingFailed(recording)) {
|
||||
<button
|
||||
class="delete-action"
|
||||
<!-- Download Button -->
|
||||
@if (canDownloadRecording(recording)) {
|
||||
<button
|
||||
mat-icon-button
|
||||
matTooltip="Download Recording"
|
||||
class="action-button download-button"
|
||||
(click)="downloadRecording(recording)"
|
||||
[disabled]="loading()"
|
||||
mat-icon-button
|
||||
matTooltip="Delete Recording"
|
||||
class="action-button delete-button"
|
||||
(click)="deleteRecording(recording)"
|
||||
[disabled]="loading"
|
||||
[disabled]="loading()"
|
||||
id="delete-recording-btn-{{ recording.recordingId }}"
|
||||
>
|
||||
<mat-icon>delete</mat-icon>
|
||||
@ -456,7 +447,7 @@
|
||||
class="action-button more-button"
|
||||
[matMenuTriggerFor]="actionsMenu"
|
||||
matTooltip="More Actions"
|
||||
[disabled]="loading"
|
||||
[disabled]="loading()"
|
||||
id="more-actions-btn-{{ recording.recordingId }}"
|
||||
>
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
@ -501,13 +492,13 @@
|
||||
}
|
||||
|
||||
<!-- Load More Section -->
|
||||
@if (showLoadMore) {
|
||||
@if (showLoadMore()) {
|
||||
<div class="load-more-container" id="load-more-container">
|
||||
<button
|
||||
mat-button
|
||||
class="load-more-btn"
|
||||
(click)="loadMoreRecordings()"
|
||||
[disabled]="loading"
|
||||
[disabled]="loading()"
|
||||
id="load-more-btn"
|
||||
>
|
||||
<mat-icon>expand_more</mat-icon>
|
||||
|
||||
@ -2,13 +2,12 @@ import { CommonModule, DatePipe } from '@angular/common';
|
||||
import {
|
||||
Component,
|
||||
computed,
|
||||
effect,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnChanges,
|
||||
input,
|
||||
OnInit,
|
||||
Output,
|
||||
signal,
|
||||
SimpleChanges
|
||||
signal
|
||||
} from '@angular/core';
|
||||
import { FormControl, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatBadgeModule } from '@angular/material/badge';
|
||||
@ -28,18 +27,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { MeetRecordingInfo, MeetRecordingStatus } from '@openvidu-meet/typings';
|
||||
import { ViewportService } from 'openvidu-components-angular';
|
||||
import { formatBytes, formatDurationToHMS } from '../../../../shared/utils/format.utils';
|
||||
|
||||
export interface RecordingTableAction {
|
||||
recordings: MeetRecordingInfo[];
|
||||
action: 'play' | 'download' | 'shareLink' | 'delete' | 'bulkDelete' | 'bulkDownload';
|
||||
}
|
||||
|
||||
export interface RecordingTableFilter {
|
||||
nameFilter: string;
|
||||
statusFilter: MeetRecordingStatus | '';
|
||||
sortField: 'roomName' | 'startDate' | 'duration' | 'size';
|
||||
sortOrder: 'asc' | 'desc';
|
||||
}
|
||||
import { RecordingTableAction, RecordingTableFilter } from '../../models/recording-list.model';
|
||||
|
||||
/**
|
||||
* Reusable component for displaying a list of recordings with filtering, selection, and bulk operations.
|
||||
@ -88,23 +76,23 @@ export interface RecordingTableFilter {
|
||||
templateUrl: './recording-lists.component.html',
|
||||
styleUrl: './recording-lists.component.scss'
|
||||
})
|
||||
export class RecordingListsComponent implements OnInit, OnChanges {
|
||||
// Input properties
|
||||
@Input() recordings: MeetRecordingInfo[] = [];
|
||||
@Input() canDeleteRecordings = false;
|
||||
@Input() showSearchBox = true;
|
||||
@Input() showFilters = true;
|
||||
@Input() showSelection = true;
|
||||
@Input() showRoomInfo = true;
|
||||
@Input() showLoadMore = false;
|
||||
@Input() loading = false;
|
||||
@Input() roomName?: string; // Optional: if provided, shows room-specific empty state message
|
||||
@Input() initialFilters: RecordingTableFilter = {
|
||||
export class RecordingListsComponent implements OnInit {
|
||||
recordings = input<MeetRecordingInfo[]>([]);
|
||||
canDeleteRecordings = input(false);
|
||||
showSearchBox = input(true);
|
||||
showFilters = input(true);
|
||||
showSelection = input(true);
|
||||
showRoomInfo = input(true);
|
||||
showLoadMore = input(false);
|
||||
loading = input(false);
|
||||
roomName = input<string | undefined>(undefined);
|
||||
initialFilters = input<RecordingTableFilter>({
|
||||
nameFilter: '',
|
||||
statusFilter: '',
|
||||
sortField: 'startDate',
|
||||
sortOrder: 'desc'
|
||||
};
|
||||
});
|
||||
|
||||
// Output events
|
||||
@Output() recordingAction = new EventEmitter<RecordingTableAction>();
|
||||
@Output() filterChange = new EventEmitter<RecordingTableFilter>();
|
||||
@ -161,36 +149,39 @@ export class RecordingListsComponent implements OnInit, OnChanges {
|
||||
DOWNLOADABLE: [MeetRecordingStatus.COMPLETE] as readonly MeetRecordingStatus[]
|
||||
} as const;
|
||||
|
||||
constructor(private viewportService: ViewportService) {}
|
||||
|
||||
protected isMobileView = computed(() => this.viewportService.isMobileView());
|
||||
|
||||
ngOnInit() {
|
||||
this.setupFilters();
|
||||
this.updateDisplayedColumns();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes['recordings']) {
|
||||
constructor(private viewportService: ViewportService) {
|
||||
effect(() => {
|
||||
// Update selected recordings based on current recordings
|
||||
const validIds = new Set(this.recordings.map((r) => r.recordingId));
|
||||
const recordings = this.recordings();
|
||||
const validIds = new Set(recordings.map((r) => r.recordingId));
|
||||
const filteredSelection = new Set([...this.selectedRecordings()].filter((id) => validIds.has(id)));
|
||||
this.selectedRecordings.set(filteredSelection);
|
||||
this.updateSelectionState();
|
||||
|
||||
// Show message when no recordings match filters
|
||||
this.showEmptyFilterMessage = this.recordings.length === 0 && this.hasActiveFilters();
|
||||
}
|
||||
this.showEmptyFilterMessage = recordings.length === 0 && this.hasActiveFilters();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.setupFilters();
|
||||
this.updateDisplayedColumns();
|
||||
|
||||
// Calculate showEmptyFilterMessage based on initial state
|
||||
this.showEmptyFilterMessage = this.recordings.length === 0 && this.hasActiveFilters();
|
||||
}
|
||||
|
||||
// ===== INITIALIZATION METHODS =====
|
||||
|
||||
private setupFilters() {
|
||||
// Set up initial filter values
|
||||
this.nameFilterControl.setValue(this.initialFilters.nameFilter);
|
||||
this.statusFilterControl.setValue(this.initialFilters.statusFilter);
|
||||
this.currentSortField = this.initialFilters.sortField;
|
||||
this.currentSortOrder = this.initialFilters.sortOrder;
|
||||
// Set up initial filter values from input signal
|
||||
const filters = this.initialFilters();
|
||||
this.nameFilterControl.setValue(filters.nameFilter);
|
||||
this.statusFilterControl.setValue(filters.statusFilter);
|
||||
this.currentSortField = filters.sortField;
|
||||
this.currentSortOrder = filters.sortOrder;
|
||||
|
||||
// Set up name filter change detection
|
||||
this.nameFilterControl.valueChanges.subscribe((value) => {
|
||||
@ -209,10 +200,10 @@ export class RecordingListsComponent implements OnInit, OnChanges {
|
||||
private updateDisplayedColumns() {
|
||||
this.displayedColumns = [];
|
||||
|
||||
if (this.showSelection) {
|
||||
if (this.showSelection()) {
|
||||
this.displayedColumns.push('select');
|
||||
}
|
||||
if (this.showRoomInfo) {
|
||||
if (this.showRoomInfo()) {
|
||||
this.displayedColumns.push('roomInfo');
|
||||
}
|
||||
|
||||
@ -226,7 +217,7 @@ export class RecordingListsComponent implements OnInit, OnChanges {
|
||||
if (this.allSelected()) {
|
||||
selected.clear();
|
||||
} else {
|
||||
this.recordings.forEach((recording) => {
|
||||
this.recordings().forEach((recording) => {
|
||||
if (this.canSelectRecording(recording)) {
|
||||
selected.add(recording.recordingId);
|
||||
}
|
||||
@ -248,7 +239,7 @@ export class RecordingListsComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
private updateSelectionState() {
|
||||
const selectableRecordings = this.recordings.filter((r) => this.canSelectRecording(r));
|
||||
const selectableRecordings = this.recordings().filter((r) => this.canSelectRecording(r));
|
||||
const selectedCount = this.selectedRecordings().size;
|
||||
const selectableCount = selectableRecordings.length;
|
||||
|
||||
@ -266,7 +257,7 @@ export class RecordingListsComponent implements OnInit, OnChanges {
|
||||
|
||||
getSelectedRecordings(): MeetRecordingInfo[] {
|
||||
const selected = this.selectedRecordings();
|
||||
return this.recordings.filter((r) => selected.has(r.recordingId));
|
||||
return this.recordings().filter((r) => selected.has(r.recordingId));
|
||||
}
|
||||
|
||||
// ===== ACTION METHODS =====
|
||||
@ -379,7 +370,7 @@ export class RecordingListsComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
canDeleteRecording(recording: MeetRecordingInfo): boolean {
|
||||
return this.canDeleteRecordings && this.isStatusInGroup(recording.status, this.STATUS_GROUPS.SELECTABLE);
|
||||
return this.canDeleteRecordings() && this.isStatusInGroup(recording.status, this.STATUS_GROUPS.SELECTABLE);
|
||||
}
|
||||
|
||||
isRecordingFailed(recording: MeetRecordingInfo): boolean {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
export * from './components';
|
||||
// export * from './models';
|
||||
export * from './guards';
|
||||
export * from './models';
|
||||
export * from './pages';
|
||||
export * from './services';
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
export * from './recording-list.model';
|
||||
@ -0,0 +1,13 @@
|
||||
import { MeetRecordingInfo, MeetRecordingStatus } from '@openvidu-meet/typings';
|
||||
|
||||
export interface RecordingTableAction {
|
||||
recordings: MeetRecordingInfo[];
|
||||
action: 'play' | 'download' | 'shareLink' | 'delete' | 'bulkDelete' | 'bulkDownload';
|
||||
}
|
||||
|
||||
export interface RecordingTableFilter {
|
||||
nameFilter: string;
|
||||
statusFilter: MeetRecordingStatus | '';
|
||||
sortField: 'roomName' | 'startDate' | 'duration' | 'size';
|
||||
sortOrder: 'asc' | 'desc';
|
||||
}
|
||||
@ -38,7 +38,7 @@
|
||||
[showFilters]="true"
|
||||
[showSelection]="true"
|
||||
[showLoadMore]="hasMoreRecordings"
|
||||
[initialFilters]="initialFilters"
|
||||
[initialFilters]="initialFilters()"
|
||||
(recordingAction)="onRecordingAction($event)"
|
||||
(loadMore)="loadMoreRecordings($event)"
|
||||
(refresh)="refreshRecordings($event)"
|
||||
|
||||
@ -5,11 +5,8 @@ import { ActivatedRoute } from '@angular/router';
|
||||
import { MeetRecordingFilters, MeetRecordingInfo } from '@openvidu-meet/typings';
|
||||
import { ILogger, LoggerService } from 'openvidu-components-angular';
|
||||
import { NotificationService } from '../../../../shared/services/notification.service';
|
||||
import {
|
||||
RecordingListsComponent,
|
||||
RecordingTableAction,
|
||||
RecordingTableFilter
|
||||
} from '../../components/recording-lists/recording-lists.component';
|
||||
import { RecordingListsComponent } from '../../components/recording-lists/recording-lists.component';
|
||||
import { RecordingTableAction, RecordingTableFilter } from '../../models/recording-list.model';
|
||||
import { RecordingService } from '../../services/recording.service';
|
||||
|
||||
@Component({
|
||||
@ -26,12 +23,12 @@ export class RecordingsComponent implements OnInit {
|
||||
showInitialLoader = false;
|
||||
isLoading = false;
|
||||
|
||||
initialFilters: RecordingTableFilter = {
|
||||
initialFilters = signal<RecordingTableFilter>({
|
||||
nameFilter: '',
|
||||
statusFilter: '',
|
||||
sortField: 'startDate',
|
||||
sortOrder: 'desc'
|
||||
};
|
||||
});
|
||||
|
||||
// Pagination
|
||||
hasMoreRecordings = false;
|
||||
@ -46,19 +43,25 @@ export class RecordingsComponent implements OnInit {
|
||||
protected route: ActivatedRoute
|
||||
) {
|
||||
this.log = this.loggerService.get('OpenVidu Meet - RecordingsComponent');
|
||||
|
||||
// Get room ID from route query params and set initial filters before component initialization
|
||||
const roomId = this.route.snapshot.queryParamMap.get('room-id');
|
||||
if (roomId) {
|
||||
this.initialFilters.set({
|
||||
nameFilter: roomId,
|
||||
statusFilter: '',
|
||||
sortField: 'startDate',
|
||||
sortOrder: 'desc'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
const roomId = this.route.snapshot.queryParamMap.get('room-id');
|
||||
const delayLoader = setTimeout(() => {
|
||||
this.showInitialLoader = true;
|
||||
}, 200);
|
||||
|
||||
// If a specific room ID is provided, filter recordings by that room
|
||||
if (roomId) {
|
||||
this.initialFilters.nameFilter = roomId;
|
||||
}
|
||||
await this.loadRecordings(this.initialFilters);
|
||||
await this.loadRecordings(this.initialFilters());
|
||||
|
||||
clearTimeout(delayLoader);
|
||||
this.showInitialLoader = false;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user