add listing component
This commit is contained in:
parent
6b0cbc09f2
commit
c552ed2e21
@ -1,8 +1,8 @@
|
||||
export * from './lib/common-ui.module';
|
||||
export * from './lib/base/auto-unsubscribe.component';
|
||||
export * from './lib/buttons/icon-button/icon-button.type';
|
||||
export * from './lib/buttons/icon-button/icon-button.component';
|
||||
export * from './lib/utils/functions';
|
||||
export * from './lib/utils/auto-unsubscribe.directive';
|
||||
export * from './lib/utils/pipes/humanize.pipe';
|
||||
export * from './lib/utils/types/utility-types';
|
||||
export * from './lib/utils/types/tooltip-positions.type';
|
||||
@ -21,5 +21,6 @@ export * from './lib/sorting/models/sorting-option.model';
|
||||
export * from './lib/sorting/models/sorting-order.type';
|
||||
export * from './lib/search/search.service';
|
||||
export * from './lib/tables/entities.service';
|
||||
export * from './lib/tables/listing-component.directive';
|
||||
export * from './lib/tables/models/table-column-config.model';
|
||||
export * from './lib/tables/table-column-name/table-column-name.component';
|
||||
|
||||
@ -57,10 +57,10 @@ export class FilterService {
|
||||
}
|
||||
|
||||
getFilterModels$(filterGroupSlug: string): Observable<NestedFilter[] | undefined> {
|
||||
return this.getFilterGroup$(filterGroupSlug).pipe(map(f => f?.filters));
|
||||
return this.getGroup$(filterGroupSlug).pipe(map(f => f?.filters));
|
||||
}
|
||||
|
||||
getFilterGroup$(slug: string): Observable<FilterGroup | undefined> {
|
||||
getGroup$(slug: string): Observable<FilterGroup | undefined> {
|
||||
return this.filterGroups$.pipe(map(all => all.find(f => f.slug === slug)));
|
||||
}
|
||||
|
||||
|
||||
77
src/lib/tables/listing-component.directive.ts
Normal file
77
src/lib/tables/listing-component.directive.ts
Normal file
@ -0,0 +1,77 @@
|
||||
import { Directive, Injector, OnDestroy, Provider } from '@angular/core';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { distinctUntilChanged, map, switchMap } from 'rxjs/operators';
|
||||
import { FilterService } from '../filtering/filter.service';
|
||||
import { SortingService } from '../sorting/sorting.service';
|
||||
import { SortingOrders } from '../sorting/models/sorting-order.type';
|
||||
import { Bind } from '../utils/decorators/bind.decorator';
|
||||
import { AutoUnsubscribe } from '../utils/auto-unsubscribe.directive';
|
||||
import { SearchService } from '../search/search.service';
|
||||
import { KeysOf } from '../utils/types/utility-types';
|
||||
import { TableColumnConfig } from './models/table-column-config.model';
|
||||
import { EntitiesService } from './entities.service';
|
||||
|
||||
export const DefaultListingServices = new Set<Provider>().add(FilterService).add(SearchService).add(EntitiesService).add(SortingService);
|
||||
|
||||
@Directive()
|
||||
export abstract class ListingComponent<T extends object> extends AutoUnsubscribe implements OnDestroy {
|
||||
readonly filterService = this._injector.get(FilterService);
|
||||
readonly searchService = this._injector.get<SearchService<T>>(SearchService);
|
||||
readonly sortingService = this._injector.get<SortingService<T>>(SortingService);
|
||||
readonly entitiesService = this._injector.get<EntitiesService<T>>(EntitiesService);
|
||||
|
||||
readonly noMatch$ = this._noMatch$;
|
||||
readonly sortedDisplayedEntities$ = this._sortedDisplayedEntities$;
|
||||
|
||||
abstract readonly tableColumnConfigs: TableColumnConfig<T>[];
|
||||
/**
|
||||
* Key used in the *trackBy* function with **ngFor* or **cdkVirtualFor*
|
||||
* and in the default sorting and as the search field
|
||||
* @protected
|
||||
*/
|
||||
protected abstract readonly _primaryKey: KeysOf<T>;
|
||||
|
||||
protected constructor(protected readonly _injector: Injector) {
|
||||
super();
|
||||
setTimeout(() => this.setInitialConfig());
|
||||
}
|
||||
|
||||
get allEntities(): T[] {
|
||||
return this.entitiesService.all;
|
||||
}
|
||||
|
||||
private get _sortedDisplayedEntities$(): Observable<readonly T[]> {
|
||||
const sort = (entities: T[]) => this.sortingService.defaultSort(entities);
|
||||
const sortedEntities = () => this.entitiesService.displayed$.pipe(map(sort));
|
||||
return this.sortingService.sortingOption$.pipe(switchMap(sortedEntities));
|
||||
}
|
||||
|
||||
private get _noMatch$(): Observable<boolean> {
|
||||
return combineLatest([this.entitiesService.allLength$, this.entitiesService.displayedLength$]).pipe(
|
||||
map(([hasEntities, hasDisplayedEntities]) => !!hasEntities && !hasDisplayedEntities),
|
||||
distinctUntilChanged()
|
||||
);
|
||||
}
|
||||
|
||||
setInitialConfig() {
|
||||
this.sortingService.setSortingOption({
|
||||
column: this._primaryKey,
|
||||
order: SortingOrders.asc
|
||||
});
|
||||
this.searchService.setSearchKey(this._primaryKey);
|
||||
}
|
||||
|
||||
toggleEntitySelected(event: MouseEvent, entity: T) {
|
||||
event.stopPropagation();
|
||||
return this.entitiesService.select(entity);
|
||||
}
|
||||
|
||||
isSelected(entity: T): boolean {
|
||||
return this.entitiesService.isSelected(entity);
|
||||
}
|
||||
|
||||
@Bind()
|
||||
trackByPrimaryKey(index: number, item: T) {
|
||||
return item[this._primaryKey];
|
||||
}
|
||||
}
|
||||
@ -5,7 +5,7 @@ import { Subscription } from "rxjs";
|
||||
* Inherit this class when you need to subscribe to observables in your components
|
||||
*/
|
||||
@Directive()
|
||||
export abstract class AutoUnsubscribeComponent implements OnDestroy {
|
||||
export abstract class AutoUnsubscribe implements OnDestroy {
|
||||
private readonly _subscriptions = new Subscription();
|
||||
|
||||
/**
|
||||
Loading…
x
Reference in New Issue
Block a user