Listing component refactor

This commit is contained in:
Dan Percic 2023-01-05 16:03:46 +02:00
parent 27c765f6bd
commit 7a75e1fa7f
7 changed files with 25 additions and 27 deletions

View File

@ -21,8 +21,7 @@ import { MatLegacyCheckboxModule as MatCheckboxModule } from '@angular/material/
import { MatLegacyProgressBarModule as MatProgressBarModule } from '@angular/material/legacy-progress-bar'; import { MatLegacyProgressBarModule as MatProgressBarModule } from '@angular/material/legacy-progress-bar';
import { ConfirmationDialogComponent } from './dialog'; import { ConfirmationDialogComponent } from './dialog';
import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip'; import { MatLegacyTooltipModule as MatTooltipModule } from '@angular/material/legacy-tooltip';
import { ApiPathInterceptor, IqserConfigService, IqserUserPreferenceService } from './services'; import { ApiPathInterceptor, DefaultUserPreferenceService, IqserConfigService, IqserUserPreferenceService } from './services';
import { DefaultUserPreferenceService } from './services/default-user-preference.service';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http'; import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { IqserSkeletonModule } from './skeleton/skeleton.module'; import { IqserSkeletonModule } from './skeleton/skeleton.module';

View File

@ -20,7 +20,9 @@ export abstract class ListingComponent<Class extends IListable<PrimaryKey>, Prim
readonly entitiesService = inject<EntitiesService<Class, Class>>(EntitiesService); readonly entitiesService = inject<EntitiesService<Class, Class>>(EntitiesService);
readonly listingService = inject<ListingService<Class>>(ListingService); readonly listingService = inject<ListingService<Class>>(ListingService);
// TODO: Move to table content component
readonly noMatch$ = this.#noMatch$; readonly noMatch$ = this.#noMatch$;
// TODO: Move to table content component
readonly noContent$ = this.#noContent$; readonly noContent$ = this.#noContent$;
readonly sortedDisplayedEntities$ = this.#sortedDisplayedEntities$; readonly sortedDisplayedEntities$ = this.#sortedDisplayedEntities$;
@ -50,17 +52,12 @@ export abstract class ListingComponent<Class extends IListable<PrimaryKey>, Prim
} }
get #noContent$(): Observable<boolean> { get #noContent$(): Observable<boolean> {
return combineLatest([this.#noMatch$, this.entitiesService.noData$]).pipe( return combineLatest([this.noMatch$, this.entitiesService.noData$]).pipe(
map(([noMatch, noData]) => noMatch || noData), map(([noMatch, noData]) => noMatch || noData),
shareDistinctLast(), shareDistinctLast(),
); );
} }
toggleEntitySelected(event: MouseEvent, entity: Class): void {
event.stopPropagation();
this.listingService.select(entity);
}
cast(entity: unknown): Class { cast(entity: unknown): Class {
return entity as Class; return entity as Class;
} }

View File

@ -1,4 +1,4 @@
<div (click)="listingComponent.toggleEntitySelected($event, entity)" *ngIf="selectionEnabled" class="selection-column"> <div (click)="toggleEntitySelected($event, entity)" *ngIf="selectionEnabled" class="selection-column">
<iqser-round-checkbox [active]="isSelected$ | async"></iqser-round-checkbox> <iqser-round-checkbox [active]="isSelected$ | async"></iqser-round-checkbox>
</div> </div>

View File

@ -6,7 +6,7 @@ import { ListingService } from '../../services';
import { switchMap } from 'rxjs/operators'; import { switchMap } from 'rxjs/operators';
@Component({ @Component({
selector: 'iqser-table-item', selector: 'iqser-table-item [entity]',
templateUrl: './table-item.component.html', templateUrl: './table-item.component.html',
styleUrls: ['./table-item.component.scss'], styleUrls: ['./table-item.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
@ -15,17 +15,22 @@ export class TableItemComponent<T extends IListable> implements OnChanges {
@Input() entity!: T; @Input() entity!: T;
@Input() selectionEnabled = false; @Input() selectionEnabled = false;
isSelected$!: Observable<boolean>; readonly isSelected$: Observable<boolean>;
private readonly _entityChanged$ = new BehaviorSubject<T>(this.entity); readonly #entityChanged$ = new BehaviorSubject<T>(this.entity);
constructor( constructor(
@Inject(forwardRef(() => ListingComponent)) readonly listingComponent: ListingComponent<T>, @Inject(forwardRef(() => ListingComponent)) readonly listingComponent: ListingComponent<T>,
readonly listingService: ListingService<T>, readonly listingService: ListingService<T>,
) { ) {
this.isSelected$ = this._entityChanged$.pipe(switchMap(entity => this.listingService.isSelected$(entity))); this.isSelected$ = this.#entityChanged$.pipe(switchMap(entity => this.listingService.isSelected$(entity)));
} }
ngOnChanges(): void { ngOnChanges(): void {
this._entityChanged$.next(this.entity); this.#entityChanged$.next(this.entity);
}
toggleEntitySelected(event: MouseEvent, entity: T): void {
event.stopPropagation();
this.listingService.select(entity);
} }
} }

View File

@ -1,9 +0,0 @@
import { inject, Injectable } from '@angular/core';
import { BASE_HREF } from '../utils';
import { IqserUserPreferenceService } from './iqser-user-preference.service';
@Injectable()
export class DefaultUserPreferenceService extends IqserUserPreferenceService {
protected readonly _defaultModelPath = 'attributes';
protected readonly _devFeaturesEnabledKey = inject(BASE_HREF) + '.enable-dev-features';
}

View File

@ -42,8 +42,8 @@ export abstract class DialogService<T extends string> {
type: T, type: T,
$event: MouseEvent, $event: MouseEvent,
data: unknown, data: unknown,
cb?: (...params: unknown[]) => Promise<unknown> | unknown, cb?: (...params: unknown[]) => Promise<unknown> | void,
finallyCb?: (...params: unknown[]) => unknown | Promise<unknown>, finallyCb?: (...params: unknown[]) => void | Promise<unknown>,
): MatDialogRef<unknown> { ): MatDialogRef<unknown> {
const config = this._config[type]; const config = this._config[type];

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { inject, Injectable } from '@angular/core';
import { firstValueFrom } from 'rxjs'; import { firstValueFrom } from 'rxjs';
import { List, RequiredParam, Validate } from '../utils'; import { BASE_HREF, List, RequiredParam, Validate } from '../utils';
import { GenericService } from './generic.service'; import { GenericService } from './generic.service';
export type UserAttributes = Record<string, List>; export type UserAttributes = Record<string, List>;
@ -68,3 +68,9 @@ export abstract class IqserUserPreferenceService extends GenericService<UserAttr
return defaultValue; return defaultValue;
} }
} }
@Injectable()
export class DefaultUserPreferenceService extends IqserUserPreferenceService {
protected readonly _defaultModelPath = 'attributes';
protected readonly _devFeaturesEnabledKey = inject(BASE_HREF) + '.enable-dev-features';
}