code cleanup, names refactoring
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {DataGridComponent} from './data-grid/data-grid.component';
|
||||
import {DataGridColDirective} from './directives/data-grid-col.directive';
|
||||
import {DataGridColHeaderDirective} from './directives/data-grid-col-header.directive';
|
||||
import {DataGridCellDirective} from './directives/data-grid-cell.directive';
|
||||
import {DataGridFooterDirective} from './directives/data-grid-footer.directive';
|
||||
import {DataGridHeaderDirective} from './directives/data-grid-header.directive';
|
||||
import {DataGridLoaderDirective} from './directives/data-grid-loader.directive';
|
||||
import {DataGridCellFilterDirective} from './directives/data-grid-cell-filter.directive';
|
||||
import {DataGridColSortDirective} from './directives/data-grid-col-sort.directive';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
DataGridComponent,DataGridColDirective,DataGridColHeaderDirective,
|
||||
DataGridCellDirective, DataGridFooterDirective, DataGridHeaderDirective,
|
||||
DataGridLoaderDirective, DataGridCellFilterDirective, DataGridColSortDirective,
|
||||
|
||||
],
|
||||
imports: [
|
||||
CommonModule
|
||||
],
|
||||
exports: [
|
||||
DataGridComponent,DataGridColDirective,DataGridColHeaderDirective,
|
||||
DataGridCellDirective,DataGridFooterDirective, DataGridHeaderDirective,
|
||||
DataGridLoaderDirective,DataGridCellFilterDirective,DataGridColSortDirective]
|
||||
})
|
||||
export class DataGridModule { }
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
<ng-container *ngIf="loading" [ngTemplateOutlet]="loadingTemplate"></ng-container>
|
||||
|
||||
<table [ngClass]="tableClasses">
|
||||
<thead [ngClass]="headerClasses">
|
||||
<tr *ngFor="let header of gridHeaders" >
|
||||
<th [attr.colspan]="columns.length">
|
||||
<ng-container [ngTemplateOutlet]="header.template"></ng-container>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th *ngFor="let column of columns">
|
||||
<div class="flex-container">
|
||||
<div class="flex-item">
|
||||
<ng-container *ngIf="hasHeaderTemplate(column)" >
|
||||
<ng-container
|
||||
[ngTemplateOutlet]="getColumnHeaderTemplate(column)"
|
||||
></ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<div class="flex-item">
|
||||
|
||||
<ng-container *ngIf="hasSortingTemplate(column)">
|
||||
<ng-container [ngTemplateOutlet]="getSortingTemplate(column)"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="hasFilterTemplate(column)">
|
||||
<ng-container [ngTemplateOutlet]="getFilterTemplate(column)"></ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody *ngIf="!noData else noResultTemplate">
|
||||
<tr *ngFor="let rowModel of latestResult.data; let i = index; let first = first; let last = last; let odd = odd">
|
||||
<td *ngFor="let column of columns">
|
||||
<ng-container *ngIf="hasCellTemplate(column)">
|
||||
<ng-container
|
||||
[ngTemplateOutlet]="getColumnCellTemplate(column)"
|
||||
[ngTemplateOutletContext]="{
|
||||
$implicit: rowModel,
|
||||
column: column,
|
||||
rowIndex: i,
|
||||
first: first,
|
||||
last: last,
|
||||
odd: odd
|
||||
}"
|
||||
></ng-container>
|
||||
</ng-container>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td *ngFor="let footer of gridFooters" [attr.colspan]="columns.length">
|
||||
<ng-container [ngTemplateOutlet]="footer.template"></ng-container>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<ng-template #loadingTemplate>
|
||||
<ng-container *ngFor="let loader of loaders">
|
||||
<ng-container [ngTemplateOutlet]="loader.template"></ng-container>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
<ng-template #noResultTemplate>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td [attr.colspan]="columns.length">
|
||||
<p style="text-align: center;">{{ noRecordsDisplayText }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</ng-template>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
:host {
|
||||
.flex-container{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex-item{
|
||||
margin-right: 1px;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ContentChildren,
|
||||
EventEmitter, Inject,
|
||||
Input,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
Output,
|
||||
QueryList
|
||||
} from '@angular/core';
|
||||
import {IDataSource, IQueryExecutionGroupResult, IQueryExecutionResult} from '@poweredsoft/data';
|
||||
import {DataGridColDirective} from '../directives/data-grid-col.directive';
|
||||
import {DataGridHeaderDirective} from '../directives/data-grid-header.directive';
|
||||
import {DataGridFooterDirective} from '../directives/data-grid-footer.directive';
|
||||
import {DataGridLoaderDirective} from '../directives/data-grid-loader.directive';
|
||||
import {Subscription} from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'cdk-data-grid',
|
||||
templateUrl: './data-grid.component.html',
|
||||
styleUrls: ['./data-grid.component.scss']
|
||||
})
|
||||
export class DataGridComponent implements OnInit, OnDestroy {
|
||||
@Inject(ChangeDetectorRef) private cdr!: ChangeDetectorRef;
|
||||
|
||||
@ContentChildren(DataGridColDirective) columnDefinitions: QueryList<DataGridColDirective>;
|
||||
@ContentChildren(DataGridHeaderDirective) gridHeaders: QueryList<DataGridHeaderDirective>;
|
||||
@ContentChildren(DataGridFooterDirective) gridFooters: QueryList<DataGridFooterDirective>;
|
||||
@ContentChildren(DataGridLoaderDirective) loaders: QueryList<DataGridLoaderDirective>;
|
||||
|
||||
latestResult: IQueryExecutionResult<any> & IQueryExecutionGroupResult<any>;
|
||||
loading: boolean = false;
|
||||
|
||||
@Input() dataSource: IDataSource<any>;
|
||||
@Input() tableClasses: any;
|
||||
@Input() headerClasses: any;
|
||||
@Input() noRecordsText: string;
|
||||
|
||||
private _columns: string[];
|
||||
private _dataSubscription: Subscription;
|
||||
private _loadingSubscription: Subscription;
|
||||
|
||||
@Input() set columns(value: string[]) {
|
||||
this._columns = value;
|
||||
this.columnsChange.emit(value);
|
||||
}
|
||||
|
||||
get columns() {
|
||||
return this._columns;
|
||||
}
|
||||
|
||||
@Output() columnsChange: EventEmitter<string []> = new EventEmitter<string []>();
|
||||
|
||||
get noData() {
|
||||
return !this.latestResult || this.latestResult.totalRecords == 0;
|
||||
}
|
||||
|
||||
get noRecordsDisplayText() {
|
||||
return this.noRecordsText || 'No records';
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this._dataSubscription.unsubscribe();
|
||||
this._loadingSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this._dataSubscription = this.dataSource.data$.subscribe(newData => {
|
||||
this.latestResult = newData;
|
||||
});
|
||||
|
||||
this._loadingSubscription = this.dataSource.loading$.subscribe(isLoading => {
|
||||
this.loading = isLoading;
|
||||
this.cdr.detectChanges();
|
||||
});
|
||||
}
|
||||
|
||||
getSortingTemplate(columnName: string){
|
||||
const ret = this.getColumn(columnName);
|
||||
if (ret && ret.sortTemplate)
|
||||
return ret.sortTemplate.template;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
getFilterTemplate(columnName: string){
|
||||
const ret = this.getColumn(columnName);
|
||||
if (ret && ret.filterTemplate)
|
||||
return ret.filterTemplate.template;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
getColumn(columnName: string) {
|
||||
if (!this.columnDefinitions)
|
||||
return null;
|
||||
|
||||
const ret = this.columnDefinitions.find(t =>
|
||||
{
|
||||
return t.columnName == columnName;
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
getColumnHeaderTemplate(columnName: string) {
|
||||
const ret = this.getColumn(columnName);
|
||||
if (ret && ret.headerTemplate)
|
||||
return ret.headerTemplate.template;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
getColumnCellTemplate(columnName: string) {
|
||||
const ret = this.getColumn(columnName);
|
||||
if (ret && ret.cellTemplate)
|
||||
return ret.cellTemplate.template;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
hasHeaderTemplate(columnName: string) {
|
||||
return this.getColumnHeaderTemplate(columnName) ? true : false;
|
||||
}
|
||||
|
||||
hasCellTemplate(columnName: string) {
|
||||
return this.getColumnCellTemplate(columnName) ? true : false;
|
||||
}
|
||||
|
||||
hasFilterTemplate(columnName: string) {
|
||||
return this.getFilterTemplate(columnName) ? true : false;
|
||||
}
|
||||
|
||||
hasSortingTemplate(columnName: string) {
|
||||
return this.getSortingTemplate(columnName) ? true : false;
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDataGridCellFilter]'
|
||||
})
|
||||
export class DataGridCellFilterDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDataGridCell]'
|
||||
})
|
||||
export class DataGridCellDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDataGridColHeader]'
|
||||
})
|
||||
export class DataGridColHeaderDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDataGridColSort]'
|
||||
})
|
||||
export class DataGridColSortDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import {ContentChild, Directive, Input} from '@angular/core';
|
||||
import {DataGridColHeaderDirective} from './data-grid-col-header.directive';
|
||||
import {DataGridCellDirective} from './data-grid-cell.directive';
|
||||
import {DataGridCellFilterDirective} from './data-grid-cell-filter.directive';
|
||||
import {DataGridColSortDirective} from './data-grid-col-sort.directive';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDataGridCol]'
|
||||
})
|
||||
export class DataGridColDirective {
|
||||
@Input('psDataGridCol') columnName: string;
|
||||
|
||||
@ContentChild(DataGridColHeaderDirective) headerTemplate: DataGridColHeaderDirective;
|
||||
@ContentChild(DataGridCellDirective) cellTemplate: DataGridCellDirective;
|
||||
@ContentChild(DataGridCellFilterDirective) filterTemplate: DataGridCellFilterDirective;
|
||||
@ContentChild(DataGridColSortDirective) sortTemplate: DataGridColSortDirective;
|
||||
|
||||
constructor() { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDataGridFooter]'
|
||||
})
|
||||
export class DataGridFooterDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDataGridHeader]'
|
||||
})
|
||||
export class DataGridHeaderDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDataGridLoader]'
|
||||
})
|
||||
export class DataGridLoaderDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDsCommandContent]'
|
||||
})
|
||||
export class DsCommandContentDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDsCommandError]'
|
||||
})
|
||||
export class DsCommandErrorDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDsCommandFooter]'
|
||||
})
|
||||
export class DsCommandFooterDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDsCommandNoCommand]'
|
||||
})
|
||||
export class DsCommandNoCommandDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, ElementRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDsCommandSubmit]'
|
||||
})
|
||||
export class DsCommandSubmitDirective {
|
||||
constructor(public element: ElementRef) { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDsCommandValidation]'
|
||||
})
|
||||
export class DsCommandValidationDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<ng-container *ngIf="command; else noCommand">
|
||||
<ng-container *ngIf="hasContent" [ngTemplateOutlet]="contentTemplate"
|
||||
[ngTemplateOutletContext]="{ $implicit: command, loading: isLoading }">
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="lastValidationResult">
|
||||
<ng-container *ngIf="hasValidationTemplate" [ngTemplateOutlet]="validationTemplate"
|
||||
[ngTemplateOutletContext]="{ $implicit: lastValidationResult }">
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="lastErrorMessage && errorContent && errorContent.template">
|
||||
<ng-container [ngTemplateOutlet]="errorContent.template"
|
||||
[ngTemplateOutletContext]="{ $implicit: lastErrorMessage }">
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="hasFooterTemplate" [ngTemplateOutlet]="footerTemplate"
|
||||
[ngTemplateOutletContext]="{ $implicit: command, loading: isLoading }">
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<ng-template #noCommand>
|
||||
<ng-container *ngIf="noCommandContent && noCommandContent.template">
|
||||
<ng-container [ngTemplateOutlet]="noCommandContent.template">
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,205 @@
|
||||
import {
|
||||
Component,
|
||||
ContentChild,
|
||||
ContentChildren,
|
||||
EventEmitter,
|
||||
HostListener,
|
||||
Input,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
Output,
|
||||
QueryList
|
||||
} from '@angular/core';
|
||||
import {IDataSource} from '@poweredsoft/data';
|
||||
import {Subscription} from 'rxjs';
|
||||
import {finalize} from 'rxjs/operators';
|
||||
import {DsCommandContentDirective} from './directives/ds-command-content.directive';
|
||||
import {DsCommandErrorDirective} from './directives/ds-command-error.directive';
|
||||
import {DsCommandFooterDirective} from './directives/ds-command-footer.directive';
|
||||
import {DsCommandNoCommandDirective} from './directives/ds-command-no-command.directive';
|
||||
import {DsCommandSubmitDirective} from './directives/ds-command-submit.directive';
|
||||
import {DsCommandValidationDirective} from './directives/ds-command-validation.directive';
|
||||
|
||||
export interface DsCommandPropertyError
|
||||
{
|
||||
name: string,
|
||||
errors: string[];
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'cdk-ds-command, [cdkDsCommand]',
|
||||
templateUrl: './ds-command.component.html',
|
||||
styleUrls: ['./ds-command.component.scss']
|
||||
})
|
||||
export class DsCommandComponent implements OnInit, OnDestroy {
|
||||
private _refreshOnSuccess: boolean = true;
|
||||
|
||||
@Input() params: any;
|
||||
@Input() dataSource: IDataSource<any>;
|
||||
@Input() name: string;
|
||||
@Input() model: any;
|
||||
@Input() resolveCommand: boolean;
|
||||
|
||||
@Input() set refreshOnSuccess(val: boolean) {
|
||||
this._refreshOnSuccess = val;
|
||||
}
|
||||
|
||||
get refreshOnSuccess() {
|
||||
return this._refreshOnSuccess;
|
||||
}
|
||||
|
||||
@Output() success = new EventEmitter<any>();
|
||||
@Output() loading = new EventEmitter<boolean>();
|
||||
@Output() commandChange = new EventEmitter<any>();
|
||||
|
||||
@ContentChild(DsCommandContentDirective) commandContent: DsCommandContentDirective;
|
||||
@ContentChild(DsCommandFooterDirective) footerContent: DsCommandFooterDirective;
|
||||
@ContentChild(DsCommandNoCommandDirective) noCommandContent: DsCommandNoCommandDirective;
|
||||
@ContentChild(DsCommandErrorDirective) errorContent: DsCommandErrorDirective;
|
||||
@ContentChild(DsCommandValidationDirective) validationDirective: DsCommandValidationDirective;
|
||||
@ContentChildren(DsCommandSubmitDirective) submitDirectives: QueryList<DsCommandSubmitDirective>;
|
||||
|
||||
lastErrorMessage: string | null;
|
||||
lastValidationResult: DsCommandPropertyError[] | null;
|
||||
|
||||
protected _command: any = null;
|
||||
|
||||
private _loading = false;
|
||||
private _validationErrorSubscription: Subscription;
|
||||
private _notifyMessageSubscription: Subscription;
|
||||
|
||||
|
||||
@Input() set command(value: any) {
|
||||
if (this._command != value) {
|
||||
this._command = value;
|
||||
this.commandChange.emit(value);
|
||||
}
|
||||
}
|
||||
|
||||
get noCommand() {
|
||||
return this._command ? true : false;
|
||||
}
|
||||
|
||||
get command() {
|
||||
return this._command;
|
||||
}
|
||||
|
||||
get hasContent() {
|
||||
return this.commandContent != null && this.commandContent.template != null;
|
||||
}
|
||||
|
||||
get footerTemplate() {
|
||||
return this.footerContent.template;
|
||||
}
|
||||
|
||||
get hasFooterTemplate() {
|
||||
return this.footerContent?.template != null;
|
||||
}
|
||||
|
||||
get hasValidationTemplate() {
|
||||
return this.validationDirective != null && this.validationDirective.template != null;
|
||||
}
|
||||
|
||||
get validationTemplate() {
|
||||
return this.validationDirective.template;
|
||||
}
|
||||
|
||||
get contentTemplate() {
|
||||
return this.commandContent.template;
|
||||
}
|
||||
|
||||
clearValidationError() {
|
||||
this.lastValidationResult = null;
|
||||
}
|
||||
|
||||
clearLastErrorMessage() {
|
||||
this.lastErrorMessage = null;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._validationErrorSubscription?.unsubscribe();
|
||||
this._notifyMessageSubscription?.unsubscribe();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this._validationErrorSubscription = this.dataSource
|
||||
.validationError$.subscribe(validationResult => {
|
||||
this.lastValidationResult = Object.keys(validationResult.errors).reduce<DsCommandPropertyError[]>((prev, attr) => {
|
||||
prev.push({
|
||||
name: attr,
|
||||
errors: validationResult.errors[attr]
|
||||
})
|
||||
return prev;
|
||||
}, []);
|
||||
});
|
||||
|
||||
this._notifyMessageSubscription = this.dataSource.notifyMessage$.subscribe(message => {
|
||||
if (message.type != 'info' && message.type != "success")
|
||||
this.lastErrorMessage = message.message;
|
||||
});
|
||||
|
||||
const shouldResolve = this.resolveCommand === undefined ? true : this.resolveCommand;
|
||||
if (shouldResolve)
|
||||
this.resolveModel();
|
||||
}
|
||||
|
||||
resolveModel() {
|
||||
this.dataSource.resolveCommandModelByName({
|
||||
model: this.model,
|
||||
command: this.name,
|
||||
params: this.params
|
||||
}).subscribe(
|
||||
commandModel => {
|
||||
this.command = commandModel;
|
||||
},
|
||||
_ => { }
|
||||
);
|
||||
}
|
||||
|
||||
private changeLoadingState(loading: boolean) {
|
||||
if (loading != this._loading) {
|
||||
this._loading = loading;
|
||||
this.loading.emit(loading);
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener("click", ["$event"])
|
||||
childClicked($event: MouseEvent) {
|
||||
const element = $event.target;
|
||||
const found = this.submitDirectives
|
||||
.toArray()
|
||||
.find(t => t.element.nativeElement == element);
|
||||
|
||||
if (found != null)
|
||||
this.execute()
|
||||
}
|
||||
|
||||
execute() {
|
||||
// secure from double send.
|
||||
if (this._loading)
|
||||
return;
|
||||
|
||||
this.changeLoadingState(true);
|
||||
this.lastValidationResult = null;
|
||||
this.lastErrorMessage = null;
|
||||
this.dataSource.executeCommandByName(this.name, this._command)
|
||||
.pipe(
|
||||
finalize(() => this.changeLoadingState(false))
|
||||
)
|
||||
.subscribe(
|
||||
commandResult => {
|
||||
this.success.emit(commandResult);
|
||||
if (this.refreshOnSuccess)
|
||||
this.dataSource.refresh();
|
||||
},
|
||||
_ => {
|
||||
// we just catch the error, this way its not uncatched its handled via the other
|
||||
// subscriptions.
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
get isLoading() {
|
||||
return this._loading;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {DsCommandComponent} from './ds-command.component';
|
||||
import {DsCommandContentDirective} from './directives/ds-command-content.directive';
|
||||
import {DsCommandSubmitDirective} from './directives/ds-command-submit.directive';
|
||||
import {DsCommandValidationDirective} from './directives/ds-command-validation.directive';
|
||||
import {DsCommandFooterDirective} from './directives/ds-command-footer.directive';
|
||||
import {DsCommandErrorDirective} from './directives/ds-command-error.directive';
|
||||
import {DsCommandNoCommandDirective} from './directives/ds-command-no-command.directive';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [DsCommandComponent, DsCommandContentDirective, DsCommandSubmitDirective, DsCommandValidationDirective, DsCommandFooterDirective, DsCommandErrorDirective, DsCommandNoCommandDirective],
|
||||
imports: [
|
||||
CommonModule
|
||||
],
|
||||
exports: [DsCommandComponent, DsCommandContentDirective, DsCommandSubmitDirective, DsCommandValidationDirective, DsCommandFooterDirective, DsCommandErrorDirective, DsCommandNoCommandDirective]
|
||||
})
|
||||
export class DsCommandModule { }
|
||||
@@ -0,0 +1,23 @@
|
||||
<ul>
|
||||
<li class="ds-pager-first" (click)="first()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 19l-7-7 7-7m8 14l-7-7 7-7" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="ds-pager-previous" (click)="previous()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="ds-pager-page" [class.ds-pager-current]="page == pr" *ngFor="let pr of pageRanges" (click)="page = pr">{{ pr }}</li>
|
||||
<li class="ds-pager-next" (click)="next()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
</li>
|
||||
<li class="ds-pager-last" (click)="last()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 5l7 7-7 7M5 5l7 7-7 7" />
|
||||
</svg>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -0,0 +1,19 @@
|
||||
:host {
|
||||
ul {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
li {
|
||||
padding: 4px 2px;
|
||||
}
|
||||
|
||||
li.ds-pager-current {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
svg {
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import {Component, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core';
|
||||
import {IDataSource, IQueryExecutionGroupResult, IQueryExecutionResult} from '@poweredsoft/data';
|
||||
import {Subscription} from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'cdk-ds-pager',
|
||||
templateUrl: './ds-pager.component.html',
|
||||
styleUrls: ['./ds-pager.component.scss']
|
||||
})
|
||||
export class DsPagerComponent implements OnInit, OnDestroy {
|
||||
|
||||
private _range: number = 5;
|
||||
|
||||
@Input() dataSource: IDataSource<any>;
|
||||
pageRanges: number[] = [];
|
||||
|
||||
// range.
|
||||
@Input() set range(value: number) {
|
||||
this._range = value;
|
||||
}
|
||||
get range() {
|
||||
return this._range;
|
||||
}
|
||||
|
||||
// page.
|
||||
@Input() set page(value: number) {
|
||||
if (this.dataSource.page != value) {
|
||||
this.dataSource.page = value;
|
||||
this.pageChange.emit(value);
|
||||
}
|
||||
}
|
||||
get page() {
|
||||
return this.dataSource?.page;
|
||||
}
|
||||
|
||||
@Output() pageChange = new EventEmitter<number>();
|
||||
|
||||
public latestResult: IQueryExecutionResult<any> & IQueryExecutionGroupResult<any> = null;
|
||||
private dataSubscription: Subscription;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.dataSubscription = this.dataSource.data$.subscribe(result => {
|
||||
this.latestResult = result;
|
||||
this.refreshPageRange();
|
||||
});
|
||||
}
|
||||
|
||||
refreshPageRange() {
|
||||
let previous = [];
|
||||
let nexts = [];
|
||||
for (let i = 0; i < this.range; i++) {
|
||||
const currentPrevious = this.dataSource.page - 1 - i;
|
||||
if (currentPrevious >= 1)
|
||||
previous.push(currentPrevious);
|
||||
|
||||
const currentNext = this.dataSource.page + i + 1;
|
||||
if (currentNext <= this.latestResult?.numberOfPages)
|
||||
nexts.push(currentNext);
|
||||
}
|
||||
|
||||
previous.reverse();
|
||||
|
||||
const final = previous.concat([this.dataSource.page]).concat(nexts);
|
||||
this.pageRanges = final;
|
||||
}
|
||||
|
||||
first() {
|
||||
this.page = 1;
|
||||
}
|
||||
|
||||
last() {
|
||||
if (this.latestResult)
|
||||
this.page = this.latestResult!.numberOfPages;
|
||||
}
|
||||
|
||||
next() {
|
||||
if (this.page + 1 <= this.latestResult?.totalRecords)
|
||||
this.page++;
|
||||
}
|
||||
|
||||
previous() {
|
||||
if (this.page > 1)
|
||||
this.page--;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.dataSubscription?.unsubscribe();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {DsPagerComponent} from './ds-pager.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [DsPagerComponent],
|
||||
imports: [
|
||||
CommonModule
|
||||
],
|
||||
exports: [DsPagerComponent]
|
||||
})
|
||||
export class DsPagerModule { }
|
||||
@@ -0,0 +1,7 @@
|
||||
<form (submit)="applySearch()">
|
||||
<div [ngClass]="classes">
|
||||
<input type="search" (onSearch)="onSearch()" [placeholder]="finalSearchText" [ngClass]="searchClasses"
|
||||
[(ngModel)]="filterValue" [ngModelOptions]="{standalone: true}">
|
||||
<button type="submit" [ngClass]="submitButtonClasses">{{ finalSearchText }}</button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -0,0 +1,75 @@
|
||||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {FilterType, ICompositeFilter, IDataSource, ISimpleFilter} from '@poweredsoft/data';
|
||||
|
||||
@Component({
|
||||
selector: 'cdk-ds-search',
|
||||
templateUrl: './ds-search.component.html',
|
||||
styleUrls: ['./ds-search.component.scss']
|
||||
})
|
||||
export class DsSearchComponent implements OnInit {
|
||||
@Input() dataSource: IDataSource<any>;
|
||||
@Input() filterType: string;
|
||||
@Input() filterPaths: string[];
|
||||
@Input() searchText: string;
|
||||
@Input() submitButtonClasses: any;
|
||||
@Input() searchClasses: any;
|
||||
@Input() classes: any;
|
||||
|
||||
filterValue: string = null;
|
||||
lastUsedFilter: any;
|
||||
|
||||
constructor() { }
|
||||
|
||||
get finalSearchText() {
|
||||
return this.searchText ?? "Search";
|
||||
}
|
||||
|
||||
get finalFilterType() {
|
||||
return this.filterType ?? FilterType.CONTAINS;
|
||||
}
|
||||
|
||||
onSearch() {
|
||||
this.applySearch();
|
||||
}
|
||||
|
||||
applySearch() {
|
||||
|
||||
const existingFilters = this.dataSource.filters;
|
||||
|
||||
|
||||
// adapt current filters to remove the previous one if exist
|
||||
// and replace with new one.
|
||||
const finalNewFilters = existingFilters
|
||||
.filter(t => t != this.lastUsedFilter);
|
||||
|
||||
if (this.filterValue) {
|
||||
const newFilter: ICompositeFilter = {
|
||||
and: true,
|
||||
type: FilterType.COMPOSITE,
|
||||
filters: this.filterPaths.map(filterPath => (<ISimpleFilter>{
|
||||
path: filterPath,
|
||||
type: this.finalFilterType,
|
||||
value: this.filterValue,
|
||||
and: false
|
||||
}))
|
||||
}
|
||||
|
||||
finalNewFilters.push(newFilter);
|
||||
|
||||
// update last used filter to replace it if changed.
|
||||
this.lastUsedFilter = newFilter;
|
||||
} else {
|
||||
this.lastUsedFilter = null;
|
||||
}
|
||||
|
||||
// execute search.
|
||||
this.dataSource.query({
|
||||
page: 1,
|
||||
filters: finalNewFilters
|
||||
})
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { DsSearchComponent } from './ds-search.component';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [DsSearchComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule
|
||||
],
|
||||
exports: [DsSearchComponent]
|
||||
})
|
||||
export class DsSearchModule { }
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
<ng-container *ngFor="let error of latestErrors; let isLast=last">
|
||||
{{ error }}
|
||||
<br *ngIf="!isLast" />
|
||||
</ng-container>
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
import {Component, Input, OnDestroy, OnInit} from '@angular/core';
|
||||
import {IDataSource} from '@poweredsoft/data';
|
||||
import {Subscription} from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'cdk-ds-validation-error',
|
||||
templateUrl: './ds-validation-error.component.html',
|
||||
styleUrls: ['./ds-validation-error.component.scss']
|
||||
})
|
||||
export class DsValidationErrorComponent implements OnInit, OnDestroy {
|
||||
@Input() dataSource: IDataSource<any>;
|
||||
@Input() field: string;
|
||||
|
||||
validationErrorsSub: Subscription;
|
||||
commandStartedSub: Subscription;
|
||||
latestErrors: string[] = [];
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.validationErrorsSub?.unsubscribe();
|
||||
this.commandStartedSub?.unsubscribe();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.commandStartedSub = this.dataSource.commandStarted$.subscribe(e => {
|
||||
this.latestErrors = [];
|
||||
});
|
||||
|
||||
this.validationErrorsSub = this.dataSource.validationError$.subscribe(validationErrors => {
|
||||
this.latestErrors = Object.keys(validationErrors.errors)
|
||||
.filter(t => t.toLowerCase() == this.field?.toLowerCase())
|
||||
.reduce<string[]>((prev, current) => {
|
||||
return prev.concat(validationErrors.errors[current]);
|
||||
}, []);
|
||||
});
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {DsValidationErrorComponent} from './ds-validation-error.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [DsValidationErrorComponent],
|
||||
imports: [
|
||||
CommonModule
|
||||
],
|
||||
exports: [DsValidationErrorComponent]
|
||||
})
|
||||
export class DsValidationErrorModule { }
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import { Directive, TemplateRef } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkListViewFooter]'
|
||||
})
|
||||
export class ListViewFooterDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkListViewHeader]'
|
||||
})
|
||||
export class ListViewHeaderDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkListViewItem]'
|
||||
})
|
||||
export class ListViewItemDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import { Directive, TemplateRef } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkListViewSeparator]'
|
||||
})
|
||||
export class ListViewSeparatorDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {ListViewComponent} from './list-view/list-view.component';
|
||||
import {ListViewItemDirective} from './directives/list-view-item.directive';
|
||||
import {ListViewHeaderDirective} from './directives/list-view-header.directive';
|
||||
import {ListViewFooterDirective} from './directives/list-view-footer.directive';
|
||||
import {ListViewSeparatorDirective} from './directives/list-view-separator.directive';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [ListViewComponent, ListViewItemDirective, ListViewHeaderDirective, ListViewFooterDirective, ListViewSeparatorDirective],
|
||||
imports: [
|
||||
CommonModule
|
||||
],
|
||||
exports: [
|
||||
ListViewComponent,
|
||||
ListViewItemDirective,
|
||||
ListViewHeaderDirective,
|
||||
ListViewFooterDirective,
|
||||
ListViewSeparatorDirective
|
||||
]
|
||||
})
|
||||
export class ListViewModule { }
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<ng-container [ngTemplateOutlet]="getViewHeaderTemplate()"></ng-container>
|
||||
<ng-container *ngIf="!noData else noResultTemplate">
|
||||
<div [ngClass]="listViewClasses">
|
||||
<ng-container *ngFor="let item of latestResult.data; let index = index; let first = first; let last = last; let odd = odd">
|
||||
<ng-container [ngTemplateOutlet]="getViewItemTemplate()" [ngTemplateOutletContext]="{
|
||||
$implicit: item,
|
||||
index: index,
|
||||
first: first,
|
||||
last: last,
|
||||
odd: odd
|
||||
}">
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container [ngTemplateOutlet]="getViewFooterTemplate()"></ng-container>
|
||||
|
||||
|
||||
<ng-template #noResultTemplate>
|
||||
<div [ngClass]="noRecordClasses">{{noRecords}}</div>
|
||||
</ng-template>
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
import {Component, ContentChild, Input, OnDestroy, OnInit} from '@angular/core';
|
||||
import {IDataSource, IQueryExecutionGroupResult, IQueryExecutionResult} from '@poweredsoft/data';
|
||||
import {Subscription} from 'rxjs';
|
||||
import {ListViewItemDirective} from '../directives/list-view-item.directive';
|
||||
import {ListViewHeaderDirective} from '../directives/list-view-header.directive';
|
||||
import {ListViewFooterDirective} from '../directives/list-view-footer.directive';
|
||||
|
||||
@Component({
|
||||
selector: 'cdk-list-view',
|
||||
templateUrl: './list-view.component.html',
|
||||
styleUrls: ['./list-view.component.scss']
|
||||
})
|
||||
export class ListViewComponent implements OnInit, OnDestroy {
|
||||
@Input() dataSource: IDataSource<any>;
|
||||
@Input() noRecordsText: string;
|
||||
@Input() noRecordClasses: any;
|
||||
@Input() listViewClasses: any;
|
||||
|
||||
latestResult: IQueryExecutionResult<any> & IQueryExecutionGroupResult<any>;
|
||||
loading:boolean;
|
||||
|
||||
private _dataSubscription: Subscription;
|
||||
|
||||
@ContentChild(ListViewItemDirective) viewItem: ListViewItemDirective;
|
||||
@ContentChild(ListViewHeaderDirective) viewHeader: ListViewHeaderDirective;
|
||||
@ContentChild(ListViewFooterDirective) viewFooter: ListViewFooterDirective;
|
||||
//@ContentChildren(ViewDataDirective) viewData: QueryList<ViewDataDirective>;
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this._dataSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this._dataSubscription = this.dataSource.data$.subscribe(newData => {
|
||||
this.latestResult = newData;
|
||||
});
|
||||
}
|
||||
|
||||
get noData(){
|
||||
if (!this.latestResult)
|
||||
return true;
|
||||
|
||||
return this.latestResult.data.length == 0;
|
||||
}
|
||||
|
||||
get noRecords(){
|
||||
return this.noRecordsText || "No records...";
|
||||
}
|
||||
|
||||
getViewItemTemplate(){
|
||||
if(this.viewItem == null)
|
||||
return null;
|
||||
return this.viewItem.template;
|
||||
}
|
||||
|
||||
getViewHeaderTemplate(){
|
||||
if(this.viewHeader == null)
|
||||
return null;
|
||||
return this.viewHeader.template;
|
||||
}
|
||||
|
||||
|
||||
getViewFooterTemplate(){
|
||||
if(this.viewFooter == null)
|
||||
return null;
|
||||
return this.viewFooter.template;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDsViewContent]'
|
||||
})
|
||||
export class ViewContentDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDsViewLoading]'
|
||||
})
|
||||
export class ViewLoadingDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import {Directive, TemplateRef} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[cdkDsViewNoRecords]'
|
||||
})
|
||||
export class ViewNoRecordsDirective {
|
||||
constructor(public template: TemplateRef<any>) { }
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<ng-container *ngIf="loading; else notLoading">
|
||||
<ng-container *ngIf="viewLoading">
|
||||
<ng-container [ngTemplateOutlet]="getViewLoadingTemplate()"></ng-container>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!viewLoading">
|
||||
{{ finalLoadingText }}
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
|
||||
<ng-template #notLoading>
|
||||
<ng-container *ngIf="!noData else noResultTemplate">
|
||||
<ng-container [ngTemplateOutlet]="getViewContentTemplate()"
|
||||
[ngTemplateOutletContext]="{$implicit: viewModel}">
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #noResultTemplate>
|
||||
<ng-container *ngIf="viewNoRecords">
|
||||
<ng-container [ngTemplateOutlet]="getViewNoRecordsTemplate()"></ng-container>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!viewNoRecords">
|
||||
<div [ngClass]="noRecordClasses">{{noRecords}}</div>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
@@ -0,0 +1,79 @@
|
||||
import {Component, ContentChild, Input, OnDestroy, OnInit} from '@angular/core';
|
||||
import {IDataSource} from '@poweredsoft/data';
|
||||
import {Subscription} from 'rxjs';
|
||||
import {ViewContentDirective} from './directives/view-content.directive';
|
||||
import {ViewLoadingDirective} from './directives/view-loading.directive';
|
||||
import {ViewNoRecordsDirective} from './directives/view-no-records.directive';
|
||||
|
||||
@Component({
|
||||
selector: 'cdk-ds-view',
|
||||
templateUrl: './view.component.html',
|
||||
styleUrls: ['./view.component.scss']
|
||||
})
|
||||
export class ViewComponent implements OnInit, OnDestroy {
|
||||
@Input() dataSource: IDataSource<any>;
|
||||
@Input() noRecordsText: string;
|
||||
@Input() loadingText: string;
|
||||
@Input() noRecordClasses: any;
|
||||
|
||||
@ContentChild(ViewContentDirective) viewContent: ViewContentDirective;
|
||||
@ContentChild(ViewLoadingDirective) viewLoading: ViewLoadingDirective;
|
||||
@ContentChild(ViewNoRecordsDirective) viewNoRecords: ViewNoRecordsDirective;
|
||||
|
||||
loading: boolean = false;
|
||||
private _viewModel: any = null;
|
||||
|
||||
private _dataSubscription: Subscription;
|
||||
private _loadingSubscription: Subscription;
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this._dataSubscription.unsubscribe();
|
||||
this._loadingSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this._dataSubscription = this.dataSource.data$.subscribe(newData => {
|
||||
if (newData && newData.data && newData.data.length)
|
||||
this._viewModel = newData.data[0];
|
||||
});
|
||||
|
||||
this._loadingSubscription = this.dataSource.loading$.subscribe(loading => {
|
||||
this.loading = loading;
|
||||
});
|
||||
}
|
||||
|
||||
get noData(){
|
||||
return this._viewModel ? false : true;
|
||||
}
|
||||
|
||||
get viewModel() {
|
||||
return this._viewModel;
|
||||
}
|
||||
|
||||
get noRecords(){
|
||||
return this.noRecordsText || "No records...";
|
||||
}
|
||||
|
||||
get finalLoadingText() {
|
||||
return this.loadingText || 'Loading ...';
|
||||
}
|
||||
|
||||
getViewContentTemplate(){
|
||||
if(this.viewContent == null)
|
||||
return null;
|
||||
return this.viewContent.template;
|
||||
}
|
||||
|
||||
getViewNoRecordsTemplate(){
|
||||
if(this.viewNoRecords == null)
|
||||
return null;
|
||||
return this.viewNoRecords.template;
|
||||
}
|
||||
|
||||
getViewLoadingTemplate(){
|
||||
if(this.viewLoading == null)
|
||||
return null;
|
||||
return this.viewLoading.template;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {ViewComponent} from './view.component';
|
||||
import {ViewContentDirective} from './directives/view-content.directive';
|
||||
import {ViewLoadingDirective} from './directives/view-loading.directive';
|
||||
import {ViewNoRecordsDirective} from './directives/view-no-records.directive';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [ViewComponent, ViewContentDirective, ViewLoadingDirective, ViewNoRecordsDirective],
|
||||
imports: [
|
||||
CommonModule
|
||||
],
|
||||
exports: [ViewComponent, ViewContentDirective, ViewLoadingDirective, ViewNoRecordsDirective]
|
||||
})
|
||||
export class ViewModule { }
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Public API Surface of ngx-cdk-ui
|
||||
*/
|
||||
|
||||
// data grid.
|
||||
export * from './lib/data-grid/data-grid.module';
|
||||
export * from './lib/data-grid/data-grid/data-grid.component';
|
||||
export * from './lib/data-grid/directives/data-grid-cell.directive';
|
||||
export * from './lib/data-grid/directives/data-grid-col.directive';
|
||||
export * from './lib/data-grid/directives/data-grid-col-header.directive';
|
||||
export * from './lib/data-grid/directives/data-grid-header.directive';
|
||||
export * from './lib/data-grid/directives/data-grid-footer.directive';
|
||||
export * from './lib/data-grid/directives/data-grid-loader.directive';
|
||||
export * from './lib/data-grid/directives/data-grid-cell-filter.directive';
|
||||
export * from './lib/data-grid/directives/data-grid-col-sort.directive';
|
||||
|
||||
//list view
|
||||
export * from './lib/list-view/list-view.module';
|
||||
export * from './lib/list-view/list-view/list-view.component';
|
||||
export * from './lib/list-view/directives/list-view-item.directive';
|
||||
export * from './lib/list-view/directives/list-view-header.directive';
|
||||
export * from './lib/list-view/directives/list-view-footer.directive';
|
||||
export * from './lib/list-view/directives/list-view-separator.directive';
|
||||
|
||||
// search
|
||||
export * from './lib/ds-search/ds-search.module';
|
||||
export * from './lib/ds-search/ds-search.component';
|
||||
|
||||
// ds validation
|
||||
export * from './lib/ds-validation-error/ds-validation-error.module';
|
||||
export * from './lib/ds-validation-error/ds-validation-error.component';
|
||||
|
||||
// view
|
||||
export * from './lib/view/view.module';
|
||||
export * from './lib/view/view.component';
|
||||
export * from './lib/view/directives/view-content.directive';
|
||||
export * from './lib/view/directives/view-loading.directive';
|
||||
export * from './lib/view/directives/view-no-records.directive';
|
||||
|
||||
// ds-command
|
||||
export * from './lib/ds-command/ds-command.module';
|
||||
export * from './lib/ds-command/ds-command.component';
|
||||
export * from './lib/ds-command/directives/ds-command-content.directive';
|
||||
export * from './lib/ds-command/directives/ds-command-submit.directive';
|
||||
export * from './lib/ds-command/directives/ds-command-validation.directive';
|
||||
export * from './lib/ds-command/directives/ds-command-footer.directive';
|
||||
export * from './lib/ds-command/directives/ds-command-no-command.directive';
|
||||
export * from './lib/ds-command/directives/ds-command-error.directive';
|
||||
|
||||
// ds-pager
|
||||
export * from './lib/ds-pager/ds-pager.module';
|
||||
export * from './lib/ds-pager/ds-pager.component';
|
||||
@@ -0,0 +1,26 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/dist/zone';
|
||||
import 'zone.js/dist/zone-testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(path: string, deep?: boolean, filter?: RegExp): {
|
||||
keys(): string[];
|
||||
<T>(id: string): T;
|
||||
};
|
||||
};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting()
|
||||
);
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
Reference in New Issue
Block a user