icons added, sidebar classes, better fonts loader

This commit is contained in:
nixa 2016-04-28 13:08:33 +03:00
parent 53aa869d22
commit b13c169995
8 changed files with 203 additions and 85 deletions

24
bower.json Normal file
View 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"
}
}

View file

@ -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']
},
@ -132,11 +132,11 @@ module.exports = {
},
{
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"
},
{

View file

@ -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"

View file

@ -6,6 +6,9 @@ import {RouteConfig, Router} from 'angular2/router';
import {Pages} from './pages';
// 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
@ -31,7 +34,7 @@ import {Pages} from './pages';
})
@RouteConfig([
{
path: '/pages/...',
path: '/...',
name: 'Pages',
component: Pages,
useAsDefault: true

View file

@ -0,0 +1,3 @@
$ionicons-font-path: "~Ionicons/fonts";
@import "~Ionicons/scss/ionicons";

View file

@ -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;
});
}
});
}
}

View file

@ -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>

View file

@ -3,77 +3,100 @@ import {Injectable} from 'angular2/core';
@Injectable()
export class SidebarService {
staticMenuItems = [ {
staticMenuItems = [
{
title: 'Pages',
icon: 'ion-document',
subMenu: [{
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: [{
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;
});
}
}