Browse Source

add loading container component

pull/18597/head
Mahmut Gundogdu 2 years ago
parent
commit
b9f387b0fa
  1. 119
      npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html
  2. 11
      npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts
  3. 20
      npm/ng-packs/packages/theme-shared/src/lib/components/loading/loading.component.ts
  4. 18
      npm/ng-packs/packages/theme-shared/src/lib/directives/loading.directive.ts
  5. 4
      npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts
  6. 1
      npm/ng-packs/packages/theme-shared/src/lib/tokens/index.ts
  7. 3
      npm/ng-packs/packages/theme-shared/src/lib/tokens/loading-container.token.ts

119
npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html

@ -1,66 +1,69 @@
<ngx-datatable
default
[rows]="data"
[count]="recordsTotal"
[list]="list"
(activate)="tableActivate.emit($event)"
>
@if (actionsTemplate || (actionList.length && hasAtLeastOnePermittedAction)) {
<ngx-datatable-column
[name]="actionsText | abpLocalization"
[maxWidth]="columnWidths[0]"
[width]="columnWidths[0]"
[sortable]="false"
<abp-loading-container [loading]="loading$ | async">
<ngx-datatable
default
[rows]="data"
[count]="recordsTotal"
[list]="list"
(activate)="tableActivate.emit($event)"
>
<ng-template let-row="row" let-i="rowIndex" ngx-datatable-cell-template>
<ng-container
*ngTemplateOutlet="actionsTemplate || gridActions; context: { $implicit: row, index: i }"
></ng-container>
<ng-template #gridActions>
<abp-grid-actions [index]="i" [record]="row" text="AbpUi::Actions"></abp-grid-actions>
</ng-template>
</ng-template>
</ngx-datatable-column>
} @for (prop of propList; track prop.name; let i = $index) {
<ngx-datatable-column
*abpVisible="prop.columnVisible(getInjected)"
[width]="columnWidths[i + 1] || 200"
[name]="prop.displayName | abpLocalization"
[prop]="prop.name"
[sortable]="prop.sortable"
>
<ng-template ngx-datatable-header-template let-column="column">
@if (prop.tooltip) {
<span [ngbTooltip]="prop.tooltip | abpLocalization" container="body">
@if (actionsTemplate || (actionList.length && hasAtLeastOnePermittedAction)) {
<ngx-datatable-column
[name]="actionsText | abpLocalization"
[maxWidth]="columnWidths[0]"
[width]="columnWidths[0]"
[sortable]="false"
>
<ng-template let-row="row" let-i="rowIndex" ngx-datatable-cell-template>
<ng-container
*ngTemplateOutlet="actionsTemplate || gridActions; context: { $implicit: row, index: i }"
></ng-container>
<ng-template #gridActions>
<abp-grid-actions [index]="i" [record]="row" text="AbpUi::Actions"></abp-grid-actions>
</ng-template>
</ng-template>
</ngx-datatable-column>
}
@for (prop of propList;track prop.name;let i = $index) {
<ngx-datatable-column
*abpVisible="prop.columnVisible(getInjected)"
[width]="columnWidths[i + 1] || 200"
[name]="prop.displayName | abpLocalization"
[prop]="prop.name"
[sortable]="prop.sortable"
>
<ng-template ngx-datatable-header-template let-column="column">
@if (prop.tooltip) {
<span [ngbTooltip]="prop.tooltip | abpLocalization" container="body">
{{ column.name }} <i class="fa fa-info-circle" aria-hidden="true"></i>
</span>
}@else{
{{ column.name }}
}
</ng-template>
<ng-template let-row="row" let-i="index" ngx-datatable-cell-template>
<ng-container *abpPermission="prop.permission; runChangeDetection: false">
<ng-container *abpVisible="row['_' + prop.name]?.visible">
@if (!row['_' + prop.name].component) {
<div
[innerHTML]="row['_' + prop.name]?.value | async"
(click)="
} @else {
{{ column.name }}
}
</ng-template>
<ng-template let-row="row" let-i="index" ngx-datatable-cell-template>
<ng-container *abpPermission="prop.permission; runChangeDetection: false">
<ng-container *abpVisible="row['_' + prop.name]?.visible">
@if (!row['_' + prop.name].component) {
<div
[innerHTML]="row['_' + prop.name]?.value | async"
(click)="
prop.action && prop.action({ getInjected: getInjected, record: row, index: i })
"
[ngClass]="entityPropTypeClasses[prop.type]"
[class.pointer]="prop.action"
></div>
}@else{
<ng-container
*ngComponentOutlet="
[ngClass]="entityPropTypeClasses[prop.type]"
[class.pointer]="prop.action"
></div>
} @else {
<ng-container
*ngComponentOutlet="
row['_' + prop.name].component;
injector: row['_' + prop.name].injector
"
></ng-container>
}
</ng-container>
</ng-container>
</ng-template>
</ngx-datatable-column>
}
</ngx-datatable>
></ng-container>
}
</ng-container>
</ng-container>
</ng-template>
</ngx-datatable-column>
}
</ngx-datatable>
</abp-loading-container>

11
npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts

@ -32,7 +32,7 @@ import {
TemplateRef,
TrackByFunction,
} from '@angular/core';
import { Observable } from 'rxjs';
import {EMPTY, Observable} from 'rxjs';
import { map } from 'rxjs/operators';
import { ePropType } from '../../enums/props.enum';
import { EntityActionList } from '../../models/entity-actions';
@ -50,7 +50,7 @@ import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap';
import {
AbpVisibleDirective,
NgxDatatableDefaultDirective,
NgxDatatableListDirective,
NgxDatatableListDirective, ThemeSharedModule,
} from '@abp/ng.theme.shared';
const DEFAULT_ACTIONS_COLUMN_WIDTH = 150;
@ -71,6 +71,7 @@ const DEFAULT_ACTIONS_COLUMN_WIDTH = 150;
AsyncPipe,
NgTemplateOutlet,
NgComponentOutlet,
ThemeSharedModule,
],
templateUrl: './extensible-table.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
@ -113,6 +114,7 @@ export class ExtensibleTableComponent<R = any> implements OnChanges {
entityPropTypeClasses = inject(ENTITY_PROP_TYPE_CLASSES);
#injector = inject(Injector);
getInjected = this.#injector.get.bind(this.#injector);
loading$:Observable<boolean> = EMPTY
constructor() {
const extensions = this.#injector.get(ExtensionsService);
@ -121,6 +123,8 @@ export class ExtensibleTableComponent<R = any> implements OnChanges {
this.actionList = extensions['entityActions'].get(name)
.actions as unknown as EntityActionList<R>;
const permissionService = this.#injector.get(PermissionService);
this.hasAtLeastOnePermittedAction =
permissionService.filterItemsByPolicy(
@ -181,6 +185,9 @@ export class ExtensibleTableComponent<R = any> implements OnChanges {
if (data.currentValue.length < 1) {
this.list.totalCount = this.recordsTotal;
}
if(this.list){
this.loading$ = this.list.isLoading$;
}
this.data = data.currentValue.map((record: any, index: number) => {
this.propList.forEach(prop => {

20
npm/ng-packs/packages/theme-shared/src/lib/components/loading/loading.component.ts

@ -4,7 +4,9 @@ import { Component, ViewEncapsulation } from '@angular/core';
selector: 'abp-loading',
template: `
<div class="abp-loading">
<i class="fa fa-spinner fa-pulse abp-spinner" aria-hidden="true"></i>
<div class="spinner-border" role="status">
<span class="visually-hidden">{{"AbpUi::LoadingWithThreeDot" | abpLocalization}}</span>
</div>
</div>
`,
encapsulation: ViewEncapsulation.None,
@ -17,18 +19,10 @@ import { Component, ViewEncapsulation } from '@angular/core';
top: 0;
left: 0;
z-index: 1040;
}
.abp-loading .abp-spinner {
position: absolute;
top: 50%;
left: 50%;
font-size: 14px;
-moz-transform: translateX(-50%) translateY(-50%);
-o-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
background: rgba(0,0,0,0.5);
display: flex;
justify-content: center;
align-items: center;
}
`,
],

18
npm/ng-packs/packages/theme-shared/src/lib/directives/loading.directive.ts

@ -12,11 +12,11 @@ import {
Renderer2,
ViewContainerRef,
} from '@angular/core';
import { Subscription, timer } from 'rxjs';
import { take } from 'rxjs/operators';
import { LoadingComponent } from '../components/loading/loading.component';
import {Subscription, timer} from 'rxjs';
import {take} from 'rxjs/operators';
import {LoadingComponent} from '../components/loading/loading.component';
@Directive({ selector: '[abpLoading]' })
@Directive({selector: '[abpLoading]'})
export class LoadingDirective implements OnInit, OnDestroy {
private _loading!: boolean;
@ -46,9 +46,7 @@ export class LoadingDirective implements OnInit, OnDestroy {
.pipe(take(1))
.subscribe(() => {
if (!this.componentRef) {
this.componentRef = this.cdRes
.resolveComponentFactory(LoadingComponent)
.create(this.injector);
this.componentRef = this.vcRef.createComponent(LoadingComponent, {injector: this.injector})
}
if (newValue && !this.rootNode) {
@ -78,14 +76,14 @@ export class LoadingDirective implements OnInit, OnDestroy {
constructor(
private elRef: ElementRef<HTMLElement>,
private vcRef: ViewContainerRef,
private cdRes: ComponentFactoryResolver,
private injector: Injector,
private renderer: Renderer2,
) {}
) {
}
ngOnInit() {
if (!this.targetElement) {
const { offsetHeight, offsetWidth } = this.elRef.nativeElement;
const {offsetHeight, offsetWidth} = this.elRef.nativeElement;
if (!offsetHeight && !offsetWidth && this.elRef.nativeElement.children.length) {
this.targetElement = this.elRef.nativeElement.children[0] as HTMLElement;
} else {

4
npm/ng-packs/packages/theme-shared/src/lib/theme-shared.module.ts

@ -41,6 +41,7 @@ import { AbpVisibleDirective, DisabledDirective } from './directives';
import { FormInputComponent } from './components/form-input/form-input.component';
import { FormCheckboxComponent } from './components/checkbox/checkbox.component';
import { tenantNotFoundProvider } from './providers/tenant-not-found.provider';
import {LoadingContainerComponent} from "./components/loading/loading-container.component";
const declarationsWithExports = [
BreadcrumbComponent,
@ -48,7 +49,6 @@ const declarationsWithExports = [
ButtonComponent,
ConfirmationComponent,
LoaderBarComponent,
LoadingComponent,
ModalComponent,
ToastComponent,
ToastContainerComponent,
@ -56,6 +56,8 @@ const declarationsWithExports = [
ModalCloseDirective,
FormInputComponent,
FormCheckboxComponent,
LoadingComponent,
LoadingContainerComponent
];
@NgModule({

1
npm/ng-packs/packages/theme-shared/src/lib/tokens/index.ts

@ -2,3 +2,4 @@ export * from './append-content.token';
export * from './http-error.token';
export * from './ngx-datatable-messages.token';
export * from './suppress-unsaved-changes-warning.token';
export * from './loading-container.token'

3
npm/ng-packs/packages/theme-shared/src/lib/tokens/loading-container.token.ts

@ -0,0 +1,3 @@
import { InjectionToken } from "@angular/core";
export const DISABLE_LOADING_COMPONENT_TOKEN = new InjectionToken<boolean>('DISABLE_LOADING_COMPONENT_TOKEN')
Loading…
Cancel
Save