Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions projects/components/src/load-async/load-async.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
ViewContainerRef
} from '@angular/core';
import { Observable, ReplaySubject } from 'rxjs';
import { LoadAsyncContext, LoadAsyncService } from './load-async.service';
import { LoadAsyncContext, LoadAsyncCustomConfig, LoadAsyncService } from './load-async.service';
import {
ASYNC_WRAPPER_PARAMETERS$,
LoadAsyncWrapperComponent,
Expand All @@ -23,6 +23,10 @@ import {
export class LoadAsyncDirective implements OnChanges, OnDestroy {
@Input('htLoadAsync')
public data$?: Observable<unknown>;

// tslint:disable-next-line:no-input-rename
@Input('htLoadAsyncCustomConfigs')
public customConfigs: LoadAsyncCustomConfig[] = [];
private readonly wrapperParamsSubject: ReplaySubject<LoadAsyncWrapperParameters> = new ReplaySubject(1);
private readonly wrapperInjector: Injector;
private wrapperView?: ComponentRef<LoadAsyncWrapperComponent>;
Expand All @@ -48,7 +52,7 @@ export class LoadAsyncDirective implements OnChanges, OnDestroy {
if (this.data$) {
this.wrapperView = this.wrapperView || this.buildWrapperView();
this.wrapperParamsSubject.next({
state$: this.loadAsyncService.mapObservableState(this.data$),
state$: this.loadAsyncService.mapObservableState(this.data$, this.customConfigs),
content: this.templateRef
});
} else {
Expand Down
14 changes: 13 additions & 1 deletion projects/components/src/load-async/load-async.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ import { LoadAsyncStateType } from './load-async-state.type';

@Injectable({ providedIn: 'root' })
export class LoadAsyncService {
public mapObservableState(data$: Observable<unknown>): Observable<AsyncState> {
public mapObservableState(
data$: Observable<unknown>,
customConfigs: LoadAsyncCustomConfig[]
): Observable<AsyncState> {
return data$.pipe(
map(data => this.buildStateForEmittedData(data)),
defaultIfEmpty(this.buildNoDataState()),
catchError(error => of(this.buildStateForEmittedError(error))),
map(data => ({ ...data, message: customConfigs.find(config => config.stateType === data.type)?.message })),
startWith({ type: LoadAsyncStateType.Loading })
);
}
Expand Down Expand Up @@ -54,14 +58,22 @@ export type AsyncState = ErrorAsyncState | SuccessAsyncState | LoadingAsyncState

interface LoadingAsyncState {
type: LoadAsyncStateType.Loading;
message?: string;
}

interface SuccessAsyncState {
type: LoadAsyncStateType.Success;
message?: string;
context: LoadAsyncContext;
}

export interface ErrorAsyncState {
type: LoadAsyncStateType.GenericError | LoadAsyncStateType.NoData;
message?: string;
description?: string;
}

export interface LoadAsyncCustomConfig {
stateType: LoadAsyncStateType;
message: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,22 @@ export class LoadAsyncWrapperComponent {
this.state$ = parameters$.pipe(
tap(params => (this.content = params.content)),
switchMap(parameter => parameter.state$),
tap(state => this.updateMessage(state.type, (state as Partial<ErrorAsyncState>).description))
tap(state => this.updateMessage(state.type, state.message, (state as Partial<ErrorAsyncState>).description))
);
}

private updateMessage(stateType: LoadAsyncStateType, description: string = ''): void {
private updateMessage(stateType: LoadAsyncStateType, message?: string, description: string = ''): void {
this.description = description;

switch (stateType) {
case LoadAsyncStateType.NoData:
this.icon = IconType.NoData;
this.title = 'No Data';
this.title = message ?? 'No Data';
break;
case LoadAsyncStateType.GenericError:
default:
this.icon = IconType.Error;
this.title = 'Error';
this.title = message ?? 'Error';
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions projects/components/src/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ export * from './list-view/list-view.module';
// Load Async
export { LoadAsyncDirective } from './load-async/load-async.directive';
export { LoadAsyncModule } from './load-async/load-async.module';
export { LoadAsyncCustomConfig } from './load-async/load-async.service';
export { LoadAsyncStateType } from './load-async/load-async-state.type';

// Message Display
export { MessageDisplayComponent } from './message-display/message-display.component';
Expand Down
2 changes: 2 additions & 0 deletions projects/components/src/table/data/table-data-source.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Observable } from 'rxjs';
import { LoadAsyncCustomConfig } from '../../load-async/load-async.service';
import { TableColumnConfig, TableFilter, TableSortDirection } from '../table-api';

export interface TableDataSource<TResult, TCol extends TableColumnConfig = TableColumnConfig> {
getData(request: TableDataRequest<TCol>): Observable<TableDataResponse<TResult>>;
getScope?(): string | undefined;
getCustomLoadingConfigs?(): LoadAsyncCustomConfig[];
}

export interface TableDataRequest<TCol extends TableColumnConfig = TableColumnConfig> {
Expand Down
9 changes: 8 additions & 1 deletion projects/components/src/table/table.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { without } from 'lodash-es';
import { BehaviorSubject, combineLatest, merge, Observable, Subject } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import { FilterAttribute } from '../filtering/filter/filter-attribute';
import { LoadAsyncCustomConfig } from '../load-async/load-async.service';
import { PageEvent } from '../paginator/page.event';
import { PaginatorComponent } from '../paginator/paginator.component';
import { CoreTableCellRendererType } from './cells/types/core-table-cell-renderer-type';
Expand Down Expand Up @@ -162,7 +163,10 @@ import { TableColumnConfigExtended, TableService } from './table.service';
<!-- State Watcher -->
<ng-container *ngIf="this.dataSource?.loadingStateChange$ | async as loadingState">
<div class="state-watcher" *ngIf="!loadingState.hide">
<ng-container class="state-watcher" *htLoadAsync="loadingState.loading$"></ng-container>
<ng-container
class="state-watcher"
*htLoadAsync="loadingState.loading$; customConfigs: this.customLoadingConfigs"
></ng-container>
</div>
</ng-container>

Expand Down Expand Up @@ -272,6 +276,9 @@ export class TableComponent
@Input()
public pageSize?: number = 50;

@Input()
public customLoadingConfigs?: LoadAsyncCustomConfig;

@Output()
public readonly rowClicked: EventEmitter<StatefulTableRow> = new EventEmitter<StatefulTableRow>();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { CoreTableCellRendererType, TableMode, TableSortDirection, TableStyle } from '@hypertrace/components';
import {
CoreTableCellRendererType,
LoadAsyncStateType,
TableMode,
TableSortDirection,
TableStyle
} from '@hypertrace/components';
import { ObservabilityTableCellType } from '../../../shared/components/table/observability-table-cell-type';
import { TracingTableCellType } from '../../../shared/components/table/tracing-table-cell-type';
import { DashboardDefaultConfiguration } from '../../../shared/dashboard/dashboard-wrapper/navigable-dashboard.module';
Expand All @@ -20,6 +26,12 @@ export const endpointListDashboard: DashboardDefaultConfiguration = {
mode: TableMode.Flat,
style: TableStyle.FullPage,
searchAttribute: 'name',
customLoadingConfigs: [
{
stateType: LoadAsyncStateType.GenericError,
message: 'This is the custom error.'
}
],
'select-control-options': [
{
type: 'table-widget-select-option',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { TableDataSource, TableMode, TableRow, TableSelectionMode, TableStyle } from '@hypertrace/components';
import {
LoadAsyncCustomConfig,
TableDataSource,
TableMode,
TableRow,
TableSelectionMode,
TableStyle
} from '@hypertrace/components';
import {
ArrayPropertyTypeInstance,
BaseModel,
Expand Down Expand Up @@ -111,6 +118,13 @@ export abstract class TableWidgetBaseModel extends BaseModel {
})
public resizable: boolean = true;

@ModelProperty({
key: 'customLoadingConfigs',
required: false,
type: ARRAY_PROPERTY.type
})
public customLoadingConfigs?: LoadAsyncCustomConfig[];

@ModelInject(MODEL_API)
protected readonly api!: ModelApi;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import { TableWidgetModel } from './table-widget.model';
[selectionMode]="this.model.getSelectionMode()"
[display]="this.model.style"
[data]="this.data$ | async"
[customLoadingConfigs]="this.api.model.customLoadingConfigs"
[filters]="this.combinedFilters$ | async"
[queryProperties]="this.queryProperties$ | async"
[pageable]="this.api.model.isPageable()"
Expand Down