Skip to content

Commit

Permalink
BREAKING Drop NaturalAbstractController in favor of DestroyRef #1…
Browse files Browse the repository at this point in the history
…0746
  • Loading branch information
PowerKiKi committed Oct 2, 2024
1 parent 6d79f67 commit 1fd56a8
Show file tree
Hide file tree
Showing 17 changed files with 95 additions and 116 deletions.
24 changes: 0 additions & 24 deletions projects/natural/src/lib/classes/abstract-controller.ts

This file was deleted.

4 changes: 1 addition & 3 deletions projects/natural/src/lib/classes/abstract-detail.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {DestroyRef, Directive, inject, OnInit} from '@angular/core';
import {Directive, inject, OnInit} from '@angular/core';
import {UntypedFormGroup} from '@angular/forms';
import {ActivatedRoute, Router} from '@angular/router';
import {kebabCase} from 'lodash-es';
Expand Down Expand Up @@ -85,8 +85,6 @@ export class NaturalAbstractDetail<

private readonly _dialogData: unknown = inject(MAT_DIALOG_DATA, {optional: true});

private readonly destroyRef = inject(DestroyRef);

/**
* Once set, this must not change anymore, especially not right after the creation mutation,
* so the form does not switch from creation mode to update mode without an actual reload of
Expand Down
5 changes: 1 addition & 4 deletions projects/natural/src/lib/classes/abstract-editable-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {AbstractControl, UntypedFormArray, UntypedFormGroup} from '@angular/form
import {MatTableDataSource} from '@angular/material/table';
import {merge} from 'lodash-es';
import {NaturalAbstractModelService} from '../services/abstract-model.service';
import {NaturalAbstractController} from './abstract-controller';
import {NaturalQueryVariablesManager, QueryVariables} from './query-variable-manager';
import {ExtractTallOne, ExtractVall, Literal} from '../types/types';
import {validateAllFormControls} from './validators';
Expand Down Expand Up @@ -46,15 +45,13 @@ export class NaturalAbstractEditableList<
// The Literal here is a bit too loose. Ideally we would like to express
// "it must be a union and one of the type in the union must be ExtractTallOne<TService>"
T extends Literal = ExtractTallOne<TService>,
> extends NaturalAbstractController {
> {
public readonly form: UntypedFormGroup;
public readonly formArray = new UntypedFormArray([]);
public readonly variablesManager = new NaturalQueryVariablesManager<ExtractVall<TService>>();
public readonly dataSource = new MatTableDataSource<AbstractControl>();

public constructor(protected readonly service: TService) {
super();

// Create a form group with a line attributes that contain an array of formGroups (one by line = one by model)
this.form = new UntypedFormGroup({rows: this.formArray});
this.dataSource.data = this.formArray.controls;
Expand Down
13 changes: 7 additions & 6 deletions projects/natural/src/lib/classes/abstract-list.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {SelectionModel} from '@angular/cdk/collections';
import {Directive, inject, Input, OnDestroy, OnInit} from '@angular/core';
import {Directive, inject, Input, OnInit} from '@angular/core';
import {PageEvent} from '@angular/material/paginator';
import {Sort} from '@angular/material/sort';
import {ActivatedRoute, Data, NavigationEnd, NavigationExtras, NavigationStart, Router} from '@angular/router';
Expand All @@ -23,9 +23,10 @@ import {
} from './query-variable-manager';
import {ExtractTall, ExtractVall, Literal} from '../types/types';
import {NavigableItem} from './abstract-navigable-list';
import {filter, takeUntil} from 'rxjs/operators';
import {filter} from 'rxjs/operators';
import {AvailableColumn} from '../modules/columns-picker/types';
import {validateColumns, validatePagination, validateSorting} from './utility';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

type MaybeNavigable = Literal | NavigableItem<Literal>;

Expand Down Expand Up @@ -71,7 +72,7 @@ export class NaturalAbstractList<
Tall extends PaginatedData<MaybeNavigable> = ExtractTall<TService>,
>
extends NaturalAbstractPanel
implements OnInit, OnDestroy
implements OnInit
{
/**
* Whether search should be loaded from url/storage and persisted in it too.
Expand Down Expand Up @@ -196,7 +197,7 @@ export class NaturalAbstractList<
let isPopState = false;
this.router.events
.pipe(
takeUntil(this.ngUnsubscribe),
takeUntilDestroyed(this.destroyRef),
filter(event => event instanceof NavigationStart && event.navigationTrigger === 'popstate'),
)
.subscribe(() => {
Expand All @@ -205,7 +206,7 @@ export class NaturalAbstractList<

this.router.events
.pipe(
takeUntil(this.ngUnsubscribe),
takeUntilDestroyed(this.destroyRef),
filter(event => event instanceof NavigationEnd && isPopState),
)
.subscribe(() => {
Expand Down Expand Up @@ -477,7 +478,7 @@ export class NaturalAbstractList<
// the casting and resolve things in a better way, but that's too much work for now
return this.service
.watchAll(this.variablesManager as unknown as any)
.pipe(takeUntil(this.ngUnsubscribe)) as unknown as Observable<Tall>;
.pipe(takeUntilDestroyed(this.destroyRef)) as unknown as Observable<Tall>;
}

protected initFromPersisted(): void {
Expand Down
9 changes: 5 additions & 4 deletions projects/natural/src/lib/classes/abstract-navigable-list.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Directive, Input, OnDestroy, OnInit} from '@angular/core';
import {Directive, Input, OnInit} from '@angular/core';
import {NavigationExtras, RouterLink} from '@angular/router';
import {map, takeUntil} from 'rxjs/operators';
import {map} from 'rxjs/operators';
import {NaturalSearchSelections} from '../modules/search/types/values';
import {NaturalAbstractModelService} from '../services/abstract-model.service';
import {NaturalAbstractList} from './abstract-list';
Expand All @@ -9,6 +9,7 @@ import {NaturalQueryVariablesManager, QueryVariables} from './query-variable-man
import {ExtractTall, ExtractTallOne, ExtractVall, Literal} from '../types/types';
import {first, Observable} from 'rxjs';
import {FilterGroupCondition} from '../modules/search/classes/graphql-doctrine.types';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

type BreadcrumbItem = {
id: string;
Expand Down Expand Up @@ -42,7 +43,7 @@ export class NaturalAbstractNavigableList<
>,
>
extends NaturalAbstractList<TService, PaginatedData<NavigableItem<ExtractTall<TService>['items'][0]>>>
implements OnInit, OnDestroy
implements OnInit
{
/**
* Name of filter for child items to access ancestor item
Expand Down Expand Up @@ -99,7 +100,7 @@ export class NaturalAbstractNavigableList<

protected override getDataObservable(): Observable<PaginatedData<NavigableItem<ExtractTallOne<TService>>>> {
return this.service.watchAll(this.variablesManager as unknown as any).pipe(
takeUntil(this.ngUnsubscribe),
takeUntilDestroyed(this.destroyRef),
map(result => {
// On each data arriving, we query children count to show/hide chevron
const navigableItems: NavigableItem<ExtractTallOne<TService>>[] = result.items.map(item => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import {AfterViewInit, Directive, Input} from '@angular/core';
import {AfterViewInit, DestroyRef, Directive, inject, Input} from '@angular/core';
import {MatTab, MatTabGroup} from '@angular/material/tabs';
import {ActivatedRoute, RouteConfigLoadEnd, RouteConfigLoadStart, Router} from '@angular/router';
import {clone} from 'lodash-es';
import {takeUntil} from 'rxjs/operators';
import {NaturalAbstractController} from '../../../classes/abstract-controller';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

/**
Expand All @@ -28,7 +26,8 @@ function getTabId(tab: MatTab): string {
selector: 'mat-tab-group[naturalLinkableTab]',
standalone: true,
})
export class NaturalLinkableTabDirective extends NaturalAbstractController implements AfterViewInit {
export class NaturalLinkableTabDirective implements AfterViewInit {
private readonly destroyRef = inject(DestroyRef);
/**
* If false, disables the persistent navigation
*/
Expand All @@ -40,8 +39,6 @@ export class NaturalLinkableTabDirective extends NaturalAbstractController imple
private readonly route: ActivatedRoute,
private readonly router: Router,
) {
super();

router.events.pipe(takeUntilDestroyed()).subscribe(event => {
if (event instanceof RouteConfigLoadStart) {
this.isLoadingRouteConfig = true;
Expand All @@ -57,7 +54,7 @@ export class NaturalLinkableTabDirective extends NaturalAbstractController imple
}

// When url params change, update the mat-tab-group selected tab
this.route.fragment.pipe(takeUntil(this.ngUnsubscribe)).subscribe(fragment => {
this.route.fragment.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(fragment => {
// Get index of tab that matches wanted name
const tabIndex = this.getTabIndex(fragment);

Expand All @@ -69,7 +66,7 @@ export class NaturalLinkableTabDirective extends NaturalAbstractController imple
});

// When mat-tab-groups selected tab change, update url
this.component.selectedTabChange.pipe(takeUntil(this.ngUnsubscribe)).subscribe(event => {
this.component.selectedTabChange.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(event => {
if (this.isLoadingRouteConfig) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import {AfterViewInit, Component, Inject, OnDestroy, ViewChild} from '@angular/core';
import {MatSelectionList, MatListModule} from '@angular/material/list';
import {AfterViewInit, Component, DestroyRef, inject, Inject, ViewChild} from '@angular/core';
import {MatListModule, MatSelectionList} from '@angular/material/list';
import {BehaviorSubject, merge, Observable, of} from 'rxjs';
import {FilterGroupConditionField, Scalar} from '../../search/classes/graphql-doctrine.types';
import {NATURAL_DROPDOWN_DATA, NaturalDropdownData} from '../../search/dropdown-container/dropdown.service';
import {DropdownComponent} from '../../search/types/dropdown-component';
import {FormControl, FormGroup, ValidatorFn, Validators, FormsModule, ReactiveFormsModule} from '@angular/forms';
import {NaturalAbstractController} from '../../../classes/abstract-controller';
import {map, startWith, takeUntil} from 'rxjs/operators';
import {FormControl, FormGroup, FormsModule, ReactiveFormsModule, ValidatorFn, Validators} from '@angular/forms';
import {map, startWith} from 'rxjs/operators';
import {PossibleDiscreteOperatorKeys, possibleDiscreteOperators} from '../types';
import {MatOptionModule} from '@angular/material/core';
import {MatSelectModule} from '@angular/material/select';
import {MatFormFieldModule} from '@angular/material/form-field';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

export type TypeSelectItem =
| Scalar
Expand All @@ -37,10 +37,8 @@ export type TypeSelectConfiguration = {
standalone: true,
imports: [FormsModule, ReactiveFormsModule, MatFormFieldModule, MatSelectModule, MatOptionModule, MatListModule],
})
export class TypeSelectComponent
extends NaturalAbstractController
implements DropdownComponent, AfterViewInit, OnDestroy
{
export class TypeSelectComponent implements DropdownComponent, AfterViewInit {
private readonly destroyRef = inject(DestroyRef);
public readonly renderedValue = new BehaviorSubject<string>('');
@ViewChild(MatSelectionList, {static: false}) public list!: MatSelectionList;
public requireValueCtrl = false;
Expand All @@ -62,7 +60,6 @@ export class TypeSelectComponent
};

public constructor(@Inject(NATURAL_DROPDOWN_DATA) data: NaturalDropdownData<TypeSelectConfiguration>) {
super();
this.configuration = {...this.defaults, ...data.configuration};

// Immediately initValidators and everytime the operator change later
Expand Down Expand Up @@ -156,7 +153,7 @@ export class TypeSelectComponent
: this.configuration.items;

return items$.pipe(
takeUntil(this.ngUnsubscribe),
takeUntilDestroyed(this.destroyRef),
map(items => {
this.items = items;

Expand Down
10 changes: 3 additions & 7 deletions projects/natural/src/lib/modules/file/abstract-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
stopEvent,
} from './utils';
import {NaturalFileService} from './file.service';
import {NaturalAbstractController} from '../../classes/abstract-controller';
import {DOCUMENT} from '@angular/common';
import {forkJoin, map, Observable, ObservableInput, of, tap} from 'rxjs';

Expand Down Expand Up @@ -53,7 +52,7 @@ export type FileSelection = {
* @dynamic
*/
@Directive({standalone: true})
export abstract class NaturalAbstractFile extends NaturalAbstractController implements OnInit, OnDestroy, OnChanges {
export abstract class NaturalAbstractFile implements OnInit, OnDestroy, OnChanges {
private fileElement?: HTMLInputElement;

/**
Expand Down Expand Up @@ -112,12 +111,9 @@ export abstract class NaturalAbstractFile extends NaturalAbstractController impl
private readonly element: ElementRef<HTMLElement>,
protected readonly naturalFileService: NaturalFileService,
@Inject(DOCUMENT) private readonly document: Document,
) {
super();
}
) {}

public override ngOnDestroy(): void {
super.ngOnDestroy();
public ngOnDestroy(): void {
delete this.fileElement; // faster memory release of dom element
}

Expand Down
8 changes: 5 additions & 3 deletions projects/natural/src/lib/modules/file/file-drop.directive.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {Directive, EventEmitter, HostBinding, HostListener, OnInit, Output} from '@angular/core';
import {DestroyRef, Directive, EventEmitter, HostBinding, HostListener, inject, OnInit, Output} from '@angular/core';
import {NaturalAbstractFile} from './abstract-file';
import {eventToFiles, stopEvent} from './utils';
import {asyncScheduler, Subject} from 'rxjs';
import {takeUntil, throttleTime} from 'rxjs/operators';
import {throttleTime} from 'rxjs/operators';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

/**
* This directive has all options to select files, and adds support for drag'n'drop.
Expand All @@ -22,6 +23,7 @@ import {takeUntil, throttleTime} from 'rxjs/operators';
standalone: true,
})
export class NaturalFileDropDirective extends NaturalAbstractFile implements OnInit {
private readonly destroyRef = inject(DestroyRef);
@HostBinding('class.natural-file-over') public fileOverClass = false;

/**
Expand All @@ -40,7 +42,7 @@ export class NaturalFileDropDirective extends NaturalAbstractFile implements OnI
// still see flicker, but it should be better for most normal usages.
this.rawFileOver
.pipe(
takeUntil(this.ngUnsubscribe),
takeUntilDestroyed(this.destroyRef),
throttleTime(200, asyncScheduler, {
leading: true,
trailing: true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import {SelectionModel} from '@angular/cdk/collections';
import {FlatTreeControl} from '@angular/cdk/tree';
import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core';
import {
Component,
DestroyRef,
EventEmitter,
inject,
Input,
OnChanges,
OnInit,
Output,
SimpleChanges,
} from '@angular/core';
import {MatTreeFlatDataSource, MatTreeFlattener, MatTreeModule} from '@angular/material/tree';
import {Observable} from 'rxjs';
import {finalize, takeUntil} from 'rxjs/operators';
import {NaturalAbstractController} from '../../../classes/abstract-controller';
import {finalize} from 'rxjs/operators';
import {QueryVariables} from '../../../classes/query-variable-manager';
import {Literal} from '../../../types/types';
import {toGraphQLDoctrineFilter} from '../../search/classes/graphql-doctrine';
Expand All @@ -24,6 +33,7 @@ import {MatButtonModule} from '@angular/material/button';
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
import {CommonModule} from '@angular/common';
import {NaturalSearchComponent} from '../../search/search/search.component';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';

@Component({
selector: 'natural-hierarchic-selector',
Expand All @@ -43,7 +53,8 @@ import {NaturalSearchComponent} from '../../search/search/search.component';
MatChipsModule,
],
})
export class NaturalHierarchicSelectorComponent extends NaturalAbstractController implements OnInit, OnChanges {
export class NaturalHierarchicSelectorComponent implements OnInit, OnChanges {
private readonly destroyRef = inject(DestroyRef);
/**
* Function that receives a model and returns a string for display value
*/
Expand Down Expand Up @@ -117,9 +128,7 @@ export class NaturalHierarchicSelectorComponent extends NaturalAbstractControlle
*/
private flatNodeMap: Map<string, HierarchicFlatNode> = new Map<string, HierarchicFlatNode>();

public constructor(private readonly hierarchicSelectorService: NaturalHierarchicSelectorService) {
super();
}
public constructor(private readonly hierarchicSelectorService: NaturalHierarchicSelectorService) {}

/**
* Angular OnChange implementation
Expand Down Expand Up @@ -157,7 +166,7 @@ export class NaturalHierarchicSelectorComponent extends NaturalAbstractControlle
// Update dataSource when receiving new list -> we assign the whole tree
// The treeControl and treeFlattener will generate the displayed tree
this.hierarchicSelectorService.dataChange
.pipe(takeUntil(this.ngUnsubscribe))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(data => (this.dataSource.data = data));

// Prevent empty screen on first load and init NaturalHierarchicSelectorService with inputted configuration
Expand Down
Loading

0 comments on commit 1fd56a8

Please sign in to comment.