Moved the navigation.model.ts into its own folder

+ Added support for translations in nav items
+ Added badge support for collapsable nav items
+ Initialize the navigation from app.component rather then navigation.service
This commit is contained in:
Sercan Yemen 2017-12-06 14:10:48 +03:00
parent db7a00440c
commit 2a10f3e443
14 changed files with 195 additions and 90 deletions

View File

@ -1,6 +1,12 @@
import { Component } from '@angular/core';
import { FuseSplashScreenService } from './core/services/splash-screen.service';
import { TranslateService } from '@ngx-translate/core';
import { FuseTranslationLoaderService } from './core/services/translation-loader.service';
import { FuseNavigationService } from './core/components/navigation/navigation.service';
import { FuseNavigationModel } from './navigation/navigation.model';
import { locale as navigationEnglish } from './navigation/i18n/en';
import { locale as navigationTurkish } from './navigation/i18n/tr';
@Component({
selector : 'fuse-root',
@ -10,8 +16,10 @@ import { TranslateService } from '@ngx-translate/core';
export class AppComponent
{
constructor(
private fuseNavigationService: FuseNavigationService,
private fuseSplashScreen: FuseSplashScreenService,
private translate: TranslateService
private translate: TranslateService,
private translationLoader: FuseTranslationLoaderService
)
{
// Add languages
@ -22,5 +30,11 @@ export class AppComponent
// Use a language
this.translate.use('en');
// Set the navigation model
this.fuseNavigationService.setNavigationModel(new FuseNavigationModel());
// Set the navigation translations
this.translationLoader.loadTranslations(navigationEnglish, navigationTurkish);
}
}

View File

@ -73,16 +73,12 @@ const appRoutes: Routes = [
SharedModule,
MarkdownModule.forRoot(),
TranslateModule.forRoot(),
InMemoryWebApiModule.forRoot(FuseFakeDbService, {
delay : 0,
passThruUnknownUrl: true
}),
FuseMainModule,
ProjectModule,
PagesModule,
UIModule,
ServicesModule,

View File

@ -1,6 +1,10 @@
<a class="nav-link" matRipple>
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
<span class="nav-link-title">{{item.title}}</span>
<span class="nav-link-title" [translate]="item.translate">{{item.title}}</span>
<span class="nav-link-badge" *ngIf="item.badge" [translate]="item.badge.translate"
[ngStyle]="{'background-color': item.badge.bg,'color': item.badge.fg}">
{{item.badge.title}}
</span>
<mat-icon class="collapse-arrow">keyboard_arrow_right</mat-icon>
</a>

View File

@ -1,8 +1,8 @@
<a class="nav-link" *ngIf="item.url" [routerLink]="[item.url]" routerLinkActive="active"
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
<span class="nav-link-title">{{item.title}}</span>
<span class="nav-link-badge" *ngIf="item.badge"
<span class="nav-link-title" [translate]="item.translate">{{item.title}}</span>
<span class="nav-link-badge" *ngIf="item.badge" [translate]="item.badge.translate"
[ngStyle]="{'background-color': item.badge.bg,'color': item.badge.fg}">
{{item.badge.title}}
</span>
@ -10,8 +10,8 @@
<span class="nav-link" *ngIf="item.function" (click)="item.function()" matRipple>
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
<span class="nav-link-title">{{item.title}}</span>
<span class="nav-link-badge" *ngIf="item.badge"
<span class="nav-link-title" [translate]="item.translate">{{item.title}}</span>
<span class="nav-link-badge" *ngIf="item.badge" [translate]="item.badge.translate"
[ngStyle]="{'background-color': item.badge.bg,'color': item.badge.fg}">
{{item.badge.title}}
</span>

View File

@ -0,0 +1,5 @@
export interface FuseNavigationModelInterface
{
model: any[];
}

View File

@ -1,6 +1,6 @@
import { EventEmitter, Injectable } from '@angular/core';
import { NavigationModel } from '../../../navigation.model';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { FuseNavigationModelInterface } from './navigation.model';
@Injectable()
export class FuseNavigationService
@ -8,13 +8,11 @@ export class FuseNavigationService
onNavCollapseToggle = new EventEmitter<any>();
onNavCollapseToggled = new EventEmitter<any>();
onNavigationModelChange: BehaviorSubject<any> = new BehaviorSubject({});
navigationModel: NavigationModel;
navigationModel: FuseNavigationModelInterface;
flatNavigation: any[] = [];
constructor()
{
this.navigationModel = new NavigationModel();
this.onNavigationModelChange.next(this.navigationModel.model);
}
/**

View File

@ -1,8 +1,13 @@
<a class="nav-link" matRipple (click)="toggleOpen($event)">
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
<span class="nav-link-title">{{item.title}}</span>
<span class="nav-link-title" [translate]="item.translate">{{item.title}}</span>
<span class="nav-link-badge" *ngIf="item.badge" [translate]="item.badge.translate"
[ngStyle]="{'background-color': item.badge.bg,'color': item.badge.fg}">
{{item.badge.title}}
</span>
<mat-icon class="collapse-arrow">keyboard_arrow_right</mat-icon>
</a>
<div class="children" [@slideInOut]="isOpen">
<ng-container *ngFor="let item of item.children">
<fuse-nav-vertical-item *ngIf="item.type=='item'" [item]="item"></fuse-nav-vertical-item>

View File

@ -1,6 +1,7 @@
<div class="group-title">
<span class="hint-text">{{ item.title }}</span>
<span class="hint-text" [translate]="item.translate">{{ item.title }}</span>
</div>
<div class="group-items">
<ng-container *ngFor="let item of item.children">
<fuse-nav-vertical-group *ngIf="item.type=='group'" [item]="item"></fuse-nav-vertical-group>

View File

@ -1,8 +1,8 @@
<a class="nav-link" *ngIf="item.url" [routerLink]="[item.url]" routerLinkActive="active"
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
<span class="nav-link-title">{{item.title}}</span>
<span class="nav-link-badge" *ngIf="item.badge"
<span class="nav-link-title" [translate]="item.translate">{{item.title}}</span>
<span class="nav-link-badge" *ngIf="item.badge" [translate]="item.badge.translate"
[ngStyle]="{'background-color': item.badge.bg,'color': item.badge.fg}">
{{item.badge.title}}
</span>
@ -10,8 +10,8 @@
<span class="nav-link" *ngIf="item.function" (click)="item.function()" matRipple>
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
<span class="nav-link-title">{{item.title}}</span>
<span class="nav-link-badge" *ngIf="item.badge"
<span class="nav-link-title" [translate]="item.translate">{{item.title}}</span>
<span class="nav-link-badge" *ngIf="item.badge" [translate]="item.badge.translate"
[ngStyle]="{'background-color': item.badge.bg,'color': item.badge.fg}">
{{item.badge.title}}
</span>

View File

@ -47,14 +47,20 @@
}
.nav-link-badge {
display: flex;
align-items: center;
min-width: 20px;
height: 20px;
line-height: 20px;
padding: 0 7px;
font-size: 11px;
font-weight: 500;
border-radius: 20px;
transition: opacity 0.2s ease-in-out 0.1s;
margin-left: 8px;
+ .collapse-arrow {
margin-left: 8px;
}
}
&:hover {

View File

@ -18,7 +18,7 @@
<p>
<code>fuse-navigation</code> is a custom built Fuse component allows you to create a multi-level collapsable
navigation.
navigation. It has built-in support for translations using <b>ngx-translate</b> module.
</p>
<div class="my-48">
@ -40,6 +40,11 @@
<b>Collapsable</b> and <b>Item</b>. These items can be mixed and matched to create unique and complex
navigation layouts.
</p>
<p class="py-8">
Navigation model can be found in <code>src/app/navigation</code> folder along with its translation
files. Navigation model and its translation files are set in <b>app.component.ts</b> file. Check that
file for more detailed usage example.
</p>
</div>
<div class="my-48">
@ -48,9 +53,10 @@
<fuse-hljs lang="json" class="source-code">
<textarea #source hidden="hidden">
{
'title': 'COMPONENTS',
'title' : 'COMPONENTS',
'translate': 'NAV.COMPONENTS',
'type' : 'group',
'children': [
'children' : [
{
'title': 'ngx-datatable',
'type' : 'item',
@ -70,9 +76,10 @@
<textarea #source hidden="hidden">
{
'title' : 'Datatables',
'translate': 'NAV.DATATABLES',
'type' : 'collapse',
'icon' : 'border_all',
'children': [
'children' : [
{
'title': 'ngx-datatable',
'type' : 'nav-item',
@ -91,7 +98,8 @@
<fuse-hljs lang="json" class="source-code">
<textarea #source hidden="hidden">
{
'title': 'Countdown',
'title' : 'Countdown',
'translate': 'NAV.COUNTDOWN',
'type' : 'item',
'icon' : 'settings_input_component',
'url' : '/components/countdown'

View File

@ -0,0 +1,20 @@
export const locale = {
lang: 'en',
data: {
'NAV': {
'APPLICATIONS': 'Applications',
'DASHBOARDS' : 'Dashboards',
'CALENDAR' : 'Calendar',
'ECOMMERCE' : 'E-Commerce',
'MAIL' : {
'TITLE': 'Mail',
'BADGE': '25'
},
'CHAT' : 'Chat',
'FILE_MANAGER': 'File Manager',
'CONTACTS' : 'Contacts',
'TODO' : 'To-Do',
'SCRUMBOARD' : 'Scrumboard'
}
}
};

View File

@ -0,0 +1,20 @@
export const locale = {
lang: 'tr',
data: {
'NAV': {
'APPLICATIONS': 'Programlar',
'DASHBOARDS' : 'Kontrol Paneli',
'CALENDAR' : 'Takvim',
'ECOMMERCE' : 'E-Ticaret',
'MAIL' : {
'TITLE': 'Posta',
'BADGE': '15'
},
'CHAT' : 'Sohbet',
'FILE_MANAGER': 'Dosya Yöneticisi',
'CONTACTS' : 'Kişiler',
'TODO' : 'Yapılacaklar',
'SCRUMBOARD' : 'Proje'
}
}
};

View File

@ -1,4 +1,6 @@
export class NavigationModel
import { FuseNavigationModelInterface } from '../core/components/navigation/navigation.model';
export class FuseNavigationModel implements FuseNavigationModelInterface
{
public model: any[];
@ -8,15 +10,17 @@ export class NavigationModel
{
'id' : 'applications',
'title' : 'Applications',
'translate': 'NAV.APPLICATIONS',
'type' : 'group',
'icon' : 'apps',
'children': [
'children' : [
{
'id' : 'dashboards',
'title' : 'Dashboards',
'translate': 'NAV.DASHBOARDS',
'type' : 'collapse',
'icon' : 'dashboard',
'children': [
'children' : [
{
'id' : 'project',
'title': 'Project',
@ -27,7 +31,8 @@ export class NavigationModel
},
{
'id' : 'calendar',
'title': 'Calendar',
'title' : 'Calendar',
'translate': 'NAV.CALENDAR',
'type' : 'item',
'icon' : 'today',
'url' : '/apps/calendar'
@ -35,9 +40,10 @@ export class NavigationModel
{
'id' : 'e-commerce',
'title' : 'E-Commerce',
'translate': 'NAV.ECOMMERCE',
'type' : 'collapse',
'icon' : 'shopping_cart',
'children': [
'children' : [
{
'id' : 'dashboard',
'title': 'Dashboard',
@ -76,23 +82,26 @@ export class NavigationModel
},
{
'id' : 'mail',
'title': 'Mail',
'title' : 'Mail',
'translate': 'NAV.MAIL.TITLE',
'type' : 'item',
'icon' : 'email',
'url' : '/apps/mail',
'badge': {
'title': 25,
'badge' : {
'title' : 25,
'translate': 'NAV.MAIL.BADGE',
'bg' : '#F44336',
'fg' : '#FFFFFF'
}
},
{
'id' : 'chat',
'title': 'Chat',
'title' : 'Chat',
'translate': 'NAV.CHAT',
'type' : 'item',
'icon' : 'chat',
'url' : '/apps/chat',
'badge': {
'badge' : {
'title': 13,
'bg' : '#09d261',
'fg' : '#FFFFFF'
@ -100,25 +109,28 @@ export class NavigationModel
},
{
'id' : 'file-manager',
'title': 'File Manager',
'title' : 'File Manager',
'translate': 'NAV.FILE_MANAGER',
'type' : 'item',
'icon' : 'folder',
'url' : '/apps/file-manager'
},
{
'id' : 'contacts',
'title': 'Contacts',
'title' : 'Contacts',
'translate': 'NAV.CONTACTS',
'type' : 'item',
'icon' : 'account_box',
'url' : '/apps/contacts'
},
{
'id' : 'to-do',
'title': 'To-Do',
'title' : 'To-Do',
'translate': 'NAV.TODO',
'type' : 'item',
'icon' : 'check_box',
'url' : '/apps/todo',
'badge': {
'badge' : {
'title': 3,
'bg' : '#FF6F00',
'fg' : '#FFFFFF'
@ -126,7 +138,8 @@ export class NavigationModel
},
{
'id' : 'scrumboard',
'title': 'Scrumboard',
'title' : 'Scrumboard',
'translate': 'NAV.SCRUMBOARD',
'type' : 'item',
'icon' : 'assessment',
'url' : '/apps/scrumboard'
@ -144,6 +157,11 @@ export class NavigationModel
'title' : 'Authentication',
'type' : 'collapse',
'icon' : 'lock',
'badge' : {
'title': 10,
'bg' : '#525e8a',
'fg' : '#FFFFFF'
},
'children': [
{
'id' : 'login',
@ -359,6 +377,11 @@ export class NavigationModel
'id' : 'carded',
'title' : 'Carded',
'type' : 'collapse',
'badge' : {
'title': 10,
'bg' : '#525e8a',
'fg' : '#FFFFFF'
},
'children': [
{
'id' : 'full-width',
@ -426,6 +449,11 @@ export class NavigationModel
'id' : 'simple',
'title' : 'Simple',
'type' : 'collapse',
'badge' : {
'title': 8,
'bg' : '#525e8a',
'fg' : '#FFFFFF'
},
'children': [
{
'id' : 'full-width',