Listing component refactor
This commit is contained in:
parent
27c765f6bd
commit
7a75e1fa7f
@ -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';
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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>
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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';
|
|
||||||
}
|
|
||||||
@ -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];
|
||||||
|
|
||||||
|
|||||||
@ -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';
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user