diff --git a/src/app/@core/data/promotion.ts b/src/app/@core/data/promotion.ts new file mode 100644 index 00000000..bac58aeb --- /dev/null +++ b/src/app/@core/data/promotion.ts @@ -0,0 +1,30 @@ +export interface PromotionList { + id: number; + customerType: string; + customerID: string; + code: string; + promotionType: string; + value?: number; + maximumDiscount: number; + maximumDiscountValue: number; + minimumOrderWeight: number; + minimumOrderAmount?: number; + quota: number; + maximumPerUser: number; + product: string; + paymentMethod: string; + deviceType: string; + description: string; + validDay: string; + validFrom: string; + validTo: string; + image: string; + lastUdpateTm: string; + status: number; + target: string; + coverage: string; +} + +export interface RootObject { + promotionList: PromotionList[]; +} diff --git a/src/app/@theme/components/footer/footer.component.ts b/src/app/@theme/components/footer/footer.component.ts index 85e3b7ac..a1e07808 100644 --- a/src/app/@theme/components/footer/footer.component.ts +++ b/src/app/@theme/components/footer/footer.component.ts @@ -5,14 +5,8 @@ import { Component } from '@angular/core'; styleUrls: ['./footer.component.scss'], template: ` - Created with ♥ by Akveo 2019 + Created with ♥ by HQ-Teams @2020 -
- - - - -
`, }) export class FooterComponent { diff --git a/src/app/@theme/components/header/header.component.html b/src/app/@theme/components/header/header.component.html index e579edba..c0ee2f2d 100644 --- a/src/app/@theme/components/header/header.component.html +++ b/src/app/@theme/components/header/header.component.html @@ -5,18 +5,16 @@ - - {{ theme.name }} -
+ + {{ theme.name }} + - - import('./layout/layout.module') - .then(m => m.LayoutModule), - }, - { - path: 'forms', - loadChildren: () => import('./forms/forms.module') - .then(m => m.FormsModule), - }, - { - path: 'ui-features', - loadChildren: () => import('./ui-features/ui-features.module') - .then(m => m.UiFeaturesModule), - }, - { - path: 'modal-overlays', - loadChildren: () => import('./modal-overlays/modal-overlays.module') - .then(m => m.ModalOverlaysModule), - }, - { - path: 'extra-components', - loadChildren: () => import('./extra-components/extra-components.module') - .then(m => m.ExtraComponentsModule), - }, - { - path: 'maps', - loadChildren: () => import('./maps/maps.module') - .then(m => m.MapsModule), - }, - { - path: 'charts', - loadChildren: () => import('./charts/charts.module') - .then(m => m.ChartsModule), - }, - { - path: 'editors', - loadChildren: () => import('./editors/editors.module') - .then(m => m.EditorsModule), - }, - { - path: 'tables', - loadChildren: () => import('./tables/tables.module') - .then(m => m.TablesModule), - }, - { - path: 'miscellaneous', - loadChildren: () => import('./miscellaneous/miscellaneous.module') - .then(m => m.MiscellaneousModule), - }, - { - path: '', - redirectTo: 'dashboard', - pathMatch: 'full', - }, - { - path: '**', + path: 'tbd', component: NotFoundComponent, }, ], diff --git a/src/app/pages/promotion/promotion-detail/promotion-detail.component.scss b/src/app/pages/promotion/promotion-detail/promotion-detail.component.scss new file mode 100644 index 00000000..5aaba5bf --- /dev/null +++ b/src/app/pages/promotion/promotion-detail/promotion-detail.component.scss @@ -0,0 +1,12 @@ +@import '../../../@theme/styles/themes'; + +@include nb-install-component() { + ::ng-deep .form { + display: flex; + flex-direction: column; + + .text-label { + margin-top: 1.5rem; + } + } +} diff --git a/src/app/pages/promotion/promotion-detail/promotion-detail.component.ts b/src/app/pages/promotion/promotion-detail/promotion-detail.component.ts new file mode 100644 index 00000000..3d206b46 --- /dev/null +++ b/src/app/pages/promotion/promotion-detail/promotion-detail.component.ts @@ -0,0 +1,22 @@ +import { Component } from '@angular/core'; +import { NbWindowRef } from '@nebular/theme'; + +@Component({ + template: ` +
+ + + + + +
+ `, + styleUrls: ['promotion-detail.component.scss'], +}) +export class PromotionDetailComponent { + constructor(public windowRef: NbWindowRef) {} + + close() { + this.windowRef.close(); + } +} diff --git a/src/app/pages/promotion/promotion.component.html b/src/app/pages/promotion/promotion.component.html index 2e563cb9..03044b7a 100644 --- a/src/app/pages/promotion/promotion.component.html +++ b/src/app/pages/promotion/promotion.component.html @@ -4,7 +4,8 @@ - + - + \ No newline at end of file diff --git a/src/app/pages/promotion/promotion.component.ts b/src/app/pages/promotion/promotion.component.ts index 4d3dd9fb..68e55d19 100644 --- a/src/app/pages/promotion/promotion.component.ts +++ b/src/app/pages/promotion/promotion.component.ts @@ -1,15 +1,15 @@ -import { Component } from '@angular/core'; -import { LocalDataSource } from 'ng2-smart-table'; - -import { SmartTableData } from '../../@core/data/smart-table'; +import { Component, OnInit } from '@angular/core'; +import { PromotionList } from '../../@core/data/promotion'; +import { PromotionService } from './promotion.service'; +import { PromotionDetailComponent } from './promotion-detail/promotion-detail.component'; +import { NbWindowService } from '@nebular/theme'; @Component({ selector: 'ngx-promotion', templateUrl: './promotion.component.html', styleUrls: ['./promotion.component.scss'], }) -export class PromotionComponent { - +export class PromotionComponent implements OnInit { settings = { add: { addButtonContent: '', @@ -26,34 +26,36 @@ export class PromotionComponent { confirmDelete: true, }, columns: { - couponCode: { + code: { title: 'Coupon Code', type: 'string', }, - period: { + validDay: { title: 'Period', type: 'string', }, - validStart: { + validFrom: { title: 'Valid Start', - type: 'string', + type: 'date', }, - validEnd: { + validTo: { title: 'Valid End', - type: 'string', - }, - action: { - title: 'Action', - type: 'string', + type: 'date', }, }, }; - source: LocalDataSource = new LocalDataSource(); + source: PromotionList[] = []; - constructor(private service: SmartTableData) { - const data = this.service.getData(); - this.source.load(data); + constructor(private service: PromotionService, private windowService: NbWindowService) { + + } + + ngOnInit(): void { + this.service.getPromotion().subscribe((result) => { + this.source = Object.assign([], result); + console.log(this.source); + }); } onDeleteConfirm(event): void { @@ -63,4 +65,8 @@ export class PromotionComponent { event.confirm.reject(); } } + + openWindowForm() { + this.windowService.open(PromotionDetailComponent, { title: `Promotion Detail` }); + } } diff --git a/src/app/pages/promotion/promotion.module.ts b/src/app/pages/promotion/promotion.module.ts index 7de4689b..069973c9 100644 --- a/src/app/pages/promotion/promotion.module.ts +++ b/src/app/pages/promotion/promotion.module.ts @@ -4,6 +4,8 @@ import { Ng2SmartTableModule } from 'ng2-smart-table'; import { ThemeModule } from '../../@theme/theme.module'; import { PromotionComponent } from './promotion.component'; +import { PromotionService } from './promotion.service'; +import { PromotionDetailComponent } from './promotion-detail/promotion-detail.component'; @NgModule({ imports: [ @@ -16,6 +18,13 @@ import { PromotionComponent } from './promotion.component'; ], declarations: [ PromotionComponent, + PromotionDetailComponent, + ], + providers: [ + PromotionService, + ], + entryComponents: [ + PromotionDetailComponent, ], }) export class PromotionModule { } diff --git a/src/app/pages/promotion/promotion.service.ts b/src/app/pages/promotion/promotion.service.ts new file mode 100644 index 00000000..73bada67 --- /dev/null +++ b/src/app/pages/promotion/promotion.service.ts @@ -0,0 +1,49 @@ +import {Injectable} from '@angular/core'; +import {HttpClient} from '@angular/common/http'; +import {Observable, throwError} from 'rxjs'; +import {map, catchError} from 'rxjs/operators'; +import {HttpErrorResponse, HttpHeaders} from '@angular/common/http'; +import { PromotionList } from '../../@core/data/promotion'; + +@Injectable({ + providedIn: 'root' +}) +export class PromotionService { + constructor(private http: HttpClient) { + } + + getPromotion(): Observable { + const url = 'http://localhost:8011/api/promotions/all'; + const headers = new HttpHeaders({ + 'Content-Type': 'application/json', + 'X-Requested-Url': url, + 'X-Requested-Method': 'GET', + }); + const options = {headers: headers}; + return this.http.get(url).pipe( + map(this.extractData), + catchError(this.handleError), + ); + } + + private extractData(body: any): PromotionList[] { + return Object.assign(body.promotionList); + } + + private handleError(error: HttpErrorResponse | any) { + let errMsg: string; + let errObj: any; + + if (error instanceof HttpErrorResponse) { + const err = error.message || JSON.stringify(error); + errMsg = `${error.status} - ${error.statusText || ''} ${err}`; + errObj = error.error.message; + } else { + errMsg = error.message ? error.message : error.toString(); + const body = error.message || ''; + errObj = body; + } + + return throwError(errObj); + } +} diff --git a/src/app/pages/sample/advanced-example-server.component.ts b/src/app/pages/sample/advanced-example-server.component.ts new file mode 100644 index 00000000..6bec740c --- /dev/null +++ b/src/app/pages/sample/advanced-example-server.component.ts @@ -0,0 +1,36 @@ +import { Component } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { ServerDataSource } from 'ng2-smart-table'; + +@Component({ + selector: 'ngx-advanced-example-server', + styleUrls: ['./examples.component.scss'], + template: ` + + `, +}) +export class AdvancedExampleServerComponent { + + settings = { + columns: { + id: { + title: 'ID', + }, + albumId: { + title: 'Album', + }, + title: { + title: 'Title', + }, + url: { + title: 'Url', + }, + }, + }; + + source: ServerDataSource; + + constructor(http: HttpClient) { + this.source = new ServerDataSource(http, { endPoint: 'https://jsonplaceholder.typicode.com/photos' }); + } +} diff --git a/src/app/pages/sample/basic-example-load.component.ts b/src/app/pages/sample/basic-example-load.component.ts new file mode 100644 index 00000000..7964410b --- /dev/null +++ b/src/app/pages/sample/basic-example-load.component.ts @@ -0,0 +1,45 @@ +import { Component } from '@angular/core'; + +import { LocalDataSource } from 'ng2-smart-table'; +import { BasicExampleLoadService } from './basic-example-load.service'; + +@Component({ + selector: 'ngx-basic-example-load', + providers: [BasicExampleLoadService], + styleUrls: ['./examples.component.scss'], + template: ` + + `, +}) +export class BasicExampleLoadComponent { + + source: LocalDataSource; + + settings = { + columns: { + id: { + title: 'ID', + editable: false, + addable: false, + }, + + name: { + title: 'Full Name', + }, + username: { + title: 'User Name', + }, + email: { + title: 'Email', + }, + }, + }; + + constructor(protected service: BasicExampleLoadService) { + this.source = new LocalDataSource(); + + this.service.getData().then((data) => { + this.source.load(data); + }); + } +} diff --git a/src/app/pages/sample/basic-example-load.service.ts b/src/app/pages/sample/basic-example-load.service.ts new file mode 100644 index 00000000..296684dd --- /dev/null +++ b/src/app/pages/sample/basic-example-load.service.ts @@ -0,0 +1,34 @@ +import { Injectable } from '@angular/core'; + +@Injectable() +export class BasicExampleLoadService { + + static DATA_SIZE = 500; + + // emulating request to the server + getData(): Promise { + return new Promise((resolve, reject) => { + setTimeout(() => { + resolve(this.generateData()); + }, 2000); + }); + } + + getNewExampleObj(n?: number): any { + n = typeof n !== 'undefined' ? n : Math.random() * 1000; + return { + id: n, + name: `Jack London ${n}`, + username: `jack_london_${n}`, + email: `jack_london_${n}@example.com`, + }; + } + + protected generateData(): Array { + const data = []; + for (let i = 0; i < BasicExampleLoadService.DATA_SIZE; i++) { + data.push(this.getNewExampleObj(i)); + } + return data; + } +} diff --git a/src/app/pages/sample/examples.component.scss b/src/app/pages/sample/examples.component.scss new file mode 100644 index 00000000..07f94b4f --- /dev/null +++ b/src/app/pages/sample/examples.component.scss @@ -0,0 +1,65 @@ +.with-sidebar { + position: relative; + + .main-content-body { + padding-left: 16rem; + } + + .fixed-sidebar { + display: block; + padding: 0 1rem; + margin-top: 2rem; + position: fixed; + top: 0; + padding-top: 290px; + width: 16rem; + font-size: 0.875rem; + + .back-top { + display: none; + margin-bottom: 1rem; + font-weight: bold; + } + + ul { + padding-left: 1rem; + list-style: none; + margin-bottom: 0.875rem; + } + + &.scrolled { + position: fixed; + top: 0; + + .back-top { + display: block; + } + } + + .examples-menu { + a.active { + font-weight: bold; + } + } + } +} + +@media screen and (max-width: 64em) { + .with-sidebar { + .fixed-sidebar { + display: none; + } + } +} + +@media screen and (min-width: 42em) and (max-width: 64em) { + .with-sidebar { + padding: 2rem 4rem; + } +} + +@media screen and (max-width: 42em) { + .with-sidebar { + padding: 2rem 1rem; + } +} diff --git a/src/app/pages/sample/sample.module.ts b/src/app/pages/sample/sample.module.ts new file mode 100644 index 00000000..b45e3018 --- /dev/null +++ b/src/app/pages/sample/sample.module.ts @@ -0,0 +1,19 @@ +import {NgModule} from '@angular/core'; +import {HttpClientModule} from '@angular/common/http'; +import {ServerExamplesComponent} from './server-examples.component'; +import {BasicExampleLoadComponent} from './basic-example-load.component'; +import {AdvancedExampleServerComponent} from './advanced-example-server.component'; +import {Ng2SmartTableModule} from 'ng2-smart-table'; + +@NgModule({ + imports: [ + HttpClientModule, + Ng2SmartTableModule, + ], + declarations: [ + ServerExamplesComponent, + BasicExampleLoadComponent, + AdvancedExampleServerComponent, + ], +}) +export class SampleModule { } diff --git a/src/app/pages/sample/server-examples.component.html b/src/app/pages/sample/server-examples.component.html new file mode 100644 index 00000000..a1efe3a9 --- /dev/null +++ b/src/app/pages/sample/server-examples.component.html @@ -0,0 +1,17 @@ +

Get data from external source example

+

Loading From Server Example

+

+ This example shows how to pass the data loaded from some API to the table DataSource. +

+
+ +
+ +

Server Data Source Example

+

+ An example on how to load data user Server DataSource: +

+
+ +
+ diff --git a/src/app/pages/sample/server-examples.component.ts b/src/app/pages/sample/server-examples.component.ts new file mode 100644 index 00000000..a0c2b244 --- /dev/null +++ b/src/app/pages/sample/server-examples.component.ts @@ -0,0 +1,8 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'ngx-server-examples', + styleUrls: ['./examples.component.scss'], + templateUrl: './server-examples.component.html', +}) +export class ServerExamplesComponent { } diff --git a/src/app/pages/sample/server.data-source.ts b/src/app/pages/sample/server.data-source.ts new file mode 100644 index 00000000..7621a359 --- /dev/null +++ b/src/app/pages/sample/server.data-source.ts @@ -0,0 +1,48 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { LocalDataSource } from 'ng2-smart-table'; +import { map } from 'rxjs/operators'; + +@Injectable() +export class CustomServerDataSource extends LocalDataSource { + + lastRequestCount: number = 0; + + constructor(protected http: HttpClient) { + super(); + } + + count(): number { + return this.lastRequestCount; + } + + getElements(): Promise { + let url = 'https://jsonplaceholder.typicode.com/photos?'; + + if (this.sortConf) { + this.sortConf.forEach((fieldConf) => { + url += `_sort=${fieldConf.field}&_order=${fieldConf.direction.toUpperCase()}&`; + }); + } + + if (this.pagingConf && this.pagingConf['page'] && this.pagingConf['perPage']) { + url += `_page=${this.pagingConf['page']}&_limit=${this.pagingConf['perPage']}&`; + } + + if (this.filterConf.filters) { + this.filterConf.filters.forEach((fieldConf) => { + if (fieldConf['search']) { + url += `${fieldConf['field']}_like=${fieldConf['search']}&`; + } + }); + } + + return this.http.get(url, { observe: 'response' }) + .pipe( + map(res => { + this.lastRequestCount = +res.headers.get('x-total-count'); + return res.body; + }), + ).toPromise(); + } +}