mirror of
https://github.com/akveo/ngx-admin.git
synced 2025-12-17 16:00:14 +01:00
icons added, sidebar classes, better fonts loader
This commit is contained in:
parent
53aa869d22
commit
b13c169995
8 changed files with 203 additions and 85 deletions
24
bower.json
Normal file
24
bower.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "angular2-webpack-starter",
|
||||
"description": "Angular 2 admin template.",
|
||||
"main": "",
|
||||
"authors": [
|
||||
"Patrick Stapleton <patrick@angularclass.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"moduleType": [
|
||||
"es6"
|
||||
],
|
||||
"homepage": "",
|
||||
"private": true,
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"dependencies": {
|
||||
"Ionicons": "ionicons#~2.0.1"
|
||||
}
|
||||
}
|
||||
|
|
@ -48,13 +48,13 @@ module.exports = {
|
|||
*
|
||||
* See: http://webpack.github.io/docs/configuration.html#resolve-extensions
|
||||
*/
|
||||
extensions: ['', '.ts', '.js'],
|
||||
extensions: ['', '.ts', '.js', '.css', '.scss'],
|
||||
|
||||
// Make sure root is src
|
||||
root: helpers.root('src'),
|
||||
|
||||
// remove other default values
|
||||
modulesDirectories: ['node_modules']
|
||||
modulesDirectories: ['node_modules', 'bower_components']
|
||||
|
||||
},
|
||||
|
||||
|
|
@ -128,15 +128,15 @@ module.exports = {
|
|||
|
||||
{
|
||||
test: /\.scss$/,
|
||||
loaders: ['raw-loader','sass-loader']
|
||||
loaders: ['raw-loader', 'sass-loader']
|
||||
},
|
||||
|
||||
{
|
||||
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff"
|
||||
test: /\.woff(2)?(\?v=.+)?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff"
|
||||
},
|
||||
|
||||
{
|
||||
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader"
|
||||
test: /\.(ttf|eot|svg)(\?v=.+)?$/, loader: "file-loader"
|
||||
},
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
"docs": "npm run typedoc -- --options typedoc.json --exclude '**/*.spec.ts' ./src/",
|
||||
"start": "npm run server:dev",
|
||||
"start:hmr": "npm run server:dev:hmr",
|
||||
"postinstall": "npm run typings -- install",
|
||||
"postinstall": "npm run typings -- install && bower install",
|
||||
"preversion": "npm run build",
|
||||
"version": "npm run build",
|
||||
"postversion": "git push && git push --tags"
|
||||
|
|
|
|||
|
|
@ -6,10 +6,13 @@ import {RouteConfig, Router} from 'angular2/router';
|
|||
|
||||
import {Pages} from './pages';
|
||||
|
||||
/*
|
||||
* App Component
|
||||
* Top Level Component
|
||||
*/
|
||||
// TODO: is it really the best place to globally require that dependency?
|
||||
require("!style!css!sass!./theme/sass/_ionicons.scss");
|
||||
|
||||
/*
|
||||
* App Component
|
||||
* Top Level Component
|
||||
*/
|
||||
@Component({
|
||||
selector: 'app',
|
||||
pipes: [ ],
|
||||
|
|
@ -31,7 +34,7 @@ import {Pages} from './pages';
|
|||
})
|
||||
@RouteConfig([
|
||||
{
|
||||
path: '/pages/...',
|
||||
path: '/...',
|
||||
name: 'Pages',
|
||||
component: Pages,
|
||||
useAsDefault: true
|
||||
|
|
|
|||
3
src/app/theme/sass/_ionicons.scss
Normal file
3
src/app/theme/sass/_ionicons.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
$ionicons-font-path: "~Ionicons/fonts";
|
||||
|
||||
@import "~Ionicons/scss/ionicons";
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import {Component, ElementRef} from 'angular2/core';
|
||||
|
||||
import {SidebarService} from './sidebar.service';
|
||||
import {Location} from 'angular2/router';
|
||||
|
||||
@Component({
|
||||
selector: 'sidebar',
|
||||
|
|
@ -11,12 +12,70 @@ import {SidebarService} from './sidebar.service';
|
|||
pipes: []
|
||||
})
|
||||
export class Sidebar {
|
||||
menuItems = [];
|
||||
menuHeight = 0;
|
||||
elementRef: ElementRef;
|
||||
location: Location;
|
||||
|
||||
constructor(el: ElementRef, private _sidebarService: SidebarService) {
|
||||
menuItems: Array<any>;
|
||||
menuHeight: number;
|
||||
isMenuCollapsed: boolean;
|
||||
|
||||
constructor(el: ElementRef, location: Location, private _sidebarService: SidebarService) {
|
||||
this.elementRef = el;
|
||||
this.location = location;
|
||||
this.menuItems = this._sidebarService.getMenuItems();
|
||||
// this.menuHeight = el.nativeElement.childNodes[0].clientHeight - 84;
|
||||
|
||||
|
||||
this.selectMenuItem();
|
||||
}
|
||||
|
||||
// TODO: is it really the best event for this kind of things?
|
||||
ngAfterViewInit() {
|
||||
// TODO: get rid of magic 84 constant
|
||||
this.menuHeight = this.elementRef.nativeElement.childNodes[0].clientHeight - 84;
|
||||
}
|
||||
|
||||
menuExpand () {
|
||||
this.isMenuCollapsed = false;
|
||||
}
|
||||
|
||||
menuCollapse () {
|
||||
this.isMenuCollapsed = true;
|
||||
}
|
||||
|
||||
toggleSubMenu ($event, item) {
|
||||
var submenu = $($event.currentTarget).next();
|
||||
|
||||
if (this.isMenuCollapsed) {
|
||||
this.menuExpand();
|
||||
if (!item.expanded) {
|
||||
setTimeout(function () {
|
||||
item.expanded = !item.expanded;
|
||||
|
||||
// TODO: incomplete
|
||||
// submenu.slideToggle();
|
||||
}, 0);
|
||||
}
|
||||
} else {
|
||||
item.expanded = !item.expanded;
|
||||
|
||||
// TODO: incomplete
|
||||
// submenu.slideToggle();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private selectMenuItem() {
|
||||
let currentPath = this.location.path();
|
||||
let isCurrent = (root) => (('#' + currentPath).indexOf(root) == 0);
|
||||
|
||||
this.menuItems.forEach(function (menu) {
|
||||
menu.selected = isCurrent(menu.root);
|
||||
menu.expanded = menu.expanded || menu.selected;
|
||||
console.log(menu);
|
||||
if (menu.subMenu) {
|
||||
menu.subMenu.forEach(function (subMenu) {
|
||||
subMenu.selected = isCurrent(subMenu.root) && !subMenu.disabled;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,17 @@
|
|||
<aside class="al-sidebar">
|
||||
<ul class="al-sidebar-list">
|
||||
<li *ngFor="#item of menuItems" class="al-sidebar-list-item"
|
||||
ngClass="{'selected': item.selected, 'with-sub-menu': item.subMenu}">
|
||||
[ngClass]="{'selected': item.selected, 'with-sub-menu': item.subMenu}">
|
||||
|
||||
<a *ngIf="item.subMenu" href="{{ item.root }}" class="al-sidebar-list-link">
|
||||
<a *ngIf="!item.subMenu" href="{{ item.root }}" class="al-sidebar-list-link">
|
||||
<i class="{{ item.icon }}"></i><span>{{ item.title }}</span>
|
||||
</a>
|
||||
|
||||
<a *ngIf="item.subMenu" ng-mouseenter="hoverItem($event, item)" (click)="toggleSubMenu($event, item)" class="al-sidebar-list-link" href>
|
||||
<i class="{{ item.icon }}"></i><span>{{ item.title }}</span>
|
||||
<b class="fa" [ngClass]="{'fa-angle-up': item.expanded, 'fa-angle-down': !item.expanded}" *ngIf="item.subMenu"></b>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<div class="sidebar-hover-elem"></div>
|
||||
|
|
|
|||
|
|
@ -3,77 +3,100 @@ import {Injectable} from 'angular2/core';
|
|||
@Injectable()
|
||||
export class SidebarService {
|
||||
|
||||
staticMenuItems = [ {
|
||||
title: 'Pages',
|
||||
icon: 'ion-document',
|
||||
subMenu: [{
|
||||
title: 'Sign In',
|
||||
root: 'auth.html',
|
||||
blank: true
|
||||
}, {
|
||||
title: 'Sign Up',
|
||||
root: 'reg.html',
|
||||
blank: true
|
||||
}, {
|
||||
title: 'User Profile',
|
||||
root: '#/profile'
|
||||
}, {
|
||||
title: '404 Page',
|
||||
root: '404.html',
|
||||
blank: true
|
||||
}]
|
||||
}, {
|
||||
title: 'Menu Level 1',
|
||||
icon: 'ion-ios-more',
|
||||
subMenu: [{
|
||||
title: 'Menu Level 1.1',
|
||||
root: '#',
|
||||
disabled: true
|
||||
}, {
|
||||
title: 'Menu Level 1.2',
|
||||
subMenu: [{
|
||||
title: 'Menu Level 1.2.1',
|
||||
root: '#',
|
||||
disabled: true
|
||||
}]
|
||||
}]
|
||||
}];
|
||||
staticMenuItems = [
|
||||
{
|
||||
title: 'Pages',
|
||||
icon: 'ion-document',
|
||||
subMenu: [
|
||||
{
|
||||
title: 'Sign In',
|
||||
root: 'auth.html',
|
||||
blank: true
|
||||
},
|
||||
{
|
||||
title: 'Sign Up',
|
||||
root: 'reg.html',
|
||||
blank: true
|
||||
},
|
||||
{
|
||||
title: 'User Profile',
|
||||
root: '#/profile'
|
||||
},
|
||||
{
|
||||
title: '404 Page',
|
||||
root: '404.html',
|
||||
blank: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Menu Level 1',
|
||||
icon: 'ion-ios-more',
|
||||
subMenu: [
|
||||
{
|
||||
title: 'Menu Level 1.1',
|
||||
root: '#',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
title: 'Menu Level 1.2',
|
||||
subMenu: [{
|
||||
title: 'Menu Level 1.2.1',
|
||||
root: '#',
|
||||
disabled: true
|
||||
}]
|
||||
}
|
||||
]
|
||||
}];
|
||||
|
||||
getMenuItems() {
|
||||
// var states = defineMenuItemStates();
|
||||
// var menuItems = states.filter(function(item) {
|
||||
// return item.level == 0;
|
||||
// });
|
||||
//
|
||||
// menuItems.forEach(function(item) {
|
||||
// var children = states.filter(function(child) {
|
||||
// return child.level == 1 && child.name.indexOf(item.name) === 0;
|
||||
// });
|
||||
// item.subMenu = children.length ? children : null;
|
||||
// });
|
||||
//
|
||||
// return menuItems.concat(staticMenuItems);
|
||||
return this.staticMenuItems;
|
||||
var states = this.defineMenuItemStates();
|
||||
var menuItems = states.filter(function(item) {
|
||||
return item.level == 0;
|
||||
});
|
||||
|
||||
menuItems.forEach(function(item) {
|
||||
var children = states.filter(function(child) {
|
||||
return child.level == 1 && child.name.indexOf(item.name) === 0;
|
||||
});
|
||||
item.subMenu = children.length ? children : null;
|
||||
});
|
||||
|
||||
return menuItems.concat(this.staticMenuItems);
|
||||
};
|
||||
|
||||
defineMenuItemStates() {
|
||||
// return $state.get()
|
||||
// .filter(function(s) {
|
||||
// return s.sidebarMeta;
|
||||
// })
|
||||
// .map(function(s) {
|
||||
// var meta = s.sidebarMeta;
|
||||
// return {
|
||||
// name: s.name,
|
||||
// title: s.title,
|
||||
// level: (s.name.match(/\./g) || []).length,
|
||||
// order: meta.order,
|
||||
// icon: meta.icon,
|
||||
// root: '#/' + s.name.replace('.', '/'),
|
||||
// };
|
||||
// })
|
||||
// .sort(function(a, b) {
|
||||
// return (a.level - b.level) * 100 + a.order - b.order;
|
||||
// });
|
||||
|
||||
// TODO mock state object
|
||||
var state = [{
|
||||
name: 'dashboard',
|
||||
title: 'Dashboard',
|
||||
selected: true,
|
||||
url: '/pages/dashboard',
|
||||
templateUrl: 'app/pages/dashboard/dashboard.html',
|
||||
sidebarMeta: {
|
||||
icon: 'ion-android-home',
|
||||
order: 0,
|
||||
}
|
||||
}];
|
||||
|
||||
return state
|
||||
.filter(function(s) {
|
||||
return s.sidebarMeta != null;
|
||||
})
|
||||
.map(function(s) {
|
||||
var meta = s.sidebarMeta;
|
||||
return {
|
||||
name: s.name,
|
||||
title: s.title,
|
||||
level: (s.name.match(/\./g) || []).length,
|
||||
order: meta.order,
|
||||
icon: meta.icon,
|
||||
root: '#/' + s.name.replace('.', '/'),
|
||||
};
|
||||
})
|
||||
.sort(function(a, b) {
|
||||
return (a.level - b.level) * 100 + a.order - b.order;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue