mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ACS-8959] Introduce new takeUntilDestroyed
operator where possible (#10388)
This commit is contained in:
committed by
GitHub
parent
3f6b60760f
commit
3078387325
@@ -15,15 +15,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Input, OnDestroy, Directive, inject } from '@angular/core';
|
||||
import { Directive, inject, Input } from '@angular/core';
|
||||
import { CardViewUpdateService } from '../services/card-view-update.service';
|
||||
import { CardViewItem } from '../interfaces/card-view.interfaces';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Directive()
|
||||
// eslint-disable-next-line @angular-eslint/directive-class-suffix
|
||||
export abstract class BaseCardView<T extends CardViewItem> implements OnDestroy {
|
||||
export abstract class BaseCardView<T extends CardViewItem> {
|
||||
protected cardViewUpdateService = inject(CardViewUpdateService);
|
||||
|
||||
@Input()
|
||||
@@ -32,10 +31,8 @@ export abstract class BaseCardView<T extends CardViewItem> implements OnDestroy
|
||||
@Input()
|
||||
property: T;
|
||||
|
||||
protected destroy$ = new Subject<boolean>();
|
||||
|
||||
constructor() {
|
||||
this.cardViewUpdateService.updateItem$.pipe(takeUntil(this.destroy$)).subscribe((itemModel) => {
|
||||
this.cardViewUpdateService.updateItem$.pipe(takeUntilDestroyed()).subscribe((itemModel) => {
|
||||
if (this.property.key === itemModel.key) {
|
||||
this.property.value = itemModel.value;
|
||||
}
|
||||
@@ -54,8 +51,4 @@ export abstract class BaseCardView<T extends CardViewItem> implements OnDestroy
|
||||
return !!this.property.icon;
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destroy$.next(true);
|
||||
this.destroy$.complete();
|
||||
}
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Input, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, DestroyRef, inject, Input, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
|
||||
import {
|
||||
DatetimeAdapter,
|
||||
@@ -26,7 +26,6 @@ import {
|
||||
} from '@mat-datetimepicker/core';
|
||||
import { CardViewDateItemModel } from '../../models/card-view-dateitem.model';
|
||||
import { UserPreferencesService, UserPreferenceValues } from '../../../common/services/user-preferences.service';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { BaseCardView } from '../base-card-view';
|
||||
import { ClipboardService } from '../../../clipboard/clipboard.service';
|
||||
import { TranslationService } from '../../../translation/translation.service';
|
||||
@@ -41,6 +40,7 @@ import { MatChipsModule } from '@angular/material/chips';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
providers: [
|
||||
@@ -66,7 +66,7 @@ import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
host: { class: 'adf-card-view-dateitem' }
|
||||
})
|
||||
export class CardViewDateItemComponent extends BaseCardView<CardViewDateItemModel> implements OnInit, OnDestroy {
|
||||
export class CardViewDateItemComponent extends BaseCardView<CardViewDateItemModel> implements OnInit {
|
||||
@Input()
|
||||
displayEmpty = true;
|
||||
|
||||
@@ -78,6 +78,8 @@ export class CardViewDateItemComponent extends BaseCardView<CardViewDateItemMode
|
||||
|
||||
valueDate: Date;
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private dateAdapter: DateAdapter<Date>,
|
||||
private userPreferencesService: UserPreferencesService,
|
||||
@@ -90,7 +92,7 @@ export class CardViewDateItemComponent extends BaseCardView<CardViewDateItemMode
|
||||
ngOnInit() {
|
||||
this.userPreferencesService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((locale) => {
|
||||
this.property.locale = locale;
|
||||
});
|
||||
@@ -104,10 +106,6 @@ export class CardViewDateItemComponent extends BaseCardView<CardViewDateItemMode
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
super.ngOnDestroy();
|
||||
}
|
||||
|
||||
get showProperty(): boolean {
|
||||
return this.displayEmpty || !this.property.isEmpty();
|
||||
}
|
||||
|
@@ -52,7 +52,6 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
})
|
||||
export class CardViewSelectItemComponent extends BaseCardView<CardViewSelectItemModel<string | number>> implements OnInit, OnChanges {
|
||||
private appConfig = inject(AppConfigService);
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
static HIDE_FILTER_LIMIT = 5;
|
||||
|
||||
@Input() options$: Observable<CardViewSelectItemOption<string | number>[]>;
|
||||
@@ -71,6 +70,8 @@ export class CardViewSelectItemComponent extends BaseCardView<CardViewSelectItem
|
||||
autocompleteControl = new UntypedFormControl();
|
||||
editedValue: string | number;
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
this.value = this.property.value;
|
||||
if (changes.property?.firstChange) {
|
||||
|
@@ -15,10 +15,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, ViewEncapsulation, ViewChild, ElementRef, OnDestroy, Inject, Output, EventEmitter, OnInit } from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
DestroyRef,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
Inject,
|
||||
inject,
|
||||
OnInit,
|
||||
Output,
|
||||
ViewChild,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import { MatSelect } from '@angular/material/select';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
@@ -26,6 +35,7 @@ import { FormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-select-filter-input',
|
||||
@@ -36,13 +46,14 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
host: { class: 'adf-select-filter-input' },
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class SelectFilterInputComponent implements OnInit, OnDestroy {
|
||||
export class SelectFilterInputComponent implements OnInit {
|
||||
@ViewChild('selectFilterInput', { read: ElementRef, static: false }) selectFilterInput: ElementRef;
|
||||
@Output() change = new EventEmitter<string>();
|
||||
|
||||
term = '';
|
||||
previousSelected: any[];
|
||||
private onDestroy$ = new Subject<void>();
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(@Inject(MatSelect) private matSelect: MatSelect) {}
|
||||
|
||||
@@ -51,9 +62,9 @@ export class SelectFilterInputComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.change.pipe(takeUntil(this.onDestroy$)).subscribe((val: string) => (this.term = val));
|
||||
this.change.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((val: string) => (this.term = val));
|
||||
|
||||
this.matSelect.openedChange.pipe(takeUntil(this.onDestroy$)).subscribe((isOpened: boolean) => {
|
||||
this.matSelect.openedChange.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((isOpened: boolean) => {
|
||||
if (isOpened) {
|
||||
this.selectFilterInput.nativeElement.focus();
|
||||
} else {
|
||||
@@ -63,7 +74,7 @@ export class SelectFilterInputComponent implements OnInit, OnDestroy {
|
||||
|
||||
if (this.matSelect.ngControl) {
|
||||
this.previousSelected = this.matSelect.ngControl.value;
|
||||
this.matSelect.ngControl.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe((values) => {
|
||||
this.matSelect.ngControl.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((values) => {
|
||||
let restoreSelection = false;
|
||||
if (this.matSelect.multiple && Array.isArray(this.previousSelected)) {
|
||||
if (!Array.isArray(values)) {
|
||||
@@ -109,9 +120,4 @@ export class SelectFilterInputComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next();
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
}
|
||||
|
@@ -15,7 +15,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, SimpleChanges, ViewEncapsulation } from '@angular/core';
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
DestroyRef,
|
||||
inject,
|
||||
Input,
|
||||
OnChanges,
|
||||
SimpleChanges,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import { CardViewTextItemModel } from '../../models/card-view-textitem.model';
|
||||
import { BaseCardView } from '../base-card-view';
|
||||
import { MatChipInputEvent, MatChipsModule } from '@angular/material/chips';
|
||||
@@ -23,7 +32,7 @@ import { ClipboardService } from '../../../clipboard/clipboard.service';
|
||||
import { TranslationService } from '../../../translation/translation.service';
|
||||
import { CardViewItemValidator } from '../../interfaces/card-view-item-validator.interface';
|
||||
import { FormsModule, ReactiveFormsModule, UntypedFormControl } from '@angular/forms';
|
||||
import { debounceTime, takeUntil, filter } from 'rxjs/operators';
|
||||
import { debounceTime, filter } from 'rxjs/operators';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
@@ -31,6 +40,7 @@ import { MatInputModule } from '@angular/material/input';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
export const DEFAULT_SEPARATOR = ', ';
|
||||
const templateTypes = {
|
||||
@@ -61,7 +71,7 @@ const templateTypes = {
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
host: { class: 'adf-card-view-textitem' }
|
||||
})
|
||||
export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemModel> implements OnChanges, OnDestroy {
|
||||
export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemModel> implements OnChanges {
|
||||
@Input()
|
||||
displayEmpty = true;
|
||||
|
||||
@@ -81,6 +91,8 @@ export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemMode
|
||||
errors: CardViewItemValidator[];
|
||||
templateType: string;
|
||||
textInput = new UntypedFormControl();
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(private clipboardService: ClipboardService, private translateService: TranslationService, private cd: ChangeDetectorRef) {
|
||||
super();
|
||||
@@ -92,7 +104,7 @@ export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemMode
|
||||
.pipe(
|
||||
filter((textInputValue) => textInputValue !== this.editedValue && textInputValue !== null),
|
||||
debounceTime(50),
|
||||
takeUntil(this.destroy$)
|
||||
takeUntilDestroyed(this.destroyRef)
|
||||
)
|
||||
.subscribe((textInputValue) => {
|
||||
this.editedValue = textInputValue;
|
||||
@@ -222,10 +234,6 @@ export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemMode
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
super.ngOnDestroy();
|
||||
}
|
||||
|
||||
get showProperty(): boolean {
|
||||
return this.displayEmpty || !this.property.isEmpty();
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@
|
||||
import { ChangeDetectionStrategy, Component, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@@ -39,7 +39,7 @@ export class BooleanCellComponent extends DataTableCellComponent implements OnIn
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
|
||||
this.value$.pipe(takeUntil(this.onDestroy$)).subscribe((value) => {
|
||||
this.value$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((value) => {
|
||||
this.boolValue = this.transformBoolean(value);
|
||||
});
|
||||
}
|
||||
|
@@ -15,11 +15,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, EventEmitter, inject, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, DestroyRef, EventEmitter, inject, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
|
||||
import { ReactiveFormsModule, UntypedFormControl } from '@angular/forms';
|
||||
import { MatMenuTrigger } from '@angular/material/menu';
|
||||
import { Subject } from 'rxjs';
|
||||
import { debounceTime, takeUntil } from 'rxjs/operators';
|
||||
import { debounceTime } from 'rxjs/operators';
|
||||
import { DataColumn } from '../../data/data-column.model';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
@@ -28,6 +27,7 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { TranslationService } from '../../../translation';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-datatable-column-selector',
|
||||
@@ -37,7 +37,7 @@ import { TranslationService } from '../../../translation';
|
||||
styleUrls: ['./columns-selector.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class ColumnsSelectorComponent implements OnInit, OnDestroy {
|
||||
export class ColumnsSelectorComponent implements OnInit {
|
||||
private translationService = inject(TranslationService);
|
||||
|
||||
@Input()
|
||||
@@ -55,21 +55,22 @@ export class ColumnsSelectorComponent implements OnInit, OnDestroy {
|
||||
@Output()
|
||||
submitColumnsVisibility = new EventEmitter<DataColumn[]>();
|
||||
|
||||
onDestroy$ = new Subject();
|
||||
columnItems: DataColumn[] = [];
|
||||
searchInputControl = new UntypedFormControl('');
|
||||
searchQuery = '';
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
ngOnInit(): void {
|
||||
this.mainMenuTrigger.menuOpened.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
|
||||
this.mainMenuTrigger.menuOpened.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
||||
this.updateColumnItems();
|
||||
});
|
||||
|
||||
this.mainMenuTrigger.menuClosed.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
|
||||
this.mainMenuTrigger.menuClosed.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
||||
this.searchInputControl.setValue('');
|
||||
});
|
||||
|
||||
this.searchInputControl.valueChanges.pipe(debounceTime(300), takeUntil(this.onDestroy$)).subscribe((searchQuery) => {
|
||||
this.searchInputControl.valueChanges.pipe(debounceTime(300), takeUntilDestroyed(this.destroyRef)).subscribe((searchQuery) => {
|
||||
this.searchQuery = searchQuery;
|
||||
this.updateColumnItems();
|
||||
});
|
||||
@@ -81,12 +82,6 @@ export class ColumnsSelectorComponent implements OnInit, OnDestroy {
|
||||
columns = this.sortColumns(columns);
|
||||
this.columnItems = columns;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
closeMenu(): void {
|
||||
this.mainMenuTrigger.closeMenu();
|
||||
}
|
||||
|
@@ -15,15 +15,23 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ChangeDetectionStrategy, Component, Input, OnInit, ViewEncapsulation, OnDestroy, inject } from '@angular/core';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
DestroyRef,
|
||||
inject,
|
||||
Input,
|
||||
OnInit,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import { DataColumn } from '../../data/data-column.model';
|
||||
import { DataRow } from '../../data/data-row.model';
|
||||
import { DataTableAdapter } from '../../data/datatable-adapter';
|
||||
import { BehaviorSubject, Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { DataTableService } from '../../services/datatable.service';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ClipboardDirective } from '../../../clipboard/clipboard.directive';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-datatable-cell',
|
||||
@@ -49,7 +57,7 @@ import { ClipboardDirective } from '../../../clipboard/clipboard.directive';
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
host: { class: 'adf-datatable-content-cell' }
|
||||
})
|
||||
export class DataTableCellComponent implements OnInit, OnDestroy {
|
||||
export class DataTableCellComponent implements OnInit {
|
||||
/** Data table adapter instance. */
|
||||
@Input()
|
||||
data: DataTableAdapter;
|
||||
@@ -74,7 +82,7 @@ export class DataTableCellComponent implements OnInit, OnDestroy {
|
||||
@Input()
|
||||
resolverFn: (row: DataRow, col: DataColumn) => any = null;
|
||||
|
||||
protected onDestroy$ = new Subject<boolean>();
|
||||
protected destroyRef = inject(DestroyRef);
|
||||
protected dataTableService = inject(DataTableService, { optional: true });
|
||||
value$ = new BehaviorSubject<any>('');
|
||||
|
||||
@@ -100,7 +108,7 @@ export class DataTableCellComponent implements OnInit, OnDestroy {
|
||||
return;
|
||||
}
|
||||
|
||||
this.dataTableService.rowUpdate.pipe(takeUntil(this.onDestroy$)).subscribe((data) => {
|
||||
this.dataTableService.rowUpdate.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data) => {
|
||||
if (data?.id === this.row?.id && data.obj) {
|
||||
this.row.obj = data.obj;
|
||||
this.row['cache'][this.column.key] = this.getNestedPropertyValue(data.obj, this.column.key);
|
||||
@@ -113,9 +121,4 @@ export class DataTableCellComponent implements OnInit, OnDestroy {
|
||||
private getNestedPropertyValue(obj: any, path: string) {
|
||||
return path.split('.').reduce((source, key) => (source ? source[key] : ''), obj);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
}
|
||||
|
@@ -22,10 +22,12 @@ import {
|
||||
AfterViewInit,
|
||||
Component,
|
||||
ContentChild,
|
||||
DestroyRef,
|
||||
DoCheck,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
HostListener,
|
||||
inject,
|
||||
Input,
|
||||
IterableDiffers,
|
||||
OnChanges,
|
||||
@@ -79,6 +81,7 @@ import { BooleanCellComponent } from '../boolean-cell/boolean-cell.component';
|
||||
import { JsonCellComponent } from '../json-cell/json-cell.component';
|
||||
import { AmountCellComponent } from '../amount-cell/amount-cell.component';
|
||||
import { NumberCellComponent } from '../number-cell/number-cell.component';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
export enum ShowHeaderMode {
|
||||
@@ -325,10 +328,10 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges,
|
||||
private differ: any;
|
||||
private rowMenuCache: any = {};
|
||||
|
||||
private subscriptions: Subscription[] = [];
|
||||
private singleClickStreamSub: Subscription;
|
||||
private multiClickStreamSub: Subscription;
|
||||
private dataRowsChanged: Subscription;
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
@HostListener('keyup', ['$event'])
|
||||
onKeydown(event: KeyboardEvent): void {
|
||||
@@ -349,11 +352,9 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges,
|
||||
|
||||
ngAfterContentInit() {
|
||||
if (this.columnList) {
|
||||
this.subscriptions.push(
|
||||
this.columnList.columns.changes.subscribe(() => {
|
||||
this.setTableSchema();
|
||||
})
|
||||
);
|
||||
this.columnList.columns.changes.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
||||
this.setTableSchema();
|
||||
});
|
||||
}
|
||||
this.setTableSchema();
|
||||
}
|
||||
@@ -713,7 +714,7 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges,
|
||||
this.isSelectAllIndeterminate = false;
|
||||
|
||||
if (this.multiselect) {
|
||||
const selectableRows = this.data.getRows().filter(row => row?.isSelectable);
|
||||
const selectableRows = this.data.getRows().filter((row) => row?.isSelectable);
|
||||
if (selectableRows && selectableRows.length > 0) {
|
||||
for (let i = 0; i < selectableRows.length; i++) {
|
||||
this.selectRow(selectableRows[i], matCheckboxChange.checked);
|
||||
@@ -954,14 +955,6 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges,
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unsubscribeClickStream();
|
||||
|
||||
this.subscriptions.forEach((s) => s.unsubscribe());
|
||||
this.subscriptions = [];
|
||||
|
||||
if (this.dataRowsChanged) {
|
||||
this.dataRowsChanged.unsubscribe();
|
||||
this.dataRowsChanged = null;
|
||||
}
|
||||
}
|
||||
|
||||
getNameColumnValue() {
|
||||
|
@@ -19,7 +19,7 @@ import { CommonModule } from '@angular/common';
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@@ -43,7 +43,7 @@ export class IconCellComponent extends DataTableCellComponent implements OnInit
|
||||
|
||||
ngOnInit(): void {
|
||||
super.ngOnInit();
|
||||
this.value$.pipe(takeUntil(this.onDestroy$)).subscribe((value) => {
|
||||
this.value$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((value) => {
|
||||
const newIcon = this.validateIconValue(value) ? value : '';
|
||||
if (this.icon !== newIcon) {
|
||||
this.icon = newIcon;
|
||||
|
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { ElementRef, NgZone, Renderer2 } from '@angular/core';
|
||||
import { ElementRef, Injector, NgZone, Renderer2, runInInjectionContext } from '@angular/core';
|
||||
import { ResizableDirective } from './resizable.directive';
|
||||
|
||||
describe('ResizableDirective', () => {
|
||||
@@ -64,9 +64,12 @@ describe('ResizableDirective', () => {
|
||||
element = TestBed.inject(ElementRef);
|
||||
renderer = TestBed.inject(Renderer2);
|
||||
ngZone = TestBed.inject(NgZone);
|
||||
const injector = TestBed.inject(Injector);
|
||||
spyOn(ngZone, 'runOutsideAngular').and.callFake((fn) => fn());
|
||||
spyOn(ngZone, 'run').and.callFake((fn) => fn());
|
||||
directive = new ResizableDirective(renderer, element, ngZone);
|
||||
runInInjectionContext(injector, () => {
|
||||
directive = new ResizableDirective(renderer, element, ngZone);
|
||||
});
|
||||
|
||||
directive.ngOnInit();
|
||||
});
|
||||
|
@@ -15,10 +15,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Subject, Observable, Observer, merge } from 'rxjs';
|
||||
import { BoundingRectangle, ResizeEvent, IResizeMouseEvent, ICoordinateX } from './types';
|
||||
import { map, take, share, filter, pairwise, mergeMap, takeUntil } from 'rxjs/operators';
|
||||
import { OnInit, Output, NgZone, OnDestroy, Directive, Renderer2, ElementRef, EventEmitter, Input } from '@angular/core';
|
||||
import { merge, Observable, Observer, Subject } from 'rxjs';
|
||||
import { BoundingRectangle, ICoordinateX, IResizeMouseEvent, ResizeEvent } from './types';
|
||||
import { filter, map, mergeMap, pairwise, share, take, takeUntil } from 'rxjs/operators';
|
||||
import { DestroyRef, Directive, ElementRef, EventEmitter, inject, Input, NgZone, OnDestroy, OnInit, Output, Renderer2 } from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Directive({
|
||||
selector: '[adf-resizable]',
|
||||
@@ -64,7 +65,7 @@ export class ResizableDirective implements OnInit, OnDestroy {
|
||||
private unsubscribeMouseMove?: () => void;
|
||||
private unsubscribeMouseUp?: () => void;
|
||||
|
||||
private destroy$ = new Subject<void>();
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(private readonly renderer: Renderer2, private readonly element: ElementRef<HTMLElement>, private readonly zone: NgZone) {
|
||||
this.pointerDown = new Observable((observer: Observer<IResizeMouseEvent>) => {
|
||||
@@ -133,7 +134,7 @@ export class ResizableDirective implements OnInit, OnDestroy {
|
||||
.pipe(
|
||||
map(({ resize = false }) => resize),
|
||||
filter((resize) => resize),
|
||||
takeUntil(this.destroy$)
|
||||
takeUntilDestroyed(this.destroyRef)
|
||||
)
|
||||
.subscribe(() => {
|
||||
const startingRect: BoundingRectangle = this.getElementRect(this.element);
|
||||
@@ -151,7 +152,7 @@ export class ResizableDirective implements OnInit, OnDestroy {
|
||||
}
|
||||
});
|
||||
|
||||
mouseup$.pipe(takeUntil(this.destroy$)).subscribe(() => {
|
||||
mouseup$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
||||
if (this.currentRect) {
|
||||
this.renderer.setStyle(document.body, 'cursor', '');
|
||||
if (this.resizeEnd.observers.length > 0) {
|
||||
@@ -172,7 +173,6 @@ export class ResizableDirective implements OnInit, OnDestroy {
|
||||
this.unsubscribeMouseDown?.();
|
||||
this.unsubscribeMouseMove?.();
|
||||
this.unsubscribeMouseUp?.();
|
||||
this.destroy$.next();
|
||||
}
|
||||
|
||||
private getNewBoundingRectangle({ top, bottom, left, right }: BoundingRectangle, clientX: number): BoundingRectangle {
|
||||
|
@@ -15,9 +15,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Subject } from 'rxjs';
|
||||
import { ResizableDirective } from './resizable.directive';
|
||||
import { Input, OnInit, Directive, Renderer2, ElementRef, OnDestroy, NgZone } from '@angular/core';
|
||||
import { Directive, ElementRef, Input, NgZone, OnDestroy, OnInit, Renderer2 } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[adf-resize-handle]',
|
||||
@@ -32,9 +31,6 @@ export class ResizeHandleDirective implements OnInit, OnDestroy {
|
||||
private unlistenMouseDown?: () => void;
|
||||
private unlistenMouseMove?: () => void;
|
||||
private unlistenMouseUp?: () => void;
|
||||
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
constructor(private readonly renderer: Renderer2, private readonly element: ElementRef, private readonly zone: NgZone) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -49,7 +45,6 @@ export class ResizeHandleDirective implements OnInit, OnDestroy {
|
||||
this.unlistenMouseDown?.();
|
||||
this.unlistenMouseMove?.();
|
||||
this.unlistenMouseUp?.();
|
||||
this.destroy$.next();
|
||||
}
|
||||
|
||||
private onMousedown(event: MouseEvent): void {
|
||||
|
@@ -15,16 +15,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Inject, InjectionToken, Injector, OnDestroy, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, Inject, InjectionToken, Injector, ViewEncapsulation } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
|
||||
import { AdditionalDialogActionButton, DialogData } from './dialog-data.interface';
|
||||
import { BehaviorSubject, Subject } from 'rxjs';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { DialogSize, DialogSizes } from './dialog.model';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
export const DIALOG_COMPONENT_DATA = new InjectionToken<any>('dialog component data');
|
||||
|
||||
@@ -36,7 +36,7 @@ export const DIALOG_COMPONENT_DATA = new InjectionToken<any>('dialog component d
|
||||
imports: [CommonModule, TranslateModule, MatIconModule, MatDialogModule, MatButtonModule],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class DialogComponent implements OnDestroy {
|
||||
export class DialogComponent {
|
||||
isConfirmButtonDisabled$ = new BehaviorSubject<boolean>(false);
|
||||
isCloseButtonHidden: boolean;
|
||||
isCancelButtonHidden: boolean;
|
||||
@@ -48,8 +48,6 @@ export class DialogComponent implements OnDestroy {
|
||||
|
||||
dataInjector: Injector;
|
||||
|
||||
private onDestroy$ = new Subject<void>();
|
||||
|
||||
constructor(
|
||||
@Inject(MAT_DIALOG_DATA)
|
||||
public data: DialogData,
|
||||
@@ -68,11 +66,11 @@ export class DialogComponent implements OnDestroy {
|
||||
});
|
||||
|
||||
if (data.isConfirmButtonDisabled$) {
|
||||
data.isConfirmButtonDisabled$.pipe(takeUntil(this.onDestroy$)).subscribe((value) => this.isConfirmButtonDisabled$.next(value));
|
||||
data.isConfirmButtonDisabled$.pipe(takeUntilDestroyed()).subscribe((value) => this.isConfirmButtonDisabled$.next(value));
|
||||
}
|
||||
|
||||
if (data.dataOnConfirm$) {
|
||||
data.dataOnConfirm$.pipe(takeUntil(this.onDestroy$)).subscribe((value) => (this.dataOnConfirm = value));
|
||||
data.dataOnConfirm$.pipe(takeUntilDestroyed()).subscribe((value) => (this.dataOnConfirm = value));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,9 +79,4 @@ export class DialogComponent implements OnDestroy {
|
||||
this.isConfirmButtonDisabled$.next(true);
|
||||
this.dialogRef.close(this.dataOnConfirm || true);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next();
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
}
|
||||
|
@@ -15,10 +15,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Inject, AfterViewInit, Directive, EventEmitter, OnDestroy, Output } from '@angular/core';
|
||||
import { AfterViewInit, DestroyRef, Directive, EventEmitter, inject, Inject, Output } from '@angular/core';
|
||||
import { MatSelect } from '@angular/material/select';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
const SELECT_ITEM_HEIGHT_EM = 3;
|
||||
|
||||
@@ -26,19 +25,19 @@ const SELECT_ITEM_HEIGHT_EM = 3;
|
||||
selector: '[adf-infinite-select-scroll]',
|
||||
standalone: true
|
||||
})
|
||||
export class InfiniteSelectScrollDirective implements AfterViewInit, OnDestroy {
|
||||
export class InfiniteSelectScrollDirective implements AfterViewInit {
|
||||
static readonly MAX_ITEMS = 50;
|
||||
|
||||
/** Emitted when scroll reaches the last item. */
|
||||
@Output() scrollEnd = new EventEmitter<Event>();
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private itemHeightToWaitBeforeLoadNext = 0;
|
||||
|
||||
constructor(@Inject(MatSelect) private matSelect: MatSelect) {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.matSelect.openedChange.pipe(takeUntil(this.onDestroy$)).subscribe((opened: boolean) => {
|
||||
this.matSelect.openedChange.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((opened: boolean) => {
|
||||
if (opened) {
|
||||
this.itemHeightToWaitBeforeLoadNext = this.getItemHeight() * (InfiniteSelectScrollDirective.MAX_ITEMS / 2);
|
||||
this.matSelect.panel.nativeElement.addEventListener('scroll', (event: Event) => this.handleScrollEvent(event));
|
||||
@@ -46,11 +45,6 @@ export class InfiniteSelectScrollDirective implements AfterViewInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
private handleScrollEvent(event: Event) {
|
||||
if (this.isScrollInNextFetchArea(event)) {
|
||||
this.scrollEnd.emit(event);
|
||||
|
@@ -38,7 +38,6 @@ import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatChip, MatChipsModule } from '@angular/material/chips';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { Chip } from './chip';
|
||||
|
||||
/**
|
||||
@@ -98,7 +97,6 @@ export class DynamicChipListComponent implements OnChanges, OnInit, AfterViewIni
|
||||
paginationData: Pagination;
|
||||
|
||||
private initialChips: Chip[] = [];
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
private initialLimitChipsDisplayed: boolean;
|
||||
private viewMoreButtonLeftOffsetBeforeFlexDirection: number;
|
||||
private requestedDisplayingAllChips = false;
|
||||
@@ -139,8 +137,6 @@ export class DynamicChipListComponent implements OnChanges, OnInit, AfterViewIni
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
this.resizeObserver.unobserve(this.containerView.nativeElement);
|
||||
}
|
||||
|
||||
|
@@ -18,20 +18,25 @@
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
import { NgIf } from '@angular/common';
|
||||
import { Component, inject, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, DestroyRef, inject, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { FormControl, ReactiveFormsModule, ValidationErrors, Validators } from '@angular/forms';
|
||||
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { DatetimeAdapter, MAT_DATETIME_FORMATS, MatDatetimepickerModule } from '@mat-datetimepicker/core';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { ADF_DATE_FORMATS, ADF_DATETIME_FORMATS, AdfDateFnsAdapter, AdfDateTimeFnsAdapter, DateFnsUtils } from '../../../../common';
|
||||
import {
|
||||
ADF_DATE_FORMATS,
|
||||
ADF_DATETIME_FORMATS,
|
||||
AdfDateFnsAdapter,
|
||||
AdfDateTimeFnsAdapter,
|
||||
DateFnsUtils
|
||||
} from '../../../../common';
|
||||
import { FormService } from '../../../services/form.service';
|
||||
import { ErrorWidgetComponent } from '../error/error.component';
|
||||
import { WidgetComponent } from '../widget.component';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { ErrorMessageModel } from '../core/error-message.model';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
selector: 'date-time-widget',
|
||||
@@ -47,14 +52,15 @@ import { ErrorMessageModel } from '../core/error-message.model';
|
||||
imports: [NgIf, TranslateModule, MatFormFieldModule, MatInputModule, MatDatetimepickerModule, ReactiveFormsModule, ErrorWidgetComponent],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class DateTimeWidgetComponent extends WidgetComponent implements OnInit, OnDestroy {
|
||||
export class DateTimeWidgetComponent extends WidgetComponent implements OnInit {
|
||||
minDate: Date;
|
||||
maxDate: Date;
|
||||
datetimeInputControl: FormControl<Date> = new FormControl<Date>(null);
|
||||
|
||||
private onDestroy$ = new Subject<void>();
|
||||
|
||||
public readonly formService = inject(FormService);
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private readonly dateAdapter = inject(DateAdapter);
|
||||
private readonly dateTimeAdapter = inject(DatetimeAdapter);
|
||||
|
||||
@@ -82,7 +88,7 @@ export class DateTimeWidgetComponent extends WidgetComponent implements OnInit,
|
||||
}
|
||||
|
||||
private subscribeToDateChanges(): void {
|
||||
this.datetimeInputControl.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe((newDate: Date) => {
|
||||
this.datetimeInputControl.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((newDate: Date) => {
|
||||
this.field.value = newDate;
|
||||
this.updateField();
|
||||
});
|
||||
@@ -151,9 +157,4 @@ export class DateTimeWidgetComponent extends WidgetComponent implements OnInit,
|
||||
this.maxDate = DateFnsUtils.getDate(this.field.maxValue);
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.onDestroy$.next();
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
}
|
||||
|
@@ -18,21 +18,20 @@
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
import { NgIf } from '@angular/common';
|
||||
import { Component, inject, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, DestroyRef, inject, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { FormControl, ReactiveFormsModule, ValidationErrors, Validators } from '@angular/forms';
|
||||
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { ADF_DATE_FORMATS, AdfDateFnsAdapter, DateFnsUtils, DEFAULT_DATE_FORMAT } from '../../../../common';
|
||||
import { FormService } from '../../../services/form.service';
|
||||
import { ErrorWidgetComponent } from '../error/error.component';
|
||||
import { WidgetComponent } from '../widget.component';
|
||||
import { ErrorMessageModel } from '../core/error-message.model';
|
||||
import { parseISO } from 'date-fns';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
selector: 'date-widget',
|
||||
@@ -56,17 +55,17 @@ import { parseISO } from 'date-fns';
|
||||
imports: [MatFormFieldModule, TranslateModule, MatInputModule, MatDatepickerModule, ReactiveFormsModule, ErrorWidgetComponent, NgIf],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class DateWidgetComponent extends WidgetComponent implements OnInit, OnDestroy {
|
||||
export class DateWidgetComponent extends WidgetComponent implements OnInit {
|
||||
minDate: Date;
|
||||
maxDate: Date;
|
||||
startAt: Date;
|
||||
|
||||
dateInputControl: FormControl<Date> = new FormControl<Date>(null);
|
||||
|
||||
private onDestroy$ = new Subject<void>();
|
||||
|
||||
public readonly formService = inject(FormService);
|
||||
|
||||
private readonly dateAdapter = inject(DateAdapter);
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
ngOnInit(): void {
|
||||
this.patchFormControl();
|
||||
@@ -92,7 +91,7 @@ export class DateWidgetComponent extends WidgetComponent implements OnInit, OnDe
|
||||
}
|
||||
|
||||
private subscribeToDateChanges(): void {
|
||||
this.dateInputControl.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe((newDate: Date) => {
|
||||
this.dateInputControl.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((newDate: Date) => {
|
||||
this.field.value = newDate;
|
||||
this.updateField();
|
||||
});
|
||||
@@ -164,9 +163,4 @@ export class DateWidgetComponent extends WidgetComponent implements OnInit, OnDe
|
||||
this.startAt = this.dateAdapter.parse(this.field.value, DEFAULT_DATE_FORMAT);
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.onDestroy$.next();
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
}
|
||||
|
@@ -15,10 +15,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Input, OnDestroy, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, Input, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { MatMenuModule, MatMenuTrigger, MenuPositionX, MenuPositionY } from '@angular/material/menu';
|
||||
import { IdentityUserModel } from '../auth/models/identity-user.model';
|
||||
import { Subject } from 'rxjs';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FullNamePipe, InitialUsernamePipe } from '../pipes';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
@@ -33,7 +32,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
styleUrls: ['./identity-user-info.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class IdentityUserInfoComponent implements OnDestroy {
|
||||
export class IdentityUserInfoComponent {
|
||||
@ViewChild(MatMenuTrigger) trigger: MatMenuTrigger;
|
||||
|
||||
/** Is the user logged in */
|
||||
@@ -67,13 +66,6 @@ export class IdentityUserInfoComponent implements OnDestroy {
|
||||
@Input()
|
||||
namePosition: 'right' | 'left' = 'right';
|
||||
|
||||
private destroy$ = new Subject();
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destroy$.next(true);
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
onKeyPress(event: KeyboardEvent) {
|
||||
this.closeUserModal(event);
|
||||
}
|
||||
|
@@ -16,29 +16,31 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ContentChild,
|
||||
Input,
|
||||
Output,
|
||||
OnInit,
|
||||
AfterViewInit,
|
||||
ViewChild,
|
||||
OnDestroy,
|
||||
TemplateRef,
|
||||
DestroyRef,
|
||||
EventEmitter,
|
||||
ViewEncapsulation,
|
||||
ChangeDetectorRef
|
||||
inject,
|
||||
Input,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
Output,
|
||||
TemplateRef,
|
||||
ViewChild,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import { MediaMatcher } from '@angular/cdk/layout';
|
||||
import { UserPreferencesService } from '../../../common/services/user-preferences.service';
|
||||
import { SidenavLayoutContentDirective } from '../../directives/sidenav-layout-content.directive';
|
||||
import { SidenavLayoutHeaderDirective } from '../../directives/sidenav-layout-header.directive';
|
||||
import { SidenavLayoutNavigationDirective } from '../../directives/sidenav-layout-navigation.directive';
|
||||
import { BehaviorSubject, Subject } from 'rxjs';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { Direction } from '@angular/cdk/bidi';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { LayoutContainerComponent } from '../layout-container/layout-container.component';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-sidenav-layout',
|
||||
@@ -99,7 +101,7 @@ export class SidenavLayoutComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
isMenuMinimized: () => this.isMenuMinimized
|
||||
};
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private readonly mediaMatcher: MediaMatcher,
|
||||
@@ -120,7 +122,7 @@ export class SidenavLayoutComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
|
||||
this.userPreferencesService
|
||||
.select('textOrientation')
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((direction: Direction) => {
|
||||
this.dir = direction;
|
||||
});
|
||||
@@ -132,8 +134,6 @@ export class SidenavLayoutComponent implements OnInit, AfterViewInit, OnDestroy
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.mediaQueryList.removeListener(this.onMediaQueryChange);
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
toggleMenu() {
|
||||
|
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, TemplateRef, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, DestroyRef, EventEmitter, inject, Input, OnInit, Output, TemplateRef, ViewEncapsulation } from '@angular/core';
|
||||
import { AbstractControl, ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
@@ -27,8 +27,6 @@ import { MatInputModule } from '@angular/material/input';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { AppConfigService, AppConfigValues } from '../../../app-config';
|
||||
import { AuthenticationService, BasicAlfrescoAuthService } from '../../../auth';
|
||||
import { OidcAuthenticationService } from '../../../auth/oidc/oidc-authentication.service';
|
||||
@@ -38,6 +36,7 @@ import { TranslationService } from '../../../translation';
|
||||
import { LoginErrorEvent } from '../../models/login-error.event';
|
||||
import { LoginSubmitEvent } from '../../models/login-submit.event';
|
||||
import { LoginSuccessEvent } from '../../models/login-success.event';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
enum LoginSteps {
|
||||
@@ -76,7 +75,7 @@ interface LoginFormValues {
|
||||
],
|
||||
host: { class: 'adf-login' }
|
||||
})
|
||||
export class LoginComponent implements OnInit, OnDestroy {
|
||||
export class LoginComponent implements OnInit {
|
||||
isPasswordShow: boolean = false;
|
||||
|
||||
/**
|
||||
@@ -146,7 +145,8 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||
data: any;
|
||||
|
||||
private _message: { [id: string]: { [id: string]: ValidationMessage } };
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private _fb: UntypedFormBuilder,
|
||||
@@ -191,12 +191,7 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||
this.form = this._fb.group(this.fieldsValidation);
|
||||
}
|
||||
|
||||
this.form.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe((data) => this.onValueChanged(data));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
this.form.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data) => this.onValueChanged(data));
|
||||
}
|
||||
|
||||
submit() {
|
||||
|
@@ -15,12 +15,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AfterViewInit, ChangeDetectorRef, Component, Input, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
DestroyRef,
|
||||
inject,
|
||||
Input,
|
||||
OnInit,
|
||||
ViewChild,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import { NotificationService } from '../services/notification.service';
|
||||
import { NOTIFICATION_TYPE, NotificationModel } from '../models/notification.model';
|
||||
import { MatMenuModule, MatMenuTrigger, MenuPositionX, MenuPositionY } from '@angular/material/menu';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject } from 'rxjs';
|
||||
import { StorageService } from '../../common/services/storage.service';
|
||||
import { PaginationModel } from '../../models/pagination.model';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
@@ -31,6 +39,7 @@ import { MatListModule } from '@angular/material/list';
|
||||
import { NgForOf, NgIf } from '@angular/common';
|
||||
import { InitialUsernamePipe, TimeAgoPipe } from '../../pipes';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-notification-history',
|
||||
@@ -52,7 +61,7 @@ import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class NotificationHistoryComponent implements OnDestroy, OnInit, AfterViewInit {
|
||||
export class NotificationHistoryComponent implements OnInit, AfterViewInit {
|
||||
public static MAX_NOTIFICATION_STACK_LENGTH = 100;
|
||||
public static NOTIFICATION_STORAGE = 'notification-history';
|
||||
|
||||
@@ -71,11 +80,12 @@ export class NotificationHistoryComponent implements OnDestroy, OnInit, AfterVie
|
||||
@Input()
|
||||
maxNotifications: number = 5;
|
||||
|
||||
onDestroy$ = new Subject<boolean>();
|
||||
notifications: NotificationModel[] = [];
|
||||
paginatedNotifications: NotificationModel[] = [];
|
||||
pagination: PaginationModel;
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(private notificationService: NotificationService, public storageService: StorageService, public cd: ChangeDetectorRef) {}
|
||||
|
||||
ngOnInit() {
|
||||
@@ -83,17 +93,12 @@ export class NotificationHistoryComponent implements OnDestroy, OnInit, AfterVie
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.notificationService.notifications$.pipe(takeUntil(this.onDestroy$)).subscribe((notification: NotificationModel) => {
|
||||
this.notificationService.notifications$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((notification: NotificationModel) => {
|
||||
this.addNewNotification(notification);
|
||||
this.cd.detectChanges();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
addNewNotification(notification: NotificationModel) {
|
||||
this.notifications.unshift(notification);
|
||||
|
||||
|
@@ -22,25 +22,25 @@ import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
DestroyRef,
|
||||
EventEmitter,
|
||||
inject,
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
OnDestroy,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
|
||||
import { PaginatedComponent } from './paginated-component.interface';
|
||||
import { Subject } from 'rxjs';
|
||||
import { PaginationComponentInterface } from './pagination-component.interface';
|
||||
import { RequestPaginationModel } from '../models/request-pagination.model';
|
||||
import { UserPreferencesService, UserPreferenceValues } from '../common/services/user-preferences.service';
|
||||
import { PaginationModel } from '../models/pagination.model';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-infinite-pagination',
|
||||
@@ -52,7 +52,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
standalone: true,
|
||||
imports: [CommonModule, MatButtonModule, MatProgressBarModule, TranslateModule]
|
||||
})
|
||||
export class InfinitePaginationComponent implements OnInit, OnDestroy, PaginationComponentInterface {
|
||||
export class InfinitePaginationComponent implements OnInit, PaginationComponentInterface {
|
||||
static DEFAULT_PAGINATION: PaginationModel = new PaginationModel({
|
||||
skipCount: 0,
|
||||
maxItems: 25,
|
||||
@@ -60,14 +60,13 @@ export class InfinitePaginationComponent implements OnInit, OnDestroy, Paginatio
|
||||
});
|
||||
|
||||
_target: PaginatedComponent;
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
/** Component that provides custom pagination support. */
|
||||
@Input()
|
||||
set target(target: PaginatedComponent) {
|
||||
if (target) {
|
||||
this._target = target;
|
||||
target.pagination.pipe(takeUntil(this.onDestroy$)).subscribe((pagination) => {
|
||||
target.pagination.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((pagination) => {
|
||||
this.isLoading = false;
|
||||
this.pagination = pagination;
|
||||
|
||||
@@ -103,12 +102,14 @@ export class InfinitePaginationComponent implements OnInit, OnDestroy, Paginatio
|
||||
merge: true
|
||||
};
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(private cdr: ChangeDetectorRef, private userPreferencesService: UserPreferencesService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.userPreferencesService
|
||||
.select(UserPreferenceValues.PaginationSize)
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((pageSize: number) => {
|
||||
this.pageSize = this.pageSize || pageSize;
|
||||
this.requestPaginationModel.maxItems = this.pageSize;
|
||||
@@ -137,9 +138,4 @@ export class InfinitePaginationComponent implements OnInit, OnDestroy, Paginatio
|
||||
this._target.updatePagination(this.pagination);
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
}
|
||||
|
@@ -16,29 +16,29 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
DestroyRef,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
inject,
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
ViewEncapsulation,
|
||||
OnDestroy,
|
||||
ElementRef,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Renderer2
|
||||
Renderer2,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import { PaginatedComponent } from './paginated-component.interface';
|
||||
import { PaginationComponentInterface } from './pagination-component.interface';
|
||||
import { Subject } from 'rxjs';
|
||||
import { PaginationModel } from '../models/pagination.model';
|
||||
import { UserPreferencesService, UserPreferenceValues } from '../common/services/user-preferences.service';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
export type PaginationAction = 'NEXT_PAGE' | 'PREV_PAGE' | 'CHANGE_PAGE_SIZE' | 'CHANGE_PAGE_NUMBER';
|
||||
|
||||
@@ -60,7 +60,7 @@ export const DEFAULT_PAGINATION: PaginationModel = {
|
||||
standalone: true,
|
||||
imports: [CommonModule, TranslateModule, MatButtonModule, MatIconModule, MatMenuModule]
|
||||
})
|
||||
export class PaginationComponent implements OnInit, OnDestroy, PaginationComponentInterface {
|
||||
export class PaginationComponent implements OnInit, PaginationComponentInterface {
|
||||
private _pagination: PaginationModel;
|
||||
private _isEmpty = true;
|
||||
private _hasItems = false;
|
||||
@@ -117,7 +117,7 @@ export class PaginationComponent implements OnInit, OnDestroy, PaginationCompone
|
||||
@Output()
|
||||
prevPage = new EventEmitter<PaginationModel>();
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private elementRef: ElementRef,
|
||||
@@ -130,7 +130,7 @@ export class PaginationComponent implements OnInit, OnDestroy, PaginationCompone
|
||||
ngOnInit() {
|
||||
this.userPreferencesService
|
||||
.select(UserPreferenceValues.PaginationSize)
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((maxItems) => {
|
||||
this.pagination = {
|
||||
...DEFAULT_PAGINATION,
|
||||
@@ -144,7 +144,7 @@ export class PaginationComponent implements OnInit, OnDestroy, PaginationCompone
|
||||
}
|
||||
|
||||
if (this.target) {
|
||||
this.target.pagination.pipe(takeUntil(this.onDestroy$)).subscribe((pagination) => {
|
||||
this.target.pagination.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((pagination) => {
|
||||
if (pagination.count === 0 && !this.isFirstPage) {
|
||||
this.goPrevious();
|
||||
}
|
||||
@@ -303,12 +303,6 @@ export class PaginationComponent implements OnInit, OnDestroy, PaginationCompone
|
||||
this.userPreferencesService.paginationSize = maxItems;
|
||||
this.handlePaginationEvent('CHANGE_PAGE_SIZE');
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
handlePaginationEvent(action: PaginationAction) {
|
||||
const paginationModel = { ...this.pagination };
|
||||
|
||||
|
@@ -16,11 +16,12 @@
|
||||
*/
|
||||
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { AppConfigService } from '../app-config/app-config.service';
|
||||
import { UserPreferencesService } from '../common/services/user-preferences.service';
|
||||
import { of } from 'rxjs';
|
||||
import { CoreTestingModule } from '../testing/core.testing.module';
|
||||
import { DecimalNumberPipe } from './decimal-number.pipe';
|
||||
import { Injector, runInInjectionContext } from '@angular/core';
|
||||
import { AppConfigService } from '@alfresco/adf-core';
|
||||
|
||||
describe('DecimalNumberPipe', () => {
|
||||
let pipe: DecimalNumberPipe;
|
||||
@@ -31,8 +32,11 @@ describe('DecimalNumberPipe', () => {
|
||||
imports: [CoreTestingModule]
|
||||
});
|
||||
userPreferences = TestBed.inject(UserPreferencesService);
|
||||
const injector = TestBed.inject(Injector);
|
||||
spyOn(userPreferences, 'select').and.returnValue(of(''));
|
||||
pipe = new DecimalNumberPipe(userPreferences, TestBed.inject(AppConfigService));
|
||||
runInInjectionContext(injector, () => {
|
||||
pipe = new DecimalNumberPipe(userPreferences, TestBed.inject(AppConfigService));
|
||||
});
|
||||
});
|
||||
|
||||
it('should return number localized and rounded following the default config', () => {
|
||||
|
@@ -16,19 +16,18 @@
|
||||
*/
|
||||
|
||||
import { DecimalPipe } from '@angular/common';
|
||||
import { Pipe, PipeTransform, OnDestroy } from '@angular/core';
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { AppConfigService } from '../app-config/app-config.service';
|
||||
import { UserPreferencesService, UserPreferenceValues } from '../common/services/user-preferences.service';
|
||||
import { DecimalNumberModel } from '../models/decimal-number.model';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Pipe({
|
||||
name: 'adfDecimalNumber',
|
||||
pure: false,
|
||||
standalone: true
|
||||
})
|
||||
export class DecimalNumberPipe implements PipeTransform, OnDestroy {
|
||||
export class DecimalNumberPipe implements PipeTransform {
|
||||
static DEFAULT_LOCALE = 'en-US';
|
||||
static DEFAULT_MIN_INTEGER_DIGITS = 1;
|
||||
static DEFAULT_MIN_FRACTION_DIGITS = 0;
|
||||
@@ -38,14 +37,11 @@ export class DecimalNumberPipe implements PipeTransform, OnDestroy {
|
||||
defaultMinIntegerDigits: number = DecimalNumberPipe.DEFAULT_MIN_INTEGER_DIGITS;
|
||||
defaultMinFractionDigits: number = DecimalNumberPipe.DEFAULT_MIN_FRACTION_DIGITS;
|
||||
defaultMaxFractionDigits: number = DecimalNumberPipe.DEFAULT_MAX_FRACTION_DIGITS;
|
||||
|
||||
onDestroy$: Subject<boolean> = new Subject<boolean>();
|
||||
|
||||
constructor(public userPreferenceService?: UserPreferencesService, public appConfig?: AppConfigService) {
|
||||
if (this.userPreferenceService) {
|
||||
this.userPreferenceService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.pipe(takeUntilDestroyed())
|
||||
.subscribe((locale) => {
|
||||
if (locale) {
|
||||
this.defaultLocale = locale;
|
||||
@@ -82,9 +78,4 @@ export class DecimalNumberPipe implements PipeTransform, OnDestroy {
|
||||
return decimalPipe.transform(value, actualDigitsInfo);
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
}
|
||||
|
@@ -28,7 +28,6 @@ import { takeUntil } from 'rxjs/operators';
|
||||
pure: false
|
||||
})
|
||||
export class LocalizedDatePipe implements PipeTransform, OnDestroy {
|
||||
|
||||
static DEFAULT_LOCALE = 'en-US';
|
||||
static DEFAULT_DATE_FORMAT = 'mediumDate';
|
||||
|
||||
@@ -37,14 +36,12 @@ export class LocalizedDatePipe implements PipeTransform, OnDestroy {
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(public userPreferenceService?: UserPreferencesService,
|
||||
public appConfig?: AppConfigService) {
|
||||
|
||||
constructor(public userPreferenceService?: UserPreferencesService, public appConfig?: AppConfigService) {
|
||||
if (this.userPreferenceService) {
|
||||
this.userPreferenceService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(locale => {
|
||||
.subscribe((locale) => {
|
||||
if (locale) {
|
||||
this.defaultLocale = locale;
|
||||
}
|
||||
@@ -67,5 +64,4 @@ export class LocalizedDatePipe implements PipeTransform, OnDestroy {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@ import { AppConfigService } from '../app-config/app-config.service';
|
||||
import { UserPreferencesService } from '../common/services/user-preferences.service';
|
||||
import { CoreTestingModule } from '../testing/core.testing.module';
|
||||
import { of } from 'rxjs';
|
||||
import { Injector, runInInjectionContext } from '@angular/core';
|
||||
|
||||
describe('TimeAgoPipe', () => {
|
||||
let pipe: TimeAgoPipe;
|
||||
@@ -31,8 +32,11 @@ describe('TimeAgoPipe', () => {
|
||||
imports: [CoreTestingModule]
|
||||
});
|
||||
userPreferences = TestBed.inject(UserPreferencesService);
|
||||
const injector = TestBed.inject(Injector);
|
||||
spyOn(userPreferences, 'select').and.returnValue(of(''));
|
||||
pipe = new TimeAgoPipe(userPreferences, TestBed.inject(AppConfigService));
|
||||
runInInjectionContext(injector, () => {
|
||||
pipe = new TimeAgoPipe(userPreferences, TestBed.inject(AppConfigService));
|
||||
});
|
||||
});
|
||||
|
||||
it('should return time difference for a given date', () => {
|
||||
|
@@ -15,58 +15,46 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Pipe, PipeTransform, OnDestroy } from '@angular/core';
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { AppConfigService } from '../app-config/app-config.service';
|
||||
import { UserPreferenceValues, UserPreferencesService } from '../common/services/user-preferences.service';
|
||||
import { UserPreferencesService, UserPreferenceValues } from '../common/services/user-preferences.service';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { differenceInDays, formatDistance } from 'date-fns';
|
||||
import * as Locales from 'date-fns/locale';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Pipe({
|
||||
standalone: true,
|
||||
name: 'adfTimeAgo'
|
||||
})
|
||||
export class TimeAgoPipe implements PipeTransform, OnDestroy {
|
||||
|
||||
export class TimeAgoPipe implements PipeTransform {
|
||||
static DEFAULT_LOCALE = 'en-US';
|
||||
static DEFAULT_DATE_TIME_FORMAT = 'dd/MM/yyyy HH:mm';
|
||||
|
||||
defaultLocale: string;
|
||||
defaultDateTimeFormat: string;
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(
|
||||
public userPreferenceService: UserPreferencesService,
|
||||
public appConfig: AppConfigService
|
||||
) {
|
||||
constructor(public userPreferenceService: UserPreferencesService, public appConfig: AppConfigService) {
|
||||
this.userPreferenceService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(locale => {
|
||||
.pipe(takeUntilDestroyed())
|
||||
.subscribe((locale) => {
|
||||
this.defaultLocale = locale || TimeAgoPipe.DEFAULT_LOCALE;
|
||||
});
|
||||
this.defaultDateTimeFormat = this.appConfig.get<string>('dateValues.defaultDateTimeFormat', TimeAgoPipe.DEFAULT_DATE_TIME_FORMAT);
|
||||
}
|
||||
|
||||
transform(value: Date, locale?: string) {
|
||||
if (value !== null && value !== undefined ) {
|
||||
if (value !== null && value !== undefined) {
|
||||
const actualLocale = locale || this.defaultLocale;
|
||||
const diff = differenceInDays(new Date(), new Date(value));
|
||||
if ( diff > 7) {
|
||||
if (diff > 7) {
|
||||
const datePipe: DatePipe = new DatePipe(actualLocale);
|
||||
return datePipe.transform(value, this.defaultDateTimeFormat);
|
||||
} else {
|
||||
return formatDistance(new Date(value) , new Date(), { addSuffix: true , locale: Locales[actualLocale] });
|
||||
return formatDistance(new Date(value), new Date(), { addSuffix: true, locale: Locales[actualLocale] });
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
}
|
||||
|
@@ -17,7 +17,19 @@
|
||||
|
||||
import { Direction } from '@angular/cdk/bidi';
|
||||
import { NgClass, NgIf } from '@angular/common';
|
||||
import { Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
DestroyRef,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
inject,
|
||||
Input,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
Output,
|
||||
ViewChild,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
@@ -25,11 +37,12 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { Observable, Subject, Subscription } from 'rxjs';
|
||||
import { debounceTime, filter, takeUntil } from 'rxjs/operators';
|
||||
import { debounceTime, filter } from 'rxjs/operators';
|
||||
import { UserPreferencesService } from '../common';
|
||||
import { searchAnimation } from './animations';
|
||||
import { SearchAnimationDirection, SearchAnimationState, SearchTextStateEnum } from './models/search-text-input.model';
|
||||
import { SearchTriggerDirective } from './search-trigger.directive';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-search-text-input',
|
||||
@@ -162,7 +175,6 @@ export class SearchTextInputComponent implements OnInit, OnDestroy {
|
||||
};
|
||||
|
||||
private dir = 'ltr';
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
private toggleSearch = new Subject<any>();
|
||||
private focusSubscription: Subscription;
|
||||
private valueChange = new Subject<string>();
|
||||
@@ -170,8 +182,10 @@ export class SearchTextInputComponent implements OnInit, OnDestroy {
|
||||
|
||||
toggle$ = this.toggleSearch.asObservable();
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(private userPreferencesService: UserPreferencesService) {
|
||||
this.toggleSubscription = this.toggle$.pipe(debounceTime(200), takeUntil(this.onDestroy$)).subscribe(() => {
|
||||
this.toggleSubscription = this.toggle$.pipe(debounceTime(200), takeUntilDestroyed()).subscribe(() => {
|
||||
if (this.expandable) {
|
||||
this.subscriptAnimationState = this.toggleAnimation();
|
||||
if (this.subscriptAnimationState.value === 'inactive') {
|
||||
@@ -189,7 +203,7 @@ export class SearchTextInputComponent implements OnInit, OnDestroy {
|
||||
ngOnInit() {
|
||||
this.userPreferencesService
|
||||
.select('textOrientation')
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((direction: Direction) => {
|
||||
this.dir = direction;
|
||||
this.subscriptAnimationState = this.getDefaultState(this.dir);
|
||||
@@ -246,7 +260,7 @@ export class SearchTextInputComponent implements OnInit, OnDestroy {
|
||||
filter(
|
||||
($event: any) => this.isSearchBarActive() && ($event.type === 'blur' || $event.type === 'focusout' || $event.type === 'focus')
|
||||
),
|
||||
takeUntil(this.onDestroy$)
|
||||
takeUntilDestroyed(this.destroyRef)
|
||||
);
|
||||
|
||||
this.focusSubscription = focusEvents.subscribe((event: FocusEvent) => {
|
||||
@@ -260,7 +274,7 @@ export class SearchTextInputComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
private setValueChangeHandler() {
|
||||
this.valueChange.pipe(debounceTime(this.debounceTime), takeUntil(this.onDestroy$)).subscribe((value: string) => {
|
||||
this.valueChange.pipe(debounceTime(this.debounceTime), takeUntilDestroyed(this.destroyRef)).subscribe((value: string) => {
|
||||
this.searchChange.emit(value);
|
||||
});
|
||||
}
|
||||
@@ -315,9 +329,6 @@ export class SearchTextInputComponent implements OnInit, OnDestroy {
|
||||
this.focusSubscription = null;
|
||||
this.focusListener = null;
|
||||
}
|
||||
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
canShowClearSearch(): boolean {
|
||||
|
@@ -18,12 +18,13 @@
|
||||
/* eslint-disable @angular-eslint/no-input-rename, @typescript-eslint/no-use-before-define, @angular-eslint/no-input-rename */
|
||||
|
||||
import { ENTER, ESCAPE } from '@angular/cdk/keycodes';
|
||||
import { ChangeDetectorRef, Directive, ElementRef, forwardRef, Inject, Input, NgZone, OnDestroy, Optional } from '@angular/core';
|
||||
import { ChangeDetectorRef, DestroyRef, Directive, ElementRef, forwardRef, inject, Inject, Input, NgZone, OnDestroy, Optional } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { Observable, Subject, Subscription, merge, of, fromEvent } from 'rxjs';
|
||||
import { filter, switchMap, takeUntil } from 'rxjs/operators';
|
||||
import { fromEvent, merge, Observable, of, Subject, Subscription } from 'rxjs';
|
||||
import { filter, switchMap } from 'rxjs/operators';
|
||||
import { SearchComponentInterface } from '../common/interface/search-component.interface';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
export const SEARCH_AUTOCOMPLETE_VALUE_ACCESSOR: any = {
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
@@ -50,8 +51,6 @@ export const SEARCH_AUTOCOMPLETE_VALUE_ACCESSOR: any = {
|
||||
providers: [SEARCH_AUTOCOMPLETE_VALUE_ACCESSOR]
|
||||
})
|
||||
export class SearchTriggerDirective implements ControlValueAccessor, OnDestroy {
|
||||
private onDestroy$: Subject<boolean> = new Subject<boolean>();
|
||||
|
||||
@Input('searchAutocomplete')
|
||||
searchPanel: SearchComponentInterface;
|
||||
|
||||
@@ -66,6 +65,8 @@ export class SearchTriggerDirective implements ControlValueAccessor, OnDestroy {
|
||||
|
||||
onTouched = () => {};
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private element: ElementRef,
|
||||
private ngZone: NgZone,
|
||||
@@ -74,9 +75,6 @@ export class SearchTriggerDirective implements ControlValueAccessor, OnDestroy {
|
||||
) {}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
|
||||
if (this.escapeEventStream) {
|
||||
this.escapeEventStream = null;
|
||||
}
|
||||
@@ -118,7 +116,7 @@ export class SearchTriggerDirective implements ControlValueAccessor, OnDestroy {
|
||||
const clickTarget = event.target as HTMLElement;
|
||||
return this._panelOpen && clickTarget !== this.element.nativeElement;
|
||||
}),
|
||||
takeUntil(this.onDestroy$)
|
||||
takeUntilDestroyed(this.destroyRef)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -183,7 +181,7 @@ export class SearchTriggerDirective implements ControlValueAccessor, OnDestroy {
|
||||
this.searchPanel.setVisibility();
|
||||
return this.panelClosingActions;
|
||||
}),
|
||||
takeUntil(this.onDestroy$)
|
||||
takeUntilDestroyed(this.destroyRef)
|
||||
)
|
||||
.subscribe((event) => this.setValueAndClose(event));
|
||||
}
|
||||
|
@@ -134,7 +134,6 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
|
||||
cMapPacked: true
|
||||
};
|
||||
private pdfjsWorkerDestroy$ = new Subject<boolean>();
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(private dialog: MatDialog, private renderingQueueServices: RenderingQueueServices, private appConfigService: AppConfigService) {
|
||||
// needed to preserve "this" context
|
||||
@@ -276,9 +275,7 @@ export class PdfViewerComponent implements OnChanges, OnDestroy {
|
||||
if (this.loadingTask) {
|
||||
this.pdfjsWorkerDestroy$.next(true);
|
||||
}
|
||||
this.onDestroy$.next(true);
|
||||
this.pdfjsWorkerDestroy$.complete();
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
private destroyPdJsWorker() {
|
||||
|
@@ -15,13 +15,22 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AppExtensionService, ViewerExtensionRef, ExtensionsModule } from '@alfresco/adf-extensions';
|
||||
import { AppExtensionService, ExtensionsModule, ViewerExtensionRef } from '@alfresco/adf-extensions';
|
||||
import { NgForOf, NgIf, NgSwitch, NgSwitchCase, NgSwitchDefault, NgTemplateOutlet } from '@angular/common';
|
||||
import { Component, EventEmitter, Injector, Input, OnChanges, OnDestroy, OnInit, Output, TemplateRef, ViewEncapsulation } from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Injector,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnInit,
|
||||
Output,
|
||||
TemplateRef,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { Track } from '../../models/viewer.model';
|
||||
import { ViewUtilService } from '../../services/view-util.service';
|
||||
import { ImgViewerComponent } from '../img-viewer/img-viewer.component';
|
||||
@@ -55,7 +64,7 @@ import { UnknownFormatComponent } from '../unknown-format/unknown-format.compone
|
||||
],
|
||||
providers: [ViewUtilService]
|
||||
})
|
||||
export class ViewerRenderComponent implements OnChanges, OnInit, OnDestroy {
|
||||
export class ViewerRenderComponent implements OnChanges, OnInit {
|
||||
/**
|
||||
* If you want to load an external file that does not come from ACS you
|
||||
* can use this URL to specify where to load the file from.
|
||||
@@ -169,8 +178,6 @@ export class ViewerRenderComponent implements OnChanges, OnInit, OnDestroy {
|
||||
|
||||
cacheTypeForContent = 'no-cache';
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(
|
||||
private viewUtilService: ViewUtilService,
|
||||
private extensionService: AppExtensionService,
|
||||
@@ -182,11 +189,6 @@ export class ViewerRenderComponent implements OnChanges, OnInit, OnDestroy {
|
||||
this.cacheTypeForContent = 'no-cache';
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
this.isLoading = !this.blobFile && !this.urlFile;
|
||||
|
||||
|
@@ -20,6 +20,7 @@ import { NgIf, NgTemplateOutlet } from '@angular/common';
|
||||
import {
|
||||
Component,
|
||||
ContentChild,
|
||||
DestroyRef,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
HostListener,
|
||||
@@ -38,8 +39,8 @@ import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { fromEvent, Subject } from 'rxjs';
|
||||
import { filter, first, skipWhile, takeUntil } from 'rxjs/operators';
|
||||
import { fromEvent } from 'rxjs';
|
||||
import { filter, first, skipWhile } from 'rxjs/operators';
|
||||
import { AppConfigService } from '../../app-config';
|
||||
import { ToolbarComponent, ToolbarDividerComponent, ToolbarTitleComponent } from '../../toolbar';
|
||||
import { DownloadPromptActions } from '../models/download-prompt.actions';
|
||||
@@ -55,6 +56,7 @@ import { ViewerToolbarActionsComponent } from './viewer-toolbar-actions.componen
|
||||
import { ViewerToolbarCustomActionsComponent } from './viewer-toolbar-custom-actions.component';
|
||||
import { IconComponent } from '../../icon';
|
||||
import { ThumbnailService } from '../../common';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
const DEFAULT_NON_PREVIEW_CONFIG = {
|
||||
enableDownloadPrompt: false,
|
||||
@@ -284,8 +286,6 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
|
||||
@Output()
|
||||
submitFile = new EventEmitter<Blob>();
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
private closeViewer = true;
|
||||
private keyDown$ = fromEvent<KeyboardEvent>(document, 'keydown');
|
||||
private isDialogVisible: boolean = false;
|
||||
@@ -293,6 +293,8 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
|
||||
public downloadPromptReminderTimer: number;
|
||||
public mimeTypeIconUrl: string;
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private el: ElementRef,
|
||||
public dialog: MatDialog,
|
||||
@@ -326,14 +328,14 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
|
||||
this.dialog.afterOpened
|
||||
.pipe(
|
||||
skipWhile(() => !this.overlayMode),
|
||||
takeUntil(this.onDestroy$)
|
||||
takeUntilDestroyed(this.destroyRef)
|
||||
)
|
||||
.subscribe(() => (this.closeViewer = false));
|
||||
|
||||
this.dialog.afterAllClosed
|
||||
.pipe(
|
||||
skipWhile(() => !this.overlayMode),
|
||||
takeUntil(this.onDestroy$)
|
||||
takeUntilDestroyed(this.destroyRef)
|
||||
)
|
||||
.subscribe(() => (this.closeViewer = true));
|
||||
|
||||
@@ -341,7 +343,7 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
|
||||
.pipe(
|
||||
skipWhile(() => !this.overlayMode),
|
||||
filter((e: KeyboardEvent) => e.keyCode === 27),
|
||||
takeUntil(this.onDestroy$)
|
||||
takeUntilDestroyed(this.destroyRef)
|
||||
)
|
||||
.subscribe((event: KeyboardEvent) => {
|
||||
event.preventDefault();
|
||||
@@ -429,8 +431,6 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
|
||||
|
||||
ngOnDestroy() {
|
||||
this.clearDownloadPromptTimeouts();
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
private configureAndInitDownloadPrompt() {
|
||||
|
@@ -15,16 +15,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AfterContentInit, ContentChild, Directive, Input, TemplateRef, OnDestroy } from '@angular/core';
|
||||
import { AfterContentInit, ContentChild, DestroyRef, Directive, inject, Input, TemplateRef } from '@angular/core';
|
||||
import { ViewerRenderComponent } from '../components/viewer-render/viewer-render.component';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Directive({
|
||||
selector: 'adf-viewer-extension',
|
||||
standalone: true
|
||||
})
|
||||
export class ViewerExtensionDirective implements AfterContentInit, OnDestroy {
|
||||
export class ViewerExtensionDirective implements AfterContentInit {
|
||||
@ContentChild(TemplateRef)
|
||||
template: any;
|
||||
|
||||
@@ -39,7 +38,7 @@ export class ViewerExtensionDirective implements AfterContentInit, OnDestroy {
|
||||
|
||||
templateModel: any;
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(private viewerComponent: ViewerRenderComponent) {}
|
||||
|
||||
@@ -48,16 +47,11 @@ export class ViewerExtensionDirective implements AfterContentInit, OnDestroy {
|
||||
this.viewerComponent.extensionsSupportedByTemplates.push(...this.supportedExtensions);
|
||||
this.viewerComponent.extensionTemplates.push(this.templateModel);
|
||||
|
||||
this.viewerComponent.extensionChange.pipe(takeUntil(this.onDestroy$)).subscribe((fileExtension) => {
|
||||
this.viewerComponent.extensionChange.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((fileExtension) => {
|
||||
this.templateModel.isVisible = this.isVisible(fileExtension);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current extension in the viewer is compatible with this extension checking against `supportedExtensions`
|
||||
*
|
||||
|
Reference in New Issue
Block a user