view ready :)
This commit is contained in:
		
							parent
							
								
									c6fc24db82
								
							
						
					
					
						commit
						d886ff797e
					
				
							
								
								
									
										6
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1684,9 +1684,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "@poweredsoft/ngx-data": { | ||||
|       "version": "0.0.16", | ||||
|       "resolved": "https://registry.npmjs.org/@poweredsoft/ngx-data/-/ngx-data-0.0.16.tgz", | ||||
|       "integrity": "sha512-hk5eNvzGkotTfu0GfksOK9KtLGVUtwc/9JSSKWRIejF04oaXeBZ6PZ6s62YRnZ/EEG5JA0bQdZSHiPlaEapeeQ==", | ||||
|       "version": "0.0.21", | ||||
|       "resolved": "https://registry.npmjs.org/@poweredsoft/ngx-data/-/ngx-data-0.0.21.tgz", | ||||
|       "integrity": "sha512-+g8plxcrivlnd5VBsHtGiqfXabRlDeYeyQI5lOCZRlfLt+IwIlCUB5kS0Hm3LvWZddyQvhg/stAzaeao0uyt3A==", | ||||
|       "requires": { | ||||
|         "tslib": "^1.9.0" | ||||
|       } | ||||
|  | ||||
| @ -25,7 +25,7 @@ | ||||
|     "@angular/router": "~9.1.4", | ||||
|     "@ng-select/ng-select": "^4.0.1", | ||||
|     "@poweredsoft/data": "0.0.30", | ||||
|     "@poweredsoft/ngx-data": "0.0.16", | ||||
|     "@poweredsoft/ngx-data": "0.0.21", | ||||
|     "@poweredsoft/ngx-data-apollo": "0.0.10", | ||||
|     "apollo-angular": "^1.8.0", | ||||
|     "apollo-angular-link-http": "^1.9.0", | ||||
|  | ||||
| @ -0,0 +1,10 @@ | ||||
| import { Directive, TemplateRef } from '@angular/core'; | ||||
| 
 | ||||
| @Directive({ | ||||
|   selector: '[psViewContent]' | ||||
| }) | ||||
| export class ViewContentDirective { | ||||
| 
 | ||||
|   constructor(public template: TemplateRef<any>) { } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,10 @@ | ||||
| import { Directive, TemplateRef } from '@angular/core'; | ||||
| 
 | ||||
| @Directive({ | ||||
|   selector: '[psViewLoading]' | ||||
| }) | ||||
| export class ViewLoadingDirective { | ||||
| 
 | ||||
|   constructor(public template: TemplateRef<any>) { } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,10 @@ | ||||
| import { Directive, TemplateRef } from '@angular/core'; | ||||
| 
 | ||||
| @Directive({ | ||||
|   selector: '[psViewNoRecords]' | ||||
| }) | ||||
| export class ViewNoRecordsDirective { | ||||
| 
 | ||||
|   constructor(public template: TemplateRef<any>) { } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,27 @@ | ||||
| <ng-container *ngIf="loading; else notLoading">  | ||||
|     <ng-container *ngIf="viewLoading"> | ||||
|         <ng-container [ngTemplateOutlet]="getViewLoadingTemplate()"></ng-container> | ||||
|     </ng-container> | ||||
|     <ng-container *ngIf="!viewLoading"> | ||||
|         {{ finalLoadingText }} | ||||
|     </ng-container> | ||||
| </ng-container> | ||||
| 
 | ||||
| <ng-template #notLoading> | ||||
|     <ng-container *ngIf="!noData else noResultTemplate"> | ||||
|         <ng-container [ngTemplateOutlet]="getViewContentTemplate()" [ngTemplateOutletContext]="{ | ||||
|             $implicit: viewModel | ||||
|             }"> | ||||
|         </ng-container> | ||||
|     </ng-container> | ||||
| </ng-template> | ||||
| 
 | ||||
| 
 | ||||
| <ng-template #noResultTemplate> | ||||
|     <ng-container *ngIf="viewNoRecords"> | ||||
|         <ng-container [ngTemplateOutlet]="getViewNoRecordsTemplate()"></ng-container> | ||||
|     </ng-container> | ||||
|     <ng-container *ngIf="!viewNoRecords"> | ||||
|         <div [ngClass]="noRecordClasses">{{noRecords}}</div> | ||||
|     </ng-container> | ||||
| </ng-template> | ||||
| @ -0,0 +1,84 @@ | ||||
| import { Component, ContentChild, Input, OnDestroy, OnInit } from '@angular/core'; | ||||
| import { IDataSource } from '@poweredsoft/data'; | ||||
| import { Subscription } from 'rxjs'; | ||||
| import { ViewContentDirective } from './directives/view-content.directive'; | ||||
| import { ViewLoadingDirective } from './directives/view-loading.directive'; | ||||
| import { ViewNoRecordsDirective } from './directives/view-no-records.directive'; | ||||
| 
 | ||||
| @Component({ | ||||
|   selector: 'ps-view', | ||||
|   templateUrl: './view.component.html', | ||||
|   styleUrls: ['./view.component.scss'] | ||||
| }) | ||||
| export class ViewComponent implements OnInit, OnDestroy { | ||||
|   | ||||
| 
 | ||||
|   constructor() { } | ||||
| 
 | ||||
|   @Input() dataSource: IDataSource<any>; | ||||
|   @Input() noRecordsText: string; | ||||
|   @Input() loadingText: string; | ||||
|   @Input() noRecordClasses: any; | ||||
| 
 | ||||
|   @ContentChild(ViewContentDirective) viewContent: ViewContentDirective; | ||||
|   @ContentChild(ViewLoadingDirective) viewLoading: ViewLoadingDirective; | ||||
|   @ContentChild(ViewNoRecordsDirective) viewNoRecords: ViewNoRecordsDirective; | ||||
| 
 | ||||
|   loading:boolean = false; | ||||
|   private _viewModel: any = null; | ||||
| 
 | ||||
|   private _dataSubscription: Subscription; | ||||
|   private _loadingSubscription: Subscription; | ||||
| 
 | ||||
|   ngOnDestroy(): void { | ||||
|     this._dataSubscription.unsubscribe(); | ||||
|     this._loadingSubscription.unsubscribe(); | ||||
|   } | ||||
| 
 | ||||
|   ngOnInit(): void { | ||||
|     this._dataSubscription = this.dataSource.data$.subscribe(newData => {  | ||||
|       if (newData && newData.data && newData.data.length)      | ||||
|         this._viewModel = newData.data[0]; | ||||
|     }); | ||||
| 
 | ||||
|     this._loadingSubscription = this.dataSource.loading$.subscribe(loading => { | ||||
|       this.loading = loading; | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   get noData(){ | ||||
|     return this._viewModel ? false : true; | ||||
|   } | ||||
| 
 | ||||
|   get viewModel() { | ||||
|     return this._viewModel; | ||||
|   } | ||||
| 
 | ||||
|   get noRecords(){ | ||||
|     return this.noRecordsText || "No records..."; | ||||
|   } | ||||
| 
 | ||||
|   get finalLoadingText() { | ||||
|     return this.loadingText || 'Loading ...'; | ||||
|   } | ||||
| 
 | ||||
|   getViewContentTemplate(){ | ||||
|     if(this.viewContent == null) | ||||
|       return null; | ||||
|     return this.viewContent.template; | ||||
|   } | ||||
| 
 | ||||
|   getViewNoRecordsTemplate(){ | ||||
|     if(this.viewNoRecords == null) | ||||
|       return null; | ||||
|     return this.viewNoRecords.template; | ||||
|   } | ||||
| 
 | ||||
|   getViewLoadingTemplate(){ | ||||
|     if(this.viewLoading == null) | ||||
|       return null; | ||||
|     return this.viewLoading.template; | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										17
									
								
								projects/poweredsoft/ngx-cdk-ui/src/lib/view/view.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								projects/poweredsoft/ngx-cdk-ui/src/lib/view/view.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| import { NgModule } from '@angular/core'; | ||||
| import { CommonModule } from '@angular/common'; | ||||
| import { ViewComponent } from './view.component'; | ||||
| import { ViewContentDirective } from './directives/view-content.directive'; | ||||
| import { ViewLoadingDirective } from './directives/view-loading.directive'; | ||||
| import { ViewNoRecordsDirective } from './directives/view-no-records.directive'; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @NgModule({ | ||||
|   declarations: [ViewComponent, ViewContentDirective, ViewLoadingDirective, ViewNoRecordsDirective], | ||||
|   imports: [ | ||||
|     CommonModule | ||||
|   ], | ||||
|   exports: [ViewComponent, ViewContentDirective, ViewLoadingDirective, ViewNoRecordsDirective] | ||||
| }) | ||||
| export class ViewModule { } | ||||
| @ -2,6 +2,7 @@ | ||||
|  * Public API Surface of ngx-cdk-ui | ||||
|  */ | ||||
| 
 | ||||
| // data grid.
 | ||||
| export * from './lib/data-grid/data-grid.module'; | ||||
| export * from './lib/data-grid/data-grid/data-grid.component'; | ||||
| export * from './lib/data-grid/directives/data-grid-cell.directive'; | ||||
| @ -21,9 +22,17 @@ export * from './lib/list-view/directives/list-view-header.directive'; | ||||
| export * from './lib/list-view/directives/list-view-footer.directive'; | ||||
| export * from './lib/list-view/directives/list-view-seperator.directive'; | ||||
| 
 | ||||
| // search
 | ||||
| export * from './lib/ds-search/ds-search.module'; | ||||
| export * from './lib/ds-search/ds-search.component'; | ||||
| 
 | ||||
| // ds validation
 | ||||
| export * from './lib/ds-validation-error/ds-validation-error.module'; | ||||
| export * from './lib/ds-validation-error/ds-validation-error.component'; | ||||
| export * from './lib/ds-validation-error/ds-validation-error.component'; | ||||
| 
 | ||||
| // view
 | ||||
| export * from './lib/view/view.module'; | ||||
| export * from './lib/view/view.component'; | ||||
| export * from './lib/view/directives/view-content.directive'; | ||||
| export * from './lib/view/directives/view-loading.directive'; | ||||
| export * from './lib/view/directives/view-no-records.directive'; | ||||
| @ -12,6 +12,10 @@ const routes: Routes = [ | ||||
|     path: 'data-grid', | ||||
|     loadChildren: () => import('./data-grid-demo/data-grid-demo.module').then(m => m.DataGridDemoModule) | ||||
|   }, | ||||
|   { | ||||
|     path: 'view', | ||||
|     loadChildren: () => import('./view-demo/view-demo.module').then(m => m.ViewDemoModule) | ||||
|   }, | ||||
|   { | ||||
|     path: 'list-view', | ||||
|     loadChildren: () => import('./list-view-demo/list-view-demo.module').then(m => m.ListViewDemoModule) | ||||
|  | ||||
| @ -12,6 +12,9 @@ | ||||
|         <li class="nav-item"> | ||||
|           <a class="nav-link" routerLink="list-view">List View</a> | ||||
|         </li> | ||||
|         <li class="nav-item"> | ||||
|           <a class="nav-link" routerLink="view">View</a> | ||||
|         </li> | ||||
|         <li class="nav-item"> | ||||
|           <a class="nav-link" routerLink="command-modal">Command Modal</a> | ||||
|         </li> | ||||
|  | ||||
							
								
								
									
										104
									
								
								src/app/view-demo/view-demo-page/view-demo-page.component.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								src/app/view-demo/view-demo-page/view-demo-page.component.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,104 @@ | ||||
| <h1>Found</h1> | ||||
| <ps-view [dataSource]="dataSource"> | ||||
|     <ng-container *psViewContent="let model"> | ||||
|         <div class="card"> | ||||
|             <div class="card-header"> | ||||
| 
 | ||||
|                 {{ model.firstName }} {{ model.lastName }} | ||||
|             </div> | ||||
|             <div class="card-body"> | ||||
|                 Hey, thank you! | ||||
|             </div> | ||||
|         </div> | ||||
|     </ng-container> | ||||
|     <ng-container *psViewNoRecords> | ||||
|         <div class="alert alert-info text-center"> | ||||
|             Could not find record that was requested.<br> | ||||
|             <svg style="height: 100px; width: 100px;" fill="none" stroke="#000" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> | ||||
|         </div> | ||||
|     </ng-container> | ||||
|     <ng-container *psViewLoading> | ||||
|         <div class="text-center mt-3"> | ||||
|             <svg style="height: 100px; "version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" | ||||
|                 xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 100 100" | ||||
|                 enable-background="new 0 0 100 100" xml:space="preserve"> | ||||
|                 <rect fill="#000" width="3" height="100" transform="translate(0) rotate(180 3 50)"> | ||||
|                     <animate attributeName="height" attributeType="XML" dur="1s" values="30; 100; 30" | ||||
|                         repeatCount="indefinite" /> | ||||
|                 </rect> | ||||
|                 <rect x="17" fill="#000" width="3" height="100" transform="translate(0) rotate(180 20 50)"> | ||||
|                     <animate attributeName="height" attributeType="XML" dur="1s" values="30; 100; 30" | ||||
|                         repeatCount="indefinite" begin="0.1s" /> | ||||
|                 </rect> | ||||
|                 <rect x="40" fill="#000" width="3" height="100" transform="translate(0) rotate(180 40 50)"> | ||||
|                     <animate attributeName="height" attributeType="XML" dur="1s" values="30; 100; 30" | ||||
|                         repeatCount="indefinite" begin="0.3s" /> | ||||
|                 </rect> | ||||
|                 <rect x="60" fill="#000" width="3" height="100" transform="translate(0) rotate(180 58 50)"> | ||||
|                     <animate attributeName="height" attributeType="XML" dur="1s" values="30; 100; 30" | ||||
|                         repeatCount="indefinite" begin="0.5s" /> | ||||
|                 </rect> | ||||
|                 <rect x="80" fill="#000" width="3" height="100" transform="translate(0) rotate(180 76 50)"> | ||||
|                     <animate attributeName="height" attributeType="XML" dur="1s" values="30; 100; 30" | ||||
|                         repeatCount="indefinite" begin="0.1s" /> | ||||
|                 </rect> | ||||
|             </svg> | ||||
| 
 | ||||
|             <h1 class="mt-3">Loading ...</h1> | ||||
|         </div> | ||||
| 
 | ||||
|     </ng-container> | ||||
| </ps-view> | ||||
| 
 | ||||
| <hr> | ||||
| <h1>Not found</h1> | ||||
| <ps-view [dataSource]="dataSource2"> | ||||
|     <ng-container *psViewContent="let model"> | ||||
|         <div class="card"> | ||||
|             <div class="card-header"> | ||||
| 
 | ||||
|                 {{ model.firstName }} {{ model.lastName }} | ||||
|             </div> | ||||
|             <div class="card-body"> | ||||
|                 Hey, thank you! | ||||
|             </div> | ||||
|         </div> | ||||
|     </ng-container> | ||||
|     <ng-container *psViewNoRecords> | ||||
|         <div class="alert alert-info text-center"> | ||||
|             Could not find record that was requested.<br> | ||||
|             <svg style="height: 100px; width: 100px;" fill="none" stroke="#000" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> | ||||
|         </div> | ||||
|     </ng-container> | ||||
|     <ng-container *psViewLoading> | ||||
|         <div class="text-center mt-3"> | ||||
|             <svg style="height: 100px; "version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" | ||||
|                 xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 100 100" | ||||
|                 enable-background="new 0 0 100 100" xml:space="preserve"> | ||||
|                 <rect fill="#000" width="3" height="100" transform="translate(0) rotate(180 3 50)"> | ||||
|                     <animate attributeName="height" attributeType="XML" dur="1s" values="30; 100; 30" | ||||
|                         repeatCount="indefinite" /> | ||||
|                 </rect> | ||||
|                 <rect x="17" fill="#000" width="3" height="100" transform="translate(0) rotate(180 20 50)"> | ||||
|                     <animate attributeName="height" attributeType="XML" dur="1s" values="30; 100; 30" | ||||
|                         repeatCount="indefinite" begin="0.1s" /> | ||||
|                 </rect> | ||||
|                 <rect x="40" fill="#000" width="3" height="100" transform="translate(0) rotate(180 40 50)"> | ||||
|                     <animate attributeName="height" attributeType="XML" dur="1s" values="30; 100; 30" | ||||
|                         repeatCount="indefinite" begin="0.3s" /> | ||||
|                 </rect> | ||||
|                 <rect x="60" fill="#000" width="3" height="100" transform="translate(0) rotate(180 58 50)"> | ||||
|                     <animate attributeName="height" attributeType="XML" dur="1s" values="30; 100; 30" | ||||
|                         repeatCount="indefinite" begin="0.5s" /> | ||||
|                 </rect> | ||||
|                 <rect x="80" fill="#000" width="3" height="100" transform="translate(0) rotate(180 76 50)"> | ||||
|                     <animate attributeName="height" attributeType="XML" dur="1s" values="30; 100; 30" | ||||
|                         repeatCount="indefinite" begin="0.1s" /> | ||||
|                 </rect> | ||||
|             </svg> | ||||
| 
 | ||||
|             <h1 class="mt-3">Loading ...</h1> | ||||
|         </div> | ||||
| 
 | ||||
|     </ng-container> | ||||
| </ps-view> | ||||
							
								
								
									
										52
									
								
								src/app/view-demo/view-demo-page/view-demo-page.component.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/app/view-demo/view-demo-page/view-demo-page.component.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| import { Component, OnInit } from '@angular/core'; | ||||
| import { IDataSource } from '@poweredsoft/data'; | ||||
| import { HttpDataSourceService } from '@poweredsoft/ngx-data'; | ||||
| import { of } from 'rxjs'; | ||||
| 
 | ||||
| interface OnePersonQuery { | ||||
|   personId: number | ||||
| } | ||||
| 
 | ||||
| interface Person { | ||||
|   id: number, | ||||
|   firstName: string, | ||||
|   lastName: string | ||||
| } | ||||
| 
 | ||||
| @Component({ | ||||
|   selector: 'ps-view-demo-page', | ||||
|   templateUrl: './view-demo-page.component.html', | ||||
|   styleUrls: ['./view-demo-page.component.scss'] | ||||
| }) | ||||
| export class ViewDemoPageComponent implements OnInit { | ||||
| 
 | ||||
|   dataSource: IDataSource<Person>; | ||||
|   dataSource2: IDataSource<Person>; | ||||
|   constructor(private hdss: HttpDataSourceService) {  | ||||
|     this.dataSource = this.hdss.singleBuilder<OnePersonQuery, Person, number>() | ||||
|       .keyResolver(m => m.id) | ||||
|       .queryUrl('https://localhost:5001/api/query/onePerson') | ||||
|       .beforeRead(_ => { | ||||
|         return of({ | ||||
|           personId: 1 | ||||
|         }) | ||||
|       }) | ||||
|       .createDataSource(); | ||||
| 
 | ||||
|       this.dataSource2 = this.hdss.singleBuilder<OnePersonQuery, Person, number>() | ||||
|       .keyResolver(m => m.id) | ||||
|       .queryUrl('https://localhost:5001/api/query/onePerson') | ||||
|       .beforeRead(_ => { | ||||
|         return of({ | ||||
|           personId: 3 | ||||
|         }); | ||||
|       }) | ||||
|       .createDataSource(); | ||||
|   } | ||||
| 
 | ||||
|   ngOnInit(): void { | ||||
|     this.dataSource.refresh(); | ||||
|     this.dataSource2.refresh(); | ||||
|   } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										17
									
								
								src/app/view-demo/view-demo-routing.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/app/view-demo/view-demo-routing.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| import { NgModule } from '@angular/core'; | ||||
| import { Routes, RouterModule } from '@angular/router'; | ||||
| import { ViewDemoPageComponent } from './view-demo-page/view-demo-page.component'; | ||||
| 
 | ||||
| 
 | ||||
| const routes: Routes = [ | ||||
|   { | ||||
|     path: '', | ||||
|     component: ViewDemoPageComponent | ||||
|   } | ||||
| ]; | ||||
| 
 | ||||
| @NgModule({ | ||||
|   imports: [RouterModule.forChild(routes)], | ||||
|   exports: [RouterModule] | ||||
| }) | ||||
| export class ViewDemoRoutingModule { } | ||||
							
								
								
									
										18
									
								
								src/app/view-demo/view-demo.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/app/view-demo/view-demo.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| import { NgModule } from '@angular/core'; | ||||
| import { CommonModule } from '@angular/common'; | ||||
| 
 | ||||
| import { ViewDemoRoutingModule } from './view-demo-routing.module'; | ||||
| import { ViewDemoPageComponent } from './view-demo-page/view-demo-page.component'; | ||||
| import { ViewModule } from '@poweredsoft/ngx-cdk-ui'; | ||||
| 
 | ||||
| 
 | ||||
| @NgModule({ | ||||
|   declarations: [ViewDemoPageComponent], | ||||
|   imports: [ | ||||
|     CommonModule, | ||||
|     ViewDemoRoutingModule, | ||||
|     CommonModule, | ||||
|     ViewModule | ||||
|   ] | ||||
| }) | ||||
| export class ViewDemoModule { } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user