[ACS-8959] Introduce new takeUntilDestroyed operator (#4237)

This commit is contained in:
dominikiwanekhyland 2024-11-21 10:49:49 +01:00 committed by GitHub
parent dec6c41e5c
commit adda597f15
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
52 changed files with 876 additions and 916 deletions

View File

@ -23,7 +23,6 @@
*/
import { Component, ViewEncapsulation } from '@angular/core';
import { Subject } from 'rxjs';
import { AppService } from '@alfresco/aca-shared';
@Component({
@ -33,8 +32,6 @@ import { AppService } from '@alfresco/aca-shared';
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
onDestroy$: Subject<boolean> = new Subject<boolean>();
constructor(private appService: AppService) {
this.appService.init();
}

809
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -30,11 +30,11 @@
},
"private": true,
"dependencies": {
"@alfresco/adf-content-services": "7.0.0-alpha.6",
"@alfresco/adf-core": "7.0.0-alpha.6",
"@alfresco/adf-extensions": "7.0.0-alpha.6",
"@alfresco/eslint-plugin-eslint-angular": "7.0.0-alpha.6",
"@alfresco/js-api": "8.0.0-alpha.6",
"@alfresco/adf-content-services": "7.0.0-alpha.6-11937616463",
"@alfresco/adf-core": "7.0.0-alpha.6-11937616463",
"@alfresco/adf-extensions": "7.0.0-alpha.6-11937616463",
"@alfresco/eslint-plugin-eslint-angular": "7.0.0-alpha.6-11937616463",
"@alfresco/js-api": "8.0.0-alpha.6-11937616463",
"@angular/animations": "16.2.9",
"@angular/cdk": "16.2.9",
"@angular/common": "16.2.9",
@ -62,7 +62,7 @@
"zone.js": "0.13.3"
},
"devDependencies": {
"@alfresco/adf-cli": "7.0.0-alpha.6",
"@alfresco/adf-cli": "7.0.0-alpha.6-11937616463",
"@angular-devkit/build-angular": "16.2.9",
"@angular-devkit/core": "16.2.9",
"@angular-devkit/schematics": "16.2.9",

View File

@ -22,17 +22,17 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { ChangeDetectionStrategy, Component, DestroyRef, inject, OnInit, ViewEncapsulation } from '@angular/core';
import { CommonModule, Location } from '@angular/common';
import { FolderRulesService } from '../services/folder-rules.service';
import { Observable, Subject, Subscription } from 'rxjs';
import { Observable } from 'rxjs';
import { Rule } from '../model/rule.model';
import { ActivatedRoute, RouterModule } from '@angular/router';
import { NodeInfo } from '@alfresco/aca-shared/store';
import { delay, takeUntil } from 'rxjs/operators';
import { delay } from 'rxjs/operators';
import { EditRuleDialogUiComponent } from '../rule-details/edit-rule-dialog.ui-component';
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { NotificationService, TemplateModule, ToolbarModule, ConfirmDialogComponent } from '@alfresco/adf-core';
import { ConfirmDialogComponent, NotificationService, TemplateModule, ToolbarModule } from '@alfresco/adf-core';
import { ActionDefinitionTransformed } from '../model/rule-action.model';
import { ActionsService } from '../services/actions.service';
import { FolderRuleSetsService } from '../services/folder-rule-sets.service';
@ -48,6 +48,7 @@ import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatDividerModule } from '@angular/material/divider';
import { RuleListUiComponent } from '../rule-list/rule-list/rule-list.ui-component';
import { RuleDetailsUiComponent } from '../rule-details/rule-details.ui-component';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -75,7 +76,7 @@ import { RuleDetailsUiComponent } from '../rule-details/rule-details.ui-componen
changeDetection: ChangeDetectionStrategy.Default,
host: { class: 'aca-manage-rules' }
})
export class ManageRulesSmartComponent implements OnInit, OnDestroy {
export class ManageRulesSmartComponent implements OnInit {
nodeId = '';
isInheritanceEnabled = true;
isInheritanceToggleDisabled = false;
@ -96,8 +97,7 @@ export class ManageRulesSmartComponent implements OnInit, OnDestroy {
isMainRuleSetNotEmpty = false;
isInheritedRuleSetsNotEmpty = false;
private destroyed$ = new Subject<void>();
private _actionDefinitionsSub: Subscription;
private readonly destroyRef = inject(DestroyRef);
constructor(
private location: Location,
@ -122,7 +122,7 @@ export class ManageRulesSmartComponent implements OnInit, OnDestroy {
this.actionDefinitions$ = this.actionsService.actionDefinitionsListing$;
this.parameterConstraints$ = this.actionsService.parameterConstraints$;
this.folderRulesService.deletedRuleId$.pipe(takeUntil(this.destroyed$)).subscribe((deletedRuleId) => this.onRuleDelete(deletedRuleId));
this.folderRulesService.deletedRuleId$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((deletedRuleId) => this.onRuleDelete(deletedRuleId));
this.actionsService.loadActionDefinitions();
@ -137,30 +137,24 @@ export class ManageRulesSmartComponent implements OnInit, OnDestroy {
}
});
this._actionDefinitionsSub = this.actionDefinitions$.subscribe((actionDefinitions: ActionDefinitionTransformed[]) =>
this.actionsService.loadActionParameterConstraints(actionDefinitions)
);
this.actionDefinitions$
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((actionDefinitions: ActionDefinitionTransformed[]) => this.actionsService.loadActionParameterConstraints(actionDefinitions));
this.mainRuleSet$.pipe(takeUntil(this.destroyed$)).subscribe((ruleSet) => {
this.mainRuleSet$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((ruleSet) => {
this.canEditMainRule = this.canEditRule(ruleSet);
this.isMainRuleSetNotEmpty = !!ruleSet;
});
this.inheritedRuleSets$.pipe(takeUntil(this.destroyed$)).subscribe((inheritedRuleSet) => {
this.inheritedRuleSets$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((inheritedRuleSet) => {
this.isInheritedRuleSetsNotEmpty = inheritedRuleSet.some((ruleSet) => ruleSet.rules.some((rule: Rule) => rule.isEnabled));
});
this.selectedRuleSet$.pipe(takeUntil(this.destroyed$)).subscribe((ruleSet) => {
this.selectedRuleSet$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((ruleSet) => {
this.canEditSelectedRule = this.canEditRule(ruleSet);
});
}
ngOnDestroy() {
this.destroyed$.next();
this.destroyed$.complete();
this._actionDefinitionsSub.unsubscribe();
}
goBack(): void {
this.location.back();
}

View File

@ -22,7 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, forwardRef, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { Component, DestroyRef, forwardRef, inject, Input, OnChanges, OnInit, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { ControlValueAccessor, FormControl, FormGroup, NG_VALUE_ACCESSOR, ReactiveFormsModule, Validators } from '@angular/forms';
import { ActionDefinitionTransformed, RuleAction } from '../../model/rule-action.model';
import {
@ -37,23 +37,24 @@ import {
} from '@alfresco/adf-core';
import { ActionParameterDefinition, Category, Node, SecurityMark } from '@alfresco/js-api';
import { from, of, Subject } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
import { map } from 'rxjs/operators';
import { ActionParameterConstraint, ConstraintValue } from '../../model/action-parameter-constraint.model';
import {
CategorySelectorDialogComponent,
CategorySelectorDialogOptions,
CategoryService,
ContentNodeSelectorComponent,
ContentNodeSelectorComponentData,
NodeAction,
TagService,
CategorySelectorDialogComponent,
CategorySelectorDialogOptions,
SecurityControlsService
SecurityControlsService,
TagService
} from '@alfresco/adf-content-services';
import { MatDialog } from '@angular/material/dialog';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { CommonModule } from '@angular/common';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -72,7 +73,7 @@ import { MatSelectModule } from '@angular/material/select';
CardViewUpdateService
]
})
export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnChanges, OnDestroy {
export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnChanges {
@Input()
nodeId = '';
@ -107,7 +108,6 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
cardViewItems: CardViewItem[] = [];
parameters: { [key: string]: unknown } = {};
private onDestroy$ = new Subject<void>();
get selectedActionDefinitionId(): string {
return this.form.get('actionDefinitionId').value;
@ -120,6 +120,8 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
onChange: (action: RuleAction) => void = () => undefined;
onTouch: () => void = () => undefined;
private readonly destroyRef = inject(DestroyRef);
constructor(
private cardViewUpdateService: CardViewUpdateService,
private dialog: MatDialog,
@ -156,7 +158,7 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
firstActionDefinition.title.localeCompare(secondActionDefinition.title)
);
this.form.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
this.form.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
this.setDefaultParameters();
this.setCardViewProperties();
this.onChange({
@ -166,7 +168,7 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
this.onTouch();
});
this.cardViewUpdateService.itemUpdated$.pipe(takeUntil(this.onDestroy$)).subscribe((updateNotification: UpdateNotification) => {
this.cardViewUpdateService.itemUpdated$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((updateNotification: UpdateNotification) => {
const isSecurityGroupUpdated = updateNotification.target.key === 'securityGroupId';
if (isSecurityGroupUpdated) {
this.parameters.securityMarkId = null;
@ -202,11 +204,6 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
}
}
ngOnDestroy() {
this.onDestroy$.next();
this.onDestroy$.complete();
}
setCardViewProperties(securityMarkOptions?: CardViewSelectItemOption<string>[]) {
const disabledTags = !this.tagService.areTagsEnabled();
const disabledCategories = !this.categoryService.areCategoriesEnabled();
@ -338,7 +335,7 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh
width: '630px'
});
data.select.pipe(takeUntil(this.onDestroy$)).subscribe((selections: Category[]) => {
data.select.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((selections: Category[]) => {
if (selections[0].id) {
this.writeValue({
actionDefinitionId: this.selectedActionDefinitionId,

View File

@ -22,7 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, forwardRef, inject, Input, OnDestroy, OnInit, ViewEncapsulation, OnChanges, SimpleChanges } from '@angular/core';
import { Component, DestroyRef, forwardRef, inject, Input, OnChanges, OnInit, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { AbstractControl, ControlValueAccessor, FormControl, FormGroup, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
import { RuleSimpleCondition } from '../../model/rule-simple-condition.model';
import { comparatorHiddenForConditionFieldType, RuleConditionField, ruleConditionFields } from './rule-condition-fields';
@ -34,12 +34,13 @@ import { MatSelectModule } from '@angular/material/select';
import { MatInputModule } from '@angular/material/input';
import { CategoryService, TagService } from '@alfresco/adf-content-services';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { debounceTime, distinctUntilChanged, first, takeUntil } from 'rxjs/operators';
import { Subject, Subscription } from 'rxjs';
import { debounceTime, distinctUntilChanged, first } from 'rxjs/operators';
import { Subscription } from 'rxjs';
import { MatOptionModule } from '@angular/material/core';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { CategoryEntry } from '@alfresco/js-api';
import { AlfrescoMimeType, AppSettingsService } from '@alfresco/aca-shared';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
interface AutoCompleteOption {
displayLabel: string;
@ -75,7 +76,7 @@ const AUTOCOMPLETE_OPTIONS_DEBOUNCE_TIME = 500;
}
]
})
export class RuleSimpleConditionUiComponent implements OnInit, ControlValueAccessor, OnChanges, OnDestroy {
export class RuleSimpleConditionUiComponent implements OnInit, ControlValueAccessor, OnChanges {
private appSettings = inject(AppSettingsService);
private categoryService = inject(CategoryService);
private tagService = inject(TagService);
@ -92,9 +93,9 @@ export class RuleSimpleConditionUiComponent implements OnInit, ControlValueAcces
@Input() readOnly = false;
private onDestroy$ = new Subject<void>();
private autoCompleteOptionsSubscription: Subscription;
private readonly destroyRef = inject(DestroyRef);
private readonly disabledTags = !this.tagService.areTagsEnabled();
private readonly disabledCategories = !this.categoryService.areCategoriesEnabled();
@ -175,25 +176,20 @@ export class RuleSimpleConditionUiComponent implements OnInit, ControlValueAcces
}
}
ngOnDestroy() {
this.onDestroy$.next();
this.onDestroy$.complete();
}
ngOnInit() {
this.form.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe((value: RuleSimpleCondition) => {
this.form.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((value: RuleSimpleCondition) => {
this.onChange(value);
this.onTouch();
});
this.form
.get('field')
.valueChanges.pipe(distinctUntilChanged(), takeUntil(this.onDestroy$))
.valueChanges.pipe(distinctUntilChanged(), takeUntilDestroyed(this.destroyRef))
.subscribe((field: string) => {
if (field === 'category') {
this.autoCompleteOptionsSubscription = this.form
.get('parameter')
.valueChanges.pipe(distinctUntilChanged(), debounceTime(AUTOCOMPLETE_OPTIONS_DEBOUNCE_TIME), takeUntil(this.onDestroy$))
.valueChanges.pipe(distinctUntilChanged(), debounceTime(AUTOCOMPLETE_OPTIONS_DEBOUNCE_TIME), takeUntilDestroyed(this.destroyRef))
.subscribe((categoryName) => {
this.getCategories(categoryName);
});

View File

@ -22,10 +22,9 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { UntypedFormGroup, UntypedFormControl, Validators, ReactiveFormsModule } from '@angular/forms';
import { Subject } from 'rxjs';
import { distinctUntilChanged, map, takeUntil } from 'rxjs/operators';
import { Component, DestroyRef, EventEmitter, inject, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { ReactiveFormsModule, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { Rule, RuleForForm } from '../model/rule.model';
import { ruleCompositeConditionValidator } from './validators/rule-composite-condition.validator';
import { FolderRulesService } from '../services/folder-rules.service';
@ -41,6 +40,7 @@ import { RuleCompositeConditionUiComponent } from './conditions/rule-composite-c
import { RuleActionListUiComponent } from './actions/rule-action-list.ui-component';
import { RuleOptionsUiComponent } from './options/rule-options.ui-component';
import { CategoryService } from '@alfresco/adf-content-services';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -61,7 +61,7 @@ import { CategoryService } from '@alfresco/adf-content-services';
encapsulation: ViewEncapsulation.None,
host: { class: 'aca-rule-details' }
})
export class RuleDetailsUiComponent implements OnInit, OnDestroy {
export class RuleDetailsUiComponent implements OnInit {
@Input()
readOnly: boolean;
@ -115,7 +115,6 @@ export class RuleDetailsUiComponent implements OnInit, OnDestroy {
@Output()
formValueChanged = new EventEmitter<Partial<Rule>>();
private onDestroy$ = new Subject<void>();
form: UntypedFormGroup;
errorScriptConstraint: ActionParameterConstraint;
@ -137,6 +136,8 @@ export class RuleDetailsUiComponent implements OnInit, OnDestroy {
return !this.readOnly || this.value.isAsynchronous || this.value.isInheritable;
}
private readonly destroyRef = inject(DestroyRef);
constructor(private categoryService: CategoryService) {}
ngOnInit() {
@ -169,14 +170,14 @@ export class RuleDetailsUiComponent implements OnInit, OnDestroy {
.pipe(
map(() => this.form.valid),
distinctUntilChanged(),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
)
.subscribe((value: boolean) => {
this.formValidationChanged.emit(value);
});
this.formValidationChanged.emit(this.form.valid);
this.form.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
this.form.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
this.formValueChanged.emit(this.value);
});
@ -194,9 +195,4 @@ export class RuleDetailsUiComponent implements OnInit, OnDestroy {
(parameterConstraint: ActionParameterConstraint) => parameterConstraint.name === 'script-ref'
);
}
ngOnDestroy() {
this.onDestroy$.next();
this.onDestroy$.complete();
}
}

View File

@ -22,7 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { Component, DestroyRef, EventEmitter, inject, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { RuleSet } from '../../model/rule-set.model';
import { Rule } from '../../model/rule.model';
import { RuleGroupingItem } from '../../model/rule-grouping-item.model';
@ -35,7 +35,8 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { RuleListGroupingUiComponent } from '../rule-list-grouping/rule-list-grouping.ui-component';
import { RouterModule } from '@angular/router';
import { MatButtonModule } from '@angular/material/button';
import { Observable, Subscription } from 'rxjs';
import { Observable } from 'rxjs';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -55,7 +56,7 @@ import { Observable, Subscription } from 'rxjs';
encapsulation: ViewEncapsulation.None,
host: { class: 'aca-rule-list' }
})
export class RuleListUiComponent implements OnInit, OnDestroy {
export class RuleListUiComponent implements OnInit {
@Input()
mainRuleSet$: Observable<RuleSet>;
@Input()
@ -90,10 +91,10 @@ export class RuleListUiComponent implements OnInit, OnDestroy {
isMainRuleSetOwned = false;
isMainRuleSetLinked = false;
private _mainRuleSetSub: Subscription;
private readonly destroyRef = inject(DestroyRef);
ngOnInit() {
this._mainRuleSetSub = this.mainRuleSet$.subscribe((ruleSet: RuleSet) => {
this.mainRuleSet$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((ruleSet: RuleSet) => {
if (ruleSet) {
this.mainRuleSet = ruleSet;
this.isMainRuleSetOwned = FolderRuleSetsService.isOwnedRuleSet(ruleSet, this.folderId);
@ -114,10 +115,6 @@ export class RuleListUiComponent implements OnInit, OnDestroy {
}
}
ngOnDestroy() {
this._mainRuleSetSub.unsubscribe();
}
getRuleSetGroupingItems(ruleSet: RuleSet, filterOutDisabledRules: boolean): RuleGroupingItem[] {
const items: RuleGroupingItem[] = ruleSet.rules
.filter((rule: Rule) => rule.isEnabled || !filterOutDisabledRules)

View File

@ -22,13 +22,13 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, Inject, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, DestroyRef, inject, Inject, OnInit, ViewEncapsulation } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { FolderRuleSetsService } from '../services/folder-rule-sets.service';
import { Node } from '@alfresco/js-api';
import { RuleSet } from '../model/rule-set.model';
import { BehaviorSubject, combineLatest, from, of, Subject } from 'rxjs';
import { finalize, map, switchMap, takeUntil } from 'rxjs/operators';
import { BehaviorSubject, combineLatest, from, of } from 'rxjs';
import { finalize, map, switchMap } from 'rxjs/operators';
import { NotificationService, TemplateModule } from '@alfresco/adf-core';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
@ -37,6 +37,7 @@ import { MatIconModule } from '@angular/material/icon';
import { ContentNodeSelectorModule } from '@alfresco/adf-content-services';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { RuleListItemUiComponent } from '../rule-list/rule-list-item/rule-list-item.ui-component';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
export interface RuleSetPickerOptions {
nodeId: string;
@ -64,7 +65,7 @@ export interface RuleSetPickerOptions {
host: { class: 'aca-rule-set-picker' },
providers: [FolderRuleSetsService]
})
export class RuleSetPickerSmartComponent implements OnInit, OnDestroy {
export class RuleSetPickerSmartComponent implements OnInit {
nodeId = '-root-';
defaultNodeId = '-root-';
isBusy = false;
@ -79,7 +80,7 @@ export class RuleSetPickerSmartComponent implements OnInit, OnDestroy {
map(([rulesLoading, folderLoading]) => rulesLoading || folderLoading)
);
onDestroy$ = new Subject<void>();
private readonly destroyRef = inject(DestroyRef);
constructor(
@Inject(MAT_DIALOG_DATA) public data: RuleSetPickerOptions,
@ -93,16 +94,11 @@ export class RuleSetPickerSmartComponent implements OnInit, OnDestroy {
}
ngOnInit(): void {
this.mainRuleSet$.pipe(takeUntil(this.onDestroy$)).subscribe((mainRuleSet) => {
this.mainRuleSet$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((mainRuleSet) => {
this.hasOwnedRules = mainRuleSet?.rules.length > 0 && FolderRuleSetsService.isOwnedRuleSet(mainRuleSet, this.selectedNodeId);
});
}
ngOnDestroy(): void {
this.onDestroy$.next();
this.onDestroy$.complete();
}
onNodeSelect(nodes: Node[]) {
if (nodes?.length && nodes[0].isFolder && nodes[0].id !== this.selectedNodeId) {
this.selectedNodeId = nodes[0].id;

View File

@ -25,15 +25,16 @@
import { ContentActionRef } from '@alfresco/adf-extensions';
import { AppStore, getSearchItemsTotalCount } from '@alfresco/aca-shared/store';
import { CommonModule } from '@angular/common';
import { Component, inject, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, DestroyRef, inject, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { MatSelectModule } from '@angular/material/select';
import { Store } from '@ngrx/store';
import { TranslateModule } from '@ngx-translate/core';
import { combineLatest, Observable, Subject } from 'rxjs';
import { combineLatest, Observable } from 'rxjs';
import { IconComponent, TranslationService } from '@alfresco/adf-core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { switchMap, takeUntil } from 'rxjs/operators';
import { switchMap } from 'rxjs/operators';
import { AppExtensionService } from '@alfresco/aca-shared';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -43,7 +44,7 @@ import { AppExtensionService } from '@alfresco/aca-shared';
imports: [CommonModule, TranslateModule, MatSelectModule, IconComponent, ReactiveFormsModule],
encapsulation: ViewEncapsulation.None
})
export class BulkActionsDropdownComponent implements OnInit, OnDestroy {
export class BulkActionsDropdownComponent implements OnInit {
@Input() items: ContentActionRef[];
placeholder: string;
@ -53,9 +54,9 @@ export class BulkActionsDropdownComponent implements OnInit, OnDestroy {
private readonly store = inject<Store<AppStore>>(Store);
private readonly translationService = inject(TranslationService);
private readonly extensions = inject(AppExtensionService);
private readonly onDestroy$ = new Subject();
private readonly destroyRef = inject(DestroyRef);
private readonly totalItems$: Observable<number> = this.store.select(getSearchItemsTotalCount);
ngOnInit() {
this.totalItems$
.pipe(
@ -76,23 +77,18 @@ export class BulkActionsDropdownComponent implements OnInit, OnDestroy {
]);
}
}),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
)
.subscribe(([placeholder, title]) => {
this.tooltip = title;
this.placeholder = placeholder;
});
this.extensions.bulkActionExecuted$.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
this.extensions.bulkActionExecuted$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
this.bulkSelectControl.setValue(null);
});
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
runAction(actionOption: ContentActionRef) {
this.extensions.runActionById(actionOption.actions.click, {
focusedElementOnCloseSelector: '.adf-context-menu-source'

View File

@ -24,6 +24,7 @@
import { ToggleSharedComponent } from './toggle-shared.component';
import { of } from 'rxjs';
import { TestBed } from '@angular/core/testing';
describe('ToggleSharedComponent', () => {
let component;
@ -41,7 +42,9 @@ describe('ToggleSharedComponent', () => {
}
};
component = new ToggleSharedComponent(storeMock);
TestBed.runInInjectionContext(() => {
component = new ToggleSharedComponent(storeMock);
});
});
it('should get Store selection entry on initialization', (done) => {

View File

@ -22,17 +22,17 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { Component, DestroyRef, inject, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { Observable } from 'rxjs';
import { Store } from '@ngrx/store';
import { SelectionState } from '@alfresco/adf-extensions';
import { AppStore, ShareNodeAction, getAppSelection } from '@alfresco/aca-shared/store';
import { AppStore, getAppSelection, ShareNodeAction } from '@alfresco/aca-shared/store';
import { CommonModule } from '@angular/common';
import { MatMenuModule } from '@angular/material/menu';
import { MatIconModule } from '@angular/material/icon';
import { TranslateModule } from '@ngx-translate/core';
import { MatButtonModule } from '@angular/material/button';
import { takeUntil } from 'rxjs/operators';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -41,7 +41,7 @@ import { takeUntil } from 'rxjs/operators';
templateUrl: './toggle-shared.component.html',
encapsulation: ViewEncapsulation.None
})
export class ToggleSharedComponent implements OnInit, OnDestroy {
export class ToggleSharedComponent implements OnInit {
@Input()
data: {
iconButton?: string;
@ -52,13 +52,13 @@ export class ToggleSharedComponent implements OnInit, OnDestroy {
selectionLabel = '';
isShared = false;
onDestroy$ = new Subject<void>();
private readonly destroyRef = inject(DestroyRef);
constructor(private store: Store<AppStore>) {}
ngOnInit() {
this.selection$ = this.store.select(getAppSelection);
this.selection$.pipe(takeUntil(this.onDestroy$)).subscribe((selectionState) => {
this.selection$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((selectionState) => {
this.selectionState = selectionState;
this.isShared =
@ -69,10 +69,6 @@ export class ToggleSharedComponent implements OnInit, OnDestroy {
});
}
ngOnDestroy(): void {
this.onDestroy$.next();
this.onDestroy$.complete();
}
editSharedNode(selection: SelectionState, focusedElementOnCloseSelector: string) {
this.store.dispatch(
new ShareNodeAction(selection.first, {

View File

@ -22,31 +22,28 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Directive, Output, EventEmitter, OnInit, OnDestroy } from '@angular/core';
import { fromEvent, Subscription } from 'rxjs';
import { DestroyRef, Directive, EventEmitter, inject, OnInit, Output } from '@angular/core';
import { fromEvent } from 'rxjs';
import { filter } from 'rxjs/operators';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Directive({
standalone: true,
selector: '[acaContextMenuOutsideEvent]'
})
export class OutsideEventDirective implements OnInit, OnDestroy {
private subscriptions: Subscription[] = [];
export class OutsideEventDirective implements OnInit {
@Output()
clickOutside: EventEmitter<void> = new EventEmitter();
ngOnInit() {
this.subscriptions = this.subscriptions.concat([
fromEvent(document.body, 'click')
.pipe(filter((event) => !this.findAncestor(event.target as Element)))
.subscribe(() => this.clickOutside.next())
]);
}
private readonly destroyRef = inject(DestroyRef);
ngOnDestroy() {
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
this.subscriptions = [];
ngOnInit() {
fromEvent(document.body, 'click')
.pipe(
filter((event) => !this.findAncestor(event.target as Element)),
takeUntilDestroyed(this.destroyRef)
)
.subscribe(() => this.clickOutside.next());
}
private findAncestor(el: Element): boolean {

View File

@ -22,7 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, ViewEncapsulation, OnInit, AfterViewInit, Inject, inject, DestroyRef } from '@angular/core';
import { AfterViewInit, Component, DestroyRef, inject, Inject, OnInit, ViewEncapsulation } from '@angular/core';
import { MatMenuModule } from '@angular/material/menu';
import { DynamicExtensionComponent } from '@alfresco/adf-extensions';
import { ContextMenuOverlayRef } from './context-menu-overlay';

View File

@ -67,12 +67,13 @@ import { FileSizePipe, InfoDrawerButtonsDirective } from '@alfresco/adf-core';
export class DetailsComponent extends PageComponent implements OnInit, OnDestroy {
nodeId: string;
isLoading: boolean;
onDestroy$ = new Subject<void>();
activeTab = 1;
aspectActions: Array<ContentActionRef> = [];
nodeIcon: string;
canManagePermissions = true;
private readonly onDestroy$: Subject<void> = new Subject<void>();
constructor(private route: ActivatedRoute, private contentApi: ContentApiService, private contentService: ContentService) {
super();
}
@ -145,9 +146,10 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy
}
ngOnDestroy(): void {
this.store.dispatch(new SetSelectedNodesAction([]));
this.onDestroy$.next();
this.onDestroy$.complete();
this.store.dispatch(new SetSelectedNodesAction([]));
super.ngOnDestroy();
}
private isSmartFolder(): boolean {

View File

@ -27,10 +27,9 @@ import { IconComponent } from '@alfresco/adf-core';
import { DynamicExtensionComponent } from '@alfresco/adf-extensions';
import { NodeEntry } from '@alfresco/js-api';
import { CommonModule } from '@angular/common';
import { Component, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, DestroyRef, inject, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { TranslateModule } from '@ngx-translate/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'aca-datatable-cell-badges',
@ -41,29 +40,24 @@ import { takeUntil } from 'rxjs/operators';
imports: [CommonModule, TranslateModule, DynamicExtensionComponent, IconComponent],
standalone: true
})
export class DatatableCellBadgesComponent implements OnInit, OnDestroy {
export class DatatableCellBadgesComponent implements OnInit {
@Input() node: NodeEntry;
badges: Badge[];
private onDestroy$ = new Subject<boolean>();
private readonly destroyRef = inject(DestroyRef);
constructor(private appExtensionService: AppExtensionService) {}
ngOnInit() {
this.appExtensionService
.getBadges(this.node)
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((badges) => {
this.badges = badges;
});
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
onBadgeClick(badge: Badge) {
if (badge.actions?.click) {
this.appExtensionService.runActionById(badge.actions?.click, this.node);

View File

@ -23,17 +23,17 @@
*/
import { NameColumnComponent, NodeNameTooltipPipe, NodesApiService } from '@alfresco/adf-content-services';
import { ChangeDetectorRef, Component, ElementRef, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { ChangeDetectorRef, Component, DestroyRef, ElementRef, inject, OnInit, ViewEncapsulation } from '@angular/core';
import { Actions, ofType } from '@ngrx/effects';
import { Subject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';
import { filter } from 'rxjs/operators';
import { NodeActionTypes } from '@alfresco/aca-shared/store';
import { LockedByComponent, isLocked } from '@alfresco/aca-shared';
import { isLocked, LockedByComponent } from '@alfresco/aca-shared';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { IconComponent } from '@alfresco/adf-core';
import { DynamicExtensionComponent } from '@alfresco/adf-extensions';
import { DatatableCellBadgesComponent } from '../datatable-cell-badges/datatable-cell-badges.component';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -54,12 +54,12 @@ import { DatatableCellBadgesComponent } from '../datatable-cell-badges/datatable
class: 'adf-datatable-content-cell adf-datatable-link adf-name-column aca-custom-name-column'
}
})
export class CustomNameColumnComponent extends NameColumnComponent implements OnInit, OnDestroy {
private onDestroy$$ = new Subject<boolean>();
export class CustomNameColumnComponent extends NameColumnComponent implements OnInit {
isFile: boolean;
isFileWriteLocked: boolean;
private readonly destroy = inject(DestroyRef);
constructor(element: ElementRef, private cd: ChangeDetectorRef, private actions$: Actions, private nodesService: NodesApiService) {
super(element, nodesService);
}
@ -69,7 +69,7 @@ export class CustomNameColumnComponent extends NameColumnComponent implements On
this.isFile = this.node?.entry && !this.node.entry.isFolder;
this.isFileWriteLocked = isLocked(this.node);
this.nodesService.nodeUpdated.pipe(takeUntil(this.onDestroy$$)).subscribe((node: any) => {
this.nodesService.nodeUpdated.pipe(takeUntilDestroyed(this.destroy)).subscribe((node: any) => {
const row = this.context.row;
if (row) {
const { entry } = row.node;
@ -91,7 +91,7 @@ export class CustomNameColumnComponent extends NameColumnComponent implements On
.pipe(
ofType<any>(NodeActionTypes.EditOffline),
filter((val) => this.node.entry.id === val.payload.entry.id),
takeUntil(this.onDestroy$$)
takeUntilDestroyed(this.destroy)
)
.subscribe(() => {
this.isFileWriteLocked = isLocked(this.node);
@ -103,9 +103,4 @@ export class CustomNameColumnComponent extends NameColumnComponent implements On
event.stopPropagation();
this.onClick();
}
ngOnDestroy() {
this.onDestroy$$.next(true);
this.onDestroy$$.complete();
}
}

View File

@ -31,7 +31,7 @@ import {
} from '@alfresco/adf-core';
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { NodeEntry, Node, PathElement } from '@alfresco/js-api';
import { Node, NodeEntry, PathElement } from '@alfresco/js-api';
import { NodeActionsService } from '../../services/node-actions.service';
import {
ContentApiService,
@ -43,8 +43,8 @@ import {
PaginationDirective,
ToolbarComponent
} from '@alfresco/aca-shared';
import { SetCurrentFolderAction, isAdmin, UploadFileVersionAction, showLoaderSelector } from '@alfresco/aca-shared/store';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { isAdmin, SetCurrentFolderAction, showLoaderSelector, UploadFileVersionAction } from '@alfresco/aca-shared/store';
import { debounceTime } from 'rxjs/operators';
import {
BreadcrumbComponent,
DocumentListComponent,
@ -59,6 +59,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { DocumentListDirective } from '../../directives/document-list.directive';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { SearchAiInputContainerComponent } from '../knowledge-retrieval/search-ai/search-ai-input-container/search-ai-input-container.component';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -109,15 +110,15 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
this.title = data.title;
this.route.queryParamMap.pipe(takeUntil(this.onDestroy$)).subscribe((queryMap: Params) => {
this.route.queryParamMap.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((queryMap: Params) => {
this.queryParams = queryMap.params;
});
this.route.params.pipe(takeUntil(this.onDestroy$)).subscribe(({ folderId }: Params) => {
this.route.params.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(({ folderId }: Params) => {
const nodeId = folderId || data.defaultNodeId;
this.contentApi
.getNode(nodeId)
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(
(node) => {
this.isValidPath = true;
@ -142,12 +143,12 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
this.store
.select(isAdmin)
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((value) => {
this.isAdmin = value;
});
this.extensions.filesDocumentListPreset$.pipe(takeUntil(this.onDestroy$)).subscribe((preset) => {
this.extensions.filesDocumentListPreset$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((preset) => {
this.columns = preset;
});

View File

@ -22,32 +22,32 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, Input, OnChanges, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, DestroyRef, inject, Input, OnChanges, OnInit, ViewEncapsulation } from '@angular/core';
import {
UntypedFormGroup,
UntypedFormControl,
Validators,
FormGroupDirective,
NgForm,
FormsModule,
ReactiveFormsModule,
FormControl,
ValidationErrors
FormGroupDirective,
FormsModule,
NgForm,
ReactiveFormsModule,
UntypedFormControl,
UntypedFormGroup,
ValidationErrors,
Validators
} from '@angular/forms';
import { QueriesApi, SiteEntry, SitePaging } from '@alfresco/js-api';
import { Store } from '@ngrx/store';
import {
AppStore,
isAdmin,
SnackbarAction,
SnackbarActionTypes,
SnackbarErrorAction,
SnackbarInfoAction,
UpdateLibraryAction,
isAdmin
UpdateLibraryAction
} from '@alfresco/aca-shared/store';
import { debounceTime, filter, mergeMap, takeUntil } from 'rxjs/operators';
import { debounceTime, filter, mergeMap } from 'rxjs/operators';
import { AlfrescoApiService } from '@alfresco/adf-content-services';
import { Observable, from, Subject } from 'rxjs';
import { from, Observable } from 'rxjs';
import { ErrorStateMatcher, MatOptionModule } from '@angular/material/core';
import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card';
@ -58,6 +58,7 @@ import { MatInputModule } from '@angular/material/input';
import { A11yModule } from '@angular/cdk/a11y';
import { MatButtonModule } from '@angular/material/button';
import { Actions, ofType } from '@ngrx/effects';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
export class InstantErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean {
@ -86,7 +87,7 @@ export class InstantErrorStateMatcher implements ErrorStateMatcher {
styleUrls: ['./library-metadata-form.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class LibraryMetadataFormComponent implements OnInit, OnChanges, OnDestroy {
export class LibraryMetadataFormComponent implements OnInit, OnChanges {
private _queriesApi: QueriesApi;
private _titleErrorTranslationKey: string;
@ -121,7 +122,7 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges, OnDestro
canUpdateLibrary = false;
isAdmin = false;
onDestroy$: Subject<boolean> = new Subject<boolean>();
private readonly destroyRef = inject(DestroyRef);
constructor(private alfrescoApiService: AlfrescoApiService, protected store: Store<AppStore>, private actions$: Actions) {}
@ -148,7 +149,7 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges, OnDestro
this.toggleEdit();
this.updateForm(this.node);
this.form.controls.title.statusChanges
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(
() =>
(this._titleErrorTranslationKey = this.form.controls.title.errors?.empty
@ -159,7 +160,7 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges, OnDestro
.pipe(
debounceTime(300),
mergeMap((title) => this.findLibraryByTitle(title)),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
)
.subscribe((result) => {
const { entries } = result.list;
@ -176,7 +177,7 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges, OnDestro
});
this.store
.select(isAdmin)
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((value) => {
this.isAdmin = value;
});
@ -187,11 +188,6 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges, OnDestro
this.handleUpdatingEvent<SnackbarErrorAction>(SnackbarActionTypes.Error, 'LIBRARY.ERRORS.LIBRARY_UPDATE_ERROR', () => this.form.markAsDirty());
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
ngOnChanges() {
this.updateForm(this.node);
this.canUpdateLibrary = this.node?.entry?.role === 'SiteManager' || this.isAdmin;
@ -236,7 +232,7 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges, OnDestro
.pipe(
ofType<T>(actionType),
filter((action) => action.payload === payload),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
)
.subscribe(handle);
}

View File

@ -22,23 +22,24 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, Input, ViewEncapsulation, OnInit, OnDestroy } from '@angular/core';
import { Component, DestroyRef, inject, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { Node } from '@alfresco/js-api';
import { NodePermissionService, isLocked, AppExtensionService } from '@alfresco/aca-shared';
import { AppStore, EditOfflineAction, NodeActionTypes, infoDrawerMetadataAspect } from '@alfresco/aca-shared/store';
import { AppExtensionService, isLocked, NodePermissionService } from '@alfresco/aca-shared';
import { AppStore, EditOfflineAction, infoDrawerMetadataAspect, NodeActionTypes } from '@alfresco/aca-shared/store';
import { AppConfigService, NotificationService } from '@alfresco/adf-core';
import { Observable, Subject } from 'rxjs';
import { Observable } from 'rxjs';
import {
ContentMetadataService,
ContentMetadataCustomPanel,
TagService,
CategoryService,
ContentMetadataComponent
ContentMetadataComponent,
ContentMetadataCustomPanel,
ContentMetadataService,
TagService
} from '@alfresco/adf-content-services';
import { filter, map, takeUntil } from 'rxjs/operators';
import { filter, map } from 'rxjs/operators';
import { CommonModule } from '@angular/common';
import { Actions, ofType } from '@ngrx/effects';
import { Store } from '@ngrx/store';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -58,8 +59,7 @@ import { Store } from '@ngrx/store';
encapsulation: ViewEncapsulation.None,
host: { class: 'app-metadata-tab' }
})
export class MetadataTabComponent implements OnInit, OnDestroy {
protected onDestroy$ = new Subject<boolean>();
export class MetadataTabComponent implements OnInit {
private _displayCategories = true;
private _displayTags = true;
@ -77,6 +77,8 @@ export class MetadataTabComponent implements OnInit, OnDestroy {
return this._displayTags;
}
private readonly destroyRef = inject(DestroyRef);
constructor(
private permission: NodePermissionService,
protected extensions: AppExtensionService,
@ -97,7 +99,7 @@ export class MetadataTabComponent implements OnInit, OnDestroy {
this._displayTags = this.tagService.areTagsEnabled();
this._displayCategories = this.categoryService.areCategoriesEnabled();
this.contentMetadataService.error.pipe(takeUntil(this.onDestroy$)).subscribe((err: { message: string }) => {
this.contentMetadataService.error.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((err: { message: string }) => {
this.notificationService.showError(err.message);
});
this.checkIfNodeIsUpdatable(this.node);
@ -105,7 +107,7 @@ export class MetadataTabComponent implements OnInit, OnDestroy {
.pipe(
ofType<EditOfflineAction>(NodeActionTypes.EditOffline),
filter((updatedNode) => this.node.id === updatedNode.payload.entry.id),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
)
.subscribe((updatedNode) => {
this.checkIfNodeIsUpdatable(updatedNode?.payload.entry);
@ -116,19 +118,14 @@ export class MetadataTabComponent implements OnInit, OnDestroy {
return { panelTitle: panel.title, component: panel.component };
});
}),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
);
this.store
.select(infoDrawerMetadataAspect)
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((metadataAspect) => (this.metadataAspect = metadataAspect));
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
private checkIfNodeIsUpdatable(node: Node) {
this.readOnly = !(node && !isLocked({ entry: node }) ? this.permission.check(node, ['update']) : false);
}

View File

@ -22,20 +22,21 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { ChangeDetectorRef, Component, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { ChangeDetectorRef, Component, DestroyRef, inject, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SelectionState } from '@alfresco/adf-extensions';
import { Store } from '@ngrx/store';
import { AppStore, getAppSelection } from '@alfresco/aca-shared/store';
import { AvatarComponent, IconComponent, NotificationService } from '@alfresco/adf-core';
import { forkJoin, Subject, throwError } from 'rxjs';
import { catchError, take, takeUntil } from 'rxjs/operators';
import { forkJoin, throwError } from 'rxjs';
import { catchError, take } from 'rxjs/operators';
import { MatMenuModule } from '@angular/material/menu';
import { MatListModule, MatSelectionListChange } from '@angular/material/list';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { Agent } from '@alfresco/js-api';
import { AgentService, SearchAiService } from '@alfresco/adf-content-services';
import { MatTooltipModule } from '@angular/material/tooltip';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -46,13 +47,12 @@ import { MatTooltipModule } from '@angular/material/tooltip';
encapsulation: ViewEncapsulation.None,
host: { class: 'aca-agents-button' }
})
export class AgentsButtonComponent implements OnInit, OnDestroy {
export class AgentsButtonComponent implements OnInit {
@Input()
data: { trigger: string };
private selectedNodesState: SelectionState;
private _agents: Agent[] = [];
private onDestroy$ = new Subject<void>();
private _disabled = true;
private _initialsByAgentId: { [key: string]: string } = {};
private _hxInsightUrl: string;
@ -73,6 +73,8 @@ export class AgentsButtonComponent implements OnInit, OnDestroy {
return this._hxInsightUrl;
}
private readonly destroyRef = inject(DestroyRef);
constructor(
private store: Store<AppStore>,
private notificationService: NotificationService,
@ -85,7 +87,7 @@ export class AgentsButtonComponent implements OnInit, OnDestroy {
ngOnInit(): void {
this.store
.select(getAppSelection)
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((selection) => {
this.selectedNodesState = selection;
});
@ -114,11 +116,6 @@ export class AgentsButtonComponent implements OnInit, OnDestroy {
);
}
ngOnDestroy(): void {
this.onDestroy$.next();
this.onDestroy$.complete();
}
onClick(): void {
if (!this.selectedNodesState.isEmpty) {
const message = this.searchAiService.checkSearchAvailability(this.selectedNodesState);

View File

@ -22,7 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, DestroyRef, inject, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { MatButtonModule } from '@angular/material/button';
@ -32,10 +32,8 @@ import { MatInputModule } from '@angular/material/input';
import { A11yModule } from '@angular/cdk/a11y';
import { AvatarComponent, IconComponent, NotificationService, UserPreferencesService } from '@alfresco/adf-core';
import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Subject } from 'rxjs';
import { Store } from '@ngrx/store';
import { AiSearchByTermPayload, AppStore, getAppSelection, SearchByTermAiAction, ToggleAISearchInput } from '@alfresco/aca-shared/store';
import { takeUntil } from 'rxjs/operators';
import { SelectionState } from '@alfresco/adf-extensions';
import { MatSelectModule } from '@angular/material/select';
import { AgentService, SearchAiService } from '@alfresco/adf-content-services';
@ -48,6 +46,7 @@ import {
} from '@angular/material/tooltip';
import { ModalAiService } from '../../../../services/modal-ai.service';
import { Agent } from '@alfresco/js-api';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
const MatTooltipOptions: MatTooltipDefaultOptions = {
...MAT_TOOLTIP_DEFAULT_OPTIONS_FACTORY(),
@ -78,7 +77,7 @@ const MatTooltipOptions: MatTooltipDefaultOptions = {
encapsulation: ViewEncapsulation.None,
providers: [{ provide: MAT_TOOLTIP_DEFAULT_OPTIONS, useValue: MatTooltipOptions }]
})
export class SearchAiInputComponent implements OnInit, OnDestroy {
export class SearchAiInputComponent implements OnInit {
@Input()
placeholder: string;
@ -95,7 +94,6 @@ export class SearchAiInputComponent implements OnInit, OnDestroy {
private _agentControl = new FormControl<Agent>(null);
private _agents: Agent[] = [];
private onDestroy$ = new Subject<void>();
private selectedNodesState: SelectionState;
private _queryControl = new FormControl('');
private _initialsByAgentId: { [key: string]: string } = {};
@ -116,6 +114,8 @@ export class SearchAiInputComponent implements OnInit, OnDestroy {
return this._initialsByAgentId;
}
private readonly destroyRef = inject(DestroyRef);
constructor(
private store: Store<AppStore>,
private searchAiService: SearchAiService,
@ -133,7 +133,7 @@ export class SearchAiInputComponent implements OnInit, OnDestroy {
if (!this.usedInAiResultsPage) {
this.store
.select(getAppSelection)
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((selection) => {
this.selectedNodesState = selection;
});
@ -143,7 +143,7 @@ export class SearchAiInputComponent implements OnInit, OnDestroy {
this.agentService
.getAgents()
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(
(agents) => {
this._agents = agents;
@ -159,11 +159,6 @@ export class SearchAiInputComponent implements OnInit, OnDestroy {
);
}
ngOnDestroy(): void {
this.onDestroy$.next();
this.onDestroy$.complete();
}
onSearchSubmit() {
this.modalAiService.openUnsavedChangesModal(() => this.search());
}

View File

@ -22,10 +22,10 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { PageComponent, PageLayoutComponent, ToolbarActionComponent, ToolbarComponent } from '@alfresco/aca-shared';
import { concatMap, delay, filter, finalize, retryWhen, skipWhile, switchMap, takeUntil } from 'rxjs/operators';
import { concatMap, delay, filter, finalize, retryWhen, skipWhile, switchMap } from 'rxjs/operators';
import { AvatarComponent, ClipboardService, EmptyContentComponent, ThumbnailService, ToolbarModule, UnsavedChangesGuard } from '@alfresco/adf-core';
import { AiAnswer, Node } from '@alfresco/js-api';
import { CommonModule } from '@angular/common';
@ -42,6 +42,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { ModalAiService } from '../../../../services/modal-ai.service';
import { ViewNodeAction } from '@alfresco/aca-shared/store';
import { ViewerService } from '@alfresco/aca-content/viewer';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -67,7 +68,7 @@ import { ViewerService } from '@alfresco/aca-content/viewer';
encapsulation: ViewEncapsulation.None,
host: { class: 'aca-search-ai-results' }
})
export class SearchAiResultsComponent extends PageComponent implements OnInit, OnDestroy {
export class SearchAiResultsComponent extends PageComponent implements OnInit {
private _agentId: string;
private _hasAnsweringError = false;
private _hasError = false;
@ -133,7 +134,7 @@ export class SearchAiResultsComponent extends PageComponent implements OnInit, O
this.openedViewer = !!params.location;
return !this.openedViewer && (!openedViewerPreviously || !this.queryAnswer);
}),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
)
.subscribe((params) => {
this._agentId = params.agentId;
@ -156,11 +157,6 @@ export class SearchAiResultsComponent extends PageComponent implements OnInit, O
};
}
ngOnDestroy(): void {
this.onDestroy$.next();
this.onDestroy$.complete();
}
copyResponseToClipboard(): void {
this.clipboardService.copyContentToClipboard(
this.queryAnswer.answer,
@ -192,7 +188,7 @@ export class SearchAiResultsComponent extends PageComponent implements OnInit, O
}),
retryWhen((errors: Observable<Error>) => this.aiSearchRetryWhen(errors)),
finalize(() => (this._loading = false)),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
)
.subscribe(
(nodes) => {

View File

@ -22,8 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, EventEmitter, Input, OnDestroy, Output, ViewEncapsulation, ViewChild, ElementRef } from '@angular/core';
import { Subject } from 'rxjs';
import { Component, ElementRef, EventEmitter, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatButtonModule } from '@angular/material/button';
@ -41,9 +40,7 @@ import { FormsModule } from '@angular/forms';
encapsulation: ViewEncapsulation.None,
host: { class: 'app-search-control' }
})
export class SearchInputControlComponent implements OnDestroy {
onDestroy$: Subject<boolean> = new Subject<boolean>();
export class SearchInputControlComponent {
/** Type of the input field to render, e.g. "search" or "text" (default). */
@Input()
inputType = 'text';
@ -68,11 +65,6 @@ export class SearchInputControlComponent implements OnDestroy {
searchTerm = '';
ngOnDestroy(): void {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
searchSubmit(event: any) {
this.submit.emit(event);
}

View File

@ -26,12 +26,10 @@ import { AppHookService, AppService } from '@alfresco/aca-shared';
import { AppStore, SearchByTermAction, SearchOptionIds, SearchOptionModel } from '@alfresco/aca-shared/store';
import { SearchQueryBuilderService } from '@alfresco/adf-content-services';
import { AppConfigService, NotificationService } from '@alfresco/adf-core';
import { Component, inject, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { Component, DestroyRef, inject, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
import { ActivatedRoute, Params, PRIMARY_OUTLET, Router, UrlSegment, UrlSegmentGroup, UrlTree } from '@angular/router';
import { Store } from '@ngrx/store';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { SearchInputControlComponent } from '../search-input-control/search-input-control.component';
import { SearchNavigationService } from '../search-navigation.service';
import { SearchLibrariesQueryBuilderService } from '../search-libraries-results/search-libraries-query-builder.service';
@ -45,6 +43,7 @@ import { A11yModule } from '@angular/cdk/a11y';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { FormsModule } from '@angular/forms';
import { extractSearchedWordFromEncodedQuery } from '../../../utils/aca-search-utils';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -70,7 +69,6 @@ import { extractSearchedWordFromEncodedQuery } from '../../../utils/aca-search-u
export class SearchInputComponent implements OnInit, OnDestroy {
private readonly notificationService = inject(NotificationService);
onDestroy$: Subject<boolean> = new Subject<boolean>();
has400LibraryError = false;
hasLibrariesConstraint = false;
searchOnChange: boolean;
@ -103,6 +101,8 @@ export class SearchInputComponent implements OnInit, OnDestroy {
@ViewChild(MatMenuTrigger, { static: true })
trigger: MatMenuTrigger;
private readonly destroyRef = inject(DestroyRef);
constructor(
private readonly queryBuilder: SearchQueryBuilderService,
private readonly queryLibrariesBuilder: SearchLibrariesQueryBuilderService,
@ -120,7 +120,7 @@ export class SearchInputComponent implements OnInit, OnDestroy {
ngOnInit() {
this.showInputValue();
this.route.queryParams.pipe(takeUntil(this.onDestroy$)).subscribe((params: Params) => {
this.route.queryParams.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((params: Params) => {
const encodedQuery = params['q'];
if (encodedQuery && this.searchInputControl) {
this.searchedWord = extractSearchedWordFromEncodedQuery(encodedQuery);
@ -128,7 +128,7 @@ export class SearchInputComponent implements OnInit, OnDestroy {
}
});
this.appHookService.library400Error.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
this.appHookService.library400Error.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
this.has400LibraryError = true;
this.hasLibrariesConstraint = this.evaluateLibrariesConstraint();
});
@ -151,8 +151,6 @@ export class SearchInputComponent implements OnInit, OnDestroy {
ngOnDestroy(): void {
this.appService.setAppNavbarMode('expanded');
this.onDestroy$.next(true);
this.onDestroy$.complete();
this.removeContentFilters();
}

View File

@ -46,7 +46,7 @@ import { MatProgressBarModule } from '@angular/material/progress-bar';
import { DocumentListDirective } from '../../../directives/document-list.directive';
import { DocumentListComponent } from '@alfresco/adf-content-services';
import { extractSearchedWordFromEncodedQuery } from '../../../utils/aca-search-utils';
import { takeUntil } from 'rxjs/operators';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -130,7 +130,7 @@ export class SearchLibrariesResultsComponent extends PageComponent implements On
);
if (this.route) {
this.route.queryParams.pipe(takeUntil(this.onDestroy$)).subscribe((params: Params) => {
this.route.queryParams.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((params: Params) => {
const encodedQuery = params[this.queryParamName] || null;
this.searchedWord = extractSearchedWordFromEncodedQuery(encodedQuery);
if (this.searchedWord?.length > 1) {

View File

@ -22,19 +22,19 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, Input, OnInit, ViewEncapsulation, ChangeDetectionStrategy, OnDestroy, inject } from '@angular/core';
import { ChangeDetectionStrategy, Component, DestroyRef, inject, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { NodeEntry, SearchEntryHighlight } from '@alfresco/js-api';
import { NavigateToFolder, ViewNodeAction } from '@alfresco/aca-shared/store';
import { Store } from '@ngrx/store';
import { BehaviorSubject, Subject } from 'rxjs';
import { BehaviorSubject } from 'rxjs';
import { NodesApiService } from '@alfresco/adf-content-services';
import { takeUntil } from 'rxjs/operators';
import { Router } from '@angular/router';
import { AutoDownloadService, AppSettingsService } from '@alfresco/aca-shared';
import { AppSettingsService, AutoDownloadService } from '@alfresco/aca-shared';
import { CommonModule } from '@angular/common';
import { LocationLinkComponent } from '../../common/location-link/location-link.component';
import { MatDialogModule } from '@angular/material/dialog';
import { DatatableCellBadgesComponent } from '../../dl-custom-components/datatable-cell-badges/datatable-cell-badges.component';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -46,14 +46,13 @@ import { DatatableCellBadgesComponent } from '../../dl-custom-components/datatab
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'aca-search-results-row' }
})
export class SearchResultsRowComponent implements OnInit, OnDestroy {
export class SearchResultsRowComponent implements OnInit {
private settings = inject(AppSettingsService);
private readonly highlightPrefix = "<span class='aca-highlight'>";
private readonly highlightPostfix = '</span>';
private node: NodeEntry;
private onDestroy$ = new Subject<boolean>();
@Input()
context: any;
@ -68,6 +67,8 @@ export class SearchResultsRowComponent implements OnInit, OnDestroy {
contentStripped = '';
isFile = false;
private readonly destroyRef = inject(DestroyRef);
constructor(
private store: Store<any>,
private nodesApiService: NodesApiService,
@ -78,7 +79,7 @@ export class SearchResultsRowComponent implements OnInit, OnDestroy {
ngOnInit() {
this.updateValues();
this.nodesApiService.nodeUpdated.pipe(takeUntil(this.onDestroy$)).subscribe((node) => {
this.nodesApiService.nodeUpdated.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((node) => {
const row = this.context.row;
if (row) {
const { entry } = row.node;
@ -136,11 +137,6 @@ export class SearchResultsRowComponent implements OnInit, OnDestroy {
}
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
showPreview(event: Event) {
event.stopPropagation();

View File

@ -22,7 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { ChangeDetectorRef, Component, DestroyRef, inject, OnInit, ViewEncapsulation } from '@angular/core';
import { ChangeDetectorRef, Component, inject, OnInit, ViewEncapsulation } from '@angular/core';
import { NodeEntry, Pagination, ResultSetPaging } from '@alfresco/js-api';
import { ActivatedRoute, Params } from '@angular/router';
import {
@ -153,8 +153,6 @@ export class SearchResultsComponent extends PageComponent implements OnInit {
searchConfig: SearchConfiguration;
private readonly loadedFilters$ = new Subject<void>();
private readonly destroyRef = inject(DestroyRef);
constructor(
tagsService: TagService,
private readonly queryBuilder: SearchQueryBuilderService,

View File

@ -22,15 +22,14 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, inject, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, DestroyRef, inject, OnInit, ViewEncapsulation } from '@angular/core';
import { SavedSearch, SavedSearchesService } from '@alfresco/adf-content-services';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { CoreModule, TranslationService } from '@alfresco/adf-core';
import { DynamicExtensionComponent, NavBarLinkRef } from '@alfresco/adf-extensions';
import { ExpandMenuComponent } from '../../../sidenav/components/expand-menu.component';
import { SidenavHeaderComponent } from '../../../sidenav/components/sidenav-header.component';
import { AppService } from '@alfresco/aca-shared';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'aca-save-search-sidenav',
@ -39,30 +38,25 @@ import { AppService } from '@alfresco/aca-shared';
templateUrl: './save-search-sidenav.component.html',
encapsulation: ViewEncapsulation.None
})
export class SaveSearchSidenavComponent implements OnInit, OnDestroy {
export class SaveSearchSidenavComponent implements OnInit {
savedSearchesService = inject(SavedSearchesService);
appService = inject(AppService);
translationService = inject(TranslationService);
destroy$ = new Subject<void>();
item: NavBarLinkRef;
private readonly manageSearchesId = 'manage-saved-searches';
private readonly destroyRef = inject(DestroyRef);
ngOnInit() {
this.savedSearchesService.innit();
this.savedSearchesService.savedSearches$
.asObservable()
.pipe(takeUntil(this.destroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((savedSearches) => {
this.item = this.createNavBarLinkRef(savedSearches);
});
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
onActionClick(el: NavBarLinkRef): void {
if (el.id !== this.manageSearchesId) {
this.appService.appNavNarMode$.next('collapsed');

View File

@ -26,14 +26,15 @@ import { AppStore, SetSelectedNodesAction } from '@alfresco/aca-shared/store';
import { ViewerModule } from '@alfresco/adf-core';
import { ContentActionRef } from '@alfresco/adf-extensions';
import { SharedLinkEntry, SharedlinksApi } from '@alfresco/js-api';
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, DestroyRef, inject, OnInit, ViewEncapsulation } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Store } from '@ngrx/store';
import { forkJoin, from, of, Subject } from 'rxjs';
import { catchError, mergeMap, takeUntil } from 'rxjs/operators';
import { forkJoin, from, of } from 'rxjs';
import { catchError, mergeMap } from 'rxjs/operators';
import { AppExtensionService, AppService, ToolbarComponent } from '@alfresco/aca-shared';
import { CommonModule } from '@angular/common';
import { AlfrescoApiService, AlfrescoViewerModule } from '@alfresco/adf-content-services';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -44,12 +45,14 @@ import { AlfrescoApiService, AlfrescoViewerModule } from '@alfresco/adf-content-
encapsulation: ViewEncapsulation.None,
host: { class: 'app-shared-link-view' }
})
export class SharedLinkViewComponent implements OnInit, OnDestroy {
private onDestroy$: Subject<boolean> = new Subject<boolean>();
private sharedLinksApi: SharedlinksApi;
export class SharedLinkViewComponent implements OnInit {
sharedLinkId: string = null;
viewerToolbarActions: Array<ContentActionRef> = [];
private sharedLinksApi: SharedlinksApi;
private readonly destroyRef = inject(DestroyRef);
constructor(
private route: ActivatedRoute,
private store: Store<AppStore>,
@ -77,14 +80,9 @@ export class SharedLinkViewComponent implements OnInit, OnDestroy {
this.extensions
.getSharedLinkViewerToolbarActions()
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((actions) => {
this.viewerToolbarActions = actions;
});
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
}

View File

@ -22,14 +22,13 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, EventEmitter, inject, OnDestroy, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { Subject } from 'rxjs';
import { Component, DestroyRef, EventEmitter, inject, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { ContentActionRef } from '@alfresco/adf-extensions';
import { AppExtensionService, AppSettingsService, ToolbarComponent } from '@alfresco/aca-shared';
import { takeUntil } from 'rxjs/operators';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { RouterModule } from '@angular/router';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -39,11 +38,12 @@ import { RouterModule } from '@angular/router';
encapsulation: ViewEncapsulation.None,
host: { class: 'app-sidenav-header' }
})
export class SidenavHeaderComponent implements OnInit, OnDestroy {
private onDestroy$ = new Subject<boolean>();
export class SidenavHeaderComponent implements OnInit {
private appSettings = inject(AppSettingsService);
private appExtensions = inject(AppExtensionService);
private readonly destroyRef = inject(DestroyRef);
appName = this.appSettings.appName;
logoUrl = this.appSettings.appLogoUrl;
landingPage = this.appSettings.landingPage;
@ -55,14 +55,9 @@ export class SidenavHeaderComponent implements OnInit, OnDestroy {
ngOnInit() {
this.appExtensions
.getHeaderActions()
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((actions) => {
this.actions = actions;
});
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
}

View File

@ -22,11 +22,23 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { AfterContentInit, ContentChildren, Directive, ElementRef, Input, OnInit, Optional, QueryList, Renderer2 } from '@angular/core';
import {
AfterContentInit,
ContentChildren,
DestroyRef,
Directive,
ElementRef,
inject,
Input,
OnInit,
Optional,
QueryList,
Renderer2
} from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { filter, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { filter } from 'rxjs/operators';
import { ActionDirective } from './action.directive';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Directive({
standalone: true,
@ -39,7 +51,7 @@ export class ActiveLinkDirective implements OnInit, AfterContentInit {
links: QueryList<ActionDirective>;
isLinkActive = false;
private onDestroy$: Subject<boolean> = new Subject<boolean>();
private readonly destroyRef = inject(DestroyRef);
constructor(private router: Router, private element: ElementRef, private renderer: Renderer2, @Optional() private action?: ActionDirective) {}
@ -47,7 +59,7 @@ export class ActiveLinkDirective implements OnInit, AfterContentInit {
this.router.events
.pipe(
filter((event) => event instanceof NavigationEnd),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
)
.subscribe((event: NavigationEnd) => {
this.update(event.urlAfterRedirects);

View File

@ -25,6 +25,7 @@
import { NavigationEnd } from '@angular/router';
import { ExpansionPanelDirective } from './expansion-panel.directive';
import { Subject } from 'rxjs';
import { TestBed } from '@angular/core/testing';
class RouterStub {
url;
@ -64,7 +65,10 @@ describe('AcaExpansionPanel', () => {
const item = {
children: [{ url: 'dummy-route-1' }, { url: 'dummy-route-2' }]
};
const directive = new ExpansionPanelDirective(mockStore, router, mockMatExpansionPanel);
let directive: ExpansionPanelDirective;
TestBed.runInInjectionContext(() => {
directive = new ExpansionPanelDirective(mockStore, router, mockMatExpansionPanel);
});
directive.acaExpansionPanel = item;
@ -75,7 +79,10 @@ describe('AcaExpansionPanel', () => {
const item = {
children: [{ url: 'dummy-route-1' }, { url: 'dummy-route-2' }]
};
const directive = new ExpansionPanelDirective(mockStore, router, mockMatExpansionPanel);
let directive: ExpansionPanelDirective;
TestBed.runInInjectionContext(() => {
directive = new ExpansionPanelDirective(mockStore, router, mockMatExpansionPanel);
});
directive.acaExpansionPanel = item;
@ -93,7 +100,10 @@ describe('AcaExpansionPanel', () => {
mockMatExpansionPanel.expanded = true;
const directive = new ExpansionPanelDirective(mockStore, router, mockMatExpansionPanel);
let directive: ExpansionPanelDirective;
TestBed.runInInjectionContext(() => {
directive = new ExpansionPanelDirective(mockStore, router, mockMatExpansionPanel);
});
directive.acaExpansionPanel = item;
@ -109,7 +119,10 @@ describe('AcaExpansionPanel', () => {
children: [{ url: 'dummy-route-1' }, { url: 'dummy-route-2' }]
};
const directive = new ExpansionPanelDirective(mockStore, router, mockMatExpansionPanel);
let directive: ExpansionPanelDirective;
TestBed.runInInjectionContext(() => {
directive = new ExpansionPanelDirective(mockStore, router, mockMatExpansionPanel);
});
directive.acaExpansionPanel = item;
mockMatExpansionPanel.expanded = true;
@ -129,7 +142,10 @@ describe('AcaExpansionPanel', () => {
}
};
const directive = new ExpansionPanelDirective(mockStore, router, mockMatExpansionPanel);
let directive: ExpansionPanelDirective;
TestBed.runInInjectionContext(() => {
directive = new ExpansionPanelDirective(mockStore, router, mockMatExpansionPanel);
});
directive.acaExpansionPanel = item;
mockMatExpansionPanel.expanded = true;

View File

@ -22,24 +22,22 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Directive, Input, HostListener, OnInit, OnDestroy } from '@angular/core';
import { Router, NavigationEnd, PRIMARY_OUTLET } from '@angular/router';
import { filter, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { DestroyRef, Directive, HostListener, inject, Input, OnInit } from '@angular/core';
import { NavigationEnd, PRIMARY_OUTLET, Router } from '@angular/router';
import { filter } from 'rxjs/operators';
import { MatExpansionPanel } from '@angular/material/expansion';
import { Store } from '@ngrx/store';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Directive({
standalone: true,
selector: '[acaExpansionPanel]',
exportAs: 'acaExpansionPanel'
})
export class ExpansionPanelDirective implements OnInit, OnDestroy {
export class ExpansionPanelDirective implements OnInit {
@Input() acaExpansionPanel;
public hasActiveChildren = false;
private onDestroy$: Subject<boolean> = new Subject<boolean>();
@HostListener('click')
onClick() {
if (this.expansionPanel.expanded && !this.hasActiveLinks() && !this.acaExpansionPanel.data?.canBeInactive) {
@ -55,6 +53,8 @@ export class ExpansionPanelDirective implements OnInit, OnDestroy {
}
}
private readonly destroyRef = inject(DestroyRef);
constructor(private store: Store<any>, private router: Router, private expansionPanel: MatExpansionPanel) {}
hasActiveLinks() {
@ -70,18 +70,13 @@ export class ExpansionPanelDirective implements OnInit, OnDestroy {
this.router.events
.pipe(
filter((event) => event instanceof NavigationEnd),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
)
.subscribe(() => {
this.hasActiveChildren = this.hasActiveLinks();
});
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
private getNavigationCommands(url: string): any[] {
const urlTree = this.router.parseUrl(url);
const urlSegmentGroup = urlTree.root.children[PRIMARY_OUTLET];

View File

@ -25,6 +25,7 @@
import { NavigationEnd } from '@angular/router';
import { MenuPanelDirective } from './menu-panel.directive';
import { Subject } from 'rxjs';
import { TestBed } from '@angular/core/testing';
class RouterStub {
url;
@ -64,7 +65,10 @@ describe('MenuPanelDirective', () => {
const item = {
children: [{ url: 'dummy-route-1' }, { url: 'dummy-route-2' }]
};
const directive = new MenuPanelDirective(mockStore, router);
let directive: MenuPanelDirective;
TestBed.runInInjectionContext(() => {
directive = new MenuPanelDirective(mockStore, router);
});
directive.acaMenuPanel = item;
@ -75,7 +79,10 @@ describe('MenuPanelDirective', () => {
const item = {
children: [{ url: 'dummy-route-1' }, { url: 'dummy-route-2' }]
};
const directive = new MenuPanelDirective(mockStore, router);
let directive: MenuPanelDirective;
TestBed.runInInjectionContext(() => {
directive = new MenuPanelDirective(mockStore, router);
});
directive.acaMenuPanel = item;
@ -93,7 +100,10 @@ describe('MenuPanelDirective', () => {
mockMatExpansionPanel.expanded = true;
const directive = new MenuPanelDirective(mockStore, router);
let directive: MenuPanelDirective;
TestBed.runInInjectionContext(() => {
directive = new MenuPanelDirective(mockStore, router);
});
directive.acaMenuPanel = item;
@ -109,7 +119,10 @@ describe('MenuPanelDirective', () => {
children: [{ url: 'dummy-route-1' }, { url: 'dummy-route-2' }]
};
const directive = new MenuPanelDirective(mockStore, router);
let directive: MenuPanelDirective;
TestBed.runInInjectionContext(() => {
directive = new MenuPanelDirective(mockStore, router);
});
directive.acaMenuPanel = item;
mockMatExpansionPanel.expanded = true;

View File

@ -22,23 +22,21 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Directive, Input, OnInit, OnDestroy, HostListener } from '@angular/core';
import { Router, NavigationEnd, PRIMARY_OUTLET } from '@angular/router';
import { filter, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { DestroyRef, Directive, HostListener, inject, Input, OnInit } from '@angular/core';
import { NavigationEnd, PRIMARY_OUTLET, Router } from '@angular/router';
import { filter } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Directive({
standalone: true,
selector: '[acaMenuPanel]',
exportAs: 'acaMenuPanel'
})
export class MenuPanelDirective implements OnInit, OnDestroy {
export class MenuPanelDirective implements OnInit {
@Input() acaMenuPanel;
hasActiveChildren = false;
private onDestroy$: Subject<boolean> = new Subject<boolean>();
@HostListener('menuOpened')
menuOpened() {
if (this.acaMenuPanel.children && !this.hasActiveLinks()) {
@ -54,6 +52,8 @@ export class MenuPanelDirective implements OnInit, OnDestroy {
}
}
private readonly destroyRef = inject(DestroyRef);
constructor(private store: Store<any>, private router: Router) {}
hasActiveLinks() {
@ -69,18 +69,13 @@ export class MenuPanelDirective implements OnInit, OnDestroy {
this.router.events
.pipe(
filter((event) => event instanceof NavigationEnd),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
)
.subscribe(() => {
this.hasActiveChildren = this.hasActiveLinks();
});
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
private getNavigationCommands(url: string): any[] {
const urlTree = this.router.parseUrl(url);
const urlSegmentGroup = urlTree.root.children[PRIMARY_OUTLET];

View File

@ -22,12 +22,11 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, Input, OnInit, ViewEncapsulation, OnDestroy } from '@angular/core';
import { Component, DestroyRef, inject, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { DynamicExtensionComponent, NavBarGroupRef, NavBarLinkRef } from '@alfresco/adf-extensions';
import { Store } from '@ngrx/store';
import { AppStore, getSideNavState } from '@alfresco/aca-shared/store';
import { Subject } from 'rxjs';
import { takeUntil, distinctUntilChanged, debounceTime } from 'rxjs/operators';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
import { AppExtensionService, AppService, NavigationHistoryService } from '@alfresco/aca-shared';
import { SidenavLayoutComponent } from '@alfresco/adf-core';
import { CommonModule } from '@angular/common';
@ -35,6 +34,7 @@ import { SidenavHeaderComponent } from './components/sidenav-header.component';
import { MatListModule } from '@angular/material/list';
import { ExpandMenuComponent } from './components/expand-menu.component';
import { NavigationEnd } from '@angular/router';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -45,7 +45,7 @@ import { NavigationEnd } from '@angular/router';
encapsulation: ViewEncapsulation.None,
host: { class: 'app-sidenav' }
})
export class SidenavComponent implements OnInit, OnDestroy {
export class SidenavComponent implements OnInit {
@Input()
data: {
layout?: SidenavLayoutComponent;
@ -53,7 +53,8 @@ export class SidenavComponent implements OnInit, OnDestroy {
} = {};
groups: Array<NavBarGroupRef> = [];
private onDestroy$ = new Subject<boolean>();
private readonly destroyRef = inject(DestroyRef);
constructor(
private store: Store<AppStore>,
@ -65,17 +66,17 @@ export class SidenavComponent implements OnInit, OnDestroy {
ngOnInit() {
this.store
.select(getSideNavState)
.pipe(debounceTime(300), distinctUntilChanged(), takeUntil(this.onDestroy$))
.pipe(debounceTime(300), distinctUntilChanged(), takeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.groups = this.extensions.getApplicationNavigation(this.extensions.navbar);
});
this.appService.setAppNavbarMode(this.data.mode);
this.appService.toggleAppNavBar$.pipe(takeUntil(this.onDestroy$)).subscribe(() => this.toggleNavBar());
this.data.layout.expanded.pipe(takeUntil(this.onDestroy$)).subscribe(() => this.setNavBarMode());
this.appService.toggleAppNavBar$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => this.toggleNavBar());
this.data.layout.expanded.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => this.setNavBarMode());
this.navigationHistoryService
.listenToRouteChanges()
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((event: NavigationEnd) => {
this.navigationHistoryService.setHistory(event, 3);
});
@ -101,9 +102,4 @@ export class SidenavComponent implements OnInit, OnDestroy {
this.data.layout.toggleMenu();
this.setNavBarMode();
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
}

View File

@ -22,19 +22,19 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, ViewEncapsulation, OnInit, OnDestroy } from '@angular/core';
import { Component, DestroyRef, inject, OnInit, ViewEncapsulation } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppHookService } from '@alfresco/aca-shared';
import { AppStore, getAppSelection } from '@alfresco/aca-shared/store';
import { SelectionState } from '@alfresco/adf-extensions';
import { distinctUntilChanged, takeUntil } from 'rxjs/operators';
import { distinctUntilChanged } from 'rxjs/operators';
import { Router } from '@angular/router';
import { Subject } from 'rxjs';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { LibraryFavoriteDirective } from '@alfresco/adf-content-services';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -55,9 +55,10 @@ import { MatMenuModule } from '@angular/material/menu';
encapsulation: ViewEncapsulation.None,
host: { class: 'app-toggle-favorite-library' }
})
export class ToggleFavoriteLibraryComponent implements OnInit, OnDestroy {
export class ToggleFavoriteLibraryComponent implements OnInit {
library;
private onDestroy$: Subject<void> = new Subject<void>();
private readonly destroyRef = inject(DestroyRef);
constructor(private store: Store<AppStore>, private appHookService: AppHookService, private router: Router) {}
@ -66,7 +67,7 @@ export class ToggleFavoriteLibraryComponent implements OnInit, OnDestroy {
this.store
.select(getAppSelection)
.pipe(distinctUntilChanged(), takeUntil(this.onDestroy$))
.pipe(distinctUntilChanged(), takeUntilDestroyed(this.destroyRef))
.subscribe((selection: SelectionState) => {
this.library = { ...selection.library };
@ -77,11 +78,6 @@ export class ToggleFavoriteLibraryComponent implements OnInit, OnDestroy {
});
}
ngOnDestroy() {
this.onDestroy$.next();
this.onDestroy$.complete();
}
onToggleEvent() {
this.appHookService.favoriteLibraryToggle.next();
}

View File

@ -22,13 +22,14 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, OnDestroy, ViewEncapsulation } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { delay, takeUntil } from 'rxjs/operators';
import { Component, ViewEncapsulation } from '@angular/core';
import { Observable } from 'rxjs';
import { delay } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { AppStore, getFileUploadingDialog } from '@alfresco/aca-shared/store';
import { CommonModule } from '@angular/common';
import { UploadModule } from '@alfresco/adf-content-services';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -37,17 +38,10 @@ import { UploadModule } from '@alfresco/adf-content-services';
templateUrl: './upload-files-dialog.component.html',
encapsulation: ViewEncapsulation.None
})
export class UploadFilesDialogComponent implements OnDestroy {
export class UploadFilesDialogComponent {
showFileUploadingDialog$: Observable<boolean>;
private onDestroy$: Subject<boolean> = new Subject<boolean>();
constructor(private store: Store<AppStore>) {
this.showFileUploadingDialog$ = this.store.select(getFileUploadingDialog).pipe(delay(0), takeUntil(this.onDestroy$));
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
this.showFileUploadingDialog$ = this.store.select(getFileUploadingDialog).pipe(delay(0), takeUntilDestroyed());
}
}

View File

@ -24,18 +24,18 @@
import { AlfrescoApiService } from '@alfresco/adf-content-services';
import { PeopleApi, Person } from '@alfresco/js-api';
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { Observable, Subject, throwError } from 'rxjs';
import { Observable, throwError } from 'rxjs';
import { AppService } from '@alfresco/aca-shared';
import { takeUntil } from 'rxjs/operators';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { TranslateModule } from '@ngx-translate/core';
import { MatDividerModule } from '@angular/material/divider';
import { MatFormFieldModule } from '@angular/material/form-field';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -45,7 +45,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
styleUrls: ['./view-profile.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class ViewProfileComponent implements OnInit, OnDestroy {
export class ViewProfileComponent implements OnInit {
peopleApi: PeopleApi;
profileForm: FormGroup;
@ -61,11 +61,10 @@ export class ViewProfileComponent implements OnInit, OnDestroy {
contactSectionDropdown = false;
contactSectionButtonsToggle = true;
appNavNarMode$: Observable<'collapsed' | 'expanded'>;
private onDestroy$ = new Subject<boolean>();
constructor(private router: Router, apiService: AlfrescoApiService, private appService: AppService) {
this.peopleApi = new PeopleApi(apiService.getInstance());
this.appNavNarMode$ = appService.appNavNarMode$.pipe(takeUntil(this.onDestroy$));
this.appNavNarMode$ = appService.appNavNarMode$.pipe(takeUntilDestroyed());
}
ngOnInit() {
@ -205,9 +204,4 @@ export class ViewProfileComponent implements OnInit, OnDestroy {
isSaveButtonDisabled(): boolean {
return this.profileForm.invalid;
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
}

View File

@ -25,6 +25,7 @@
import { DocumentListDirective } from './document-list.directive';
import { Subject } from 'rxjs';
import { SetSelectedNodesAction } from '@alfresco/aca-shared/store';
import { TestBed } from '@angular/core/testing';
describe('DocumentListDirective', () => {
let documentListDirective: DocumentListDirective;
@ -74,14 +75,16 @@ describe('DocumentListDirective', () => {
};
beforeEach(() => {
documentListDirective = new DocumentListDirective(
storeMock,
documentListMock,
userPreferencesServiceMock,
mockRoute,
mockRouter,
documentListServiceMock as any
);
TestBed.runInInjectionContext(() => {
documentListDirective = new DocumentListDirective(
storeMock,
documentListMock,
userPreferencesServiceMock,
mockRoute,
mockRouter,
documentListServiceMock as any
);
});
});
afterEach(() => {

View File

@ -22,30 +22,30 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Directive, OnDestroy, OnInit, HostListener } from '@angular/core';
import { DestroyRef, Directive, HostListener, inject, OnInit } from '@angular/core';
import { DocumentListComponent, DocumentListService } from '@alfresco/adf-content-services';
import { ActivatedRoute, Router } from '@angular/router';
import { UserPreferencesService } from '@alfresco/adf-core';
import { Subject } from 'rxjs';
import { Store } from '@ngrx/store';
import { SetSelectedNodesAction } from '@alfresco/aca-shared/store';
import { takeUntil, filter } from 'rxjs/operators';
import { filter } from 'rxjs/operators';
import { NodeEntry } from '@alfresco/js-api';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Directive({
standalone: true,
selector: '[acaDocumentList]'
})
export class DocumentListDirective implements OnInit, OnDestroy {
export class DocumentListDirective implements OnInit {
private isLibrary = false;
selectedNode: NodeEntry;
onDestroy$ = new Subject<boolean>();
get sortingPreferenceKey(): string {
return this.route.snapshot.data.sortingPreferenceKey;
}
private readonly destroyRef = inject(DestroyRef);
constructor(
private store: Store<any>,
private documentList: DocumentListComponent,
@ -87,24 +87,19 @@ export class DocumentListDirective implements OnInit, OnDestroy {
this.documentList.ready
.pipe(
filter(() => !this.router.url.includes('viewer:view')),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
)
.subscribe(() => this.onReady());
this.documentListService.reload$.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
this.documentListService.reload$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
this.reload();
});
this.documentListService.resetSelection$.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
this.documentListService.resetSelection$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
this.reset();
});
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
@HostListener('sorting-changed', ['$event'])
onSortingChanged(event: CustomEvent) {
if (this.sortingPreferenceKey) {

View File

@ -22,25 +22,26 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, OnInit, OnDestroy, ViewEncapsulation, HostListener } from '@angular/core';
import { Component, HostListener, OnInit, ViewEncapsulation } from '@angular/core';
import { CommonModule, Location } from '@angular/common';
import { UrlTree, UrlSegmentGroup, UrlSegment, PRIMARY_OUTLET, ActivatedRoute } from '@angular/router';
import { debounceTime, map, takeUntil } from 'rxjs/operators';
import { ActivatedRoute, PRIMARY_OUTLET, UrlSegment, UrlSegmentGroup, UrlTree } from '@angular/router';
import { debounceTime, map } from 'rxjs/operators';
import { ViewerModule } from '@alfresco/adf-core';
import { ClosePreviewAction, ViewerActionTypes, SetSelectedNodesAction } from '@alfresco/aca-shared/store';
import { ClosePreviewAction, SetSelectedNodesAction, ViewerActionTypes } from '@alfresco/aca-shared/store';
import {
PageComponent,
AppHookService,
ContentApiService,
InfoDrawerComponent,
ToolbarMenuItemComponent,
ToolbarComponent
PageComponent,
ToolbarComponent,
ToolbarMenuItemComponent
} from '@alfresco/aca-shared';
import { ContentActionRef } from '@alfresco/adf-extensions';
import { from } from 'rxjs';
import { Actions, ofType } from '@ngrx/effects';
import { AlfrescoViewerModule, NodesApiService } from '@alfresco/adf-content-services';
import { ViewerService } from '../../services/viewer.service';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -51,7 +52,7 @@ import { ViewerService } from '../../services/viewer.service';
encapsulation: ViewEncapsulation.None,
host: { class: 'app-preview' }
})
export class PreviewComponent extends PageComponent implements OnInit, OnDestroy {
export class PreviewComponent extends PageComponent implements OnInit {
folderId: string = null;
navigateBackAsClose = false;
navigateMultiple = false;
@ -84,7 +85,7 @@ export class PreviewComponent extends PageComponent implements OnInit, OnDestroy
super.ngOnInit();
from(this.infoDrawerOpened$)
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((val) => {
this.showRightSide = val;
});
@ -131,16 +132,12 @@ export class PreviewComponent extends PageComponent implements OnInit, OnDestroy
this.extensions
.getOpenWithActions()
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((actions) => {
this.openWith = actions;
});
}
ngOnDestroy() {
super.ngOnDestroy();
}
/**
* Loads the particular node into the Viewer
*

View File

@ -44,16 +44,17 @@ import {
} from '@alfresco/aca-shared/store';
import { ContentActionRef, SelectionState } from '@alfresco/adf-extensions';
import { Node, VersionEntry, VersionsApi } from '@alfresco/js-api';
import { Component, HostListener, inject, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, DestroyRef, HostListener, inject, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { ActivatedRoute, PRIMARY_OUTLET, Router } from '@angular/router';
import { ViewerOpenWithComponent, ViewerSidebarComponent, ViewerToolbarActionsComponent } from '@alfresco/adf-core';
import { Store } from '@ngrx/store';
import { from, Observable, Subject } from 'rxjs';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { from, Observable } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import { Actions, ofType } from '@ngrx/effects';
import { AlfrescoApiService, AlfrescoViewerComponent, DocumentListService, NodesApiService, UploadService } from '@alfresco/adf-content-services';
import { CommonModule } from '@angular/common';
import { ViewerService } from '../../services/viewer.service';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -84,8 +85,6 @@ export class AcaViewerComponent implements OnInit, OnDestroy {
return this._versionsApi;
}
onDestroy$ = new Subject<boolean>();
fileName: string;
folderId: string = null;
infoDrawerOpened$: Observable<boolean>;
@ -106,6 +105,8 @@ export class AcaViewerComponent implements OnInit, OnDestroy {
private previewLocation: string;
private containersSkipNavigation = ['adf-viewer__sidebar', 'cdk-overlay-container', 'adf-image-viewer'];
private readonly destroyRef = inject(DestroyRef);
constructor(
private actions$: Actions,
private apiService: AlfrescoApiService,
@ -124,28 +125,28 @@ export class AcaViewerComponent implements OnInit, OnDestroy {
this.infoDrawerOpened$ = this.store.select(isInfoDrawerOpened);
from(this.infoDrawerOpened$)
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((val) => {
this.showRightSide = val;
});
this.store
.select(getAppSelection)
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((selection) => {
this.selection = selection;
});
this.extensions
.getViewerToolbarActions()
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((actions) => {
this.toolbarActions = actions;
});
this.extensions
.getOpenWithActions()
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((actions) => {
this.openWith = actions;
});
@ -177,23 +178,23 @@ export class AcaViewerComponent implements OnInit, OnDestroy {
}
}
this.actions$.pipe(ofType<ClosePreviewAction>(ViewerActionTypes.ClosePreview), takeUntil(this.onDestroy$)).subscribe(() => {
this.actions$.pipe(ofType<ClosePreviewAction>(ViewerActionTypes.ClosePreview), takeUntilDestroyed(this.destroyRef)).subscribe(() => {
this.store.dispatch(new SetCurrentNodeVersionAction(null));
this.navigateToFileLocation();
});
this.actions$
.pipe(ofType<RefreshPreviewAction>(ViewerActionTypes.RefreshPreview), takeUntil(this.onDestroy$))
.pipe(ofType<RefreshPreviewAction>(ViewerActionTypes.RefreshPreview), takeUntilDestroyed(this.destroyRef))
.subscribe((action: RefreshPreviewAction) => {
this.nodesApiService.nodeUpdated.next(action.node);
void this.displayNode(action.node.id);
});
this.appHookService.nodesDeleted.pipe(takeUntil(this.onDestroy$)).subscribe(() => this.navigateToFileLocation());
this.appHookService.nodesDeleted.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => this.navigateToFileLocation());
this.uploadService.fileUploadDeleted.pipe(takeUntil(this.onDestroy$)).subscribe(() => this.navigateToFileLocation());
this.uploadService.fileUploadDeleted.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => this.navigateToFileLocation());
this.uploadService.fileUploadComplete.pipe(debounceTime(300), takeUntil(this.onDestroy$)).subscribe((file) => {
this.uploadService.fileUploadComplete.pipe(debounceTime(300), takeUntilDestroyed(this.destroyRef)).subscribe((file) => {
this.nodesApiService.nodeUpdated.next(file.data.entry);
void this.displayNode(file.data.entry.id);
});
@ -208,8 +209,6 @@ export class AcaViewerComponent implements OnInit, OnDestroy {
ngOnDestroy() {
this.store.dispatch(new SetCurrentNodeVersionAction(null));
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
trackByActionId(_: number, obj: ContentActionRef): string {

View File

@ -32,20 +32,19 @@ import {
} from '@alfresco/adf-content-services';
import { ShowHeaderMode, UserPreferencesService } from '@alfresco/adf-core';
import { ContentActionRef, DocumentListPresetRef, SelectionState } from '@alfresco/adf-extensions';
import { OnDestroy, OnInit, OnChanges, ViewChild, SimpleChanges, Directive, inject, HostListener } from '@angular/core';
import { DestroyRef, Directive, HostListener, inject, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from '@angular/core';
import { Store } from '@ngrx/store';
import { NodeEntry, Node, NodePaging } from '@alfresco/js-api';
import { Observable, Subject, Subscription } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { Node, NodeEntry, NodePaging } from '@alfresco/js-api';
import { Observable, Subscription } from 'rxjs';
import { DocumentBasePageService } from './document-base-page.service';
import {
AppStore,
getCurrentFolder,
getAppSelection,
getCurrentFolder,
isInfoDrawerOpened,
SetSelectedNodesAction,
ViewNodeAction,
ViewNodeExtras,
SetSelectedNodesAction
ViewNodeExtras
} from '@alfresco/aca-shared/store';
import { AppExtensionService } from '../../services/app.extension.service';
import { isLibrary, isLocked } from '../../utils/node.utils';
@ -54,12 +53,11 @@ import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { Router } from '@angular/router';
import { AppSettingsService } from '../../services/app-settings.service';
import { NavigationHistoryService } from '../../services/navigation-history.service';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
/* eslint-disable @angular-eslint/directive-class-suffix */
@Directive()
export abstract class PageComponent implements OnInit, OnDestroy, OnChanges {
onDestroy$: Subject<void> = new Subject<void>();
@ViewChild(DocumentListComponent)
documentList: DocumentListComponent;
@ -90,6 +88,9 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges {
protected router = inject(Router);
protected userPreferencesService = inject(UserPreferencesService);
protected searchAiService = inject(SearchAiService);
protected readonly destroyRef = inject(DestroyRef);
private autoDownloadService = inject(AutoDownloadService, { optional: true });
private navigationHistoryService = inject(NavigationHistoryService);
@ -106,7 +107,7 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges {
ngOnInit() {
this.extensions
.getCreateActions()
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((actions) => {
this.createActions = actions;
});
@ -115,7 +116,7 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges {
this.store
.select(getAppSelection)
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((selection) => {
this.selection = selection;
this.canUpdateNode = this.selection.count === 1 && this.content.canUpdateNode(selection.first);
@ -123,41 +124,41 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges {
this.extensions
.getAllowedToolbarActions()
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((actions) => {
this.actions = actions;
});
this.extensions
.getBulkActions()
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((actions) => {
this.bulkActions = actions;
});
this.extensions
.getViewerToolbarActions()
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((actions) => {
this.viewerToolbarActions = actions;
});
this.store
.select(getCurrentFolder)
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((node) => {
this.canUpload = node && this.content.canUploadContent(node);
});
this.breakpointObserver
.observe([Breakpoints.HandsetPortrait, Breakpoints.HandsetLandscape])
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((result) => {
this.isSmallScreen = result.matches;
});
this.searchAiService.toggleSearchAiInput$
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((searchAiInputState) => (this._searchAiInputState = searchAiInputState));
this.setKnowledgeRetrievalState();
@ -173,8 +174,6 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges {
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
this.subscriptions = [];
this.onDestroy$.next();
this.onDestroy$.complete();
this.store.dispatch(new SetSelectedNodesAction([]));
}

View File

@ -22,15 +22,13 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, HostListener, Input, OnChanges, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { NodeEntry, Node, SiteEntry } from '@alfresco/js-api';
import { Component, DestroyRef, HostListener, inject, Input, OnChanges, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { Node, NodeEntry, SiteEntry } from '@alfresco/js-api';
import { ContentActionRef, DynamicTabComponent, SidebarTabRef } from '@alfresco/adf-extensions';
import { Store } from '@ngrx/store';
import { SetInfoDrawerStateAction, ToggleInfoDrawerAction, infoDrawerPreview } from '@alfresco/aca-shared/store';
import { infoDrawerPreview, SetInfoDrawerStateAction, ToggleInfoDrawerAction } from '@alfresco/aca-shared/store';
import { AppExtensionService } from '../../services/app.extension.service';
import { ContentApiService } from '../../services/content-api.service';
import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { CommonModule } from '@angular/common';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { InfoDrawerModule } from '@alfresco/adf-core';
@ -38,6 +36,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { A11yModule } from '@angular/cdk/a11y';
import { ToolbarComponent } from '../toolbar/toolbar.component';
import { ContentService, NodesApiService } from '@alfresco/adf-content-services';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -57,7 +56,7 @@ export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy {
displayNode: Node | SiteEntry;
tabs: Array<SidebarTabRef> = [];
actions: Array<ContentActionRef> = [];
onDestroy$ = new Subject<boolean>();
preventFromClosing = false;
icon: string = null;
@ -66,6 +65,8 @@ export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy {
this.close();
}
private readonly destroyRef = inject(DestroyRef);
constructor(
private store: Store<any>,
private contentApi: ContentApiService,
@ -78,26 +79,24 @@ export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy {
this.tabs = this.extensions.getSidebarTabs();
this.extensions
.getAllowedSidebarActions()
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((actions) => {
this.actions = actions;
});
this.store
.select(infoDrawerPreview)
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((isInfoDrawerPreviewOpened) => {
this.preventFromClosing = isInfoDrawerPreviewOpened;
});
this.nodesService.nodeUpdated.pipe(takeUntil(this.onDestroy$)).subscribe((node: any) => {
this.nodesService.nodeUpdated.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((node: any) => {
this.node.entry = node;
});
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
if (!this.preventFromClosing) {
this.store.dispatch(new SetInfoDrawerStateAction(false));
}

View File

@ -22,14 +22,14 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, ViewEncapsulation, Input, OnDestroy } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { Component, Input, ViewEncapsulation } from '@angular/core';
import { Observable } from 'rxjs';
import { AppService } from '../../services/app.service';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
standalone: true,
@ -40,23 +40,17 @@ import { MatIconModule } from '@angular/material/icon';
encapsulation: ViewEncapsulation.None,
host: { class: 'aca-page-layout' }
})
export class PageLayoutComponent implements OnDestroy {
export class PageLayoutComponent {
@Input()
hasError = false;
private onDestroy$ = new Subject<boolean>();
appNavNarMode$: Observable<'collapsed' | 'expanded'>;
constructor(private appService: AppService) {
this.appNavNarMode$ = appService.appNavNarMode$.pipe(takeUntil(this.onDestroy$));
this.appNavNarMode$ = appService.appNavNarMode$.pipe(takeUntilDestroyed());
}
toggleClick() {
this.appService.toggleAppNavBar$.next();
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
}

View File

@ -25,7 +25,9 @@
import { ContextActionsDirective } from './contextmenu.directive';
import { ContextMenu, CustomContextMenu } from '@alfresco/aca-shared/store';
import { ContentActionRef, ContentActionType } from '@alfresco/adf-extensions';
import { fakeAsync, tick } from '@angular/core/testing';
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
import { Store } from '@ngrx/store';
import { Injector, runInInjectionContext } from '@angular/core';
const customActionsMock: ContentActionRef[] = [
{
@ -46,7 +48,13 @@ describe('ContextActionsDirective', () => {
};
beforeEach(() => {
directive = new ContextActionsDirective(storeMock);
TestBed.configureTestingModule({
imports: [ContextActionsDirective],
providers: [{ provide: Store, useValue: storeMock }]
});
runInInjectionContext(TestBed.inject(Injector), () => {
directive = new ContextActionsDirective(storeMock);
});
});
it('should not render context menu when `enabled` property is false', () => {

View File

@ -22,22 +22,20 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Directive, HostListener, Input, OnInit, OnDestroy } from '@angular/core';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { DestroyRef, Directive, HostListener, inject, Input, OnInit } from '@angular/core';
import { debounceTime } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { Store } from '@ngrx/store';
import { AppStore, ContextMenu, CustomContextMenu } from '@alfresco/aca-shared/store';
import { ContentActionRef } from '@alfresco/adf-extensions';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Directive({
standalone: true,
selector: '[acaContextActions]',
exportAs: 'acaContextActions'
})
export class ContextActionsDirective implements OnInit, OnDestroy {
private execute$: Subject<any> = new Subject();
onDestroy$: Subject<boolean> = new Subject<boolean>();
export class ContextActionsDirective implements OnInit {
// eslint-disable-next-line
@Input('acaContextEnable')
enabled = true;
@ -59,10 +57,14 @@ export class ContextActionsDirective implements OnInit, OnDestroy {
}
}
private execute$: Subject<any> = new Subject();
private readonly destroyRef = inject(DestroyRef);
constructor(private store: Store<AppStore>) {}
ngOnInit() {
this.execute$.pipe(debounceTime(300), takeUntil(this.onDestroy$)).subscribe((event: MouseEvent) => {
this.execute$.pipe(debounceTime(300), takeUntilDestroyed(this.destroyRef)).subscribe((event: MouseEvent) => {
if (this.customActions?.length) {
this.store.dispatch(new CustomContextMenu(event, this.customActions));
} else {
@ -70,12 +72,6 @@ export class ContextActionsDirective implements OnInit, OnDestroy {
}
});
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
execute(event: MouseEvent, target: Element) {
if (!this.isSelected(target)) {
target.dispatchEvent(new MouseEvent('click'));

View File

@ -23,10 +23,11 @@
*/
import { PaginationDirective } from './pagination.directive';
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { UserPreferencesService, AppConfigService, PaginationComponent, PaginationModel } from '@alfresco/adf-core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AppConfigService, PaginationComponent, PaginationModel, UserPreferencesService } from '@alfresco/adf-core';
import { initialState, LibTestingModule } from '../testing/lib-testing-module';
import { provideMockStore } from '@ngrx/store/testing';
import { Injector, runInInjectionContext } from '@angular/core';
describe('PaginationDirective', () => {
let preferences: UserPreferencesService;
@ -45,12 +46,13 @@ describe('PaginationDirective', () => {
config = TestBed.inject(AppConfigService);
fixture = TestBed.createComponent(PaginationComponent);
pagination = fixture.componentInstance;
directive = new PaginationDirective(pagination, preferences, config);
runInInjectionContext(TestBed.inject(Injector), () => {
directive = new PaginationDirective(pagination, preferences, config);
});
});
afterEach(() => {
fixture.destroy();
directive.ngOnDestroy();
});
it('should setup supported page sizes from app config', () => {

View File

@ -22,31 +22,23 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Directive, OnInit, OnDestroy } from '@angular/core';
import { PaginationComponent, UserPreferencesService, PaginationModel, AppConfigService } from '@alfresco/adf-core';
import { Subscription } from 'rxjs';
import { DestroyRef, Directive, inject, OnInit } from '@angular/core';
import { AppConfigService, PaginationComponent, PaginationModel, UserPreferencesService } from '@alfresco/adf-core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Directive({
standalone: true,
selector: '[acaPagination]'
})
export class PaginationDirective implements OnInit, OnDestroy {
private subscriptions: Subscription[] = [];
export class PaginationDirective implements OnInit {
private readonly destroyRef = inject(DestroyRef);
constructor(private pagination: PaginationComponent, private preferences: UserPreferencesService, private config: AppConfigService) {}
ngOnInit() {
this.pagination.supportedPageSizes = this.config.get('pagination.supportedPageSizes');
this.subscriptions.push(
this.pagination.changePageSize.subscribe((event: PaginationModel) => {
this.preferences.paginationSize = event.maxItems;
})
);
}
ngOnDestroy() {
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
this.subscriptions = [];
this.pagination.changePageSize.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event: PaginationModel) => {
this.preferences.paginationSize = event.maxItems;
});
}
}

View File

@ -22,20 +22,20 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { inject, Injectable, OnDestroy } from '@angular/core';
import { AuthenticationService, AppConfigService, PageTitleService, UserPreferencesService, NotificationService } from '@alfresco/adf-core';
import { Observable, BehaviorSubject, Subject } from 'rxjs';
import { inject, Injectable } from '@angular/core';
import { AppConfigService, AuthenticationService, NotificationService, PageTitleService, UserPreferencesService } from '@alfresco/adf-core';
import { BehaviorSubject, Observable, Subject } from 'rxjs';
import {
AlfrescoApiService,
FileUploadErrorEvent,
SearchQueryBuilderService,
SharedLinksApiService,
UploadService,
FileUploadErrorEvent
UploadService
} from '@alfresco/adf-content-services';
import { OverlayContainer } from '@angular/cdk/overlay';
import { ActivatedRoute, ActivationEnd, NavigationStart, Router } from '@angular/router';
import { filter, map } from 'rxjs/operators';
import { AppStore, SetCurrentUrlAction, SetRepositoryInfoAction, SetUserProfileAction, ResetSelectionAction } from '@alfresco/aca-shared/store';
import { AppStore, ResetSelectionAction, SetCurrentUrlAction, SetRepositoryInfoAction, SetUserProfileAction } from '@alfresco/aca-shared/store';
import { ContentApiService } from './content-api.service';
import { RouterExtensionService } from './router.extension.service';
import { Store } from '@ngrx/store';
@ -50,7 +50,7 @@ import { MatDialog } from '@angular/material/dialog';
providedIn: 'root'
})
// After moving shell to ADF to core, AppService will implement ShellAppService
export class AppService implements ShellAppService, OnDestroy {
export class AppService implements ShellAppService {
private notificationService = inject(NotificationService);
private matDialog = inject(MatDialog);
private ready: BehaviorSubject<boolean>;
@ -67,8 +67,6 @@ export class AppService implements ShellAppService, OnDestroy {
hideSidenavConditions = ['/preview/'];
minimizeSidenavConditions = ['/search'];
onDestroy$ = new Subject<boolean>();
/**
* Whether `withCredentials` mode is enabled.
* Usually means that `Kerberos` mode is used.
@ -121,11 +119,6 @@ export class AppService implements ShellAppService, OnDestroy {
});
}
ngOnDestroy(): void {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
init(): void {
this.alfrescoApiService.getInstance().on('error', (error: { status: number; response: any }) => {
if (error.status === 401 && !this.alfrescoApiService.isExcludedErrorListener(error?.response?.req?.url)) {