Making navigation better

This commit is contained in:
mustafahlvc 2017-07-09 13:38:38 +03:00
parent e98e37402a
commit b7ef64154d
5 changed files with 519 additions and 459 deletions

View File

@ -1,5 +1,6 @@
import {Component, HostBinding, HostListener, Input, OnInit} from '@angular/core'; import {Component, HostBinding, Input, OnInit} from '@angular/core';
import {NavigationService} from '../navigation.service'; import {NavigationService} from '../navigation.service';
import {NavigationEnd, Router} from '@angular/router';
@Component({ @Component({
selector : 'fuse-nav-collapse', selector : 'fuse-nav-collapse',
@ -10,36 +11,127 @@ export class NavCollapseComponent implements OnInit
{ {
@Input() item: any; @Input() item: any;
@HostBinding('class') classes = 'nav-collapse nav-item'; @HostBinding('class') classes = 'nav-collapse nav-item';
@HostBinding('class.open') public isOpen = false; @HostBinding('class.open') private isOpen = false;
constructor(private navigationService: NavigationService) constructor(private navigationService: NavigationService, private router: Router)
{ {
this.navigationService.navItemClicked.subscribe( /**
(instance) => * When navigation changed
*/
router.events.subscribe(
(event) =>
{ {
// console.warn('navItemClicked', instance); if ( event instanceof NavigationEnd )
if ( !instance.includes(this.item.url) && this.isOpen )
{ {
this.isOpen = !this.isOpen; /**
* Check if the url is child of the collapse
*/
if ( this.isUrlInChildren(this.item, event.urlAfterRedirects) )
{
this.expand();
}
else
{
this.collapse();
}
} }
console.warn(this.item.url, instance); }
if ( instance.includes(this.item.url) && !this.isOpen ) );
/**
* Whenever a navigaiton collapse item toggled
*/
this.navigationService.onNavCollapseToggled.subscribe(
(clickedItem) =>
{
if ( clickedItem.children )
{ {
this.isOpen = !this.isOpen; /**
* if clicked collapse is child of this collapse
* return
*/
if ( this.item.children.indexOf(clickedItem) !== -1 )
{
return;
}
/**
* If collapsed item is not related with this collapse
* collapse
*/
if ( this.item !== clickedItem )
{
this.collapse();
}
} }
} }
); );
} }
toggleOpen(event) /**
* Toggle Collapse
* @param ev
*/
toggleOpen(ev)
{ {
event.preventDefault(); ev.preventDefault();
this.isOpen = !this.isOpen; this.isOpen = !this.isOpen;
this.navigationService.navItemClicked.emit(this.item.url); // this.navigationService.onNavItemClicked.emit(this.item);
this.navigationService.onNavCollapseToggled.emit(this.item);
console.log('toggleOpen'); console.log('toggleOpen');
} }
/**
* Expand
*/
expand()
{
if ( this.isOpen )
{
return;
}
this.isOpen = true;
}
/**
* Collapse
*/
collapse()
{
if ( !this.isOpen )
{
return;
}
this.isOpen = false;
}
/**
* Checking the url is in children
* @param arr
* @param url
* @returns {any}
*/
isUrlInChildren(arr, url)
{
if ( !arr.children )
{
return false;
}
for ( let i = 0; i < arr.children.length; i++ )
{
if ( arr.children[i].children )
{
return this.isUrlInChildren(arr.children[i], url)
}
else
{
if ( arr.children[i].url === url )
{
return true;
}
}
}
return false;
}
ngOnInit() ngOnInit()
{ {

View File

@ -1,6 +1,5 @@
<a class="nav-link" md-ripple <a class="nav-link" md-ripple
[routerLink]="[item.url]" routerLinkActive="active" [routerLink]="[item.url]" routerLinkActive="active">
(click)="onClick()">
<md-icon *ngIf="item.icon">{{item.icon}}</md-icon> <md-icon *ngIf="item.icon">{{item.icon}}</md-icon>
<span>{{item.title}}</span> <span>{{item.title}}</span>
</a> </a>

View File

@ -1,5 +1,4 @@
import {Component, EventEmitter, HostBinding, Input, OnInit, Output, ViewEncapsulation} from '@angular/core'; import {Component, HostBinding, Input, OnInit} from '@angular/core';
import {NavigationService} from '../navigation.service';
@Component({ @Component({
selector : 'fuse-nav-item', selector : 'fuse-nav-item',
@ -11,17 +10,11 @@ export class NavItemComponent implements OnInit
@HostBinding('class') classes = 'nav-item'; @HostBinding('class') classes = 'nav-item';
@Input() item: any; @Input() item: any;
constructor(private navigationService: NavigationService) constructor()
{ {
} }
ngOnInit() ngOnInit()
{ {
} }
onClick()
{
console.log('clicked');
this.navigationService.navItemClicked.emit(this.item.url);
}
} }

View File

@ -1,415 +1,410 @@
export class FuseNavigation export class FuseNavigation
{ {
items = [ public items: any[];
{
'title': 'APPS', constructor()
'type' : 'subheader' {
}, this.items = [
{ {
'title' : 'Dashboards', 'title': 'APPS',
'type' : 'nav-collapse', 'type' : 'subheader'
'icon' : 'dashboard', },
'url' : '/apps/dashboards', {
'children': [ 'title' : 'Dashboards',
{ 'type' : 'nav-collapse',
'type' : 'nav-item', 'icon' : 'dashboard',
'title': 'Project', 'children': [
'url' : '/apps/dashboards/project' {
}, 'type' : 'nav-item',
{ 'title': 'Project',
'type' : 'nav-item', 'url' : '/apps/dashboards/project'
'title': 'Server', },
'url' : '/apps/dashboards/server' {
} 'type' : 'nav-item',
] 'title': 'Server',
}, 'url' : '/apps/dashboards/server'
{ }
'title': 'Calendar', ]
'type' : 'nav-item', },
'icon' : 'today', {
'url' : '/apps/calendar' 'title': 'Calendar',
}, 'type' : 'nav-item',
{ 'icon' : 'today',
'title' : 'Ecommerce', 'url' : '/apps/calendar'
'type' : 'nav-collapse', },
'icon' : 'shopping_cart', {
'url' : '/apps/e-commerce', 'title' : 'Ecommerce',
'children': [ 'type' : 'nav-collapse',
{ 'icon' : 'shopping_cart',
'title': 'Products', 'children': [
'type' : 'nav-item', {
'url' : '/apps/e-commerce/products' 'title': 'Products',
}, 'type' : 'nav-item',
{ 'url' : '/apps/e-commerce/products'
'title': 'Product', },
'type' : 'nav-item', {
'url' : '/apps/e-commerce/product' 'title': 'Product',
}, 'type' : 'nav-item',
{ 'url' : '/apps/e-commerce/product'
'title': 'Orders', },
'type' : 'nav-item', {
'url' : '/apps/e-commerce/orders' 'title': 'Orders',
} 'type' : 'nav-item',
] 'url' : '/apps/e-commerce/orders'
}, }
{ ]
'title': 'Mail', },
'type' : 'nav-item', {
'icon' : 'email', 'title': 'Mail',
'url' : '/apps/mail' 'type' : 'nav-item',
}, 'icon' : 'email',
{ 'url' : '/apps/mail'
'title': 'Chat', },
'type' : 'nav-item', {
'icon' : 'chat', 'title': 'Chat',
'url' : '/apps/chat' 'type' : 'nav-item',
}, 'icon' : 'chat',
{ 'url' : '/apps/chat'
'title': 'File Manager', },
'type' : 'nav-item', {
'icon' : 'folder', 'title': 'File Manager',
'url' : '/apps/file-manager' 'type' : 'nav-item',
}, 'icon' : 'folder',
{ 'url' : '/apps/file-manager'
'title': 'Contacts', },
'type' : 'nav-item', {
'icon' : 'account_box', 'title': 'Contacts',
'url' : '/apps/contacts' 'type' : 'nav-item',
}, 'icon' : 'account_box',
{ 'url' : '/apps/contacts'
'title': 'To-Do', },
'type' : 'nav-item', {
'icon' : 'checkbox_cricle', 'title': 'To-Do',
'url' : '/apps/todo' 'type' : 'nav-item',
}, 'icon' : 'checkbox_cricle',
{ 'url' : '/apps/todo'
'title': 'PAGES', },
'type' : 'subheader' {
}, 'title': 'PAGES',
{ 'type' : 'subheader'
'title' : 'Authentication', },
'type' : 'nav-collapse', {
'icon' : 'lock', 'title' : 'Authentication',
'url' : '/pages/auth', 'type' : 'nav-collapse',
'children': [ 'icon' : 'lock',
{ 'children': [
'title': 'Login', {
'type' : 'nav-item', 'title': 'Login',
'url' : '/pages/auth/login' 'type' : 'nav-item',
}, 'url' : '/pages/auth/login'
{ },
'title': 'Login v2', {
'type' : 'nav-item', 'title': 'Login v2',
'url' : '/pages/auth/login-v2' 'type' : 'nav-item',
}, 'url' : '/pages/auth/login-v2'
{ },
'title': 'Register', {
'type' : 'nav-item', 'title': 'Register',
'url' : '/pages/auth/register' 'type' : 'nav-item',
}, 'url' : '/pages/auth/register'
{ },
'title': 'Register v2', {
'type' : 'nav-item', 'title': 'Register v2',
'url' : '/pages/auth/register-v2' 'type' : 'nav-item',
}, 'url' : '/pages/auth/register-v2'
{ },
'title': 'Forgot Password', {
'type' : 'nav-item', 'title': 'Forgot Password',
'url' : '/pages/auth/forgot-password' 'type' : 'nav-item',
}, 'url' : '/pages/auth/forgot-password'
{ },
'title': 'Reset Password', {
'type' : 'nav-item', 'title': 'Reset Password',
'url' : '/pages/auth/reset-password' 'type' : 'nav-item',
}, 'url' : '/pages/auth/reset-password'
{ },
'title': 'Lock Screen', {
'type' : 'nav-item', 'title': 'Lock Screen',
'url' : '/pages/auth/lock-screen' 'type' : 'nav-item',
} 'url' : '/pages/auth/lock-screen'
] }
}, ]
{ },
'title': 'Coming Soon', {
'type' : 'nav-item', 'title': 'Coming Soon',
'icon' : 'alarm', 'type' : 'nav-item',
'url' : '/pages/coming-soon' 'icon' : 'alarm',
}, 'url' : '/pages/coming-soon'
{ },
'title' : 'Errors', {
'type' : 'nav-collapse', 'title' : 'Errors',
'icon' : 'error', 'type' : 'nav-collapse',
'url' : '/pages/errors', 'icon' : 'error',
'children': [ 'children': [
{ {
'title': '404', 'title': '404',
'type' : 'nav-item', 'type' : 'nav-item',
'url' : '/pages/errors/404' 'url' : '/pages/errors/404'
}, },
{ {
'title': '500', 'title': '500',
'type' : 'nav-item', 'type' : 'nav-item',
'url' : '/pages/errors/500' 'url' : '/pages/errors/500'
} }
] ]
}, },
{ {
'title': 'Maintenance', 'title': 'Maintenance',
'type' : 'nav-item', 'type' : 'nav-item',
'icon' : 'build', 'icon' : 'build',
'url' : '/pages/maintenance' 'url' : '/pages/maintenance'
}, },
{ {
'title': 'Profile', 'title': 'Profile',
'type' : 'nav-item', 'type' : 'nav-item',
'icon' : 'account', 'icon' : 'account',
'url' : '/pages/profile' 'url' : '/pages/profile'
}, },
{ {
'title': 'Search', 'title': 'Search',
'type' : 'nav-item', 'type' : 'nav-item',
'icon' : 'search', 'icon' : 'search',
'url' : '/pages/search' 'url' : '/pages/search'
}, },
{ {
'title': 'USER INTERFACE', 'title': 'USER INTERFACE',
'type' : 'subheader' 'type' : 'subheader'
}, },
{ {
'title' : 'Elements', 'title' : 'Elements',
'type' : 'nav-collapse', 'type' : 'nav-collapse',
'icon' : 'layers', 'icon' : 'layers',
'url' : '/user-interface/elements', 'children': [
'children': [ {
{ 'title': 'Alerts',
'title': 'Alerts', 'type' : 'nav-item',
'type' : 'nav-item', 'url' : '/user-interface/elements/alerts'
'url' : '/user-interface/elements/alerts' },
}, {
{ 'title': 'Badges',
'title': 'Badges', 'type' : 'nav-item',
'type' : 'nav-item', 'url' : '/user-interface/elements/badges'
'url' : '/user-interface/elements/badges' },
}, {
{ 'title': 'Breadcrumb',
'title': 'Breadcrumb', 'type' : 'nav-item',
'type' : 'nav-item', 'url' : '/user-interface/elements/breadcrumb'
'url' : '/user-interface/elements/breadcrumb' },
}, {
{ 'title': 'Buttons',
'title': 'Buttons', 'type' : 'nav-item',
'type' : 'nav-item', 'url' : '/user-interface/elements/buttons'
'url' : '/user-interface/elements/buttons' },
}, {
{ 'title': 'Button Group',
'title': 'Button Group', 'type' : 'nav-item',
'type' : 'nav-item', 'url' : '/user-interface/elements/button-group'
'url' : '/user-interface/elements/button-group' },
}, {
{ 'title': 'Cards',
'title': 'Cards', 'type' : 'nav-item',
'type' : 'nav-item', 'url' : '/user-interface/elements/cards'
'url' : '/user-interface/elements/cards' },
}, {
{ 'title': 'Dropdowns',
'title': 'Dropdowns', 'type' : 'nav-item',
'type' : 'nav-item', 'url' : '/user-interface/elements/dropdowns'
'url' : '/user-interface/elements/dropdowns' },
}, {
{ 'title': 'Forms',
'title': 'Forms', 'type' : 'nav-item',
'type' : 'nav-item', 'url' : '/user-interface/elements/forms'
'url' : '/user-interface/elements/forms' },
}, {
{ 'title': 'Input Group',
'title': 'Input Group', 'type' : 'nav-item',
'type' : 'nav-item', 'url' : '/user-interface/elements/input-group'
'url' : '/user-interface/elements/input-group' },
}, {
{ 'title': 'Jumbotron',
'title': 'Jumbotron', 'type' : 'nav-item',
'type' : 'nav-item', 'url' : '/user-interface/elements/jumbotron'
'url' : '/user-interface/elements/jumbotron' },
}, {
{ 'title': 'List Group',
'title': 'List Group', 'type' : 'nav-item',
'type' : 'nav-item', 'url' : '/user-interface/elements/list-group'
'url' : '/user-interface/elements/list-group' },
}, {
{ 'title': 'Navs',
'title': 'Navs', 'type' : 'nav-item',
'type' : 'nav-item', 'url' : '/user-interface/elements/navs'
'url' : '/user-interface/elements/navs' },
}, {
{ 'title': 'Navbar',
'title': 'Navbar', 'type' : 'nav-item',
'type' : 'nav-item', 'url' : '/user-interface/elements/navbar'
'url' : '/user-interface/elements/navbar' },
}, {
{ 'title': 'Pagination',
'title': 'Pagination', 'type' : 'nav-item',
'type' : 'nav-item', 'url' : '/user-interface/elements/pagination'
'url' : '/user-interface/elements/pagination' },
}, {
{ 'title': 'Progress',
'title': 'Progress', 'type' : 'nav-item',
'type' : 'nav-item', 'url' : '/user-interface/elements/progress'
'url' : '/user-interface/elements/progress' }
} ]
] },
}, {
{ 'title' : 'Tables',
'title' : 'Tables', 'type' : 'nav-collapse',
'type' : 'nav-collapse', 'icon' : 'border_all',
'icon' : 'border_all', 'children': [
'url' : '/user-interface/tables', {
'children': [ 'title': 'Simple Table',
{ 'type' : 'nav-item',
'title': 'Simple Table', 'url' : '/user-interface/tables/simple-table'
'type' : 'nav-item', },
'url' : '/user-interface/tables/simple-table' {
}, 'title': 'Data Table',
{ 'type' : 'nav-item',
'title': 'Data Table', 'url' : '/user-interface/tables/data-table'
'type' : 'nav-item', }
'url' : '/user-interface/tables/data-table' ]
} },
] {
}, 'title' : 'Page Layouts',
{ 'type' : 'nav-collapse',
'title' : 'Page Layouts', 'icon' : 'view_quilt',
'type' : 'nav-collapse', 'children': [
'icon' : 'view_quilt', {
'url' : 'page-layouts', 'title' : 'Carded',
'children': [ 'type' : 'nav-collapse',
{ 'children': [
'title' : 'Carded', {
'type' : 'nav-collapse', 'title': 'Full Width',
'url' : '/user-interface/page-layouts/carded', 'type' : 'nav-item',
'children': [ 'url' : '/user-interface/page-layouts/carded/full-width'
{ },
'title': 'Full Width', {
'type' : 'nav-item', 'title': 'Left Sidebar',
'url' : '/user-interface/page-layouts/carded/full-width' 'type' : 'nav-item',
}, 'url' : '/user-interface/page-layouts/carded/left-sidebar'
{ },
'title': 'Left Sidebar', {
'type' : 'nav-item', 'title': 'Right Sidebar',
'url' : '/user-interface/page-layouts/carded/left-sidebar' 'type' : 'nav-item',
}, 'url' : '/user-interface/page-layouts/carded/right-sidebar'
{ }
'title': 'Right Sidebar', ]
'type' : 'nav-item', },
'url' : '/user-interface/page-layouts/carded/right-sidebar' {
} 'title' : 'Simple',
] 'type' : 'nav-collapse',
}, 'children': [
{ {
'title' : 'Simple', 'title': 'Full Width',
'type' : 'nav-collapse', 'type' : 'nav-item',
'url' : '/user-interface/page-layouts/simple', 'url' : '/user-interface/page-layouts/simple/full-width'
'children': [ },
{ {
'title': 'Full Width', 'title': 'Left Sidebar',
'type' : 'nav-item', 'type' : 'nav-item',
'url' : '/user-interface/page-layouts/simple/full-width' 'url' : '/user-interface/page-layouts/simple/left-sidebar'
}, },
{ {
'title': 'Left Sidebar', 'title': 'Left Sidebar Inner',
'type' : 'nav-item', 'type' : 'nav-item',
'url' : '/user-interface/page-layouts/simple/left-sidebar' 'url' : '/user-interface/page-layouts/simple/left-sidebar-inner'
}, },
{ {
'title': 'Left Sidebar Inner', 'title': 'Left Sidebar Floating',
'type' : 'nav-item', 'type' : 'nav-item',
'url' : '/user-interface/page-layouts/simple/left-sidebar-inner' 'url' : '/user-interface/page-layouts/simple/left-sidebar-floating'
}, },
{ {
'title': 'Left Sidebar Floating', 'title': 'Right Sidebar',
'type' : 'nav-item', 'type' : 'nav-item',
'url' : '/user-interface/page-layouts/simple/left-sidebar-floating' 'url' : '/user-interface/page-layouts/simple/right-sidebar'
}, },
{ {
'title': 'Right Sidebar', 'title': 'Right Sidebar Inner',
'type' : 'nav-item', 'type' : 'nav-item',
'url' : '/user-interface/page-layouts/simple/right-sidebar' 'url' : '/user-interface/page-layouts/simple/sidebar-inner'
}, },
{ {
'title': 'Right Sidebar Inner', 'title': 'Right Sidebar Floating',
'type' : 'nav-item', 'type' : 'nav-item',
'url' : '/user-interface/page-layouts/simple/sidebar-inner' 'url' : '/user-interface/page-layouts/simple/right-sidebar-floating'
}, },
{ {
'title': 'Right Sidebar Floating', 'title': 'Tabbed',
'type' : 'nav-item', 'type' : 'nav-item',
'url' : '/user-interface/page-layouts/simple/right-sidebar-floating' 'url' : '/user-interface/page-layouts/simple/tabbed'
}, }
{ ]
'title': 'Tabbed', },
'type' : 'nav-item', {
'url' : '/user-interface/page-layouts/simple/tabbed' 'title': 'Blank',
} 'type' : 'nav-item',
] 'url' : '/user-interface/page-layouts/blank'
}, }
{ ]
'title': 'Blank', },
'type' : 'nav-item', {
'url' : '/user-interface/page-layouts/blank' 'title': 'Colors',
} 'type' : 'nav-item',
] 'icon' : 'color_lens',
}, 'url' : '/user-interface/colors'
{ },
'title': 'Colors', {
'type' : 'nav-item', 'title': 'COMPONENTS',
'icon' : 'color_lens', 'type' : 'subheader'
'url' : '/user-interface/colors' },
}, {
{ 'title' : 'Charts',
'title': 'COMPONENTS', 'type' : 'nav-collapse',
'type' : 'subheader' 'icon' : 'poll',
}, 'children': [
{ {
'title' : 'Charts', 'title': 'nvD3',
'type' : 'nav-collapse', 'type' : 'nav-item',
'url' : '/components/charts', 'url' : '/components/charts/nvd3'
'icon' : 'poll', }
'children': [ ]
{ },
'title': 'nvD3', {
'type' : 'nav-item', 'title': 'Collapse',
'url' : '/components/charts/nvd3' 'type' : 'nav-item',
} 'icon' : 'add_box',
] 'url' : '/components/collapse'
}, },
{ {
'title': 'Collapse', 'title': 'Modal',
'type' : 'nav-item', 'type' : 'nav-item',
'icon' : 'add_box', 'icon' : 'picture_in_picture',
'url' : '/components/collapse' 'url' : '/components/modal'
}, },
{ {
'title': 'Modal', 'title': 'Popovers',
'type' : 'nav-item', 'type' : 'nav-item',
'icon' : 'picture_in_picture', 'icon' : 'chat_buble',
'url' : '/components/modal' 'url' : '/components/popovers'
}, },
{ {
'title': 'Popovers', 'title': 'Snackbar',
'type' : 'nav-item', 'type' : 'nav-item',
'icon' : 'chat_buble', 'icon' : 'call_to_action',
'url' : '/components/popovers' 'url' : '/components/snackbar'
}, },
{ {
'title': 'Snackbar', 'title': 'Tooltips',
'type' : 'nav-item', 'type' : 'nav-item',
'icon' : 'call_to_action', 'icon' : 'live_help',
'url' : '/components/snackbar' 'url' : '/components/tooltips'
}, }
{ ];
'title': 'Tooltips', }
'type' : 'nav-item',
'icon' : 'live_help',
'url' : '/components/tooltips'
}
];
} }

View File

@ -1,34 +1,15 @@
import {EventEmitter, Injectable} from '@angular/core'; import {EventEmitter, Injectable} from '@angular/core';
import {NavigationEnd, NavigationStart, Router} from '@angular/router';
import {FuseNavigation} from './navigation.model'; import {FuseNavigation} from './navigation.model';
@Injectable() @Injectable()
export class NavigationService export class NavigationService
{ {
navItemClicked = new EventEmitter<any>(); onNavCollapseToggled = new EventEmitter<any>();
clickedItemUrl: string;
navigation: object[]; navigation: object[];
constructor(private router: Router) constructor()
{ {
this.navigation = new FuseNavigation().items; this.navigation = new FuseNavigation().items;
router.events.subscribe(
(event) =>
{
if ( event instanceof NavigationEnd )
{
console.warn('event', event);
this.navItemClicked.emit(event.urlAfterRedirects);
}
}
);
this.navItemClicked.subscribe(
(instance) =>
{
console.log('instance', instance);
this.clickedItemUrl = instance;
}
);
} }
getNavigation() getNavigation()