Merged PR 48: filtering sorting and select
filtering sorting and select need comments for naming i.e. NgSelectorModule => NgSelectModule GridFilterModule => DataSourceFilterModule ??
This commit is contained in:
commit
397d6753f2
41
angular.json
41
angular.json
@ -28,6 +28,7 @@
|
|||||||
"src/assets"
|
"src/assets"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
|
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||||
"src/styles.scss"
|
"src/styles.scss"
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": []
|
||||||
@ -203,6 +204,46 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"@poweredsoft/ng-select": {
|
||||||
|
"projectType": "library",
|
||||||
|
"root": "projects/poweredsoft/ng-select",
|
||||||
|
"sourceRoot": "projects/poweredsoft/ng-select/src",
|
||||||
|
"prefix": "ps-ng",
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||||
|
"options": {
|
||||||
|
"tsConfig": "projects/poweredsoft/ng-select/tsconfig.lib.json",
|
||||||
|
"project": "projects/poweredsoft/ng-select/ng-package.json"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"tsConfig": "projects/poweredsoft/ng-select/tsconfig.lib.prod.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@angular-devkit/build-angular:karma",
|
||||||
|
"options": {
|
||||||
|
"main": "projects/poweredsoft/ng-select/src/test.ts",
|
||||||
|
"tsConfig": "projects/poweredsoft/ng-select/tsconfig.spec.json",
|
||||||
|
"karmaConfig": "projects/poweredsoft/ng-select/karma.conf.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"builder": "@angular-devkit/build-angular:tslint",
|
||||||
|
"options": {
|
||||||
|
"tsConfig": [
|
||||||
|
"projects/poweredsoft/ng-select/tsconfig.lib.json",
|
||||||
|
"projects/poweredsoft/ng-select/tsconfig.spec.json"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"**/node_modules/**"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}},
|
}},
|
||||||
"defaultProject": "ngx-cdk-ui"
|
"defaultProject": "ngx-cdk-ui"
|
||||||
}
|
}
|
||||||
|
20
package-lock.json
generated
20
package-lock.json
generated
@ -1644,6 +1644,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@ng-select/ng-select": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ng-select/ng-select/-/ng-select-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-f5NzrKRvswOvxa8BzBgAUOpzl0B8SrlVQHQLB2zPymuZlzC2dWUi9mUhgu6s2igwdClmrZ8bysNBBNpgqHskyA==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^1.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@ngtools/webpack": {
|
"@ngtools/webpack": {
|
||||||
"version": "9.1.7",
|
"version": "9.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-9.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-9.1.7.tgz",
|
||||||
@ -1668,9 +1676,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@poweredsoft/data": {
|
"@poweredsoft/data": {
|
||||||
"version": "0.0.26",
|
"version": "0.0.30",
|
||||||
"resolved": "https://registry.npmjs.org/@poweredsoft/data/-/data-0.0.26.tgz",
|
"resolved": "https://registry.npmjs.org/@poweredsoft/data/-/data-0.0.30.tgz",
|
||||||
"integrity": "sha512-JogKJQ01w4hTQr4EDSoYp2KfJzBbzC8trc7iHCxw7tjF6kB9nqWxu8gvRxX5pqzDK6ORz0Ieuw7i0hEZusW+ww==",
|
"integrity": "sha512-lKojW+yCKPSrdohqhuoEUTo196Z1cHs+SkOZ9N43N7MUcbIR0SA6Uz6k4QZtbmbXmR5AvDKPrDp37nqPXGZFYA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"tslib": "^1.9.0"
|
"tslib": "^1.9.0"
|
||||||
}
|
}
|
||||||
@ -1684,9 +1692,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@poweredsoft/ngx-data-apollo": {
|
"@poweredsoft/ngx-data-apollo": {
|
||||||
"version": "0.0.8",
|
"version": "0.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/@poweredsoft/ngx-data-apollo/-/ngx-data-apollo-0.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/@poweredsoft/ngx-data-apollo/-/ngx-data-apollo-0.0.10.tgz",
|
||||||
"integrity": "sha512-8nIlvHTnbLyG9aNxkSYOHIbNBBSjj92v0BeFTq4xkttp3UmYzhOO7lkgo1cEIDUuYo+ITAYoZbKwrd4CbnBgcA==",
|
"integrity": "sha512-0HjJthjXstNXS/T9u6t9VTWtQO/LUzGsbT/m0tjj8y0YuivMzfK76EyQldvjGXDYGfIL12kEhsKEbiOPXyCXcA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"tslib": "^1.9.0"
|
"tslib": "^1.9.0"
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,10 @@
|
|||||||
"@angular/platform-browser": "~9.1.4",
|
"@angular/platform-browser": "~9.1.4",
|
||||||
"@angular/platform-browser-dynamic": "~9.1.4",
|
"@angular/platform-browser-dynamic": "~9.1.4",
|
||||||
"@angular/router": "~9.1.4",
|
"@angular/router": "~9.1.4",
|
||||||
"@poweredsoft/data": "0.0.26",
|
"@ng-select/ng-select": "^4.0.1",
|
||||||
|
"@poweredsoft/data": "0.0.30",
|
||||||
"@poweredsoft/ngx-data": "0.0.13",
|
"@poweredsoft/ngx-data": "0.0.13",
|
||||||
"@poweredsoft/ngx-data-apollo": "0.0.8",
|
"@poweredsoft/ngx-data-apollo": "0.0.10",
|
||||||
"apollo-angular": "^1.8.0",
|
"apollo-angular": "^1.8.0",
|
||||||
"apollo-angular-link-http": "^1.9.0",
|
"apollo-angular-link-http": "^1.9.0",
|
||||||
"apollo-cache-inmemory": "^1.6.0",
|
"apollo-cache-inmemory": "^1.6.0",
|
||||||
|
24
projects/poweredsoft/ng-select/README.md
Normal file
24
projects/poweredsoft/ng-select/README.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# NgSelect
|
||||||
|
|
||||||
|
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.9.
|
||||||
|
|
||||||
|
## Code scaffolding
|
||||||
|
|
||||||
|
Run `ng generate component component-name --project ng-select` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ng-select`.
|
||||||
|
> Note: Don't forget to add `--project ng-select` or else it will be added to the default project in your `angular.json` file.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Run `ng build ng-select` to build the project. The build artifacts will be stored in the `dist/` directory.
|
||||||
|
|
||||||
|
## Publishing
|
||||||
|
|
||||||
|
After building your library with `ng build ng-select`, go to the dist folder `cd dist/ng-select` and run `npm publish`.
|
||||||
|
|
||||||
|
## Running unit tests
|
||||||
|
|
||||||
|
Run `ng test ng-select` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||||
|
|
||||||
|
## Further help
|
||||||
|
|
||||||
|
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
32
projects/poweredsoft/ng-select/karma.conf.js
Normal file
32
projects/poweredsoft/ng-select/karma.conf.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Karma configuration file, see link for more information
|
||||||
|
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||||
|
|
||||||
|
module.exports = function (config) {
|
||||||
|
config.set({
|
||||||
|
basePath: '',
|
||||||
|
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||||
|
plugins: [
|
||||||
|
require('karma-jasmine'),
|
||||||
|
require('karma-chrome-launcher'),
|
||||||
|
require('karma-jasmine-html-reporter'),
|
||||||
|
require('karma-coverage-istanbul-reporter'),
|
||||||
|
require('@angular-devkit/build-angular/plugins/karma')
|
||||||
|
],
|
||||||
|
client: {
|
||||||
|
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||||
|
},
|
||||||
|
coverageIstanbulReporter: {
|
||||||
|
dir: require('path').join(__dirname, '../../../coverage/poweredsoft/ng-select'),
|
||||||
|
reports: ['html', 'lcovonly', 'text-summary'],
|
||||||
|
fixWebpackSourcePaths: true
|
||||||
|
},
|
||||||
|
reporters: ['progress', 'kjhtml'],
|
||||||
|
port: 9876,
|
||||||
|
colors: true,
|
||||||
|
logLevel: config.LOG_INFO,
|
||||||
|
autoWatch: true,
|
||||||
|
browsers: ['Chrome'],
|
||||||
|
singleRun: false,
|
||||||
|
restartOnFileChange: true
|
||||||
|
});
|
||||||
|
};
|
7
projects/poweredsoft/ng-select/ng-package.json
Normal file
7
projects/poweredsoft/ng-select/ng-package.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
|
||||||
|
"dest": "../../../dist/poweredsoft/ng-select",
|
||||||
|
"lib": {
|
||||||
|
"entryFile": "src/public-api.ts"
|
||||||
|
}
|
||||||
|
}
|
11
projects/poweredsoft/ng-select/package.json
Normal file
11
projects/poweredsoft/ng-select/package.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "@poweredsoft/ng-select",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/common": "^9.1.9",
|
||||||
|
"@angular/core": "^9.1.9"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^1.10.0"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
import { Directive, TemplateRef } from '@angular/core';
|
||||||
|
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[psNgNotFoundTemplate]'
|
||||||
|
})
|
||||||
|
export class NotFoundTemplateDirective {
|
||||||
|
|
||||||
|
constructor(public template: TemplateRef<any>) { }
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
import { Directive, TemplateRef } from '@angular/core';
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[psNgSelectLabel]'
|
||||||
|
})
|
||||||
|
export class SelectLabelTemplateDirective {
|
||||||
|
constructor(public template: TemplateRef<any>) { }
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
import { Directive, TemplateRef } from '@angular/core';
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[psNgSelectOption]'
|
||||||
|
})
|
||||||
|
export class SelectOptionTemplateDirective {
|
||||||
|
|
||||||
|
constructor(public template: TemplateRef<any>) { }
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
<ng-select [items]="data$ |async"
|
||||||
|
[bindLabel]="bindLabel"
|
||||||
|
[bindValue]="bindValue"
|
||||||
|
autofocus
|
||||||
|
[typeahead] = "searchInput$"
|
||||||
|
[trackByFn]="trackFn"
|
||||||
|
[searchable]="true"
|
||||||
|
[multiple]="true"
|
||||||
|
(change)="valueChanged($event)">
|
||||||
|
<ng-container *ngIf="hasOptionTemplate">
|
||||||
|
<ng-template ng-option-tmp let-item="item" let-index="index">
|
||||||
|
<ng-container [ngTemplateOutlet]="selectOptionTemplate"
|
||||||
|
[ngTemplateOutletContext]="{
|
||||||
|
$implicit: item,
|
||||||
|
index: index
|
||||||
|
}"></ng-container>
|
||||||
|
</ng-template>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngIf="hasLabelTemplate">
|
||||||
|
<ng-template ng-label-tmp let-item="item" let-index="index" let-clear="clear">
|
||||||
|
<span class="ng-value-label">
|
||||||
|
<ng-container [ngTemplateOutlet]="selectLabelTemplate"
|
||||||
|
[ngTemplateOutletContext]="{ $implicit: item, index: index, clear: clear }"></ng-container>
|
||||||
|
</span>
|
||||||
|
<span class="ng-value-icon right" (click)="clear(item)" aria-hidden="true">×</span>
|
||||||
|
</ng-template>
|
||||||
|
</ng-container>
|
||||||
|
</ng-select>
|
@ -0,0 +1,153 @@
|
|||||||
|
import { Component, OnInit, ContentChild, ViewChild, Input, Output, EventEmitter, ChangeDetectorRef, forwardRef, OnDestroy } from '@angular/core';
|
||||||
|
import { SelectLabelTemplateDirective } from '../directives/select-label-template.directive';
|
||||||
|
import { IDataSource, ISimpleFilter } from '@poweredsoft/data';
|
||||||
|
import { Observable, Subject, Subscription } from 'rxjs';
|
||||||
|
import { map, distinctUntilChanged, debounceTime } from 'rxjs/operators';
|
||||||
|
import { NgSelectComponent as SelectComponent } from '@ng-select/ng-select';
|
||||||
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||||
|
import { SelectOptionTemplateDirective } from '../directives/select-option-template.directive';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ps-ng-multi-select',
|
||||||
|
templateUrl: './multi-select.component.html',
|
||||||
|
providers: [{
|
||||||
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
useExisting: forwardRef(() => MultiSelectComponent),
|
||||||
|
multi: true
|
||||||
|
}],
|
||||||
|
styleUrls: ['./multi-select.component.scss']
|
||||||
|
})
|
||||||
|
export class MultiSelectComponent implements OnInit,OnDestroy {
|
||||||
|
|
||||||
|
|
||||||
|
@ContentChild(SelectOptionTemplateDirective) optionTemplate: SelectOptionTemplateDirective;
|
||||||
|
@ContentChild(SelectLabelTemplateDirective) labelTemplate: SelectLabelTemplateDirective;
|
||||||
|
|
||||||
|
@ViewChild(SelectComponent, { static: true }) selectComponent: SelectComponent;
|
||||||
|
@Input() dataSource: IDataSource<any>;
|
||||||
|
@Input() searchPath: string;
|
||||||
|
@Input() searchType: string;
|
||||||
|
@Input() sortingPath: string;
|
||||||
|
@Input() serverFiltering:boolean;
|
||||||
|
@Input() bindLabel:string;
|
||||||
|
@Input() bindValue: string;
|
||||||
|
|
||||||
|
@Output('change') changeEvent = new EventEmitter();
|
||||||
|
|
||||||
|
trackFn: (item: any) => any;
|
||||||
|
data$ : Observable<any[]>;
|
||||||
|
isLoading:boolean = false;
|
||||||
|
searchInput$ = new Subject<string>();
|
||||||
|
|
||||||
|
private _loadingSubscription: Subscription;
|
||||||
|
|
||||||
|
constructor(private cdr: ChangeDetectorRef) {
|
||||||
|
this.trackFn = this.trackBy.bind(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
trackBy(item: any) {
|
||||||
|
return this.dataSource.resolveIdField(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
valueChanged(event) {
|
||||||
|
this.changeEvent.emit(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeValue(obj: any): void {
|
||||||
|
this.selectComponent.writeValue(obj);
|
||||||
|
}
|
||||||
|
registerOnChange(fn: any): void {
|
||||||
|
this.selectComponent.registerOnChange(fn);
|
||||||
|
}
|
||||||
|
registerOnTouched(fn: any): void {
|
||||||
|
this.selectComponent.registerOnTouched(fn);
|
||||||
|
}
|
||||||
|
setDisabledState?(isDisabled: boolean): void {
|
||||||
|
if (this.selectComponent.setDisabledState)
|
||||||
|
this.selectComponent.setDisabledState(isDisabled);
|
||||||
|
}
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this._loadingSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.dataFetching();
|
||||||
|
this.detectLoading();
|
||||||
|
if(this.serverFiltering){
|
||||||
|
this.searchOnServer();
|
||||||
|
}else{
|
||||||
|
this.refreshDataSource();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dataFetching(){
|
||||||
|
this.data$ = this.dataSource.data$.pipe(
|
||||||
|
map(t => {
|
||||||
|
if (t == null)
|
||||||
|
return [];
|
||||||
|
return t.data;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
detectLoading(){
|
||||||
|
this._loadingSubscription = this.dataSource.loading$.subscribe(loading => {
|
||||||
|
this.isLoading = loading;
|
||||||
|
this.cdr.detectChanges();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
searchOnServer(){
|
||||||
|
this.searchInput$.pipe(
|
||||||
|
distinctUntilChanged(), // emit the difference from previous input
|
||||||
|
debounceTime(500) // this is for delaying searching speed
|
||||||
|
).subscribe(searchTerm => this.refreshDataSource(searchTerm, 1, 100)); // page: 1, pageSize: 50
|
||||||
|
|
||||||
|
this.refreshDataSource(); //send the query to server to sorting & filtering by default
|
||||||
|
}
|
||||||
|
|
||||||
|
get selectedModel() {
|
||||||
|
return this.selectComponent.selectedItems.map(t => t.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshDataSource(searchTerm:any = null, page:number = null, pageSize:number = null){
|
||||||
|
let searchfilters:ISimpleFilter[] = null;
|
||||||
|
if(searchTerm){
|
||||||
|
searchfilters = [<ISimpleFilter>{
|
||||||
|
path: this.searchPath || this.bindLabel,
|
||||||
|
type: this.searchType || 'Contains', // Default: Contains
|
||||||
|
value: searchTerm
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
this.dataSource.query({
|
||||||
|
page: page,
|
||||||
|
pageSize: pageSize,
|
||||||
|
filters:searchfilters,
|
||||||
|
sorts:[
|
||||||
|
{path: this.sortingPath || this.bindLabel, ascending: true}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasOptionTemplate() {
|
||||||
|
return this.optionTemplate ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get selectOptionTemplate(){
|
||||||
|
if (this.optionTemplate)
|
||||||
|
return this.optionTemplate.template;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasLabelTemplate() {
|
||||||
|
return this.labelTemplate ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get selectLabelTemplate(){
|
||||||
|
if (this.labelTemplate)
|
||||||
|
return this.labelTemplate.template;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
<ng-select [items]="data$ |async"
|
||||||
|
[bindLabel]="bindLabel"
|
||||||
|
[bindValue]="bindValue"
|
||||||
|
autofocus
|
||||||
|
[typeahead] = "searchInput$"
|
||||||
|
[trackByFn]="trackFn"
|
||||||
|
(change)="valueChanged($event)">
|
||||||
|
<ng-container *ngIf="hasOptionTemplate">
|
||||||
|
<ng-template ng-option-tmp let-item="item" let-index="index">
|
||||||
|
<ng-container [ngTemplateOutlet]="selectOptionTemplate"
|
||||||
|
[ngTemplateOutletContext]="{
|
||||||
|
$implicit: item,
|
||||||
|
index: index
|
||||||
|
}"></ng-container>
|
||||||
|
</ng-template>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngIf="hasLabelTemplate">
|
||||||
|
<ng-template ng-label-tmp let-item="item" let-index="index">
|
||||||
|
<ng-container [ngTemplateOutlet]="selectLabelTemplate"
|
||||||
|
[ngTemplateOutletContext]="{
|
||||||
|
$implicit: item,
|
||||||
|
index: index
|
||||||
|
}"></ng-container>
|
||||||
|
</ng-template>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngIf="hasNotFoundTemplate">
|
||||||
|
<ng-template ng-notfound-tmp let-searchTerm="searchTerm">
|
||||||
|
<ng-container [ngTemplateOutlet]="selectNotFoundTemplate"
|
||||||
|
[ngTemplateOutletContext]="{
|
||||||
|
$implicit: searchTerm
|
||||||
|
}"></ng-container>
|
||||||
|
</ng-template>
|
||||||
|
</ng-container>
|
||||||
|
</ng-select>
|
@ -0,0 +1,170 @@
|
|||||||
|
import { Component, OnInit, ContentChild, ViewChild, Input, Output, EventEmitter, ChangeDetectorRef, forwardRef, OnDestroy } from '@angular/core';
|
||||||
|
import { SelectLabelTemplateDirective } from '../directives/select-label-template.directive';
|
||||||
|
import { IDataSource, ISimpleFilter } from '@poweredsoft/data';
|
||||||
|
import { Observable, Subject, Subscription } from 'rxjs';
|
||||||
|
import { map, distinctUntilChanged, debounceTime } from 'rxjs/operators';
|
||||||
|
import { NgSelectComponent as SelectComponent } from '@ng-select/ng-select';
|
||||||
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||||
|
import { SelectOptionTemplateDirective } from '../directives/select-option-template.directive';
|
||||||
|
import { NotFoundTemplateDirective } from '../directives/not-found-template.directive';
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ps-ng-select',
|
||||||
|
templateUrl: './ng-select.component.html',
|
||||||
|
providers: [{
|
||||||
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
useExisting: forwardRef(() => NgSelectComponent),
|
||||||
|
multi: true
|
||||||
|
}],
|
||||||
|
styleUrls: ['./ng-select.component.scss']
|
||||||
|
})
|
||||||
|
export class NgSelectComponent implements OnInit,OnDestroy {
|
||||||
|
|
||||||
|
@ContentChild(SelectOptionTemplateDirective) optionTemplate: SelectOptionTemplateDirective;
|
||||||
|
@ContentChild(SelectLabelTemplateDirective) labelTemplate: SelectLabelTemplateDirective;
|
||||||
|
@ContentChild(NotFoundTemplateDirective) notFoundTemplate: NotFoundTemplateDirective;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ViewChild(SelectComponent, { static: true }) selectComponent: SelectComponent;
|
||||||
|
@Input() dataSource: IDataSource<any>;
|
||||||
|
@Input() searchPath: string;
|
||||||
|
@Input() searchType: string;
|
||||||
|
@Input() sortingPath: string;
|
||||||
|
@Input() serverFiltering:boolean;
|
||||||
|
@Input() bindLabel:string;
|
||||||
|
@Input() bindValue: string;
|
||||||
|
|
||||||
|
@Output('change') changeEvent = new EventEmitter();
|
||||||
|
|
||||||
|
trackFn: (item: any) => any;
|
||||||
|
data$ : Observable<any[]>;
|
||||||
|
isLoading:boolean = false;
|
||||||
|
searchInput$ = new Subject<string>();
|
||||||
|
|
||||||
|
private _loadingSubscription: Subscription;
|
||||||
|
|
||||||
|
constructor(private cdr: ChangeDetectorRef) {
|
||||||
|
this.trackFn = this.trackBy.bind(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.dataFetching();
|
||||||
|
this.detectLoading();
|
||||||
|
|
||||||
|
if(this.serverFiltering){
|
||||||
|
this.searchOnServer();
|
||||||
|
}else{
|
||||||
|
this.refreshDataSource();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
valueChanged(event) {
|
||||||
|
this.changeEvent.emit(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeValue(obj: any): void {
|
||||||
|
this.selectComponent.writeValue(obj);
|
||||||
|
}
|
||||||
|
registerOnChange(fn: any): void {
|
||||||
|
this.selectComponent.registerOnChange(fn);
|
||||||
|
}
|
||||||
|
registerOnTouched(fn: any): void {
|
||||||
|
this.selectComponent.registerOnTouched(fn);
|
||||||
|
}
|
||||||
|
setDisabledState?(isDisabled: boolean): void {
|
||||||
|
if (this.selectComponent.setDisabledState)
|
||||||
|
this.selectComponent.setDisabledState(isDisabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
trackBy(item: any) {
|
||||||
|
return this.dataSource.resolveIdField(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this._loadingSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dataFetching(){
|
||||||
|
this.data$ = this.dataSource.data$.pipe(
|
||||||
|
map(t => {
|
||||||
|
if (t == null)
|
||||||
|
return [];
|
||||||
|
return t.data;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
detectLoading(){
|
||||||
|
this._loadingSubscription = this.dataSource.loading$.subscribe(loading => {
|
||||||
|
this.isLoading = loading;
|
||||||
|
this.cdr.detectChanges();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
searchOnServer(){
|
||||||
|
this.searchInput$.pipe(
|
||||||
|
distinctUntilChanged(), // emit the difference from previous input
|
||||||
|
debounceTime(500) // this is for delaying searching speed
|
||||||
|
).subscribe(searchTerm => this.refreshDataSource(searchTerm, 1, 100)); // page: 1, pageSize: 50
|
||||||
|
|
||||||
|
this.refreshDataSource(); //send the query to server to sorting & filtering by default
|
||||||
|
}
|
||||||
|
|
||||||
|
get selectedModel() {
|
||||||
|
return this.selectComponent.hasValue ? this.selectComponent.selectedItems[0] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshDataSource(searchTerm:any = null, page:number = null, pageSize:number = null){
|
||||||
|
let searchfilters:ISimpleFilter[] = null;
|
||||||
|
if(searchTerm){
|
||||||
|
searchfilters = [<ISimpleFilter>{
|
||||||
|
path: this.searchPath || this.bindLabel,
|
||||||
|
type: this.searchType || 'Contains', // Default: Contains
|
||||||
|
value: searchTerm
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
this.dataSource.query({
|
||||||
|
page: page,
|
||||||
|
pageSize: pageSize,
|
||||||
|
filters:searchfilters,
|
||||||
|
sorts:[
|
||||||
|
{path: this.sortingPath || this.bindLabel, ascending: true}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasOptionTemplate() {
|
||||||
|
return this.optionTemplate ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get selectOptionTemplate(){
|
||||||
|
if (this.optionTemplate)
|
||||||
|
return this.optionTemplate.template;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasLabelTemplate() {
|
||||||
|
return this.labelTemplate ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get selectLabelTemplate(){
|
||||||
|
if (this.labelTemplate)
|
||||||
|
return this.labelTemplate.template;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasNotFoundTemplate() {
|
||||||
|
return this.notFoundTemplate ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get selectNotFoundTemplate(){
|
||||||
|
if(this.notFoundTemplate)
|
||||||
|
return this.notFoundTemplate.template;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { NgSelectComponent } from './ng-select/ng-select.component';
|
||||||
|
import { MultiSelectComponent } from './multi-select/multi-select.component';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { NgSelectModule } from '@ng-select/ng-select';
|
||||||
|
import { SelectLabelTemplateDirective } from './directives/select-label-template.directive';
|
||||||
|
import { SelectOptionTemplateDirective } from './directives/select-option-template.directive';
|
||||||
|
import { NotFoundTemplateDirective } from './directives/not-found-template.directive';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [NgSelectComponent, MultiSelectComponent, SelectLabelTemplateDirective, SelectOptionTemplateDirective, NotFoundTemplateDirective],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
FormsModule,
|
||||||
|
NgSelectModule,
|
||||||
|
],
|
||||||
|
exports:[
|
||||||
|
NgSelectComponent,
|
||||||
|
MultiSelectComponent,
|
||||||
|
SelectLabelTemplateDirective,
|
||||||
|
SelectOptionTemplateDirective,
|
||||||
|
NotFoundTemplateDirective
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class PsNgSelectModule { }//NGSELECT
|
10
projects/poweredsoft/ng-select/src/public-api.ts
Normal file
10
projects/poweredsoft/ng-select/src/public-api.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* Public API Surface of ng-select
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './lib/ps-ng-select/ps-ng-select.module';
|
||||||
|
export * from './lib/ps-ng-select/ng-select/ng-select.component';
|
||||||
|
export * from './lib/ps-ng-select/multi-select/multi-select.component';
|
||||||
|
export * from './lib/ps-ng-select/directives/select-label-template.directive';
|
||||||
|
export * from './lib/ps-ng-select/directives/select-option-template.directive';
|
||||||
|
export * from './lib/ps-ng-select/directives/not-found-template.directive';
|
26
projects/poweredsoft/ng-select/src/test.ts
Normal file
26
projects/poweredsoft/ng-select/src/test.ts
Normal file
@ -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);
|
23
projects/poweredsoft/ng-select/tsconfig.lib.json
Normal file
23
projects/poweredsoft/ng-select/tsconfig.lib.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../../out-tsc/lib",
|
||||||
|
"target": "es2015",
|
||||||
|
"declaration": true,
|
||||||
|
"inlineSources": true,
|
||||||
|
"types": [],
|
||||||
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"es2018"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"skipTemplateCodegen": true,
|
||||||
|
"strictMetadataEmit": true,
|
||||||
|
"enableResourceInlining": true
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"src/test.ts",
|
||||||
|
"**/*.spec.ts"
|
||||||
|
]
|
||||||
|
}
|
6
projects/poweredsoft/ng-select/tsconfig.lib.prod.json
Normal file
6
projects/poweredsoft/ng-select/tsconfig.lib.prod.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.lib.json",
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"enableIvy": false
|
||||||
|
}
|
||||||
|
}
|
17
projects/poweredsoft/ng-select/tsconfig.spec.json
Normal file
17
projects/poweredsoft/ng-select/tsconfig.spec.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../../out-tsc/spec",
|
||||||
|
"types": [
|
||||||
|
"jasmine",
|
||||||
|
"node"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/test.ts"
|
||||||
|
],
|
||||||
|
"include": [
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
17
projects/poweredsoft/ng-select/tslint.json
Normal file
17
projects/poweredsoft/ng-select/tslint.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../../tslint.json",
|
||||||
|
"rules": {
|
||||||
|
"directive-selector": [
|
||||||
|
true,
|
||||||
|
"attribute",
|
||||||
|
"lib",
|
||||||
|
"camelCase"
|
||||||
|
],
|
||||||
|
"component-selector": [
|
||||||
|
true,
|
||||||
|
"element",
|
||||||
|
"lib",
|
||||||
|
"kebab-case"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@poweredsoft/ngx-bootstrap",
|
"name": "@poweredsoft/ngx-bootstrap",
|
||||||
"version": "0.0.1",
|
"version": "0.0.3",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/common": "^9.1.9",
|
"@angular/common": "^9.1.9",
|
||||||
"@angular/core": "^9.1.9",
|
"@angular/core": "^9.1.9",
|
||||||
|
@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { ModalModule } from 'ngx-bootstrap/modal';
|
import { ModalModule } from 'ngx-bootstrap/modal';
|
||||||
import { CommandModalDirective } from './directives/command-modal.directive';
|
import { CommandModalDirective } from './directives/command-modal.directive';
|
||||||
import { CommandModalComponent } from './command-modal/command-modal.component';
|
import { CommandModalComponent } from './command-modal/command-modal.component';
|
||||||
import { InputValidatorDirective } from './directives/input-validator.directive';
|
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -12,7 +12,7 @@ import { FormsModule } from '@angular/forms';
|
|||||||
ModalModule.forRoot(),
|
ModalModule.forRoot(),
|
||||||
FormsModule
|
FormsModule
|
||||||
],
|
],
|
||||||
declarations: [CommandModalDirective, CommandModalComponent, InputValidatorDirective],
|
declarations: [CommandModalDirective, CommandModalComponent],
|
||||||
exports: [CommandModalDirective]
|
exports: [CommandModalDirective]
|
||||||
})
|
})
|
||||||
export class CommandModalModule { }
|
export class CommandModalModule { }
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-light" (click)="modalRef.hide()"
|
<button type="button" class="btn btn-light" (click)="modalRef.hide()"
|
||||||
[disabled]="loading">{{ cancelText }}</button>
|
[disabled]="loading">{{ cancelText }}</button>
|
||||||
<button type="button" class="btn btn-primary" [disabled]="loading" (click)="onSubmit()">{{ commandText }}</button>
|
<button type="button" class="btn btn-{{btnClass}}" [disabled]="loading" (click)="onSubmit()">{{ commandText }}</button>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<div class="progress" style="width: 100%" *ngIf="loading">
|
<div class="progress" style="width: 100%" *ngIf="loading">
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { CommandModalComponent } from './command-modal.component';
|
|
||||||
|
|
||||||
describe('CommandModalComponent', () => {
|
|
||||||
let component: CommandModalComponent;
|
|
||||||
let fixture: ComponentFixture<CommandModalComponent>;
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
declarations: [ CommandModalComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(CommandModalComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit, TemplateRef, OnDestroy } from '@angular/core';
|
import { Component, OnInit, TemplateRef, OnDestroy, EventEmitter } from '@angular/core';
|
||||||
import { IDataSource } from '@poweredsoft/data';
|
import { IDataSource } from '@poweredsoft/data';
|
||||||
import { BsModalRef } from 'ngx-bootstrap/modal';
|
import { BsModalRef } from 'ngx-bootstrap/modal';
|
||||||
import { finalize} from 'rxjs/operators';
|
import { finalize} from 'rxjs/operators';
|
||||||
@ -23,6 +23,8 @@ export class CommandModalComponent implements OnInit, OnDestroy {
|
|||||||
cancelText: string;
|
cancelText: string;
|
||||||
form:NgForm;
|
form:NgForm;
|
||||||
validationMessage:string ;
|
validationMessage:string ;
|
||||||
|
btnClass:string;
|
||||||
|
successEmitter: EventEmitter<any>;
|
||||||
|
|
||||||
private _notifyMessage: Subscription;
|
private _notifyMessage: Subscription;
|
||||||
private _validationError: Subscription;
|
private _validationError: Subscription;
|
||||||
@ -62,11 +64,12 @@ export class CommandModalComponent implements OnInit, OnDestroy {
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.subscribe(success => {
|
.subscribe(commandResult => {
|
||||||
if (this.refreshOnSuccess)
|
if (this.refreshOnSuccess)
|
||||||
this.dataSource.refresh();
|
this.dataSource.refresh();
|
||||||
|
|
||||||
this.modalRef.hide();
|
this.modalRef.hide();
|
||||||
|
this.successEmitter.emit(commandResult);
|
||||||
}, fail => {
|
}, fail => {
|
||||||
// you do not want to close on failure.. so just ignore..
|
// you do not want to close on failure.. so just ignore..
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Directive, HostListener, Input, TemplateRef } from '@angular/core';
|
import { Directive, HostListener, Input, TemplateRef, Output, EventEmitter } from '@angular/core';
|
||||||
import { IDataSource } from '@poweredsoft/data';
|
import { IDataSource } from '@poweredsoft/data';
|
||||||
import { BsModalService } from 'ngx-bootstrap/modal';
|
import { BsModalService } from 'ngx-bootstrap/modal';
|
||||||
import { CommandModalComponent } from '../command-modal/command-modal.component';
|
import { CommandModalComponent } from '../command-modal/command-modal.component';
|
||||||
@ -20,6 +20,9 @@ export class CommandModalDirective {
|
|||||||
@Input() commandText: string;
|
@Input() commandText: string;
|
||||||
@Input() cancelText: string;
|
@Input() cancelText: string;
|
||||||
@Input() animated: boolean;
|
@Input() animated: boolean;
|
||||||
|
@Input() btnClass:string;
|
||||||
|
|
||||||
|
@Output() success: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
@HostListener('click')
|
@HostListener('click')
|
||||||
wasClicked() {
|
wasClicked() {
|
||||||
@ -35,7 +38,9 @@ export class CommandModalDirective {
|
|||||||
title: this.commandTitle,
|
title: this.commandTitle,
|
||||||
refreshOnSuccess: this.refreshOnSuccess === undefined ? true : this.refreshOnSuccess,
|
refreshOnSuccess: this.refreshOnSuccess === undefined ? true : this.refreshOnSuccess,
|
||||||
commandText: this.commandText || 'OK',
|
commandText: this.commandText || 'OK',
|
||||||
cancelText: this.cancelText || 'Cancel'
|
cancelText: this.cancelText || 'Cancel',
|
||||||
|
successEmitter: this.success,
|
||||||
|
btnClass: this.btnClass || 'primary'
|
||||||
};
|
};
|
||||||
this.modalService.show(CommandModalComponent, {
|
this.modalService.show(CommandModalComponent, {
|
||||||
animated: this.animated === undefined ? true : this.animated,
|
animated: this.animated === undefined ? true : this.animated,
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
import { Directive } from '@angular/core';
|
|
||||||
import { Validator, AbstractControl, ValidationErrors, NG_VALIDATORS } from '@angular/forms';
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[psbxInputValidator]',
|
|
||||||
providers: [{ provide: NG_VALIDATORS, useExisting: InputValidatorDirective, multi: true }]
|
|
||||||
})
|
|
||||||
export class InputValidatorDirective implements Validator{
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
|
|
||||||
validate(control: AbstractControl): ValidationErrors {
|
|
||||||
throw new Error("Method not implemented.");
|
|
||||||
}
|
|
||||||
registerOnValidatorChange?(fn: () => void): void {
|
|
||||||
throw new Error("Method not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,16 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { CommandDirective } from './directives/command.directive';
|
||||||
|
import { ConfirmModalModule } from '../confirm-modal/confirm-modal.module';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [CommandDirective],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
ConfirmModalModule
|
||||||
|
],
|
||||||
|
exports:[CommandDirective]
|
||||||
|
})
|
||||||
|
export class CommandModule { }
|
@ -0,0 +1,70 @@
|
|||||||
|
import { Directive, Input, TemplateRef, HostListener, Output, EventEmitter } from '@angular/core';
|
||||||
|
import { IDataSource } from '@poweredsoft/data';
|
||||||
|
import { ConfirmModalService } from '../../confirm-modal/confirm-modal.service';
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[psbxCommand]'
|
||||||
|
})
|
||||||
|
export class CommandDirective {
|
||||||
|
|
||||||
|
constructor(private confirmModalService: ConfirmModalService) { }
|
||||||
|
|
||||||
|
|
||||||
|
@Input() dataSource: IDataSource<any>;
|
||||||
|
@Input() command: string;
|
||||||
|
@Input() model: any;
|
||||||
|
@Input() refreshOnSuccess: boolean;
|
||||||
|
@Input() animated: boolean;
|
||||||
|
|
||||||
|
@Input() confirm: boolean;
|
||||||
|
@Input() confirmMessage: string;
|
||||||
|
@Input() yesText: string;
|
||||||
|
@Input() noText: string;
|
||||||
|
@Input() yesClass: string;
|
||||||
|
@Input() noClass: string;
|
||||||
|
|
||||||
|
@Output() success: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
@Output() failure: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
private doCommand() {
|
||||||
|
this.dataSource.resolveCommandModelByName({
|
||||||
|
command: this.command,
|
||||||
|
model: this.model
|
||||||
|
}).subscribe(commandModel => {
|
||||||
|
this.dataSource.executeCommandByName(this.command, commandModel).subscribe(
|
||||||
|
commandResult => {
|
||||||
|
if (this.refreshOnSuccess !== false)
|
||||||
|
this.dataSource.refresh();
|
||||||
|
|
||||||
|
this.success.emit(commandResult);
|
||||||
|
},
|
||||||
|
commandError => {
|
||||||
|
this.failure.emit(commandError);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, resolveCommandError => {
|
||||||
|
this.failure.emit(resolveCommandError);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@HostListener('click')
|
||||||
|
wasClicked() {
|
||||||
|
|
||||||
|
if (this.confirm) {
|
||||||
|
this.confirmModalService.confirm({
|
||||||
|
message: this.confirmMessage,
|
||||||
|
yesText: this.yesText || 'yes',
|
||||||
|
yesClass: this.yesClass || 'danger',
|
||||||
|
noText: this.noText || 'no',
|
||||||
|
noClass: this.noClass || 'light',
|
||||||
|
}).subscribe(result => {
|
||||||
|
if (result)
|
||||||
|
this.doCommand();
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.doCommand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
import { Component, OnInit, TemplateRef } from '@angular/core';
|
import { Component, OnInit, TemplateRef, EventEmitter } from '@angular/core';
|
||||||
import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
|
import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
|
||||||
import { ConfirmModalService } from '../../confirm-modal.service';
|
|
||||||
import { Observer } from 'rxjs';
|
import { Observer } from 'rxjs';
|
||||||
|
|
||||||
|
|
||||||
@ -19,7 +18,7 @@ export class ConfirmModalComponent implements OnInit {
|
|||||||
noClass: string;
|
noClass: string;
|
||||||
observer: Observer<boolean>;
|
observer: Observer<boolean>;
|
||||||
|
|
||||||
constructor(private modelRef: BsModalRef, private actionService: ConfirmModalService) {
|
constructor(private modelRef: BsModalRef) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,11 +27,11 @@ export class ConfirmModalComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get yesButtonClass() {
|
get yesButtonClass() {
|
||||||
return `btn btn-sm btn-${this.yesClass}`
|
return `btn btn-${this.yesClass}`
|
||||||
}
|
}
|
||||||
|
|
||||||
get noButtonClass() {
|
get noButtonClass() {
|
||||||
return `btn btn-sm btn-${this.noClass}`
|
return `btn btn-${this.noClass}`
|
||||||
}
|
}
|
||||||
|
|
||||||
confirm(): void {
|
confirm(): void {
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
import { Directive, Input, TemplateRef, HostListener } from '@angular/core';
|
|
||||||
import { ConfirmModalService } from './confirm-modal.service';
|
|
||||||
import { IDataSource } from '@poweredsoft/data';
|
|
||||||
|
|
||||||
@Directive({
|
|
||||||
selector: '[psbxConfirmModal]'
|
|
||||||
})
|
|
||||||
export class ConfirmModalDirective {
|
|
||||||
|
|
||||||
constructor(private confirmModalService: ConfirmModalService) { }
|
|
||||||
|
|
||||||
|
|
||||||
@Input() dataSource: IDataSource<any>;
|
|
||||||
@Input() command: string;
|
|
||||||
@Input() model: any;
|
|
||||||
@Input() template: TemplateRef<any>;
|
|
||||||
@Input() commandTitle: string;
|
|
||||||
@Input() refreshOnSuccess: boolean;
|
|
||||||
@Input() commandText: string;
|
|
||||||
@Input() cancelText: string;
|
|
||||||
@Input() animated: boolean;
|
|
||||||
|
|
||||||
|
|
||||||
@HostListener('click')
|
|
||||||
wasClicked() {
|
|
||||||
this.dataSource.resolveCommandModelByName({
|
|
||||||
command: this.command,
|
|
||||||
model: this.model
|
|
||||||
}).subscribe(commandModel => {
|
|
||||||
this.confirmModalService.confirm({
|
|
||||||
message: 'Do you want to delete this merchant?',
|
|
||||||
yesText: 'yes delete this merchant',
|
|
||||||
yesClass: 'danger',
|
|
||||||
noText: 'no please dont',
|
|
||||||
noClass: 'light'
|
|
||||||
}).subscribe(result => {
|
|
||||||
if(result){
|
|
||||||
this.dataSource.executeCommandByName(this.command, commandModel).subscribe(
|
|
||||||
res => {
|
|
||||||
this.dataSource.refresh();
|
|
||||||
},
|
|
||||||
err => {
|
|
||||||
console.log(err);
|
|
||||||
alert('failed');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}, error => {
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -3,18 +3,20 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { ConfirmModalComponent } from './confirm-modal-components/confirm-modal/confirm-modal.component';
|
import { ConfirmModalComponent } from './confirm-modal-components/confirm-modal/confirm-modal.component';
|
||||||
import { ModalModule } from 'ngx-bootstrap/modal';
|
import { ModalModule } from 'ngx-bootstrap/modal';
|
||||||
import { ConfirmModalService } from './confirm-modal.service';
|
import { ConfirmModalService } from './confirm-modal.service';
|
||||||
import { ConfirmModalDirective } from './confirm-modal.directive';
|
import { CommandModule } from '../command/command.module';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [ConfirmModalComponent, ConfirmModalDirective],
|
declarations: [ConfirmModalComponent],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
//CommandModule,
|
||||||
ModalModule.forRoot(),
|
ModalModule.forRoot(),
|
||||||
|
|
||||||
],
|
],
|
||||||
exports:[ConfirmModalDirective],
|
exports:[],
|
||||||
providers: [ConfirmModalService]
|
providers: [ConfirmModalService]
|
||||||
})
|
})
|
||||||
export class ConfirmModalModule { }
|
export class ConfirmModalModule { }
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { DataSourceTextFilterComponent } from './text-filter/data-source-text-filter.component';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { DataSourceNumberFilterComponent } from './number-filter/data-source-number-filter.component';
|
||||||
|
import { DataSourceDatetimeFilterComponent } from './datetime-filter/data-source-datetime-filter.component';
|
||||||
|
import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
|
||||||
|
import { PopoverModule } from 'ngx-bootstrap/popover';
|
||||||
|
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
|
||||||
|
import { TooltipModule } from 'ngx-bootstrap/tooltip';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [DataSourceTextFilterComponent, DataSourceNumberFilterComponent,DataSourceDatetimeFilterComponent],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
FormsModule,
|
||||||
|
BsDatepickerModule.forRoot(),
|
||||||
|
PopoverModule.forRoot(),
|
||||||
|
BsDropdownModule.forRoot(),
|
||||||
|
TooltipModule.forRoot()
|
||||||
|
],
|
||||||
|
exports: [DataSourceTextFilterComponent, DataSourceNumberFilterComponent,DataSourceDatetimeFilterComponent]
|
||||||
|
})
|
||||||
|
export class DataSourceFilterModule { }
|
@ -0,0 +1,76 @@
|
|||||||
|
<ng-template #popTemplate>
|
||||||
|
<form (ngSubmit)="applyFilter()" novalidate>
|
||||||
|
<div class="container" >
|
||||||
|
<div class="row">
|
||||||
|
<select class="custom-select" title="Choose one of the following..." [(ngModel)]="filterType" [ngModelOptions]="{standalone: true}">
|
||||||
|
<option *ngFor="let filter of filterTypes" [value]="filter.value">{{filter.key}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-1 mb-1">
|
||||||
|
<input *ngIf="!isRangeFilter"
|
||||||
|
type="text"
|
||||||
|
placeholder="Datepicker"
|
||||||
|
class="form-control"
|
||||||
|
bsDatepicker [(ngModel)]="filterValue" [ngModelOptions]="{standalone: true}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-1 mb-1">
|
||||||
|
<input *ngIf="isRangeFilter" type="text"
|
||||||
|
placeholder="Daterangepicker"
|
||||||
|
class="form-control"
|
||||||
|
bsDaterangepicker [(ngModel)]="filterValue" [ngModelOptions]="{standalone: true}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-2">
|
||||||
|
<button class="btn btn-primary mr-1" type="submit" >Filter</button>
|
||||||
|
<button type="button" class="btn btn-warning" *ngIf="!isFiltering" (click)="pop.hide()">Hide</button>
|
||||||
|
<button type="button" class="btn btn-dark" *ngIf="isFiltering" (click)="clearFilter()">Clear</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<button [popover]="popTemplate" class="btn btn-default" [(isOpen)]="filterPopUpOpened" [outsideClick]="true" #pop="bs-popover">
|
||||||
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 477.875 477.875" style="enable-background:new 0 0 477.875 477.875;" xml:space="preserve" fill-opacity="0.5" [tooltip]="showTooltip()" [tooltipEnable]="!filterPopUpOpened" width="13px" height="13px" [ngStyle]="{'fill': isFiltering ? 'red': 'black', 'fill-opacity': isFiltering ? '1': '0.5'}">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M460.804,0H17.071C7.645,0,0.004,7.641,0.004,17.067V102.4c-0.004,4.842,2.05,9.458,5.649,12.698l165.018,148.514V460.8
|
||||||
|
c-0.004,9.426,7.633,17.07,17.059,17.075c2.651,0.001,5.266-0.615,7.637-1.8l102.4-51.2c5.786-2.891,9.441-8.806,9.438-15.275
|
||||||
|
V263.612l165.018-148.48c3.608-3.247,5.662-7.878,5.649-12.732V17.067C477.871,7.641,470.23,0,460.804,0z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</button>
|
@ -0,0 +1,150 @@
|
|||||||
|
import { Component, OnInit, Input, Output, EventEmitter} from '@angular/core';
|
||||||
|
import { IDataSource, ISimpleFilter, ICompositeFilter, IFilter,FilterType } from '@poweredsoft/data';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'psbx-ds-datetime-filter',
|
||||||
|
templateUrl: './data-source-datetime-filter.component.html',
|
||||||
|
styleUrls: ['./data-source-datetime-filter.component.scss']
|
||||||
|
})
|
||||||
|
export class DataSourceDatetimeFilterComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input() path: string;
|
||||||
|
@Input() dataSource : IDataSource<any>;
|
||||||
|
@Input() filterType: string;
|
||||||
|
@Output() filterTypeChanged: EventEmitter<string> = new EventEmitter<string>();
|
||||||
|
|
||||||
|
filterPopUpOpened: boolean = false;
|
||||||
|
isFiltering: boolean;
|
||||||
|
filterValue: Date = null;
|
||||||
|
filterTypes = [
|
||||||
|
{key:'Equal', value: 'Equal'},
|
||||||
|
{key:'Greater Than', value: 'GreaterThan'},
|
||||||
|
{key:'Less Than', value: 'LessThan'},
|
||||||
|
{key:'Greater Than Equal', value: 'GreaterThanOrEqual'},
|
||||||
|
{key:'Less Than Equal', value: 'LessThanOrEqual'},
|
||||||
|
{key:'Range', value: FilterType.COMPOSITE }
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
bsInlineValue = new Date();
|
||||||
|
bsInlineRangeValue: Date[];
|
||||||
|
maxDate = new Date();
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.maxDate.setDate(this.maxDate.getDate() + 7);
|
||||||
|
this.bsInlineRangeValue = [this.bsInlineValue, this.maxDate];
|
||||||
|
}
|
||||||
|
|
||||||
|
get isRangeFilter() {
|
||||||
|
return this.filterType == FilterType.COMPOSITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
if (!this.filterType)
|
||||||
|
this.filterType = 'Equal';
|
||||||
|
}
|
||||||
|
showTooltip(){
|
||||||
|
return "Filter by "+ this.path;
|
||||||
|
}
|
||||||
|
clearFilter() {
|
||||||
|
|
||||||
|
this.filterValue = null;
|
||||||
|
this.isFiltering = false;
|
||||||
|
const existingFilter = this.dataSource.filters.find(t => (t as ISimpleFilter).path == this.path) as ISimpleFilter;
|
||||||
|
if (existingFilter) {
|
||||||
|
this.dataSource.query({
|
||||||
|
page: 1,
|
||||||
|
filters: this.dataSource.filters.filter(t => t != existingFilter)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isRangeFilter){
|
||||||
|
|
||||||
|
let existingFilter2 = this.dataSource.filters.find(t=> t.type == 'Composite');
|
||||||
|
this.dataSource.query({
|
||||||
|
page: 1,
|
||||||
|
filters: this.dataSource.filters.filter(t => t != existingFilter2)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
applyFilter(){
|
||||||
|
|
||||||
|
this.isFiltering = true;
|
||||||
|
const filters = this.dataSource.filters;
|
||||||
|
let compositeF: any = null;
|
||||||
|
let freshFilter: ISimpleFilter = null;
|
||||||
|
let startDate:Date;
|
||||||
|
let endDate:Date;
|
||||||
|
|
||||||
|
// TODO create filter here.
|
||||||
|
if(Array.isArray(this.filterValue)){ //check if it's a dateRange value
|
||||||
|
startDate = this.filterValue[0];
|
||||||
|
endDate = this.filterValue[1];
|
||||||
|
compositeF = {
|
||||||
|
type: FilterType.COMPOSITE,
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
path: this.path,
|
||||||
|
type: 'GREATERTHANOREQUAL',
|
||||||
|
value: startDate,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
and: true,
|
||||||
|
path: this.path,
|
||||||
|
type: 'LESSTHANOREQUAL',
|
||||||
|
value: endDate,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
freshFilter = {
|
||||||
|
type: this.filterType,
|
||||||
|
and: true,
|
||||||
|
path: this.path,
|
||||||
|
value: this.filterValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO???
|
||||||
|
// set this for gql better handling of variant.
|
||||||
|
//(freshFilter as IGraphQLFilter).__gqlVariantType = 'DATETIME';
|
||||||
|
|
||||||
|
|
||||||
|
const existingFilterIndex = filters.findIndex(t => {
|
||||||
|
if (t.type == 'COMPOSITE') {
|
||||||
|
const compositeFilter = t as ICompositeFilter;
|
||||||
|
return compositeFilter.filters && compositeFilter.filters.length
|
||||||
|
&& compositeFilter[0].path == this.path;
|
||||||
|
} else {
|
||||||
|
return (t as ISimpleFilter).path == this.path;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingFilterIndex == -1) {
|
||||||
|
// create it.
|
||||||
|
if(compositeF){
|
||||||
|
filters.push(compositeF);
|
||||||
|
}else{
|
||||||
|
filters.push(freshFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// replace it.
|
||||||
|
if(compositeF){
|
||||||
|
filters[existingFilterIndex] = compositeF;
|
||||||
|
}else{
|
||||||
|
filters[existingFilterIndex] = freshFilter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dataSource.query({
|
||||||
|
filters: filters,
|
||||||
|
page: 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
<ng-template #popTemplate>
|
||||||
|
<form (ngSubmit)="applyFilter()" novalidate>
|
||||||
|
<div class="container" >
|
||||||
|
<div class="row">
|
||||||
|
<select class="custom-select" title="Choose one of the following..." [(ngModel)]="filterType" [ngModelOptions]="{standalone: true}">
|
||||||
|
<option *ngFor="let filter of filterTypes" [value]="filter.value">{{filter.key}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-1 mb-1">
|
||||||
|
<input type="number" class="form-control" placeholder="Value" aria-label="number"
|
||||||
|
aria-describedby="basic-addon1" [(ngModel)]="filterValue" [ngModelOptions]="{standalone: true}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="btn btn-primary mr-1">Filter</button>
|
||||||
|
<button type="button" class="btn btn-warning" *ngIf="!isFiltering" (click)="pop.hide()">Hide</button>
|
||||||
|
<button type="button" class="btn btn-dark" *ngIf="isFiltering" (click)="clearFilter()">Clear</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<button [popover]="popTemplate" class="btn btn-default" [(isOpen)]="filterIsOpenned" [outsideClick]="true" #pop="bs-popover">
|
||||||
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 477.875 477.875" style="enable-background:new 0 0 477.875 477.875;" xml:space="preserve" fill-opacity="0.5" [tooltip]="showTooltip()" [tooltipEnable]="!filterIsOpenned" width="13px" height="13px" [ngStyle]="{'fill': isFiltering ? 'red': 'black', 'fill-opacity': isFiltering ? '1': '0.5'}">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M460.804,0H17.071C7.645,0,0.004,7.641,0.004,17.067V102.4c-0.004,4.842,2.05,9.458,5.649,12.698l165.018,148.514V460.8
|
||||||
|
c-0.004,9.426,7.633,17.07,17.059,17.075c2.651,0.001,5.266-0.615,7.637-1.8l102.4-51.2c5.786-2.891,9.441-8.806,9.438-15.275
|
||||||
|
V263.612l165.018-148.48c3.608-3.247,5.662-7.878,5.649-12.732V17.067C477.871,7.641,470.23,0,460.804,0z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</button>
|
@ -0,0 +1,71 @@
|
|||||||
|
import { Component, OnInit, Input, Output, EventEmitter, ElementRef, ViewChild } from '@angular/core';
|
||||||
|
import { IDataSource,IFilter, ISimpleFilter } from '@poweredsoft/data';
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'psbx-ds-number-filter',
|
||||||
|
templateUrl: './data-source-number-filter.component.html',
|
||||||
|
styleUrls: ['./data-source-number-filter.component.scss']
|
||||||
|
})
|
||||||
|
export class DataSourceNumberFilterComponent implements OnInit {
|
||||||
|
@Input() dataSource : IDataSource<any>;
|
||||||
|
@Input() path:string;
|
||||||
|
|
||||||
|
filterType: string = 'Equal';
|
||||||
|
filterValue: number = 0;
|
||||||
|
isFiltering: boolean;
|
||||||
|
filterTypes = [
|
||||||
|
{key:'Equals', value: 'Equal'},
|
||||||
|
{key:'Greater Than', value: 'GreaterThan'},
|
||||||
|
{key:'Less Than', value: 'LessThan'},
|
||||||
|
{key:'Greater Than Equal', value: 'GreaterThanOrEqual'},
|
||||||
|
{key:'Less Than Equal', value: 'LessThanOrEqual'},
|
||||||
|
];
|
||||||
|
filterIsOpenned: boolean = false;
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
clearFilter() {
|
||||||
|
this.filterValue = 0;
|
||||||
|
this.isFiltering = false;
|
||||||
|
const existingFilter = this.dataSource.filters.find(t => (t as ISimpleFilter).path == this.path) as ISimpleFilter;
|
||||||
|
if (existingFilter) {
|
||||||
|
this.dataSource.query({
|
||||||
|
page: 1,
|
||||||
|
filters: this.dataSource.filters.filter(t => t != existingFilter)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applyFilter(){
|
||||||
|
this.isFiltering = true;
|
||||||
|
const filters = this.dataSource.filters;
|
||||||
|
const existingFilter = filters.find(t => (t as ISimpleFilter).path == this.path) as ISimpleFilter;
|
||||||
|
if (existingFilter) {
|
||||||
|
existingFilter.type = this.filterType;
|
||||||
|
existingFilter.value =this.filterValue.toString();
|
||||||
|
} else {
|
||||||
|
filters.push(<ISimpleFilter>{
|
||||||
|
and: true,
|
||||||
|
type: this.filterType,
|
||||||
|
path: this.path,
|
||||||
|
value: this.filterValue.toString()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dataSource.query({
|
||||||
|
filters: filters,
|
||||||
|
page: 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
showTooltip(){
|
||||||
|
return "Filter by "+ this.path;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
<ng-template #popTemplate>
|
||||||
|
|
||||||
|
<form (ngSubmit)="applyFilter(pop)" novalidate>
|
||||||
|
|
||||||
|
<div class="container" >
|
||||||
|
<div class="row">
|
||||||
|
<select class="custom-select" title="Choose one of the following..." [(ngModel)]="filterType" [ngModelOptions]="{standalone: true}">
|
||||||
|
<option *ngFor="let filter of filterTypes" [value]="filter.value">{{filter.key}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-1 mb-1">
|
||||||
|
<input type="text" class="form-control" placeholder="Value" aria-label="Username"
|
||||||
|
aria-describedby="basic-addon1" [(ngModel)]="filterValue" [ngModelOptions]="{standalone: true}" >
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="btn btn-primary mr-1" type="submit">Filter</button>
|
||||||
|
<button type="button" class="btn btn-warning" *ngIf="!isFiltering" (click)="pop.hide()">Hide</button>
|
||||||
|
<button type="button" class="btn btn-dark" *ngIf="isFiltering" (click)="clearFilter()">Clear</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<button [popover]="popTemplate" class="btn btn-default" [(isOpen)]="filterIsOpenned" [outsideClick]="true" #pop="bs-popover">
|
||||||
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 477.875 477.875" style="enable-background:new 0 0 477.875 477.875;" xml:space="preserve" fill-opacity="0.5" [tooltip]="showTooltip()" [tooltipEnable]="!filterIsOpenned" width="13px" height="13px" [ngStyle]="{'fill': isFiltering ? 'red': 'black', 'fill-opacity': isFiltering ? '1': '0.5'}">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M460.804,0H17.071C7.645,0,0.004,7.641,0.004,17.067V102.4c-0.004,4.842,2.05,9.458,5.649,12.698l165.018,148.514V460.8
|
||||||
|
c-0.004,9.426,7.633,17.07,17.059,17.075c2.651,0.001,5.266-0.615,7.637-1.8l102.4-51.2c5.786-2.891,9.441-8.806,9.438-15.275
|
||||||
|
V263.612l165.018-148.48c3.608-3.247,5.662-7.878,5.649-12.732V17.067C477.871,7.641,470.23,0,460.804,0z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</button>
|
@ -0,0 +1,75 @@
|
|||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { IDataSource} from '@poweredsoft/data';
|
||||||
|
import { ISimpleFilter } from '@poweredsoft/data';
|
||||||
|
import { PopoverDirective } from 'ngx-bootstrap/popover';
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'psbx-ds-text-filter',
|
||||||
|
templateUrl: './data-source-text-filter.component.html',
|
||||||
|
styleUrls: ['./data-source-text-filter.component.scss']
|
||||||
|
})
|
||||||
|
export class DataSourceTextFilterComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input() dataSource : IDataSource<any>;
|
||||||
|
@Input() path:string;
|
||||||
|
|
||||||
|
filterType: string = 'Contains';
|
||||||
|
filterValue: string = null;
|
||||||
|
isFiltering: boolean;
|
||||||
|
filterTypes = [
|
||||||
|
{key:'Contains', value: 'Contains'},
|
||||||
|
{key:'Equals', value: 'Equal'},
|
||||||
|
{key:'Starts With', value: 'startsWith'},
|
||||||
|
{key:'Ends With', value: 'endsWith'}
|
||||||
|
];
|
||||||
|
filterIsOpenned: boolean = false;
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
clearFilter() {
|
||||||
|
this.filterValue = '';
|
||||||
|
this.isFiltering = false;
|
||||||
|
const existingFilter = this.dataSource.filters.find(t => (t as ISimpleFilter).path == this.path) as ISimpleFilter;
|
||||||
|
if (existingFilter) {
|
||||||
|
this.dataSource.query({
|
||||||
|
page: 1,
|
||||||
|
filters: this.dataSource.filters.filter(t => t != existingFilter)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applyFilter(pop: PopoverDirective = null){
|
||||||
|
this.isFiltering = true;
|
||||||
|
const filters = this.dataSource.filters;
|
||||||
|
const existingFilter = filters.find(t => (t as ISimpleFilter).path == this.path) as ISimpleFilter;
|
||||||
|
if (existingFilter) {
|
||||||
|
existingFilter.type = this.filterType;
|
||||||
|
existingFilter.value = this.filterValue;
|
||||||
|
} else {
|
||||||
|
filters.push(<ISimpleFilter>{
|
||||||
|
and: true,
|
||||||
|
type: this.filterType,
|
||||||
|
path: this.path,
|
||||||
|
value: this.filterValue
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dataSource.query({
|
||||||
|
filters: filters,
|
||||||
|
page: 1
|
||||||
|
})
|
||||||
|
|
||||||
|
if (pop)
|
||||||
|
pop.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
showTooltip(){
|
||||||
|
return "Filter by "+ this.path;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { DataSourceSortingComponent } from './ds-sorting/data-source-sorting.component';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [DataSourceSortingComponent],
|
||||||
|
imports: [
|
||||||
|
CommonModule
|
||||||
|
],
|
||||||
|
exports:[DataSourceSortingComponent]
|
||||||
|
})
|
||||||
|
export class DataSourceSortingModule { }
|
@ -0,0 +1,3 @@
|
|||||||
|
<span>
|
||||||
|
<span class="caret dropdown-toggle" [class.not-sorting-state]="!isSorting" [class.sort-desc]="!isAscending" (click)="sorting()"></span>
|
||||||
|
</span>
|
@ -0,0 +1,16 @@
|
|||||||
|
:host span.dropdown-toggle.sort-desc{
|
||||||
|
transform: rotate(180deg);
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host span{
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host .not-sorting-state{
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host .not-sorting-state:hover{
|
||||||
|
opacity: 1;
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
import { IDataSource } from '@poweredsoft/data';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'psbx-ds-sorting',
|
||||||
|
templateUrl: './data-source-sorting.component.html',
|
||||||
|
styleUrls: ['./data-source-sorting.component.scss']
|
||||||
|
})
|
||||||
|
export class DataSourceSortingComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input() dataSource : IDataSource<any>;
|
||||||
|
@Input() path:string;
|
||||||
|
isSorting: boolean =false;
|
||||||
|
isAscending:boolean = false;
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
sorting(){
|
||||||
|
this.isSorting = true;
|
||||||
|
this.isAscending = !this.isAscending;
|
||||||
|
const existingSort = this.dataSource.sorts.find(t => t.path == this.path);
|
||||||
|
if (existingSort){
|
||||||
|
existingSort.ascending = (this.isAscending)? true : false;
|
||||||
|
}else{
|
||||||
|
this.dataSource.sorts.push({
|
||||||
|
path: this.path,
|
||||||
|
ascending: (this.isAscending)? true : false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.dataSource.query({
|
||||||
|
sorts: this.dataSource.sorts,
|
||||||
|
page: 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -29,9 +29,10 @@ export class FormGroupCommandModalDirective {
|
|||||||
@Input() refreshOnSuccess: boolean;
|
@Input() refreshOnSuccess: boolean;
|
||||||
@Input() commandText: string;
|
@Input() commandText: string;
|
||||||
@Input() cancelText: string;
|
@Input() cancelText: string;
|
||||||
@Input() isConfirmModal:boolean;
|
|
||||||
@Output() formCreate: EventEmitter<IModelFormCreateEvent> = new EventEmitter<IModelFormCreateEvent>();
|
@Output() formCreate: EventEmitter<IModelFormCreateEvent> = new EventEmitter<IModelFormCreateEvent>();
|
||||||
|
|
||||||
|
@Output() success: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
constructor(private modalService: BsModalService) { }
|
constructor(private modalService: BsModalService) { }
|
||||||
|
|
||||||
@HostListener('click')
|
@HostListener('click')
|
||||||
@ -47,25 +48,6 @@ export class FormGroupCommandModalDirective {
|
|||||||
shouldSetCommandModel: true
|
shouldSetCommandModel: true
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.isConfirmModal){
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
dataSource: this.dataSource,
|
|
||||||
command: this.command,
|
|
||||||
template: this.template,
|
|
||||||
title: this.commandTitle,
|
|
||||||
refreshOnSuccess: this.refreshOnSuccess === undefined ? true : this.refreshOnSuccess,
|
|
||||||
commandText: this.commandText || 'OK',
|
|
||||||
cancelText: this.cancelText || 'Cancel',
|
|
||||||
commandModel:commandModel
|
|
||||||
};
|
|
||||||
|
|
||||||
this.modalService.show(ConfirmModalComponent, {
|
|
||||||
animated: this.animated === undefined ? true : this.animated,
|
|
||||||
initialState
|
|
||||||
});
|
|
||||||
|
|
||||||
}else{
|
|
||||||
this.formCreate.emit(event);
|
this.formCreate.emit(event);
|
||||||
if (event.formGroup == null)
|
if (event.formGroup == null)
|
||||||
throw new Error('form group should be set, after form createEvent');
|
throw new Error('form group should be set, after form createEvent');
|
||||||
@ -82,61 +64,18 @@ export class FormGroupCommandModalDirective {
|
|||||||
commandText: this.commandText || 'OK',
|
commandText: this.commandText || 'OK',
|
||||||
cancelText: this.cancelText || 'Cancel',
|
cancelText: this.cancelText || 'Cancel',
|
||||||
modelForm: event.formGroup,
|
modelForm: event.formGroup,
|
||||||
commandModel:commandModel
|
commandModel:commandModel,
|
||||||
|
successEmitter: this.success
|
||||||
};
|
};
|
||||||
|
|
||||||
this.modalService.show(FormGroupCommandModalComponent, {
|
this.modalService.show(FormGroupCommandModalComponent, {
|
||||||
animated: this.animated === undefined ? true : this.animated,
|
animated: this.animated === undefined ? true : this.animated,
|
||||||
initialState
|
initialState
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}, error => {
|
}, error => {
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// @HostListener('click')
|
|
||||||
// wasClicked() {
|
|
||||||
// this.dataSource.resolveCommandModelByName({
|
|
||||||
// command: this.command,
|
|
||||||
// model: this.model
|
|
||||||
// }).subscribe(commandModel => {
|
|
||||||
// debugger;
|
|
||||||
// const event = <IModelFormCreateEvent>{
|
|
||||||
// commandName: this.command,
|
|
||||||
// viewModel: this.model,
|
|
||||||
// commandModel: commandModel,
|
|
||||||
// shouldSetCommandModel: true
|
|
||||||
// }
|
|
||||||
|
|
||||||
// this.formCreate.emit(event);
|
|
||||||
|
|
||||||
// if (event.formGroup == null)
|
|
||||||
// throw new Error('form group should be set, after form createEvent');
|
|
||||||
|
|
||||||
// if (event.shouldSetCommandModel)
|
|
||||||
// event.formGroup.patchValue(commandModel);
|
|
||||||
|
|
||||||
// const initialState = {
|
|
||||||
// dataSource: this.dataSource,
|
|
||||||
// command: this.command,
|
|
||||||
// template: this.template,
|
|
||||||
// title: this.commandTitle,
|
|
||||||
// refreshOnSuccess: this.refreshOnSuccess === undefined ? true : this.refreshOnSuccess,
|
|
||||||
// commandText: this.commandText || 'OK',
|
|
||||||
// cancelText: this.cancelText || 'Cancel',
|
|
||||||
// modelForm: event.formGroup,
|
|
||||||
// commandModel:commandModel
|
|
||||||
// };
|
|
||||||
|
|
||||||
// this.modalService.show(FormGroupCommandModalComponent, {
|
|
||||||
// animated: this.animated === undefined ? true : this.animated,
|
|
||||||
// initialState
|
|
||||||
// });
|
|
||||||
|
|
||||||
// }, error => {
|
|
||||||
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit, TemplateRef } from '@angular/core';
|
import { Component, OnInit, TemplateRef, OnDestroy, EventEmitter } from '@angular/core';
|
||||||
import { BsModalRef } from 'ngx-bootstrap/modal';
|
import { BsModalRef } from 'ngx-bootstrap/modal';
|
||||||
import { IDataSource } from '@poweredsoft/data';
|
import { IDataSource } from '@poweredsoft/data';
|
||||||
import { finalize } from 'rxjs/operators';
|
import { finalize } from 'rxjs/operators';
|
||||||
@ -10,7 +10,7 @@ import { FormGroup, FormControl } from '@angular/forms';
|
|||||||
templateUrl: './form-group-command-modal.component.html',
|
templateUrl: './form-group-command-modal.component.html',
|
||||||
styleUrls: ['./form-group-command-modal.component.scss']
|
styleUrls: ['./form-group-command-modal.component.scss']
|
||||||
})
|
})
|
||||||
export class FormGroupCommandModalComponent implements OnInit {
|
export class FormGroupCommandModalComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
|
||||||
modelForm: FormGroup;
|
modelForm: FormGroup;
|
||||||
@ -24,10 +24,13 @@ export class FormGroupCommandModalComponent implements OnInit {
|
|||||||
cancelText: string;
|
cancelText: string;
|
||||||
errorMessage: string;
|
errorMessage: string;
|
||||||
commandModel:any;
|
commandModel:any;
|
||||||
|
successEmitter: EventEmitter<any>;
|
||||||
|
|
||||||
private _notifyMessage: Subscription;
|
private _notifyMessage: Subscription;
|
||||||
private _validationError: Subscription;
|
private _validationError: Subscription;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor(public modalRef: BsModalRef) { }
|
constructor(public modalRef: BsModalRef) { }
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
@ -37,9 +40,9 @@ export class FormGroupCommandModalComponent implements OnInit {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.errorMessage = null;
|
this.errorMessage = null;
|
||||||
// this._notifyMessage = this.dataSource.notifyMessage$.subscribe(message => {
|
this._notifyMessage = this.dataSource.notifyMessage$.subscribe(message => {
|
||||||
|
|
||||||
// });
|
});
|
||||||
|
|
||||||
this._validationError = this.dataSource.validationError$.subscribe(validatorErrors => {
|
this._validationError = this.dataSource.validationError$.subscribe(validatorErrors => {
|
||||||
let validationSummary = '';
|
let validationSummary = '';
|
||||||
@ -71,11 +74,12 @@ export class FormGroupCommandModalComponent implements OnInit {
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.subscribe(success => {
|
.subscribe(commandResult => {
|
||||||
if (this.refreshOnSuccess)
|
if (this.refreshOnSuccess)
|
||||||
this.dataSource.refresh();
|
this.dataSource.refresh();
|
||||||
|
|
||||||
this.modalRef.hide();
|
this.modalRef.hide();
|
||||||
|
this.successEmitter.emit(commandResult);
|
||||||
}, fail => {
|
}, fail => {
|
||||||
// you do not want to close on failure.. so just ignore..
|
// you do not want to close on failure.. so just ignore..
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { DataSourcePaginationComponent } from './data-source-pagination/data-source-pagination.component';
|
import { DataSourcePaginationComponent } from './data-source-pagination/data-source-pagination.component';
|
||||||
import { PaginationModule } from 'ngx-bootstrap/pagination';
|
import { PaginationModule as ValorPaginationModule } from 'ngx-bootstrap/pagination';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
|
||||||
@ -9,9 +9,9 @@ import { FormsModule } from '@angular/forms';
|
|||||||
declarations: [DataSourcePaginationComponent],
|
declarations: [DataSourcePaginationComponent],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
PaginationModule.forRoot(),
|
ValorPaginationModule.forRoot(),
|
||||||
FormsModule
|
FormsModule
|
||||||
],
|
],
|
||||||
exports:[DataSourcePaginationComponent]
|
exports:[DataSourcePaginationComponent]
|
||||||
})
|
})
|
||||||
export class psbxPaginationModule { }
|
export class PaginationModule { }
|
@ -6,10 +6,17 @@ export * from './lib/command-modal/command-modal.module';
|
|||||||
export * from './lib/command-modal/directives/command-modal.directive';
|
export * from './lib/command-modal/directives/command-modal.directive';
|
||||||
export * from './lib/form-group-command-modal/form-group-command-modal.module';
|
export * from './lib/form-group-command-modal/form-group-command-modal.module';
|
||||||
export * from './lib/form-group-command-modal/directives/form-group-command-modal.directive';
|
export * from './lib/form-group-command-modal/directives/form-group-command-modal.directive';
|
||||||
export * from './lib/pagination/psbxPagination.module';
|
export * from './lib/pagination/Pagination.module';
|
||||||
export * from './lib/pagination/data-source-pagination/data-source-pagination.component';
|
export * from './lib/pagination/data-source-pagination/data-source-pagination.component';
|
||||||
export * from './lib/confirm-modal/confirm-modal.module';
|
export * from './lib/confirm-modal/confirm-modal.module';
|
||||||
export * from './lib/confirm-modal/confirm-modal.service';
|
export * from './lib/confirm-modal/confirm-modal.service';
|
||||||
export * from './lib/confirm-modal/confirm-modal.directive';
|
|
||||||
export * from './lib/spinner/spinner.module';
|
export * from './lib/spinner/spinner.module';
|
||||||
export * from './lib/spinner/spinner/spinner.component';
|
export * from './lib/spinner/spinner/spinner.component';
|
||||||
|
export * from './lib/data-source-filter/data-source-filter.module';
|
||||||
|
export * from './lib/data-source-filter/text-filter/data-source-text-filter.component';
|
||||||
|
export * from './lib/data-source-filter/number-filter/data-source-number-filter.component';
|
||||||
|
export * from './lib/data-source-filter/datetime-filter/data-source-datetime-filter.component';
|
||||||
|
export * from './lib/data-source-sorting/data-source-sorting.module';
|
||||||
|
export * from './lib/data-source-sorting/ds-sorting/data-source-sorting.component';
|
||||||
|
export * from './lib/command/command.module';
|
||||||
|
export * from './lib/command/directives/command.directive';
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@poweredsoft/ngx-cdk-ui",
|
"name": "@poweredsoft/ngx-cdk-ui",
|
||||||
"version": "0.0.1",
|
"version": "0.0.2",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/common": "^9.1.9",
|
"@angular/common": "^9.1.9",
|
||||||
"@angular/core": "^9.1.9"
|
"@angular/core": "^9.1.9"
|
||||||
|
@ -7,6 +7,8 @@ import { DataGridCellDirective } from './directives/data-grid-cell.directive';
|
|||||||
import { DataGridFooterDirective } from './directives/data-grid-footer.directive';
|
import { DataGridFooterDirective } from './directives/data-grid-footer.directive';
|
||||||
import { DataGridHeaderDirective } from './directives/data-grid-header.directive';
|
import { DataGridHeaderDirective } from './directives/data-grid-header.directive';
|
||||||
import { DataGridLoaderDirective } from './directives/data-grid-loader.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';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -16,7 +18,7 @@ import { DataGridLoaderDirective } from './directives/data-grid-loader.directive
|
|||||||
declarations: [
|
declarations: [
|
||||||
DataGridComponent,DataGridColDirective,DataGridColHeaderDirective,
|
DataGridComponent,DataGridColDirective,DataGridColHeaderDirective,
|
||||||
DataGridCellDirective, DataGridFooterDirective, DataGridHeaderDirective,
|
DataGridCellDirective, DataGridFooterDirective, DataGridHeaderDirective,
|
||||||
DataGridLoaderDirective,
|
DataGridLoaderDirective, DataGridCellFilterDirective, DataGridColSortDirective,
|
||||||
|
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
@ -25,6 +27,6 @@ import { DataGridLoaderDirective } from './directives/data-grid-loader.directive
|
|||||||
exports: [
|
exports: [
|
||||||
DataGridComponent,DataGridColDirective,DataGridColHeaderDirective,
|
DataGridComponent,DataGridColDirective,DataGridColHeaderDirective,
|
||||||
DataGridCellDirective,DataGridFooterDirective, DataGridHeaderDirective,
|
DataGridCellDirective,DataGridFooterDirective, DataGridHeaderDirective,
|
||||||
DataGridLoaderDirective]
|
DataGridLoaderDirective,DataGridCellFilterDirective,DataGridColSortDirective]
|
||||||
})
|
})
|
||||||
export class DataGridModule { }
|
export class DataGridModule { }
|
||||||
|
@ -2,18 +2,34 @@
|
|||||||
|
|
||||||
<table [ngClass]="tableClasses" style="min-height: 300px;">
|
<table [ngClass]="tableClasses" style="min-height: 300px;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr *ngFor="let header of gridHeaders" >
|
||||||
<th *ngFor="let header of gridHeaders" [attr.colspan]="columns.length">
|
<th [attr.colspan]="columns.length">
|
||||||
<ng-container [ngTemplateOutlet]="header.template"></ng-container>
|
<ng-container [ngTemplateOutlet]="header.template"></ng-container>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th *ngFor="let column of columns">
|
<th *ngFor="let column of columns">
|
||||||
<ng-container *ngIf="hasHeaderTemplate(column)">
|
<div class="flex-container">
|
||||||
<ng-container
|
<div class="flex-item">
|
||||||
[ngTemplateOutlet]="getColumnHeaderTemplate(column)"
|
<ng-container *ngIf="hasHeaderTemplate(column)" >
|
||||||
></ng-container>
|
<ng-container
|
||||||
</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>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
:host .flex-container{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host .flex-item{
|
||||||
|
margin-right: 1px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
@ -5,6 +5,8 @@ import { DataGridHeaderDirective } from '../directives/data-grid-header.directiv
|
|||||||
import { DataGridFooterDirective } from '../directives/data-grid-footer.directive';
|
import { DataGridFooterDirective } from '../directives/data-grid-footer.directive';
|
||||||
import { DataGridLoaderDirective } from '../directives/data-grid-loader.directive';
|
import { DataGridLoaderDirective } from '../directives/data-grid-loader.directive';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
|
import { DataGridCellFilterDirective } from '../directives/data-grid-cell-filter.directive';
|
||||||
|
import { DataGridColSortDirective } from '../directives/data-grid-col-sort.directive';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ps-data-grid',
|
selector: 'ps-data-grid',
|
||||||
@ -23,12 +25,15 @@ export class DataGridComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
@Input() dataSource: IDataSource<any>;
|
@Input() dataSource: IDataSource<any>;
|
||||||
@Input() tableClasses: any;
|
@Input() tableClasses: any;
|
||||||
|
@Input() headerClasses: any;
|
||||||
@Input() noRecordsText: string;
|
@Input() noRecordsText: string;
|
||||||
|
|
||||||
private _columns: string[];
|
private _columns: string[];
|
||||||
private _dataSubscription: Subscription;
|
private _dataSubscription: Subscription;
|
||||||
private _loadingSubscription: Subscription;
|
private _loadingSubscription: Subscription;
|
||||||
|
|
||||||
|
_fiters:any
|
||||||
|
|
||||||
@Input() set columns(value: string[]) {
|
@Input() set columns(value: string[]) {
|
||||||
this._columns = value;
|
this._columns = value;
|
||||||
this.columnsChange.emit(value);
|
this.columnsChange.emit(value);
|
||||||
@ -69,12 +74,27 @@ export class DataGridComponent implements OnInit, OnDestroy {
|
|||||||
this.loading = isLoading;
|
this.loading = isLoading;
|
||||||
this.cdr.detectChanges();
|
this.cdr.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
console.log(this.loaders);
|
getSortingTemplate(columnName){
|
||||||
|
const ret = this.getColumn(columnName);
|
||||||
|
if (ret && ret.sortTemplate)
|
||||||
|
return ret.sortTemplate.template;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getFilterTemplate(columnName){
|
||||||
|
const ret = this.getColumn(columnName);
|
||||||
|
if (ret && ret.filterTemplate)
|
||||||
|
return ret.filterTemplate.template;
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getColumn(columnName: string) {
|
getColumn(columnName: string) {
|
||||||
|
|
||||||
if (!this.columnDefinitions)
|
if (!this.columnDefinitions)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@ -86,6 +106,7 @@ export class DataGridComponent implements OnInit, OnDestroy {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
getColumnHeaderTemplate(columnName: string) {
|
getColumnHeaderTemplate(columnName: string) {
|
||||||
const ret = this.getColumn(columnName);
|
const ret = this.getColumn(columnName);
|
||||||
if (ret && ret.headerTemplate)
|
if (ret && ret.headerTemplate)
|
||||||
@ -110,5 +131,13 @@ export class DataGridComponent implements OnInit, OnDestroy {
|
|||||||
return this.getColumnCellTemplate(columnName) ? true :false;
|
return this.getColumnCellTemplate(columnName) ? true :false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasFilterTemplate(columnName: string) {
|
||||||
|
return this.getFilterTemplate(columnName) ? true :false;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasSortingTemplate(columnName: string) {
|
||||||
|
return this.getSortingTemplate(columnName) ? true :false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
import { Directive, TemplateRef } from '@angular/core';
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[psDataGridCellFilter]'
|
||||||
|
})
|
||||||
|
export class DataGridCellFilterDirective {
|
||||||
|
|
||||||
|
constructor(public template: TemplateRef<any>) { }
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
import { Directive, TemplateRef } from '@angular/core';
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[psDataGridColSort]'
|
||||||
|
})
|
||||||
|
export class DataGridColSortDirective {
|
||||||
|
|
||||||
|
constructor(public template: TemplateRef<any>) { }
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,9 @@
|
|||||||
import { Directive, Input, ContentChild } from '@angular/core';
|
import { Directive, Input, ContentChild, ContentChildren } from '@angular/core';
|
||||||
import { DataGridColHeaderDirective } from './data-grid-col-header.directive';
|
import { DataGridColHeaderDirective } from './data-grid-col-header.directive';
|
||||||
import { DataGridCellDirective } from './data-grid-cell.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({
|
@Directive({
|
||||||
selector: '[psDataGridCol]'
|
selector: '[psDataGridCol]'
|
||||||
@ -10,6 +13,8 @@ export class DataGridColDirective {
|
|||||||
@Input('psDataGridCol') columnName:string;
|
@Input('psDataGridCol') columnName:string;
|
||||||
@ContentChild(DataGridColHeaderDirective) headerTemplate:DataGridColHeaderDirective;
|
@ContentChild(DataGridColHeaderDirective) headerTemplate:DataGridColHeaderDirective;
|
||||||
@ContentChild(DataGridCellDirective) cellTemplate:DataGridCellDirective;
|
@ContentChild(DataGridCellDirective) cellTemplate:DataGridCellDirective;
|
||||||
|
@ContentChild(DataGridCellFilterDirective) filterTemplate: DataGridCellFilterDirective;
|
||||||
|
@ContentChild(DataGridColSortDirective) sortTemplate: DataGridColSortDirective;
|
||||||
|
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
|
@ -9,4 +9,7 @@ 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-col-header.directive';
|
||||||
export * from './lib/data-grid/directives/data-grid-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-footer.directive';
|
||||||
export * from './lib/data-grid/directives/data-grid-loader.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';
|
||||||
|
|
||||||
|
@ -27,6 +27,14 @@ const routes: Routes = [
|
|||||||
{
|
{
|
||||||
path: 'pagination-demo',
|
path: 'pagination-demo',
|
||||||
loadChildren: ()=> import('./pagination-demo/pagination-demo.module').then(m => m.PaginationDemoModule)
|
loadChildren: ()=> import('./pagination-demo/pagination-demo.module').then(m => m.PaginationDemoModule)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'grid-filter',
|
||||||
|
loadChildren: ()=> import('./grid-filter&sorting-demo/grid-filter-demo.module').then(m => m.GridFilterDemoModule)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'select',
|
||||||
|
loadChildren: ()=> import('./ng-select-demo/ng-select-demo.module').then(m => m.NgSelectDemoModule)
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -21,9 +21,15 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" routerLink="pagination-demo">pagination Demo</a>
|
<a class="nav-link" routerLink="pagination-demo">pagination Demo</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" routerLink="grid-filter">Fitering Demo</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" routerLink="select">NG-select</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-10" style="padding-top: 5px">
|
<div class="col-lg-10" style="padding-top: 5px;">
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,6 +10,8 @@ import { HttpLink, HttpLinkModule } from 'apollo-angular-link-http';
|
|||||||
import { DefaultOptions } from 'apollo-client';
|
import { DefaultOptions } from 'apollo-client';
|
||||||
import { InMemoryCache } from 'apollo-cache-inmemory';
|
import { InMemoryCache } from 'apollo-cache-inmemory';
|
||||||
import { HttpClientModule } from '@angular/common/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
|
||||||
|
|
||||||
export function app_Init(apollo: Apollo, httpLink: HttpLink) {
|
export function app_Init(apollo: Apollo, httpLink: HttpLink) {
|
||||||
return async () => {
|
return async () => {
|
||||||
@ -49,6 +51,7 @@ export function app_Init(apollo: Apollo, httpLink: HttpLink) {
|
|||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
HomeComponent,
|
HomeComponent,
|
||||||
|
//SelectLabelTemplateDirective,
|
||||||
|
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
@ -56,7 +59,8 @@ export function app_Init(apollo: Apollo, httpLink: HttpLink) {
|
|||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
ApolloModule,
|
ApolloModule,
|
||||||
HttpLinkModule
|
HttpLinkModule,
|
||||||
|
BrowserAnimationsModule
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@ import { CommandModalDemoRoutingModule } from './command-modal-demo-routing.modu
|
|||||||
import { DataGridModule } from '@poweredsoft/ngx-cdk-ui';
|
import { DataGridModule } from '@poweredsoft/ngx-cdk-ui';
|
||||||
|
|
||||||
import {FormsModule} from '@angular/forms';
|
import {FormsModule} from '@angular/forms';
|
||||||
import { CommandModalModule, psbxPaginationModule, ConfirmModalModule } from '@poweredsoft/ngx-bootstrap';
|
import { CommandModalModule, PaginationModule, ConfirmModalModule,CommandModule } from '@poweredsoft/ngx-bootstrap';
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [CommandModalDemoComponent],
|
declarations: [CommandModalDemoComponent],
|
||||||
imports: [
|
imports: [
|
||||||
@ -14,8 +14,9 @@ import { CommandModalModule, psbxPaginationModule, ConfirmModalModule } from '@p
|
|||||||
DataGridModule,
|
DataGridModule,
|
||||||
CommandModalModule,
|
CommandModalModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
psbxPaginationModule,
|
PaginationModule,
|
||||||
ConfirmModalModule
|
ConfirmModalModule,
|
||||||
|
CommandModule
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class CommandModalDemoModule { }
|
export class CommandModalDemoModule { }
|
||||||
|
@ -4,8 +4,10 @@
|
|||||||
<ps-data-grid [dataSource]="merchantDataSource" [(columns)]="columns"
|
<ps-data-grid [dataSource]="merchantDataSource" [(columns)]="columns"
|
||||||
tableClasses="table table-sm table-dark table-striped table-bordered">
|
tableClasses="table table-sm table-dark table-striped table-bordered">
|
||||||
<ng-container *psDataGridHeader>
|
<ng-container *psDataGridHeader>
|
||||||
<button class="btn-primary btn" psbxCommandModal commandTitle="Adding a new merchant" commandText="Add"
|
<button class="btn-primary btn" psbxCommandModal
|
||||||
[dataSource]="merchantDataSource" command="addMerchant" [template]="theModal">Create a new record</button>
|
commandTitle="Adding a new merchant" commandText="Add"
|
||||||
|
[dataSource]="merchantDataSource" command="addMerchant"
|
||||||
|
[template]="theModal">Create a new record</button>
|
||||||
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container psDataGridCol="id">
|
<ng-container psDataGridCol="id">
|
||||||
@ -24,11 +26,26 @@
|
|||||||
<ng-container psDataGridCol="commands">
|
<ng-container psDataGridCol="commands">
|
||||||
<ng-container *psDataGridColHeader>Actions</ng-container>
|
<ng-container *psDataGridColHeader>Actions</ng-container>
|
||||||
<ng-container *psDataGridCell="let model">
|
<ng-container *psDataGridCell="let model">
|
||||||
|
<div class="btn-group">
|
||||||
|
|
||||||
|
|
||||||
<button class="btn-primary btn" psbxCommandModal [commandTitle]="'Change ' + model.name + ' name'" commandText="Update"
|
<button class="btn-primary btn" psbxCommandModal [commandTitle]="'Change ' + model.name + ' name'" commandText="Update"
|
||||||
[dataSource]="merchantDataSource" command="changeMerchant" [model]="model" [template]="changeName">Change</button>
|
[dataSource]="merchantDataSource" command="changeMerchant" [model]="model" [template]="changeName">Change</button>
|
||||||
|
|
||||||
<button class="btn-danger btn" psbxConfirmModal [commandTitle]="'Are you sure you wnat to remove ' + model.name + '?'" commandText="Remove"
|
<button class="btn-danger btn" psbxCommand
|
||||||
[dataSource]="merchantDataSource" command="removeMerchant" [model]="model" >RemoveIt</button>
|
[dataSource]="merchantDataSource"
|
||||||
|
command="removeMerchant"
|
||||||
|
[model]="model"
|
||||||
|
[confirm]="true"
|
||||||
|
confirmMessage="Are you sure you want to delete this merchant?"
|
||||||
|
|
||||||
|
>RemoveIt</button>
|
||||||
|
|
||||||
|
<button class="btn-warning btn" psbxCommand
|
||||||
|
[dataSource]="merchantDataSource"
|
||||||
|
command="removeMerchant"
|
||||||
|
[model]="model"
|
||||||
|
>Remove Without confirmation</button> </div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *psDataGridFooter>
|
<ng-container *psDataGridFooter>
|
||||||
@ -46,11 +63,13 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template #theModal let-command let-loading="loading">
|
<ng-template #theModal let-command let-loading="loading">
|
||||||
<form ngNativeValidate >
|
<form >
|
||||||
Name
|
Name
|
||||||
<input type="text" required [disabled]="loading" name="name" [(ngModel)]="command.name" placeholder="Enter a merchant name" class="form-control" >
|
<input type="text" required [disabled]="loading" name="name" [(ngModel)]="command.name" placeholder="Enter a merchant name" class="form-control" >
|
||||||
Address
|
Address
|
||||||
<input type="text" required [disabled]="loading" name="address" [(ngModel)]="command.address" placeholder="Enter the merchant's address" class="form-control" >
|
<input type="text" required [disabled]="loading" name="address" [(ngModel)]="command.address" placeholder="Enter the merchant's address" class="form-control" >
|
||||||
|
Date
|
||||||
|
<input type="text" required [disabled]="loading" name="address" [(ngModel)]="command.address" placeholder="Enter the merchant's address" class="form-control" >
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</ng-template>
|
</ng-template>
|
@ -1,23 +1,28 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||||
import { IDataSource } from '@poweredsoft/data';
|
import { IDataSource } from '@poweredsoft/data';
|
||||||
import { IMerchant } from 'src/app/data/services/IMerchant';
|
import { IMerchant } from 'src/app/data/services/IMerchant';
|
||||||
import { MerchantService } from 'src/app/data/services/merchant.service';
|
import { MerchantService } from 'src/app/data/services/merchant.service';
|
||||||
import { BsModalRef } from 'ngx-bootstrap/modal';
|
import { BsModalRef } from 'ngx-bootstrap/modal';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ps-command-modal-demo',
|
selector: 'ps-command-modal-demo',
|
||||||
templateUrl: './command-modal-demo.component.html',
|
templateUrl: './command-modal-demo.component.html',
|
||||||
styleUrls: ['./command-modal-demo.component.scss']
|
styleUrls: ['./command-modal-demo.component.scss']
|
||||||
})
|
})
|
||||||
export class CommandModalDemoComponent implements OnInit {
|
export class CommandModalDemoComponent implements OnInit,OnDestroy {
|
||||||
|
|
||||||
columns = ['id','name', 'address', 'commands'];
|
columns = ['id','name', 'address', 'commands'];
|
||||||
pages:any;
|
pages:any;
|
||||||
merchantDataSource: IDataSource<IMerchant>;
|
merchantDataSource: IDataSource<IMerchant>;
|
||||||
|
private _dataSubscription: Subscription;
|
||||||
constructor(private merchantService: MerchantService){
|
constructor(private merchantService: MerchantService){
|
||||||
this.merchantDataSource = this.createDataSource();
|
this.merchantDataSource = this.createDataSource();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this._dataSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
newMerchant(name: string) {
|
newMerchant(name: string) {
|
||||||
this.merchantDataSource.executeCommandByName('addMerchant', {
|
this.merchantDataSource.executeCommandByName('addMerchant', {
|
||||||
@ -40,7 +45,7 @@ export class CommandModalDemoComponent implements OnInit {
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.merchantDataSource.refresh();
|
this.merchantDataSource.refresh();
|
||||||
this.merchantDataSource.data$.subscribe(newData => {
|
this._dataSubscription = this.merchantDataSource.data$.subscribe(newData => {
|
||||||
if (newData)
|
if (newData)
|
||||||
this.pages = new Array(newData.numberOfPages);
|
this.pages = new Array(newData.numberOfPages);
|
||||||
});
|
});
|
||||||
|
@ -2,14 +2,11 @@
|
|||||||
This is a demo for a grid.
|
This is a demo for a grid.
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<ps-data-grid [dataSource]="merchantDataSource" [(columns)]="columns" tableClasses="table table-sm table-bordered" >
|
<ps-data-grid [dataSource]="merchantDataSource" [(columns)]="columns"
|
||||||
|
tableClasses="table table-sm table-bordered" >
|
||||||
|
|
||||||
<ng-container *psDataGridHeader>
|
<ng-container *psDataGridHeader>
|
||||||
<h1>Hey! </h1>
|
Some header
|
||||||
<p>Welcome to my Grid!</p>
|
|
||||||
<label>New merchant name</label>
|
|
||||||
<input class="form-control" #newMerchantName/>
|
|
||||||
<button class="btn btn-primary btn-sm" (click)="newMerchant(newMerchantName.value)">Add</button>
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container psDataGridCol="id">
|
<ng-container psDataGridCol="id">
|
||||||
<div *psDataGridColHeader>ID</div>
|
<div *psDataGridColHeader>ID</div>
|
||||||
@ -27,11 +24,10 @@
|
|||||||
<ng-container psDataGridCol="commands">
|
<ng-container psDataGridCol="commands">
|
||||||
<ng-container *psDataGridColHeader>Actions</ng-container>
|
<ng-container *psDataGridColHeader>Actions</ng-container>
|
||||||
<ng-container *psDataGridCell="let model">
|
<ng-container *psDataGridCell="let model">
|
||||||
<button class="btn btn-primary mr-2">{{model.name}}</button>
|
<button class="btn btn-primary mr-2">Some Actions</button>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *psDataGridFooter>
|
<ng-container *psDataGridFooter>
|
||||||
|
|
||||||
<strong>Footer works!</strong>
|
<strong>Footer works!</strong>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ps-data-grid>
|
</ps-data-grid>
|
@ -1,22 +1,29 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||||
import { DataSource, IDataSource, IQueryExecutionResult, IQueryExecutionGroupResult } from '@poweredsoft/data';
|
import { DataSource, IDataSource, IQueryExecutionResult, IQueryExecutionGroupResult } from '@poweredsoft/data';
|
||||||
import { IMerchant } from 'src/app/data/services/IMerchant';
|
import { IMerchant } from 'src/app/data/services/IMerchant';
|
||||||
import { MerchantService } from 'src/app/data/services/merchant.service';
|
import { MerchantService } from 'src/app/data/services/merchant.service';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ps-data-grid-demo-home',
|
selector: 'ps-data-grid-demo-home',
|
||||||
templateUrl: './data-grid-demo-home.component.html',
|
templateUrl: './data-grid-demo-home.component.html',
|
||||||
styleUrls: ['./data-grid-demo-home.component.scss']
|
styleUrls: ['./data-grid-demo-home.component.scss']
|
||||||
})
|
})
|
||||||
export class DataGridDemoHomeComponent implements OnInit {
|
export class DataGridDemoHomeComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
title = 'cdkDemo';
|
title = 'cdkDemo';
|
||||||
columns = ['id','name', 'address', 'commands']
|
columns = ['id','name', 'address', 'commands']
|
||||||
merchantDataSource: IDataSource<IMerchant>;
|
merchantDataSource: IDataSource<IMerchant>;
|
||||||
|
private _dataSubscription: Subscription;
|
||||||
|
private _loading: Subscription;
|
||||||
constructor(private merchantService: MerchantService){
|
constructor(private merchantService: MerchantService){
|
||||||
this.merchantDataSource = this.createDataSource();
|
this.merchantDataSource = this.createDataSource();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this._dataSubscription.unsubscribe();
|
||||||
|
this._loading.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -41,11 +48,11 @@ export class DataGridDemoHomeComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.merchantDataSource.loading$.subscribe(isLoading => {
|
this._loading = this.merchantDataSource.loading$.subscribe(isLoading => {
|
||||||
console.log('merchant data source event loading', isLoading);
|
console.log('merchant data source event loading', isLoading);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.merchantDataSource.data$.subscribe(receivedData => {
|
this._dataSubscription = this.merchantDataSource.data$.subscribe(receivedData => {
|
||||||
console.log('new data is coming from the server', receivedData);
|
console.log('new data is coming from the server', receivedData);
|
||||||
});
|
});
|
||||||
this.merchantDataSource.refresh();
|
this.merchantDataSource.refresh();
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
export interface IChangeMerchantNameCommand {
|
export interface IChangeMerchantCommand {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
address: string;
|
address: string;
|
||||||
|
ordering: number;
|
||||||
}
|
}
|
||||||
export interface IAddMerchantCommand {
|
export interface IAddMerchantCommand {
|
||||||
name: string;
|
name: string;
|
||||||
address: string;
|
address: string;
|
||||||
|
ordering: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IRemoveMerchantCommand {
|
export interface IRemoveMerchantCommand {
|
@ -2,4 +2,6 @@ export interface IMerchant {
|
|||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
address: string;
|
address: string;
|
||||||
|
ordering:number;
|
||||||
|
openDate: Date;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import { IDataSource, DataSource } from '@poweredsoft/data';
|
|||||||
import { Apollo } from 'apollo-angular';
|
import { Apollo } from 'apollo-angular';
|
||||||
import gql from 'graphql-tag';
|
import gql from 'graphql-tag';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import { IChangeMerchantNameCommand, IAddMerchantCommand, IRemoveMerchantCommand } from './IChangeMerchantNameCommand';
|
import { IChangeMerchantCommand as IChangeMerchantCommand, IAddMerchantCommand, IRemoveMerchantCommand } from './IChangeMerchantCommand';
|
||||||
import { IMerchant } from './IMerchant';
|
import { IMerchant } from './IMerchant';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
@ -23,7 +23,7 @@ export class MerchantService {
|
|||||||
>(
|
>(
|
||||||
'merchants',
|
'merchants',
|
||||||
'GraphQLAdvanceQueryOfMerchantInput',
|
'GraphQLAdvanceQueryOfMerchantInput',
|
||||||
'id, name, address',
|
'id, name, address, ordering, openDate',
|
||||||
(model) => model.id,
|
(model) => model.id,
|
||||||
{
|
{
|
||||||
page: 1,
|
page: 1,
|
||||||
@ -31,8 +31,8 @@ export class MerchantService {
|
|||||||
},
|
},
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
builder.addMutation<IChangeMerchantNameCommand, string>(
|
builder.addMutation<IChangeMerchantCommand, string>(
|
||||||
'changeMerchant', //<-- command name
|
'changeMerchant', //<-- command name
|
||||||
'changeMerchant', //<-- graph ql mutation name
|
'changeMerchant', //<-- graph ql mutation name
|
||||||
|
|
||||||
@ -51,10 +51,11 @@ export class MerchantService {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// viewModel -> transform to the form model for that command -> IChangeMerchantName
|
// viewModel -> transform to the form model for that command -> IChangeMerchantName
|
||||||
e => of(<IChangeMerchantNameCommand>{
|
e => of(<IChangeMerchantCommand>{
|
||||||
id: e.model.id,
|
id: e.model.id,
|
||||||
name: e.model.name,
|
name: e.model.name,
|
||||||
address: e.model.address
|
address: e.model.address,
|
||||||
|
ordering:e.model.ordering,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -80,7 +81,8 @@ export class MerchantService {
|
|||||||
// viewModel -> transform to the form model for that command -> IChangeMerchantName
|
// viewModel -> transform to the form model for that command -> IChangeMerchantName
|
||||||
e => of(<IAddMerchantCommand>{
|
e => of(<IAddMerchantCommand>{
|
||||||
name: 'A New merchant',
|
name: 'A New merchant',
|
||||||
address: ''
|
address: '',
|
||||||
|
ordering: 11
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { FormGroupModalDemoComponent } from './form-group-modal-demo/form-group-modal-demo.component';
|
import { FormGroupModalDemoComponent } from './form-group-modal-demo/form-group-modal-demo.component';
|
||||||
import { FormGroupModalDemoRoutingModule } from './form-group-modal-demo-routing.module'
|
import { FormGroupModalDemoRoutingModule } from './form-group-modal-demo-routing.module'
|
||||||
import { DataGridModule } from '@poweredsoft/ngx-cdk-ui';
|
import { DataGridModule } from '@poweredsoft/ngx-cdk-ui';
|
||||||
import { FormGroupCommandModalModule,CommandModalModule, psbxPaginationModule } from '@poweredsoft/ngx-bootstrap';
|
import { FormGroupCommandModalModule, PaginationModule, CommandModule } from '@poweredsoft/ngx-bootstrap';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
import { ConfirmModalModule } from 'projects/poweredsoft/ngx-bootstrap/src/public-api';
|
import { ConfirmModalModule } from 'projects/poweredsoft/ngx-bootstrap/src/public-api';
|
||||||
|
|
||||||
@ -17,8 +17,9 @@ import { ConfirmModalModule } from 'projects/poweredsoft/ngx-bootstrap/src/publi
|
|||||||
DataGridModule,
|
DataGridModule,
|
||||||
FormGroupCommandModalModule,
|
FormGroupCommandModalModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
psbxPaginationModule,
|
PaginationModule,
|
||||||
ConfirmModalModule,
|
ConfirmModalModule,
|
||||||
|
CommandModule
|
||||||
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<ng-container *psDataGridHeader>
|
<ng-container *psDataGridHeader>
|
||||||
<button class="btn-success btn" psbxFormGroupCommandModal commandTitle="Adding a new merchant"
|
<button class="btn-success btn" psbxFormGroupCommandModal commandTitle="Adding a new merchant"
|
||||||
commandText="Add" [dataSource]="merchantDataSource" command="addMerchant"
|
commandText="Add" [dataSource]="merchantDataSource" command="addMerchant"
|
||||||
(formCreate)="onFormCreate($event)" [template]="theModal">Create a new</button>
|
(formCreate)="onFormCreate($event)" [template]="theModal">Create New Records</button>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container psDataGridCol="id">
|
<ng-container psDataGridCol="id">
|
||||||
<div *psDataGridColHeader>ID</div>
|
<div *psDataGridColHeader>ID</div>
|
||||||
@ -19,16 +19,32 @@
|
|||||||
<div *psDataGridCell="let model">{{model.address}}</div>
|
<div *psDataGridCell="let model">{{model.address}}</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container psDataGridCol="actions">
|
<ng-container psDataGridCol="actions">
|
||||||
|
|
||||||
<ng-container *psDataGridColHeader>Actions</ng-container>
|
<ng-container *psDataGridColHeader>Actions</ng-container>
|
||||||
<ng-container *psDataGridCell="let model">
|
<ng-container *psDataGridCell="let model">
|
||||||
<button class="btn-success btn" psbxFormGroupCommandModal [commandTitle]="'Change ' + model.name + ' name'" commandText="Update"
|
<div class="btn-group">
|
||||||
[dataSource]="merchantDataSource" command="changeMerchant" (formCreate)="onFormCreate($event)" [model]="model" [template]="theModal">Change</button>
|
<button class="btn-success btn" psbxFormGroupCommandModal
|
||||||
|
[commandTitle]="'Change ' + model.name + ' name'"
|
||||||
<button class="btn-danger btn" psbxConfirmModal [commandTitle]="'Are you sure you wnat to remove ' + model.name + '?'" commandText="Remove"
|
commandText="Update"
|
||||||
[dataSource]="merchantDataSource" command="removeMerchant" [model]="model" >Delete!</button>
|
[dataSource]="merchantDataSource"
|
||||||
|
command="changeMerchant"
|
||||||
<!-- <button class="btn-danger btn" psbxExecuteCommand [dataSource]="merchantDataSource" [command]="removeMerchant"
|
(formCreate)="onFormCreate($event)"
|
||||||
[model]="model" [confirm]="true" [confirmMessage]="do you wish to delete the merchant `' + model.name + '`" [refresh]="false">Delete</button> -->
|
[model]="model"
|
||||||
|
[template]="theModal">Change</button>
|
||||||
|
|
||||||
|
<button class="btn-danger btn"
|
||||||
|
psbxCommand
|
||||||
|
[dataSource]="merchantDataSource"
|
||||||
|
command="removeMerchant"
|
||||||
|
[model]="model"
|
||||||
|
[confirm]="true"
|
||||||
|
yesClass="warning"
|
||||||
|
noClass = "secondary"
|
||||||
|
noText = "Cancel Delete"
|
||||||
|
yesText = "Delete It"
|
||||||
|
confirmMessage="Are you sure you want to delete this merchant?"
|
||||||
|
>RemoveIt</button>
|
||||||
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *psDataGridFooter>
|
<ng-container *psDataGridFooter>
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||||
import { IDataSource } from '@poweredsoft/data';
|
import { IDataSource } from '@poweredsoft/data';
|
||||||
import { IMerchant } from 'src/app/data/services/IMerchant';
|
import { IMerchant } from 'src/app/data/services/IMerchant';
|
||||||
import { MerchantService } from 'src/app/data/services/merchant.service';
|
import { MerchantService } from 'src/app/data/services/merchant.service';
|
||||||
import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';
|
import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';
|
||||||
import { IModelFormCreateEvent } from 'projects/poweredsoft/ngx-bootstrap/src/public-api';
|
import { IModelFormCreateEvent } from 'projects/poweredsoft/ngx-bootstrap/src/public-api';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
import { THIS_EXPR } from '@angular/compiler/src/output/output_ast';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ps-form-group-modal-demo',
|
selector: 'ps-form-group-modal-demo',
|
||||||
templateUrl: './form-group-modal-demo.component.html',
|
templateUrl: './form-group-modal-demo.component.html',
|
||||||
styleUrls: ['./form-group-modal-demo.component.scss']
|
styleUrls: ['./form-group-modal-demo.component.scss']
|
||||||
})
|
})
|
||||||
export class FormGroupModalDemoComponent implements OnInit {
|
export class FormGroupModalDemoComponent implements OnInit,OnDestroy {
|
||||||
|
|
||||||
createDataSource(): IDataSource<IMerchant> {
|
createDataSource(): IDataSource<IMerchant> {
|
||||||
return this.merchantService.createDataSource();
|
return this.merchantService.createDataSource();
|
||||||
@ -18,14 +20,18 @@ export class FormGroupModalDemoComponent implements OnInit {
|
|||||||
|
|
||||||
pages:any;
|
pages:any;
|
||||||
merchantDataSource: IDataSource<IMerchant>;
|
merchantDataSource: IDataSource<IMerchant>;
|
||||||
|
private _dataSubscription: Subscription;
|
||||||
columns = ['id','name', 'address', 'actions'];
|
columns = ['id','name', 'address', 'actions'];
|
||||||
constructor(private merchantService: MerchantService, private fb: FormBuilder) {
|
constructor(private merchantService: MerchantService, private fb: FormBuilder) {
|
||||||
this.merchantDataSource = this.createDataSource();
|
this.merchantDataSource = this.createDataSource();
|
||||||
}
|
}
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this._dataSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.merchantDataSource.refresh();
|
this.merchantDataSource.refresh();
|
||||||
this.merchantDataSource.data$.subscribe(newData => {
|
this._dataSubscription = this.merchantDataSource.data$.subscribe(newData => {
|
||||||
if (newData)
|
if (newData)
|
||||||
this.pages = new Array(newData.numberOfPages);
|
this.pages = new Array(newData.numberOfPages);
|
||||||
});
|
});
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { Routes, RouterModule } from '@angular/router';
|
||||||
|
import { GridFilterDemoComponent } from './grid-filter-demo/grid-filter-demo.component';
|
||||||
|
|
||||||
|
|
||||||
|
const routes: Routes = [{
|
||||||
|
path: '',
|
||||||
|
component: GridFilterDemoComponent
|
||||||
|
}];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forChild(routes)],
|
||||||
|
exports: [RouterModule]
|
||||||
|
})
|
||||||
|
export class GridFilterDemoRoutingModule { }
|
26
src/app/grid-filter&sorting-demo/grid-filter-demo.module.ts
Normal file
26
src/app/grid-filter&sorting-demo/grid-filter-demo.module.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
|
||||||
|
import { GridFilterDemoRoutingModule } from './grid-filter-demo-routing.module';
|
||||||
|
import { GridFilterDemoComponent } from './grid-filter-demo/grid-filter-demo.component';
|
||||||
|
import { DataSourceFilterModule, PaginationModule, CommandModalModule, ConfirmModalModule, SpinnerModule, DataSourceSortingModule, CommandModule } from '@poweredsoft/ngx-bootstrap';
|
||||||
|
import { DataGridModule } from '@poweredsoft/ngx-cdk-ui';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [GridFilterDemoComponent],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
GridFilterDemoRoutingModule,
|
||||||
|
DataSourceFilterModule,
|
||||||
|
PaginationModule,
|
||||||
|
DataGridModule,
|
||||||
|
CommandModalModule,
|
||||||
|
ConfirmModalModule,
|
||||||
|
FormsModule,
|
||||||
|
SpinnerModule,
|
||||||
|
DataSourceSortingModule,
|
||||||
|
CommandModule
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class GridFilterDemoModule { }
|
@ -0,0 +1,105 @@
|
|||||||
|
<h2>grid-filter-demo works!</h2>
|
||||||
|
|
||||||
|
<ps-data-grid [dataSource]="merchantDataSource" [(columns)]="columns"
|
||||||
|
tableClasses="table table-sm table-striped table-bordered">
|
||||||
|
<psbx-spinner *psDataGridLoader></psbx-spinner>
|
||||||
|
<ng-container *psDataGridHeader>
|
||||||
|
<button class="btn-info btn" psbxCommandModal commandTitle="Adding a new merchant" commandText="Add"
|
||||||
|
[dataSource]="merchantDataSource" command="addMerchant" [template]="theModal">Create Record</button>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<ng-container psDataGridCol="id">
|
||||||
|
<ng-container *psDataGridColHeader>ID</ng-container>
|
||||||
|
<psbx-ds-text-filter *psDataGridCellFilter [dataSource]="merchantDataSource" path="id"></psbx-ds-text-filter>
|
||||||
|
<psbx-ds-sorting *psDataGridColSort [dataSource]="merchantDataSource" path="id"></psbx-ds-sorting>
|
||||||
|
<ng-container *psDataGridCell="let model">{{model.id}}</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container psDataGridCol="name">
|
||||||
|
<ng-container *psDataGridColHeader>Name</ng-container>
|
||||||
|
<psbx-ds-text-filter *psDataGridCellFilter [dataSource]="merchantDataSource" path="name"></psbx-ds-text-filter>
|
||||||
|
<psbx-ds-sorting *psDataGridColSort [dataSource]="merchantDataSource" path="name"></psbx-ds-sorting>
|
||||||
|
<ng-container *psDataGridCell="let model">{{model.name}}</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container psDataGridCol="address">
|
||||||
|
<ng-container *psDataGridColHeader>Address</ng-container>
|
||||||
|
<ng-container *psDataGridCell="let model">{{model.address}}</ng-container>
|
||||||
|
<psbx-ds-text-filter *psDataGridCellFilter [dataSource]="merchantDataSource" path="address">
|
||||||
|
</psbx-ds-text-filter>
|
||||||
|
<psbx-ds-sorting *psDataGridColSort [dataSource]="merchantDataSource" path="address"></psbx-ds-sorting>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container psDataGridCol="ordering">
|
||||||
|
<ng-container *psDataGridColHeader>Priority</ng-container>
|
||||||
|
<ng-container *psDataGridCell="let model">{{model.ordering}}</ng-container>
|
||||||
|
<psbx-ds-number-filter *psDataGridCellFilter [dataSource]="merchantDataSource" path="ordering">
|
||||||
|
</psbx-ds-number-filter>
|
||||||
|
<psbx-ds-sorting *psDataGridColSort [dataSource]="merchantDataSource" path="ordering"></psbx-ds-sorting>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container psDataGridCol="openDate">
|
||||||
|
<ng-container *psDataGridColHeader>Open Date</ng-container>
|
||||||
|
<ng-container *psDataGridCell="let model">{{model.openDate}}</ng-container>
|
||||||
|
<psbx-ds-datetime-filter *psDataGridCellFilter [dataSource]="merchantDataSource" path="openDate">
|
||||||
|
</psbx-ds-datetime-filter>
|
||||||
|
<psbx-ds-sorting *psDataGridColSort [dataSource]="merchantDataSource" path="openDate"></psbx-ds-sorting>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container psDataGridCol="commands">
|
||||||
|
<ng-container *psDataGridColHeader>Actions</ng-container>
|
||||||
|
<ng-container *psDataGridCell="let model">
|
||||||
|
<div class="btn-group">
|
||||||
|
<button class="btn-info btn" psbxCommandModal [commandTitle]="'Change ' + model.name + ' name'"
|
||||||
|
commandText="Update" [dataSource]="merchantDataSource" command="changeMerchant" [model]="model"
|
||||||
|
[template]="theModal">Change</button>
|
||||||
|
<button class="btn-danger btn"
|
||||||
|
psbxCommand
|
||||||
|
[dataSource]="merchantDataSource"
|
||||||
|
command="removeMerchant"
|
||||||
|
[model]="model"
|
||||||
|
[confirm]="true"
|
||||||
|
yesClass="warning"
|
||||||
|
noClass = "secondary"
|
||||||
|
noText = "Cancel Delete"
|
||||||
|
yesText = "Delete It"
|
||||||
|
confirmMessage="Are you sure you want to delete this merchant?"
|
||||||
|
>RemoveIt</button></div>
|
||||||
|
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *psDataGridFooter>
|
||||||
|
<psbx-ds-pagination [dataSource]="merchantDataSource"></psbx-ds-pagination>
|
||||||
|
</ng-container>
|
||||||
|
</ps-data-grid>
|
||||||
|
|
||||||
|
|
||||||
|
<ng-template #theModal let-command let-loading="loading">
|
||||||
|
<label for="name">Name</label>
|
||||||
|
<input type="text" required [(ngModel)]="command.name" placeholder="Enter a merchant name"
|
||||||
|
class="form-control">
|
||||||
|
<label for="address">Address</label>
|
||||||
|
<input type="text" required [(ngModel)]="command.address"
|
||||||
|
placeholder="Enter the merchant's address" class="form-control">
|
||||||
|
<label for="address">Priority</label>
|
||||||
|
<input type="number" required [(ngModel)]="command.ordering"
|
||||||
|
placeholder="Enter the merchant's Priority" class="form-control">
|
||||||
|
<label for="address">Priority</label>
|
||||||
|
<input type="date" required [(ngModel)]="command.openDate"
|
||||||
|
placeholder="Enter the merchant's Priority" class="form-control">
|
||||||
|
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
|
||||||
|
<ng-template #confirm>
|
||||||
|
<div class="modal-body text-center">
|
||||||
|
<p>Do you want to confirm?</p>
|
||||||
|
<button type="button" class="btn btn-default">Yes</button>
|
||||||
|
<button type="button" class="btn btn-primary">No</button>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { IDataSource, ISimpleFilter } from '@poweredsoft/data';
|
||||||
|
import { IMerchant } from 'src/app/data/services/IMerchant';
|
||||||
|
import { MerchantService } from 'src/app/data/services/merchant.service';
|
||||||
|
import { ConfirmModalService } from '@poweredsoft/ngx-bootstrap';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ps-grid-filter-demo',
|
||||||
|
templateUrl: './grid-filter-demo.component.html',
|
||||||
|
styleUrls: ['./grid-filter-demo.component.scss']
|
||||||
|
})
|
||||||
|
export class GridFilterDemoComponent implements OnInit {
|
||||||
|
|
||||||
|
columns = ['id','name', 'address', 'ordering','openDate', 'commands']
|
||||||
|
merchantDataSource: IDataSource<IMerchant>;
|
||||||
|
constructor(private merchantService: MerchantService){
|
||||||
|
this.merchantDataSource = this.createDataSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
pages:any;
|
||||||
|
filteredResults:any;
|
||||||
|
somefilter:any;
|
||||||
|
|
||||||
|
createDataSource(): IDataSource<IMerchant> {
|
||||||
|
return this.merchantService.createDataSource();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.merchantDataSource.refresh();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
19
src/app/ng-select-demo/ng-select-demo-routing.module.ts
Normal file
19
src/app/ng-select-demo/ng-select-demo-routing.module.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { NgModule } from "@angular/core";
|
||||||
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { NgSelectDemoComponent } from './ng-select-demo/ng-select-demo.component';
|
||||||
|
|
||||||
|
|
||||||
|
const routes: Routes =[
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: NgSelectDemoComponent
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forChild(routes)],
|
||||||
|
exports: [RouterModule]
|
||||||
|
})
|
||||||
|
export class NgSelectDemoRoutingModule {
|
||||||
|
|
||||||
|
}
|
26
src/app/ng-select-demo/ng-select-demo.module.ts
Normal file
26
src/app/ng-select-demo/ng-select-demo.module.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { NgSelectDemoComponent } from './ng-select-demo/ng-select-demo.component';
|
||||||
|
import { NgSelectDemoRoutingModule } from './ng-select-demo-routing.module';
|
||||||
|
import { NgSelectModule } from '@ng-select/ng-select';
|
||||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { PsNgSelectModule } from '@poweredsoft/ng-select';
|
||||||
|
import { CommandModule, CommandModalModule } from '@poweredsoft/ngx-bootstrap';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [NgSelectDemoComponent],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
NgSelectModule,
|
||||||
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
NgSelectDemoRoutingModule,
|
||||||
|
PsNgSelectModule,
|
||||||
|
CommandModule,
|
||||||
|
CommandModalModule
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class NgSelectDemoModule { }
|
@ -0,0 +1,69 @@
|
|||||||
|
<h2>Single Select Demo | ngModel | option template</h2>
|
||||||
|
<ps-ng-select [dataSource]="merchantDataSource" bindLabel="name" bindValue="id" [(ngModel)]="myValue">
|
||||||
|
<div *psNgSelectOption="let item">
|
||||||
|
{{ item.name }} - {{ item.address }}
|
||||||
|
</div>
|
||||||
|
</ps-ng-select>
|
||||||
|
|
||||||
|
selected: {{ myValue | json }}
|
||||||
|
|
||||||
|
<h2>Single Select With Form | formGroup | option template</h2>
|
||||||
|
<form #form [formGroup]="myForm">
|
||||||
|
<ps-ng-select [dataSource]="merchantDataSource2" bindLabel="name" bindValue="id" formControlName="merchantId" [serverFiltering]="true">
|
||||||
|
<div *psNgSelectOption="let item">
|
||||||
|
<span>Merchant:</span> {{ item.name }} - <span>Address: </span>{{ item.address }}
|
||||||
|
</div>
|
||||||
|
</ps-ng-select>
|
||||||
|
</form>
|
||||||
|
selected: {{ myForm.value | json }}
|
||||||
|
|
||||||
|
<h2>Single Select Demo | label Template</h2>
|
||||||
|
<ps-ng-select [dataSource]="merchantDataSource3" bindLabel="name" bindValue="id" [(ngModel)]="myValue3" [serverFiltering]="true">
|
||||||
|
<div *psNgSelectOption="let item">
|
||||||
|
<span>Merchant:</span> {{ item.name }} - <span>Address: </span>{{ item.address }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *psNgSelectLabel="let item">
|
||||||
|
<img src="assets/32x32-blue.png"><span>Name: </span>{{ item.name }} - <span> Address: </span>{{item.address }}
|
||||||
|
</div>
|
||||||
|
</ps-ng-select>
|
||||||
|
selected: {{ myValue3 | json }}
|
||||||
|
|
||||||
|
<h2>Single Select Demo | notFound Template</h2>
|
||||||
|
<ps-ng-select [dataSource]="merchantDataSource3" bindLabel="name" bindValue="id" [(ngModel)]="myValue2" [serverFiltering]="false">
|
||||||
|
<div *psNgNotFoundTemplate="let searchTerm">
|
||||||
|
<div class="ng-option disabled">
|
||||||
|
No data found for "{{searchTerm}}"
|
||||||
|
<button class="btn-primary btn"
|
||||||
|
psbxCommandModal
|
||||||
|
commandTitle="Adding a new {{searchTerm}}"
|
||||||
|
commandText="Add"
|
||||||
|
[dataSource]="merchantDataSource"
|
||||||
|
command="addMerchant"
|
||||||
|
cancelText="Abort"
|
||||||
|
[template]="theModal"
|
||||||
|
(success)="myValue2 = $event"> Create New {{searchTerm}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ps-ng-select>
|
||||||
|
selected: {{ myValue2 | json }}
|
||||||
|
|
||||||
|
<h2>Multi-Select Demo</h2>
|
||||||
|
<ps-ng-multi-select [dataSource]="merchantDataSource4" bindLabel="name" bindValue="id" [serverFiltering]="true" [(ngModel)]="myValue4" >
|
||||||
|
<div *psNgSelectOption="let item">
|
||||||
|
<img src="assets/32x32-blue.png"><span>Name: </span>{{ item.name }} - <span> Address: </span>{{item.address }}
|
||||||
|
</div>
|
||||||
|
<ng-container *psNgSelectLabel="let item;">
|
||||||
|
{{ item.name }}
|
||||||
|
</ng-container>
|
||||||
|
</ps-ng-multi-select>
|
||||||
|
selected: {{ myValue4 | json }}
|
||||||
|
|
||||||
|
<ng-template #theModal let-command let-loading="loading">
|
||||||
|
<form >
|
||||||
|
Name
|
||||||
|
<input type="text" required [disabled]="loading" name="name" [(ngModel)]="command.name" placeholder="Enter a merchant name" class="form-control" >
|
||||||
|
Address
|
||||||
|
<input type="text" required [disabled]="loading" name="address" [(ngModel)]="command.address" placeholder="Enter the merchant's address" class="form-control" >
|
||||||
|
</form>
|
||||||
|
</ng-template>
|
@ -0,0 +1,47 @@
|
|||||||
|
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
|
||||||
|
import { MerchantService } from 'src/app/data/services/merchant.service';
|
||||||
|
|
||||||
|
import { IMerchant } from 'src/app/data/services/IMerchant';
|
||||||
|
import { Observable, Subject } from 'rxjs';
|
||||||
|
import { map, distinctUntilChanged, debounceTime } from 'rxjs/operators';
|
||||||
|
import { IDataSource, ISimpleFilter } from '@poweredsoft/data';
|
||||||
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ps-ng-select-demo',
|
||||||
|
templateUrl: './ng-select-demo.component.html',
|
||||||
|
styleUrls: ['./ng-select-demo.component.scss']
|
||||||
|
})
|
||||||
|
export class NgSelectDemoComponent implements OnInit {
|
||||||
|
|
||||||
|
merchantDataSource: IDataSource<IMerchant>;
|
||||||
|
merchantDataSource2: IDataSource<IMerchant>;
|
||||||
|
merchantDataSource3: IDataSource<IMerchant>;
|
||||||
|
merchantDataSource4: IDataSource<IMerchant>;
|
||||||
|
|
||||||
|
selectedValue: IMerchant;
|
||||||
|
|
||||||
|
myForm: FormGroup;
|
||||||
|
myValue: string;
|
||||||
|
myValue2: string;
|
||||||
|
myValue3: string;
|
||||||
|
myValue4: string;
|
||||||
|
|
||||||
|
constructor(private merchantService: MerchantService, private fb: FormBuilder
|
||||||
|
) {
|
||||||
|
this.merchantDataSource = merchantService.createDataSource(); //Assign the dataSource
|
||||||
|
this.merchantDataSource2 = merchantService.createDataSource();
|
||||||
|
this.merchantDataSource3 = merchantService.createDataSource();
|
||||||
|
this.merchantDataSource4 = merchantService.createDataSource();
|
||||||
|
this.myForm = fb.group({
|
||||||
|
'merchantId': [null]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -4,7 +4,7 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { PaginationDemoRoutingModule } from './pagination-demo-routing.module';
|
import { PaginationDemoRoutingModule } from './pagination-demo-routing.module';
|
||||||
import { PaginationDemoComponent } from './pagination-demo/pagination/pagination-demo.component';
|
import { PaginationDemoComponent } from './pagination-demo/pagination/pagination-demo.component';
|
||||||
import { DataGridModule } from '@poweredsoft/ngx-cdk-ui';
|
import { DataGridModule } from '@poweredsoft/ngx-cdk-ui';
|
||||||
import { psbxPaginationModule, CommandModalModule, ConfirmModalModule,SpinnerModule } from '@poweredsoft/ngx-bootstrap';
|
import { PaginationModule, CommandModalModule, ConfirmModalModule,SpinnerModule, CommandModule } from '@poweredsoft/ngx-bootstrap';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { ModalModule } from 'ngx-bootstrap/modal';
|
import { ModalModule } from 'ngx-bootstrap/modal';
|
||||||
|
|
||||||
@ -16,12 +16,13 @@ import { ModalModule } from 'ngx-bootstrap/modal';
|
|||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
PaginationDemoRoutingModule,
|
PaginationDemoRoutingModule,
|
||||||
psbxPaginationModule,
|
PaginationModule,
|
||||||
DataGridModule,
|
DataGridModule,
|
||||||
CommandModalModule,
|
CommandModalModule,
|
||||||
ConfirmModalModule,
|
ConfirmModalModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
SpinnerModule
|
SpinnerModule,
|
||||||
|
CommandModule
|
||||||
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@ -16,18 +16,6 @@
|
|||||||
<ng-container psDataGridCol="id">
|
<ng-container psDataGridCol="id">
|
||||||
<div *psDataGridColHeader>ID</div>
|
<div *psDataGridColHeader>ID</div>
|
||||||
<div *psDataGridCell="let model">{{model.id}}</div>
|
<div *psDataGridCell="let model">{{model.id}}</div>
|
||||||
|
|
||||||
<!-- <psfa-ds-sort-icon *psDataGridColSort [sortPath]="id" [dataSource]="merchantDataSource">
|
|
||||||
|
|
||||||
</psfa-ds-sort-icon> -->
|
|
||||||
|
|
||||||
<!-- <psbx-ds-text-filter *psDataGridCellFilter [dataSource]="merchantDataSource"></psbx-ds-text-filter>
|
|
||||||
<psdb-ds-date-filter *psDataGridCellFilter></psdb-ds-date-filter>
|
|
||||||
<psdb-ds-date-range-filter *psDataGridCellFilter></psdb-ds-date-range-filter>
|
|
||||||
<psbx-ds-number-filter *psDataGridCellFilter></psbx-ds-number-filter>
|
|
||||||
<psbx-ds-multi-select-filter [dataSource]="merchantDataSource" [selectDataSource]="selectDataSource" [valueField]="id">
|
|
||||||
<ng-container *psSelectOption="let option">{{ option.name }}</ng-container>
|
|
||||||
</psbx-ds-multi-select-filter> -->
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container psDataGridCol="name">
|
<ng-container psDataGridCol="name">
|
||||||
@ -42,8 +30,29 @@
|
|||||||
<ng-container psDataGridCol="commands">
|
<ng-container psDataGridCol="commands">
|
||||||
<ng-container *psDataGridColHeader>Actions</ng-container>
|
<ng-container *psDataGridColHeader>Actions</ng-container>
|
||||||
<ng-container *psDataGridCell="let model">
|
<ng-container *psDataGridCell="let model">
|
||||||
<button class="btn-danger btn" psbxConfirmModal [commandTitle]="'Are you sure you wnat to remove ' + model.name + '?'" commandText="Remove"
|
<div class="btn-group">
|
||||||
[dataSource]="merchantDataSource" command="removeMerchant" [model]="model" >Remove</button>
|
<button class="btn-warning btn" psbxCommandModal
|
||||||
|
commandTitle="Update {{model.name}}"
|
||||||
|
commandText="Save"
|
||||||
|
[dataSource]="merchantDataSource"
|
||||||
|
command="changeMerchant"
|
||||||
|
[model]="model"
|
||||||
|
[template]="theModal">Update</button>
|
||||||
|
|
||||||
|
<button class="btn-danger btn"
|
||||||
|
psbxCommand
|
||||||
|
[dataSource]="merchantDataSource"
|
||||||
|
command="removeMerchant"
|
||||||
|
[model]="model"
|
||||||
|
[confirm]="true"
|
||||||
|
yesClass="warning"
|
||||||
|
noClass = "secondary"
|
||||||
|
noText = "Cancel Delete"
|
||||||
|
yesText = "Delete It"
|
||||||
|
confirmMessage="Are you sure you want to delete this merchant?"
|
||||||
|
>Remove</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
@ -63,7 +72,6 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<ng-template #theModal let-command let-loading="loading">
|
<ng-template #theModal let-command let-loading="loading">
|
||||||
<label for="name">Name</label>
|
<label for="name">Name</label>
|
||||||
<input type="text" required [attr.disabled]="loading" [(ngModel)]="command.name" placeholder="Enter a merchant name"
|
<input type="text" required [attr.disabled]="loading" [(ngModel)]="command.name" placeholder="Enter a merchant name"
|
||||||
|
@ -1,49 +1,29 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||||
import { IDataSource } from '@poweredsoft/data';
|
import { IDataSource } from '@poweredsoft/data';
|
||||||
import { IMerchant } from 'src/app/data/services/IMerchant';
|
import { IMerchant } from 'src/app/data/services/IMerchant';
|
||||||
import { MerchantService } from 'src/app/data/services/merchant.service';
|
import { MerchantService } from 'src/app/data/services/merchant.service';
|
||||||
import { FormBuilder, Validators } from '@angular/forms';
|
import { FormBuilder, Validators } from '@angular/forms';
|
||||||
import { ConfirmModalService } from '@poweredsoft/ngx-bootstrap';
|
import { ConfirmModalService } from '@poweredsoft/ngx-bootstrap';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ps-pagination',
|
selector: 'ps-pagination',
|
||||||
templateUrl: './pagination-demo.component.html',
|
templateUrl: './pagination-demo.component.html',
|
||||||
styleUrls: ['./pagination-demo.component.scss']
|
styleUrls: ['./pagination-demo.component.scss']
|
||||||
})
|
})
|
||||||
export class PaginationDemoComponent implements OnInit {
|
export class PaginationDemoComponent implements OnInit, OnDestroy {
|
||||||
columns = ['id','name', 'address','commands']
|
columns = ['id','name', 'address','commands']
|
||||||
merchantDataSource: IDataSource<IMerchant>;
|
merchantDataSource: IDataSource<IMerchant>;
|
||||||
|
private _dataSubscription: Subscription;
|
||||||
constructor(private merchantService: MerchantService, private confirmModalService: ConfirmModalService){
|
constructor(private merchantService: MerchantService, private confirmModalService: ConfirmModalService){
|
||||||
this.merchantDataSource = this.createDataSource();
|
this.merchantDataSource = this.createDataSource();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this._dataSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
pages:any;
|
pages:any;
|
||||||
|
|
||||||
// removeMerchant(id:string) {
|
|
||||||
// this.confirmModalService.confirm({
|
|
||||||
// message: 'Do you want to delete this merchant?',
|
|
||||||
// yesText: 'yes delete this merchant',
|
|
||||||
// yesClass: 'danger',
|
|
||||||
// noText: 'no please dont',
|
|
||||||
// noClass: 'light'
|
|
||||||
// }).subscribe(result => {
|
|
||||||
// if(result){
|
|
||||||
// this.merchantDataSource.executeCommandByName('removeMerchant', {
|
|
||||||
// id: id
|
|
||||||
// }).subscribe(
|
|
||||||
// res => {
|
|
||||||
// this.merchantDataSource.refresh();
|
|
||||||
// },
|
|
||||||
// err => {
|
|
||||||
// console.log(err);
|
|
||||||
// alert('failed');
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
createDataSource(): IDataSource<IMerchant> {
|
createDataSource(): IDataSource<IMerchant> {
|
||||||
return this.merchantService.createDataSource();
|
return this.merchantService.createDataSource();
|
||||||
@ -51,7 +31,7 @@ export class PaginationDemoComponent implements OnInit {
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.merchantDataSource.refresh();
|
this.merchantDataSource.refresh();
|
||||||
this.merchantDataSource.data$.subscribe(newData => {
|
this._dataSubscription = this.merchantDataSource.data$.subscribe(newData => {
|
||||||
if (newData)
|
if (newData)
|
||||||
this.pages = new Array(newData.numberOfPages);
|
this.pages = new Array(newData.numberOfPages);
|
||||||
});
|
});
|
||||||
|
BIN
src/assets/32x32-blue.png
Normal file
BIN
src/assets/32x32-blue.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
src/assets/avatar.png
Normal file
BIN
src/assets/avatar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 194 B |
@ -1,2 +1,4 @@
|
|||||||
/* You can add global styles to this file, and also import other style files */
|
/* You can add global styles to this file, and also import other style files */
|
||||||
@import '~bootstrap/scss/bootstrap';
|
@import '~bootstrap/scss/bootstrap';
|
||||||
|
@import '~ngx-bootstrap/datepicker/bs-datepicker.css';
|
||||||
|
@import "~@ng-select/ng-select/themes/default.theme.css";
|
@ -23,6 +23,10 @@
|
|||||||
"@poweredsoft/ngx-bootstrap": [
|
"@poweredsoft/ngx-bootstrap": [
|
||||||
"dist/poweredsoft/ngx-bootstrap/poweredsoft-ngx-bootstrap",
|
"dist/poweredsoft/ngx-bootstrap/poweredsoft-ngx-bootstrap",
|
||||||
"dist/poweredsoft/ngx-bootstrap"
|
"dist/poweredsoft/ngx-bootstrap"
|
||||||
|
],
|
||||||
|
"@poweredsoft/ng-select": [
|
||||||
|
"dist/poweredsoft/ng-select/poweredsoft-ng-select",
|
||||||
|
"dist/poweredsoft/ng-select"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user