feat: upgrade to angular 9

This commit is contained in:
Maksim Karatkevich 2020-05-22 11:06:37 +03:00
parent ce09539c66
commit 246f9b595a
90 changed files with 2505 additions and 7521 deletions

View file

@ -1,26 +1,9 @@
# ngx-admin [<img src="https://i.imgur.com/oMcxwZ0.png" alt="Eva Design System" height="20px" />](https://hubs.ly/H0n4ZDy0) [![Build Status](https://travis-ci.org/akveo/ngx-admin.svg?branch=master)](https://travis-ci.org/akveo/ngx-admin) [![Dependency Status](https://david-dm.org/akveo/ngx-admin/status.svg)](https://david-dm.org/akveo/ng2-admin)
# ngx-admin [<img src="https://i.imgur.com/oMcxwZ0.png" alt="Eva Design System" height="20px" />](https://eva.design) [![Build Status](https://travis-ci.org/akveo/ngx-admin.svg?branch=master)](https://travis-ci.org/akveo/ngx-admin) [![Dependency Status](https://david-dm.org/akveo/ngx-admin/status.svg)](https://david-dm.org/akveo/ng2-admin)
[Who uses ngx-admin?](https://github.com/akveo/ngx-admin/issues/1645)| [Documentation](https://hubs.ly/H0n4Sfq0) | [Installation Guidelines](https://hubs.ly/H0n4Svc0)
# New! Material theme for ngx-admin
### Material admin theme is based on the most popular Angular dashboard template - [ngx-admin](https://hubs.ly/H0nJG1G0)
### Included: Angular 9+, [Nebular](https://hubs.ly/H0nJG5g0) and [Eva design system](https://hubs.ly/H0nJGdC0). Free for personal and commercial usage.
### Get material ngx-admin integrated with backend technology of your choice. Check out our store.
<a target="_blank" href="https://hubs.ly/H0nxM3b0"><img src="https://i.imgur.com/csP0aZ9.png"/></a>
## Key features
- The most popular and trusted Angular open source dashboard template is out there. Used by hundreds of thousands developers worldwide and Fortune 500 companies*.
- Over 40+ Angular Components and 60+ Usage Examples. Kick off your project and save money by using ngx-admin.
- Already using ngx-admin and willing to switch to material theme? Material theme is backward-compatible. Check out the article describing how to do that.
- ngx-admin material works perfectly with Angular Material and Nebular. Take the best from both!
### To use material theme checkout `feat/material-theme` branch
[Who uses ngx-admin?](https://github.com/akveo/ngx-admin/issues/1645)| [Documentation](https://akveo.github.io/ngx-admin/?utm_source=github&utm_medium=ngx_admin_readme&utm_campaign=themes) | [Installation Guidelines](https://akveo.github.io/ngx-admin/docs/getting-started/what-is-ngxadmin?utm_source=github&utm_medium=ngx_admin_readme&utm_campaign=themes)
# Admin template based on Angular 9+ and <a href="https://github.com/akveo/nebular">Nebular</a>
<a target="_blank" href="https://hubs.ly/H0n4Sw20"><img src="https://i.imgur.com/mFdqvgG.png"/></a>
<a target="_blank" href="http://akveo.com/ngx-admin/pages/dashboard?theme=corporate&utm_source=github&utm_medium=ngx_admin_readme&utm_campaign=main_pic"><img src="https://i.imgur.com/mFdqvgG.png"/></a>
### Backend Integration Bundles
Easy way to integrate ngx-admin with backend (.NET, Node.js, Java etc.).
@ -29,7 +12,7 @@ Easy way to integrate ngx-admin with backend (.NET, Node.js, Java etc.).
<img src="https://i.imgur.com/Ywbs8cl.png"/>
</a>
[Check out our Store](https://hubs.ly/H0n4Zvy0) for ready to use Backend Bundles.
[Checkout our Store](https://hubs.ly/H0qwC2Q0) for ready to use Backend Bundles.
### With 6 stunning visual themes
@ -66,10 +49,10 @@ Easy way to integrate ngx-admin with backend (.NET, Node.js, Java etc.).
### Demo
<a target="_blank" href="https://hubs.ly/H0n4Tk70">Live Demo</a>
<a target="_blank" href="http://akveo.com/ngx-admin/">Live Demo</a>
## Documentation
This template is using [Nebular](https://github.com/akveo/nebular) modules set, [here you can find documentation and other useful articles](https://hubs.ly/H0n4ZPt0).
This template is using [Nebular](https://github.com/akveo/nebular) modules set, [here you can find documentation and other useful articles](https://akveo.github.io/nebular/docs/guides/install-based-on-starter-kit).
### Empty starter kit
Don't need all the pages and modules and just looking for an empty starter kit for your next project? Check out our [starter-kit branch](https://github.com/akveo/ngx-admin/tree/starter-kit).
@ -91,8 +74,8 @@ This project runs its tests on multiple desktop and mobile browsers using [Brows
- Like our page on [Facebook](https://www.facebook.com/akveo/) :thumbsup:
### Looking for engineering services?
Visit [our homepage](https://hubs.ly/H0n4YJt0) or simply leave us a message to [contact@akveo.com](mailto:contact@akveo.com). We will be happy to work with you!
Visit [our homepage](http://akveo.com/) or simply leave us a message to [contact@akveo.com](mailto:contact@akveo.com). We will be happy to work with you!
### From Developers
Made with :heart: by [Akveo team](https://hubs.ly/H0n4YwQ0). Follow us on [Twitter](https://twitter.com/akveo_inc) to get the latest news first!
Made with :heart: by [Akveo team](http://akveo.com/). Follow us on [Twitter](https://twitter.com/akveo_inc) to get the latest news first!
We're always happy to receive your feedback!

View file

@ -183,5 +183,8 @@
"@schematics/angular:directive": {
"prefix": "ngx"
}
},
"cli": {
"analytics": "25084c8e-7e3c-4955-91c5-66ed595e9666"
}
}

4813
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -37,7 +37,7 @@
"@angular/compiler": "^9.0.4",
"@angular/core": "^9.0.4",
"@angular/forms": "^9.0.4",
"@angular/google-maps": "^9.1.0",
"@angular/material": "^9.1.0",
"@angular/platform-browser": "^9.0.4",
"@angular/platform-browser-dynamic": "^9.0.4",
"@angular/router": "^9.0.4",
@ -60,7 +60,6 @@
"leaflet": "1.2.0",
"nebular-icons": "1.1.0",
"ng2-ckeditor": "^1.2.2",
"ng2-smart-table": "^1.6.0",
"ngx-echarts": "^4.2.2",
"node-sass": "^4.12.0",
"normalize.css": "6.0.0",
@ -84,7 +83,6 @@
"@compodoc/compodoc": "1.0.1",
"@fortawesome/fontawesome-free": "^5.2.0",
"@types/d3-color": "1.0.5",
"@types/googlemaps": "^3.39.3",
"@types/jasmine": "2.5.54",
"@types/jasminewd2": "2.0.3",
"@types/leaflet": "1.2.3",

View file

@ -1,6 +1,5 @@
import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MAT_RIPPLE_GLOBAL_OPTIONS } from '@angular/material/core';
import { NbAuthModule, NbDummyAuthStrategy } from '@nebular/auth';
import { NbSecurityModule, NbRoleProvider } from '@nebular/security';
import { of as observableOf } from 'rxjs';
@ -9,50 +8,9 @@ import { throwIfAlreadyLoaded } from './module-import-guard';
import {
AnalyticsService,
LayoutService,
PlayerService,
SeoService,
StateService,
} from './utils';
import { UserData } from './data/users';
import { ElectricityData } from './data/electricity';
import { SmartTableData } from './data/smart-table';
import { UserActivityData } from './data/user-activity';
import { OrdersChartData } from './data/orders-chart';
import { ProfitChartData } from './data/profit-chart';
import { TrafficListData } from './data/traffic-list';
import { EarningData } from './data/earning';
import { OrdersProfitChartData } from './data/orders-profit-chart';
import { TrafficBarData } from './data/traffic-bar';
import { ProfitBarAnimationChartData } from './data/profit-bar-animation-chart';
import { TemperatureHumidityData } from './data/temperature-humidity';
import { SolarData } from './data/solar';
import { TrafficChartData } from './data/traffic-chart';
import { StatsBarData } from './data/stats-bar';
import { CountryOrderData } from './data/country-order';
import { StatsProgressBarData } from './data/stats-progress-bar';
import { VisitorsAnalyticsData } from './data/visitors-analytics';
import { SecurityCamerasData } from './data/security-cameras';
import { UserService } from './mock/users.service';
import { ElectricityService } from './mock/electricity.service';
import { SmartTableService } from './mock/smart-table.service';
import { UserActivityService } from './mock/user-activity.service';
import { OrdersChartService } from './mock/orders-chart.service';
import { ProfitChartService } from './mock/profit-chart.service';
import { TrafficListService } from './mock/traffic-list.service';
import { EarningService } from './mock/earning.service';
import { OrdersProfitChartService } from './mock/orders-profit-chart.service';
import { TrafficBarService } from './mock/traffic-bar.service';
import { ProfitBarAnimationChartService } from './mock/profit-bar-animation-chart.service';
import { TemperatureHumidityService } from './mock/temperature-humidity.service';
import { SolarService } from './mock/solar.service';
import { TrafficChartService } from './mock/traffic-chart.service';
import { StatsBarService } from './mock/stats-bar.service';
import { CountryOrderService } from './mock/country-order.service';
import { StatsProgressBarService } from './mock/stats-progress-bar.service';
import { VisitorsAnalyticsService } from './mock/visitors-analytics.service';
import { SecurityCamerasService } from './mock/security-cameras.service';
import { RippleService } from './utils/ripple.service';
import { MockDataModule } from './mock/mock-data.module';
const socialLinks = [
@ -75,25 +33,6 @@ const socialLinks = [
const DATA_SERVICES = [
{ provide: UserData, useClass: UserService },
{ provide: ElectricityData, useClass: ElectricityService },
{ provide: SmartTableData, useClass: SmartTableService },
{ provide: UserActivityData, useClass: UserActivityService },
{ provide: OrdersChartData, useClass: OrdersChartService },
{ provide: ProfitChartData, useClass: ProfitChartService },
{ provide: TrafficListData, useClass: TrafficListService },
{ provide: EarningData, useClass: EarningService },
{ provide: OrdersProfitChartData, useClass: OrdersProfitChartService },
{ provide: TrafficBarData, useClass: TrafficBarService },
{ provide: ProfitBarAnimationChartData, useClass: ProfitBarAnimationChartService },
{ provide: TemperatureHumidityData, useClass: TemperatureHumidityService },
{ provide: SolarData, useClass: SolarService },
{ provide: TrafficChartData, useClass: TrafficChartService },
{ provide: StatsBarData, useClass: StatsBarService },
{ provide: CountryOrderData, useClass: CountryOrderService },
{ provide: StatsProgressBarData, useClass: StatsProgressBarService },
{ provide: VisitorsAnalyticsData, useClass: VisitorsAnalyticsService },
{ provide: SecurityCamerasData, useClass: SecurityCamerasService },
{provide: MAT_RIPPLE_GLOBAL_OPTIONS, useExisting: RippleService},
];
export class NbSimpleRoleProvider extends NbRoleProvider {
@ -143,9 +82,6 @@ export const NB_CORE_PROVIDERS = [
},
AnalyticsService,
LayoutService,
PlayerService,
SeoService,
StateService,
];
@NgModule({

View file

@ -16,7 +16,7 @@ const SERVICES = [
],
})
export class MockDataModule {
static forRoot(): ModuleWithProviders<MockDataModule> {
static forRoot(): ModuleWithProviders {
return <ModuleWithProviders>{
ngModule: MockDataModule,
providers: [

View file

@ -1,13 +1,7 @@
import { LayoutService } from './layout.service';
import { AnalyticsService } from './analytics.service';
import { PlayerService } from './player.service';
import { StateService } from './state.service';
import { SeoService } from './seo.service';
export {
LayoutService,
AnalyticsService,
PlayerService,
SeoService,
StateService,
};

View file

@ -1,58 +0,0 @@
import { Injectable, Inject, PLATFORM_ID, OnDestroy } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { NavigationEnd, Router } from '@angular/router';
import { NB_DOCUMENT } from '@nebular/theme';
import { filter, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
@Injectable()
export class SeoService implements OnDestroy {
private readonly destroy$ = new Subject<void>();
private readonly dom: Document;
private readonly isBrowser: boolean;
private linkCanonical: HTMLLinkElement;
constructor(
private router: Router,
@Inject(NB_DOCUMENT) document,
@Inject(PLATFORM_ID) platformId,
) {
this.isBrowser = isPlatformBrowser(platformId);
this.dom = document;
if (this.isBrowser) {
this.createCanonicalTag();
}
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
createCanonicalTag() {
this.linkCanonical = this.dom.createElement('link');
this.linkCanonical.setAttribute('rel', 'canonical');
this.dom.head.appendChild(this.linkCanonical);
this.linkCanonical.setAttribute('href', this.getCanonicalUrl());
}
trackCanonicalChanges() {
if (!this.isBrowser) {
return;
}
this.router.events.pipe(
filter((event) => event instanceof NavigationEnd),
takeUntil(this.destroy$),
)
.subscribe(() => {
this.linkCanonical.setAttribute('href', this.getCanonicalUrl());
});
}
private getCanonicalUrl(): string {
return this.dom.location.origin + this.dom.location.pathname;
}
}

View file

@ -4,9 +4,7 @@ import { Component } from '@angular/core';
selector: 'ngx-footer',
styleUrls: ['./footer.component.scss'],
template: `
<span class="created-by">
Created with by <b><a href="https://akveo.page.link/8V2f" target="_blank">Akveo</a></b> 2019
</span>
<span class="created-by">Created with by <b><a href="https://akveo.com" target="_blank">Akveo</a></b> 2019</span>
<div class="socials">
<a href="#" target="_blank" class="ion ion-social-github"></a>
<a href="#" target="_blank" class="ion ion-social-facebook"></a>

View file

@ -1,37 +0,0 @@
import { Component, OnDestroy, AfterViewInit, Output, EventEmitter, ElementRef } from '@angular/core';
import { LocationStrategy } from '@angular/common';
@Component({
selector: 'ngx-tiny-mce',
template: '',
})
export class TinyMCEComponent implements OnDestroy, AfterViewInit {
@Output() editorKeyup = new EventEmitter<any>();
editor: any;
constructor(
private host: ElementRef,
private locationStrategy: LocationStrategy,
) { }
ngAfterViewInit() {
tinymce.init({
target: this.host.nativeElement,
plugins: ['link', 'paste', 'table'],
skin_url: `${this.locationStrategy.getBaseHref()}assets/skins/lightgray`,
setup: editor => {
this.editor = editor;
editor.on('keyup', () => {
this.editorKeyup.emit(editor.getContent());
});
},
height: '320',
});
}
ngOnDestroy() {
tinymce.remove(this.editor);
}
}

View file

@ -5,7 +5,6 @@
*/
import { Component, OnInit } from '@angular/core';
import { AnalyticsService } from './@core/utils/analytics.service';
import { SeoService } from './@core/utils/seo.service';
@Component({
selector: 'ngx-app',
@ -13,11 +12,10 @@ import { SeoService } from './@core/utils/seo.service';
})
export class AppComponent implements OnInit {
constructor(private analytics: AnalyticsService, private seoService: SeoService) {
constructor(private analytics: AnalyticsService) {
}
ngOnInit() {
this.analytics.trackPageViews();
this.seoService.trackCanonicalChanges();
}
}

View file

@ -28,6 +28,9 @@ import {
BrowserAnimationsModule,
HttpClientModule,
AppRoutingModule,
ThemeModule.forRoot(),
NbSidebarModule.forRoot(),
NbMenuModule.forRoot(),
NbDatepickerModule.forRoot(),
@ -38,7 +41,6 @@ import {
messageGoogleMapKey: 'AIzaSyA_wNuCzia92MAmdLRzmqitRGvCF7wCZPY',
}),
CoreModule.forRoot(),
ThemeModule.forRoot(),
],
bootstrap: [AppComponent],
})

View file

@ -1,23 +0,0 @@
<nb-card size="giant">
<nb-tabset fullWidth>
<nb-tab tabTitle="Contacts">
<nb-list>
<nb-list-item matRipple class="contact" *ngFor="let c of contacts">
<nb-user [picture]="c.user.picture" [name]="c.user.name" [title]="c.type" size="large"></nb-user>
<nb-icon icon="phone-outline" pack="eva"></nb-icon>
</nb-list-item>
</nb-list>
</nb-tab>
<nb-tab tabTitle="Recent">
<nb-list>
<nb-list-item matRipple class="contact" *ngFor="let c of recent">
<nb-user [picture]="c.user.picture" [name]="c.user.name" [title]="c.type" size="large"></nb-user>
<span class="caption">{{ c.time | date: 'shortTime' }}</span>
</nb-list-item>
</nb-list>
</nb-tab>
</nb-tabset>
</nb-card>

View file

@ -1,103 +1,8 @@
import {Component, OnDestroy} from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { takeWhile } from 'rxjs/operators' ;
import { SolarData } from '../../@core/data/solar';
interface CardSettings {
title: string;
iconClass: string;
type: string;
}
import { Component } from '@angular/core';
@Component({
selector: 'ngx-dashboard',
styleUrls: ['./dashboard.component.scss'],
templateUrl: './dashboard.component.html',
})
export class DashboardComponent implements OnDestroy {
private alive = true;
solarValue: number;
lightCard: CardSettings = {
title: 'Light',
iconClass: 'nb-lightbulb',
type: 'primary',
};
rollerShadesCard: CardSettings = {
title: 'Roller Shades',
iconClass: 'nb-roller-shades',
type: 'success',
};
wirelessAudioCard: CardSettings = {
title: 'Wireless Audio',
iconClass: 'nb-audio',
type: 'info',
};
coffeeMakerCard: CardSettings = {
title: 'Coffee Maker',
iconClass: 'nb-coffee-maker',
type: 'warning',
};
statusCards: string;
commonStatusCardsSet: CardSettings[] = [
this.lightCard,
this.rollerShadesCard,
this.wirelessAudioCard,
this.coffeeMakerCard,
];
statusCardsByThemes: {
default: CardSettings[];
cosmic: CardSettings[];
corporate: CardSettings[];
dark: CardSettings[];
'material-dark': CardSettings[];
'material-light': CardSettings[];
} = {
default: this.commonStatusCardsSet,
cosmic: this.commonStatusCardsSet,
corporate: [
{
...this.lightCard,
type: 'warning',
},
{
...this.rollerShadesCard,
type: 'primary',
},
{
...this.wirelessAudioCard,
type: 'danger',
},
{
...this.coffeeMakerCard,
type: 'info',
},
],
dark: this.commonStatusCardsSet,
'material-dark': this.commonStatusCardsSet,
'material-light': this.commonStatusCardsSet,
};
constructor(private themeService: NbThemeService,
private solarService: SolarData) {
this.themeService.getJsTheme()
.pipe(takeWhile(() => this.alive))
.subscribe(theme => {
this.statusCards = this.statusCardsByThemes[theme.name];
});
this.solarService.getSolarData()
.pipe(takeWhile(() => this.alive))
.subscribe((data) => {
this.solarValue = data;
});
}
ngOnDestroy() {
this.alive = false;
}
export class DashboardComponent {
}

View file

@ -1,197 +0,0 @@
import { delay, takeWhile } from 'rxjs/operators';
import { AfterViewInit, Component, Input, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { LayoutService } from '../../../../@core/utils';
import { ElectricityChart } from '../../../../@core/data/electricity';
@Component({
selector: 'ngx-electricity-chart',
styleUrls: ['./electricity-chart.component.scss'],
template: `
<div echarts
[options]="option"
class="echart"
(chartInit)="onChartInit($event)">
</div>
`,
})
export class ElectricityChartComponent implements AfterViewInit, OnDestroy {
private alive = true;
@Input() data: ElectricityChart[];
option: any;
echartsIntance: any;
constructor(private theme: NbThemeService,
private layoutService: LayoutService) {
this.layoutService.onSafeChangeLayoutSize()
.pipe(
takeWhile(() => this.alive),
)
.subscribe(() => this.resizeChart());
}
ngAfterViewInit(): void {
this.theme.getJsTheme()
.pipe(
takeWhile(() => this.alive),
delay(1),
)
.subscribe(config => {
const eTheme: any = config.variables.electricity;
this.option = {
grid: {
left: 0,
top: 0,
right: 0,
bottom: 80,
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'line',
lineStyle: {
color: eTheme.tooltipLineColor,
width: eTheme.tooltipLineWidth,
},
},
textStyle: {
color: eTheme.tooltipTextColor,
fontSize: 20,
fontWeight: eTheme.tooltipFontWeight,
},
position: 'top',
backgroundColor: eTheme.tooltipBg,
borderColor: eTheme.tooltipBorderColor,
borderWidth: 1,
formatter: '{c0} kWh',
extraCssText: eTheme.tooltipExtraCss,
},
xAxis: {
type: 'category',
boundaryGap: false,
offset: 25,
data: this.data.map(i => i.label),
axisTick: {
show: false,
},
axisLabel: {
color: eTheme.xAxisTextColor,
fontSize: 18,
},
axisLine: {
lineStyle: {
color: eTheme.axisLineColor,
width: '2',
},
},
},
yAxis: {
boundaryGap: [0, '5%'],
axisLine: {
show: false,
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
splitLine: {
show: true,
lineStyle: {
color: eTheme.yAxisSplitLine,
width: '1',
},
},
},
series: [
{
type: 'line',
smooth: true,
symbolSize: 20,
itemStyle: {
normal: {
opacity: 0,
},
emphasis: {
color: '#ffffff',
borderColor: eTheme.itemBorderColor,
borderWidth: 2,
opacity: 1,
},
},
lineStyle: {
normal: {
width: eTheme.lineWidth,
type: eTheme.lineStyle,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.lineGradFrom,
}, {
offset: 1,
color: eTheme.lineGradTo,
}]),
shadowColor: eTheme.lineShadow,
shadowBlur: 6,
shadowOffsetY: 12,
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.areaGradFrom,
}, {
offset: 1,
color: eTheme.areaGradTo,
}]),
},
},
data: this.data.map(i => i.value),
},
{
type: 'line',
smooth: true,
symbol: 'none',
lineStyle: {
normal: {
width: eTheme.lineWidth,
type: eTheme.lineStyle,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.lineGradFrom,
}, {
offset: 1,
color: eTheme.lineGradTo,
}]),
shadowColor: eTheme.shadowLineDarkBg,
shadowBlur: 14,
opacity: 1,
},
},
data: this.data.map(i => i.value),
},
],
};
});
}
onChartInit(echarts) {
this.echartsIntance = echarts;
}
resizeChart() {
if (this.echartsIntance) {
this.echartsIntance.resize();
}
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -1,47 +0,0 @@
<nb-card class="cards-container">
<nb-card size="large" class="table-card">
<nb-card-header>
Electricity Consumption
</nb-card-header>
<nb-tabset fullWidth>
<nb-tab *ngFor="let year of listData" [tabTitle]="year.title" [active]="year.active">
<nb-list>
<nb-list-item *ngFor="let month of year.months">
<span class="month">{{ month.month }}</span>
<span>
<nb-icon
[class.down]="month.down"
[class.up]="!month.down"
[icon]="month.down ? 'arrow-down' : 'arrow-up'" pack="eva">
</nb-icon>
{{ month.delta }}
</span>
<span class="results">
{{ month.kWatts }} <span class="caption">kWh</span> / {{ month.cost }} <span class="caption">USD</span>
</span>
</nb-list-item>
</nb-list>
</nb-tab>
</nb-tabset>
</nb-card>
<nb-card size="large" class="chart-card">
<nb-card-header>
<span class="stats">
<span class="caption">Consumed</span>
<span>816 <span class="caption">kWh</span></span>
</span>
<span class="stats">
<span class="caption">Spent</span>
<span>291 <span class="caption">USD</span></span>
</span>
<nb-select matRipple [(selected)]="type" class="type-select">
<nb-option matRipple *ngFor="let t of types" [value]="t">{{ t }}</nb-option>
</nb-select>
</nb-card-header>
<ngx-electricity-chart [data]="chartData"></ngx-electricity-chart>
</nb-card>
</nb-card>

View file

@ -1,25 +0,0 @@
<nb-card size="medium">
<div class="picture" style.background-image="url('assets/images/kitten-{{currentTheme}}.png')"></div>
<div class="details">
<div class="h4">UI Kitten</div>
<div class="description">
UI Kitten is a framework that contains a set of commonly used UI components styled in a similar way. The most awesome thing: you can change themes on the fly by just passing a different set of variables. 100% native. Give our kitten a try!
</div>
</div>
<nb-card-footer>
<a href="https://hubs.ly/H0n4Z_d0" target="_blank">
<nb-icon icon="globe" pack="eva"></nb-icon>
</a>
<a href="https://itunes.apple.com/us/app/kitten-tricks/id1246143230" target="_blank">
<i class="link-icon ion-social-apple"></i>
</a>
<a href="https://play.google.com/store/apps/details?id=com.akveo.kittenTricks" target="_blank">
<i class="link-icon ion-social-android"></i>
</a>
<a href="https://github.com/akveo/react-native-ui-kitten" target="_blank">
<nb-icon icon="github" pack="eva"></nb-icon>
</a>
</nb-card-footer>
</nb-card>

View file

@ -1,77 +0,0 @@
@import '../../../../@theme/styles/themes';
@include nb-install-component() {
nb-card {
background-color: transparent;
border-width: 0;
box-shadow: none;
margin: 0;
height: 100%;
}
nb-card-header {
border-color: transparent;
}
svg {
width: 100%;
}
.stroke-pattern {
fill: none;
stroke: #bdc4cd;
stroke-miterlimit: 10;
opacity: 0.1;
stroke-width: 1px;
}
.stroked-element {
stroke-width: 4px;
stroke: #bdc4cd;
stroke-miterlimit: 10;
}
.room-border {
stroke-width: 4px;
stroke: #bdc4cd;
stroke-miterlimit: 10;
fill: none;
}
.room-bg {
fill: nb-theme(card-background-color);
stroke: transparent;
cursor: pointer;
stroke-width: 4px;
}
.room-bg-border-grad {
fill: none;
stroke: none;
stroke-width: 4px;
}
.room-text {
cursor: pointer;
user-select: none;
pointer-events: none;
fill: nb-theme(text-hint-color);
}
.selected-room {
z-index: 40;
.room-text {
fill: nb-theme(text-basic-color);
}
.room-border {
stroke: nb-theme(color-primary-default);
}
}
.header {
border-bottom: none;
padding-bottom: 0;
}
}

View file

@ -1,61 +0,0 @@
<nb-card size="giant">
<nb-card-header>
Security Cameras
<button class="single-view-button"
nbButton
size="small"
[appearance]="isSingleView ? 'filled' : 'outline'"
(click)="isSingleView = true">
<i class="nb-square"></i>
</button>
<button class="grid-view-button"
nbButton
size="small"
[appearance]="isSingleView ? 'outline' : 'filled'"
(click)="isSingleView = false">
<nb-icon icon="grid" pack="eva"></nb-icon>
</button>
</nb-card-header>
<div class="grid-container">
<div class="single-view" *ngIf="isSingleView">
<div class="camera single" [style.background-image]="'url(' + selectedCamera.source + ')'">
<span class="camera-name">{{ selectedCamera.title }}</span>
</div>
</div>
<div class="grid-view" *ngIf="!isSingleView">
<div class="camera"
*ngFor="let camera of cameras"
[style.background-image]="'url(' + camera.source + ')'"
(click)="selectCamera(camera)">
<span class="camera-name">{{ camera.title }}</span>
</div>
</div>
</div>
<nb-card-footer>
<nb-actions [size]="actionSize" fullWidth>
<nb-action matRipple>
<nb-icon icon="pause-circle-outline" pack="eva"></nb-icon>
Pause
</nb-action>
<nb-action matRipple>
<nb-icon icon="list-outline" pack="eva"></nb-icon>
Logs
</nb-action>
<nb-action matRipple>
<nb-icon icon="search-outline" pack="eva"></nb-icon>
Search
</nb-action>
<nb-action matRipple>
<nb-icon icon="settings-2-outline" pack="eva"></nb-icon>
Setup
</nb-action>
</nb-actions>
</nb-card-footer>
</nb-card>

View file

@ -1,121 +0,0 @@
@import '../../../@theme/styles/themes';
@import '~@nebular/theme/styles/global/breakpoints';
@import '~bootstrap/scss/mixins/breakpoints';
@include nb-install-component() {
nb-card-header {
display: flex;
align-items: center;
padding-top: 0.625rem;
padding-bottom: 0.625rem;
}
.single-view-button {
.nb-square {
font-size: 1rem;
}
@include nb-ltr {
margin-left: auto;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
@include nb-rtl {
margin-right: auto;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
.grid-view-button {
::ng-deep svg {
vertical-align: top;
}
@include nb-ltr {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
@include nb-rtl {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
.grid-container {
height: 100%;
display: flex;
}
.single-view,
.grid-view {
flex: 1 0 100%;
}
.grid-view {
display: flex;
flex-wrap: wrap;
.camera {
flex: 1 0 50%;
}
}
.single-view .camera {
width: 100%;
height: 100%;
}
.camera {
background-position: center;
background-size: cover;
position: relative;
&:not(.single) {
cursor: pointer;
}
&::before {
background-color: rgba(255, 255, 255, 0.1);
content: '';
position: absolute;
width: 100%;
height: 100%;
opacity: 1;
}
&:hover::before {
opacity: 0;
}
}
.camera-name {
position: absolute;
bottom: 0;
width: 100%;
color: white;
background: nb-theme(overlay-backdrop-background-color);
padding: 0.5rem 1rem;
}
nb-action {
cursor: pointer;
border-radius: 2px;
nb-icon {
@include nb-ltr(margin-right, 0.5rem);
@include nb-rtl(margin-left, 0.5rem);
}
::ng-deep svg {
vertical-align: top;
}
}
@include media-breakpoint-down(xl) {
nb-action {
padding: 0;
}
}
}

View file

@ -1,79 +0,0 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
nb-card {
flex-direction: row;
align-items: center;
height: 6rem;
cursor: pointer;
.icon-container {
height: 100%;
padding: 0.625rem;
}
.icon {
display: flex;
align-items: center;
justify-content: center;
width: 5.75rem;
height: 4.75rem;
font-size: 3.75rem;
border-radius: nb-theme(card-border-radius);
transition: width 0.4s ease;
transform: translate3d(0, 0, 0);
-webkit-transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
color: nb-theme(text-control-color);
@each $status in nb-get-statuses() {
&.status-#{$status} {
$left-color: nb-theme(button-hero-#{$status}-left-background-color);
$right-color: nb-theme(button-hero-#{$status}-right-background-color);
background-image: linear-gradient(to right, $left-color, $right-color);
&:hover {
$left-hover-color: nb-theme(button-hero-#{$status}-hover-left-background-color);
$right-hover-color: nb-theme(button-hero-#{$status}-hover-right-background-color);
background-image: linear-gradient(to right, $left-hover-color, $right-hover-color);
}
}
}
}
&.off {
color: nb-theme(text-hint-color);
.status,
.title,
.icon {
color: nb-theme(text-hint-color);
}
@each $status in nb-get-statuses() {
.icon.status-#{$status} {
box-shadow: none;
background-image: linear-gradient(to right, transparent, transparent);
}
}
}
.details {
display: flex;
flex-direction: column;
justify-content: center;
height: 100%;
@include nb-ltr(padding, 0 0.5rem 0 0.75rem);
@include nb-rtl(padding, 0 0.75rem 0 0.5rem);
border-left: 1px solid transparent;
}
.title {
margin: 0;
}
.status {
text-transform: uppercase;
}
}
}

View file

@ -1,26 +0,0 @@
import { Component, Input } from '@angular/core';
@Component({
selector: 'ngx-status-card',
styleUrls: ['./status-card.component.scss'],
template: `
<nb-card matRipple (click)="on = !on" [ngClass]="{'off': !on}">
<div class="icon-container">
<div class="icon status-{{ type }}">
<ng-content></ng-content>
</div>
</div>
<div class="details">
<div class="title h5">{{ title }}</div>
<div class="status paragraph-2">{{ on ? 'ON' : 'OFF' }}</div>
</div>
</nb-card>
`,
})
export class StatusCardComponent {
@Input() title: string;
@Input() type: string;
@Input() on = true;
}

View file

@ -1,47 +0,0 @@
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsAQMAAABDsxw2AAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAACJJREFUaN7twTEBAAAAwiD7pzbFPmAAAAAAAAAAAAAAAGQOLbQAAU3zwM4AAAAASUVORK5CYII=">
<div class="svg-container">
<svg #svgRoot xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
[attr.viewBox]="styles.viewBox" preserveAspectRatio="xMinYMin meet" (mousedown)="mouseDown($event)">
<defs>
<filter [attr.id]="'blurFilter' + svgControlId" x="0" y="0" width="100%" height="100%">
<feGaussianBlur in="SourceGraphic" [attr.stdDeviation]="styles.blurRadius" />
<feComponentTransfer>
<feFuncA type="discrete" tableValues="1 1"/>
</feComponentTransfer>
</filter>
<clipPath [attr.id]="'sliderClip' + svgControlId">
<path [attr.d]="styles.clipPathStr" stroke="black"></path>
</clipPath>
</defs>
<g [attr.transform]="styles.arcTranslateStr">
<g class="toClip" [attr.clip-path]="getUrlPath('#sliderClip')">
<g class="toFilter" [attr.filter]="getUrlPath('#blurFilter')">
<path [attr.d]="arc.d" [attr.fill]="off ? styles.nonSelectedArc.color : arc.color" *ngFor="let arc of styles.gradArcs"></path>
</g>
<!-- ngFor is a quirk fix for webkit rendering issues -->
<path [attr.d]="styles.nonSelectedArc.d" [attr.fill]="styles.nonSelectedArc.color" *ngFor="let number of [0,1,2,3,4,5]"></path>
</g>
<circle [attr.cx]="styles.thumbPosition.x"
[attr.cy]="styles.thumbPosition.y"
[attr.r]="pinRadius"
[attr.stroke-width]="thumbBorder / scaleFactor"
[attr.fill]="off ? 'none' : thumbBg"
[attr.stroke]="off ? 'none' : thumbBorderColor">
</circle>
</g>
</svg>
</div>
<div class="temperature-bg">
<ng-content></ng-content>
</div>
<button nbButton matRipple appearance="ghost" class="power-bg" [class.on]="!off" (click)="switchPower()">
<nb-icon class="power-icon" icon="power-outline" pack="eva"></nb-icon>
</button>

View file

@ -1,65 +0,0 @@
@import '../../../../@theme/styles/themes';
@include nb-install-component() {
position: relative;
img {
width: 100%;
height: auto;
visibility: hidden;
}
.svg-container {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 2;
}
.temperature-bg {
position: absolute;
width: 88%;
height: 88%;
top: 13%;
left: 6%;
border-radius: 50%;
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border: nb-theme(divider-width) nb-theme(divider-style) nb-theme(divider-color);
}
.power-bg {
position: absolute;
width: 5.25rem;
height: 5.25rem;
background-color: nb-theme(card-background-color) !important;
border-radius: 50%;
bottom: 2%;
left: 50%;
transform: translate(-50%, 50%);
z-index: 2;
cursor: pointer;
border: nb-theme(divider-width) nb-theme(divider-style) nb-theme(divider-color);
&.on {
color: nb-theme(color-primary-default);
}
}
.power-icon {
position: absolute;
top: 50%;
margin-top: -0.625rem;
left: 50%;
margin-left: -0.625rem;
font-size: 3rem;
}
}

View file

@ -1,69 +0,0 @@
<nb-card size="large">
<nb-tabset fullWidth>
<nb-tab tabTitle="Temperature">
<div class="slider-container">
<ngx-temperature-dragger [(value)]="temperature" (power)="temperatureOff = !$event"
[min]="temperatureData.min" [max]="temperatureData.max" [disableArcColor]="theme.arcEmpty"
[fillColors]="theme.arcFill" [thumbBg]="theme.thumbBg" [thumbBorderColor]="theme.thumbBorder">
<div class="slider-value-container" [ngClass]="{ 'off': temperatureOff }">
<div class="value temperature h1">
{{ temperatureOff ? '--' : (temperature | ngxRound) }}
</div>
<div class="desc">
Celsius
</div>
</div>
</ngx-temperature-dragger>
</div>
<nb-radio-group [(ngModel)]="temperatureMode" name="temperature-mode">
<nb-radio matRipple value="cool">
<i class="nb-snowy-circled"></i>
</nb-radio>
<nb-radio matRipple value="warm">
<i class="nb-sunny-circled"></i>
</nb-radio>
<nb-radio matRipple value="heat">
<i class="nb-flame-circled"></i>
</nb-radio>
<nb-radio matRipple value="fan">
<i class="nb-loop-circled"></i>
</nb-radio>
</nb-radio-group>
</nb-tab>
<nb-tab tabTitle="Humidity">
<div class="slider-container">
<ngx-temperature-dragger [(value)]="humidity" (power)="humidityOff = !$event"
[min]="humidityData.min" [max]="humidityData.max" [disableArcColor]="theme.arcEmpty"
[fillColors]="theme.arcFill" [thumbBg]="theme.thumbBg" [thumbBorderColor]="theme.thumbBorder">
<div class="slider-value-container" [ngClass]="{ 'off': humidityOff }">
<div class="value humidity h1">
{{ humidityOff ? '--' : (humidity | ngxRound) }}
</div>
</div>
</ngx-temperature-dragger>
</div>
<nb-radio-group [(ngModel)]="humidityMode" name="humidity-mode">
<nb-radio matRipple value="cool">
<i class="nb-snowy-circled"></i>
</nb-radio>
<nb-radio matRipple value="warm">
<i class="nb-sunny-circled"></i>
</nb-radio>
<nb-radio matRipple value="heat">
<i class="nb-flame-circled"></i>
</nb-radio>
<nb-radio matRipple value="fan">
<i class="nb-loop-circled"></i>
</nb-radio>
</nb-radio-group>
</nb-tab>
</nb-tabset>
</nb-card>

View file

@ -1,174 +0,0 @@
import { delay, takeWhile } from 'rxjs/operators';
import { AfterViewInit, Component, Input, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { LayoutService } from '../../../@core/utils';
@Component({
selector: 'ngx-traffic-chart',
template: `
<div echarts
[options]="option"
class="echart"
(chartInit)="onChartInit($event)">
</div>
`,
})
export class TrafficChartComponent implements AfterViewInit, OnDestroy {
private alive = true;
@Input() points: number[];
type = 'month';
types = ['week', 'month', 'year'];
option: any = {};
echartsIntance: any;
constructor(private theme: NbThemeService,
private layoutService: LayoutService) {
this.layoutService.onSafeChangeLayoutSize()
.pipe(
takeWhile(() => this.alive),
)
.subscribe(() => this.resizeChart());
}
ngAfterViewInit() {
this.theme.getJsTheme()
.pipe(
delay(1),
takeWhile(() => this.alive),
)
.subscribe(config => {
const trafficTheme: any = config.variables.traffic;
this.option = Object.assign({}, {
grid: {
left: 0,
top: 0,
right: 0,
bottom: 0,
},
xAxis: {
type: 'category',
boundaryGap: false,
data: this.points,
},
yAxis: {
boundaryGap: [0, '5%'],
axisLine: {
show: false,
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
splitLine: {
show: true,
lineStyle: {
color: trafficTheme.yAxisSplitLine,
width: '1',
},
},
},
tooltip: {
axisPointer: {
type: 'shadow',
},
textStyle: {
color: trafficTheme.tooltipTextColor,
fontWeight: trafficTheme.tooltipFontWeight,
fontSize: 16,
},
position: 'top',
backgroundColor: trafficTheme.tooltipBg,
borderColor: trafficTheme.tooltipBorderColor,
borderWidth: 1,
formatter: '{c0} MB',
extraCssText: trafficTheme.tooltipExtraCss,
},
series: [
{
type: 'line',
symbol: 'circle',
symbolSize: 8,
sampling: 'average',
silent: true,
itemStyle: {
normal: {
color: trafficTheme.shadowLineDarkBg,
},
emphasis: {
color: 'rgba(0,0,0,0)',
borderColor: 'rgba(0,0,0,0)',
borderWidth: 0,
},
},
lineStyle: {
normal: {
width: 2,
color: trafficTheme.shadowLineDarkBg,
},
},
data: this.points.map(p => p - 15),
},
{
type: 'line',
symbol: 'circle',
symbolSize: 6,
sampling: 'average',
itemStyle: {
normal: {
color: trafficTheme.itemColor,
borderColor: trafficTheme.itemBorderColor,
borderWidth: 2,
},
emphasis: {
color: 'white',
borderColor: trafficTheme.itemEmphasisBorderColor,
borderWidth: 2,
},
},
lineStyle: {
normal: {
width: 2,
color: trafficTheme.lineBg,
shadowColor: trafficTheme.lineBg,
shadowBlur: trafficTheme.lineShadowBlur,
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: trafficTheme.gradFrom,
}, {
offset: 1,
color: trafficTheme.gradTo,
}]),
opacity: 1,
},
},
data: this.points,
},
],
});
});
}
onChartInit(echarts) {
this.echartsIntance = echarts;
}
resizeChart() {
if (this.echartsIntance) {
this.echartsIntance.resize();
}
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -1,51 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { takeWhile } from 'rxjs/operators';
import { TrafficChartData } from '../../../@core/data/traffic-chart';
@Component({
selector: 'ngx-traffic',
styleUrls: ['./traffic.component.scss'],
template: `
<nb-card size="tiny">
<nb-card-header>
<span>Traffic Consumption</span>
<nb-select matRipple [(selected)]="type">
<nb-option matRipple *ngFor="let t of types" [value]="t">{{ t }}</nb-option>
</nb-select>
</nb-card-header>
<ngx-traffic-chart [points]="trafficChartPoints"></ngx-traffic-chart>
</nb-card>
`,
})
export class TrafficComponent implements OnDestroy {
private alive = true;
trafficChartPoints: number[];
type = 'month';
types = ['week', 'month', 'year'];
currentTheme: string;
constructor(private themeService: NbThemeService,
private trafficChartService: TrafficChartData) {
this.themeService.getJsTheme()
.pipe(takeWhile(() => this.alive))
.subscribe(theme => {
this.currentTheme = theme.name;
});
this.trafficChartService.getTrafficChartData()
.pipe(takeWhile(() => this.alive))
.subscribe((data) => {
this.trafficChartPoints = data;
});
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -1,7 +0,0 @@
<ngx-legend-chart [legendItems]="chartLegend"></ngx-legend-chart>
<nb-select matRipple class="period-select" [selected]="type" (selectedChange)="changePeriod($event)">
<nb-option matRipple *ngFor="let period of types" [value]="period">
{{ period }}
</nb-option>
</nb-select>

View file

@ -1,25 +0,0 @@
@import '../../../../@theme/styles/themes';
@import '~bootstrap/scss/mixins/breakpoints';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
padding: 1.5rem 4.5rem;
display: flex;
flex-wrap: wrap;
align-items: center;
margin: -1rem;
ngx-legend-chart,
.period-select {
margin-top: 1rem;
@include nb-ltr(margin-left, 0.5rem);
@include nb-rtl(margin-right, 0.5rem);
}
@include media-breakpoint-up(md) {
.period-select {
@include nb-ltr(margin-left, auto);
@include nb-rtl(margin-right, auto);
}
}
}

View file

@ -1,45 +0,0 @@
@import '../../../@theme/styles/themes';
$legend-all-orders-color: #00977e;
$legend-payment-color: #6935ca;
$legend-canceled-color: #3f4fda;
@include nb-install-component() {
nb-card {
overflow: hidden;
}
nb-tabset {
display: flex;
flex-direction: column;
flex: 1;
::ng-deep ul {
// make same size as card header
border-color: transparent;
padding-bottom: 1px;
.tab-link {
padding: 1.25rem 2rem;
}
}
}
nb-tab {
flex: 1;
padding: 0 0 1.25rem;
}
.chart-container {
flex: 1;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
ngx-profit-chart,
ngx-orders-chart {
padding: 0 1.25rem;
}
}

View file

@ -1,307 +0,0 @@
import { AfterViewInit, Component, Input, OnChanges, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { delay, takeWhile } from 'rxjs/operators';
import { OrdersChart } from '../../../../@core/data/orders-chart';
import { LayoutService } from '../../../../@core/utils/layout.service';
@Component({
selector: 'ngx-orders-chart',
styleUrls: ['./charts-common.component.scss'],
template: `
<div echarts
[options]="option"
class="echart"
(chartInit)="onChartInit($event)">
</div>
`,
})
export class OrdersChartComponent implements AfterViewInit, OnDestroy, OnChanges {
@Input()
ordersChartData: OrdersChart;
private alive = true;
echartsIntance: any;
option: any;
ngOnChanges(): void {
if (this.option) {
this.updateOrdersChartOptions(this.ordersChartData);
}
}
constructor(private theme: NbThemeService,
private layoutService: LayoutService) {
this.layoutService.onSafeChangeLayoutSize()
.pipe(
takeWhile(() => this.alive),
)
.subscribe(() => this.resizeChart());
}
ngAfterViewInit(): void {
this.theme.getJsTheme()
.pipe(
takeWhile(() => this.alive),
delay(1),
)
.subscribe(config => {
const eTheme: any = config.variables.orders;
this.setOptions(eTheme);
this.updateOrdersChartOptions(this.ordersChartData);
});
}
setOptions(eTheme) {
this.option = {
grid: {
left: 40,
top: 20,
right: 0,
bottom: 40,
},
tooltip: {
trigger: 'item',
axisPointer: {
type: 'line',
lineStyle: {
color: eTheme.tooltipLineColor,
width: eTheme.tooltipLineWidth,
},
},
textStyle: {
color: eTheme.tooltipTextColor,
fontSize: eTheme.tooltipFontSize,
fontWeight: eTheme.tooltipFontWeight,
},
position: 'top',
backgroundColor: eTheme.tooltipBg,
borderColor: eTheme.tooltipBorderColor,
borderWidth: 1,
formatter: (params) => {
return Math.round(parseInt(params.value, 10));
},
extraCssText: eTheme.tooltipExtraCss,
},
xAxis: {
type: 'category',
boundaryGap: false,
offset: 5,
data: [],
axisTick: {
show: false,
},
axisLabel: {
color: eTheme.axisTextColor,
fontSize: eTheme.axisFontSize,
},
axisLine: {
lineStyle: {
color: eTheme.axisLineColor,
width: '2',
},
},
},
yAxis: {
type: 'value',
boundaryGap: false,
axisLine: {
lineStyle: {
color: eTheme.axisLineColor,
width: '1',
},
},
axisLabel: {
color: eTheme.axisTextColor,
fontSize: eTheme.axisFontSize,
},
axisTick: {
show: false,
},
splitLine: {
lineStyle: {
color: eTheme.yAxisSplitLine,
width: '1',
},
},
},
series: [
this.getFirstLine(eTheme),
this.getSecondLine(eTheme),
this.getThirdLine(eTheme),
],
};
}
getFirstLine(eTheme) {
return {
type: 'line',
smooth: true,
symbolSize: 20,
itemStyle: {
normal: {
opacity: 0,
},
emphasis: {
opacity: 0,
},
},
lineStyle: {
normal: {
width: 0,
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.firstAreaGradFrom,
}, {
offset: 1,
color: eTheme.firstAreaGradTo,
}]),
opacity: 1,
},
},
data: [],
};
}
getSecondLine(eTheme) {
return {
type: 'line',
smooth: true,
symbolSize: 20,
itemStyle: {
normal: {
opacity: 0,
},
emphasis: {
color: '#ffffff',
borderColor: eTheme.itemBorderColor,
borderWidth: 2,
opacity: 1,
},
},
lineStyle: {
normal: {
width: eTheme.lineWidth,
type: eTheme.lineStyle,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.secondLineGradFrom,
}, {
offset: 1,
color: eTheme.secondLineGradTo,
}]),
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.secondAreaGradFrom,
}, {
offset: 1,
color: eTheme.secondAreaGradTo,
}]),
},
},
data: [],
};
}
getThirdLine(eTheme) {
return {
type: 'line',
smooth: true,
symbolSize: 20,
itemStyle: {
normal: {
opacity: 0,
},
emphasis: {
color: '#ffffff',
borderColor: eTheme.itemBorderColor,
borderWidth: 2,
opacity: 1,
},
},
lineStyle: {
normal: {
width: eTheme.lineWidth,
type: eTheme.lineStyle,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.thirdLineGradFrom,
}, {
offset: 1,
color: eTheme.thirdLineGradTo,
}]),
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.thirdAreaGradFrom,
}, {
offset: 1,
color: eTheme.thirdAreaGradTo,
}]),
},
},
data: [],
};
}
updateOrdersChartOptions(ordersChartData: OrdersChart) {
const options = this.option;
const series = this.getNewSeries(options.series, ordersChartData.linesData);
const xAxis = this.getNewXAxis(options.xAxis, ordersChartData.chartLabel);
this.option = {
...options,
xAxis,
series,
};
}
getNewSeries(series, linesData: number[][]) {
return series.map((line, index) => {
return {
...line,
data: linesData[index],
};
});
}
getNewXAxis(xAxis, chartLabel: string[]) {
return {
...xAxis,
data: chartLabel,
};
}
onChartInit(echarts) {
this.echartsIntance = echarts;
}
resizeChart() {
if (this.echartsIntance) {
// Fix recalculation chart size
// TODO: investigate more deeply
setTimeout(() => {
this.echartsIntance.resize();
}, 0);
}
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -1,200 +0,0 @@
import { AfterViewInit, Component, Input, OnChanges, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { takeWhile } from 'rxjs/operators';
import { ProfitChart } from '../../../../@core/data/profit-chart';
import { LayoutService } from '../../../../@core/utils/layout.service';
@Component({
selector: 'ngx-profit-chart',
styleUrls: ['./charts-common.component.scss'],
template: `
<div echarts [options]="options" class="echart" (chartInit)="onChartInit($event)"></div>
`,
})
export class ProfitChartComponent implements AfterViewInit, OnDestroy, OnChanges {
@Input()
profitChartData: ProfitChart;
private alive = true;
echartsIntance: any;
options: any = {};
constructor(private theme: NbThemeService,
private layoutService: LayoutService) {
this.layoutService.onSafeChangeLayoutSize()
.pipe(
takeWhile(() => this.alive),
)
.subscribe(() => this.resizeChart());
}
ngOnChanges(): void {
if (this.echartsIntance) {
this.updateProfitChartOptions(this.profitChartData);
}
}
ngAfterViewInit() {
this.theme.getJsTheme()
.pipe(takeWhile(() => this.alive))
.subscribe(config => {
const eTheme: any = config.variables.profit;
this.setOptions(eTheme);
});
}
setOptions(eTheme) {
this.options = {
backgroundColor: eTheme.bg,
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
shadowStyle: {
color: 'rgba(0, 0, 0, 0.3)',
},
},
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
xAxis: [
{
type: 'category',
data: this.profitChartData.chartLabel,
axisTick: {
alignWithLabel: true,
},
axisLine: {
lineStyle: {
color: eTheme.axisLineColor,
},
},
axisLabel: {
color: eTheme.axisTextColor,
fontSize: eTheme.axisFontSize,
},
},
],
yAxis: [
{
type: 'value',
axisLine: {
lineStyle: {
color: eTheme.axisLineColor,
},
},
splitLine: {
lineStyle: {
color: eTheme.splitLineColor,
},
},
axisLabel: {
color: eTheme.axisTextColor,
fontSize: eTheme.axisFontSize,
},
},
],
series: [
{
name: 'Canceled',
type: 'bar',
barGap: 0,
barWidth: '20%',
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.firstLineGradFrom,
}, {
offset: 1,
color: eTheme.firstLineGradTo,
}]),
},
},
data: this.profitChartData.data[0],
},
{
name: 'Payment',
type: 'bar',
barWidth: '20%',
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.secondLineGradFrom,
}, {
offset: 1,
color: eTheme.secondLineGradTo,
}]),
},
},
data: this.profitChartData.data[1],
},
{
name: 'All orders',
type: 'bar',
barWidth: '20%',
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.thirdLineGradFrom,
}, {
offset: 1,
color: eTheme.thirdLineGradTo,
}]),
},
},
data: this.profitChartData.data[2],
},
],
};
}
updateProfitChartOptions(profitChartData: ProfitChart) {
const options = this.options;
const series = this.getNewSeries(options.series, profitChartData.data);
this.echartsIntance.setOption({
series: series,
xAxis: {
data: this.profitChartData.chartLabel,
},
});
}
getNewSeries(series, data: number[][]) {
return series.map((line, index) => {
return {
...line,
data: data[index],
};
});
}
onChartInit(echarts) {
this.echartsIntance = echarts;
}
resizeChart() {
if (this.echartsIntance) {
// Fix recalculation chart size
// TODO: investigate more deeply
setTimeout(() => {
this.echartsIntance.resize();
}, 0);
}
}
ngOnDestroy(): void {
this.alive = false;
}
}

View file

@ -1,181 +0,0 @@
import { AfterViewInit, Component, Input, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { takeWhile } from 'rxjs/operators';
import { LayoutService } from '../../../../@core/utils/layout.service';
@Component({
selector: 'ngx-country-orders-chart',
styleUrls: ['./country-orders-chart.component.scss'],
template: `
<div class="header">
<span class="caption">Selected Country/Region</span>
<h2 class="h4">{{ countryName }}</h2>
</div>
<div echarts
[options]="option"
class="echart"
(chartInit)="onChartInit($event)">
</div>
`,
})
export class CountryOrdersChartComponent implements AfterViewInit, OnDestroy, OnChanges {
@Input() countryName: string;
@Input() data: number[];
@Input() maxValue: number;
@Input() labels: string[];
private alive = true;
option: any = {};
echartsInstance;
constructor(private theme: NbThemeService,
private layoutService: LayoutService) {
this.layoutService.onSafeChangeLayoutSize()
.pipe(
takeWhile(() => this.alive),
)
.subscribe(() => this.resizeChart());
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.data && !changes.data.isFirstChange()) {
this.echartsInstance.setOption({
series: [
{
data: this.data.map(v => this.maxValue),
},
{
data: this.data,
},
{
data: this.data,
},
],
});
}
}
ngAfterViewInit() {
this.theme.getJsTheme()
.pipe(takeWhile(() => this.alive))
.subscribe(config => {
const countriesTheme: any = config.variables.countryOrders;
this.option = Object.assign({}, {
grid: {
left: '3%',
right: '3%',
bottom: '3%',
top: '3%',
containLabel: true,
},
xAxis: {
axisLabel: {
color: countriesTheme.chartAxisTextColor,
fontSize: countriesTheme.chartAxisFontSize,
},
axisLine: {
lineStyle: {
color: countriesTheme.chartAxisLineColor,
width: '2',
},
},
axisTick: {
show: false,
},
splitLine: {
lineStyle: {
color: countriesTheme.chartAxisSplitLine,
width: '1',
},
},
},
yAxis: {
data: this.labels,
axisLabel: {
color: countriesTheme.chartAxisTextColor,
fontSize: countriesTheme.chartAxisFontSize,
},
axisLine: {
lineStyle: {
color: countriesTheme.chartAxisLineColor,
width: '2',
},
},
axisTick: {
show: false,
},
},
series: [
{ // For shadow
type: 'bar',
data: this.data.map(v => this.maxValue),
cursor: 'default',
itemStyle: {
normal: {
color: countriesTheme.chartInnerLineColor,
},
opacity: 1,
},
barWidth: '40%',
barGap: '-100%',
barCategoryGap: '30%',
animation: false,
z: 1,
},
{ // For bottom line
type: 'bar',
data: this.data,
cursor: 'default',
itemStyle: {
normal: {
color: countriesTheme.chartLineBottomShadowColor,
},
opacity: 1,
},
barWidth: '40%',
barGap: '-100%',
barCategoryGap: '30%',
z: 2,
},
{
type: 'bar',
barWidth: '35%',
data: this.data,
cursor: 'default',
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [{
offset: 0,
color: countriesTheme.chartGradientFrom,
}, {
offset: 1,
color: countriesTheme.chartGradientTo,
}]),
},
},
z: 3,
},
],
});
});
}
onChartInit(ec) {
this.echartsInstance = ec;
}
resizeChart() {
if (this.echartsInstance) {
this.echartsInstance.resize();
}
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -1,67 +0,0 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { NbMediaBreakpoint, NbMediaBreakpointsService, NbThemeService } from '@nebular/theme';
import { takeWhile } from 'rxjs/operators';
import { CountryOrderData } from '../../../@core/data/country-order';
@Component({
selector: 'ngx-country-orders',
styleUrls: ['./country-orders.component.scss'],
template: `
<nb-card [size]="breakpoint.width >= breakpoints.md ? 'medium' : 'giant'">
<nb-card-header>Country Orders Statistics</nb-card-header>
<nb-card-body>
<ngx-country-orders-map (select)="selectCountryById($event)"
countryId="USA">
</ngx-country-orders-map>
<ngx-country-orders-chart [countryName]="countryName"
[data]="countryData"
[labels]="countriesCategories"
maxValue="20">
</ngx-country-orders-chart>
</nb-card-body>
</nb-card>
`,
})
export class CountryOrdersComponent implements OnInit, OnDestroy {
private alive = true;
countryName = '';
countryData: number[] = [];
countriesCategories: string[];
breakpoint: NbMediaBreakpoint = { name: '', width: 0 };
breakpoints: any;
constructor(private themeService: NbThemeService,
private breakpointService: NbMediaBreakpointsService,
private countryOrderService: CountryOrderData) {
this.breakpoints = this.breakpointService.getBreakpointsMap();
}
ngOnInit() {
this.themeService.onMediaQueryChange()
.pipe(takeWhile(() => this.alive))
.subscribe(([oldValue, newValue]) => {
this.breakpoint = newValue;
});
this.countryOrderService.getCountriesCategories()
.pipe(takeWhile(() => this.alive))
.subscribe((countriesCategories) => {
this.countriesCategories = countriesCategories;
});
}
selectCountryById(countryName: string) {
this.countryName = countryName;
this.countryOrderService.getCountriesCategoriesData(countryName)
.pipe(takeWhile(() => this.alive))
.subscribe((countryData) => {
this.countryData = countryData;
});
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -1,23 +0,0 @@
<nb-card-header>
<nb-select matRipple [selected]="selectedCurrency" (selectedChange)="changeCurrency($event)">
<nb-option matRipple *ngFor="let currency of currencies" [value]="currency">{{ currency }}</nb-option>
</nb-select>
</nb-card-header>
<nb-card-body>
<div class="chart-info">
<div>Daily Income</div>
<div class="h6">{{ earningLiveUpdateCardData.dailyIncome | ngxNumberWithCommas }}</div>
<div class="delta"
[class.up]="earningLiveUpdateCardData.delta.up"
[class.down]="!earningLiveUpdateCardData.delta.up">
<nb-icon [icon]="earningLiveUpdateCardData.delta.up ? 'arrow-up' : 'arrow-down'"
pack="eva"
class="direction">
</nb-icon>
{{ earningLiveUpdateCardData.delta.value }}%
</div>
</div>
<ngx-earning-live-update-chart
[liveUpdateChartData]="liveUpdateChartData">
</ngx-earning-live-update-chart>
</nb-card-body>

View file

@ -1,164 +0,0 @@
import { delay, takeWhile } from 'rxjs/operators';
import { AfterViewInit, Component, Input, OnChanges, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { LayoutService } from '../../../../@core/utils/layout.service';
@Component({
selector: 'ngx-earning-live-update-chart',
styleUrls: ['earning-card-front.component.scss'],
template: `
<div echarts
class="echart"
[options]="option"
(chartInit)="onChartInit($event)"></div>
`,
})
export class EarningLiveUpdateChartComponent implements AfterViewInit, OnDestroy, OnChanges {
private alive = true;
@Input() liveUpdateChartData: { value: [string, number] }[];
option: any;
echartsInstance;
constructor(private theme: NbThemeService,
private layoutService: LayoutService) {
this.layoutService.onSafeChangeLayoutSize()
.pipe(
takeWhile(() => this.alive),
)
.subscribe(() => this.resizeChart());
}
ngOnChanges(): void {
if (this.option) {
this.updateChartOptions(this.liveUpdateChartData);
}
}
ngAfterViewInit() {
this.theme.getJsTheme()
.pipe(
delay(1),
takeWhile(() => this.alive),
)
.subscribe(config => {
const earningLineTheme: any = config.variables.earningLine;
this.setChartOption(earningLineTheme);
});
}
setChartOption(earningLineTheme) {
this.option = {
grid: {
left: 0,
top: 0,
right: 0,
bottom: 0,
},
xAxis: {
type: 'time',
axisLine: {
show: false,
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
splitLine: {
show: false,
},
},
yAxis: {
boundaryGap: [0, '5%'],
axisLine: {
show: false,
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
splitLine: {
show: false,
},
},
tooltip: {
axisPointer: {
type: 'shadow',
},
textStyle: {
color: earningLineTheme.tooltipTextColor,
fontWeight: earningLineTheme.tooltipFontWeight,
fontSize: earningLineTheme.tooltipFontSize,
},
position: 'top',
backgroundColor: earningLineTheme.tooltipBg,
borderColor: earningLineTheme.tooltipBorderColor,
borderWidth: earningLineTheme.tooltipBorderWidth,
formatter: params => `$ ${Math.round(parseInt(params.value[1], 10))}`,
extraCssText: earningLineTheme.tooltipExtraCss,
},
series: [
{
type: 'line',
symbol: 'circle',
sampling: 'average',
itemStyle: {
normal: {
opacity: 0,
},
emphasis: {
opacity: 0,
},
},
lineStyle: {
normal: {
width: 0,
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: earningLineTheme.gradFrom,
}, {
offset: 1,
color: earningLineTheme.gradTo,
}]),
opacity: 1,
},
},
data: this.liveUpdateChartData,
},
],
animation: true,
};
}
updateChartOptions(chartData: { value: [string, number] }[]) {
this.echartsInstance.setOption({
series: [{
data: chartData,
}],
});
}
onChartInit(ec) {
this.echartsInstance = ec;
}
resizeChart() {
if (this.echartsInstance) {
this.echartsInstance.resize();
}
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -1,172 +0,0 @@
import { delay, takeWhile } from 'rxjs/operators';
import { AfterViewInit, Component, Input, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { LayoutService } from '../../../../@core/utils';
@Component({
selector: 'ngx-stats-ares-chart',
styleUrls: ['stats-card-back.component.scss'],
template: `
<div echarts [options]="option"
class="echart"
(chartInit)="onChartInit($event)">
</div>
`,
})
export class StatsAreaChartComponent implements AfterViewInit, OnDestroy {
private alive = true;
@Input() points: number[];
echartsIntance: any;
option: any = {};
constructor(private theme: NbThemeService,
private layoutService: LayoutService) {
this.layoutService.onSafeChangeLayoutSize()
.pipe(
takeWhile(() => this.alive),
)
.subscribe(() => this.resizeChart());
}
ngAfterViewInit() {
this.theme.getJsTheme()
.pipe(
delay(1),
takeWhile(() => this.alive),
)
.subscribe(config => {
const trafficTheme: any = config.variables.traffic;
this.option = Object.assign({}, {
grid: {
left: 0,
top: 0,
right: 0,
bottom: 0,
},
xAxis: {
type: 'category',
boundaryGap: false,
data: this.points,
},
yAxis: {
boundaryGap: [0, '5%'],
axisLine: {
show: false,
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
splitLine: {
show: true,
lineStyle: {
color: trafficTheme.yAxisSplitLine,
width: '1',
},
},
},
tooltip: {
axisPointer: {
type: 'shadow',
},
textStyle: {
color: trafficTheme.tooltipTextColor,
fontWeight: trafficTheme.tooltipFontWeight,
fontSize: 16,
},
position: 'top',
backgroundColor: trafficTheme.tooltipBg,
borderColor: trafficTheme.tooltipBorderColor,
borderWidth: 1,
formatter: '$ {c0}',
extraCssText: trafficTheme.tooltipExtraCss,
},
series: [
{
type: 'line',
symbol: 'circle',
symbolSize: 8,
sampling: 'average',
silent: true,
itemStyle: {
normal: {
color: trafficTheme.shadowLineDarkBg,
},
emphasis: {
color: 'rgba(0,0,0,0)',
borderColor: 'rgba(0,0,0,0)',
borderWidth: 0,
},
},
lineStyle: {
normal: {
width: 2,
color: trafficTheme.shadowLineDarkBg,
},
},
data: this.points.map(p => p - 15),
},
{
type: 'line',
symbol: 'circle',
symbolSize: 6,
sampling: 'average',
itemStyle: {
normal: {
color: trafficTheme.itemColor,
borderColor: trafficTheme.itemBorderColor,
borderWidth: 2,
},
emphasis: {
color: 'white',
borderColor: trafficTheme.itemEmphasisBorderColor,
borderWidth: 2,
},
},
lineStyle: {
normal: {
width: 2,
color: trafficTheme.lineBg,
shadowColor: trafficTheme.lineBg,
shadowBlur: trafficTheme.lineShadowBlur,
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: trafficTheme.gradFrom,
}, {
offset: 1,
color: trafficTheme.gradTo,
}]),
opacity: 1,
},
},
data: this.points,
},
],
});
});
}
onChartInit(echarts) {
this.echartsIntance = echarts;
}
resizeChart() {
if (this.echartsIntance) {
this.echartsIntance.resize();
}
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -1,153 +0,0 @@
import { AfterViewInit, Component, Input, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { takeWhile } from 'rxjs/operators';
import { LayoutService } from '../../../../@core/utils/layout.service';
@Component({
selector: 'ngx-stats-bar-animation-chart',
template: `
<div echarts
[options]="options"
class="echart"
(chartInit)="onChartInit($event)">
</div>
`,
})
export class StatsBarAnimationChartComponent implements AfterViewInit, OnDestroy {
private alive = true;
@Input() linesData: { firstLine: number[]; secondLine: number[] } = {
firstLine: [],
secondLine: [],
};
echartsIntance: any;
options: any = {};
constructor(private theme: NbThemeService,
private layoutService: LayoutService) {
this.layoutService.onSafeChangeLayoutSize()
.pipe(
takeWhile(() => this.alive),
)
.subscribe(() => this.resizeChart());
}
ngAfterViewInit() {
this.theme.getJsTheme()
.pipe(takeWhile(() => this.alive))
.subscribe(config => {
const profitBarAnimationEchart: any = config.variables.profitBarAnimationEchart;
this.setChartOption(profitBarAnimationEchart);
});
}
setChartOption(chartVariables) {
this.options = {
color: [
chartVariables.firstAnimationBarColor,
chartVariables.secondAnimationBarColor,
],
grid: {
left: 0,
top: 0,
right: 0,
bottom: 0,
},
legend: {
data: ['transactions', 'orders'],
borderWidth: 0,
borderRadius: 0,
itemWidth: 15,
itemHeight: 15,
textStyle: {
color: chartVariables.textColor,
},
},
tooltip: {
axisPointer: {
type: 'shadow',
},
textStyle: {
color: chartVariables.tooltipTextColor,
fontWeight: chartVariables.tooltipFontWeight,
fontSize: chartVariables.tooltipFontSize,
},
position: 'top',
backgroundColor: chartVariables.tooltipBg,
borderColor: chartVariables.tooltipBorderColor,
borderWidth: chartVariables.tooltipBorderWidth,
formatter: params => `$ ${Math.round(parseInt(params.value, 10))}`,
extraCssText: chartVariables.tooltipExtraCss,
},
xAxis: [
{
data: this.linesData.firstLine.map((_, index) => index),
silent: false,
axisLine: {
show: false,
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
},
],
yAxis: [
{
axisLine: {
show: false,
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
splitLine: {
show: true,
lineStyle: {
color: chartVariables.splitLineStyleColor,
opacity: chartVariables.splitLineStyleOpacity,
width: chartVariables.splitLineStyleWidth,
},
},
},
],
series: [
{
name: 'transactions',
type: 'bar',
data: this.linesData.firstLine,
animationDelay: idx => idx * 10,
},
{
name: 'orders',
type: 'bar',
data: this.linesData.secondLine,
animationDelay: idx => idx * 10 + 100,
},
],
animationEasing: 'elasticOut',
animationDelayUpdate: idx => idx * 5,
};
}
onChartInit(echarts) {
this.echartsIntance = echarts;
}
resizeChart() {
if (this.echartsIntance) {
this.echartsIntance.resize();
}
}
ngOnDestroy(): void {
this.alive = false;
}
}

View file

@ -1,32 +0,0 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
.flip-icon {
position: absolute;
right: 0.625rem;
top: 1rem;
@include nb-rtl(right, auto);
@include nb-rtl(left, 0.625rem);
cursor: pointer;
}
::ng-deep {
.front-container {
max-width: 100%;
}
.flipped {
.back-container {
.flip-icon {
transform: scaleX(-1);
}
}
.front-container {
.flip-icon {
display: none;
}
}
}
}
}

View file

@ -1,5 +0,0 @@
<ngx-traffic-bar-chart
[data]="trafficBarData.data"
[labels]="trafficBarData.labels"
[formatter]="trafficBarData.formatter"
></ngx-traffic-bar-chart>

View file

@ -1,19 +0,0 @@
@import '../../../../@theme/styles/themes';
@include nb-install-component() {
ngx-traffic-bar-chart {
position: relative;
::ng-deep {
canvas {
border-bottom-left-radius: nb-theme(card-border-radius);
border-bottom-right-radius: nb-theme(card-border-radius);
}
.echart {
height: 100%;
width: 100%;
}
}
}
}

View file

@ -1,150 +0,0 @@
import { AfterViewInit, Component, Input, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { takeWhile } from 'rxjs/operators';
import { LayoutService } from '../../../../@core/utils/layout.service';
declare const echarts: any;
@Component({
selector: 'ngx-traffic-bar-chart',
template: `
<div echarts
[options]="option"
class="echart"
(chartInit)="onChartInit($event)">
</div>
`,
})
export class TrafficBarChartComponent implements AfterViewInit, OnDestroy, OnChanges {
@Input() data: number[];
@Input() labels: string[];
@Input() formatter: string;
private alive = true;
option: any = {};
echartsInstance: any;
constructor(private theme: NbThemeService,
private layoutService: LayoutService) {
this.layoutService.onSafeChangeLayoutSize()
.pipe(
takeWhile(() => this.alive),
)
.subscribe(() => this.resizeChart());
}
onChartInit(ec) {
this.echartsInstance = ec;
}
resizeChart() {
if (this.echartsInstance) {
this.echartsInstance.resize();
}
}
ngOnChanges(changes: SimpleChanges): void {
if (!changes.data.isFirstChange() && !changes.labels.isFirstChange()) {
this.echartsInstance.setOption({
series: [{
data: this.data,
}],
xAxis: {
data: this.labels,
},
tooltip: {
formatter: this.formatter,
},
});
}
}
ngAfterViewInit() {
this.theme.getJsTheme()
.pipe(takeWhile(() => this.alive))
.subscribe(config => {
const trafficTheme: any = config.variables.trafficBarEchart;
this.option = Object.assign({}, {
grid: {
left: 0,
top: 0,
right: 0,
bottom: 0,
containLabel: true,
},
xAxis: {
type : 'category',
data : this.labels,
axisLabel: {
color: trafficTheme.axisTextColor,
fontSize: trafficTheme.axisFontSize,
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
},
yAxis: {
show: false,
axisLine: {
show: false,
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
boundaryGap: [0, '5%'],
},
tooltip: {
axisPointer: {
type: 'shadow',
},
textStyle: {
color: trafficTheme.tooltipTextColor,
fontWeight: trafficTheme.tooltipFontWeight,
fontSize: 16,
},
position: 'top',
backgroundColor: trafficTheme.tooltipBg,
borderColor: trafficTheme.tooltipBorderColor,
borderWidth: 1,
formatter: this.formatter,
extraCssText: trafficTheme.tooltipExtraCss,
},
series: [
{
type: 'bar',
barWidth: '40%',
data: this.data,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: trafficTheme.gradientFrom,
}, {
offset: 1,
color: trafficTheme.gradientTo,
}]),
opacity: 1,
shadowColor: trafficTheme.gradientFrom,
shadowBlur: trafficTheme.shadowBlur,
},
},
},
],
});
});
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -1,44 +0,0 @@
@import '~bootstrap/scss/mixins/breakpoints';
@import '~@nebular/theme/styles/global/breakpoints';
@import '../../../../@theme/styles/themes';
@include nb-install-component() {
overflow: hidden;
nb-list {
height: 100%;
}
.item {
display: flex;
justify-content: space-between;
align-items: center;
> * {
flex: 1;
}
&:first-child {
border-top: none;
}
}
.delta {
display: flex;
align-items: center;
&.down {
color: nb-theme(color-danger-default);
}
&.up {
color: nb-theme(color-success-default);
}
}
@include media-breakpoint-down(is) {
ngx-traffic-bar {
display: none;
}
}
}

View file

@ -1,4 +0,0 @@
<span>Traffic</span>
<nb-select matRipple [selected]="type" (selectedChange)="changePeriod($event)">
<nb-option matRipple *ngFor="let period of types" [value]="period">{{ period }}</nb-option>
</nb-select>

View file

@ -1,5 +0,0 @@
:host {
display: flex;
align-items: center;
justify-content: space-between;
}

View file

@ -1,24 +0,0 @@
<nb-reveal-card [showToggleButton]="false" [revealed]="revealed">
<nb-card-front>
<nb-card size="small">
<nb-card-header>
<ngx-traffic-cards-header [type]="period" (periodChange)="setPeriodAngGetData($event)">
</ngx-traffic-cards-header>
</nb-card-header>
<ngx-traffic-front-card [frontCardData]="trafficListData"></ngx-traffic-front-card>
<nb-icon class="toggle-icon" icon="chevron-up-outline" pack="eva" (click)="toggleView()"></nb-icon>
</nb-card>
</nb-card-front>
<nb-card-back>
<nb-card size="small">
<nb-card-header>
<ngx-traffic-cards-header [type]="period" (periodChange)="setPeriodAngGetData($event)">
</ngx-traffic-cards-header>
</nb-card-header>
<nb-card-body>
<ngx-traffic-back-card [trafficBarData]="trafficBarData"></ngx-traffic-back-card>
</nb-card-body>
<nb-icon class="toggle-icon" icon="chevron-down-outline" pack="eva" (click)="toggleView()"></nb-icon>
</nb-card>
</nb-card-back>
</nb-reveal-card>

View file

@ -1,19 +0,0 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
.toggle-icon {
position: absolute;
top: 1rem;
right: 1.25rem;
@include nb-rtl(right, auto);
@include nb-rtl(left, 1.25rem);
cursor: pointer;
}
nb-card-header {
padding-top: nb-theme(card-header-with-select-padding-top);
padding-bottom: nb-theme(card-header-with-select-padding-bottom);
@include nb-ltr(padding-right, 4rem);
@include nb-rtl(padding-left, 4rem);
}
}

View file

@ -1,33 +0,0 @@
<nb-card size="medium">
<nb-card-header>
<span>User Activity</span>
<nb-select matRipple [selected]="type" (selectedChange)="getUserActivity($event); type = $event">
<nb-option matRipple *ngFor="let t of types" [value]="t">{{ t }}</nb-option>
</nb-select>
</nb-card-header>
<nb-list class="user-activity-list">
<nb-list-item *ngFor="let item of userActivity">
<div class="visited-date">
{{ item.date }}
</div>
<div class="visited-pages-count">
<div class="caption">Pages Visit</div>
<div class="value">{{ item.pagesVisitCount }}</div>
</div>
<div class="visited-percentages">
<div class="caption">New visits, %</div>
<div class="delta value" [class.up]="item.deltaUp" [class.down]="!item.deltaUp">
<nb-icon [icon]="item.deltaUp ? 'arrow-up' : 'arrow-down'" pack="eva"></nb-icon>
{{ item.newVisits }}%
</div>
</div>
</nb-list-item>
</nb-list>
</nb-card>

View file

@ -1,234 +0,0 @@
import { delay, takeWhile } from 'rxjs/operators';
import { AfterViewInit, Component, Input, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { LayoutService } from '../../../../@core/utils';
import { OutlineData } from '../../../../@core/data/visitors-analytics';
@Component({
selector: 'ngx-visitors-analytics-chart',
styleUrls: ['./visitors-analytics-chart.component.scss'],
template: `
<div echarts
[options]="option"
class="echart"
(chartInit)="onChartInit($event)">
</div>
`,
})
export class ECommerceVisitorsAnalyticsChartComponent implements AfterViewInit, OnDestroy {
private alive = true;
@Input() chartData: {
innerLine: number[];
outerLine: OutlineData[];
};
option: any;
themeSubscription: any;
echartsIntance: any;
constructor(private theme: NbThemeService,
private layoutService: LayoutService) {
this.layoutService.onSafeChangeLayoutSize()
.pipe(
takeWhile(() => this.alive),
)
.subscribe(() => this.resizeChart());
}
ngAfterViewInit(): void {
this.theme.getJsTheme()
.pipe(
delay(1),
takeWhile(() => this.alive),
)
.subscribe(config => {
const eTheme: any = config.variables.visitors;
this.setOptions(eTheme);
});
}
setOptions(eTheme) {
this.option = {
grid: {
left: 40,
top: 20,
right: 0,
bottom: 60,
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'line',
lineStyle: {
color: eTheme.tooltipLineColor,
width: eTheme.tooltipLineWidth,
},
},
textStyle: {
color: eTheme.tooltipTextColor,
fontSize: 20,
fontWeight: eTheme.tooltipFontWeight,
},
position: 'top',
backgroundColor: eTheme.tooltipBg,
borderColor: eTheme.tooltipBorderColor,
borderWidth: 1,
formatter: (params) => {
return Math.round(parseInt(params[0].value, 10));
},
extraCssText: eTheme.tooltipExtraCss,
},
xAxis: {
type: 'category',
boundaryGap: false,
offset: 25,
data: this.chartData.outerLine.map(i => i.label),
axisTick: {
show: false,
},
axisLabel: {
color: eTheme.axisTextColor,
fontSize: eTheme.axisFontSize,
},
axisLine: {
lineStyle: {
color: eTheme.axisLineColor,
width: '2',
},
},
},
yAxis: {
type: 'value',
boundaryGap: false,
axisLine: {
lineStyle: {
color: eTheme.axisLineColor,
width: '1',
},
},
axisLabel: {
color: eTheme.axisTextColor,
fontSize: eTheme.axisFontSize,
},
axisTick: {
show: false,
},
splitLine: {
lineStyle: {
color: eTheme.yAxisSplitLine,
width: '1',
},
},
},
series: [
this.getInnerLine(eTheme),
this.getOuterLine(eTheme),
],
};
}
getOuterLine(eTheme) {
return {
type: 'line',
smooth: true,
symbolSize: 20,
itemStyle: {
normal: {
opacity: 0,
},
emphasis: {
color: '#ffffff',
borderColor: eTheme.itemBorderColor,
borderWidth: 2,
opacity: 1,
},
},
lineStyle: {
normal: {
width: eTheme.lineWidth,
type: eTheme.lineStyle,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.lineGradFrom,
}, {
offset: 1,
color: eTheme.lineGradTo,
}]),
shadowColor: eTheme.lineShadow,
shadowBlur: 6,
shadowOffsetY: 12,
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.areaGradFrom,
}, {
offset: 1,
color: eTheme.areaGradTo,
}]),
},
},
data: this.chartData.outerLine.map(i => i.value),
};
}
getInnerLine(eTheme) {
return {
type: 'line',
smooth: true,
symbolSize: 20,
tooltip: {
show: false,
extraCssText: '',
},
itemStyle: {
normal: {
opacity: 0,
},
emphasis: {
opacity: 0,
},
},
lineStyle: {
normal: {
width: eTheme.innerLineWidth,
type: eTheme.innerLineStyle,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1),
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.innerAreaGradFrom,
}, {
offset: 1,
color: eTheme.innerAreaGradTo,
}]),
opacity: 1,
},
},
data: this.chartData.innerLine,
};
}
onChartInit(echarts) {
this.echartsIntance = echarts;
}
resizeChart() {
if (this.echartsIntance) {
this.echartsIntance.resize();
}
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -1,49 +0,0 @@
@import '../../../@theme/styles/themes';
@import '~bootstrap/scss/mixins/breakpoints';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
position: relative;
display: block;
nb-card {
position: relative;
overflow: hidden;
}
nb-card-header {
border-bottom: none;
}
.subtitle {
color: nb-theme(text-hint-color);
}
.container {
display: flex;
flex-direction: row;
}
.chart-container {
flex: 1;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
position: relative;
}
.chart-header {
display: flex;
justify-content: space-between;
margin-bottom: 2.125rem;
}
@include media-breakpoint-down(is) {
ngx-legend-chart {
::ng-deep .legends {
padding-left: 0;
}
}
}
}

View file

@ -1,215 +0,0 @@
import { AfterViewInit, Component, Input, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { delay, takeWhile } from 'rxjs/operators';
import { LayoutService } from '../../../../@core/utils/layout.service';
@Component({
selector: 'ngx-visitors-statistics',
styleUrls: ['./visitors-statistics.component.scss'],
templateUrl: './visitors-statistics.component.html',
})
export class ECommerceVisitorsStatisticsComponent implements AfterViewInit, OnDestroy {
private alive = true;
@Input() value: number;
option: any = {};
chartLegend: { iconColor: string; title: string }[];
echartsIntance: any;
constructor(private theme: NbThemeService,
private layoutService: LayoutService) {
this.layoutService.onSafeChangeLayoutSize()
.pipe(
takeWhile(() => this.alive),
)
.subscribe(() => this.resizeChart());
}
ngAfterViewInit() {
this.theme.getJsTheme()
.pipe(
takeWhile(() => this.alive),
delay(1),
)
.subscribe(config => {
const variables: any = config.variables;
const visitorsPieLegend: any = config.variables.visitorsPieLegend;
this.setOptions(variables);
this.setLegendItems(visitorsPieLegend);
});
}
setLegendItems(visitorsPieLegend) {
this.chartLegend = [
{
iconColor: visitorsPieLegend.firstSection,
title: 'New Visitors',
},
{
iconColor: visitorsPieLegend.secondSection,
title: 'Return Visitors',
},
];
}
setOptions(variables) {
const visitorsPie: any = variables.visitorsPie;
this.option = {
tooltip: {
trigger: 'item',
formatter: '',
},
series: [
{
name: ' ',
clockWise: true,
hoverAnimation: false,
type: 'pie',
center: ['50%', '50%'],
radius: visitorsPie.firstPieRadius,
data: [
{
value: this.value,
name: ' ',
label: {
normal: {
position: 'center',
formatter: '',
textStyle: {
fontSize: '22',
fontFamily: variables.fontSecondary,
fontWeight: '600',
color: variables.fgHeading,
},
},
},
tooltip: {
show: false,
},
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: visitorsPie.firstPieGradientLeft,
},
{
offset: 1,
color: visitorsPie.firstPieGradientRight,
},
]),
shadowColor: visitorsPie.firstPieShadowColor,
shadowBlur: 0,
shadowOffsetX: 0,
shadowOffsetY: 3,
},
},
hoverAnimation: false,
},
{
value: 100 - this.value,
name: ' ',
tooltip: {
show: false,
},
label: {
normal: {
position: 'inner',
},
},
itemStyle: {
normal: {
color: variables.layoutBg,
},
},
},
],
},
{
name: ' ',
clockWise: true,
hoverAnimation: false,
type: 'pie',
center: ['50%', '50%'],
radius: visitorsPie.secondPieRadius,
data: [
{
value: this.value,
name: ' ',
label: {
normal: {
position: 'center',
formatter: '',
textStyle: {
fontSize: '22',
fontFamily: variables.fontSecondary,
fontWeight: '600',
color: variables.fgHeading,
},
},
},
tooltip: {
show: false,
},
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1),
},
},
hoverAnimation: false,
},
{
value: 100 - this.value,
name: ' ',
tooltip: {
show: false,
},
label: {
normal: {
position: 'inner',
},
},
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: visitorsPie.secondPieGradientLeft,
},
{
offset: 1,
color: visitorsPie.secondPieGradientRight,
},
]),
shadowColor: visitorsPie.secondPieShadowColor,
shadowBlur: 0,
shadowOffsetX: visitorsPie.shadowOffsetX,
shadowOffsetY: visitorsPie.shadowOffsetY,
},
},
},
],
},
],
};
}
onChartInit(echarts) {
this.echartsIntance = echarts;
}
resizeChart() {
if (this.echartsIntance) {
this.echartsIntance.resize();
}
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -1,23 +0,0 @@
<div class="calendars">
<div class="calendar-container">
<span class="subtitle">
Selected date: {{ date | date }}
</span>
<nb-calendar [(date)]="date" [boundingMonth]="true" showWeekNumber></nb-calendar>
</div>
<div class="calendar-container">
<span class="subtitle">
Selected range: {{ range.start | date }} - {{ range.end | date }}
</span>
<nb-calendar-range [(range)]="range"></nb-calendar-range>
</div>
<div class="calendar-container">
<span class="subtitle">
Selected date: {{ date2 | date }}
</span>
<nb-calendar
[(date)]="date2"
[dayCellComponent]="dayCellComponent"
></nb-calendar>
</div>
</div>

View file

@ -1,39 +0,0 @@
<nb-card>
<nb-card-header>Button With Spinner</nb-card-header>
<nb-card-body>
<div class="row">
<div class="col-md-12 col-lg-12 col-xxxl-12">
<button nbButton matRipple status="success" size="large" (click)="toggleLoadingLargeGroupAnimation()"
[nbSpinner]="loadingLargeGroup" nbSpinnerStatus="success" nbSpinnerSize="large" nbSpinnerMessage="">
Download
</button>
<button nbButton matRipple status="primary" size="large" (click)="toggleLoadingLargeGroupAnimation()"
[nbSpinner]="loadingLargeGroup" nbSpinnerStatus="primary" nbSpinnerSize="large" nbSpinnerMessage="">
Download
</button>
<button nbButton matRipple status="warning" size="large" (click)="toggleLoadingLargeGroupAnimation()"
[nbSpinner]="loadingLargeGroup" nbSpinnerStatus="warning" nbSpinnerSize="large" nbSpinnerMessage="">
Download
</button>
</div>
<div class="col-md-12 col-lg-12 col-xxxl-12 size-medium-group">
<button nbButton matRipple status="danger" size="medium" (click)="toggleLoadingMediumGroupAnimation()"
[nbSpinner]="loadingMediumGroup" nbSpinnerStatus="danger" nbSpinnerMessage="">
Download
</button>
<button nbButton matRipple status="info" size="medium" (click)="toggleLoadingMediumGroupAnimation()"
[nbSpinner]="loadingMediumGroup" nbSpinnerStatus="info" nbSpinnerSize="small" nbSpinnerMessage="">
Download
</button>
<button nbButton matRipple status="primary" size="medium" (click)="toggleLoadingMediumGroupAnimation()"
[nbSpinner]="loadingMediumGroup" nbSpinnerStatus="primary" nbSpinnerSize="tiny" nbSpinnerMessage="">
Download
</button>
</div>
</div>
</nb-card-body>
</nb-card>

View file

@ -1,129 +0,0 @@
<div class="row">
<div class="col-lg-12">
<nb-card>
<nb-card-header>Hero Buttons</nb-card-header>
<nb-card-body>
<div class="buttons-row">
<button *ngFor="let status of statuses" nbButton matRipple [status]="status" hero>
{{ status }}
</button>
<button disabled nbButton matRipple hero>
disabled
</button>
</div>
</nb-card-body>
</nb-card>
<nb-card>
<nb-card-header>Default Buttons</nb-card-header>
<nb-card-body>
<div class="buttons-row">
<button *ngFor="let status of statuses" nbButton matRipple [status]="status">
{{ status }}
</button>
<button disabled nbButton matRipple>
disabled
</button>
</div>
</nb-card-body>
</nb-card>
<nb-card>
<nb-card-header>Outline Buttons</nb-card-header>
<nb-card-body>
<div class="buttons-row">
<button *ngFor="let status of statuses" nbButton matRipple [status]="status" outline>
{{ status }}
</button>
<button disabled nbButton matRipple outline>
disabled
</button>
</div>
</nb-card-body>
</nb-card>
<nb-card>
<nb-card-header>Ghost Buttons</nb-card-header>
<nb-card-body>
<div class="buttons-row">
<button *ngFor="let status of statuses" nbButton matRipple [status]="status" ghost>
{{ status }}
</button>
<button disabled nbButton matRipple outline>
disabled
</button>
</div>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-12 col-lg-12 col-xxxl-6">
<nb-card>
<nb-card-header>Button shapes</nb-card-header>
<nb-card-body>
<div class="buttons-row">
<button *ngFor="let shape of shapes" nbButton matRipple [shape]="shape">
{{ shape }}
</button>
</div>
</nb-card-body>
</nb-card>
<nb-card>
<nb-card-header>Button sizes</nb-card-header>
<nb-card-body>
<div class="buttons-row">
<button *ngFor="let size of sizes" nbButton matRipple [size]="size">
{{ size }}
</button>
</div>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-12 col-lg-12 col-xxxl-6">
<nb-card class="actions-card">
<nb-card-header>Action Groups</nb-card-header>
<nb-card-body>
<nb-actions size="medium">
<nb-action matRipple icon="menu-outline"></nb-action>
<nb-action matRipple icon="search-outline"></nb-action>
<nb-action matRipple icon="email-outline"></nb-action>
<nb-action disabled icon="bell-outline"></nb-action><nb-action>
<nb-user matRipple name="Han Solo"></nb-user>
</nb-action>
<nb-action matRipple icon="settings-2-outline"></nb-action>
</nb-actions>
</nb-card-body>
</nb-card>
<nb-card>
<nb-card-body>
<nb-actions size="medium" fullWidth>
<nb-action matRipple>
<nb-icon class="action-icon" icon="pause-circle-outline"></nb-icon>
<span>Pause</span>
</nb-action>
<nb-action matRipple>
<nb-icon class="action-icon" icon="list-outline"></nb-icon>
<span>Logs</span>
</nb-action>
<nb-action matRipple>
<nb-icon class="action-icon" icon="search-outline"></nb-icon>
<span>Search</span>
</nb-action>
<nb-action matRipple>
<nb-icon class="action-icon" icon="settings-2-outline"></nb-icon>
<span>Setup</span>
</nb-action>
</nb-actions>
</nb-card-body>
</nb-card>
<nb-card *ngIf="materialTheme$ | async">
<nb-card-body>
<ngx-material-buttons></ngx-material-buttons>
</nb-card-body>
</nb-card>
</div>
</div>

View file

@ -1,25 +0,0 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
.buttons-row {
margin: -0.5rem;
}
button[nbButton] {
margin: 0.5rem;
}
.action-icon {
@include nb-ltr(margin-right, 0.5rem);
@include nb-rtl(margin-left, 0.5rem);
}
.actions-card {
height: 8rem;
}
nb-action {
border-radius: 2px;
cursor: pointer;
}
}

View file

@ -1,26 +0,0 @@
import { Component } from '@angular/core';
import { NbComponentShape, NbComponentSize, NbComponentStatus, NbThemeService } from '@nebular/theme';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Component({
selector: 'ngx-buttons',
styleUrls: ['./buttons.component.scss'],
templateUrl: './buttons.component.html',
})
export class ButtonsComponent {
public constructor(private readonly themeService: NbThemeService) {
this.materialTheme$ = this.themeService.onThemeChange()
.pipe(map(theme => {
const themeName: string = theme?.name || '';
return themeName.startsWith('material');
}));
}
public readonly materialTheme$: Observable<boolean>;
public readonly statuses: NbComponentStatus[] = [ 'primary', 'success', 'info', 'warning', 'danger' ];
public readonly shapes: NbComponentShape[] = [ 'rectangle', 'semi-round', 'round' ];
public readonly sizes: NbComponentSize[] = [ 'tiny', 'small', 'medium', 'large', 'giant' ];
}

View file

@ -1,9 +0,0 @@
<button mat-button color="primary">Basic</button>
<button mat-raised-button color="primary">Raised</button>
<button mat-stroked-button color="primary">Stroked</button>
<button mat-flat-button color="primary">Flat</button>
<button mat-fab color="primary">FAB</button>
<mat-button-toggle-group>
<mat-button-toggle value="left" [checked]="true">Toggle left</mat-button-toggle>
<mat-button-toggle value="right">Toggle right</mat-button-toggle>
</mat-button-toggle-group>

View file

@ -1,3 +0,0 @@
button, mat-button-toggle-group {
margin: 0.5rem;
}

View file

@ -1,8 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'ngx-material-buttons',
templateUrl: './material-buttons.component.html',
styleUrls: ['./material-buttons.component.scss'],
})
export class MaterialButtonsComponent {}

View file

@ -1,94 +0,0 @@
<div class="row">
<div class="col-lg-6">
<nb-card>
<nb-card-header>Default Inputs</nb-card-header>
<nb-card-body>
<input type="text" nbInput fullWidth placeholder="Project">
<div class="full-name-inputs">
<input type="text" nbInput fullWidth placeholder="Nick">
<input type="text" nbInput fullWidth placeholder="Last Name">
</div>
<input type="password" nbInput fullWidth placeholder="Password">
<input type="text" nbInput fullWidth shape="rectangle" placeholder="Rectangle border">
<ng-container *ngIf="!(materialTheme$ | async)">
<input type="text" nbInput fullWidth shape="semi-round" placeholder="Semi-round border">
<input type="text" nbInput fullWidth shape="round" placeholder="Rounded border">
</ng-container>
<input type="text" nbInput fullWidth placeholder="Disabled input" disabled/>
<textarea rows="5" nbInput fullWidth shape="round" placeholder="Text Area"></textarea>
<input type="text" nbInput fullWidth fieldSize="small" placeholder="Small Input">
<input type="text" nbInput fullWidth fieldSize="medium" placeholder="Medium Input">
<input type="text" nbInput fullWidth fieldSize="large" placeholder="Large Input">
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Select</nb-card-header>
<nb-card-body>
<nb-select matRipple selected="1">
<nb-option matRipple value="1">Option 1</nb-option>
<nb-option matRipple value="2">Option 2</nb-option>
</nb-select>
</nb-card-body>
</nb-card>
<nb-card>
<nb-card-header>Validation States</nb-card-header>
<nb-card-body>
<input type="text" nbInput fullWidth status="info" placeholder="Input with Info">
<input type="text" nbInput fullWidth status="success" placeholder="Warning Input">
<input type="text" nbInput fullWidth status="warning" placeholder="Danger Input">
<input type="text" nbInput fullWidth status="danger" placeholder="Danger Input">
<input type="text" nbInput fullWidth status="primary" placeholder="Input with Primary">
<div class="validation-checkboxes">
<nb-checkbox status="success">Success Checkbox</nb-checkbox>
<nb-checkbox status="warning">Warning Checkbox</nb-checkbox>
<nb-checkbox status="danger">Danger Checkbox</nb-checkbox>
</div>
</nb-card-body>
</nb-card>
<nb-card>
<nb-card-header>Checkboxes & Radios</nb-card-header>
<nb-card-body class="checkbox-radio">
<div class="demo-items">
<nb-checkbox>Checkbox 1</nb-checkbox>
<nb-checkbox [value]="true">Checkbox 2</nb-checkbox>
</div>
<div class="demo-items">
<nb-radio-group [(value)]="radioGroupValue">
<nb-radio
[value]="'This is value 1'">
Radio 1
</nb-radio>
<nb-radio
[value]="'This is value 2'">
Radio 2
</nb-radio>
<nb-radio
[value]="'This is value 3'">
Radio 3
</nb-radio>
</nb-radio-group>
</div>
<div class="demo-items">
<nb-checkbox disabled>Disabled Checkbox</nb-checkbox>
<nb-radio-group disabled>
<nb-radio
[value]="'Disabled Value'">
Disabled Radio
</nb-radio>
</nb-radio-group>
</div>
</nb-card-body>
</nb-card>
</div>
</div>
<div *ngIf="showMaterialInputs" class="row">
<div class="col-lg-12">
<ngx-material-inputs></ngx-material-inputs>
</div>
</div>

View file

@ -1,28 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Component({
selector: 'ngx-form-inputs',
styleUrls: ['./form-inputs.component.scss'],
templateUrl: './form-inputs.component.html',
})
export class FormInputsComponent implements OnInit {
public constructor(private readonly themeService: NbThemeService) {
}
public materialTheme$: Observable<boolean>;
public starRate: number = 2;
public heartRate: number = 4;
public radioGroupValue: string = 'This is value 2';
public showMaterialInputs = false;
ngOnInit() {
this.materialTheme$ = this.themeService.onThemeChange()
.pipe(tap(theme => {
const themeName: string = theme?.name || '';
this.showMaterialInputs = themeName.startsWith('material');
}));
}
}

View file

@ -1,58 +0,0 @@
<nb-card>
<nb-card-header>Angular Material</nb-card-header>
<nb-card-body>
<div class="row">
<div class="col-lg-6">
<mat-form-field class="input-example">
<mat-label>Input</mat-label>
<input matInput autocomplete="off">
<mat-hint>hint</mat-hint>
</mat-form-field>
<mat-form-field class="input-example">
<mat-label>Select</mat-label>
<mat-select>
<mat-option value="1">Option 1</mat-option>
<mat-option value="2">Option 2</mat-option>
<mat-option value="3">Option 3</mat-option>
</mat-select>
<mat-hint>hint</mat-hint>
</mat-form-field>
<mat-form-field class="input-example">
<mat-label>Datepicker</mat-label>
<input matInput autocomplete="off" [matDatepicker]="picker">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
<mat-hint>hint</mat-hint>
</mat-form-field>
</div>
<div class="col-lg-6">
<mat-form-field class="input-example">
<mat-label>Textarea</mat-label>
<textarea matInput autocomplete="off"></textarea>
<mat-hint>hint</mat-hint>
</mat-form-field>
<div class="input-example">
<label>Checkbox</label>
<mat-checkbox color="primary" [checked]="true"></mat-checkbox>
</div>
<div class="input-example">
<label>Toggle</label>
<mat-slide-toggle color="primary" [checked]="true"></mat-slide-toggle>
</div>
<div class="input-example">
<label>Radio</label>
<mat-radio-group color="primary">
<mat-radio-button value="1" [checked]="true">Option 1</mat-radio-button>
<mat-radio-button value="2">Option 2</mat-radio-button>
<mat-radio-button value="3">Option 3</mat-radio-button>
</mat-radio-group>
</div>
</div>
</div>
</nb-card-body>
</nb-card>

View file

@ -1,16 +0,0 @@
:host {
display: block;
}
.input-example {
display: block;
margin-top: 1rem;
label, mat-radio-button {
margin-right: 1rem;
}
textarea {
min-height: 3rem;
}
}

View file

@ -1,8 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'ngx-material-inputs',
templateUrl: './material-inputs.component.html',
styleUrls: ['./material-inputs.component.scss'],
})
export class MaterialInputsComponent {}

View file

@ -1,76 +0,0 @@
import { NgModule } from '@angular/core';
import {
NbActionsModule,
NbButtonModule,
NbCardModule,
NbCheckboxModule,
NbDatepickerModule, NbIconModule,
NbInputModule,
NbRadioModule,
NbSelectModule,
NbUserModule,
} from '@nebular/theme';
import { ThemeModule } from '../../@theme/theme.module';
import { FormsRoutingModule } from './forms-routing.module';
import { FormsComponent } from './forms.component';
import { FormInputsComponent } from './form-inputs/form-inputs.component';
import { MaterialInputsComponent } from './form-inputs/material-inputs/material-inputs.component';
import { FormLayoutsComponent } from './form-layouts/form-layouts.component';
import { DatepickerComponent } from './datepicker/datepicker.component';
import { ButtonsComponent } from './buttons/buttons.component';
import { MaterialButtonsComponent } from './buttons/material-buttons/material-buttons.component';
import { FormsModule as ngFormsModule } from '@angular/forms';
import { MatNativeDateModule } from '@angular/material/core';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatRadioModule } from '@angular/material/radio';
import { MatButtonModule } from '@angular/material/button';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
const materialModules = [
MatFormFieldModule,
MatInputModule,
MatSelectModule,
MatNativeDateModule,
MatDatepickerModule,
MatCheckboxModule,
MatSlideToggleModule,
MatRadioModule,
MatButtonModule,
MatButtonToggleModule,
];
@NgModule({
imports: [
ThemeModule,
NbInputModule,
NbCardModule,
NbButtonModule,
NbActionsModule,
NbUserModule,
NbCheckboxModule,
NbRadioModule,
NbDatepickerModule,
FormsRoutingModule,
NbSelectModule,
NbIconModule,
ngFormsModule,
...materialModules,
],
declarations: [
FormsComponent,
ButtonsComponent,
FormInputsComponent,
FormLayoutsComponent,
DatepickerComponent,
MaterialInputsComponent,
MaterialButtonsComponent,
],
})
export class FormsModule { }

View file

@ -1,82 +0,0 @@
<div class="accordions-container row">
<div class="accordion-container col-md-12 col-lg-6 col-xxxl-6">
<nb-card>
<nb-card-header>Toggle Accordion By Button</nb-card-header>
<nb-card-body>
<button nbButton matRipple (click)="toggle()">Toggle First Item</button>
</nb-card-body>
</nb-card>
<nb-accordion>
<nb-accordion-item #item>
<nb-accordion-item-header matRipple>
Product Details
</nb-accordion-item-header>
<nb-accordion-item-body>
A nebula is an interstellar cloud of dust, hydrogen, helium and other ionized gases.
Originally, nebula was a name for any diffuse astronomical object,
including galaxies beyond the Milky Way.
</nb-accordion-item-body>
</nb-accordion-item>
<nb-accordion-item>
<nb-accordion-item-header matRipple>
Reviews
</nb-accordion-item-header>
<nb-accordion-item-body>
A nebula is an interstellar cloud of dust, hydrogen, helium and other ionized gases.
Originally, nebula was a name for any diffuse astronomical object,
including galaxies beyond the Milky Way.
</nb-accordion-item-body>
</nb-accordion-item>
<nb-accordion-item>
<nb-accordion-item-header matRipple>
Edit
</nb-accordion-item-header>
<nb-accordion-item-body>
A nebula is an interstellar cloud of dust, hydrogen, helium and other ionized gases.
Originally, nebula was a name for any diffuse astronomical object,
including galaxies beyond the Milky Way.
</nb-accordion-item-body>
</nb-accordion-item>
</nb-accordion>
</div>
<div class="accordion-container col-md-12 col-lg-6 col-xxxl-6">
<nb-accordion multi>
<nb-accordion-item>
<nb-accordion-item-header matRipple>
Product Details
</nb-accordion-item-header>
<nb-accordion-item-body>
A nebula is an interstellar cloud of dust, hydrogen, helium and other ionized gases.
Originally, nebula was a name for any diffuse astronomical object,
including galaxies beyond the Milky Way.
</nb-accordion-item-body>
</nb-accordion-item>
<nb-accordion-item>
<nb-accordion-item-header matRipple>
Reviews
</nb-accordion-item-header>
<nb-accordion-item-body>
A nebula is an interstellar cloud of dust, hydrogen, helium and other ionized gases.
Originally, nebula was a name for any diffuse astronomical object,
including galaxies beyond the Milky Way.
</nb-accordion-item-body>
</nb-accordion-item>
<nb-accordion-item>
<nb-accordion-item-header matRipple>
Edit
</nb-accordion-item-header>
<nb-accordion-item-body>
A nebula is an interstellar cloud of dust, hydrogen, helium and other ionized gases.
Originally, nebula was a name for any diffuse astronomical object,
including galaxies beyond the Milky Way.
</nb-accordion-item-body>
</nb-accordion-item>
</nb-accordion>
</div>
</div>

View file

@ -1,28 +0,0 @@
<div class="lists row">
<div class="col-md-12 col-lg-6 col-xxxl-6">
<nb-card class="list-card">
<nb-card-header>Some Fruits</nb-card-header>
<nb-card-body>
<nb-list>
<nb-list-item *ngFor="let fruit of fruits">
{{ fruit }}
</nb-list-item>
</nb-list>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-12 col-lg-6 col-xxxl-6">
<nb-card class="list-card" size="small">
<nb-card-header>Users</nb-card-header>
<nb-card-body>
<nb-list>
<nb-list-item *ngFor="let user of users">
<nb-user [name]="user.name" [title]="user.title">
</nb-user>
</nb-list-item>
</nb-list>
</nb-card-body>
</nb-card>
</div>
</div>

View file

@ -1,143 +0,0 @@
<nb-card class="col-md-12 col-lg-12 col-xxxl-12">
<nb-card-body>
<nb-stepper orientation="horizontal">
<nb-step [label]="labelOne">
<ng-template #labelOne>First step</ng-template>
<h3>Step content #1</h3>
<button nbButton matRipple disabled nbStepperNext>prev</button>
<button nbButton matRipple nbStepperNext>next</button>
</nb-step>
<nb-step [label]="labelTwo">
<ng-template #labelTwo>Second step</ng-template>
<h3>Step content #2</h3>
<button nbButton matRipple nbStepperPrevious>prev</button>
<button nbButton matRipple nbStepperNext>next</button>
</nb-step>
<nb-step label="Third step">
<h3>Step content #3</h3>
<button nbButton matRipple nbStepperPrevious>prev</button>
<button nbButton matRipple nbStepperNext>next</button>
</nb-step>
<nb-step [label]="labelFour">
<ng-template #labelFour>Fourth step</ng-template>
<h3>Step content #4</h3>
<button nbButton matRipple nbStepperPrevious>prev</button>
<button nbButton matRipple disabled nbStepperNext>next</button>
</nb-step>
</nb-stepper>
</nb-card-body>
</nb-card>
<div class="steppers-container row">
<div class="col-md-12 col-lg-6 col-xxxl-6">
<nb-card>
<nb-card-body>
<nb-stepper #stepper>
<nb-step [stepControl]="firstForm" label="First step">
<form [formGroup]="firstForm" (ngSubmit)="onFirstSubmit()" class="step-container">
<p class="lorem">
Lorizzle ipsum dolizzle stuff fizzle, consectetuer adipiscing break it down. Nullizzle sapien velizzle,
my shizz pimpin', shizzle my nizzle crocodizzle shut the shizzle up, gravida vizzle, dang.
</p>
<div class="input-group">
<input type="text" placeholder="Enter your name" class="form-control" formControlName="firstCtrl"
[ngClass]="{'form-control-danger': firstForm.invalid && (firstForm.dirty || firstForm.touched)}">
</div>
<button nbButton matRipple nbStepperNext>next</button>
</form>
</nb-step>
<nb-step [stepControl]="secondForm" label="Second step">
<form [formGroup]="secondForm" (ngSubmit)="onSecondSubmit()" class="step-container">
<p class="lorem">
Pellentesque we gonna chung tortor.
Sizzle pizzle. Fizzle izzle dolor dapibus fo shizzle mah nizzle fo rizzle, mah home g-dizzle tempus tempor.
Maurizzle cool nibh owned turpizzle. My shizz fo shizzle tortor.
</p>
<div class="input-group">
<input type="text" placeholder="Enter favorite movie" class="form-control" formControlName="secondCtrl"
[ngClass]="{'form-control-danger': secondForm.invalid && (secondForm.dirty || secondForm.touched)}">
</div>
<button nbButton matRipple nbStepperPrevious>prev</button>
<button nbButton matRipple nbStepperNext>next</button>
</form>
</nb-step>
<nb-step [stepControl]="thirdForm" label="Third step">
<form [formGroup]="thirdForm" (ngSubmit)="onThirdSubmit()" class="step-container">
<p class="lorem">
Things boom shackalack rhoncus yo. In fo shizzle my nizzle gangsta platea dictumst. Check it out pot.
</p>
<div class="input-group">
<input type="text" placeholder="Enter something" class="form-control" formControlName="thirdCtrl"
[ngClass]="{'form-control-danger': thirdForm.invalid && (thirdForm.dirty || thirdForm.touched)}">
</div>
<button nbButton matRipple nbStepperPrevious>prev</button>
<button nbButton matRipple nbStepperNext>Confirm</button>
</form>
</nb-step>
<nb-step [stepControl]="thirdForm" [hidden]="true" label="Third step">
<div class="step-container">
<h3>Wizard completed!</h3>
<button nbButton matRipple (click)="stepper.reset()">Try again</button>
</div>
</nb-step>
</nb-stepper>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-12 col-lg-6 col-xxxl-6">
<nb-card size="medium">
<nb-card-body>
<nb-stepper orientation="vertical">
<nb-step label="First step">
<h3>Step content #1</h3>
<p class="lorem">
Proin varius accumsan semper. Praesent consequat tincidunt sagittis. Curabitur egestas sem a ipsum bibendum,
sit amet fringilla orci efficitur. Nam bibendum lectus ut viverra tristique. Fusce eu pulvinar magna, quis
viverra ex. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent metus turpis, commodo vel
placerat quis, lobortis in ligula.
</p>
<button nbButton matRipple disabled nbStepperNext>prev</button>
<button nbButton matRipple nbStepperNext>next</button>
</nb-step>
<nb-step label="Second step">
<h3>Step content #2</h3>
<p class="lorem">
Curabitur luctus mattis risus nec condimentum. Donec at dui turpis. Sed vehicula fringilla rutrum. Nullam
sed ornare magna. Mauris vitae laoreet diam. Mauris fermentum ligula at lacinia semper. Nulla placerat dui
eu sapien pellentesque, eu placerat leo luctus. Cras pharetra blandit fermentum.
</p>
<button nbButton matRipple nbStepperPrevious>prev</button>
<button nbButton matRipple nbStepperNext>next</button>
</nb-step>
<nb-step label="Third step">
<h3>Step content #3</h3>
<p class="lorem">
Proin varius accumsan semper. Praesent consequat tincidunt sagittis. Curabitur egestas sem a ipsum bibendum,
sit amet fringilla orci efficitur. Nam bibendum lectus ut viverra tristique. Fusce eu pulvinar magna, quis
viverra ex. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent metus turpis, commodo vel
placerat quis, lobortis in ligula.
</p>
<p class="lorem">
Curabitur luctus mattis risus nec condimentum. Donec at dui turpis. Sed vehicula fringilla rutrum. Nullam
sed ornare magna. Mauris vitae laoreet diam. Mauris fermentum ligula at lacinia semper. Nulla placerat dui
eu sapien pellentesque, eu placerat leo luctus. Cras pharetra blandit fermentum.
</p>
<button nbButton matRipple nbStepperPrevious>prev</button>
<button nbButton matRipple nbStepperNext>next</button>
</nb-step>
<nb-step label="Fourth step">
<h3>Step content #4</h3>
<p class="lorem">
Proin varius accumsan semper. Praesent consequat tincidunt sagittis. Curabitur egestas sem a ipsum bibendum,
sit amet fringilla orci efficitur. Nam bibendum lectus ut viverra tristique. Fusce eu pulvinar magna, quis
viverra ex.
</p>
<button nbButton matRipple nbStepperPrevious>prev</button>
<button nbButton matRipple disabled nbStepperNext>next</button>
</nb-step>
</nb-stepper>
</nb-card-body>
</nb-card>
</div>
</div>

View file

@ -1,8 +0,0 @@
<nb-card>
<nb-card-header>Google Maps</nb-card-header>
<nb-card-body>
<google-map [center]="position" [zoom]="8" width="100%" height="36.5625rem">
<map-marker [position]="position"></map-marker>
</google-map>
</nb-card-body>
</nb-card>

View file

@ -1,10 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'ngx-gmaps',
styleUrls: ['./gmaps.component.scss'],
templateUrl: './gmaps.component.html',
})
export class GmapsComponent {
public readonly position = { lat: 51.678418, lng: 7.809007 };
}

View file

@ -1,24 +0,0 @@
import { NgModule } from '@angular/core';
import { GoogleMapsModule } from '@angular/google-maps';
import { LeafletModule } from '@asymmetrik/ngx-leaflet';
import { NgxEchartsModule } from 'ngx-echarts';
import { NbCardModule } from '@nebular/theme';
import { ThemeModule } from '../../@theme/theme.module';
import { MapsRoutingModule, routedComponents } from './maps-routing.module';
@NgModule({
imports: [
ThemeModule,
GoogleMapsModule,
LeafletModule.forRoot(),
MapsRoutingModule,
NgxEchartsModule,
NbCardModule,
],
exports: [],
declarations: [
...routedComponents,
],
})
export class MapsModule { }

View file

@ -1,6 +0,0 @@
export class PositionModel {
public constructor(
public lat: number = 53.9,
public lng: number = 27.5667,
) {}
}

View file

@ -1,3 +0,0 @@
<google-map [center]="position" [zoom]="zoom" width="100%" height="36.5625rem">
<map-marker [position]="position"></map-marker>
</google-map>

View file

@ -1,33 +0,0 @@
import { Component, Input, OnInit } from '@angular/core';
import { PositionModel } from '../entity/position.model';
@Component({
selector: 'ngx-map',
templateUrl: './map.component.html',
styleUrls: ['./map.component.scss'],
})
export class MapComponent implements OnInit {
public position: PositionModel = null;
public zoom: number = 1;
@Input()
public set searchedPosition(position: PositionModel) {
if (!position) return;
console.dir(position);
this.position = position;
this.zoom = 12;
}
public ngOnInit(): void {
// set up current location
if ('geolocation' in navigator) {
navigator.geolocation.getCurrentPosition((position) => {
this.searchedPosition = new PositionModel(
position.coords.latitude,
position.coords.longitude,
);
});
}
}
}

View file

@ -1,7 +0,0 @@
<nb-card>
<nb-card-header>Google Maps with search</nb-card-header>
<nb-card-body>
<ngx-search (positionChanged)="setPosition($event)"></ngx-search>
<ngx-map [searchedPosition]="searchedPosition"></ngx-map>
</nb-card-body>
</nb-card>

View file

@ -1,14 +0,0 @@
import { Component } from '@angular/core';
import { PositionModel } from './entity/position.model';
@Component({
selector: 'ngx-search-map',
templateUrl: './search-map.component.html',
})
export class SearchMapComponent {
public searchedPosition: PositionModel = new PositionModel();
public setPosition(position: PositionModel): void {
this.searchedPosition = position;
}
}

View file

@ -1,40 +0,0 @@
import { Component, ElementRef, EventEmitter, NgZone, OnInit, Output, ViewChild } from '@angular/core';
import { PositionModel } from '../entity/position.model';
@Component({
selector: 'ngx-search',
templateUrl: './search.component.html',
})
export class SearchComponent implements OnInit {
@Output()
public readonly positionChanged: EventEmitter<PositionModel> = new EventEmitter<PositionModel>();
@ViewChild('search', { static: true })
public searchElementRef: ElementRef;
constructor(private readonly ngZone: NgZone) {}
ngOnInit() {
const autocomplete = new google.maps.places.Autocomplete(
this.searchElementRef.nativeElement, { types: ['address'] },
);
autocomplete.addListener('place_changed', () => {
this.ngZone.run(() => {
// get the place result
const place: google.maps.places.PlaceResult = autocomplete.getPlace();
// verify result
if (place.geometry === undefined || place.geometry === null) {
return;
}
this.positionChanged.emit(new PositionModel(
place.geometry.location.lat(),
place.geometry.location.lng(),
));
});
});
}
}

View file

@ -1,15 +0,0 @@
<div class="row">
<div class="col-md-12">
<nb-card>
<nb-card-body>
<div class="flex-centered col-xl-4 col-lg-6 col-md-8 col-sm-12">
<h2 class="title">404 Page Not Found</h2>
<small class="sub-title">The page you were looking for doesn't exist</small>
<button nbButton matRipple fullWidth (click)="goToHome()" type="button" class="home-button">
Take me home
</button>
</div>
</nb-card-body>
</nb-card>
</div>
</div>

View file

@ -1,10 +0,0 @@
<nb-card>
<nb-card-header>Enter your name</nb-card-header>
<nb-card-body>
<input #name nbInput placeholder="Name">
</nb-card-body>
<nb-card-footer>
<button class="cancel" nbButton matRipple status="danger" (click)="cancel()">Cancel</button>
<button nbButton matRipple status="success" (click)="submit(name.value)">Submit</button>
</nb-card-footer>
</nb-card>

View file

@ -1,70 +0,0 @@
<div class="row">
<div class="col-md-12 col-lg-6 col-xxxl-3">
<nb-card>
<nb-card-header>Open Dialog</nb-card-header>
<nb-card-body>
<button nbButton matRipple (click)="open()">Open Dialog with component</button>
<button nbButton matRipple (click)="open2(dialog)">Open Dialog with template</button>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-12 col-lg-6 col-xxxl-3">
<nb-card>
<nb-card-header>Open Without Backdrop</nb-card-header>
<nb-card-body>
<button nbButton matRipple (click)="open()">Open Dialog with backdrop</button>
<button nbButton matRipple (click)="openWithoutBackdrop(dialog)">Open Dialog without backdrop</button>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-12 col-lg-6 col-xxxl-3">
<nb-card>
<nb-card-header>Open Without Esc Close</nb-card-header>
<nb-card-body>
<button nbButton matRipple (click)="open()">Open Dialog with esc close</button>
<button nbButton matRipple (click)="openWithoutEscClose(dialog)">Open Dialog without esc close</button>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-12 col-lg-6 col-xxxl-3">
<nb-card>
<nb-card-header>Open Without Backdrop Click</nb-card-header>
<nb-card-body>
<button nbButton matRipple (click)="open()">Open Dialog with backdrop click</button>
<button nbButton matRipple (click)="openWithoutBackdropClick(dialog)">Open without backdrop click</button>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-12 col-lg-6 col-xxxl-3">
<nb-card class="form-input-card">
<nb-card-header>Return Result From Dialog</nb-card-header>
<nb-card-body class="result-from-dialog">
<button nbButton matRipple (click)="open3()">Enter Name</button>
<br>
<h3 class="title">Names:</h3>
<ul>
<li *ngFor="let name of names">{{ name }}</li>
</ul>
</nb-card-body>
</nb-card>
</div>
</div>
<ng-template #dialog let-data let-ref="dialogRef">
<nb-card>
<nb-card-header>Template Dialog</nb-card-header>
<nb-card-body>{{ data }}</nb-card-body>
<nb-card-footer>
<button nbButton matRipple (click)="ref.close()">Close Dialog</button>
</nb-card-footer>
</nb-card>
</ng-template>

View file

@ -1,14 +0,0 @@
<nb-card>
<nb-card-header>{{ title }}</nb-card-header>
<nb-card-body>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras convallis tincidunt tincidunt.
Vestibulum vulputate maximus massa vel tristique. Suspendisse potenti. Duis aliquet purus sed dictum dictum.
Donec fringilla, purus at fermentum imperdiet, velit enim malesuada turpis, quis luctus arcu arcu nec orci.
Duis eu mattis felis. Quisque sollicitudin elementum nunc vel tincidunt. Vestibulum egestas mi nec
iaculis varius. Morbi in risus sed sapien ultricies feugiat. Quisque pulvinar mattis purus,
in aliquet massa aliquet et.
</nb-card-body>
<nb-card-footer>
<button nbButton matRipple hero status="primary" (click)="dismiss()">Dismiss Dialog</button>
</nb-card-footer>
</nb-card>

View file

@ -1,67 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'ngx-popover-tabs',
template: `
<nb-tabset>
<nb-tab tabTitle="What's up?">
<div class="p-4">
Such a wonderful day!
</div>
</nb-tab>
<nb-tab tabTitle="Second Tab">
<div class="p-4">
Indeed!
</div>
</nb-tab>
</nb-tabset>
`,
})
export class NgxPopoverTabsComponent {
}
@Component({
selector: 'ngx-popover-form',
template: `
<div class="p-4">
<form>
<div class="form-group">
<input type="text" class="form-control" placeholder="Recipients">
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Subject">
</div>
<div class="form-group">
<textarea class="form-control" placeholder="Message"></textarea>
</div>
<button matRipple type="submit" class="btn btn-primary w-100">Send</button>
</form>
</div>
`,
})
export class NgxPopoverFormComponent {
}
@Component({
selector: 'ngx-popover-card',
template: `
<nb-card class="popover-card">
<nb-card-header status="warning">
Hello!
</nb-card-header>
<nb-card-body>
Far far away, behind the word mountains, far from the countries Vokalia and Consonantia,
there live the blind texts.
Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean.
</nb-card-body>
</nb-card>
`,
styles: [`
nb-card {
margin: 0;
max-width: 20rem;
}
`],
})
export class NgxPopoverCardComponent {
}

View file

@ -1,157 +0,0 @@
<div class="row">
<div class="col-lg-6">
<nb-card size="small">
<nb-card-header>Popover Position</nb-card-header>
<nb-card-body>
<p>When popover has not enough space based on the configured placement, it will adjust accordingly trying to fit the screen.</p>
<button nbButton matRipple status="danger" nbPopover="Hello, how are you today?" nbPopoverTrigger="hint" nbPopoverPlacement="left">Left</button>
<button nbButton matRipple status="danger" nbPopover="Hello, how are you today?" nbPopoverTrigger="hint" nbPopoverPlacement="top">Top</button>
<button nbButton matRipple status="danger" nbPopover="Hello, how are you today?" nbPopoverTrigger="hint" nbPopoverPlacement="bottom">Bottom</button>
<button nbButton matRipple status="danger" nbPopover="Hello, how are you today?" nbPopoverTrigger="hint" nbPopoverPlacement="right">Right</button>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card size="small">
<nb-card-header>Simple Popovers</nb-card-header>
<nb-card-body>
<p>In a simples form popover can take a string of text to render.</p>
<button nbButton matRipple status="success" nbPopover="Hello, how are you today?">on click</button>
<button nbButton matRipple status="success" nbPopover="Hello, how are you today?" nbPopoverTrigger="hover">on hover</button>
<button nbButton matRipple status="success" nbPopover="Hello, how are you today?" nbPopoverTrigger="hint">on hint</button>
</nb-card-body>
</nb-card>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<ng-template #tabs>
<nb-tabset>
<nb-tab tabTitle="What's up?">
<div class="p-4">
Such a wonderful day!
</div>
</nb-tab>
<nb-tab tabTitle="Second Tab">
<div class="p-4">
Indeed!
</div>
</nb-tab>
</nb-tabset>
</ng-template>
<ng-template #form>
<div class="p-4">
<form>
<div class="form-group">
<input type="text" class="form-control" placeholder="Recipients">
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Subject">
</div>
<div class="form-group">
<textarea class="form-control" placeholder="Message"></textarea>
</div>
<button matRipple type="submit" class="btn btn-primary w-100">Send</button>
</form>
</div>
</ng-template>
<ng-template #card>
<nb-card class="popover-card">
<nb-card-header status="warning">
Hello!
</nb-card-header>
<nb-card-body>
Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts.
Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean.
</nb-card-body>
</nb-card>
</ng-template>
<nb-card size="small">
<nb-card-header>Template Popovers</nb-card-header>
<nb-card-body>
<p>You can pass a refference to `ng-template` to be rendered.</p>
<button nbButton matRipple status="warning" [nbPopover]="tabs">With tabs</button>
<button nbButton matRipple status="warning" [nbPopover]="form">With form</button>
<button nbButton matRipple status="warning" [nbPopover]="card">With card</button>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card size="small">
<nb-card-header>Component Popovers</nb-card-header>
<nb-card-body>
<p>Same way popover can render any angular compnoent.</p>
<button nbButton matRipple status="warning" [nbPopover]="tabsComponent">With tabs</button>
<button nbButton matRipple status="warning" [nbPopover]="formComponent">With form</button>
<button nbButton matRipple status="warning" [nbPopover]="cardComponent">With card</button>
</nb-card-body>
</nb-card>
</div>
</div>
<div class="row">
<div class="col-md-12">
<nb-card>
<nb-card-header>Event Debouncing</nb-card-header>
<nb-card-body class="debounce-card">
<p>Quickly move mouse cursor over the buttons, only the last popover will be created. It allows us to avoid excess white improving page performance.</p>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
<button nbButton matRipple nbPopover="Popover!" nbPopoverTrigger="hint">
show hint
</button>
</nb-card-body>
</nb-card>
</div>
</div>

View file

@ -1,59 +0,0 @@
<nb-card>
<nb-card-header>
Toaster configuration
</nb-card-header>
<nb-card-body>
<div class="row">
<div class="col-md-6 col-sm-12">
<div class="form-group">
<label class="label">Position:</label>
<nb-select [(selected)]="position" matRipple class="position-select">
<nb-option *ngFor="let p of positions" [value]="p" matRipple>{{ p }}</nb-option>
</nb-select>
</div>
<div class="form-group">
<label class="label">Title:</label>
<input nbInput [(ngModel)]="title" name="title">
</div>
<form>
<div class="form-group">
<label class="label">Content:</label>
<input nbInput [(ngModel)]="content" name="content">
</div>
</form>
<div class="form-group">
<label class="label">Time to hide toast, ms. 0 to persistent toast:</label>
<input nbInput type="number" [(ngModel)]="duration" name="timeout">
</div>
</div>
<div class="col-md-6 col-sm-12">
<div class="form-group">
<label class="label">Toast type:</label>
<nb-select [(selected)]="status" matRipple>
<nb-option *ngFor="let t of types" [value]="t" matRipple>{{ t }}</nb-option>
</nb-select>
</div>
<div>
<nb-checkbox [(ngModel)]="destroyByClick">Hide on click</nb-checkbox>
</div>
<div>
<nb-checkbox [(ngModel)]="preventDuplicates">Prevent arising of duplicate toast</nb-checkbox>
</div>
<div>
<nb-checkbox [(ngModel)]="hasIcon">Show toast with icon</nb-checkbox>
</div>
</div>
</div>
</nb-card-body>
<nb-card-footer>
<button nbButton matRipple (click)="makeToast()">Show toast</button>
<button nbButton matRipple status="success" (click)="openRandomToast()">Random toast</button>
</nb-card-footer>
</nb-card>

View file

@ -1,86 +0,0 @@
import { Component } from '@angular/core';
import {
NbComponentStatus,
NbGlobalLogicalPosition,
NbGlobalPhysicalPosition,
NbGlobalPosition,
NbToastrService,
NbToastrConfig,
} from '@nebular/theme';
@Component({
selector: 'ngx-toastr',
styleUrls: ['./toastr.component.scss'],
templateUrl: './toastr.component.html',
})
export class ToastrComponent {
constructor(private toastrService: NbToastrService) {}
config: NbToastrConfig;
index = 1;
destroyByClick = true;
duration = 2000;
hasIcon = true;
position: NbGlobalPosition = NbGlobalPhysicalPosition.TOP_RIGHT;
preventDuplicates = false;
status: NbComponentStatus = 'primary';
title = 'HI there!';
content = `I'm cool toaster!`;
types: NbComponentStatus[] = [
'primary',
'success',
'info',
'warning',
'danger',
];
positions: string[] = [
NbGlobalPhysicalPosition.TOP_RIGHT,
NbGlobalPhysicalPosition.TOP_LEFT,
NbGlobalPhysicalPosition.BOTTOM_LEFT,
NbGlobalPhysicalPosition.BOTTOM_RIGHT,
NbGlobalLogicalPosition.TOP_END,
NbGlobalLogicalPosition.TOP_START,
NbGlobalLogicalPosition.BOTTOM_END,
NbGlobalLogicalPosition.BOTTOM_START,
];
quotes = [
{ title: null, body: 'We rock at Angular' },
{ title: null, body: 'Titles are not always needed' },
{ title: null, body: 'Toastr rock!' },
];
makeToast() {
this.showToast(this.status, this.title, this.content);
}
openRandomToast () {
const typeIndex = Math.floor(Math.random() * this.types.length);
const quoteIndex = Math.floor(Math.random() * this.quotes.length);
const type = this.types[typeIndex];
const quote = this.quotes[quoteIndex];
this.showToast(type, quote.title, quote.body);
}
private showToast(type: NbComponentStatus, title: string, body: string) {
const config = {
status: type,
destroyByClick: this.destroyByClick,
duration: this.duration,
hasIcon: this.hasIcon,
position: this.position,
preventDuplicates: this.preventDuplicates,
};
const titleContent = title ? `. ${title}` : '';
this.index += 1;
this.toastrService.show(
body,
`Toast ${this.index}${titleContent}`,
config);
}
}

View file

@ -1,37 +0,0 @@
<div class="row">
<div class="col-md-12 col-lg-6 col-xxxl-4">
<nb-card>
<nb-card-header>Tooltip With Icon</nb-card-header>
<nb-card-body>
<button nbTooltip="This is a tooltip" nbTooltipIcon="home-outline" nbButton matRipple>Show Tooltip</button>
<button nbTooltip="" nbTooltipIcon="alert-triangle" nbTooltipStatus="danger" nbButton matRipple>Show Tooltip</button>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-12 col-lg-6 col-xxxl-4">
<nb-card>
<nb-card-header>Tooltip Placements</nb-card-header>
<nb-card-body>
<button nbTooltip="This is a tooltip" nbTooltipPlacement="top" nbButton matRipple>Top</button>
<button nbTooltip="This is a tooltip" nbTooltipPlacement="right" nbButton matRipple>Right</button>
<button nbTooltip="This is a tooltip" nbTooltipPlacement="bottom" nbButton matRipple>Bottom</button>
<button nbTooltip="This is a tooltip" nbTooltipPlacement="left" nbButton matRipple>Left</button>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-12 col-lg-6 col-xxxl-4">
<nb-card>
<nb-card-header>Colored Tooltips</nb-card-header>
<nb-card-body>
<button nbTooltip="This is a tooltip" nbTooltipPlacement="top" nbButton matRipple>Default</button>
<button nbTooltip="This is a tooltip" nbTooltipPlacement="top" nbTooltipStatus="primary" nbButton matRipple>Primary</button>
<button nbTooltip="This is a tooltip" nbTooltipPlacement="top" nbTooltipStatus="success" nbButton matRipple>Success</button>
<button nbTooltip="This is a tooltip" nbTooltipPlacement="top" nbTooltipStatus="danger" nbButton matRipple>Danger</button>
<button nbTooltip="This is a tooltip" nbTooltipPlacement="top" nbTooltipStatus="info" nbButton matRipple>Info</button>
<button nbTooltip="This is a tooltip" nbTooltipPlacement="top" nbTooltipStatus="warning" nbButton matRipple>Warning</button>
</nb-card-body>
</nb-card>
</div>
</div>

View file

@ -1,31 +0,0 @@
<div class="row">
<div class="col-md-12 col-lg-12 col-xxxl-6">
<nb-card>
<nb-card-header>Window Form</nb-card-header>
<nb-card-body>
<button (click)="openWindowForm()" nbButton matRipple>Open window form</button>
<button (click)="openWindow(contentTemplate)" nbButton matRipple>Open window with template</button>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-12 col-lg-12 col-xxxl-6">
<nb-card>
<nb-card-header>Window Without Backdrop</nb-card-header>
<nb-card-body>
<button (click)="openWindow(contentTemplate)" nbButton matRipple>Open window with backdrop</button>
<button (click)="openWindowWithoutBackdrop()" nbButton matRipple>Open window without backdrop</button>
</nb-card-body>
</nb-card>
</div>
</div>
<ng-template #contentTemplate let-data>
<p>Here is the text provided via config: "{{ data.text }}"</p>
</ng-template>
<ng-template #disabledEsc>
Disabled close on escape click.
</ng-template>

View file

@ -1,45 +0,0 @@
<div class="row">
<div class="col-md-12 col-lg-6">
<nb-card>
<nb-card-header>
Eva Icons
</nb-card-header>
<nb-card-body>
<nb-icon *ngFor="let icon of evaIcons" [icon]="icon" pack="eva"></nb-icon>
</nb-card-body>
<nb-card-footer>
<a href="https://hubs.ly/H0n4_1m0" target="_blank">See all Eva Icons</a>
</nb-card-footer>
</nb-card>
</div>
<div class="col-md-12 col-lg-6">
<nb-card>
<nb-card-header>
Font awesome icons
</nb-card-header>
<nb-card-body>
<nb-icon *ngFor="let icon of icons.fontAwesome" [icon]="icon" pack="fa"></nb-icon>
<nb-icon *ngFor="let icon of icons.fontAwesomeRegular" [icon]="icon" pack="far"></nb-icon>
</nb-card-body>
<nb-card-footer>
<a href="http://fortawesome.github.io/Font-Awesome/icons/" target="_blank">
See all Font Awesome icons
</a>
</nb-card-footer>
</nb-card>
<nb-card>
<nb-card-header>
Ionicons
</nb-card-header>
<nb-card-body>
<nb-icon *ngFor="let icon of icons.ionicons" [icon]="icon" pack="ion"></nb-icon>
</nb-card-body>
<nb-card-footer>
<a href="http://ionicons.com/" target="_blank">See all ionicons</a>
</nb-card-footer>
</nb-card>
</div>
</div>

View file

@ -1,122 +0,0 @@
<div class="row">
<div class="col-md-6">
<nb-card>
<nb-card-header>
Layout Rotate Search
</nb-card-header>
<nb-card-body>
<nb-search
matRipple
[matRippleUnbounded]="true"
[matRippleCentered]="true"
[matRippleRadius]="36"
type="rotate-layout"
tag="rotate-layout"
></nb-search>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-6">
<nb-card>
<nb-card-header>
Modal Zoomin Search
</nb-card-header>
<nb-card-body>
<nb-search
matRipple
[matRippleUnbounded]="true"
[matRippleCentered]="true"
[matRippleRadius]="36"
type="modal-zoomin"
tag="modal-zoomin"
></nb-search>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-6">
<nb-card>
<nb-card-header>
Modal Move Search
</nb-card-header>
<nb-card-body>
<nb-search
matRipple
[matRippleUnbounded]="true"
[matRippleCentered]="true"
[matRippleRadius]="36"
type="modal-move"
tag="modal-move"
></nb-search>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-6">
<nb-card>
<nb-card-header>
Modal Drop Search
</nb-card-header>
<nb-card-body>
<nb-search
matRipple
[matRippleUnbounded]="true"
[matRippleCentered]="true"
[matRippleRadius]="36"
type="modal-drop"
tag="modal-drop"
></nb-search>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-6">
<nb-card>
<nb-card-header>
Modal Half Search
</nb-card-header>
<nb-card-body>
<nb-search
matRipple
[matRippleUnbounded]="true"
[matRippleCentered]="true"
[matRippleRadius]="36"
type="modal-half"
tag="modal-half"
></nb-search>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-6">
<nb-card>
<nb-card-header>
Curtain Search
</nb-card-header>
<nb-card-body>
<nb-search
matRipple
[matRippleUnbounded]="true"
[matRippleCentered]="true"
[matRippleRadius]="36"
type="curtain"
tag="curtain"
></nb-search>
</nb-card-body>
</nb-card>
</div>
<div class="col-md-6">
<nb-card>
<nb-card-header>
Column Curtain Search
</nb-card-header>
<nb-card-body>
<nb-search
matRipple
[matRippleUnbounded]="true"
[matRippleCentered]="true"
[matRippleRadius]="36"
type="column-curtain"
tag="column-curtain"
></nb-search>
</nb-card-body>
</nb-card>
</div>
</div>

View file

@ -9,7 +9,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="favicon.png">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<script defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCpVhQiwAllg1RAFaxMWSpQruuGARy0Y1k&libraries=places"></script>
</head>
<body>
<ngx-app>Loading...</ngx-app>