mirror of
https://github.com/akveo/ngx-admin.git
synced 2026-01-06 09:38:50 +01:00
Merge branch 'master' into develop/bacard
This commit is contained in:
commit
cb5739711c
68 changed files with 2271 additions and 58 deletions
25
src/app/theme/contentTop/contentTop.component.ts
Normal file
25
src/app/theme/contentTop/contentTop.component.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import {Component, ViewEncapsulation} from 'angular2/core';
|
||||
|
||||
import {ThemeGlobal} from "../theme.global";
|
||||
import {Subscription} from "rxjs/Subscription";
|
||||
|
||||
@Component({
|
||||
selector: 'content-top',
|
||||
styles: [require('./contentTop.scss')],
|
||||
template: require('./contentTop.html'),
|
||||
})
|
||||
export class ContentTop {
|
||||
activePageTitle = '';
|
||||
private _themeGlobalSubscription:Subscription;
|
||||
|
||||
constructor(private _themeGlobal:ThemeGlobal) {
|
||||
this._themeGlobalSubscription = this._themeGlobal.getDataStream().subscribe((data) => {
|
||||
this.activePageTitle = data['menu.activeLink'] != null ? data['menu.activeLink'].title : this.activePageTitle;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
// prevent memory leak when component destroyed
|
||||
this._themeGlobalSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
9
src/app/theme/contentTop/contentTop.html
Normal file
9
src/app/theme/contentTop/contentTop.html
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<div class="content-top clearfix">
|
||||
<h1 class="al-title">{{ activePageTitle }}</h1>
|
||||
|
||||
<ul class="breadcrumb al-breadcrumb">
|
||||
<li>
|
||||
<a href="#/dashboard">Home</a></li>
|
||||
<li>{{ activePageTitle }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
40
src/app/theme/contentTop/contentTop.scss
Normal file
40
src/app/theme/contentTop/contentTop.scss
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
@import '../sass/conf/conf';
|
||||
|
||||
.content-top {
|
||||
padding-top: 13px;
|
||||
padding-bottom: 27px;
|
||||
}
|
||||
|
||||
h1.al-title {
|
||||
font-weight: $font-bold;
|
||||
color: #ffffff;
|
||||
float: left;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 24px;
|
||||
text-transform: uppercase;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.al-breadcrumb {
|
||||
background: none;
|
||||
color: #ffffff;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
float: right;
|
||||
padding-top: 11px;
|
||||
li {
|
||||
font-size: 18px;
|
||||
font-weight: $font-light;
|
||||
}
|
||||
}
|
||||
|
||||
.al-look {
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
padding-top: 10px;
|
||||
> a {
|
||||
font-size: 19px;
|
||||
}
|
||||
}
|
||||
1
src/app/theme/contentTop/index.ts
Normal file
1
src/app/theme/contentTop/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from './contentTop.component';
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
export * from './pageTop';
|
||||
export * from './msgCenter';
|
||||
export * from './sidebar';
|
||||
export * from './contentTop';
|
||||
export * from './baCard';
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import {Component, ViewEncapsulation} from 'angular2/core';
|
||||
import {Subscription} from 'rxjs/Subscription';
|
||||
|
||||
import {MsgCenter} from '../msgCenter';
|
||||
import {ProfilePicturePipe} from '../pipes/image/profile-picture.pipe';
|
||||
import {ScrollPosition} from '../directives/scrollPosition.directive';
|
||||
import {SidebarStateService} from '../sidebar/sidebarState.service'
|
||||
import {ThemeGlobal} from "../theme.global";
|
||||
|
||||
@Component({
|
||||
selector: 'page-top',
|
||||
|
|
@ -17,15 +16,14 @@ export class PageTop {
|
|||
isScrolled:Boolean = false;
|
||||
isMenuCollapsed:boolean = false;
|
||||
|
||||
private _sidebarStateSubscription:Subscription;
|
||||
|
||||
constructor(private _sidebarStateService:SidebarStateService) {
|
||||
this._sidebarStateSubscription = this._sidebarStateService.getStateStream().subscribe((isCollapsed) => this.isMenuCollapsed = isCollapsed);
|
||||
constructor(private _themeGlobal:ThemeGlobal) {
|
||||
|
||||
}
|
||||
|
||||
toggleMenu() {
|
||||
this.isMenuCollapsed = !this.isMenuCollapsed;
|
||||
this._sidebarStateService.stateChanged(this.isMenuCollapsed);
|
||||
this._themeGlobal.setData('menu.isCollapsed', this.isMenuCollapsed);
|
||||
}
|
||||
|
||||
scrolledChanged(isScrolled) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import {Router} from 'angular2/router';
|
|||
|
||||
import {layoutSizes} from '../theme.constants';
|
||||
import {SidebarService} from './sidebar.service';
|
||||
import {SidebarStateService} from './sidebarState.service';
|
||||
import {ThemeGlobal} from "../theme.global";
|
||||
|
||||
@Component({
|
||||
selector: 'sidebar',
|
||||
|
|
@ -31,7 +31,7 @@ export class Sidebar {
|
|||
constructor(private _elementRef:ElementRef,
|
||||
private _router:Router,
|
||||
private _sidebarService:SidebarService,
|
||||
private _sidebarStateService:SidebarStateService) {
|
||||
private _themeGlobal:ThemeGlobal) {
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ export class Sidebar {
|
|||
|
||||
menuCollapseStateChange(isCollapsed) {
|
||||
this.isMenuCollapsed = isCollapsed;
|
||||
this._sidebarStateService.stateChanged(this.isMenuCollapsed);
|
||||
this._themeGlobal.setData('menu.isCollapsed', this.isMenuCollapsed);
|
||||
}
|
||||
|
||||
hoverItem($event) {
|
||||
|
|
@ -99,19 +99,28 @@ export class Sidebar {
|
|||
return false;
|
||||
}
|
||||
|
||||
// TODO: there is a bug in the router thus all child routers are considered as active
|
||||
private selectMenuItem() {
|
||||
let isCurrent = (instruction) => (instruction ? this._router.isRouteActive(this._router.generate([instruction])) : false);
|
||||
let currentMenu;
|
||||
|
||||
let isCurrent = (instructions) => (instructions.filter(i => typeof i !== 'undefined').length > 0 ? this._router.isRouteActive(this._router.generate(instructions)) : false);
|
||||
let assignCurrent = (menu) => (menu.selected ? currentMenu = menu : null);
|
||||
|
||||
this.menuItems.forEach(function (menu: any) {
|
||||
|
||||
menu.selected = isCurrent(menu.name);
|
||||
menu.selected = isCurrent([menu.name]);
|
||||
menu.expanded = menu.expanded || menu.selected;
|
||||
assignCurrent(menu);
|
||||
|
||||
if (menu.subMenu) {
|
||||
menu.subMenu.forEach(function (subMenu) {
|
||||
subMenu.selected = isCurrent(subMenu.name) && !subMenu.disabled;
|
||||
subMenu.selected = isCurrent([menu.name, subMenu.name]) && !subMenu.disabled;
|
||||
assignCurrent(menu);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// notifies all subscribers
|
||||
this._themeGlobal.setData('menu.activeLink', currentMenu);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@
|
|||
[ngClass]="{expanded: subitem.expanded, 'slide-right': subitem.slideRight}">
|
||||
<li *ngFor="#subSubitem of subitem.subMenu" (mouseenter)="hoverItem($event, item)"
|
||||
[ngClass]="{selected: subitem.selected}">
|
||||
<a (mouseenter)="hoverItem($event, item)" [routerLink]="[subSubitem.name]">
|
||||
<a (mouseenter)="hoverItem($event, item)" [routerLink]="[item.name, subitem.name, subSubitem.name]">
|
||||
{{ subSubitem.title }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<a *ngIf="!subitem.subMenu" [routerLink]="[subitem.name]"
|
||||
<a *ngIf="!subitem.subMenu" [routerLink]="[item.name, subitem.name]"
|
||||
(mouseenter)="hoverItem($event, item)" target="{{subitem.blank ? '_blank' : '_self'}}">
|
||||
{{ subitem.title}}
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,57 @@ export class SidebarService {
|
|||
icon: 'ion-android-laptop',
|
||||
selected: false,
|
||||
expanded: false,
|
||||
order: 200
|
||||
order: 200,
|
||||
subMenu: [
|
||||
{
|
||||
title: 'Typography',
|
||||
name: 'Typography',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Maps',
|
||||
name: 'Maps',
|
||||
icon: 'ion-ios-location-outline',
|
||||
selected: false,
|
||||
expanded: false,
|
||||
order: 300,
|
||||
subMenu: [
|
||||
{
|
||||
title: 'Google Maps',
|
||||
name: 'GoogleMaps',
|
||||
},
|
||||
{
|
||||
title: 'Leaflet Maps',
|
||||
name: 'LeafletMaps',
|
||||
},
|
||||
{
|
||||
title: 'Bubble Maps',
|
||||
name: 'BubbleMaps',
|
||||
},
|
||||
{
|
||||
title: 'Line Maps',
|
||||
name: 'LineMaps',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Charts',
|
||||
name: 'Charts',
|
||||
icon: 'ion-stats-bars',
|
||||
selected: false,
|
||||
expanded: false,
|
||||
order: 400,
|
||||
subMenu: [
|
||||
{
|
||||
title: 'Chart Js',
|
||||
name: 'ChartJs',
|
||||
},
|
||||
{
|
||||
title: 'ChartistJs',
|
||||
name: 'ChartistJs',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Pages',
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
import {Injectable} from 'angular2/core'
|
||||
import {Subject} from 'rxjs/Subject';
|
||||
|
||||
@Injectable()
|
||||
export class SidebarStateService {
|
||||
|
||||
// Observable string sources
|
||||
private _isCollapsed = new Subject<boolean>();
|
||||
|
||||
// Observable string streams
|
||||
isCollapsedStream$ = this._isCollapsed.asObservable();
|
||||
|
||||
// Service message commands
|
||||
stateChanged(isCollapsed:boolean) {
|
||||
this._isCollapsed.next(isCollapsed)
|
||||
}
|
||||
|
||||
getStateStream() {
|
||||
return this.isCollapsedStream$;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,133 @@
|
|||
export const IMAGES_ROOT = 'assets/img/';
|
||||
|
||||
export let shade = (color, weight) => {
|
||||
return mix('#000000', color, weight);
|
||||
};
|
||||
|
||||
export let tint = (color, weight) => {
|
||||
return mix('#ffffff', color, weight);
|
||||
};
|
||||
|
||||
//SASS mix function
|
||||
export let mix = (color1, color2, weight) => {
|
||||
// convert a decimal value to hex
|
||||
function d2h(d) {
|
||||
return d.toString(16);
|
||||
}
|
||||
// convert a hex value to decimal
|
||||
function h2d(h) {
|
||||
return parseInt(h, 16);
|
||||
}
|
||||
|
||||
let result = "#";
|
||||
for(let i = 1; i < 7; i += 2) {
|
||||
let color1Part = h2d(color1.substr(i, 2));
|
||||
let color2Part = h2d(color2.substr(i, 2));
|
||||
let resultPart = d2h(Math.floor(color2Part + (color1Part - color2Part) * (weight / 100.0)));
|
||||
result += ('0' + resultPart).slice(-2);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
export let hexToRgbA = (hex, alpha) => {
|
||||
var c;
|
||||
if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
|
||||
c= hex.substring(1).split('');
|
||||
if(c.length== 3){
|
||||
c= [c[0], c[0], c[1], c[1], c[2], c[2]];
|
||||
}
|
||||
c= '0x'+c.join('');
|
||||
return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+',' + alpha + ')';
|
||||
}
|
||||
throw new Error('Bad Hex');
|
||||
};
|
||||
|
||||
export const layoutSizes = {
|
||||
resWidthCollapseSidebar: 1200,
|
||||
resWidthHideSidebar: 500
|
||||
};
|
||||
|
||||
export const colorScheme = {
|
||||
primary: '#209e91',
|
||||
info: '#2dacd1',
|
||||
success: '#90b900',
|
||||
warning: '#dfb81c',
|
||||
danger: '#e85656',
|
||||
};
|
||||
|
||||
export const bgColorPalette = {
|
||||
blueStone: '#005562',
|
||||
surfieGreen: '#0e8174',
|
||||
silverTree: '#6eba8c',
|
||||
gossip: '#b9f2a1',
|
||||
white: '#ffffff',
|
||||
};
|
||||
|
||||
export const layoutColors = {
|
||||
primary: colorScheme.primary,
|
||||
info: colorScheme.info,
|
||||
success: colorScheme.success,
|
||||
warning: colorScheme.warning,
|
||||
danger: colorScheme.danger,
|
||||
|
||||
primaryLight: tint(colorScheme.primary, 30),
|
||||
infoLight: tint(colorScheme.info, 30),
|
||||
successLight: tint(colorScheme.success, 30),
|
||||
warningLight: tint(colorScheme.warning, 30),
|
||||
dangerLight: tint(colorScheme.danger, 30),
|
||||
|
||||
primaryDark: shade(colorScheme.primary, 15),
|
||||
infoDark: shade(colorScheme.info, 15),
|
||||
successDark: shade(colorScheme.success, 15),
|
||||
warningDark: shade(colorScheme.warning, 15),
|
||||
dangerDark: shade(colorScheme.danger, 15),
|
||||
|
||||
primaryBg: tint(colorScheme.primary, 20),
|
||||
infoBg: tint(colorScheme.info, 20),
|
||||
successBg: tint(colorScheme.success, 20),
|
||||
warningBg: tint(colorScheme.warning, 20),
|
||||
dangerBg: tint(colorScheme.danger, 20),
|
||||
|
||||
default: '#ffffff',
|
||||
defaultText: '#ffffff',
|
||||
|
||||
bgColorPalette: {
|
||||
blueStone: bgColorPalette.blueStone,
|
||||
surfieGreen: bgColorPalette.surfieGreen,
|
||||
silverTree: bgColorPalette.silverTree,
|
||||
gossip: bgColorPalette.gossip,
|
||||
white: bgColorPalette.white,
|
||||
|
||||
blueStoneDark: shade(bgColorPalette.blueStone, 15),
|
||||
surfieGreenDark: shade(bgColorPalette.surfieGreen, 15),
|
||||
silverTreeDark: shade(bgColorPalette.silverTree, 15),
|
||||
gossipDark: shade(bgColorPalette.gossip, 15),
|
||||
whiteDark: shade(bgColorPalette.white, 5),
|
||||
}
|
||||
};
|
||||
|
||||
let _chartColors = [];
|
||||
let _colorsForChart = [ layoutColors.primary, layoutColors.danger, layoutColors.warning, layoutColors.success, layoutColors.info, layoutColors.default, layoutColors.primaryDark, layoutColors.successDark, layoutColors.warningLight, layoutColors.successLight, layoutColors.successBg];
|
||||
|
||||
_colorsForChart.forEach((color) => {
|
||||
_chartColors.push({
|
||||
fillColor: hexToRgbA(color, 0.2),
|
||||
strokeColor: hexToRgbA(color, 1),
|
||||
pointColor: hexToRgbA(color, 1),
|
||||
pointStrokeColor: color,
|
||||
pointHighlightFill: color,
|
||||
pointHighlightStroke: hexToRgbA(color, 0.8),
|
||||
color: hexToRgbA(color, 1),
|
||||
highlight: hexToRgbA(color, 0.8)
|
||||
});
|
||||
});
|
||||
export const chartColors = _chartColors;
|
||||
|
||||
export const layoutPaths = {
|
||||
images: {
|
||||
root: IMAGES_ROOT,
|
||||
profile: IMAGES_ROOT + 'app/profile/',
|
||||
amMap: 'assets/img/theme/vendor/ammap//dist/ammap/images/',
|
||||
amMap: 'assets/img/theme/vendor/ammap/',
|
||||
amChart: 'assets/img/theme/vendor/amcharts/dist/amcharts/images/'
|
||||
}
|
||||
};
|
||||
|
|
|
|||
24
src/app/theme/theme.global.ts
Normal file
24
src/app/theme/theme.global.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import {Injectable} from 'angular2/core'
|
||||
import {Subject} from 'rxjs/Subject';
|
||||
|
||||
@Injectable()
|
||||
export class ThemeGlobal {
|
||||
private _data = new Subject<Object>();
|
||||
|
||||
dataStream$ = this._data.asObservable();
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
setData(key, value) {
|
||||
let current = this._data[key];
|
||||
if (current != value) {
|
||||
this._data[key] = value;
|
||||
this._data.next(this._data);
|
||||
}
|
||||
}
|
||||
|
||||
getDataStream() {
|
||||
return this.dataStream$;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue