Compare commits

...

60 Commits

Author SHA1 Message Date
Sercan Yemen
20ac3abb25 Merge branch 'master' into skeleton 2017-11-27 17:21:38 +03:00
Sercan Yemen
19fdbbdbcb Increased version number
Fixed: Sidenav helper causes issues on mobile media steps
2017-11-27 17:20:34 +03:00
Sercan Yemen
f634cb06a7 Merge branch 'master' into skeleton 2017-11-27 14:42:23 +03:00
Sercan Yemen
7d67a481ff Merge branch 'master' into skeleton 2017-11-27 14:35:37 +03:00
Sercan Yemen
8bbabd7437 Corrected the version number 2017-11-27 14:31:57 +03:00
Sercan Yemen
5a9cd36282 Increased the Fuse version number
+ Updated Angular, Angular Material and Flex Layout
+ Updated various components for better Angular5 support
+ Fixed: Contacts app various issues
+ Fixed: Duplicate content in Profile page tabs
+ Fixed: Folded status of the Navbar shouldn't brake the layout if Horizontal Navbar is active
2017-11-27 14:28:08 +03:00
mustafahlvc
297bb95a2e Temporary aot build fix for @swimlane/ngx-charts 2017-11-18 01:43:08 +03:00
Sercan Yemen
2511a03b66 Increased the Fuse version number
+ Updated ngx-charts and ngx-datatables
+ added rxjs imports for the various search
2017-11-18 00:45:42 +03:00
mustafahlvc
76358f996e Angular material docs updated,
+ @angular/material-moment-adapter added to package.json
2017-11-17 18:35:44 +03:00
mustafahlvc
142fc982ca Angular updated to 5.0.2, angular-cli updated to 1.5.2,
+ angular-material-elements and fakeDb folder excluded from linting,
+ some lint errors solved.
2017-11-17 16:57:42 +03:00
Sercan Yemen
22d9279e3b Fix: Authentication (v2) pages not scrollable when custom scrollbars disabled 2017-11-14 09:35:03 +03:00
Sercan Yemen
4659da7390 Added missing variables that prevents skeleton from building as it is 2017-11-13 12:30:11 +03:00
Sercan Yemen
2a5d15694c Merge branch 'master' into skeleton 2017-11-13 11:09:27 +03:00
Sercan Yemen
a1bec98d44 Todo adjustments 2017-11-13 11:04:57 +03:00
Sercan Yemen
e8449e340d Contact list checkbox rendering broken due to ripple 2017-11-13 10:45:16 +03:00
Sercan Yemen
4cb8009c69 Scrumboard label selector not working correctly + style refinements 2017-11-13 10:36:32 +03:00
Sercan Yemen
7f357306eb Angular 5.0.1 & Angular Material 5.0.0-rc0 compatibility (wip) 2017-11-12 22:36:14 +03:00
Sercan Yemen
8e6024c3ee Fixes #44 : Removed angular material elements assets 2017-11-08 15:11:20 +03:00
Sercan Yemen
f4c47daadc Merge branch 'master' into skeleton 2017-11-08 15:10:51 +03:00
Sercan Yemen
06679343a4 Fixes #44 : Example e2e test file content is wrong
+ Renamed 'mat-sidenav-helper' files/folders to 'fuse-mat-sidenav-helper' & fixed its import issues
2017-11-08 15:08:40 +03:00
Sercan Yemen
381bc6c0fe Merge branch 'master' into skeleton 2017-11-04 16:50:03 +03:00
Sercan Yemen
f35d83567e Update the footer button text 2017-11-04 16:49:47 +03:00
Sercan Yemen
b5a139f81d Merge branch 'master' into skeleton 2017-11-04 16:32:29 +03:00
Sercan Yemen
c97fd77c13 Updated title 2017-11-04 16:32:12 +03:00
Sercan Yemen
914477da41 Merge branch 'master' into skeleton 2017-11-04 16:25:09 +03:00
Sercan Yemen
410802808e Merge branch 'master' into skeleton 2017-11-04 16:20:46 +03:00
Sercan Yemen
62904cdb42 Updated readme file 2017-11-04 16:15:00 +03:00
Sercan Yemen
d9c36cad82 Fix: Angular 5 AoT issues 2017-11-04 16:14:12 +03:00
Sercan Yemen
d2bfc152a0 Fix: Some css issues after updating the ngx-datatable 2017-11-04 14:00:26 +03:00
Sercan Yemen
f013b2b667 Angular 5 compatibility (wip)
+ Fuse2 version: 1.2.0
2017-11-04 13:41:40 +03:00
Sercan Yemen
9fbcc20623 Fix: Navbar vertical puts out wrong classes 2017-11-04 13:41:24 +03:00
Sercan Yemen
0fd8a75f7d Added exactMatch parameter to the navigation items for correctly highlighting them 2017-11-04 13:39:18 +03:00
Sercan Yemen
99d9552813 Added E-Commerce pages to the navigation for easier access 2017-11-04 12:49:38 +03:00
Sercan Yemen
3bca193bcc Fixes #39 : Nav item not showing in Horizontal menu + its height is not correct 2017-11-04 12:46:40 +03:00
Sercan Yemen
f73ff363a5 Small fixes on cards 2017-11-04 12:45:12 +03:00
Sercan Yemen
1bf689f154 Angular 5 compatibility (wip) 2017-11-02 12:52:27 +03:00
Sercan Yemen
3499d89098 Angular 5 compatibility (wip) 2017-11-02 12:52:05 +03:00
Sercan Yemen
685cd76da2 Fixed: Minor issues with E-Commerce app
+ Fixed: Navigation collapsable items don't expand if the url has extra parameters in it
2017-11-02 11:16:24 +03:00
Sercan Yemen
786180958d Merge branch 'master' of https://github.com/withinpixels/fuse2 2017-11-02 10:47:33 +03:00
Sercan Yemen
a2f72c92d5 New: Material design cards 2017-11-02 10:47:28 +03:00
mustafahlvc
6b368d2e79 Merge remote-tracking branch 'origin/master' 2017-11-01 14:32:42 +03:00
mustafahlvc
47c2cc721e E-commerce App added. 2017-11-01 14:32:25 +03:00
Sercan Yemen
5574e3f729 Merge branch 'master' of https://github.com/withinpixels/fuse2 2017-10-31 10:08:04 +03:00
Sercan Yemen
1934bad3eb Fixes #33: Toolbar navigation bar button should toggle the navigation bar 2017-10-31 10:06:49 +03:00
Sercan Yemen
ee29f20304 Added an ability to control the folded status of the vertical navigation via FuseConfig 2017-10-30 13:31:23 +03:00
mustafahlvc
93c2eab584 Merge remote-tracking branch 'origin/master' 2017-10-27 18:22:44 +03:00
mustafahlvc
b0f45980be ngx-datatable data fake api data fix. 2017-10-27 18:22:14 +03:00
Sercan Yemen
56dbc58d5e Merge branch 'master' into skeleton
+ Added translation example to the sample page
2017-10-27 12:01:09 +03:00
Sercan Yemen
d7c6b2d617 Merge branch 'master' into skeleton 2017-10-27 11:49:31 +03:00
Sercan Yemen
7b10b2ad86 Added docs about vertical navigation default folded status 2017-10-27 11:45:11 +03:00
Sercan Yemen
3fc510469d New: Knowledge base page design 2017-10-25 13:09:35 +03:00
Sercan Yemen
5d56b3bcd6 Small typo on FAQ page 2017-10-25 13:09:17 +03:00
Sercan Yemen
aaa14eb1e9 Fixed: Stagger animation doesn't have {optional:true} 2017-10-25 10:15:19 +03:00
Sercan Yemen
f43608f93b Added a "Learn more" link to the language switcher for the demo 2017-10-24 16:02:09 +03:00
Sercan Yemen
9ecd921722 File based translations - multi language
+ Example in the Mail app
+ Component/doc page for translations
2017-10-24 15:41:44 +03:00
Sercan Yemen
98e2ff0e1e Small adjustment on the FAQ page header 2017-10-24 11:47:10 +03:00
Sercan Yemen
b7cb09b087 Small adjustment on the layout mode setting 2017-10-24 11:02:40 +03:00
Sercan Yemen
fe8b44b14c Fixed: FAQ page header shrinks on small heights 2017-10-24 10:19:17 +03:00
Sercan Yemen
ca8ed939ae Added new tabbed versions of the carded sidenav layouts
+ Small tweaks on other carded sidenav layouts
2017-10-23 14:39:44 +03:00
Sercan Yemen
4469a2c25a Fix: iOS10 scrolling issue in dashboard 2017-10-23 10:51:28 +03:00
85 changed files with 2929 additions and 2735 deletions

View File

@@ -37,13 +37,28 @@
},
"lint": [
{
"project": "src/tsconfig.app.json"
"project": "src/tsconfig.app.json",
"exclude": [
"**/node_modules/**",
"**/src/app/fuse-fake-db/**/*",
"**/src/assets/angular-material-examples/**/*"
]
},
{
"project": "src/tsconfig.spec.json"
"project": "src/tsconfig.spec.json",
"exclude": [
"**/node_modules/**",
"**/src/app/fuse-fake-db/**/*",
"**/src/assets/angular-material-examples/**/*"
]
},
{
"project": "e2e/tsconfig.e2e.json"
"project": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**",
"**/src/app/fuse-fake-db/**/*",
"**/src/assets/angular-material-examples/**/*"
]
}
],
"test": {

View File

@@ -1,6 +1,6 @@
# Fuse2
Material Design Admin Template with Angular 4+ and Angular Material 2
Material Design Admin Template with Angular 5+ and Angular Material 2
## Development server

View File

@@ -1,14 +1,14 @@
import { Fuse2Page } from './app.po';
describe('fuse2 App', () => {
let page: Fuse2Page;
describe('Fuse2 App', () => {
let page: Fuse2Page;
beforeEach(() => {
page = new Fuse2Page();
});
beforeEach(() => {
page = new Fuse2Page();
});
it('should display welcome message', () => {
page.navigateTo();
expect(page.getParagraphText()).toEqual('Welcome to app!!');
});
it('should display welcome message', () => {
page.navigateTo();
expect(page.getParagraphText()).toEqual('Welcome to app!');
});
});

View File

@@ -1,11 +1,11 @@
import { browser, by, element } from 'protractor';
export class Fuse2Page {
navigateTo() {
return browser.get('/');
}
navigateTo() {
return browser.get('/');
}
getParagraphText() {
return element(by.css('app-root h1')).getText();
}
getParagraphText() {
return element(by.css('app-root h1')).getText();
}
}

View File

@@ -2,10 +2,12 @@
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"baseUrl": "./",
"module": "commonjs",
"target": "es5",
"types": [
"jasmine",
"jasminewd2",
"node"
]
}

View File

@@ -1,33 +1,33 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/0.13/config/configuration-file.html
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular/cli'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular/cli/plugins/karma')
],
client:{
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true
},
angularCli: {
environment: 'dev'
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
config.set({
basePath: '',
frameworks: ['jasmine', '@angular/cli'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular/cli/plugins/karma')
],
client:{
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true
},
angularCli: {
environment: 'dev'
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};

4315
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,72 +1,73 @@
{
"name": "fuse2",
"version": "1.1.2",
"version": "1.2.3",
"license": "",
"scripts": {
"ng": "ng",
"start": "ng serve",
"start-hmr": "ng serve --hmr -e=hmr -sm=false",
"start-hmr-sourcemaps": "ng serve --hmr -e=hmr",
"build": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build",
"build-prod": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --prod",
"build": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --dev",
"build-prod": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@agm/core": "1.0.0-beta.1",
"@angular/animations": "4.4.5",
"@angular/cdk": "2.0.0-beta.12",
"@angular/common": "4.4.5",
"@angular/compiler": "4.4.5",
"@angular/core": "4.4.5",
"@angular/flex-layout": "2.0.0-beta.9",
"@angular/forms": "4.4.5",
"@angular/http": "4.4.5",
"@angular/material": "2.0.0-beta.12",
"@angular/platform-browser": "4.4.5",
"@angular/platform-browser-dynamic": "4.4.5",
"@angular/router": "4.4.5",
"@swimlane/ngx-charts": "6.0.2",
"@swimlane/ngx-datatable": "9.3.1",
"@swimlane/ngx-dnd": "3.0.0",
"angular-calendar": "0.21.2",
"angular-in-memory-web-api": "0.5.0",
"@agm/core": "1.0.0-beta.2",
"@angular/animations": "5.0.3",
"@angular/cdk": "5.0.0-rc.1",
"@angular/common": "5.0.3",
"@angular/compiler": "5.0.3",
"@angular/core": "5.0.3",
"@angular/flex-layout": "2.0.0-beta.10-4905443",
"@angular/forms": "5.0.3",
"@angular/http": "5.0.3",
"@angular/material": "5.0.0-rc.1",
"@angular/material-moment-adapter": "5.0.0-rc.1",
"@angular/platform-browser": "5.0.3",
"@angular/platform-browser-dynamic": "5.0.3",
"@angular/router": "5.0.3",
"@ngx-translate/core": "8.0.0",
"@swimlane/ngx-charts": "7.0.1",
"@swimlane/ngx-datatable": "11.1.4",
"@withinpixels/ngx-dnd": "3.1.0",
"angular-calendar": "0.22.1",
"classlist.js": "1.1.20150312",
"core-js": "2.5.1",
"d3": "4.10.0",
"d3": "4.12.0",
"hammerjs": "2.0.8",
"highlight.js": "9.12.0",
"intl": "1.2.5",
"moment": "2.19.1",
"ngx-color-picker": "4.4.0",
"moment": "2.19.2",
"ngx-color-picker": "5.0.4",
"ngx-cookie-service": "1.0.9",
"perfect-scrollbar": "1.0.3",
"rxjs": "5.4.3",
"perfect-scrollbar": "1.2.0",
"rxjs": "5.5.2",
"web-animations-js": "2.3.1",
"zone.js": "0.8.18"
},
"devDependencies": {
"@angular/cli": "1.4.7",
"@angular/compiler-cli": "4.4.5",
"@angular/language-service": "4.4.5",
"@angular/cli": "1.5.4",
"@angular/compiler-cli": "5.0.3",
"@angular/language-service": "5.0.3",
"@angularclass/hmr": "2.1.3",
"@types/jasmine": "2.6.0",
"@types/jasminewd2": "2.0.2",
"@types/node": "6.0.88",
"codelyzer": "3.2.0",
"jasmine-core": "2.6.2",
"jasmine-spec-reporter": "4.1.0",
"@types/jasmine": "2.5.54",
"@types/jasminewd2": "2.0.3",
"@types/node": "6.0.92",
"codelyzer": "4.0.1",
"jasmine-core": "2.6.4",
"jasmine-spec-reporter": "4.1.1",
"karma": "1.7.1",
"karma-chrome-launcher": "2.1.1",
"karma-cli": "1.0.1",
"karma-coverage-istanbul-reporter": "1.2.1",
"karma-coverage-istanbul-reporter": "1.3.0",
"karma-jasmine": "1.1.0",
"karma-jasmine-html-reporter": "0.2.2",
"protractor": "5.1.2",
"ts-node": "3.2.0",
"ts-node": "3.2.2",
"tslint": "5.7.0",
"typescript": "2.3.3"
"typescript": "2.4.2"
}
}

View File

@@ -4,25 +4,25 @@
const { SpecReporter } = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./e2e/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: 'e2e/tsconfig.e2e.json'
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
allScriptsTimeout: 11000,
specs: [
'./e2e/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: 'e2e/tsconfig.e2e.json'
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};

View File

@@ -1,5 +1,6 @@
import { Component } from '@angular/core';
import { FuseSplashScreenService } from './core/services/splash-screen.service';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector : 'fuse-root',
@@ -8,7 +9,18 @@ import { FuseSplashScreenService } from './core/services/splash-screen.service';
})
export class AppComponent
{
constructor(private fuseSplashScreen: FuseSplashScreenService)
constructor(
private fuseSplashScreen: FuseSplashScreenService,
private translate: TranslateService
)
{
// Add languages
this.translate.addLangs(['en', 'tr']);
// Set the default language
this.translate.setDefaultLang('en');
// Use a language
this.translate.use('en');
}
}

View File

@@ -12,6 +12,7 @@ import { FuseSplashScreenService } from './core/services/splash-screen.service';
import { FuseConfigService } from './core/services/config.service';
import { FuseNavigationService } from './core/components/navigation/navigation.service';
import { FuseSampleModule } from './main/content/sample/sample.module';
import { TranslateModule } from '@ngx-translate/core';
const appRoutes: Routes = [
{
@@ -31,6 +32,7 @@ const appRoutes: Routes = [
BrowserAnimationsModule,
RouterModule.forRoot(appRoutes),
SharedModule,
TranslateModule.forRoot(),
FuseMainModule,
FuseSampleModule
],

View File

@@ -33,21 +33,21 @@ export const fuseAnimations = [
stagger('50ms', [
animateChild()
])
])),
], {optional: true})),
transition('void => 100',
query('@*',
[
stagger('100ms', [
animateChild()
])
])),
], {optional: true})),
transition('void => 200',
query('@*',
[
stagger('200ms', [
animateChild()
])
]))
], {optional: true}))
]),
trigger('fadeInOut', [
@@ -129,6 +129,17 @@ export const fuseAnimations = [
transition('* => void', animate('300ms'))
]),
trigger('expandCollapse', [
state('void', style({
height: '0px'
})),
state('*', style({
height: '*'
})),
transition('void => *', animate('300ms ease-out')),
transition('* => void', animate('300ms ease-in'))
]),
trigger('routerTransitionLeft', [
transition('* => *', [

View File

@@ -1,6 +1,7 @@
import { Component, Input, OnInit } from '@angular/core';
import * as moment from 'moment';
import { Observable } from 'rxjs/Rx';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/interval';
@Component({
selector : 'fuse-countdown',

View File

@@ -2,7 +2,7 @@
type="button"
class="mat-elevation-z1"
[matMenuTriggerFor]="colorMenu"
(onMenuOpen)="onMenuOpen()"
(menuOpened)="onMenuOpen()"
[ngClass]="'mat-'+selectedPalette+'-'+selectedHue+'-bg'">
<mat-icon>palette</mat-icon>
</button>

View File

@@ -1,4 +1,5 @@
<a class="nav-link" *ngIf="item.url" [routerLink]="[item.url]" routerLinkActive="active" matRipple>
<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"

View File

@@ -22,7 +22,7 @@
<fuse-nav-horizontal-collapse *ngIf="item.type=='group'" [item]="item"></fuse-nav-horizontal-collapse>
<fuse-nav-horizontal-collapse *ngIf="item.type=='collapse'" [item]="item"></fuse-nav-horizontal-collapse>
<fuse-nav-horizontal-item *ngIf="item.type=='nav-item'" [item]="item"></fuse-nav-horizontal-item>
<fuse-nav-horizontal-item *ngIf="item.type=='item'" [item]="item"></fuse-nav-horizontal-item>
</ng-container>

View File

@@ -166,7 +166,7 @@ export class FuseNavVerticalCollapseComponent implements OnInit
}
}
if ( parent.children[i].url === url )
if ( parent.children[i].url === url || url.includes(parent.children[i].url) )
{
return true;
}

View File

@@ -1,4 +1,5 @@
<a class="nav-link" *ngIf="item.url" [routerLink]="[item.url]" routerLinkActive="active" matRipple>
<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"

View File

@@ -26,7 +26,7 @@
</div>
<button mat-icon-button [matMenuTriggerFor]="addMenu" matTooltip="Click to add/remove shortcut"
(onMenuOpen)="onMenuOpen()">
(menuOpened)="onMenuOpen()">
<mat-icon class="amber-600-fg">star</mat-icon>
</button>

View File

@@ -149,7 +149,9 @@ export class FuseShortcutsComponent implements OnInit, OnDestroy
onMenuOpen()
{
this.searchInputField.nativeElement.focus();
setTimeout(() => {
this.searchInputField.nativeElement.focus();
});
}
showMobileShortcutsPanel()

View File

@@ -21,6 +21,12 @@
<mat-radio-button class="mr-8 mb-8" value="none">None</mat-radio-button>
</mat-radio-group>
<h3>Navigation Fold (for vertical navigation):</h3>
<mat-slide-toggle [(ngModel)]="fuseSettings.layout.navigationFolded"
(change)="onSettingsChange()">
Folded
</mat-slide-toggle>
<h3 class="mt-24">Toolbar:</h3>
<mat-radio-group [(ngModel)]="fuseSettings.layout.toolbar" (ngModelChange)="onSettingsChange()"
fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign="start start" fxLayoutWrap>

View File

@@ -1,9 +1,9 @@
import { Directive, Input, OnInit, HostListener, OnDestroy, HostBinding } from '@angular/core';
import { MatSidenav } from '@angular/material';
import { FuseMatSidenavHelperService } from 'app/core/directives/mat-sidenav-helper/mat-sidenav-helper.service';
import { FuseMatchMedia } from '../../services/match-media.service';
import { ObservableMedia } from '@angular/flex-layout';
import { Subscription } from 'rxjs/Subscription';
import { FuseMatchMedia } from '../../services/match-media.service';
import { FuseMatSidenavHelperService } from './fuse-mat-sidenav-helper.service';
@Directive({
selector: '[fuseMatSidenavHelper]'
@@ -13,7 +13,6 @@ export class FuseMatSidenavHelperDirective implements OnInit, OnDestroy
matchMediaSubscription: Subscription;
@HostBinding('class.mat-is-locked-open') isLockedOpen = true;
@HostBinding('class.mat-stop-transition') stopTransition = true;
@Input('fuseMatSidenavHelper') id: string;
@Input('mat-is-locked-open') matIsLockedOpenBreakpoint: string;
@@ -33,45 +32,31 @@ export class FuseMatSidenavHelperDirective implements OnInit, OnDestroy
if ( this.observableMedia.isActive(this.matIsLockedOpenBreakpoint) )
{
setTimeout(() => {
this.isLockedOpen = true;
this.matSidenav.mode = 'side';
this.matSidenav.open();
});
this.stopTransition = false;
this.isLockedOpen = true;
this.matSidenav.mode = 'side';
this.matSidenav.toggle(true);
}
else
{
setTimeout(() => {
this.isLockedOpen = false;
this.matSidenav.mode = 'over';
this.matSidenav.close();
});
setTimeout(() => {
this.stopTransition = false;
}, 3000);
this.isLockedOpen = false;
this.matSidenav.mode = 'over';
this.matSidenav.toggle(false);
}
this.matchMediaSubscription = this.fuseMatchMedia.onMediaChange.subscribe(() => {
if ( this.observableMedia.isActive(this.matIsLockedOpenBreakpoint) )
{
setTimeout(() => {
this.isLockedOpen = true;
this.matSidenav.mode = 'side';
this.matSidenav.open();
});
this.isLockedOpen = true;
this.matSidenav.mode = 'side';
this.matSidenav.toggle(true);
}
else
{
setTimeout(() => {
this.isLockedOpen = false;
this.matSidenav.mode = 'over';
this.matSidenav.close();
});
this.isLockedOpen = false;
this.matSidenav.mode = 'over';
this.matSidenav.toggle(false);
}
});
}
ngOnDestroy()

View File

@@ -82,10 +82,12 @@ export class FuseUtils
{
function S4()
{
return (((1 + Math.random()) * 0x10000) || 0).toString(16).substring(1);
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return (S4() + S4());
return S4() + S4();
}
public static toggleInArray(item, array)
@@ -99,4 +101,14 @@ export class FuseUtils
array.splice(array.indexOf(item), 1);
}
}
public static handleize(text)
{
return text.toString().toLowerCase()
.replace(/\s+/g, '-') // Replace spaces with -
.replace(/[^\w\-]+/g, '') // Remove all non-word chars
.replace(/\-\-+/g, '-') // Replace multiple - with single -
.replace(/^-+/, '') // Trim - from start of text
.replace(/-+$/, ''); // Trim - from end of text
}
}

View File

@@ -681,6 +681,7 @@ const matColors = {
}
};
// tslint:disable-next-line
const matPresetColors = [
'#ffebee', '#ffcdd2', '#ef9a9a', '#e57373', '#ef5350', '#f44336', '#e53935', '#d32f2f', '#c62828', '#b71c1c', '#ff8a80', '#ff5252', '#ff1744', '#d50000', '#fce4ec', '#f8bbd0', '#f48fb1', '#f06292', '#ec407a', '#e91e63', '#d81b60', '#c2185b', '#ad1457', '#880e4f', '#ff80ab', '#ff4081', '#f50057', '#c51162', '#f3e5f5', '#e1bee7', '#ce93d8', '#ba68c8', '#ab47bc', '#9c27b0', '#8e24aa', '#7b1fa2', '#6a1b9a', '#4a148c', '#ea80fc', '#e040fb', '#d500f9', '#aa00ff', '#ede7f6', '#d1c4e9', '#b39ddb', '#9575cd', '#7e57c2', '#673ab7', '#5e35b1', '#512da8', '#4527a0', '#311b92', '#b388ff', '#7c4dff', '#651fff', '#6200ea', '#e8eaf6', '#c5cae9', '#9fa8da', '#7986cb', '#5c6bc0', '#3f51b5', '#3949ab', '#303f9f', '#283593', '#1a237e', '#8c9eff', '#536dfe', '#3d5afe', '#304ffe', '#e3f2fd', '#bbdefb', '#90caf9', '#64b5f6', '#42a5f5', '#2196f3', '#1e88e5', '#1976d2', '#1565c0', '#0d47a1', '#82b1ff', '#448aff', '#2979ff', '#2962ff', '#e1f5fe', '#b3e5fc', '#81d4fa', '#4fc3f7', '#29b6f6', '#03a9f4', '#039be5', '#0288d1', '#0277bd', '#01579b', '#80d8ff', '#40c4ff', '#00b0ff', '#0091ea', '#e0f7fa', '#b2ebf2', '#80deea', '#4dd0e1', '#26c6da', '#00bcd4', '#00acc1', '#0097a7', '#00838f', '#006064', '#84ffff', '#18ffff', '#00e5ff', '#00b8d4', '#e0f2f1', '#b2dfdb', '#80cbc4', '#4db6ac', '#26a69a', '#009688', '#00897b', '#00796b', '#00695c', '#004d40', '#a7ffeb', '#64ffda', '#1de9b6', '#00bfa5', '#e8f5e9', '#c8e6c9', '#a5d6a7', '#81c784', '#66bb6a', '#4caf50', '#43a047', '#388e3c', '#2e7d32', '#1b5e20', '#b9f6ca', '#69f0ae', '#00e676', '#00c853', '#f1f8e9', '#dcedc8', '#c5e1a5', '#aed581', '#9ccc65', '#8bc34a', '#7cb342', '#689f38', '#558b2f', '#33691e', '#ccff90', '#b2ff59', '#76ff03', '#64dd17', '#f9fbe7', '#f0f4c3', '#e6ee9c', '#dce775', '#d4e157', '#cddc39', '#c0ca33', '#afb42b', '#9e9d24', '#827717', '#f4ff81', '#eeff41', '#c6ff00', '#aeea00', '#fffde7', '#fff9c4', '#fff59d', '#fff176', '#ffee58', '#ffeb3b', '#fdd835', '#fbc02d', '#f9a825', '#f57f17', '#ffff8d', '#ffff00', '#ffea00', '#ffd600', '#fff8e1', '#ffecb3', '#ffe082', '#ffd54f', '#ffca28', '#ffc107', '#ffb300', '#ffa000', '#ff8f00', '#ff6f00', '#ffe57f', '#ffd740', '#ffc400', '#ffab00', '#fff3e0', '#ffe0b2', '#ffcc80', '#ffb74d', '#ffa726', '#ff9800', '#fb8c00', '#f57c00', '#ef6c00', '#e65100', '#ffd180', '#ffab40', '#ff9100', '#ff6d00', '#fbe9e7', '#ffccbc', '#ffab91', '#ff8a65', '#ff7043', '#ff5722', '#f4511e', '#e64a19', '#d84315', '#bf360c', '#ff9e80', '#ff6e40', '#ff3d00', '#dd2c00', '#efebe9', '#d7ccc8', '#bcaaa4', '#a1887f', '#8d6e63', '#795548', '#6d4c41', '#5d4037', '#4e342e', '#3e2723', '#d7ccc8', '#bcaaa4', '#8d6e63', '#5d4037', '#fafafa', '#f5f5f5', '#eeeeee', '#e0e0e0', '#bdbdbd', '#9e9e9e', '#757575', '#616161', '#424242', '#212121', '#ffffff', '#eeeeee', '#bdbdbd', '#616161', '#eceff1', '#cfd8dc', '#b0bec5', '#90a4ae', '#78909c', '#607d8b', '#546e7a', '#455a64', '#37474f', '#263238', '#cfd8dc', '#b0bec5', '#78909c', '#455a64'
];

View File

@@ -5,21 +5,23 @@ import { CommonModule } from '@angular/common';
import { MaterialModule } from './material.module';
import { FlexLayoutModule } from '@angular/flex-layout';
import { ColorPickerModule } from 'ngx-color-picker';
import { NgxDnDModule } from '@swimlane/ngx-dnd';
import { NgxDnDModule } from '@withinpixels/ngx-dnd';
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import { FuseMatSidenavHelperDirective, FuseMatSidenavTogglerDirective } from '../directives/mat-sidenav-helper/mat-sidenav-helper.directive';
import { FuseMatSidenavHelperDirective, FuseMatSidenavTogglerDirective } from '../directives/fuse-mat-sidenav-helper/fuse-mat-sidenav-helper.directive';
import { FuseMatSidenavHelperService } from '../directives/fuse-mat-sidenav-helper/fuse-mat-sidenav-helper.service';
import { FusePipesModule } from '../pipes/pipes.module';
import { FuseConfirmDialogComponent } from '../components/confirm-dialog/confirm-dialog.component';
import { FuseCountdownComponent } from '../components/countdown/countdown.component';
import { FuseMatchMedia } from '../services/match-media.service';
import { FuseNavbarVerticalService } from '../../main/navbar/vertical/navbar-vertical.service';
import { FuseMatSidenavHelperService } from '../directives/mat-sidenav-helper/mat-sidenav-helper.service';
import { FuseHljsComponent } from '../components/hljs/hljs.component';
import { FusePerfectScrollbarDirective } from '../directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive';
import { FuseIfOnDomDirective } from '../directives/fuse-if-on-dom/fuse-if-on-dom.directive';
import { FuseMaterialColorPickerComponent } from '../components/material-color-picker/material-color-picker.component';
import { FuseTranslationLoaderService } from '../services/translation-loader.service';
import { CookieService } from 'ngx-cookie-service';
import { TranslateModule } from '@ngx-translate/core';
@NgModule({
declarations : [
@@ -59,7 +61,8 @@ import { CookieService } from 'ngx-cookie-service';
NgxDnDModule,
NgxDatatableModule,
FuseIfOnDomDirective,
FuseMaterialColorPickerComponent
FuseMaterialColorPickerComponent,
TranslateModule
],
entryComponents: [
FuseConfirmDialogComponent
@@ -68,7 +71,8 @@ import { CookieService } from 'ngx-cookie-service';
CookieService,
FuseMatchMedia,
FuseNavbarVerticalService,
FuseMatSidenavHelperService
FuseMatSidenavHelperService,
FuseTranslationLoaderService
]
})

View File

@@ -25,6 +25,7 @@
@import "partials/angular-material-fix";
@import "partials/typography";
@import "partials/page-layouts";
@import "partials/cards";
@import "partials/navigation";
@import "partials/forms";
@import "partials/toolbar";

View File

@@ -6,42 +6,6 @@
}
}
// Fix: "Sidenav opening with animations for the first time"
mat-sidenav-container {
mat-sidenav {
&[mat-is-locked-open].mat-stop-transition {
transition: none !important;
transform: translate3d(0, 0, 0) !important;
opacity: 0;
~ .mat-sidenav-content,
~ .mat-drawer-content {
transition: none !important;
}
}
&.mat-sidenav-opened {
&.mat-drawer-side {
~ .mat-sidenav-content,
~ .mat-drawer-content {
transition: none !important;
transform: translate3d(0, 0, 0) !important;
}
}
}
&.mat-drawer-end {
}
}
.mat-drawer-content {
}
}
// Fix: "Inconsistent font sizes across elements"
.mat-input-wrapper {
font-size: 16px;
@@ -59,3 +23,8 @@ mat-sidenav-container {
width: 14px;
height: 7px;
}
// Fix: "Input underlines has wrong color opacity value"
.mat-form-field-underline {
background-color: rgba(0, 0, 0, 0.12);
}

View File

@@ -0,0 +1,154 @@
.fuse-card {
max-width: 320px;
min-width: 320px;
background: white;
border-radius: 2px;
@include mat-elevation(2);
&.variable-width {
min-width: 0;
}
.card-rich-media {
position: relative;
.card-title {
position: absolute;
right: 16px;
bottom: 16px;
left: 16px;
font-size: 20px;
color: white;
}
}
.card-media-header {
display: flex;
padding: 16px;
align-items: center;
&.medium {
align-items: flex-start;
.card-rich-media {
width: 120px;
height: 120px;
}
}
&.large {
align-items: flex-start;
.card-rich-media {
width: 160px;
height: 160px;
}
}
.card-primary-title {
padding: 0 16px 0 0;
flex: 1;
}
.card-rich-media {
width: 80px;
height: 80px;
}
+ div {
padding-top: 0;
}
}
.card-avatar-header {
display: flex;
padding: 16px;
align-items: center;
.card-avatar {
width: 40px;
height: 40px;
border-radius: 100%;
margin-right: 16px;
}
.card-avatar-title {
.card-title {
font-size: 14px;
font-weight: bold;
}
.card-subtitle {
font-size: 13px;
font-weight: bold;
}
}
}
.card-primary-title {
padding: 16px;
.card-title {
font-size: 24px;
}
.card-subtitle {
font-size: 14px;
}
+ div {
padding-top: 0;
}
}
.card-supporting-text {
padding: 16px;
font-size: 14px;
line-height: 1.75;
+ div {
padding-top: 0;
}
}
.card-actions {
display: flex;
padding: 8px;
&.icon-buttons {
padding: 0 8px;
}
&.align-center {
justify-content: center;
}
&.align-right {
justify-content: flex-end;
}
.mat-button {
min-width: 0 !important;
padding: 0 8px !important;
}
.card-expander {
margin-left: auto;
}
+ div {
padding-top: 0;
}
}
.card-expand-area {
overflow: hidden;
.card-expanded-supporting-text {
padding: 8px 16px 16px 16px;
font-size: 14px;
line-height: 1.75;
}
}
}

View File

@@ -187,6 +187,11 @@ $matColorHues: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, A100, A200, A400
// Generate material element colors
// based on current contrast color
@include generateMaterialElementColors($contrastColor);
&[disabled] {
background-color: rgba($color, .12) !important;
color: rgba($contrastColor, .26) !important;
}
}
.#{$colorName}#{$hue}-fg {

View File

@@ -195,6 +195,10 @@
> .nav-item {
> .nav-link {
height: 56px;
}
&.nav-collapse {
position: relative;

View File

@@ -96,7 +96,7 @@ $top-bg-image: url('assets/images/backgrounds/header-bg.png');
max-height: $carded-toolbar-height;
}
.content {
> .content {
display: flex;
flex: 1;
overflow: auto;
@@ -222,6 +222,62 @@ $top-bg-image: url('assets/images/backgrounds/header-bg.png');
}
}
}
// Tabbed
&.tabbed {
> mat-sidenav-container {
> .mat-sidenav-content,
> .mat-drawer-content {
width: calc(100% - 240px);
.center {
width: calc(100% - 32px);
@include media-breakpoint-down('md') {
width: calc(100% - 64px);
}
.header {
flex: 1;
}
.content-card {
.content {
.mat-tab-group {
overflow: hidden;
.mat-tab-header {
.mat-tab-label {
height: 64px;
}
}
.mat-tab-body {
overflow: hidden;
.mat-tab-body-content {
overflow: hidden;
.tab-content {
position: relative;
width: 100%;
height: 100%;
overflow: auto;
}
}
}
}
}
}
}
}
}
}
}
// Left sidenav

View File

@@ -55,6 +55,7 @@
min-height: 48px;
transition: none;
padding: 0 24px;
overflow: hidden;
}
}
}
@@ -82,6 +83,16 @@
.datatable-pager {
margin: 0 0 0 24px;
.pager {
li {
a {
text-decoration: none !important;
}
}
}
}
}
}

View File

@@ -22,10 +22,11 @@ export class FuseConfigService
// Set the default settings
this.defaultSettings = {
layout : {
navigation: 'left', // 'right', 'left', 'top', 'none'
toolbar : 'below', // 'above', 'below', 'none'
footer : 'below', // 'above', 'below', 'none'
mode : 'fullwidth' // 'boxed', 'fullwidth'
navigation : 'left', // 'right', 'left', 'top', 'none'
navigationFolded: false, // true, false
toolbar : 'below', // 'above', 'below', 'none'
footer : 'below', // 'above', 'below', 'none'
mode : 'fullwidth' // 'boxed', 'fullwidth'
},
colorClasses : {
toolbar: 'mat-white-500-bg',
@@ -44,6 +45,7 @@ export class FuseConfigService
this.defaultSettings.customScrollbars = false;
}
// Set the settings from the default settings
this.settings = Object.assign({}, this.defaultSettings);
// Reload the default settings on every navigation start
@@ -58,7 +60,6 @@ export class FuseConfigService
// Create the behavior subject
this.onSettingsChanged = new BehaviorSubject(this.settings);
}
/**
@@ -67,7 +68,10 @@ export class FuseConfigService
*/
setSettings(settings)
{
// Set the settings from the given object
this.settings = Object.assign({}, this.settings, settings);
// Trigger the event
this.onSettingsChanged.next(this.settings);
}
}

View File

@@ -0,0 +1,27 @@
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
export interface Locale
{
lang: string;
data: Object;
}
@Injectable()
export class FuseTranslationLoaderService
{
constructor(private translate: TranslateService)
{
}
public loadTranslations(...args: Locale[]): void
{
const locales = [...args];
locales.forEach((locale) => {
// use setTranslation() with the third argument set to true
// to append translations instead of replacing them
this.translate.setTranslation(locale.lang, locale.data, true);
});
}
}

View File

@@ -0,0 +1,8 @@
export const locale = {
lang: 'en',
data: {
'SAMPLE': {
'HELLO': 'Hello, World!'
}
}
};

View File

@@ -0,0 +1,8 @@
export const locale = {
lang: 'tr',
data: {
'SAMPLE': {
'HELLO': 'Merhaba Dünya!'
}
}
};

View File

@@ -1,5 +1,5 @@
<div class="page-layout blank p-24" fusePerfectScrollbar>
<h2>Sample Page</h2>
<h2>{{'SAMPLE.HELLO' | translate}}</h2>
</div>

View File

@@ -1,4 +1,8 @@
import { Component } from '@angular/core';
import { FuseTranslationLoaderService } from '../../../core/services/translation-loader.service';
import { locale as english } from './i18n/en';
import { locale as turkish } from './i18n/tr';
@Component({
selector : 'fuse-sample',
@@ -7,7 +11,8 @@ import { Component } from '@angular/core';
})
export class FuseSampleComponent
{
constructor()
constructor(private translationLoader: FuseTranslationLoaderService)
{
this.translationLoader.loadTranslations(english, turkish);
}
}

View File

@@ -6,7 +6,7 @@
target="_blank" mat-button class="mat-pink-bg" fxFlex="0 0 auto" fxLayout="row"
fxLayoutAlign="start center">
<mat-icon class="s-16 mr-sm-4">shopping_cart</mat-icon>
<span>Purchase FUSE (Angular4+)</span>
<span>Purchase FUSE (Angular5+)</span>
</a>
<div fxLayout="row" fxLayoutAlign="start center" fxHide fxShow.gt-xs>

View File

@@ -4,13 +4,13 @@
<!-- TOOLBAR: Above -->
<ng-container *ngIf="fuseSettings.layout.toolbar === 'above'">
<fuse-toolbar class="above" [class]="fuseSettings.colorClasses.toolbar"></fuse-toolbar>
<fuse-toolbar class="above" [ngClass]="fuseSettings.colorClasses.toolbar"></fuse-toolbar>
</ng-container>
<!-- / TOOLBAR: Above -->
<!-- NAVBAR: Top -->
<fuse-navbar-horizontal class="top-navbar" fxHide fxShow.gt-md
[class]="fuseSettings.colorClasses.navbar"
[ngClass]="fuseSettings.colorClasses.navbar"
*ngIf="fuseSettings.layout.navigation === 'top'">
</fuse-navbar-horizontal>
<!-- / NAVBAR: Top -->
@@ -18,9 +18,9 @@
<div id="wrapper">
<!-- NAVBAR: Left -->
<fuse-navbar-vertical [folded]="false"
<fuse-navbar-vertical [folded]="fuseSettings.layout.navigationFolded"
class="left-navbar"
[class]="fuseSettings.colorClasses.navbar"
[ngClass]="fuseSettings.colorClasses.navbar"
*ngIf="fuseSettings.layout.navigation === 'left' || fuseSettings.layout.navigation === 'top'">
</fuse-navbar-vertical>
<!-- / NAVBAR: Left -->
@@ -29,7 +29,7 @@
<!-- TOOLBAR: Below -->
<ng-container *ngIf="fuseSettings.layout.toolbar === 'below'">
<fuse-toolbar class="below" [class]="fuseSettings.colorClasses.toolbar"></fuse-toolbar>
<fuse-toolbar class="below" [ngClass]="fuseSettings.colorClasses.toolbar"></fuse-toolbar>
</ng-container>
<!-- / TOOLBAR: Below -->
@@ -37,16 +37,16 @@
<!-- FOOTER: Below -->
<ng-container *ngIf="fuseSettings.layout.footer === 'below'">
<fuse-footer class="below" [class]="fuseSettings.colorClasses.footer"></fuse-footer>
<fuse-footer class="below" [ngClass]="fuseSettings.colorClasses.footer"></fuse-footer>
</ng-container>
<!-- / FOOTER: Below -->
</div>
<!-- NAVBAR: Right -->
<fuse-navbar-vertical [folded]="false"
<fuse-navbar-vertical [folded]="fuseSettings.layout.navigationFolded"
class="right-navbar"
[class]="fuseSettings.colorClasses.navbar"
[ngClass]="fuseSettings.colorClasses.navbar"
*ngIf="fuseSettings.layout.navigation === 'right'">
</fuse-navbar-vertical>
<!-- / NAVBAR: Right -->
@@ -55,7 +55,7 @@
<!-- FOOTER: Above -->
<ng-container *ngIf="fuseSettings.layout.footer === 'above'">
<fuse-footer class="above" [class]="fuseSettings.colorClasses.footer"></fuse-footer>
<fuse-footer class="above" [ngClass]="fuseSettings.colorClasses.footer"></fuse-footer>
</ng-container>
<!-- FOOTER: Above -->

View File

@@ -6,12 +6,6 @@ fuse-main {
width: 100%;
height: 100%;
&.boxed {
max-width: 1200px;
margin: 0 auto;
@include mat-elevation(8);
}
> .mat-sidenav-container {
display: flex;
flex: 1;
@@ -72,4 +66,10 @@ fuse-main {
}
}
}
&[fuse-layout-mode="boxed"] {
max-width: 1200px;
margin: 0 auto;
@include mat-elevation(8);
}
}

View File

@@ -14,7 +14,7 @@ export class FuseMainComponent implements OnInit, OnDestroy
{
onSettingsChanged: Subscription;
fuseSettings: any;
@HostBinding('class.boxed') boxed;
@HostBinding('attr.fuse-layout-mode') layoutMode;
constructor(
private _renderer: Renderer2,
@@ -29,7 +29,7 @@ export class FuseMainComponent implements OnInit, OnDestroy
.subscribe(
(newSettings) => {
this.fuseSettings = newSettings;
this.boxed = this.fuseSettings.layout.mode === 'boxed';
this.layoutMode = this.fuseSettings.layout.mode;
}
);

View File

@@ -1,4 +1,5 @@
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { FuseMainComponent } from '../../main.component';
@Component({
selector : 'fuse-navbar-horizontal',
@@ -6,14 +7,19 @@ import { Component, OnInit, ViewEncapsulation } from '@angular/core';
styleUrls : ['./navbar-horizontal.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class FuseNavbarHorizontalComponent implements OnInit
export class FuseNavbarHorizontalComponent implements OnInit, OnDestroy
{
constructor()
constructor(private fuseMainComponent: FuseMainComponent)
{
}
ngOnInit()
{
this.fuseMainComponent.addClass('fuse-nav-bar-horizontal');
}
ngOnDestroy()
{
this.fuseMainComponent.removeClass('fuse-nav-bar-horizontal');
}
}

View File

@@ -2,7 +2,7 @@
fuse-main {
&.fuse-nav-bar-folded {
&.fuse-nav-bar-folded:not(.fuse-nav-bar-horizontal) {
.content-wrapper {

View File

@@ -18,13 +18,34 @@ import { animate, AnimationBuilder, AnimationPlayer, style } from '@angular/anim
export class FuseNavbarVerticalComponent implements OnInit, OnDestroy
{
private _backdropElement: HTMLElement | null = null;
private _folded = false;
@HostBinding('class.close') isClosed: boolean;
@HostBinding('class.folded') isFoldedActive: boolean;
@HostBinding('class.folded-open') isFoldedOpen: boolean;
@HostBinding('class.initialized') initialized: boolean;
@Input('folded') foldedByDefault = false;
@ViewChild(FusePerfectScrollbarDirective) fusePerfectScrollbarDirective;
@Input()
set folded(value: boolean)
{
this._folded = value;
if ( this._folded )
{
this.activateFolded();
}
else
{
this.deActivateFolded();
}
}
get folded(): boolean
{
return this._folded;
}
matchMediaWatcher: Subscription;
navigationServiceWatcher: Subscription;
fusePerfectScrollbarUpdateTimeout;
@@ -36,11 +57,11 @@ export class FuseNavbarVerticalComponent implements OnInit, OnDestroy
private fuseMatchMedia: FuseMatchMedia,
private fuseNavigationService: FuseNavigationService,
private navBarService: FuseNavbarVerticalService,
public media: ObservableMedia,
private router: Router,
private _renderer: Renderer2,
private _elementRef: ElementRef,
private animationBuilder: AnimationBuilder
private animationBuilder: AnimationBuilder,
public media: ObservableMedia
)
{
navBarService.setNavBar(this);
@@ -88,7 +109,7 @@ export class FuseNavbarVerticalComponent implements OnInit, OnDestroy
ngOnInit()
{
this.isClosed = false;
this.isFoldedActive = this.foldedByDefault;
this.isFoldedActive = this._folded;
this.isFoldedOpen = false;
this.initialized = false;
this.updateCssClasses();
@@ -104,7 +125,7 @@ export class FuseNavbarVerticalComponent implements OnInit, OnDestroy
}
else
{
if ( !this.foldedByDefault )
if ( !this._folded )
{
this.deActivateFolded();
}
@@ -124,6 +145,11 @@ export class FuseNavbarVerticalComponent implements OnInit, OnDestroy
openBar()
{
if ( !this.isClosed )
{
return;
}
this.isClosed = false;
this.updateCssClasses();
if ( this.media.isActive('lt-lg') )
@@ -134,6 +160,11 @@ export class FuseNavbarVerticalComponent implements OnInit, OnDestroy
closeBar()
{
if ( this.isClosed )
{
return;
}
this.isClosed = true;
this.updateCssClasses();
this._detachBackdrop();
@@ -191,15 +222,15 @@ export class FuseNavbarVerticalComponent implements OnInit, OnDestroy
updateCssClasses()
{
if ( this.isClosed )
if ( !this.isClosed )
{
this.fuseMainComponent.addClass('fuse-nav-bar-opened');
this.fuseMainComponent.removeClass('fuse-nav-bar-closed');
this.fuseMainComponent.addClass('fuse-navbar-opened');
this.fuseMainComponent.removeClass('fuse-navbar-closed');
}
else
{
this.fuseMainComponent.addClass('fuse-nav-bar-closed');
this.fuseMainComponent.removeClass('fuse-nav-bar-opened');
this.fuseMainComponent.addClass('fuse-navbar-closed');
this.fuseMainComponent.removeClass('fuse-navbar-opened');
}
}

View File

@@ -10,6 +10,8 @@ export class FuseQuickPanelComponent implements OnInit
{
date: Date;
settings: any;
notes = [];
events = [];
constructor()
{

View File

@@ -7,7 +7,7 @@
<div fxFlex="1 0 auto" fxLayout="row" fxLayoutAlign="start center">
<button mat-button class="toggle-button-navbar mat-icon-button"
fuseNavbarVertical="openBar" fxHide.gt-md>
fuseNavbarVertical="toggleBar" fxHide.gt-md>
<mat-icon>menu</mat-icon>
</button>
@@ -71,12 +71,14 @@
</button>
<mat-menu #languageMenu="matMenu">
<button mat-menu-item *ngFor="let lang of languages" (click)="selectedLanguage = lang">
<button mat-menu-item *ngFor="let lang of languages" (click)="setLanguage(lang)">
<div fxLayout="row" fxLayoutAlign="start center">
<img class="flag mr-16" [src]="'assets/images/flags/'+lang.flag+'.png'">
<span class="iso">{{lang.title}}</span>
</div>
</button>
</mat-menu>
<div class="toolbar-separator" fxHide fxShow.gt-xs></div>

View File

@@ -1,6 +1,7 @@
import { Component } from '@angular/core';
import { NavigationEnd, NavigationStart, Router } from '@angular/router';
import { FuseConfigService } from '../../core/services/config.service';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector : 'fuse-toolbar',
@@ -18,7 +19,8 @@ export class FuseToolbarComponent
constructor(
private router: Router,
private fuseConfig: FuseConfigService
private fuseConfig: FuseConfigService,
private translate: TranslateService
)
{
this.userStatusOptions = [
@@ -55,11 +57,6 @@ export class FuseToolbarComponent
'title': 'English',
'flag' : 'us'
},
{
'id' : 'es',
'title': 'Spanish',
'flag' : 'es'
},
{
'id' : 'tr',
'title': 'Turkish',
@@ -92,4 +89,13 @@ export class FuseToolbarComponent
// Do your search here...
console.log(value);
}
setLanguage(lang)
{
// Set the selected language for toolbar
this.selectedLanguage = lang;
// Use the selected language for translations
this.translate.use(lang.id);
}
}

View File

@@ -1,21 +0,0 @@
div {
display: flex;
}
input {
border: none;
background: none;
padding: 0;
outline: none;
font: inherit;
text-align: center;
}
span {
opacity: 0;
transition: opacity 200ms;
}
:host.floating span {
opacity: 1;
}

View File

@@ -1,7 +0,0 @@
<div [formGroup]="parts">
<input class="area" formControlName="area" size="3" [disabled]="disabled">
<span>&ndash;</span>
<input class="exchange" formControlName="exchange" size="3" [disabled]="disabled">
<span>&ndash;</span>
<input class="subscriber" formControlName="subscriber" size="4" [disabled]="disabled">
</div>

View File

@@ -1,177 +0,0 @@
import { FocusMonitor } from '@angular/cdk/a11y';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { Component, ElementRef, Input, OnDestroy, Renderer2 } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { MatFormFieldControl } from '@angular/material/form-field';
import { Subject } from 'rxjs/Subject';
/** Data structure for holding telephone number. */
export class MyTel
{
constructor(public area: string, public exchange: string, public subscriber: string)
{
}
}
/** Custom `MatFormFieldControl` for telephone number input. */
@Component({
selector : 'my-tel-input',
templateUrl: 'form-field-custom-control-example.html',
styleUrls : ['form-field-custom-control-example.css'],
providers : [
{
provide : MatFormFieldControl,
useExisting: MyTelInput
}
],
host : {
'[class.floating]' : 'shouldPlaceholderFloat',
'[id]' : 'id',
'[attr.aria-describedby]': 'describedBy'
}
})
export class MyTelInput implements MatFormFieldControl<MyTel>, OnDestroy
{
static nextId = 0;
parts: FormGroup;
stateChanges = new Subject<void>();
focused = false;
ngControl = null;
errorState = false;
controlType = 'my-tel-input';
get empty()
{
let n = this.parts.value;
return !n.area && !n.exchange && !n.subscriber;
}
get shouldPlaceholderFloat()
{
return this.focused || !this.empty;
}
id = `my-tel-input-${MyTelInput.nextId++}`;
describedBy = '';
@Input()
get placeholder()
{
return this._placeholder;
}
set placeholder(plh)
{
this._placeholder = plh;
this.stateChanges.next();
}
private _placeholder: string;
@Input()
get required()
{
return this._required;
}
set required(req)
{
this._required = coerceBooleanProperty(req);
this.stateChanges.next();
}
private _required = false;
@Input()
get disabled()
{
return this._disabled;
}
set disabled(dis)
{
this._disabled = coerceBooleanProperty(dis);
this.stateChanges.next();
}
private _disabled = false;
@Input()
get value(): MyTel | null
{
let n = this.parts.value;
if ( n.area.length == 3 && n.exchange.length == 3 && n.subscriber.length == 4 )
{
return new MyTel(n.area, n.exchange, n.subscriber);
}
return null;
}
set value(tel: MyTel | null)
{
tel = tel || new MyTel('', '', '');
this.parts.setValue({
area : tel.area,
exchange : tel.exchange,
subscriber: tel.subscriber
});
this.stateChanges.next();
}
constructor(fb: FormBuilder, private fm: FocusMonitor, private elRef: ElementRef,
renderer: Renderer2
)
{
this.parts = fb.group({
'area' : '',
'exchange' : '',
'subscriber': ''
});
fm.monitor(elRef.nativeElement, renderer, true).subscribe((origin) => {
this.focused = !!origin;
this.stateChanges.next();
});
}
ngOnDestroy()
{
this.stateChanges.complete();
this.fm.stopMonitoring(this.elRef.nativeElement);
}
setDescribedByIds(ids: string[])
{
this.describedBy = ids.join(' ');
}
onContainerClick(event: MouseEvent)
{
if ( (event.target as Element).tagName.toLowerCase() != 'input' )
{
this.elRef.nativeElement.querySelector('input').focus();
}
}
}
/** @title Form field with custom telephone number input control. */
@Component({
selector: 'form-field-custom-control-example',
template: `
<mat-form-field>
<my-tel-input placeholder="Phone number" required></my-tel-input>
<mat-icon matSuffix>phone</mat-icon>
<mat-hint>Include area code</mat-hint>
</mat-form-field>
`
})
export class FormFieldCustomControlExample
{
}

View File

@@ -1,8 +0,0 @@
.example-container {
display: flex;
flex-direction: column;
}
.example-container > * {
width: 100%;
}

View File

@@ -1,6 +0,0 @@
<div class="example-container">
<mat-form-field>
<input matInput placeholder="Enter your email" [formControl]="email" required>
<mat-error *ngIf="email.invalid">{{getErrorMessage()}}</mat-error>
</mat-form-field>
</div>

View File

@@ -1,20 +0,0 @@
import { Component } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';
/** @title Form field with error messages */
@Component({
selector : 'form-field-error-example',
templateUrl: 'form-field-error-example.html',
styleUrls : ['form-field-error-example.css']
})
export class FormFieldErrorExample
{
email = new FormControl('', [Validators.required, Validators.email]);
getErrorMessage()
{
return this.email.hasError('required') ? 'You must enter a value' :
this.email.hasError('email') ? 'Not a valid email' :
'';
}
}

View File

@@ -1,8 +0,0 @@
.example-container {
display: flex;
flex-direction: column;
}
.example-container > * {
width: 100%;
}

View File

@@ -1,13 +0,0 @@
<div class="example-container">
<mat-form-field hintLabel="Max 10 characters">
<input matInput #input maxlength="10" placeholder="Enter some input">
<mat-hint align="end">{{input.value?.length || 0}}/10</mat-hint>
</mat-form-field>
<mat-form-field>
<mat-select placeholder="Select me">
<mat-option value="option">Option</mat-option>
</mat-select>
<mat-hint align="end">Here's the dropdown arrow ^</mat-hint>
</mat-form-field>
</div>

View File

@@ -1,11 +0,0 @@
import { Component } from '@angular/core';
/** @title Form field with hints */
@Component({
selector : 'form-field-hint-example',
templateUrl: 'form-field-hint-example.html',
styleUrls : ['form-field-hint-example.css']
})
export class FormFieldHintExample
{
}

View File

@@ -1,8 +0,0 @@
.example-container {
display: flex;
flex-direction: column;
}
.example-container > * {
width: 100%;
}

View File

@@ -1,15 +0,0 @@
<div class="example-container">
<mat-form-field>
<input matInput placeholder="Input">
</mat-form-field>
<mat-form-field>
<textarea matInput placeholder="Textarea"></textarea>
</mat-form-field>
<mat-form-field>
<mat-select placeholder="Select">
<mat-option value="option">Option</mat-option>
</mat-select>
</mat-form-field>
</div>

View File

@@ -1,11 +0,0 @@
import { Component } from '@angular/core';
/** @title Simple form field */
@Component({
selector : 'form-field-overview-example',
templateUrl: 'form-field-overview-example.html',
styleUrls : ['form-field-overview-example.css']
})
export class FormFieldOverviewExample
{
}

View File

@@ -1,20 +0,0 @@
.example-container {
display: flex;
flex-direction: column;
}
.example-container > * {
width: 100%;
}
.example-container form {
margin-bottom: 20px;
}
.example-container form > * {
margin: 5px 0;
}
.example-container .mat-radio-button {
margin: 0 5px;
}

View File

@@ -1,31 +0,0 @@
<div class="example-container">
<form class="example-container" [formGroup]="options">
<mat-checkbox formControlName="hideRequired">Hide required marker</mat-checkbox>
<div>
<label>Float placeholder: </label>
<mat-radio-group formControlName="floatPlaceholder">
<mat-radio-button value="auto">Auto</mat-radio-button>
<mat-radio-button value="always">Always</mat-radio-button>
<mat-radio-button value="never">Never</mat-radio-button>
</mat-radio-group>
</div>
</form>
<mat-form-field
[hideRequiredMarker]="options.value.hideRequired"
[floatPlaceholder]="options.value.floatPlaceholder">
<input matInput placeholder="Simple placeholder" required>
</mat-form-field>
<mat-form-field
[hideRequiredMarker]="options.value.hideRequired"
[floatPlaceholder]="options.value.floatPlaceholder">
<mat-select required>
<mat-option>-- None --</mat-option>
<mat-option value="option">Option</mat-option>
</mat-select>
<mat-placeholder>
<mat-icon>favorite</mat-icon>
<b> Fancy</b> <i> placeholder</i></mat-placeholder>
</mat-form-field>
</div>

View File

@@ -1,21 +0,0 @@
import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
/** @title Form field with placeholder */
@Component({
selector : 'form-field-placeholder-example',
templateUrl: 'form-field-placeholder-example.html',
styleUrls : ['form-field-placeholder-example.css']
})
export class FormFieldPlaceholderExample
{
options: FormGroup;
constructor(fb: FormBuilder)
{
this.options = fb.group({
hideRequired : false,
floatPlaceholder: 'auto'
});
}
}

View File

@@ -1,17 +0,0 @@
.example-container {
display: flex;
flex-direction: column;
}
.example-container > * {
width: 100%;
}
.example-right-align {
text-align: right;
}
input.example-right-align::-webkit-outer-spin-button,
input.example-right-align::-webkit-inner-spin-button {
display: none;
}

View File

@@ -1,12 +0,0 @@
<div class="example-container">
<mat-form-field>
<input matInput placeholder="Enter your password" [type]="hide ? 'password' : 'text'">
<mat-icon matSuffix (click)="hide = !hide">{{hide ? 'visibility' : 'visibility_off'}}</mat-icon>
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Amount" type="number" class="example-right-align">
<span matPrefix>$&nbsp;</span>
<span matSuffix>.00</span>
</mat-form-field>
</div>

View File

@@ -1,12 +0,0 @@
import { Component } from '@angular/core';
/** @title Form field with prefix & suffix */
@Component({
selector : 'form-field-prefix-suffix-example',
templateUrl: 'form-field-prefix-suffix-example.html',
styleUrls : ['form-field-prefix-suffix-example.css']
})
export class FormFieldPrefixSuffixExample
{
hide = true;
}

View File

@@ -1,8 +0,0 @@
.example-container {
display: flex;
flex-direction: column;
}
.example-container > * {
width: 100%;
}

View File

@@ -1,14 +0,0 @@
<form class="example-container" [formGroup]="options" [style.fontSize.px]="getFontSize()">
<mat-form-field [color]="options.value.color">
<mat-select placeholder="Color" formControlName="color">
<mat-option value="primary">Primary</mat-option>
<mat-option value="accent">Accent</mat-option>
<mat-option value="warn">Warn</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field [color]="options.value.color">
<input matInput type="number" placeholder="Font size (px)" formControlName="fontSize" min="10">
<mat-error *ngIf="options.get('fontSize').invalid">Min size: 10px</mat-error>
</mat-form-field>
</form>

View File

@@ -1,26 +0,0 @@
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
/** @title Form field theming */
@Component({
selector : 'form-field-theming-example',
templateUrl: 'form-field-theming-example.html',
styleUrls : ['form-field-theming-example.css']
})
export class FormFieldThemingExample
{
options: FormGroup;
constructor(fb: FormBuilder)
{
this.options = fb.group({
'color' : 'primary',
'fontSize': [16, Validators.min(10)]
});
}
getFontSize()
{
return Math.max(10, this.options.value.fontSize);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -3,12 +3,12 @@
<head>
<title>Fuse2 - Angular 4+ Material Design Admin Template</title>
<title>Fuse2 - Angular 5+ Material Design Admin Template</title>
<base href="/">
<meta charset="utf-8">
<meta name="description" content="Material design admin template with pre-built apps and pages">
<meta name="keywords" content="HTML,CSS,AngularJS,Angular,Angular 4,Angular 5,Angular 6, Material">
<meta name="keywords" content="HTML,CSS,AngularJS,Angular,Angular 4,Angular 5,Angular 6,Material">
<meta name="author" content="Withinpixels">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

View File

@@ -39,14 +39,17 @@ import 'core-js/es7/array';
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
import 'classlist.js'; // Run `npm install --save classlist.js`.
/** IE10 and IE11 requires the following to support `@angular/animation`. */
import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/** IE10 and IE11 requires the following for the Reflect API. */
import 'core-js/es6/reflect';
/** Evergreen browsers require these. **/
import 'core-js/es6/reflect';
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
import 'core-js/es7/reflect';
/** ALL Firefox browsers require the following to support `@angular/animation`. **/
/**
* Required to support Web Animations `@angular/platform-browser/animations`.
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
**/
import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/***************************************************************************************************

View File

@@ -17,8 +17,7 @@ declare const __karma__: any;
declare const require: any;
// Prevent Karma from running prematurely.
__karma__.loaded = function () {
};
__karma__.loaded = function () {};
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(

View File

@@ -2,8 +2,8 @@
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"baseUrl": "./",
"module": "es2015",
"baseUrl": "",
"types": []
},
"exclude": [

View File

@@ -2,9 +2,9 @@
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/spec",
"baseUrl": "./",
"module": "commonjs",
"target": "es5",
"baseUrl": "",
"types": [
"jasmine",
"node"

4
src/typings.d.ts vendored
View File

@@ -1,7 +1,5 @@
/* SystemJS module definition */
declare var module: NodeModule;
interface NodeModule
{
interface NodeModule {
id: string;
}

View File

@@ -2,7 +2,6 @@
"compileOnSave": false,
"compilerOptions": {
"outDir": "./dist/out-tsc",
"baseUrl": "src",
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
@@ -13,8 +12,14 @@
"node_modules/@types"
],
"lib": [
"es2016",
"es2017",
"dom"
]
},
"angularCompilerOptions": {
"genDir": "release/",
"strictMetadataEmit": true,
"skipTemplateCodegen": true,
"annotationsAs": "decorators"
}
}

View File

@@ -15,7 +15,8 @@
"forin": true,
"import-blacklist": [
true,
"rxjs"
"rxjs",
"rxjs/Rx"
],
"import-spacing": true,
"indent": [
@@ -31,8 +32,14 @@
"member-access": false,
"member-ordering": [
true,
"static-before-instance",
"variables-before-functions"
{
"order": [
"static-field",
"instance-field",
"static-method",
"instance-method"
]
}
],
"no-arg": true,
"no-bitwise": true,
@@ -63,7 +70,7 @@
"no-trailing-whitespace": false,
"no-unnecessary-initializer": true,
"no-unused-expression": true,
"no-use-before-declare": true,
"no-use-before-declare": false,
"no-var-keyword": true,
"object-literal-sort-keys": false,
"one-line": false,