Compare commits

..

56 Commits

Author SHA1 Message Date
Sercan Yemen
33d295f42c Merge branch 'master' into skeleton 2018-01-02 12:37:12 +03:00
Sercan Yemen
91e277ce3f Merge branch 'master' into skeleton 2018-01-02 12:32:01 +03:00
Sercan Yemen
b7a3d35eb8 Updated package-lock.json 2017-12-28 10:52:40 +03:00
Sercan Yemen
f29f11232f Merge branch 'master' into skeleton 2017-12-28 10:51:09 +03:00
Sercan Yemen
16ffb09350 Merge branch 'master' into skeleton 2017-12-26 10:49:15 +03:00
Sercan Yemen
643a129a46 Merge branch 'master' into skeleton 2017-12-21 10:06:16 +03:00
Sercan Yemen
de16f4f866 Merge branch 'master' into skeleton 2017-12-18 12:25:56 +03:00
Sercan Yemen
415d7cebfa Skeleton updates 2017-12-14 16:20:52 +03:00
Sercan Yemen
f7d1995f63 Merge branch 'master' into skeleton 2017-12-14 16:06:32 +03:00
Sercan Yemen
3741abc063 Skeleton package updates 2017-12-14 16:03:34 +03:00
Sercan Yemen
54ccdd7de2 Merge branch 'master' into skeleton 2017-12-14 16:01:09 +03:00
Sercan Yemen
8b2e6b95b1 Merge branch 'master' into skeleton 2017-11-30 15:56:00 +03:00
Sercan Yemen
e86cea1e73 Merge branch 'master' into skeleton 2017-11-30 10:38:03 +03:00
Sercan Yemen
b81638690e Merge branch 'master' into skeleton 2017-11-30 10:23:19 +03:00
Sercan Yemen
20ac3abb25 Merge branch 'master' into skeleton 2017-11-27 17:21:38 +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
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
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
381bc6c0fe Merge branch 'master' into skeleton 2017-11-04 16:50:03 +03:00
Sercan Yemen
b5a139f81d Merge branch 'master' into skeleton 2017-11-04 16:32:29 +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
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
80627bdde9 removed fake-db thingy 2017-10-16 10:50:57 +03:00
Sercan Yemen
6595975f2b Merge branch 'master' into skeleton 2017-10-16 10:45:27 +03:00
Sercan Yemen
dcb8032758 Merge branch 'master' into skeleton 2017-10-16 10:10:06 +03:00
Sercan Yemen
fb214da5fe Merge branch 'master' into skeleton 2017-10-14 18:53:08 +03:00
Sercan Yemen
e20687034f Merge branch 'master' into skeleton 2017-10-14 18:53:00 +03:00
Sercan Yemen
f9bda99deb Merge branch 'master' into skeleton 2017-10-02 10:15:00 +03:00
Sercan Yemen
1d81e37a0f removed markdown module imports 2017-09-28 13:00:44 +03:00
Sercan Yemen
83f0ed5ec1 Merge branch 'master' into skeleton 2017-09-28 12:52:59 +03:00
Sercan Yemen
e486413872 remove unnecessary stuff from skeleton 2017-09-28 12:51:15 +03:00
Sercan Yemen
576e167ef1 Merge branch 'master' into skeleton 2017-09-28 12:49:18 +03:00
Sercan Yemen
cf9e9fc209 Merge branch 'master' into skeleton 2017-09-22 16:45:47 +03:00
Sercan Yemen
ff0f2933d9 Merge branch 'master' into skeleton 2017-09-22 16:45:23 +03:00
Sercan Yemen
62467c8ddf Merge branch 'master' into skeleton 2017-09-12 16:06:21 +03:00
Sercan Yemen
024ab15b25 Merge branch 'master' into skeleton 2017-09-11 16:34:07 +03:00
Sercan Yemen
915ad52863 Merge branch 'master' into skeleton 2017-09-11 16:21:05 +03:00
Sercan Yemen
97bfaa9979 Merge branch 'master' into skeleton 2017-09-11 13:06:42 +03:00
Sercan Yemen
6ae3e154c3 Merge branch 'master' into skeleton 2017-09-11 12:59:36 +03:00
Sercan Yemen
49b6ff7292 navigation model for horizontal nav 2017-09-11 12:58:24 +03:00
Sercan Yemen
903688ab43 Merge branch 'master' into skeleton 2017-09-11 12:57:59 +03:00
Sercan Yemen
19f822cbab removed unnecessary md2 from skeleton 2017-09-01 09:05:56 +03:00
Sercan Yemen
1d21a14d0e Merge branch 'master' into skeleton 2017-08-30 20:52:23 +03:00
Sercan Yemen
4bf2ba73ad merge 'master' into skeleton 2017-08-30 20:08:12 +03:00
Sercan Yemen
6a3972fff8 Merge branch 'master' into skeleton 2017-08-30 14:43:10 +03:00
Sercan Yemen
dca16238eb Merge branch 'master' into skeleton 2017-08-30 14:41:30 +03:00
Sercan Yemen
2b91119d00 Merge branch 'master' into skeleton 2017-08-30 11:50:56 +03:00
Sercan Yemen
ff4899e8d2 Merge branch 'master' into skeleton
# Conflicts:
#	src/app/app.module.ts
#	src/app/main/content/apps/calendar/calendar.component.html
#	src/app/main/content/apps/contacts/contact-list/contact-list.component.html
#	src/app/main/content/apps/contacts/contacts.component.html
#	src/app/main/content/apps/contacts/contacts.component.scss
#	src/app/main/content/apps/contacts/contacts.module.ts
#	src/app/main/content/apps/contacts/contacts.service.ts
#	src/app/main/content/apps/contacts/selected-bar/selected-bar.component.html
#	src/app/main/content/apps/mail/sidenavs/main/main-sidenav.component.html
#	src/app/navigation.model.ts
2017-08-24 11:18:24 +03:00
Sercan Yemen
e818c53f1d navbar fixes 2017-08-22 16:05:32 +03:00
Sercan Yemen
ca96fffadf removed fuse fake db 2017-08-22 15:58:35 +03:00
Sercan Yemen
d7003711ee skeleton branch 2017-08-22 15:55:48 +03:00
1388 changed files with 9732 additions and 90702 deletions

73
.angular-cli.json Normal file
View File

@@ -0,0 +1,73 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
"name": "fuse2"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"favicon.ico"
],
"index": "index.html",
"main": "main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"styles.scss"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"hmr": "environments/environment.hmr.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "src/tsconfig.app.json",
"exclude": [
"**/node_modules/**",
"**/src/app/fuse-fake-db/**/*",
"**/src/assets/angular-material-examples/**/*"
]
},
{
"project": "src/tsconfig.spec.json",
"exclude": [
"**/node_modules/**",
"**/src/app/fuse-fake-db/**/*",
"**/src/assets/angular-material-examples/**/*"
]
},
{
"project": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**",
"**/src/app/fuse-fake-db/**/*",
"**/src/assets/angular-material-examples/**/*"
]
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "scss",
"component": {}
}
}

View File

@@ -1,6 +1,12 @@
root = true
[*]
charset=utf-8
end_of_line=lf
insert_final_newline=false
indent_style=space
indent_size=4
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
max_line_length = off
trim_trailing_whitespace = false

5
.gitignore vendored
View File

@@ -30,10 +30,13 @@
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# e2e
/e2e/*.js
/e2e/*.map
# System Files
.DS_Store
Thumbs.db

View File

@@ -1,12 +1,6 @@
# Fuse - Angular
# Fuse2
Material Design Admin Template with Angular 6+ and Angular Material
## The Community
Share your ideas, discuss Fuse and help each other.
[Click here](http://fusetheme.com/community) to see our Community page.
Material Design Admin Template with Angular 5+ and Angular Material 2
## Development server
@@ -14,11 +8,11 @@ Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app w
## Code scaffolding
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|module`.
## Build
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
## Running unit tests
@@ -27,8 +21,4 @@ Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.
## Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
Before running the tests make sure you are serving the app via `ng serve`.

View File

@@ -1,150 +0,0 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"fuse": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"@schematics/angular:component": {
"styleext": "scss"
}
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets",
"src/app/main/angular-material-elements"
],
"styles": [
"src/styles.scss"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
},
"ec": {
"sourceMap": true,
"extractCss": true
},
"hmr": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.hmr.ts"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "fuse:build"
},
"configurations": {
"production": {
"browserTarget": "fuse:build:production"
},
"hmr": {
"hmr": true,
"browserTarget": "fuse:build:hmr"
},
"ec": {
"browserTarget": "fuse:build:ec"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "fuse:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"styles.scss"
],
"scripts": [],
"assets": [
"src/favicon.ico",
"src/assets"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**",
"**/src/app/fake-db/**/*",
"**/src/assets/angular-material-examples/**/*"
]
}
}
}
},
"fuse-e2e": {
"root": "e2e/",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "fuse:serve"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**",
"**/src/app/fake-db/**/*",
"**/src/assets/angular-material-examples/**/*"
]
}
}
}
}
},
"defaultProject": "fuse"
}

View File

@@ -9,6 +9,6 @@ describe('Fuse2 App', () => {
it('should display welcome message', () => {
page.navigateTo();
expect(page.getParagraphText()).toEqual('Welcome to Fuse2!');
expect(page.getParagraphText()).toEqual('Welcome to app!');
});
});

View File

@@ -1,31 +0,0 @@
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const {SpecReporter} = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs : [
'./src/**/*.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: require('path').join(__dirname, './tsconfig.e2e.json')
});
jasmine.getEnv().addReporter(new SpecReporter({spec: {displayStacktrace: true}}));
}
};

View File

@@ -1,7 +1,8 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"outDir": "../out-tsc/e2e",
"baseUrl": "./",
"module": "commonjs",
"target": "es5",
"types": [

33
karma.conf.js Normal file
View File

@@ -0,0 +1,33 @@
// Karma configuration file, see link for more information
// 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
});
};

14394
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,88 +1,80 @@
{
"name": "fuse",
"version": "6.2.2",
"name": "fuse2",
"version": "1.3.1",
"license": "https://themeforest.net/licenses/terms/regular",
"scripts": {
"ng": "ng",
"start": "ng serve --open",
"start-hmr": "ng serve --configuration hmr --source-map=false --hmr-warning=false",
"start-hmr-sourcemaps": "ng serve --configuration hmr --source-map=true --hmr-warning=false",
"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=6144 ./node_modules/@angular/cli/bin/ng build --dev",
"build-stats": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --dev --stats-json",
"build-prod": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --prod",
"build-prod-stats": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --prod --stats-json",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"bundle-report": "webpack-bundle-analyzer dist/stats.json"
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@agm/core": "1.0.0-beta.3",
"@angular/animations": "6.0.7",
"@angular/cdk": "6.3.3",
"@angular/common": "6.0.7",
"@angular/compiler": "6.0.7",
"@angular/core": "6.0.7",
"@angular/flex-layout": "6.0.0-beta.16",
"@angular/forms": "6.0.7",
"@angular/http": "6.0.7",
"@angular/material": "6.3.3",
"@angular/material-moment-adapter": "6.3.3",
"@angular/platform-browser": "6.0.7",
"@angular/platform-browser-dynamic": "6.0.7",
"@angular/router": "6.0.7",
"@ngrx/effects": "6.0.1",
"@ngrx/router-store": "6.0.1",
"@ngrx/store": "6.0.1",
"@ngrx/store-devtools": "6.0.1",
"@ngx-translate/core": "10.0.2",
"@swimlane/ngx-charts": "8.1.0",
"@swimlane/ngx-datatable": "13.0.1",
"@swimlane/ngx-dnd": "4.0.0",
"@types/prismjs": "1.9.0",
"angular-calendar": "0.25.2",
"angular-in-memory-web-api": "0.6.0",
"chart.js": "2.7.2",
"@agm/core": "1.0.0-beta.2",
"@angular/animations": "5.1.2",
"@angular/cdk": "5.0.2",
"@angular/common": "5.1.2",
"@angular/compiler": "5.1.2",
"@angular/core": "5.1.2",
"@angular/flex-layout": "2.0.0-beta.12",
"@angular/forms": "5.1.2",
"@angular/http": "5.1.2",
"@angular/material": "5.0.2",
"@angular/material-moment-adapter": "5.0.2",
"@angular/platform-browser": "5.1.2",
"@angular/platform-browser-dynamic": "5.1.2",
"@angular/router": "5.1.2",
"@ngx-translate/core": "9.0.2",
"@swimlane/ngx-charts": "7.0.1",
"@swimlane/ngx-datatable": "11.1.7",
"@swimlane/ngx-dnd": "3.1.0",
"angular-calendar": "0.23.0",
"angular-in-memory-web-api": "0.5.2",
"angular2-markdown": "1.6.0",
"classlist.js": "1.1.20150312",
"core-js": "2.5.7",
"d3": "5.5.0",
"core-js": "2.5.3",
"d3": "4.12.0",
"hammerjs": "2.0.8",
"lodash": "4.17.10",
"moment": "2.22.2",
"ng2-charts": "1.6.0",
"ngrx-store-freeze": "0.2.4",
"ngx-color-picker": "6.4.0",
"ngx-cookie-service": "1.0.10",
"perfect-scrollbar": "1.4.0",
"prismjs": "1.15.0",
"rxjs": "6.2.1",
"rxjs-compat": "6.2.1",
"highlight.js": "9.12.0",
"intl": "1.2.5",
"moment": "2.20.1",
"@ngrx/effects": "4.1.1",
"@ngrx/router-store": "4.1.1",
"@ngrx/store": "4.1.1",
"@ngrx/store-devtools": "4.1.1",
"ngrx-store-freeze": "0.2.0",
"ngx-color-picker": "5.3.0",
"ngx-cookie-service": "1.0.9",
"perfect-scrollbar": "1.3.0",
"rxjs": "5.5.6",
"web-animations-js": "2.3.1",
"zone.js": "0.8.26"
"zone.js": "0.8.18"
},
"devDependencies": {
"@angular/cli": "6.0.8",
"@angular/compiler-cli": "6.0.7",
"@angular/language-service": "6.0.7",
"@angular-devkit/build-angular": "0.6.8",
"@angular/cli": "1.6.2",
"@angular/compiler-cli": "5.1.2",
"@angular/language-service": "5.1.2",
"@angularclass/hmr": "2.1.3",
"@types/jasmine": "2.8.8",
"@types/jasmine": "2.5.54",
"@types/jasminewd2": "2.0.3",
"@types/lodash": "4.14.110",
"@types/node": "8.9.5",
"codelyzer": "4.2.1",
"jasmine-core": "2.99.1",
"jasmine-spec-reporter": "4.2.1",
"@types/node": "6.0.95",
"codelyzer": "4.0.2",
"jasmine-core": "2.6.4",
"jasmine-spec-reporter": "4.1.1",
"karma": "1.7.1",
"karma-chrome-launcher": "2.2.0",
"karma-coverage-istanbul-reporter": "2.0.1",
"karma-jasmine": "1.1.2",
"karma-chrome-launcher": "2.1.1",
"karma-cli": "1.0.1",
"karma-coverage-istanbul-reporter": "1.3.1",
"karma-jasmine": "1.1.1",
"karma-jasmine-html-reporter": "0.2.2",
"protractor": "5.3.2",
"ts-node": "5.0.1",
"tslint": "5.9.1",
"typescript": "2.7.2",
"webpack-bundle-analyzer": "2.13.1"
"protractor": "5.1.2",
"ts-node": "3.2.2",
"tslint": "5.7.0",
"typescript": "2.4.2"
}
}

28
protractor.conf.js Normal file
View File

@@ -0,0 +1,28 @@
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
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 } }));
}
};

View File

@@ -1,24 +0,0 @@
import { Component } from '@angular/core';
import { MatDialogRef } from '@angular/material';
@Component({
selector : 'fuse-confirm-dialog',
templateUrl: './confirm-dialog.component.html',
styleUrls : ['./confirm-dialog.component.scss']
})
export class FuseConfirmDialogComponent
{
public confirmMessage: string;
/**
* Constructor
*
* @param {MatDialogRef<FuseConfirmDialogComponent>} dialogRef
*/
constructor(
public dialogRef: MatDialogRef<FuseConfirmDialogComponent>
)
{
}
}

View File

@@ -1,20 +0,0 @@
import { NgModule } from '@angular/core';
import { MatButtonModule, MatDialogModule } from '@angular/material';
import { FuseConfirmDialogComponent } from '@fuse/components/confirm-dialog/confirm-dialog.component';
@NgModule({
declarations: [
FuseConfirmDialogComponent
],
imports: [
MatDialogModule,
MatButtonModule
],
entryComponents: [
FuseConfirmDialogComponent
],
})
export class FuseConfirmDialogModule
{
}

View File

@@ -1,89 +0,0 @@
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { interval, Subject } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
import * as moment from 'moment';
@Component({
selector : 'fuse-countdown',
templateUrl: './countdown.component.html',
styleUrls : ['./countdown.component.scss']
})
export class FuseCountdownComponent implements OnInit, OnDestroy
{
// Event date
@Input('eventDate')
eventDate;
countdown: any;
// Private
private _unsubscribeAll: Subject<any>;
/**
* Constructor
*/
constructor()
{
// Set the defaults
this.countdown = {
days : '',
hours : '',
minutes: '',
seconds: ''
};
// Set the private defaults
this._unsubscribeAll = new Subject();
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
{
const currDate = moment();
const eventDate = moment(this.eventDate);
// Get the difference in between the current date and event date
let diff = eventDate.diff(currDate, 'seconds');
// Create a subscribable interval
const countDown = interval(1000)
.pipe(
map(value => {
return diff = diff - 1;
}),
map(value => {
const timeLeft = moment.duration(value, 'seconds');
return {
days : timeLeft.asDays().toFixed(0),
hours : timeLeft.hours(),
minutes: timeLeft.minutes(),
seconds: timeLeft.seconds()
};
})
);
// Subscribe to the countdown interval
countDown
.pipe(takeUntil(this._unsubscribeAll))
.subscribe(value => {
this.countdown = value;
});
}
/**
* On destroy
*/
ngOnDestroy(): void
{
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
}
}

View File

@@ -1,15 +0,0 @@
import { NgModule } from '@angular/core';
import { FuseCountdownComponent } from '@fuse/components/countdown/countdown.component';
@NgModule({
declarations: [
FuseCountdownComponent
],
exports: [
FuseCountdownComponent
],
})
export class FuseCountdownModule
{
}

View File

@@ -1,75 +0,0 @@
<!-- DEMO CONTENT -->
<div class="demo-content">
<img src="assets/images/beach.jpg" alt="beach" style="max-width: 640px; width: 100%;">
<h1>Early Sunrise</h1>
<h4 class="secondary-text">Demo Content</h4>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse tortor nibh, convallis sed purus nec,
auctor venenatis nisl. Suspendisse potenti. Nullam sagittis nulla in diam finibus, sed pharetra velit
vestibulum. Suspendisse euismod in urna eu posuere.
</p>
<blockquote>
<p>
Nunc vel lacinia lorem. Nullam tincidunt sed purus eu placerat. Donec id dictum erat. Etiam enim ex, dapibus
et tortor id, posuere pretium est. Maecenas fringilla ipsum vitae neque elementum, at eleifend ante
sollicitudin. Donec viverra augue dolor, a venenatis tellus consectetur sit amet.
</p>
<footer>
John Doe
</footer>
</blockquote>
<p>
Ut ornare sit amet velit vel congue. Ut nec tristique eros. Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Vivamus sed lorem quis nibh porta iaculis. Vestibulum ut eleifend ante, at semper mi. Nam imperdiet est
nisi, quis hendrerit tellus convallis et. Morbi in luctus neque. Curabitur elementum ut est et gravida. In hac
habitasse platea dictumst.
</p>
<p>
In et placerat eros, eu tempor turpis. Curabitur ac felis finibus, elementum lectus vitae, venenatis est.
Integer mollis nisl a eros scelerisque varius. Etiam venenatis lectus vel erat condimentum tristique vel vel mi.
Nulla id euismod mi, et mollis tellus.
</p>
<p>
Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Class aptent taciti
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur vitae sagittis odio.
Suspendisse ullamcorper nunc non pellentesque laoreet. Curabitur eu tortor id quam pretium mattis. Proin ut quam
velit.
</p>
<p>
Quisque sit amet risus enim. Aliquam sit amet interdum justo, at ultricies sapien. Suspendisse et semper urna,
in gravida eros. Quisque id nibh iaculis, euismod urna sed, egestas nisi. Donec eros metus, congue a imperdiet
feugiat, sagittis nec ipsum. Quisque dapibus mollis felis non tristique.
</p>
<p>
Ut auctor, metus sed dapibus tempus, urna diam auctor odio, in malesuada odio risus vitae nisi. Etiam blandit
ante urna, vitae placerat massa mollis in. Duis nec urna ac purus semper dictum ut eget justo. Aenean non
sagittis augue. Sed venenatis rhoncus enim eget ornare. Donec viverra sed felis at venenatis. Mauris aliquam
fringilla nulla, sit amet congue felis dignissim at.
</p>
<p>
Quisque accumsan augue tempor ante mollis, sed placerat diam porttitor. Vestibulum dignissim sem vel velit
eleifend, non pellentesque quam convallis. Pellentesque est dolor, dignissim ac tortor tristique, hendrerit
iaculis metus. Praesent pulvinar quam eu leo consectetur faucibus. Vestibulum purus diam, gravida sagittis
feugiat sit amet, tincidunt in ligula. Sed semper vestibulum magna. Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Suspendisse tortor nibh, convallis sed purus nec, auctor venenatis nisl. Suspendisse potenti.
</p>
<p>
Nullam sagittis nulla in diam finibus, sed pharetra velit vestibulum. Suspendisse euismod in urna eu posuere.
Etiam blandit nunc arcu, et consectetur orci blandit a. Aliquam condimentum pharetra quam at ultricies. Nunc vel
lacinia lorem. Nullam tincidunt sed purus eu placerat. Donec id dictum erat. Etiam enim ex, dapibus et tortor
id, posuere pretium est. Maecenas fringilla ipsum vitae neque elementum, at eleifend ante sollicitudin. Donec
viverra augue dolor, a venenatis tellus consectetur sit amet...
</p>
</div>
<!-- / DEMO CONTENT -->

View File

@@ -1,16 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector : 'fuse-demo-sidebar',
templateUrl: './demo-sidebar.component.html',
styleUrls : ['./demo-sidebar.component.scss']
})
export class FuseDemoSidebarComponent
{
/**
* Constructor
*/
constructor()
{
}
}

View File

@@ -1,7 +0,0 @@
:host {
display: block;
padding: 8px;
background: #263238;
cursor: text;
overflow: auto;
}

View File

@@ -1,149 +0,0 @@
import { Component, ContentChild, ElementRef, Input, OnDestroy, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import * as Prism from 'prismjs/prism';
import '@fuse/components/highlight/prism-languages';
@Component({
selector : 'fuse-highlight',
template : '',
styleUrls: ['./highlight.component.scss']
})
export class FuseHighlightComponent implements OnInit, OnDestroy
{
// Source
@ContentChild('source')
source: ElementRef;
// Lang
@Input('lang')
lang: string;
// Path
@Input('path')
path: string;
// Private
private _unsubscribeAll: Subject<any>;
/**
* Constructor
*
* @param {ElementRef} _elementRef
* @param {HttpClient} _httpClient
*/
constructor(
private _elementRef: ElementRef,
private _httpClient: HttpClient
)
{
// Set the private defaults
this._unsubscribeAll = new Subject();
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
{
// If there is no language defined, return...
if ( !this.lang )
{
return;
}
// If the path is defined...
if ( this.path )
{
// Get the source
this._httpClient.get(this.path, {responseType: 'text'})
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((response) => {
// Highlight it
this.highlight(response);
});
}
// If the path is not defined and the source element exists...
if ( !this.path && this.source )
{
// Highlight it
this.highlight(this.source.nativeElement.value);
}
}
/**
* On destroy
*/
ngOnDestroy(): void
{
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Highlight the given source code
*
* @param sourceCode
*/
highlight(sourceCode): void
{
// Split the source into lines
const sourceLines = sourceCode.split('\n');
// Remove the first and the last line of the source
// code if they are blank lines. This way, the html
// can be formatted properly while using fuse-highlight
// component
if ( !sourceLines[0].trim() )
{
sourceLines.shift();
}
if ( !sourceLines[sourceLines.length - 1].trim() )
{
sourceLines.pop();
}
// Find the first non-whitespace char index in
// the first line of the source code
const indexOfFirstChar = sourceLines[0].search(/\S|$/);
// Generate the trimmed source
let source = '';
// Iterate through all the lines
sourceLines.forEach((line, index) => {
// Trim the beginning white space depending on the index
// and concat the source code
source = source + line.substr(indexOfFirstChar, line.length);
// If it's not the last line...
if ( index !== sourceLines.length - 1 )
{
// Add a line break at the end
source = source + '\n';
}
});
// Generate the highlighted code
const highlightedCode = Prism.highlight(source, Prism.languages[this.lang]);
// Replace the innerHTML of the component with the highlighted code
this._elementRef.nativeElement.innerHTML =
'<pre><code class="highlight language-' + this.lang + '">' + highlightedCode + '</code></pre>';
}
}

View File

@@ -1,15 +0,0 @@
import { NgModule } from '@angular/core';
import { FuseHighlightComponent } from '@fuse/components/highlight/highlight.component';
@NgModule({
declarations: [
FuseHighlightComponent
],
exports: [
FuseHighlightComponent
],
})
export class FuseHighlightModule
{
}

View File

@@ -1,18 +0,0 @@
import 'prismjs/prism';
import 'prismjs/components/prism-bash';
import 'prismjs/components/prism-c';
import 'prismjs/components/prism-cpp';
import 'prismjs/components/prism-csharp';
import 'prismjs/components/prism-css';
import 'prismjs/components/prism-diff';
import 'prismjs/components/prism-markup';
import 'prismjs/components/prism-markup-templating';
import 'prismjs/components/prism-java';
import 'prismjs/components/prism-javascript';
import 'prismjs/components/prism-json';
import 'prismjs/components/prism-perl';
import 'prismjs/components/prism-php';
import 'prismjs/components/prism-python';
import 'prismjs/components/prism-sass';
import 'prismjs/components/prism-scss';
import 'prismjs/components/prism-typescript';

View File

@@ -1,11 +0,0 @@
export * from './confirm-dialog/confirm-dialog.module';
export * from './countdown/countdown.module';
export * from './demo/demo.module';
export * from './highlight/highlight.module';
export * from './material-color-picker/material-color-picker.module';
export * from './navigation/navigation.module';
export * from './search-bar/search-bar.module';
export * from './shortcuts/shortcuts.module';
export * from './sidebar/sidebar.module';
export * from './theme-options/theme-options.module';
export * from './widget/widget.module';

View File

@@ -1,32 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FlexLayoutModule } from '@angular/flex-layout';
import { MatButtonModule, MatIconModule, MatMenuModule, MatRippleModule } from '@angular/material';
import { FusePipesModule } from '@fuse/pipes/pipes.module';
import { FuseMaterialColorPickerComponent } from '@fuse/components/material-color-picker/material-color-picker.component';
@NgModule({
declarations: [
FuseMaterialColorPickerComponent
],
imports: [
CommonModule,
FlexLayoutModule,
MatButtonModule,
MatIconModule,
MatMenuModule,
MatRippleModule,
FusePipesModule
],
exports: [
FuseMaterialColorPickerComponent
],
})
export class FuseMaterialColorPickerModule
{
}

View File

@@ -1,69 +0,0 @@
<ng-container *ngIf="!item.hidden">
<!-- normal collapse -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="!item.url && !item.function" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<!-- item.url -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && !item.externalUrl && !item.function"
[routerLink]="[item.url]" [routerLinkActive]="['active', 'mat-accent-bg']"
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
[target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<!-- item.externalUrl -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && item.externalUrl && !item.function"
[href]="item.url" [target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<!-- item.function -->
<span class="nav-link" [ngClass]="item.classes" *ngIf="!item.url && item.function"
(click)="item.function()" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</span>
<!-- item.url && item.function -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && !item.externalUrl && item.function"
(click)="item.function()"
[routerLink]="[item.url]" [routerLinkActive]="['active', 'mat-accent-bg']"
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<!-- item.externalUrl && item.function -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && item.externalUrl && item.function"
(click)="item.function()"
[href]="item.url" [target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<ng-template #itemContent>
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
<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="collapsable-arrow">keyboard_arrow_right</mat-icon>
</ng-template>
<div class="children" [ngClass]="{'open': isOpen}">
<div class="{{fuseConfig.layout.navbar.background}}">
<ng-container *ngFor="let item of item.children">
<fuse-nav-horizontal-item *ngIf="item.type=='item'" [item]="item"></fuse-nav-horizontal-item>
<fuse-nav-horizontal-collapsable *ngIf="item.type=='collapsable'"
[item]="item"></fuse-nav-horizontal-collapsable>
<fuse-nav-horizontal-collapsable *ngIf="item.type=='group'"
[item]="item"></fuse-nav-horizontal-collapsable>
</ng-container>
</div>
</div>
</ng-container>

View File

@@ -1,86 +0,0 @@
import { Component, HostBinding, HostListener, Input, OnDestroy, OnInit } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { fuseAnimations } from '@fuse/animations';
import { FuseConfigService } from '@fuse/services/config.service';
@Component({
selector : 'fuse-nav-horizontal-collapsable',
templateUrl: './collapsable.component.html',
styleUrls : ['./collapsable.component.scss'],
animations : fuseAnimations
})
export class FuseNavHorizontalCollapsableComponent implements OnInit, OnDestroy
{
fuseConfig: any;
isOpen = false;
@HostBinding('class')
classes = 'nav-collapsable nav-item';
@Input()
item: any;
// Private
private _unsubscribeAll: Subject<any>;
constructor(
private _fuseConfigService: FuseConfigService
)
{
// Set the private defaults
this._unsubscribeAll = new Subject();
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
{
// Subscribe to config changes
this._fuseConfigService.config
.pipe(takeUntil(this._unsubscribeAll))
.subscribe(
(config) => {
this.fuseConfig = config;
}
);
}
/**
* On destroy
*/
ngOnDestroy(): void
{
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Open
*/
@HostListener('mouseenter')
open(): void
{
this.isOpen = true;
}
/**
* Close
*/
@HostListener('mouseleave')
close(): void
{
this.isOpen = false;
}
}

View File

@@ -1,48 +0,0 @@
<ng-container *ngIf="!item.hidden">
<!-- item.url -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && !item.externalUrl && !item.function"
[routerLink]="[item.url]" [routerLinkActive]="['active', 'mat-accent-bg']"
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
[target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<!-- item.externalUrl -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && item.externalUrl && !item.function"
[href]="item.url" [target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<!-- item.function -->
<span class="nav-link" [ngClass]="item.classes" *ngIf="!item.url && item.function"
(click)="item.function()" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</span>
<!-- item.url && item.function -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && !item.externalUrl && item.function"
(click)="item.function()"
[routerLink]="[item.url]" [routerLinkActive]="['active', 'mat-accent-bg']"
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
[target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<!-- item.externalUrl && item.function -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && item.externalUrl && item.function"
(click)="item.function()"
[href]="item.url" [target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<ng-template #itemContent>
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
<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>
</ng-template>
</ng-container>

View File

@@ -1,23 +0,0 @@
import { Component, HostBinding, Input } from '@angular/core';
@Component({
selector : 'fuse-nav-horizontal-item',
templateUrl: './item.component.html',
styleUrls : ['./item.component.scss']
})
export class FuseNavHorizontalItemComponent
{
@HostBinding('class')
classes = 'nav-item';
@Input()
item: any;
/**
* Constructor
*/
constructor()
{
}
}

View File

@@ -1,12 +0,0 @@
@import 'src/@fuse/scss/fuse';
fuse-navigation {
display: flex;
flex: 1 0 auto;
> .nav {
margin: 0;
padding: 0;
width: 100%;
}
}

View File

@@ -1,54 +0,0 @@
import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
@Component({
selector : 'fuse-navigation',
templateUrl : './navigation.component.html',
styleUrls : ['./navigation.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class FuseNavigationComponent implements OnInit
{
@Input()
layout = 'vertical';
@Input()
navigation: any;
// Private
private _unsubscribeAll: Subject<any>;
/**
* Constructor
*/
constructor(
private _fuseNavigationService: FuseNavigationService
)
{
// Set the private defaults
this._unsubscribeAll = new Subject();
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
{
// Load the navigation either from the input or from the service
this.navigation = this.navigation || this._fuseNavigationService.getCurrentNavigation();
// Subscribe to the current navigation changes
this._fuseNavigationService.onNavigationChanged
.pipe(takeUntil(this._unsubscribeAll))
.subscribe(() => {
this.navigation = this._fuseNavigationService.getCurrentNavigation();
});
}
}

View File

@@ -1,39 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { MatIconModule, MatRippleModule } from '@angular/material';
import { TranslateModule } from '@ngx-translate/core';
import { FuseNavigationComponent } from './navigation.component';
import { FuseNavVerticalItemComponent } from './vertical/item/item.component';
import { FuseNavVerticalCollapsableComponent } from './vertical/collapsable/collapsable.component';
import { FuseNavVerticalGroupComponent } from './vertical/group/group.component';
import { FuseNavHorizontalItemComponent } from './horizontal/item/item.component';
import { FuseNavHorizontalCollapsableComponent } from './horizontal/collapsable/collapsable.component';
@NgModule({
imports : [
CommonModule,
RouterModule,
MatIconModule,
MatRippleModule,
TranslateModule.forChild()
],
exports : [
FuseNavigationComponent
],
declarations: [
FuseNavigationComponent,
FuseNavVerticalGroupComponent,
FuseNavVerticalItemComponent,
FuseNavVerticalCollapsableComponent,
FuseNavHorizontalItemComponent,
FuseNavHorizontalCollapsableComponent
]
})
export class FuseNavigationModule
{
}

View File

@@ -1,350 +0,0 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable, Subject } from 'rxjs';
import { FuseNavigationItem } from '@fuse/types';
@Injectable({
providedIn: 'root'
})
export class FuseNavigationService
{
onItemCollapsed: Subject<any>;
onItemCollapseToggled: Subject<any>;
// Private
private _onNavigationChanged: BehaviorSubject<any>;
private _onNavigationRegistered: BehaviorSubject<any>;
private _onNavigationUnregistered: BehaviorSubject<any>;
private _currentNavigationKey: string;
private _registry: { [key: string]: any } = {};
/**
* Constructor
*/
constructor()
{
// Set the defaults
this.onItemCollapsed = new Subject();
this.onItemCollapseToggled = new Subject();
// Set the private defaults
this._currentNavigationKey = null;
this._onNavigationChanged = new BehaviorSubject(null);
this._onNavigationRegistered = new BehaviorSubject(null);
this._onNavigationUnregistered = new BehaviorSubject(null);
}
// -----------------------------------------------------------------------------------------------------
// @ Accessors
// -----------------------------------------------------------------------------------------------------
/**
* Get onNavigationChanged
*
* @returns {Observable<any>}
*/
get onNavigationChanged(): Observable<any>
{
return this._onNavigationChanged.asObservable();
}
/**
* Get onNavigationRegistered
*
* @returns {Observable<any>}
*/
get onNavigationRegistered(): Observable<any>
{
return this._onNavigationRegistered.asObservable();
}
/**
* Get onNavigationUnregistered
*
* @returns {Observable<any>}
*/
get onNavigationUnregistered(): Observable<any>
{
return this._onNavigationUnregistered.asObservable();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Register the given navigation
* with the given key
*
* @param key
* @param navigation
*/
register(key, navigation): void
{
// Check if the key already being used
if ( this._registry[key] )
{
console.error(`The navigation with the key '${key}' already exists. Either unregister it first or use a unique key.`);
return;
}
// Add to the registry
this._registry[key] = navigation;
// Notify the subject
this._onNavigationRegistered.next([key, navigation]);
}
/**
* Unregister the navigation from the registry
* @param key
*/
unregister(key): void
{
// Check if the navigation exists
if ( !this._registry[key] )
{
console.warn(`The navigation with the key '${key}' doesn't exist in the registry.`);
}
// Unregister the sidebar
delete this._registry[key];
// Notify the subject
this._onNavigationUnregistered.next(key);
}
/**
* Get navigation from registry by key
*
* @param key
* @returns {any}
*/
getNavigation(key): any
{
// Check if the navigation exists
if ( !this._registry[key] )
{
console.warn(`The navigation with the key '${key}' doesn't exist in the registry.`);
return;
}
// Return the sidebar
return this._registry[key];
}
/**
* Get flattened navigation array
*
* @param navigation
* @param flatNavigation
* @returns {any[]}
*/
getFlatNavigation(navigation, flatNavigation: FuseNavigationItem[] = []): any
{
for ( const item of navigation )
{
if ( item.type === 'item' )
{
flatNavigation.push(item);
continue;
}
if ( item.type === 'collapsable' || item.type === 'group' )
{
if ( item.children )
{
this.getFlatNavigation(item.children, flatNavigation);
}
}
}
return flatNavigation;
}
/**
* Get the current navigation
*
* @returns {any}
*/
getCurrentNavigation(): any
{
if ( !this._currentNavigationKey )
{
console.warn(`The current navigation is not set.`);
return;
}
return this.getNavigation(this._currentNavigationKey);
}
/**
* Set the navigation with the key
* as the current navigation
*
* @param key
*/
setCurrentNavigation(key): void
{
// Check if the sidebar exists
if ( !this._registry[key] )
{
console.warn(`The navigation with the key '${key}' doesn't exist in the registry.`);
return;
}
// Set the current navigation key
this._currentNavigationKey = key;
// Notify the subject
this._onNavigationChanged.next(key);
}
/**
* Get navigation item by id from the
* current navigation
*
* @param id
* @param {any} navigation
* @returns {any | boolean}
*/
getNavigationItem(id, navigation = null): any | boolean
{
if ( !navigation )
{
navigation = this.getCurrentNavigation();
}
for ( const item of navigation )
{
if ( item.id === id )
{
return item;
}
if ( item.children )
{
const childItem = this.getNavigationItem(id, item.children);
if ( childItem )
{
return childItem;
}
}
}
return false;
}
/**
* Get the parent of the navigation item
* with the id
*
* @param id
* @param {any} navigation
* @param parent
*/
getNavigationItemParent(id, navigation = null, parent = null): any
{
if ( !navigation )
{
navigation = this.getCurrentNavigation();
parent = navigation;
}
for ( const item of navigation )
{
if ( item.id === id )
{
return parent;
}
if ( item.children )
{
const childItem = this.getNavigationItemParent(id, item.children, item);
if ( childItem )
{
return childItem;
}
}
}
return false;
}
/**
* Add a navigation item to the specified location
*
* @param item
* @param id
*/
addNavigationItem(item, id): void
{
// Get the current navigation
const navigation: any[] = this.getCurrentNavigation();
// Add to the end of the navigation
if ( id === 'end' )
{
navigation.push(item);
return;
}
// Add to the start of the navigation
if ( id === 'start' )
{
navigation.unshift(item);
}
// Add it to a specific location
const parent: any = this.getNavigationItem(id);
if ( parent )
{
// Check if parent has a children entry,
// and add it if it doesn't
if ( !parent.children )
{
parent.children = [];
}
// Add the item
parent.children.push(item);
}
}
/**
* Remove navigation item with the given id
*
* @param id
*/
removeNavigationItem(id): void
{
const item = this.getNavigationItem(id);
// Return, if there is not such an item
if ( !item )
{
return;
}
// Get the parent of the item
let parent = this.getNavigationItemParent(id);
// This check is required because of the first level
// of the navigation, since the first level is not
// inside the 'children' array
parent = parent.children || parent;
// Remove the item
parent.splice(parent.indexOf(item), 1);
}
}

View File

@@ -1,65 +0,0 @@
<ng-container *ngIf="!item.hidden">
<!-- normal collapse -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="!item.url && !item.function"
(click)="toggleOpen($event)" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<!-- item.url -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && !item.externalUrl && !item.function"
(click)="toggleOpen($event)"
[routerLink]="[item.url]" [routerLinkActive]="['active', 'mat-accent-bg']"
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
[target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<!-- item.externalUrl -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && item.externalUrl && !item.function"
(click)="toggleOpen($event)"
[href]="item.url" [target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<!-- item.function -->
<span class="nav-link" [ngClass]="item.classes" *ngIf="!item.url && item.function"
(click)="toggleOpen($event);item.function()" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</span>
<!-- item.url && item.function -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && !item.externalUrl && item.function"
(click)="toggleOpen($event);item.function()"
[routerLink]="[item.url]" [routerLinkActive]="['active', 'mat-accent-bg']"
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<!-- item.externalUrl && item.function -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && item.externalUrl && item.function"
(click)="toggleOpen($event);item.function()"
[href]="item.url" [target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<ng-template #itemContent>
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
<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="collapsable-arrow">keyboard_arrow_right</mat-icon>
</ng-template>
<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>
<fuse-nav-vertical-collapsable *ngIf="item.type=='collapsable'"
[item]="item"></fuse-nav-vertical-collapsable>
<fuse-nav-vertical-group *ngIf="item.type=='group'" [item]="item"></fuse-nav-vertical-group>
</ng-container>
</div>
</ng-container>

View File

@@ -1,16 +0,0 @@
<ng-container *ngIf="!item.hidden">
<div class="group-title" [ngClass]="item.classes">
<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>
<fuse-nav-vertical-collapsable *ngIf="item.type=='collapsable'"
[item]="item"></fuse-nav-vertical-collapsable>
<fuse-nav-vertical-item *ngIf="item.type=='item'" [item]="item"></fuse-nav-vertical-item>
</ng-container>
</div>
</ng-container>

View File

@@ -1,25 +0,0 @@
import { Component, HostBinding, Input } from '@angular/core';
import { FuseNavigationItem } from '@fuse/types';
@Component({
selector : 'fuse-nav-vertical-group',
templateUrl: './group.component.html',
styleUrls : ['./group.component.scss']
})
export class FuseNavVerticalGroupComponent
{
@HostBinding('class')
classes = 'nav-group nav-item';
@Input()
item: FuseNavigationItem;
/**
* Constructor
*/
constructor()
{
}
}

View File

@@ -1,48 +0,0 @@
<ng-container *ngIf="!item.hidden">
<!-- item.url -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && !item.externalUrl && !item.function"
[routerLink]="[item.url]" [routerLinkActive]="['active', 'mat-accent-bg']"
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
[target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<!-- item.externalUrl -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && item.externalUrl && !item.function"
[href]="item.url" [target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<!-- item.function -->
<span class="nav-link" [ngClass]="item.classes" *ngIf="!item.url && item.function"
(click)="item.function()" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</span>
<!-- item.url && item.function -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && !item.externalUrl && item.function"
(click)="item.function()"
[routerLink]="[item.url]" [routerLinkActive]="['active', 'mat-accent-bg']"
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
[target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<!-- item.externalUrl && item.function -->
<a class="nav-link" [ngClass]="item.classes" *ngIf="item.url && item.externalUrl && item.function"
(click)="item.function()"
[href]="item.url" [target]="item.openInNewTab ? '_blank' : '_self'" matRipple>
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
</a>
<ng-template #itemContent>
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
<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>
</ng-template>
</ng-container>

View File

@@ -1,24 +0,0 @@
import { Component, HostBinding, Input } from '@angular/core';
import { FuseNavigationItem } from '@fuse/types';
@Component({
selector : 'fuse-nav-vertical-item',
templateUrl: './item.component.html',
styleUrls : ['./item.component.scss']
})
export class FuseNavVerticalItemComponent
{
@HostBinding('class')
classes = 'nav-item';
@Input()
item: FuseNavigationItem;
/**
* Constructor
*/
constructor()
{
}
}

View File

@@ -1,91 +0,0 @@
@import "src/@fuse/scss/fuse";
:host {
.fuse-search-bar {
display: flex;
flex: 0 1 auto;
min-width: 64px;
height: 64px;
font-size: 13px;
@include media-breakpoint-down('xs') {
height: 56px;
}
.fuse-search-bar-content {
display: flex;
flex: 1 1 auto;
align-items: center;
justify-content: flex-start;
.fuse-search-bar-expander,
.fuse-search-bar-collapser {
cursor: pointer;
padding: 0 20px;
margin: 0;
width: 64px !important;
height: 64px !important;
line-height: 64px !important;
@include media-breakpoint-down('xs') {
height: 56px !important;
line-height: 56px !important;
}
}
.fuse-search-bar-loader {
width: 64px !important;
height: 64px !important;
line-height: 64px !important;
@include media-breakpoint-down('xs') {
height: 56px !important;
line-height: 56px !important;
}
}
.fuse-search-bar-collapser {
display: none;
}
#fuse-search-bar-input {
display: none;
flex: 1 0 auto;
min-height: 64px;
background-color: transparent;
font-size: 16px;
}
}
&.expanded {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 10;
.fuse-search-bar-content {
#fuse-search-bar-input {
display: flex;
}
.fuse-search-bar-collapser {
display: flex;
}
}
}
}
body {
&.fuse-search-bar-expanded {
#toolbar {
z-index: 999 !important;
}
}
}
}

View File

@@ -1,99 +0,0 @@
import { Component, EventEmitter, OnDestroy, OnInit, Output } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseConfigService } from '@fuse/services/config.service';
@Component({
selector : 'fuse-search-bar',
templateUrl: './search-bar.component.html',
styleUrls : ['./search-bar.component.scss']
})
export class FuseSearchBarComponent implements OnInit, OnDestroy
{
collapsed: boolean;
fuseConfig: any;
@Output()
input: EventEmitter<any>;
// Private
private _unsubscribeAll: Subject<any>;
/**
* Constructor
*
* @param {FuseConfigService} _fuseConfigService
*/
constructor(
private _fuseConfigService: FuseConfigService
)
{
// Set the defaults
this.input = new EventEmitter();
this.collapsed = true;
// Set the private defaults
this._unsubscribeAll = new Subject();
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
{
// Subscribe to config changes
this._fuseConfigService.config
.pipe(takeUntil(this._unsubscribeAll))
.subscribe(
(config) => {
this.fuseConfig = config;
}
);
}
/**
* On destroy
*/
ngOnDestroy(): void
{
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Collapse
*/
collapse(): void
{
this.collapsed = true;
}
/**
* Expand
*/
expand(): void
{
this.collapsed = false;
}
/**
* Search
*
* @param event
*/
search(event): void
{
this.input.emit(event.target.value);
}
}

View File

@@ -1,227 +0,0 @@
import { Component, ElementRef, Input, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core';
import { ObservableMedia } from '@angular/flex-layout';
import { CookieService } from 'ngx-cookie-service';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseMatchMediaService } from '@fuse/services/match-media.service';
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
@Component({
selector : 'fuse-shortcuts',
templateUrl: './shortcuts.component.html',
styleUrls : ['./shortcuts.component.scss']
})
export class FuseShortcutsComponent implements OnInit, OnDestroy
{
shortcutItems: any[];
navigationItems: any[];
filteredNavigationItems: any[];
searching: boolean;
mobileShortcutsPanelActive: boolean;
@Input()
navigation: any;
@ViewChild('searchInput')
searchInputField;
@ViewChild('shortcuts')
shortcutsEl: ElementRef;
// Private
private _unsubscribeAll: Subject<any>;
/**
* Constructor
*
* @param {Renderer2} _renderer
* @param {CookieService} _cookieService
* @param {FuseMatchMediaService} _fuseMatchMediaService
* @param {FuseNavigationService} _fuseNavigationService
* @param {ObservableMedia} _observableMedia
*/
constructor(
private _cookieService: CookieService,
private _fuseMatchMediaService: FuseMatchMediaService,
private _fuseNavigationService: FuseNavigationService,
private _observableMedia: ObservableMedia,
private _renderer: Renderer2
)
{
// Set the defaults
this.shortcutItems = [];
this.searching = false;
this.mobileShortcutsPanelActive = false;
// Set the private defaults
this._unsubscribeAll = new Subject();
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
{
// Get the navigation items and flatten them
this.filteredNavigationItems = this.navigationItems = this._fuseNavigationService.getFlatNavigation(this.navigation);
const cookieExists = this._cookieService.check('FUSE2.shortcuts');
if ( cookieExists )
{
this.shortcutItems = JSON.parse(this._cookieService.get('FUSE2.shortcuts'));
}
else
{
// User's shortcut items
this.shortcutItems = [
{
'title': 'Calendar',
'type' : 'item',
'icon' : 'today',
'url' : '/apps/calendar'
},
{
'title': 'Mail',
'type' : 'item',
'icon' : 'email',
'url' : '/apps/mail'
},
{
'title': 'Contacts',
'type' : 'item',
'icon' : 'account_box',
'url' : '/apps/contacts'
},
{
'title': 'To-Do',
'type' : 'item',
'icon' : 'check_box',
'url' : '/apps/todo'
}
];
}
this._fuseMatchMediaService.onMediaChange
.pipe(takeUntil(this._unsubscribeAll))
.subscribe(() => {
if ( this._observableMedia.isActive('gt-sm') )
{
this.hideMobileShortcutsPanel();
}
});
}
/**
* On destroy
*/
ngOnDestroy(): void
{
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Search
*
* @param event
*/
search(event): void
{
const value = event.target.value.toLowerCase();
if ( value === '' )
{
this.searching = false;
this.filteredNavigationItems = this.navigationItems;
return;
}
this.searching = true;
this.filteredNavigationItems = this.navigationItems.filter((navigationItem) => {
return navigationItem.title.toLowerCase().includes(value);
});
}
/**
* Toggle shortcut
*
* @param event
* @param itemToToggle
*/
toggleShortcut(event, itemToToggle): void
{
event.stopPropagation();
for ( let i = 0; i < this.shortcutItems.length; i++ )
{
if ( this.shortcutItems[i].url === itemToToggle.url )
{
this.shortcutItems.splice(i, 1);
// Save to the cookies
this._cookieService.set('FUSE2.shortcuts', JSON.stringify(this.shortcutItems));
return;
}
}
this.shortcutItems.push(itemToToggle);
// Save to the cookies
this._cookieService.set('FUSE2.shortcuts', JSON.stringify(this.shortcutItems));
}
/**
* Is in shortcuts?
*
* @param navigationItem
* @returns {any}
*/
isInShortcuts(navigationItem): any
{
return this.shortcutItems.find(item => {
return item.url === navigationItem.url;
});
}
/**
* On menu open
*/
onMenuOpen(): void
{
setTimeout(() => {
this.searchInputField.nativeElement.focus();
});
}
/**
* Show mobile shortcuts
*/
showMobileShortcutsPanel(): void
{
this.mobileShortcutsPanelActive = true;
this._renderer.addClass(this.shortcutsEl.nativeElement, 'show-mobile-panel');
}
/**
* Hide mobile shortcuts
*/
hideMobileShortcutsPanel(): void
{
this.mobileShortcutsPanelActive = false;
this._renderer.removeClass(this.shortcutsEl.nativeElement, 'show-mobile-panel');
}
}

View File

@@ -1,38 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { FlexLayoutModule } from '@angular/flex-layout';
import { MatButtonModule, MatDividerModule, MatFormFieldModule, MatIconModule, MatInputModule, MatListModule, MatMenuModule, MatTooltipModule } from '@angular/material';
import { CookieService } from 'ngx-cookie-service';
import { FuseShortcutsComponent } from './shortcuts.component';
@NgModule({
declarations: [
FuseShortcutsComponent
],
imports : [
CommonModule,
RouterModule,
FlexLayoutModule,
MatButtonModule,
MatDividerModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
MatMenuModule,
MatListModule,
MatTooltipModule
],
exports : [
FuseShortcutsComponent
],
providers : [
CookieService
]
})
export class FuseShortcutsModule
{
}

View File

@@ -1 +0,0 @@
<ng-content></ng-content>

View File

@@ -1,70 +0,0 @@
@import "src/@fuse/scss/fuse";
fuse-sidebar {
display: flex;
flex-direction: column;
flex: 1 0 auto;
position: absolute;
top: 0;
bottom: 0;
overflow-x: hidden;
overflow-y: auto;
width: 280px;
min-width: 280px;
max-width: 280px;
z-index: 1000;
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.35);
background: white;
@include media-breakpoint-down('xs') {
min-width: 0 !important;
max-width: 80vw !important;
width: 80vw !important;
}
&.left-positioned {
left: 0;
transform: translateX(-100%);
}
&.right-positioned {
right: 0;
transform: translateX(100%);
}
&.open {
transform: translateX(0);
}
&.locked-open {
position: relative !important;
transform: translateX(0) !important;
}
&.folded {
position: absolute !important;
top: 0;
bottom: 0;
}
&.animations-enabled {
transition-property: transform, width, min-width, max-width;
transition-duration: 150ms;
transition-timing-function: ease-in-out;
}
}
.fuse-sidebar-overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 999;
background-color: rgba(0, 0, 0, 0.6);
opacity: 0;
&.fuse-sidebar-overlay-invisible {
background-color: transparent;
}
}

View File

@@ -1,799 +0,0 @@
import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostBinding, HostListener, Input, OnDestroy, OnInit, Output, Renderer2, RendererStyleFlags2, ViewEncapsulation } from '@angular/core';
import { animate, AnimationBuilder, AnimationPlayer, style } from '@angular/animations';
import { ObservableMedia } from '@angular/flex-layout';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseSidebarService } from './sidebar.service';
import { FuseMatchMediaService } from '@fuse/services/match-media.service';
import { FuseConfigService } from '@fuse/services/config.service';
@Component({
selector : 'fuse-sidebar',
templateUrl : './sidebar.component.html',
styleUrls : ['./sidebar.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class FuseSidebarComponent implements OnInit, OnDestroy
{
// Name
@Input()
name: string;
// Key
@Input()
key: string;
// Position
@Input()
position: 'left' | 'right';
// Open
@HostBinding('class.open')
opened: boolean;
// Locked Open
@Input()
lockedOpen: string;
// isLockedOpen
@HostBinding('class.locked-open')
isLockedOpen: boolean;
// Folded width
@Input()
foldedWidth: number;
// Folded auto trigger on hover
@Input()
foldedAutoTriggerOnHover: boolean;
// Folded unfolded
@HostBinding('class.unfolded')
unfolded: boolean;
// Invisible overlay
@Input()
invisibleOverlay: boolean;
// Folded changed
@Output()
foldedChanged: EventEmitter<boolean>;
// Opened changed
@Output()
openedChanged: EventEmitter<boolean>;
// Private
private _folded: boolean;
private _fuseConfig: any;
private _wasActive: boolean;
private _wasFolded: boolean;
private _backdrop: HTMLElement | null = null;
private _player: AnimationPlayer;
private _unsubscribeAll: Subject<any>;
@HostBinding('class.animations-enabled')
private _animationsEnabled: boolean;
/**
* Constructor
*
* @param {AnimationBuilder} _animationBuilder
* @param {ChangeDetectorRef} _changeDetectorRef
* @param {ElementRef} _elementRef
* @param {FuseConfigService} _fuseConfigService
* @param {FuseMatchMediaService} _fuseMatchMediaService
* @param {FuseSidebarService} _fuseSidebarService
* @param {ObservableMedia} _observableMedia
* @param {Renderer2} _renderer
*/
constructor(
private _animationBuilder: AnimationBuilder,
private _changeDetectorRef: ChangeDetectorRef,
private _elementRef: ElementRef,
private _fuseConfigService: FuseConfigService,
private _fuseMatchMediaService: FuseMatchMediaService,
private _fuseSidebarService: FuseSidebarService,
private _observableMedia: ObservableMedia,
private _renderer: Renderer2
)
{
// Set the defaults
this.foldedAutoTriggerOnHover = true;
this.foldedWidth = 64;
this.foldedChanged = new EventEmitter();
this.openedChanged = new EventEmitter();
this.opened = false;
this.position = 'left';
this.invisibleOverlay = false;
// Set the private defaults
this._animationsEnabled = false;
this._folded = false;
this._unsubscribeAll = new Subject();
}
// -----------------------------------------------------------------------------------------------------
// @ Accessors
// -----------------------------------------------------------------------------------------------------
/**
* Folded
*
* @param {boolean} value
*/
@Input()
set folded(value: boolean)
{
// Set the folded
this._folded = value;
// Return if the sidebar is closed
if ( !this.opened )
{
return;
}
// Programmatically add/remove padding to the element
// that comes after or before based on the position
let sibling,
styleRule;
const styleValue = this.foldedWidth + 'px';
// Get the sibling and set the style rule
if ( this.position === 'left' )
{
sibling = this._elementRef.nativeElement.nextElementSibling;
styleRule = 'padding-left';
}
else
{
sibling = this._elementRef.nativeElement.previousElementSibling;
styleRule = 'padding-right';
}
// If there is no sibling, return...
if ( !sibling )
{
return;
}
// If folded...
if ( value )
{
// Fold the sidebar
this.fold();
// Set the folded width
this._renderer.setStyle(this._elementRef.nativeElement, 'width', styleValue);
this._renderer.setStyle(this._elementRef.nativeElement, 'min-width', styleValue);
this._renderer.setStyle(this._elementRef.nativeElement, 'max-width', styleValue);
// Set the style and class
this._renderer.setStyle(sibling, styleRule, styleValue, RendererStyleFlags2.Important + RendererStyleFlags2.DashCase);
this._renderer.addClass(this._elementRef.nativeElement, 'folded');
}
// If unfolded...
else
{
// Unfold the sidebar
this.unfold();
// Remove the folded width
this._renderer.removeStyle(this._elementRef.nativeElement, 'width');
this._renderer.removeStyle(this._elementRef.nativeElement, 'min-width');
this._renderer.removeStyle(this._elementRef.nativeElement, 'max-width');
// Remove the style and class
this._renderer.removeStyle(sibling, styleRule);
this._renderer.removeClass(this._elementRef.nativeElement, 'folded');
}
// Emit the 'foldedChanged' event
this.foldedChanged.emit(this.folded);
}
get folded(): boolean
{
return this._folded;
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
{
// Subscribe to config changes
this._fuseConfigService.config
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((config) => {
this._fuseConfig = config;
});
// Register the sidebar
this._fuseSidebarService.register(this.name, this);
// Setup visibility
this._setupVisibility();
// Setup position
this._setupPosition();
// Setup lockedOpen
this._setupLockedOpen();
// Setup folded
this._setupFolded();
}
/**
* On destroy
*/
ngOnDestroy(): void
{
// If the sidebar is folded, unfold it to revert modifications
if ( this.folded )
{
this.unfold();
}
// Unregister the sidebar
this._fuseSidebarService.unregister(this.name);
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
}
// -----------------------------------------------------------------------------------------------------
// @ Private methods
// -----------------------------------------------------------------------------------------------------
/**
* Setup the visibility of the sidebar
*
* @private
*/
private _setupVisibility(): void
{
// Remove the existing box-shadow
this._renderer.setStyle(this._elementRef.nativeElement, 'box-shadow', 'none');
// Make the sidebar invisible
this._renderer.setStyle(this._elementRef.nativeElement, 'visibility', 'hidden');
}
/**
* Setup the sidebar position
*
* @private
*/
private _setupPosition(): void
{
// Add the correct class name to the sidebar
// element depending on the position attribute
if ( this.position === 'right' )
{
this._renderer.addClass(this._elementRef.nativeElement, 'right-positioned');
}
else
{
this._renderer.addClass(this._elementRef.nativeElement, 'left-positioned');
}
}
/**
* Setup the lockedOpen handler
*
* @private
*/
private _setupLockedOpen(): void
{
// Return if the lockedOpen wasn't set
if ( !this.lockedOpen )
{
// Return
return;
}
// Set the wasActive for the first time
this._wasActive = false;
// Set the wasFolded
this._wasFolded = this.folded;
// Show the sidebar
this._showSidebar();
// Act on every media change
this._fuseMatchMediaService.onMediaChange
.pipe(takeUntil(this._unsubscribeAll))
.subscribe(() => {
// Get the active status
const isActive = this._observableMedia.isActive(this.lockedOpen);
// If the both status are the same, don't act
if ( this._wasActive === isActive )
{
return;
}
// Activate the lockedOpen
if ( isActive )
{
// Set the lockedOpen status
this.isLockedOpen = true;
// Show the sidebar
this._showSidebar();
// Force the the opened status to true
this.opened = true;
// Emit the 'openedChanged' event
this.openedChanged.emit(this.opened);
// If the sidebar was folded, forcefully fold it again
if ( this._wasFolded )
{
// Enable the animations
this._enableAnimations();
// Fold
this.folded = true;
// Mark for check
this._changeDetectorRef.markForCheck();
}
// Hide the backdrop if any exists
this._hideBackdrop();
}
// De-Activate the lockedOpen
else
{
// Set the lockedOpen status
this.isLockedOpen = false;
// Unfold the sidebar in case if it was folded
this.unfold();
// Force the the opened status to close
this.opened = false;
// Emit the 'openedChanged' event
this.openedChanged.emit(this.opened);
// Hide the sidebar
this._hideSidebar();
}
// Store the new active status
this._wasActive = isActive;
});
}
/**
* Setup the initial folded status
*
* @private
*/
private _setupFolded(): void
{
// Return, if sidebar is not folded
if ( !this.folded )
{
return;
}
// Return if the sidebar is closed
if ( !this.opened )
{
return;
}
// Programmatically add/remove padding to the element
// that comes after or before based on the position
let sibling,
styleRule;
const styleValue = this.foldedWidth + 'px';
// Get the sibling and set the style rule
if ( this.position === 'left' )
{
sibling = this._elementRef.nativeElement.nextElementSibling;
styleRule = 'padding-left';
}
else
{
sibling = this._elementRef.nativeElement.previousElementSibling;
styleRule = 'padding-right';
}
// If there is no sibling, return...
if ( !sibling )
{
return;
}
// Fold the sidebar
this.fold();
// Set the folded width
this._renderer.setStyle(this._elementRef.nativeElement, 'width', styleValue);
this._renderer.setStyle(this._elementRef.nativeElement, 'min-width', styleValue);
this._renderer.setStyle(this._elementRef.nativeElement, 'max-width', styleValue);
// Set the style and class
this._renderer.setStyle(sibling, styleRule, styleValue, RendererStyleFlags2.Important + RendererStyleFlags2.DashCase);
this._renderer.addClass(this._elementRef.nativeElement, 'folded');
}
/**
* Show the backdrop
*
* @private
*/
private _showBackdrop(): void
{
// Create the backdrop element
this._backdrop = this._renderer.createElement('div');
// Add a class to the backdrop element
this._backdrop.classList.add('fuse-sidebar-overlay');
// Add a class depending on the invisibleOverlay option
if ( this.invisibleOverlay )
{
this._backdrop.classList.add('fuse-sidebar-overlay-invisible');
}
// Append the backdrop to the parent of the sidebar
this._renderer.appendChild(this._elementRef.nativeElement.parentElement, this._backdrop);
// Create the enter animation and attach it to the player
this._player =
this._animationBuilder
.build([
animate('300ms ease', style({opacity: 1}))
]).create(this._backdrop);
// Play the animation
this._player.play();
// Add an event listener to the overlay
this._backdrop.addEventListener('click', () => {
this.close();
}
);
// Mark for check
this._changeDetectorRef.markForCheck();
}
/**
* Hide the backdrop
*
* @private
*/
private _hideBackdrop(): void
{
if ( !this._backdrop )
{
return;
}
// Create the leave animation and attach it to the player
this._player =
this._animationBuilder
.build([
animate('300ms ease', style({opacity: 0}))
]).create(this._backdrop);
// Play the animation
this._player.play();
// Once the animation is done...
this._player.onDone(() => {
// If the backdrop still exists...
if ( this._backdrop )
{
// Remove the backdrop
this._backdrop.parentNode.removeChild(this._backdrop);
this._backdrop = null;
}
});
// Mark for check
this._changeDetectorRef.markForCheck();
}
/**
* Change some properties of the sidebar
* and make it visible
*
* @private
*/
private _showSidebar(): void
{
// Remove the box-shadow style
this._renderer.removeStyle(this._elementRef.nativeElement, 'box-shadow');
// Make the sidebar invisible
this._renderer.removeStyle(this._elementRef.nativeElement, 'visibility');
// Mark for check
this._changeDetectorRef.markForCheck();
}
/**
* Change some properties of the sidebar
* and make it invisible
*
* @private
*/
private _hideSidebar(delay = true): void
{
const delayAmount = delay ? 300 : 0;
// Add a delay so close animation can play
setTimeout(() => {
// Remove the box-shadow
this._renderer.setStyle(this._elementRef.nativeElement, 'box-shadow', 'none');
// Make the sidebar invisible
this._renderer.setStyle(this._elementRef.nativeElement, 'visibility', 'hidden');
}, delayAmount);
// Mark for check
this._changeDetectorRef.markForCheck();
}
/**
* Enable the animations
*
* @private
*/
private _enableAnimations(): void
{
// Return if animations already enabled
if ( this._animationsEnabled )
{
return;
}
// Enable the animations
this._animationsEnabled = true;
// Mark for check
this._changeDetectorRef.markForCheck();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Open the sidebar
*/
open(): void
{
if ( this.opened || this.isLockedOpen )
{
return;
}
// Enable the animations
this._enableAnimations();
// Show the sidebar
this._showSidebar();
// Show the backdrop
this._showBackdrop();
// Set the opened status
this.opened = true;
// Emit the 'openedChanged' event
this.openedChanged.emit(this.opened);
// Mark for check
this._changeDetectorRef.markForCheck();
}
/**
* Close the sidebar
*/
close(): void
{
if ( !this.opened || this.isLockedOpen )
{
return;
}
// Enable the animations
this._enableAnimations();
// Hide the backdrop
this._hideBackdrop();
// Set the opened status
this.opened = false;
// Emit the 'openedChanged' event
this.openedChanged.emit(this.opened);
// Hide the sidebar
this._hideSidebar();
// Mark for check
this._changeDetectorRef.markForCheck();
}
/**
* Toggle open/close the sidebar
*/
toggleOpen(): void
{
if ( this.opened )
{
this.close();
}
else
{
this.open();
}
}
/**
* Mouseenter
*/
@HostListener('mouseenter')
onMouseEnter(): void
{
// Only work if the auto trigger is enabled
if ( !this.foldedAutoTriggerOnHover )
{
return;
}
this.unfoldTemporarily();
}
/**
* Mouseleave
*/
@HostListener('mouseleave')
onMouseLeave(): void
{
// Only work if the auto trigger is enabled
if ( !this.foldedAutoTriggerOnHover )
{
return;
}
this.foldTemporarily();
}
/**
* Fold the sidebar permanently
*/
fold(): void
{
// Only work if the sidebar is not folded
if ( this.folded )
{
return;
}
// Enable the animations
this._enableAnimations();
// Fold
this.folded = true;
// Mark for check
this._changeDetectorRef.markForCheck();
}
/**
* Unfold the sidebar permanently
*/
unfold(): void
{
// Only work if the sidebar is folded
if ( !this.folded )
{
return;
}
// Enable the animations
this._enableAnimations();
// Unfold
this.folded = false;
// Mark for check
this._changeDetectorRef.markForCheck();
}
/**
* Toggle the sidebar fold/unfold permanently
*/
toggleFold(): void
{
if ( this.folded )
{
this.unfold();
}
else
{
this.fold();
}
}
/**
* Fold the temporarily unfolded sidebar back
*/
foldTemporarily(): void
{
// Only work if the sidebar is folded
if ( !this.folded )
{
return;
}
// Enable the animations
this._enableAnimations();
// Fold the sidebar back
this.unfolded = false;
// Set the folded width
const styleValue = this.foldedWidth + 'px';
this._renderer.setStyle(this._elementRef.nativeElement, 'width', styleValue);
this._renderer.setStyle(this._elementRef.nativeElement, 'min-width', styleValue);
this._renderer.setStyle(this._elementRef.nativeElement, 'max-width', styleValue);
// Mark for check
this._changeDetectorRef.markForCheck();
}
/**
* Unfold the sidebar temporarily
*/
unfoldTemporarily(): void
{
// Only work if the sidebar is folded
if ( !this.folded )
{
return;
}
// Enable the animations
this._enableAnimations();
// Unfold the sidebar temporarily
this.unfolded = true;
// Remove the folded width
this._renderer.removeStyle(this._elementRef.nativeElement, 'width');
this._renderer.removeStyle(this._elementRef.nativeElement, 'min-width');
this._renderer.removeStyle(this._elementRef.nativeElement, 'max-width');
// Mark for check
this._changeDetectorRef.markForCheck();
}
}

View File

@@ -1,15 +0,0 @@
import { NgModule } from '@angular/core';
import { FuseSidebarComponent } from './sidebar.component';
@NgModule({
declarations: [
FuseSidebarComponent
],
exports : [
FuseSidebarComponent
]
})
export class FuseSidebarModule
{
}

View File

@@ -1,77 +0,0 @@
import { Injectable } from '@angular/core';
import { FuseSidebarComponent } from './sidebar.component';
@Injectable({
providedIn: 'root'
})
export class FuseSidebarService
{
// Private
private _registry: { [key: string]: FuseSidebarComponent } = {};
/**
* Constructor
*/
constructor()
{
}
/**
* Add the sidebar to the registry
*
* @param key
* @param sidebar
*/
register(key, sidebar): void
{
// Check if the key already being used
if ( this._registry[key] )
{
console.error(`The sidebar with the key '${key}' already exists. Either unregister it first or use a unique key.`);
return;
}
// Add to the registry
this._registry[key] = sidebar;
}
/**
* Remove the sidebar from the registry
*
* @param key
*/
unregister(key): void
{
// Check if the sidebar exists
if ( !this._registry[key] )
{
console.warn(`The sidebar with the key '${key}' doesn't exist in the registry.`);
}
// Unregister the sidebar
delete this._registry[key];
}
/**
* Return the sidebar with the given key
*
* @param key
* @returns {FuseSidebarComponent}
*/
getSidebar(key): FuseSidebarComponent
{
// Check if the sidebar exists
if ( !this._registry[key] )
{
console.warn(`The sidebar with the key '${key}' doesn't exist in the registry.`);
return;
}
// Return the sidebar
return this._registry[key];
}
}

View File

@@ -1,495 +0,0 @@
<div class="theme-options-panel" fusePerfectScrollbar>
<div class="header">
<span class="title">Theme Options</span>
<button mat-icon-button class="close-button" (click)="toggleSidebarOpen('themeOptionsPanel')">
<mat-icon>close</mat-icon>
</button>
</div>
<form [formGroup]="form">
<!-- LAYOUT STYLES -->
<div class="group" formGroupName="layout">
<h2>Layout Styles</h2>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="style">
<mat-radio-button class="mb-12" value="vertical-layout-1">
Vertical Layout #1
</mat-radio-button>
<mat-radio-button class="mb-12" value="vertical-layout-2">
Vertical Layout #2
</mat-radio-button>
<mat-radio-button class="mb-12" value="vertical-layout-3">
Vertical Layout #3
</mat-radio-button>
<mat-radio-button class="mb-12" value="horizontal-layout-1">
Horizontal Layout #1
</mat-radio-button>
</mat-radio-group>
<!-- DIFFERENT FORMS BASED ON LAYOUT STYLES -->
<ng-container [ngSwitch]="fuseConfig.layout.style">
<!-- VERTICAL LAYOUT #1 -->
<ng-container *ngSwitchCase="'vertical-layout-1'">
<!-- LAYOUT WIDTH -->
<div class="group mt-32">
<h2>Layout Width</h2>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="width">
<mat-radio-button class="mb-12" value="fullwidth">Fullwidth</mat-radio-button>
<mat-radio-button class="mb-12" value="boxed">Boxed</mat-radio-button>
</mat-radio-group>
</div>
<!-- NAVBAR -->
<div class="group" formGroupName="navbar">
<h2>Navbar</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<mat-slide-toggle class="mt-24" formControlName="folded">
Folded
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-16" value="left">Left</mat-radio-button>
<mat-radio-button class="mb-16" value="right">Right</mat-radio-button>
</mat-radio-group>
<h3 class="mt-8">Variant:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="variant">
<mat-radio-button class="mb-16" value="vertical-style-1">Style 1</mat-radio-button>
<mat-radio-button class="mb-16" value="vertical-style-2">Style 2</mat-radio-button>
</mat-radio-group>
<h3 class="mt-24 mb-8">Color:</h3>
<fuse-material-color-picker class="mb-16"
[(selectedClass)]="fuseConfig.layout.navbar.background">
</fuse-material-color-picker>
</div>
<!-- TOOLBAR -->
<div class="group" formGroupName="toolbar">
<h2>Toolbar</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-12" value="above">Above</mat-radio-button>
<mat-radio-button class="mb-12" value="below-static">Below Static</mat-radio-button>
<mat-radio-button class="mb-12" value="below-fixed">Below Fixed</mat-radio-button>
</mat-radio-group>
<h3 class="mt-24 mb-8">Color:</h3>
<fuse-material-color-picker class="mb-16"
[(selectedClass)]="fuseConfig.layout.toolbar.background">
</fuse-material-color-picker>
</div>
<!-- FOOTER -->
<div class="group" formGroupName="footer">
<h2>Footer</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-12" value="above">Above</mat-radio-button>
<mat-radio-button class="mb-12" value="below-static">Below Static</mat-radio-button>
<mat-radio-button class="mb-12" value="below-fixed">Below Fixed</mat-radio-button>
</mat-radio-group>
<h3 class="mt-24 mb-8">Color:</h3>
<fuse-material-color-picker class="mb-16"
[(selectedClass)]="fuseConfig.layout.footer.background">
</fuse-material-color-picker>
</div>
<!-- SIDE PANEL -->
<div class="group" formGroupName="sidepanel">
<h2>Side Panel</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-12" value="left">Left</mat-radio-button>
<mat-radio-button class="mb-12" value="right">Right</mat-radio-button>
</mat-radio-group>
</div>
</ng-container>
<!-- VERTICAL LAYOUT #2 -->
<ng-container *ngSwitchCase="'vertical-layout-2'">
<!-- LAYOUT WIDTH -->
<div class="group mt-32">
<h2>Layout Width</h2>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="width">
<mat-radio-button class="mb-12" value="fullwidth">Fullwidth</mat-radio-button>
<mat-radio-button class="mb-12" value="boxed">Boxed</mat-radio-button>
</mat-radio-group>
</div>
<!-- NAVBAR -->
<div class="group" formGroupName="navbar">
<h2>Navbar</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<mat-slide-toggle class="mt-24" formControlName="folded">
Folded
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-16" value="left">Left</mat-radio-button>
<mat-radio-button class="mb-16" value="right">Right</mat-radio-button>
</mat-radio-group>
<h3 class="mt-8">Variant:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="variant">
<mat-radio-button class="mb-16" value="vertical-style-1">Style 1</mat-radio-button>
<mat-radio-button class="mb-16" value="vertical-style-2">Style 2</mat-radio-button>
</mat-radio-group>
<h3 class="mt-24 mb-8">Color:</h3>
<fuse-material-color-picker class="mb-16"
[(selectedClass)]="fuseConfig.layout.navbar.background">
</fuse-material-color-picker>
</div>
<!-- TOOLBAR -->
<div class="group" formGroupName="toolbar">
<h2>Toolbar</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-12" value="above-static">Above Static</mat-radio-button>
<mat-radio-button class="mb-12" value="above-fixed">Above Fixed</mat-radio-button>
<mat-radio-button class="mb-12" value="below">Below</mat-radio-button>
</mat-radio-group>
<h3 class="mt-24 mb-8">Color:</h3>
<fuse-material-color-picker class="mb-16"
[(selectedClass)]="fuseConfig.layout.toolbar.background">
</fuse-material-color-picker>
</div>
<!-- FOOTER -->
<div class="group" formGroupName="footer">
<h2>Footer</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-12" value="above-static">Above Static</mat-radio-button>
<mat-radio-button class="mb-12" value="above-fixed">Above Fixed</mat-radio-button>
<mat-radio-button class="mb-12" value="below">Below</mat-radio-button>
</mat-radio-group>
<h3 class="mt-24 mb-8">Color:</h3>
<fuse-material-color-picker class="mb-16"
[(selectedClass)]="fuseConfig.layout.footer.background">
</fuse-material-color-picker>
</div>
<!-- SIDE PANEL -->
<div class="group" formGroupName="sidepanel">
<h2>Side Panel</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-12" value="left">Left</mat-radio-button>
<mat-radio-button class="mb-12" value="right">Right</mat-radio-button>
</mat-radio-group>
</div>
</ng-container>
<!-- VERTICAL LAYOUT #3 -->
<ng-container *ngSwitchCase="'vertical-layout-3'">
<!-- LAYOUT WIDTH -->
<div class="group mt-32">
<h2>Layout Width</h2>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="width">
<mat-radio-button class="mb-12" value="fullwidth">Fullwidth</mat-radio-button>
<mat-radio-button class="mb-12" value="boxed">Boxed</mat-radio-button>
</mat-radio-group>
</div>
<!-- NAVBAR -->
<div class="group" formGroupName="navbar">
<h2>Navbar</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<mat-slide-toggle class="mt-24" formControlName="folded">
Folded
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-16" value="left">Left</mat-radio-button>
<mat-radio-button class="mb-16" value="right">Right</mat-radio-button>
</mat-radio-group>
<h3 class="mt-8">Variant:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="variant">
<mat-radio-button class="mb-16" value="vertical-style-1">Style 1</mat-radio-button>
<mat-radio-button class="mb-16" value="vertical-style-2">Style 2</mat-radio-button>
</mat-radio-group>
<h3 class="mt-24 mb-8">Color:</h3>
<fuse-material-color-picker class="mb-16"
[(selectedClass)]="fuseConfig.layout.navbar.background">
</fuse-material-color-picker>
</div>
<!-- TOOLBAR -->
<div class="group" formGroupName="toolbar">
<h2>Toolbar</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-12" value="above-static">Above Static</mat-radio-button>
<mat-radio-button class="mb-12" value="above-fixed">Above Fixed</mat-radio-button>
</mat-radio-group>
<h3 class="mt-24 mb-8">Color:</h3>
<fuse-material-color-picker class="mb-16"
[(selectedClass)]="fuseConfig.layout.toolbar.background">
</fuse-material-color-picker>
</div>
<!-- FOOTER -->
<div class="group" formGroupName="footer">
<h2>Footer</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-12" value="above-static">Above Static</mat-radio-button>
<mat-radio-button class="mb-12" value="above-fixed">Above Fixed</mat-radio-button>
</mat-radio-group>
<h3 class="mt-24 mb-8">Color:</h3>
<fuse-material-color-picker class="mb-16"
[(selectedClass)]="fuseConfig.layout.footer.background">
</fuse-material-color-picker>
</div>
<!-- SIDE PANEL -->
<div class="group" formGroupName="sidepanel">
<h2>Side Panel</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-12" value="left">Left</mat-radio-button>
<mat-radio-button class="mb-12" value="right">Right</mat-radio-button>
</mat-radio-group>
</div>
</ng-container>
<!-- HORIZONTAL LAYOUT #1 -->
<ng-container *ngSwitchCase="'horizontal-layout-1'">
<!-- LAYOUT WIDTH -->
<div class="group mt-32">
<h2>Layout Width</h2>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="width">
<mat-radio-button class="mb-12" value="fullwidth">Fullwidth</mat-radio-button>
<mat-radio-button class="mb-12" value="boxed">Boxed</mat-radio-button>
</mat-radio-group>
</div>
<!-- NAVBAR -->
<div class="group" formGroupName="navbar">
<h2>Navbar</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-16" value="top">Top</mat-radio-button>
</mat-radio-group>
<h3 class="mt-8">Variant (Vertical):</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="variant">
<mat-radio-button class="mb-16" value="vertical-style-1">Style 1</mat-radio-button>
<mat-radio-button class="mb-16" value="vertical-style-2">Style 2</mat-radio-button>
</mat-radio-group>
<h3 class="mt-24 mb-8">Color:</h3>
<fuse-material-color-picker class="mb-16"
[(selectedClass)]="fuseConfig.layout.navbar.background">
</fuse-material-color-picker>
</div>
<!-- TOOLBAR -->
<div class="group" formGroupName="toolbar">
<h2>Toolbar</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-12" value="above">Above</mat-radio-button>
<mat-radio-button class="mb-12" value="below">Below</mat-radio-button>
</mat-radio-group>
<h3 class="mt-24 mb-8">Color:</h3>
<fuse-material-color-picker class="mb-16"
[(selectedClass)]="fuseConfig.layout.toolbar.background">
</fuse-material-color-picker>
</div>
<!-- FOOTER -->
<div class="group" formGroupName="footer">
<h2>Footer</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-12" value="above-fixed">Above Fixed</mat-radio-button>
<mat-radio-button class="mb-12" value="above-static">Above Static</mat-radio-button>
</mat-radio-group>
<h3 class="mt-24 mb-8">Color:</h3>
<fuse-material-color-picker class="mb-16"
[(selectedClass)]="fuseConfig.layout.footer.background">
</fuse-material-color-picker>
</div>
<!-- SIDE PANEL -->
<div class="group" formGroupName="sidepanel">
<h2>Side Panel</h2>
<mat-slide-toggle formControlName="hidden">
Hide
</mat-slide-toggle>
<h3 class="mt-24">Position:</h3>
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="position">
<mat-radio-button class="mb-12" value="left">Left</mat-radio-button>
<mat-radio-button class="mb-12" value="right">Right</mat-radio-button>
</mat-radio-group>
</div>
</ng-container>
</ng-container>
</div>
<!-- CUSTOM SCROLLBARS -->
<div class="group">
<h2>Custom scrollbars</h2>
<mat-slide-toggle class="mb-12" formControlName="customScrollbars">
Enable custom scrollbars
</mat-slide-toggle>
</div>
</form>
</div>

View File

@@ -1,78 +0,0 @@
@import "src/@fuse/scss/fuse";
@keyframes rotating {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
:host {
display: flex;
overflow: hidden;
.theme-options-panel {
display: flex;
flex-direction: column;
flex: 1 0 auto;
padding: 40px 24px 24px 24px;
overflow: auto;
.header {
display: flex;
flex: 0 1 auto;
margin-bottom: 32px;
align-items: center;
justify-content: space-between;
.title {
font-size: 20px;
font-weight: 500;
padding-left: 4px;
}
}
form {
display: flex;
flex: 1 1 auto;
flex-direction: column;
.group {
display: flex;
flex: 1 0 auto;
flex-direction: column;
position: relative;
border: 1px solid rgba(0, 0, 0, 0.12);
border-radius: 2px;
padding: 28px 16px 8px 16px;
margin: 16px 0;
h2 {
position: absolute;
top: -11px;
left: 8px;
margin: 0;
padding: 0 8px;
font-size: 16px;
font-weight: 500;
background: white;
color: rgba(0, 0, 0, 0.54);
}
h3 {
font-size: 14px;
font-weight: 500;
color: rgba(0, 0, 0, 0.54);
margin: 24px 0 16px 0;
padding: 0;
&:first-of-type {
margin-top: 0;
}
}
}
}
}
}

View File

@@ -1,307 +0,0 @@
import { Component, HostBinding, OnDestroy, OnInit, Renderer2 } from '@angular/core';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { fuseAnimations } from '@fuse/animations';
import { FuseConfigService } from '@fuse/services/config.service';
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service';
@Component({
selector : 'fuse-theme-options',
templateUrl: './theme-options.component.html',
styleUrls : ['./theme-options.component.scss'],
animations : fuseAnimations
})
export class FuseThemeOptionsComponent implements OnInit, OnDestroy
{
fuseConfig: any;
form: FormGroup;
@HostBinding('class.bar-closed')
barClosed: boolean;
// Private
private _unsubscribeAll: Subject<any>;
/**
* Constructor
*
* @param {FormBuilder} _formBuilder
* @param {FuseConfigService} _fuseConfigService
* @param {FuseNavigationService} _fuseNavigationService
* @param {FuseSidebarService} _fuseSidebarService
* @param {Renderer2} _renderer
*/
constructor(
private _formBuilder: FormBuilder,
private _fuseConfigService: FuseConfigService,
private _fuseNavigationService: FuseNavigationService,
private _fuseSidebarService: FuseSidebarService,
private _renderer: Renderer2
)
{
// Set the defaults
this.barClosed = true;
// Set the private defaults
this._unsubscribeAll = new Subject();
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
{
// Build the config form
// noinspection TypeScriptValidateTypes
this.form = this._formBuilder.group({
layout : this._formBuilder.group({
style : new FormControl(),
width : new FormControl(),
navbar : this._formBuilder.group({
background: new FormControl(),
folded : new FormControl(),
hidden : new FormControl(),
position : new FormControl(),
variant : new FormControl()
}),
toolbar : this._formBuilder.group({
background: new FormControl(),
hidden : new FormControl(),
position : new FormControl()
}),
footer : this._formBuilder.group({
background: new FormControl(),
hidden : new FormControl(),
position : new FormControl()
}),
sidepanel: this._formBuilder.group({
hidden: new FormControl(),
position : new FormControl()
})
}),
customScrollbars: new FormControl()
});
// Subscribe to the config changes
this._fuseConfigService.config
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((config) => {
// Update the stored config
this.fuseConfig = config;
// Set the config form values without emitting an event
// so that we don't end up with an infinite loop
this.form.setValue(config, {emitEvent: false});
});
// Subscribe to the specific form value changes (layout.style)
this.form.get('layout.style').valueChanges
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((value) => {
// Reset the form values based on the
// selected layout style
this._resetFormValues(value);
});
// Subscribe to the form value changes
this.form.valueChanges
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((config) => {
// Update the config
this._fuseConfigService.config = config;
});
// Add customize nav item that opens the bar programmatically
const customFunctionNavItem = {
'id' : 'custom-function',
'title' : 'Custom Function',
'type' : 'group',
'icon' : 'settings',
'children': [
{
'id' : 'customize',
'title' : 'Customize',
'type' : 'item',
'icon' : 'settings',
'function': () => {
this.toggleSidebarOpen('themeOptionsPanel');
}
}
]
};
this._fuseNavigationService.addNavigationItem(customFunctionNavItem, 'end');
}
/**
* On destroy
*/
ngOnDestroy(): void
{
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
// Remove the custom function menu
this._fuseNavigationService.removeNavigationItem('custom-function');
}
// -----------------------------------------------------------------------------------------------------
// @ Private methods
// -----------------------------------------------------------------------------------------------------
/**
* Reset the form values based on the
* selected layout style
*
* @param value
* @private
*/
private _resetFormValues(value): void
{
switch ( value )
{
// Vertical Layout #1
case 'vertical-layout-1':
{
this.form.patchValue({
layout: {
width : 'fullwidth',
navbar : {
background: 'mat-fuse-dark-700-bg',
folded : false,
hidden : false,
position : 'left',
variant : 'vertical-style-1'
},
toolbar: {
background: 'mat-white-500-bg',
hidden : false,
position : 'below-static'
},
footer : {
background: 'mat-fuse-dark-900-bg',
hidden : false,
position : 'below-static'
}
}
});
break;
}
// Vertical Layout #2
case 'vertical-layout-2':
{
this.form.patchValue({
layout: {
width : 'fullwidth',
navbar : {
background: 'mat-fuse-dark-700-bg',
folded : false,
hidden : false,
position : 'left',
variant : 'vertical-style-1'
},
toolbar: {
background: 'mat-white-500-bg',
hidden : false,
position : 'below'
},
footer : {
background: 'mat-fuse-dark-900-bg',
hidden : false,
position : 'below'
}
}
});
break;
}
// Vertical Layout #3
case 'vertical-layout-3':
{
this.form.patchValue({
layout: {
width : 'fullwidth',
navbar : {
background: 'mat-fuse-dark-700-bg',
folded : false,
hidden : false,
position : 'left',
layout : 'vertical-style-1'
},
toolbar: {
background: 'mat-white-500-bg',
hidden : false,
position : 'above-static'
},
footer : {
background: 'mat-fuse-dark-900-bg',
hidden : false,
position : 'above-static'
}
}
});
break;
}
// Horizontal Layout #1
case 'horizontal-layout-1':
{
this.form.patchValue({
layout: {
width : 'fullwidth',
navbar : {
background: 'mat-fuse-dark-700-bg',
folded : false,
hidden : false,
position : 'top',
variant : 'vertical-style-1'
},
toolbar: {
background: 'mat-white-500-bg',
hidden : false,
position : 'above'
},
footer : {
background: 'mat-fuse-dark-900-bg',
hidden : false,
position : 'above-fixed'
}
}
});
break;
}
}
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Toggle sidebar open
*
* @param key
*/
toggleSidebarOpen(key): void
{
this._fuseSidebarService.getSidebar(key).toggleOpen();
}
}

View File

@@ -1,43 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { FlexLayoutModule } from '@angular/flex-layout';
import { MatButtonModule, MatDividerModule, MatFormFieldModule, MatIconModule, MatOptionModule, MatRadioModule, MatSelectModule, MatSlideToggleModule } from '@angular/material';
import { FuseDirectivesModule } from '@fuse/directives/directives';
import { FuseSidebarModule } from '@fuse/components/sidebar/sidebar.module';
import { FuseMaterialColorPickerModule } from '@fuse/components/material-color-picker/material-color-picker.module';
import { FuseThemeOptionsComponent } from '@fuse/components/theme-options/theme-options.component';
@NgModule({
declarations: [
FuseThemeOptionsComponent
],
imports : [
CommonModule,
FormsModule,
ReactiveFormsModule,
FlexLayoutModule,
MatButtonModule,
MatDividerModule,
MatFormFieldModule,
MatIconModule,
MatOptionModule,
MatRadioModule,
MatSelectModule,
MatSlideToggleModule,
FuseDirectivesModule,
FuseMaterialColorPickerModule,
FuseSidebarModule
],
exports : [
FuseThemeOptionsComponent
]
})
export class FuseThemeOptionsModule
{
}

View File

@@ -1,18 +0,0 @@
import { Directive, ElementRef } from '@angular/core';
@Directive({
selector: '[fuseWidgetToggle]'
})
export class FuseWidgetToggleDirective
{
/**
* Constructor
*
* @param {ElementRef} elementRef
*/
constructor(
public elementRef: ElementRef
)
{
}
}

View File

@@ -1,65 +0,0 @@
import { AfterContentInit, Component, ContentChildren, ElementRef, HostBinding, QueryList, Renderer2, ViewEncapsulation } from '@angular/core';
import { FuseWidgetToggleDirective } from './widget-toggle.directive';
@Component({
selector : 'fuse-widget',
templateUrl : './widget.component.html',
styleUrls : ['./widget.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class FuseWidgetComponent implements AfterContentInit
{
@HostBinding('class.flipped')
flipped = false;
@ContentChildren(FuseWidgetToggleDirective, {descendants: true})
toggleButtons: QueryList<FuseWidgetToggleDirective>;
/**
* Constructor
*
* @param {ElementRef} _elementRef
* @param {Renderer2} _renderer
*/
constructor(
private _elementRef: ElementRef,
private _renderer: Renderer2
)
{
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* After content init
*/
ngAfterContentInit(): void
{
// Listen for the flip button click
setTimeout(() => {
this.toggleButtons.forEach(flipButton => {
this._renderer.listen(flipButton.elementRef.nativeElement, 'click', (event) => {
event.preventDefault();
event.stopPropagation();
this.toggle();
});
});
});
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Toggle the flipped status
*/
toggle(): void
{
this.flipped = !this.flipped;
}
}

View File

@@ -1,27 +0,0 @@
import { NgModule } from '@angular/core';
import { FuseIfOnDomDirective } from '@fuse/directives/fuse-if-on-dom/fuse-if-on-dom.directive';
import { FuseInnerScrollDirective } from '@fuse/directives/fuse-inner-scroll/fuse-inner-scroll.directive';
import { FusePerfectScrollbarDirective } from '@fuse/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive';
import { FuseMatSidenavHelperDirective, FuseMatSidenavTogglerDirective } from '@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.directive';
@NgModule({
declarations: [
FuseIfOnDomDirective,
FuseInnerScrollDirective,
FuseMatSidenavHelperDirective,
FuseMatSidenavTogglerDirective,
FusePerfectScrollbarDirective
],
imports : [],
exports : [
FuseIfOnDomDirective,
FuseInnerScrollDirective,
FuseMatSidenavHelperDirective,
FuseMatSidenavTogglerDirective,
FusePerfectScrollbarDirective
]
})
export class FuseDirectivesModule
{
}

View File

@@ -1,49 +0,0 @@
import { AfterContentChecked, Directive, ElementRef, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[fuseIfOnDom]'
})
export class FuseIfOnDomDirective implements AfterContentChecked
{
isCreated: boolean;
/**
* Constructor
*
* @param {ElementRef} _elementRef
* @param {TemplateRef<any>} _templateRef
* @param {ViewContainerRef} _viewContainerRef
*/
constructor(
private _elementRef: ElementRef,
private _templateRef: TemplateRef<any>,
private _viewContainerRef: ViewContainerRef
)
{
// Set the defaults
this.isCreated = false;
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* After content checked
*/
ngAfterContentChecked(): void
{
if ( document.body.contains(this._elementRef.nativeElement) && !this.isCreated )
{
setTimeout(() => {
this._viewContainerRef.createEmbeddedView(this._templateRef);
}, 300);
this.isCreated = true;
}
else if ( this.isCreated && !document.body.contains(this._elementRef.nativeElement) )
{
this._viewContainerRef.clear();
this.isCreated = false;
}
}
}

View File

@@ -1,115 +0,0 @@
import { Directive, ElementRef, OnDestroy, OnInit, Renderer2 } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseMatchMediaService } from '@fuse/services/match-media.service';
@Directive({
selector: '.inner-scroll'
})
export class FuseInnerScrollDirective implements OnInit, OnDestroy
{
// Private
private _parent: any;
private _grandParent: any;
private _unsubscribeAll: Subject<any>;
/**
* Constructor
*
* @param {ElementRef} _elementRef
* @param {FuseMatchMediaService} _fuseMediaMatchService
* @param {Renderer2} _renderer
*/
constructor(
private _elementRef: ElementRef,
private _fuseMediaMatchService: FuseMatchMediaService,
private _renderer: Renderer2
)
{
// Set the private defaults
this._unsubscribeAll = new Subject();
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
{
// Get the parent
this._parent = this._renderer.parentNode(this._elementRef.nativeElement);
// Return, if there is no parent
if ( !this._parent )
{
return;
}
// Get the grand parent
this._grandParent = this._renderer.parentNode(this._parent);
// Register to the media query changes
this._fuseMediaMatchService.onMediaChange
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((alias) => {
if ( alias === 'xs' )
{
this._removeClass();
}
else
{
this._addClass();
}
});
}
/**
* On destroy
*/
ngOnDestroy(): void
{
// Return, if there is no parent
if ( !this._parent )
{
return;
}
// Remove the class
this._removeClass();
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
}
// -----------------------------------------------------------------------------------------------------
// @ Private methods
// -----------------------------------------------------------------------------------------------------
/**
* Add the class name
*
* @private
*/
private _addClass(): void
{
// Add the inner-scroll class
this._renderer.addClass(this._grandParent, 'inner-scroll');
}
/**
* Remove the class name
* @private
*/
private _removeClass(): void
{
// Remove the inner-scroll class
this._renderer.removeClass(this._grandParent, 'inner-scroll');
}
}

View File

@@ -1,133 +0,0 @@
import { Directive, Input, OnInit, HostListener, OnDestroy, HostBinding } from '@angular/core';
import { MatSidenav } from '@angular/material';
import { ObservableMedia } from '@angular/flex-layout';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseMatchMediaService } from '@fuse/services/match-media.service';
import { FuseMatSidenavHelperService } from '@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.service';
@Directive({
selector: '[fuseMatSidenavHelper]'
})
export class FuseMatSidenavHelperDirective implements OnInit, OnDestroy
{
@HostBinding('class.mat-is-locked-open')
isLockedOpen: boolean;
@Input('fuseMatSidenavHelper')
id: string;
@Input('mat-is-locked-open')
matIsLockedOpenBreakpoint: string;
// Private
private _unsubscribeAll: Subject<any>;
/**
* Constructor
*
* @param {FuseMatchMediaService} _fuseMatchMediaService
* @param {FuseMatSidenavHelperService} _fuseMatSidenavHelperService
* @param {MatSidenav} _matSidenav
* @param {ObservableMedia} _observableMedia
*/
constructor(
private _fuseMatchMediaService: FuseMatchMediaService,
private _fuseMatSidenavHelperService: FuseMatSidenavHelperService,
private _matSidenav: MatSidenav,
private _observableMedia: ObservableMedia
)
{
// Set the defaults
this.isLockedOpen = true;
// Set the private defaults
this._unsubscribeAll = new Subject();
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
{
// Register the sidenav to the service
this._fuseMatSidenavHelperService.setSidenav(this.id, this._matSidenav);
if ( this._observableMedia.isActive(this.matIsLockedOpenBreakpoint) )
{
this.isLockedOpen = true;
this._matSidenav.mode = 'side';
this._matSidenav.toggle(true);
}
else
{
this.isLockedOpen = false;
this._matSidenav.mode = 'over';
this._matSidenav.toggle(false);
}
this._fuseMatchMediaService.onMediaChange
.pipe(takeUntil(this._unsubscribeAll))
.subscribe(() => {
if ( this._observableMedia.isActive(this.matIsLockedOpenBreakpoint) )
{
this.isLockedOpen = true;
this._matSidenav.mode = 'side';
this._matSidenav.toggle(true);
}
else
{
this.isLockedOpen = false;
this._matSidenav.mode = 'over';
this._matSidenav.toggle(false);
}
});
}
/**
* On destroy
*/
ngOnDestroy(): void
{
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
}
}
@Directive({
selector: '[fuseMatSidenavToggler]'
})
export class FuseMatSidenavTogglerDirective
{
@Input('fuseMatSidenavToggler')
id;
/**
* Constructor
*
* @param {FuseMatSidenavHelperService} _fuseMatSidenavHelperService
*/
constructor(
private _fuseMatSidenavHelperService: FuseMatSidenavHelperService)
{
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* On click
*/
@HostListener('click')
onClick()
{
this._fuseMatSidenavHelperService.getSidenav(this.id).toggle();
}
}

View File

@@ -1,44 +0,0 @@
import { Injectable } from '@angular/core';
import { MatSidenav } from '@angular/material';
@Injectable({
providedIn: 'root'
})
export class FuseMatSidenavHelperService
{
sidenavInstances: MatSidenav[];
/**
* Constructor
*/
constructor()
{
this.sidenavInstances = [];
}
// -----------------------------------------------------------------------------------------------------
// @ Accessors
// -----------------------------------------------------------------------------------------------------
/**
* Set sidenav
*
* @param id
* @param instance
*/
setSidenav(id, instance): void
{
this.sidenavInstances[id] = instance;
}
/**
* Get sidenav
*
* @param id
* @returns {any}
*/
getSidenav(id): any
{
return this.sidenavInstances[id];
}
}

View File

@@ -1,410 +0,0 @@
import { AfterViewInit, Directive, ElementRef, HostListener, Input, OnDestroy } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { Platform } from '@angular/cdk/platform';
import { Subject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';
import PerfectScrollbar from 'perfect-scrollbar';
import * as _ from 'lodash';
import { FuseConfigService } from '@fuse/services/config.service';
@Directive({
selector: '[fusePerfectScrollbar]'
})
export class FusePerfectScrollbarDirective implements AfterViewInit, OnDestroy
{
isInitialized: boolean;
isMobile: boolean;
ps: PerfectScrollbar;
// Private
private _enabled: boolean | '';
private _debouncedUpdate: any;
private _options: any;
private _unsubscribeAll: Subject<any>;
/**
* Constructor
*
* @param {ElementRef} elementRef
* @param {FuseConfigService} _fuseConfigService
* @param {Platform} _platform
* @param {Router} _router
*/
constructor(
public elementRef: ElementRef,
private _fuseConfigService: FuseConfigService,
private _platform: Platform,
private _router: Router
)
{
// Set the defaults
this.isInitialized = false;
this.isMobile = false;
// Set the private defaults
this._enabled = false;
this._debouncedUpdate = _.debounce(this.update, 150);
this._options = {
updateOnRouteChange: false
};
this._unsubscribeAll = new Subject();
}
// -----------------------------------------------------------------------------------------------------
// @ Accessors
// -----------------------------------------------------------------------------------------------------
/**
* Perfect Scrollbar options
*
* @param value
*/
@Input()
set fusePerfectScrollbarOptions(value)
{
// Merge the options
this._options = _.merge({}, this._options, value);
}
get fusePerfectScrollbarOptions(): any
{
// Return the options
return this._options;
}
/**
* Is enabled
*
* @param {boolean | ""} value
*/
@Input('fusePerfectScrollbar')
set enabled(value: boolean | '')
{
// If nothing is provided with the directive (empty string),
// we will take that as a true
if ( value === '' )
{
value = true;
}
// Return, if both values are the same
if ( this.enabled === value )
{
return;
}
// Store the value
this._enabled = value;
// If enabled...
if ( this.enabled )
{
// Init the directive
this._init();
}
else
{
// Otherwise destroy it
this._destroy();
}
}
get enabled(): boolean | ''
{
// Return the enabled status
return this._enabled;
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* After view init
*/
ngAfterViewInit(): void
{
// Check if scrollbars enabled or not from the main config
this._fuseConfigService.config
.pipe(takeUntil(this._unsubscribeAll))
.subscribe(
(settings) => {
this.enabled = settings.customScrollbars;
}
);
// Scroll to the top on every route change
if ( this.fusePerfectScrollbarOptions.updateOnRouteChange )
{
this._router.events
.pipe(
takeUntil(this._unsubscribeAll),
filter(event => event instanceof NavigationEnd)
)
.subscribe(() => {
setTimeout(() => {
this.scrollToTop();
this.update();
}, 0);
});
}
}
/**
* On destroy
*/
ngOnDestroy(): void
{
this._destroy();
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
}
// -----------------------------------------------------------------------------------------------------
// @ Private methods
// -----------------------------------------------------------------------------------------------------
/**
* Initialize
*
* @private
*/
_init(): void
{
// Return, if already initialized
if ( this.isInitialized )
{
return;
}
// Check if is mobile
if ( this._platform.ANDROID || this._platform.IOS )
{
this.isMobile = true;
}
// Return if it's mobile
if ( this.isMobile )
{
// Return...
return;
}
// Set as initialized
this.isInitialized = true;
// Initialize the perfect-scrollbar
this.ps = new PerfectScrollbar(this.elementRef.nativeElement, {
...this.fusePerfectScrollbarOptions
});
}
/**
* Destroy
*
* @private
*/
_destroy(): void
{
if ( !this.isInitialized || !this.ps )
{
return;
}
// Destroy the perfect-scrollbar
this.ps.destroy();
// Clean up
this.ps = null;
this.isInitialized = false;
}
/**
* Update scrollbars on window resize
*
* @private
*/
@HostListener('window:resize')
_updateOnResize(): void
{
this._debouncedUpdate();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Document click
*
* @param {Event} event
*/
@HostListener('document:click', ['$event'])
documentClick(event: Event): void
{
if ( !this.isInitialized || !this.ps )
{
return;
}
// Update the scrollbar on document click..
// This isn't the most elegant solution but there is no other way
// of knowing when the contents of the scrollable container changes.
// Therefore, we update scrollbars on every document click.
this.ps.update();
}
/**
* Update the scrollbar
*/
update(): void
{
if ( !this.isInitialized )
{
return;
}
// Update the perfect-scrollbar
this.ps.update();
}
/**
* Destroy the scrollbar
*/
destroy(): void
{
this.ngOnDestroy();
}
/**
* Scroll to X
*
* @param {number} x
* @param {number} speed
*/
scrollToX(x: number, speed?: number): void
{
this.animateScrolling('scrollLeft', x, speed);
}
/**
* Scroll to Y
*
* @param {number} y
* @param {number} speed
*/
scrollToY(y: number, speed?: number): void
{
this.animateScrolling('scrollTop', y, speed);
}
/**
* Scroll to top
*
* @param {number} offset
* @param {number} speed
*/
scrollToTop(offset?: number, speed?: number): void
{
this.animateScrolling('scrollTop', (offset || 0), speed);
}
/**
* Scroll to left
*
* @param {number} offset
* @param {number} speed
*/
scrollToLeft(offset?: number, speed?: number): void
{
this.animateScrolling('scrollLeft', (offset || 0), speed);
}
/**
* Scroll to right
*
* @param {number} offset
* @param {number} speed
*/
scrollToRight(offset?: number, speed?: number): void
{
const width = this.elementRef.nativeElement.scrollWidth;
this.animateScrolling('scrollLeft', width - (offset || 0), speed);
}
/**
* Scroll to bottom
*
* @param {number} offset
* @param {number} speed
*/
scrollToBottom(offset?: number, speed?: number): void
{
const height = this.elementRef.nativeElement.scrollHeight;
this.animateScrolling('scrollTop', height - (offset || 0), speed);
}
/**
* Animate scrolling
*
* @param {string} target
* @param {number} value
* @param {number} speed
*/
animateScrolling(target: string, value: number, speed?: number): void
{
if ( !speed )
{
this.elementRef.nativeElement[target] = value;
// PS has weird event sending order, this is a workaround for that
this.update();
this.update();
}
else if ( value !== this.elementRef.nativeElement[target] )
{
let newValue = 0;
let scrollCount = 0;
let oldTimestamp = performance.now();
let oldValue = this.elementRef.nativeElement[target];
const cosParameter = (oldValue - value) / 2;
const step = (newTimestamp) => {
scrollCount += Math.PI / (speed / (newTimestamp - oldTimestamp));
newValue = Math.round(value + cosParameter + cosParameter * Math.cos(scrollCount));
// Only continue animation if scroll position has not changed
if ( this.elementRef.nativeElement[target] === oldValue )
{
if ( scrollCount >= Math.PI )
{
this.elementRef.nativeElement[target] = value;
// PS has weird event sending order, this is a workaround for that
this.update();
this.update();
}
else
{
this.elementRef.nativeElement[target] = oldValue = newValue;
oldTimestamp = newTimestamp;
window.requestAnimationFrame(step);
}
}
};
window.requestAnimationFrame(step);
}
}
}

View File

@@ -1,28 +0,0 @@
import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';
import { FUSE_CONFIG } from '@fuse/services/config.service';
@NgModule()
export class FuseModule
{
constructor(@Optional() @SkipSelf() parentModule: FuseModule)
{
if ( parentModule )
{
throw new Error('FuseModule is already loaded. Import it in the AppModule only!');
}
}
static forRoot(config): ModuleWithProviders
{
return {
ngModule : FuseModule,
providers: [
{
provide : FUSE_CONFIG,
useValue: config
}
]
};
}
}

View File

@@ -1,5 +0,0 @@
// Material theming
@import "theming";
// Breakpoint mixins
@import "mixins/breakpoints";

View File

@@ -1,61 +0,0 @@
.fuse-card {
max-width: 320px;
min-width: 320px;
background: white;
border-radius: 2px;
@include mat-elevation(2);
&.variable-width {
min-width: 0;
}
&.auto-width {
min-width: 0;
max-width: none;
}
// Buttons
.mat-button {
min-width: 0 !important;
padding: 0 8px !important;
}
// Button Toggle Group
.mat-button-toggle-group,
.mat-button-toggle-standalone {
box-shadow: none !important;
}
// Tabs
.mat-tab-labels {
justify-content: center;
}
.mat-tab-label {
min-width: 0 !important;
}
// Divider
.card-divider {
border-top: 1px solid rgba(0, 0, 0, 0.12);
margin: 16px;
&.light {
border-top-color: rgba(255, 255, 255, 0.12);
}
&.full-width {
margin: 0;
}
}
// Expand Area
.card-expand-area {
overflow: hidden;
.card-expanded-content {
padding: 8px 16px 16px 16px;
line-height: 1.75;
}
}
}

View File

@@ -1,358 +0,0 @@
.secondary-text,
.icon,
i {
color: rgba(0, 0, 0, 0.54);
}
.hint-text,
.disabled-text {
color: rgba(0, 0, 0, 0.38);
}
.divider {
color: rgba(0, 0, 0, 0.12);
}
// Material colors map
$matPalettes: (
primary: $primary,
accent: $accent,
warn: $warn,
red: $mat-red,
pink: $mat-pink,
purple: $mat-purple,
deep-purple: $mat-deep-purple,
indigo: $mat-indigo,
blue: $mat-blue,
light-blue: $mat-light-blue,
cyan: $mat-cyan,
teal: $mat-teal,
green: $mat-green,
light-green: $mat-light-green,
lime: $mat-lime,
yellow: $mat-yellow,
amber: $mat-amber,
orange: $mat-orange,
deep-orange: $mat-deep-orange,
brown: $mat-brown,
grey: $mat-grey,
blue-grey: $mat-blue-grey,
white: $mat-white,
black: $mat-black,
fuse-dark: $mat-fusedark
);
// Material color hues list
$matHues: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, A100, A200, A400, A700;
// Text color levels generator mixin
@mixin generateTextColorLevels($classes, $contrast) {
// If the contrast is dark...
@if ($contrast == 'dark') {
// Put down the color classes
#{$classes} {
i,
.icon {
color: rgba(0, 0, 0, 0.54);
}
&.secondary-text,
.secondary-text {
color: rgba(0, 0, 0, 0.54) !important;
}
&.hint-text,
.hint-text,
&.disabled-text,
.disabled-text {
color: rgba(0, 0, 0, 0.38) !important;
}
&.divider,
.divider {
color: rgba(0, 0, 0, 0.12) !important;
}
.mat-ripple-element {
background: rgba(0, 0, 0, 0.1);
}
.adaptive-border-color {
border-color: rgba(0, 0, 0, 0.12);
}
}
}
// If the base text color is white...
@else {
// Put down the color classes
#{$classes} {
i,
.icon {
color: rgba(255, 255, 255, 1);
}
&.secondary-text,
.secondary-text {
color: rgba(255, 255, 255, 0.70) !important;
}
&.hint-text,
.hint-text,
&.disabled-text,
.disabled-text {
color: rgba(255, 255, 255, 0.50) !important;
}
&.divider,
.divider {
color: rgba(255, 255, 255, 0.12) !important;
}
.mat-ripple-element {
background: rgba(255, 255, 255, 0.1);
}
.adaptive-border-color {
border-color: rgba(255, 255, 255, 0.12);
}
}
}
}
@mixin generateMaterialElementColors($classes, $contrast) {
// If the contrast color is light...
$fuseForeground: (
base: white,
text: white,
hint-text: rgba(white, 0.5),
divider: rgba(white, 0.12),
);
// If the contrast color is dark...
@if ($contrast == 'dark') {
$fuseForeground: (
base: black,
hint-text: rgba(black, 0.38),
divider: rgba(black, 0.12),
);
}
// Put down the color classes
#{$classes} {
// Native Input
input[type="text"] {
color: map_get($fuseForeground, base);
}
// Input
.mat-form-field-label {
color: map_get($fuseForeground, hint-text);
}
.mat-form-field-underline {
background-color: map_get($fuseForeground, divider);
}
// Select
.mat-select-trigger,
.mat-select-arrow {
color: map_get($fuseForeground, hint-text);
}
.mat-select-underline {
background-color: map_get($fuseForeground, divider);
}
.mat-select-disabled .mat-select-value,
.mat-select-arrow,
.mat-select-trigger {
color: map_get($fuseForeground, hint-text);
}
.mat-select-content,
.mat-select-panel-done-animating {
background: map_get($background, card);
}
.mat-select-value {
color: map_get($fuseForeground, text);
}
}
}
// Color classes generator mixin
@mixin generateColorClasses($colorName, $color, $contrastColor, $hue) {
.#{$colorName}#{$hue}-bg {
background-color: $color !important;
}
.mat-#{$colorName}#{$hue}-bg {
background-color: $color !important;
color: $contrastColor !important;
&[disabled] {
background-color: rgba($color, .12) !important;
color: rgba($contrastColor, .26) !important;
}
}
.#{$colorName}#{$hue}-fg {
color: $color !important;
}
.#{$colorName}#{$hue}-border {
border-color: $color !important;
}
.#{$colorName}#{$hue}-border-top {
border-top-color: $color !important;
}
.#{$colorName}#{$hue}-border-right {
border-right-color: $color !important;
}
.#{$colorName}#{$hue}-border-bottom {
border-bottom-color: $color !important;
}
.#{$colorName}#{$hue}-border-left {
border-left-color: $color !important;
}
}
@mixin generateFuseColorClasses($primary, $accent, $warn) {
$palettes: (
primary: $primary,
accent: $accent,
warn: $warn
);
// Define contrast lists
$light-contrasting-classes: ();
$dark-contrasting-classes: ();
// Generate the color classes...
@each $paletteName, $palette in $palettes {
// Get the contrasts map
$contrasts: map-get($palette, 'contrast');
@each $hue in $matHues {
// Get the color and the contrasting color
$color: map-get($palette, $hue);
$contrast: map-get($contrasts, $hue);
@if ($color != null and $contrast != null) {
// Generate color classes
@include generateColorClasses($paletteName, $color, $contrast, '-#{$hue}');
// If the contrast color is dark
@if (rgba(black, 1) == rgba($contrast, 1)) {
$dark-contrasting-classes: append($dark-contrasting-classes, unquote('.mat-#{$paletteName}-#{$hue}-bg'), 'comma');
}
// if the contrast color is light
@else {
$light-contrasting-classes: append($light-contrasting-classes, unquote('.mat-#{$paletteName}-#{$hue}-bg'), 'comma');
}
// Run the generator one more time for default values (500)
@if ($hue == 500) {
// Generate color classes
@include generateColorClasses($paletteName, $color, $contrast, '');
// Add color to the correct list depending on the contrasting color
// If the contrast color is dark
@if (rgba(black, 1) == rgba($contrast, 1)) {
$dark-contrasting-classes: append($dark-contrasting-classes, unquote('.mat-#{$paletteName}-bg'), 'comma');
}
// if the contrast color is light
@else {
$light-contrasting-classes: append($light-contrasting-classes, unquote('.mat-#{$paletteName}-bg'), 'comma');
}
}
}
}
}
// Generate contrasting colors
@include generateTextColorLevels($dark-contrasting-classes, 'dark');
@include generateTextColorLevels($light-contrasting-classes, 'light');
@include generateMaterialElementColors($dark-contrasting-classes, 'dark');
@include generateMaterialElementColors($light-contrasting-classes, 'light');
}
// Generate the color classes...
// Define contrast lists
$light-contrasting-classes: ();
$dark-contrasting-classes: ();
@each $paletteName, $palette in $matPalettes {
// Get the contrasts map
$contrasts: map-get($palette, 'contrast');
@each $hue in $matHues {
// Get the color and the contrasting color
$color: map-get($palette, $hue);
$contrast: map-get($contrasts, $hue);
@if ($color != null and $contrast != null) {
// Generate color classes
@include generateColorClasses($paletteName, $color, $contrast, '-#{$hue}');
// Add color to the correct list depending on the contrasting color
// If the contrast color is dark
@if (rgba(black, 1) == rgba($contrast, 1)) {
$dark-contrasting-classes: append($dark-contrasting-classes, unquote('.mat-#{$paletteName}-#{$hue}-bg'), 'comma');
}
// if the contrast color is light
@else {
$light-contrasting-classes: append($light-contrasting-classes, unquote('.mat-#{$paletteName}-#{$hue}-bg'), 'comma');
}
// Run the generator one more time for default values (500)
@if ($hue == 500) {
// Generate color classes
@include generateColorClasses($paletteName, $color, $contrast, '');
// Add color to the correct list depending on the contrasting color
// If the contrast color is dark
@if (rgba(black, 1) == rgba($contrast, 1)) {
$dark-contrasting-classes: append($dark-contrasting-classes, unquote('.mat-#{$paletteName}-bg'), 'comma');
}
// if the contrast color is light
@else {
$light-contrasting-classes: append($light-contrasting-classes, unquote('.mat-#{$paletteName}-bg'), 'comma');
}
}
}
}
}
// Generate contrasting colors
@include generateTextColorLevels($dark-contrasting-classes, 'dark');
@include generateTextColorLevels($light-contrasting-classes, 'light');
@include generateMaterialElementColors($dark-contrasting-classes, 'dark');
@include generateMaterialElementColors($light-contrasting-classes, 'light');

View File

@@ -1,42 +0,0 @@
.docs {
font-size: 16px;
> .content {
max-width: 980px;
> .main-title {
&:first-child {
margin-top: 0;
}
}
}
.main-title {
display: flex;
margin-top: 72px;
font-size: 24px;
}
.section-title {
display: inline-flex;
font-size: 18px;
margin-top: 24px;
border-bottom: 1px solid #F44336;
color: #F44336;
}
ol,
ul {
padding-left: 24px;
li {
margin-bottom: 12px;
line-height: 1.7;
}
}
p {
line-height: 1.7;
}
}

View File

@@ -1,13 +0,0 @@
html,
body {
display: flex;
flex: 1 0 auto;
width: 100%;
height: 100%;
max-height: 100%;
min-height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
background: #F5F5F5;
}

View File

@@ -1,621 +0,0 @@
// Page Layouts
$carded-header-height: 200px !default;
$carded-header-height-sm: 160px !default;
$carded-toolbar-height: 64px !default;
$header-height: 120px !default;
$header-height-sm: 100px !default;
// Calculate toolbarless header height
$carded-header-height-without-toolbar: $carded-header-height - $carded-toolbar-height;
$carded-header-height-without-toolbar-sm: $carded-header-height-sm - $carded-toolbar-height;
.page-layout {
position: relative;
overflow: hidden;
// Carded layout
&.carded {
display: flex;
flex-direction: column;
flex: 1 0 auto;
width: 100%;
min-width: 100%;
// Top bg
> .top-bg {
position: absolute;
z-index: 1;
top: 0;
right: 0;
left: 0;
height: $carded-header-height;
@include media-breakpoint-down('sm') {
height: $carded-header-height-sm;
}
}
// Fullwidth
&.fullwidth {
// Center
> .center {
display: flex;
flex-direction: column;
flex: 1 0 auto;
position: relative;
z-index: 2;
padding: 0 32px;
width: 100%;
min-width: 0;
max-width: 100%;
max-height: 100%;
> .header {
height: $carded-header-height-without-toolbar !important;
min-height: $carded-header-height-without-toolbar !important;
max-height: $carded-header-height-without-toolbar !important;
@include media-breakpoint-down('sm') {
height: $carded-header-height-without-toolbar-sm !important;
min-height: $carded-header-height-without-toolbar-sm !important;
max-height: $carded-header-height-without-toolbar-sm !important;
}
}
> .content-card {
display: flex;
flex-direction: column;
flex: 1 0 auto;
overflow: hidden;
@include mat-elevation(7);
> .toolbar {
display: flex;
justify-content: flex-start;
align-items: center;
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
height: $carded-toolbar-height;
min-height: $carded-toolbar-height;
max-height: $carded-toolbar-height;
}
> .content {
flex: 1 0 auto;
}
}
}
// Tabbed
&.tabbed {
> .center {
width: 100%;
min-width: 0;
> .header {
flex: 1 1 auto;
}
> .content-card {
> .content {
display: flex;
> .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%;
}
}
}
}
}
}
}
}
// Inner scroll
&.inner-scroll {
flex: 1 1 auto;
> .center {
flex: 1 1 auto;
> .content-card {
flex: 1 1 auto;
> .content {
overflow: auto;
flex: 1 1 auto;
}
}
}
// Tabbed
&.tabbed {
> .center {
> .content-card {
> .content {
> .mat-tab-group {
.mat-tab-body {
.mat-tab-body-content {
.tab-content {
overflow: auto;
}
}
}
}
}
}
}
}
}
}
// Left / Right sidebar
&.left-sidebar,
&.right-sidebar {
flex-direction: row;
// Sidebar
> .sidebar {
display: flex;
flex-direction: column;
flex: 1 1 auto;
width: 240px;
min-width: 240px;
max-width: 240px;
height: auto;
overflow: hidden;
@include mat-elevation(7);
&.locked-open {
background: none;
box-shadow: none;
+ .center {
z-index: 1001;
}
&.left-positioned {
+ .center {
margin-left: 0;
}
}
&.right-positioned {
+ .center {
margin-right: 0;
}
}
}
.header {
height: $carded-header-height;
min-height: $carded-header-height;
max-height: $carded-header-height;
@include media-breakpoint-down('sm') {
height: $carded-header-height-sm;
min-height: $carded-header-height-sm;
max-height: $carded-header-height-sm;
}
}
.content {
background: transparent;
flex: 1 1 auto;
}
}
// Center
> .center {
display: flex;
flex-direction: column;
flex: 1 1 auto;
position: relative;
z-index: 3;
margin-left: 32px;
margin-right: 32px;
min-width: 0;
> .header {
display: flex;
height: $carded-header-height-without-toolbar;
min-height: $carded-header-height-without-toolbar;
max-height: $carded-header-height-without-toolbar;
@include media-breakpoint-down('sm') {
height: $carded-header-height-without-toolbar-sm;
min-height: $carded-header-height-without-toolbar-sm;
max-height: $carded-header-height-without-toolbar-sm;
}
}
> .content-card {
display: flex;
flex-direction: column;
flex: 1 1 auto;
overflow: hidden;
@include mat-elevation(7);
> .toolbar {
display: flex;
justify-content: flex-start;
align-items: center;
flex: 1 1 auto;
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
height: $carded-toolbar-height;
min-height: $carded-toolbar-height;
max-height: $carded-toolbar-height;
.sidebar-toggle {
margin: 0 8px 0 0 !important;
padding: 0 !important;
border-radius: 0;
}
}
> .content {
flex: 1 1 auto;
}
}
}
// Tabbed
&.tabbed {
> .center {
width: calc(100% - 32px);
min-width: 0;
@include media-breakpoint-down('md') {
width: calc(100% - 64px);
}
> .header {
flex: 1 1 auto;
}
> .content-card {
> .content {
display: flex;
> .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%;
}
}
}
}
}
}
}
}
// Inner scroll
&.inner-scroll {
flex: 1 1 auto;
> .sidebar {
.content {
overflow: auto;
}
}
> .center {
flex: 1 1 auto;
> .content-card {
flex: 1 1 auto;
> .content {
flex: 1 1 auto;
overflow: auto;
}
}
}
// Tabbed
&.tabbed {
> .center {
> .content-card {
> .content {
> .mat-tab-group {
.mat-tab-body {
.mat-tab-body-content {
.tab-content {
overflow: auto;
}
}
}
}
}
}
}
}
}
}
// Right sidebar specific
&.right-sidebar {
> .sidebar {
order: 2;
}
> .center {
order: 1;
}
}
}
// Simple layout
&.simple {
display: flex;
flex-direction: column;
flex: 1 0 auto;
width: 100%;
min-width: 100%;
// Fullwidth
&.fullwidth {
> .content {
flex: 1 1 auto;
min-width: 0;
}
}
&.fullwidth,
&.inner-sidebar {
> .header {
height: $header-height;
min-height: $header-height;
max-height: $header-height;
}
}
// Left / Right sidebar
&.left-sidebar,
&.right-sidebar {
flex-direction: row;
// Sidebar
> .sidebar {
width: 240px;
min-width: 240px;
max-width: 240px;
overflow: hidden;
@include mat-elevation(7);
&.locked-open {
background: none;
box-shadow: none;
+ .center {
z-index: 1001;
}
&.left-positioned {
+ .center {
margin-left: 0;
}
}
&.right-positioned {
+ .center {
margin-right: 0;
}
}
}
.content {
flex: 1 1 auto;
}
}
// Center
> .center {
position: relative;
display: flex;
flex-direction: column;
flex: 1 1 auto;
z-index: 3;
min-width: 0;
@include mat-elevation(7);
> .header {
height: $header-height;
min-height: $header-height;
max-height: $header-height;
}
> .content {
flex: 1 0 auto;
}
}
// Inner scroll
&.inner-scroll {
flex: 1 1 auto;
> .sidebar {
.content {
overflow: auto;
}
}
> .center {
flex: 1 1 auto;
overflow: auto;
}
}
// Inner Sidebar
&.inner-sidebar {
flex-direction: column;
overflow: hidden;
height: 100%;
> .content {
display: flex;
min-height: 0;
> .sidebar {
&.locked-open {
background: none;
box-shadow: none;
}
.content {
overflow: auto;
}
}
> .center {
flex: 1 1 auto;
overflow: auto;
}
}
}
}
// Right sidebar specific
&.right-sidebar {
> .sidebar {
order: 2;
}
> .center {
order: 1;
}
// Inner sidebar
&.inner-sidebar {
> .content {
> .sidebar {
order: 2;
}
> .center {
order: 1;
}
}
}
}
// Tabbed
&.tabbed {
min-height: 100%;
> .header {
height: $header-height;
min-height: $header-height;
max-height: $header-height;
}
> .content {
> .mat-tab-group {
.mat-tab-labels {
padding: 0 24px;
}
}
}
}
}
// Blank layout
&.blank {
width: 100%;
min-height: 100%;
}
@include media-breakpoint-down('xs') {
// Smaller margins
&.carded {
&.fullwidth {
> .center {
padding: 0 16px;
}
}
&.left-sidebar,
&.right-sidebar {
> .center {
margin: 0 16px;
}
}
}
// End - Smaller margins
}
}

View File

@@ -1,269 +0,0 @@
// Edit the sixteen color-value variables, and create your own syntax highlighter colorscheme
$base00: #263238;
$base01: #2C393F;
$base02: #62727A;
$base03: #707880;
$base04: #C9CCD3;
$base05: #CDD3DE;
$base06: #D5DBE5;
$base07: #FFFFFF;
$base08: #EC5F67;
$base09: #EA9560;
$base0A: #FFCC00;
$base0B: #8BD649;
$base0C: #80CBC4;
$base0D: #89DDFF;
$base0E: #82AAFF;
$base0F: #EC5F67;
$red: $base08;
$orange: $base09;
$yellow: $base0A;
$green: $base0B;
$cyan: $base0C;
$blue: $base0D;
$violet: $base0E;
$magenta: $base0F;
$code-font-family: Consolas, Menlo, Monaco, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", "Courier New", Courier, monospace;
$code-font-size: 14px;
$code-line-height: 1.6;
$code-background: $base00;
$code-color: $base05;
$code-color-fade: $base05;
// $code-text-shadow: none;
$code-color-comment: $base02;
$code-color-keyword: $base0B;
$code-color-value: $base0C;
$code-color-attr-name: $base09;
$code-color-string: $base0C;
$code-color-name: $base0A;
$code-color-number: $base09;
$code-color-variable: $base0D;
$code-color-selector: $base0E;
$code-color-property: $base0A;
$code-color-important: $base08;
$code-color-tag: $base0D;
$code-color-atrule: $base0C;
// @import "../partials/prism";
/**
* Prism base code highlighter theme using Sass
*
* @author @MoOx
* https://github.com/MoOx/sass-prism-theme-base/blob/master/_prism.scss
* slightly adapted by me, Bram de Haan
*/
// prism selector
$code-selector: "code[class*=\"language-\"], pre[class*=\"language-\"]";
$code-selector-block: "pre[class*=\"language-\"]";
$code-selector-inline: ":not(pre) > code[class*=\"language-\"]";
// generic stuff
$code-font-family: Menlo, Monaco, "Courier New", monospace !default;
$code-font-size: 14px !default;
$code-line-height: 1.6 !default;
$code-tab-size: 4 !default;
$code-hyphens: none !default;
$code-block-padding: 12px !default;
$code-inline-padding: 2px 6px !default;
$code-border-radius: 0 !default;
$code-border: none !default;
$code-background: #2A2A2A !default;
$code-color: #FFF !default;
$code-color-fade: #BEBEC5 !default;
// $code-text-shadow: 0 1px 0 #000 !default;
$code-box-shadow: none !default;
$code-color-property: #B58900 !default;
$code-color-important: #CB4B16 !default;
$code-color-tag: #268BD2 !default;
$code-color-atrule: #2AA198 !default;
$code-color-attr-name: #B65611 !default;
// $code-linenums-padding: 7px !default;
// $code-linenums-width: 40px !default;
// $code-linenums-background: #444 !default;
// $code-linenums-border-color: #555 !default;
// $code-linenums-border-width: 1px !default;
@if $code-selector != null {
#{$code-selector} {
-moz-tab-size: $code-tab-size;
-o-tab-size: $code-tab-size;
tab-size: $code-tab-size;
-webkit-hyphens: $code-hyphens;
-moz-hyphens: $code-hyphens;
-ms-hyphens: $code-hyphens;
hyphens: $code-hyphens;
// whitespace management
white-space: pre; // fallback
//white-space: pre-wrap;
//word-break: break-all;
//word-wrap: break-word;
font-family: $code-font-family;
font-size: $code-font-size;
line-height: $code-line-height;
color: $code-color;
// text-shadow: $code-text-shadow;
background: $code-background;
}
}
%code-background {
border-radius: $code-border-radius;
border: $code-border;
box-shadow: $code-box-shadow;
}
@if $code-selector-block != null {
#{$code-selector-block} {
@extend %code-background;
padding: $code-block-padding;
}
}
@if $code-selector-inline != null {
#{$code-selector-inline} {
@extend %code-background;
padding: $code-inline-padding;
}
}
// pre[class*="language-"],
// :not(pre) > code[class*="language-"] {
// background: $code-background;
// }
// prism tokens
//
$code-color-comment: null !default;
$code-color-keyword: null !default;
$code-color-value: null !default;
$code-color-string: null !default;
$code-color-name: null !default;
$code-color-number: null !default;
$code-color-variable: null !default;
$code-color-selector: null !default;
$code-color-punctuation: $code-color-fade !default;
#{$code-selector} {
.namespace {
opacity: .7;
}
.token {
&.comment,
&.prolog,
&.doctype,
&.cdata {
color: $code-color-comment;
}
&.null,
&.operator,
&.boolean,
&.number {
color: $code-color-number;
}
&.string {
color: $code-color-string;
}
&.attr-name {
color: $code-color-attr-name;
}
&.entity,
&.url,
.language-css &.string,
.style &.string {
color: $code-color-string;
}
&.selector {
color: $code-color-selector;
}
&.attr-value,
&.keyword,
&.control,
&.directive,
&.unit {
color: $code-color-keyword;
}
&.important {
color: $code-color-important;
}
&.atrule {
color: $code-color-atrule;
}
&.regex,
&.statement {
color: $code-color-value;
}
&.placeholder,
&.variable {
color: $code-color-variable;
}
&.property,
&.tag {
// font-style: italic;
}
&.property {
color: $code-color-property;
}
&.tag {
color: $code-color-tag;
}
&.important,
&.statement {
font-weight: bold;
}
// todo ?
// &.mixin
// &.gradient
// &.abslength
// &.easing
// &.time
// &.angle
// &.fontfamily
// ruby/vim https://github.com/LeaVerou/prism/pull/18
// &.inst-var
// &.builtin
// &.const
// &.symbol
//
// php https://github.com/LeaVerou/prism/pull/20
// &.deliminator
// &.function
&.punctuation {
color: $code-color-punctuation;
}
&.entity {
cursor: help;
}
// for dev :)
&.debug {
color: red
}
}
}

View File

@@ -1,157 +0,0 @@
import { Inject, Injectable, InjectionToken } from '@angular/core';
import { NavigationStart, Router } from '@angular/router';
import { Platform } from '@angular/cdk/platform';
import { BehaviorSubject, Observable } from 'rxjs';
import { filter } from 'rxjs/operators';
import * as _ from 'lodash';
// Create the injection token for the custom settings
export const FUSE_CONFIG = new InjectionToken('fuseCustomConfig');
@Injectable({
providedIn: 'root'
})
export class FuseConfigService
{
// Private
private _configSubject: BehaviorSubject<any>;
private readonly _defaultConfig: any;
/**
* Constructor
*
* @param {Platform} _platform
* @param {Router} _router
* @param _config
*/
constructor(
private _platform: Platform,
private _router: Router,
@Inject(FUSE_CONFIG) private _config
)
{
// Set the default config from the user provided config (from forRoot)
this._defaultConfig = _config;
// Initialize the service
this._init();
}
// -----------------------------------------------------------------------------------------------------
// @ Accessors
// -----------------------------------------------------------------------------------------------------
/**
* Set and get the config
*/
set config(value)
{
// Get the value from the behavior subject
let config = this._configSubject.getValue();
// Merge the new config
config = _.merge({}, config, value);
// Notify the observers
this._configSubject.next(config);
}
get config(): any | Observable<any>
{
return this._configSubject.asObservable();
}
/**
* Get default config
*
* @returns {any}
*/
get defaultConfig(): any
{
return this._defaultConfig;
}
// -----------------------------------------------------------------------------------------------------
// @ Private methods
// -----------------------------------------------------------------------------------------------------
/**
* Initialize
*
* @private
*/
private _init(): void
{
/**
* Disable custom scrollbars if browser is mobile
*/
if ( this._platform.ANDROID || this._platform.IOS )
{
this._defaultConfig.customScrollbars = false;
}
// Set the config from the default config
this._configSubject = new BehaviorSubject(_.cloneDeep(this._defaultConfig));
// Reload the default config on every navigation start if
// the current config is different from the default one
this._router.events
.pipe(filter(event => event instanceof NavigationStart))
.subscribe(() => {
if ( !_.isEqual(this._configSubject.getValue(), this._defaultConfig) )
{
// Clone the default config
const config = _.cloneDeep(this._defaultConfig);
// Set the config
this._configSubject.next(config);
}
});
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Set config
*
* @param value
* @param {{emitEvent: boolean}} opts
*/
setConfig(value, opts = {emitEvent: true}): void
{
// Get the value from the behavior subject
let config = this._configSubject.getValue();
// Merge the new config
config = _.merge({}, config, value);
// If emitEvent option is true...
if ( opts.emitEvent === true )
{
// Notify the observers
this._configSubject.next(config);
}
}
/**
* Get config
*
* @returns {Observable<any>}
*/
getConfig(): Observable<any>
{
return this._configSubject.asObservable();
}
/**
* Reset to the default config
*/
resetToDefaults(): void
{
// Set the config from the default config
this._configSubject.next(_.cloneDeep(this._defaultConfig));
}
}

View File

@@ -1,91 +0,0 @@
import { Injectable } from '@angular/core';
import { NavigationEnd, NavigationStart, Router } from '@angular/router';
import { BehaviorSubject, Observable } from 'rxjs';
import { filter } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class FuseLoadingBarService
{
// Private
private _visible: BehaviorSubject<boolean>;
/**
* Constructor
*
* @param {Router} _router
*/
constructor(
private _router: Router
)
{
// Initialize the service
this._init();
}
// -----------------------------------------------------------------------------------------------------
// @ Accessors
// -----------------------------------------------------------------------------------------------------
get visible(): Observable<any>
{
// Return the _visible as observable
return this._visible.asObservable();
}
// -----------------------------------------------------------------------------------------------------
// @ Private methods
// -----------------------------------------------------------------------------------------------------
/**
* Initialize
*
* @private
*/
private _init(): void
{
// Initialize the behavior subject
this._visible = new BehaviorSubject(false);
// Subscribe to the router events to show/hide the loading bar
this._router.events
.pipe(
filter((event) => event instanceof NavigationStart)
)
.subscribe(() => {
this.showLoadingBar();
});
this._router.events
.pipe(
filter((event) => event instanceof NavigationEnd)
)
.subscribe(() => {
this.hideLoadingBar();
});
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Show the loading bar
*/
showLoadingBar(): void
{
// Show
this._visible.next(true);
}
/**
* Hide the loading bar
*/
hideLoadingBar(): void
{
// Hide
this._visible.next(false);
}
}

View File

@@ -1,51 +0,0 @@
import { MediaChange, ObservableMedia } from '@angular/flex-layout';
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class FuseMatchMediaService
{
activeMediaQuery: string;
onMediaChange: BehaviorSubject<string> = new BehaviorSubject<string>('');
/**
* Constructor
*
* @param {ObservableMedia} _observableMedia
*/
constructor(
private _observableMedia: ObservableMedia
)
{
// Set the defaults
this.activeMediaQuery = '';
// Initialize
this._init();
}
// -----------------------------------------------------------------------------------------------------
// @ Private methods
// -----------------------------------------------------------------------------------------------------
/**
* Initialize
*
* @private
*/
private _init(): void
{
this._observableMedia
.subscribe((change: MediaChange) => {
if ( this.activeMediaQuery !== change.mqAlias )
{
this.activeMediaQuery = change.mqAlias;
this.onMediaChange.next(change.mqAlias);
}
});
}
}

View File

@@ -1,108 +0,0 @@
import { Inject, Injectable } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { animate, AnimationBuilder, AnimationPlayer, style } from '@angular/animations';
import { NavigationEnd, Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class FuseSplashScreenService
{
splashScreenEl: any;
player: AnimationPlayer;
/**
* Constructor
*
* @param {AnimationBuilder} _animationBuilder
* @param _document
* @param {Router} _router
*/
constructor(
private _animationBuilder: AnimationBuilder,
@Inject(DOCUMENT) private _document: any,
private _router: Router
)
{
// Initialize
this._init();
}
// -----------------------------------------------------------------------------------------------------
// @ Private methods
// -----------------------------------------------------------------------------------------------------
/**
* Initialize
*
* @private
*/
private _init(): void
{
// Get the splash screen element
this.splashScreenEl = this._document.body.querySelector('#fuse-splash-screen');
// If the splash screen element exists...
if ( this.splashScreenEl )
{
// Hide it on the first NavigationEnd event
const hideOnLoad = this._router.events.subscribe((event) => {
if ( event instanceof NavigationEnd )
{
setTimeout(() => {
this.hide();
// Unsubscribe from this event so it
// won't get triggered again
hideOnLoad.unsubscribe();
}, 0);
}
}
);
}
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Show the splash screen
*/
show(): void
{
this.player =
this._animationBuilder
.build([
style({
opacity: '0',
zIndex : '99999'
}),
animate('400ms ease', style({opacity: '1'}))
]).create(this.splashScreenEl);
setTimeout(() => {
this.player.play();
}, 0);
}
/**
* Hide the splash screen
*/
hide(): void
{
this.player =
this._animationBuilder
.build([
style({opacity: '1'}),
animate('400ms ease', style({
opacity: '0',
zIndex : '-10'
}))
]).create(this.splashScreenEl);
setTimeout(() => {
this.player.play();
}, 0);
}
}

View File

@@ -1,45 +0,0 @@
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
export interface Locale
{
lang: string;
data: Object;
}
@Injectable({
providedIn: 'root'
})
export class FuseTranslationLoaderService
{
/**
* Constructor
*
* @param {TranslateService} _translateService
*/
constructor(
private _translateService: TranslateService
)
{
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Load translations
*
* @param {Locale} args
*/
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._translateService.setTranslation(locale.lang, locale.data, true);
});
}
}

View File

@@ -1,34 +0,0 @@
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { FlexLayoutModule } from '@angular/flex-layout';
import { FuseDirectivesModule } from '@fuse/directives/directives';
import { FusePipesModule } from '@fuse/pipes/pipes.module';
@NgModule({
imports : [
CommonModule,
FormsModule,
ReactiveFormsModule,
FlexLayoutModule,
FuseDirectivesModule,
FusePipesModule
],
exports : [
CommonModule,
FormsModule,
ReactiveFormsModule,
FlexLayoutModule,
FuseDirectivesModule,
FusePipesModule
]
})
export class FuseSharedModule
{
}

View File

@@ -1,29 +0,0 @@
export interface FuseConfig
{
layout: {
style: string,
width: 'fullwidth' | 'boxed',
navbar: {
background: string,
hidden: boolean,
folded: boolean,
position: 'left' | 'right' | 'top',
variant: string
},
toolbar: {
background: string,
hidden: boolean,
position: 'above' | 'above-static' | 'above-fixed' | 'below' | 'below-static' | 'below-fixed'
}
footer: {
background: string,
hidden: boolean,
position: 'above' | 'above-static' | 'above-fixed' | 'below' | 'below-static' | 'below-fixed'
},
sidepanel: {
hidden: boolean,
position: 'left' | 'right'
}
};
customScrollbars: boolean;
}

View File

@@ -1,27 +0,0 @@
export interface FuseNavigationItem
{
id: string;
title: string;
type: 'item' | 'group' | 'collapsable';
translate?: string;
icon?: string;
hidden?: boolean;
url?: string;
classes?: string;
exactMatch?: boolean;
externalUrl?: boolean;
openInNewTab?: boolean;
function?: any;
badge?: {
title?: string;
translate?: string;
bg?: string;
fg?: string;
};
children?: FuseNavigationItem[];
}
export interface FuseNavigation extends FuseNavigationItem
{
children?: FuseNavigationItem[];
}

View File

@@ -1,2 +0,0 @@
export * from './fuse-config';
export * from './fuse-navigation';

View File

@@ -1,31 +1 @@
<!-- VERTICAL LAYOUT 1 -->
<ng-container *ngIf="fuseConfig.layout.style === 'vertical-layout-1'">
<vertical-layout-1></vertical-layout-1>
</ng-container>
<!-- VERTICAL LAYOUT 2 -->
<ng-container *ngIf="fuseConfig.layout.style === 'vertical-layout-2'">
<vertical-layout-2></vertical-layout-2>
</ng-container>
<!-- VERTICAL LAYOUT 3 -->
<ng-container *ngIf="fuseConfig.layout.style === 'vertical-layout-3'">
<vertical-layout-3></vertical-layout-3>
</ng-container>
<!-- HORIZONTAL LAYOUT 1 -->
<ng-container *ngIf="fuseConfig.layout.style === 'horizontal-layout-1'">
<horizontal-layout-1></horizontal-layout-1>
</ng-container>
<!-- THEME OPTIONS PANEL -->
<button mat-icon-button class="mat-primary-bg mat-elevation-z2 theme-options-button"
[ngClass]="{'right-side-panel': fuseConfig.layout.sidepanel.position === 'right',
'side-panel-hidden': fuseConfig.layout.sidepanel.hidden === true}"
(click)="toggleSidebarOpen('themeOptionsPanel')">
<mat-icon>settings</mat-icon>
</button>
<fuse-sidebar name="themeOptionsPanel" class="theme-options-sidebar" position="right" [invisibleOverlay]="true">
<fuse-theme-options></fuse-theme-options>
</fuse-sidebar>
<fuse-main></fuse-main>

View File

@@ -1,51 +0,0 @@
@import "src/@fuse/scss/fuse";
:host {
position: relative;
display: flex;
flex: 1 1 auto;
width: 100%;
height: 100%;
min-width: 0;
.theme-options-button {
position: absolute;
top: 160px;
right: 0;
width: 48px;
height: 48px;
line-height: 48px;
text-align: center;
cursor: pointer;
border-radius: 0;
margin: 0;
pointer-events: auto;
opacity: .90;
z-index: 998;
&.right-side-panel {
@include media-breakpoint-up('lg') {
right: 70px;
}
}
&.side-panel-hidden {
right: 0 !important;
}
mat-icon {
animation: rotating 3s linear infinite;
}
&:hover {
opacity: 1;
}
}
.theme-options-sidebar {
width: 360px;
min-width: 360px;
max-width: 360px;
}
}

View File

@@ -1,125 +1,40 @@
import { Component, Inject, OnDestroy, OnInit } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { Platform } from '@angular/cdk/platform';
import { Component } from '@angular/core';
import { FuseSplashScreenService } from './core/services/splash-screen.service';
import { TranslateService } from '@ngx-translate/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FuseTranslationLoaderService } from './core/services/translation-loader.service';
import { FuseConfigService } from '@fuse/services/config.service';
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service';
import { FuseSplashScreenService } from '@fuse/services/splash-screen.service';
import { FuseTranslationLoaderService } from '@fuse/services/translation-loader.service';
import { navigation } from 'app/navigation/navigation';
import { locale as navigationEnglish } from 'app/navigation/i18n/en';
import { locale as navigationTurkish } from 'app/navigation/i18n/tr';
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 : 'app',
selector : 'fuse-root',
templateUrl: './app.component.html',
styleUrls : ['./app.component.scss']
})
export class AppComponent implements OnInit, OnDestroy
export class AppComponent
{
navigation: any;
fuseConfig: any;
// Private
private _unsubscribeAll: Subject<any>;
/**
* Constructor
*
* @param {DOCUMENT} document
* @param {FuseConfigService} _fuseConfigService
* @param {FuseNavigationService} _fuseNavigationService
* @param {FuseSidebarService} _fuseSidebarService
* @param {FuseSplashScreenService} _fuseSplashScreenService
* @param {FuseTranslationLoaderService} _fuseTranslationLoaderService
* @param {Platform} _platform
* @param {TranslateService} _translateService
*/
constructor(
@Inject(DOCUMENT) private document: any,
private _fuseConfigService: FuseConfigService,
private _fuseNavigationService: FuseNavigationService,
private _fuseSidebarService: FuseSidebarService,
private _fuseSplashScreenService: FuseSplashScreenService,
private _fuseTranslationLoaderService: FuseTranslationLoaderService,
private _translateService: TranslateService,
private _platform: Platform
private fuseNavigationService: FuseNavigationService,
private fuseSplashScreen: FuseSplashScreenService,
private translate: TranslateService,
private translationLoader: FuseTranslationLoaderService
)
{
// Get default navigation
this.navigation = navigation;
// Register the navigation to the service
this._fuseNavigationService.register('main', this.navigation);
// Set the main navigation as our current navigation
this._fuseNavigationService.setCurrentNavigation('main');
// Add languages
this._translateService.addLangs(['en', 'tr']);
this.translate.addLangs(['en', 'tr']);
// Set the default language
this._translateService.setDefaultLang('en');
// Set the navigation translations
this._fuseTranslationLoaderService.loadTranslations(navigationEnglish, navigationTurkish);
this.translate.setDefaultLang('en');
// Use a language
this._translateService.use('en');
this.translate.use('en');
// Add is-mobile class to the body if the platform is mobile
if ( this._platform.ANDROID || this._platform.IOS )
{
this.document.body.className += ' is-mobile';
}
// Set the navigation model
this.fuseNavigationService.setNavigationModel(new FuseNavigationModel());
// Set the private defaults
this._unsubscribeAll = new Subject();
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void
{
// Subscribe to config changes
this._fuseConfigService.config
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((config) => {
this.fuseConfig = config;
});
}
/**
* On destroy
*/
ngOnDestroy(): void
{
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Toggle sidebar open
*
* @param key
*/
toggleSidebarOpen(key): void
{
this._fuseSidebarService.getSidebar(key).toggleOpen();
// Set the navigation translations
this.translationLoader.loadTranslations(navigationEnglish, navigationTurkish);
}
}

View File

@@ -3,47 +3,20 @@ import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterModule, Routes } from '@angular/router';
import { MatMomentDateModule } from '@angular/material-moment-adapter';
import { MatButtonModule, MatIconModule } from '@angular/material';
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { TranslateModule } from '@ngx-translate/core';
import 'hammerjs';
import { FuseModule } from '@fuse/fuse.module';
import { FuseSharedModule } from '@fuse/shared.module';
import { FuseSidebarModule, FuseThemeOptionsModule } from '@fuse/components';
import { fuseConfig } from 'app/fuse-config';
import { FakeDbService } from 'app/fake-db/fake-db.service';
import { AppComponent } from 'app/app.component';
import { AppStoreModule } from 'app/store/store.module';
import { LayoutModule } from 'app/layout/layout.module';
import { SharedModule } from './core/modules/shared.module';
import { AppComponent } from './app.component';
import { FuseMainModule } from './main/main.module';
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 = [
{
path : 'apps',
loadChildren: './main/apps/apps.module#AppsModule'
},
{
path : 'pages',
loadChildren: './main/pages/pages.module#PagesModule'
},
{
path : 'ui',
loadChildren: './main/ui/ui.module#UIModule'
},
{
path : 'documentation',
loadChildren: './main/documentation/documentation.module#DocumentationModule'
},
{
path : 'angular-material-elements',
loadChildren: './main/angular-material-elements/angular-material-elements.module#AngularMaterialElementsModule'
},
{
path : '**',
redirectTo: 'apps/dashboards/analytics'
redirectTo: 'sample'
}
];
@@ -53,32 +26,18 @@ const appRoutes: Routes = [
],
imports : [
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
BrowserAnimationsModule,
RouterModule.forRoot(appRoutes),
SharedModule,
TranslateModule.forRoot(),
InMemoryWebApiModule.forRoot(FakeDbService, {
delay : 0,
passThruUnknownUrl: true
}),
// Material moment date module
MatMomentDateModule,
// Material
MatButtonModule,
MatIconModule,
// Fuse modules
FuseModule.forRoot(fuseConfig),
FuseSharedModule,
FuseSidebarModule,
FuseThemeOptionsModule,
// App modules
LayoutModule,
AppStoreModule
FuseMainModule,
FuseSampleModule
],
providers : [
FuseSplashScreenService,
FuseConfigService,
FuseNavigationService
],
bootstrap : [
AppComponent

View File

@@ -187,14 +187,10 @@ export const fuseAnimations = [
transition('* => void', animate('300ms ease-in'))
]),
// -----------------------------------------------------------------------------------------------------
// @ Router animations
// -----------------------------------------------------------------------------------------------------
trigger('routerTransitionLeft', [
transition('* => *', [
query('content > :enter, content > :leave', [
query('fuse-content > :enter, fuse-content > :leave', [
style({
position: 'absolute',
top : 0,
@@ -203,7 +199,7 @@ export const fuseAnimations = [
right : 0
})
], {optional: true}),
query('content > :enter', [
query('fuse-content > :enter', [
style({
transform: 'translateX(100%)',
opacity : 0
@@ -211,7 +207,7 @@ export const fuseAnimations = [
], {optional: true}),
sequence([
group([
query('content > :leave', [
query('fuse-content > :leave', [
style({
transform: 'translateX(0)',
opacity : 1
@@ -222,7 +218,7 @@ export const fuseAnimations = [
opacity : 0
}))
], {optional: true}),
query('content > :enter', [
query('fuse-content > :enter', [
style({transform: 'translateX(100%)'}),
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
style({
@@ -231,8 +227,8 @@ export const fuseAnimations = [
}))
], {optional: true})
]),
query('content > :leave', animateChild(), {optional: true}),
query('content > :enter', animateChild(), {optional: true})
query('fuse-content > :leave', animateChild(), {optional: true}),
query('fuse-content > :enter', animateChild(), {optional: true})
])
])
]),
@@ -240,7 +236,7 @@ export const fuseAnimations = [
trigger('routerTransitionRight', [
transition('* => *', [
query('content > :enter, content > :leave', [
query('fuse-content > :enter, fuse-content > :leave', [
style({
position: 'absolute',
top : 0,
@@ -249,7 +245,7 @@ export const fuseAnimations = [
right : 0
})
], {optional: true}),
query('content > :enter', [
query('fuse-content > :enter', [
style({
transform: 'translateX(-100%)',
opacity : 0
@@ -257,7 +253,7 @@ export const fuseAnimations = [
], {optional: true}),
sequence([
group([
query('content > :leave', [
query('fuse-content > :leave', [
style({
transform: 'translateX(0)',
opacity : 1
@@ -268,7 +264,7 @@ export const fuseAnimations = [
opacity : 0
}))
], {optional: true}),
query('content > :enter', [
query('fuse-content > :enter', [
style({transform: 'translateX(-100%)'}),
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
style({
@@ -277,8 +273,8 @@ export const fuseAnimations = [
}))
], {optional: true})
]),
query('content > :leave', animateChild(), {optional: true}),
query('content > :enter', animateChild(), {optional: true})
query('fuse-content > :leave', animateChild(), {optional: true}),
query('fuse-content > :enter', animateChild(), {optional: true})
])
])
]),
@@ -286,7 +282,7 @@ export const fuseAnimations = [
trigger('routerTransitionUp', [
transition('* => *', [
query('content > :enter, content > :leave', [
query('fuse-content > :enter, fuse-content > :leave', [
style({
position: 'absolute',
top : 0,
@@ -295,14 +291,14 @@ export const fuseAnimations = [
right : 0
})
], {optional: true}),
query('content > :enter', [
query('fuse-content > :enter', [
style({
transform: 'translateY(100%)',
opacity : 0
})
], {optional: true}),
group([
query('content > :leave', [
query('fuse-content > :leave', [
style({
transform: 'translateY(0)',
opacity : 1
@@ -313,7 +309,7 @@ export const fuseAnimations = [
opacity : 0
}))
], {optional: true}),
query('content > :enter', [
query('fuse-content > :enter', [
style({transform: 'translateY(100%)'}),
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
style({
@@ -322,15 +318,15 @@ export const fuseAnimations = [
}))
], {optional: true})
]),
query('content > :leave', animateChild(), {optional: true}),
query('content > :enter', animateChild(), {optional: true})
query('fuse-content > :leave', animateChild(), {optional: true}),
query('fuse-content > :enter', animateChild(), {optional: true})
])
]),
trigger('routerTransitionDown', [
transition('* => *', [
query('content > :enter, content > :leave', [
query('fuse-content > :enter, fuse-content > :leave', [
style({
position: 'absolute',
top : 0,
@@ -339,7 +335,7 @@ export const fuseAnimations = [
right : 0
})
], {optional: true}),
query('content > :enter', [
query('fuse-content > :enter', [
style({
transform: 'translateY(-100%)',
opacity : 0
@@ -347,7 +343,7 @@ export const fuseAnimations = [
], {optional: true}),
sequence([
group([
query('content > :leave', [
query('fuse-content > :leave', [
style({
transform: 'translateY(0)',
opacity : 1
@@ -358,7 +354,7 @@ export const fuseAnimations = [
opacity : 0
}))
], {optional: true}),
query('content > :enter', [
query('fuse-content > :enter', [
style({transform: 'translateY(-100%)'}),
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
style({
@@ -367,8 +363,8 @@ export const fuseAnimations = [
}))
], {optional: true})
]),
query('content > :leave', animateChild(), {optional: true}),
query('content > :enter', animateChild(), {optional: true})
query('fuse-content > :leave', animateChild(), {optional: true}),
query('fuse-content > :enter', animateChild(), {optional: true})
])
])
]),
@@ -377,7 +373,7 @@ export const fuseAnimations = [
transition('* => *', group([
query('content > :enter, content > :leave ', [
query('fuse-content > :enter, fuse-content > :leave ', [
style({
position: 'absolute',
top : 0,
@@ -387,12 +383,12 @@ export const fuseAnimations = [
})
], {optional: true}),
query('content > :enter', [
query('fuse-content > :enter', [
style({
opacity: 0
})
], {optional: true}),
query('content > :leave', [
query('fuse-content > :leave', [
style({
opacity: 1
}),
@@ -401,7 +397,7 @@ export const fuseAnimations = [
opacity: 0
}))
], {optional: true}),
query('content > :enter', [
query('fuse-content > :enter', [
style({
opacity: 0
}),
@@ -410,8 +406,8 @@ export const fuseAnimations = [
opacity: 1
}))
], {optional: true}),
query('content > :enter', animateChild(), {optional: true}),
query('content > :leave', animateChild(), {optional: true})
query('fuse-content > :enter', animateChild(), {optional: true}),
query('fuse-content > :leave', animateChild(), {optional: true})
]))
])
];

View File

@@ -0,0 +1,21 @@
import { Component, OnInit } from '@angular/core';
import { MatDialogRef } from '@angular/material';
@Component({
selector : 'fuse-confirm-dialog',
templateUrl: './confirm-dialog.component.html',
styleUrls : ['./confirm-dialog.component.scss']
})
export class FuseConfirmDialogComponent implements OnInit
{
public confirmMessage: string;
constructor(public dialogRef: MatDialogRef<FuseConfirmDialogComponent>)
{
}
ngOnInit()
{
}
}

View File

@@ -1,31 +1,26 @@
/**
* This class is based on the code in the following projects:
* https://github.com/zenorocha/select
* https://github.com/zenorocha/clipboard.js/
*
* - https://github.com/zenorocha/select
* - https://github.com/zenorocha/clipboard.js/
*
* Both released under MIT license - © Zeno Rocha
*/
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class FuseCopierService
@Injectable()
export class CopierService
{
private textarea: HTMLTextAreaElement;
/**
* Copy the text value to the clipboard
*
* @param {string} text
* @returns {boolean}
*/
/** Copy the text value to the clipboard. */
copyText(text: string): boolean
{
this.createTextareaAndSelect(text);
const copySuccessful = document.execCommand('copy');
this._removeFake();
this.removeFake();
return copySuccessful;
}
@@ -33,10 +28,8 @@ export class FuseCopierService
/**
* Creates a hidden textarea element, sets its value from `text` property,
* and makes a selection on it.
*
* @param {string} text
*/
private createTextareaAndSelect(text: string): void
private createTextareaAndSelect(text: string)
{
// Create a fake element to hold the contents to copy
this.textarea = document.createElement('textarea');
@@ -60,12 +53,8 @@ export class FuseCopierService
this.textarea.setSelectionRange(0, this.textarea.value.length);
}
/**
* Remove the text area from the DOM
*
* @private
*/
private _removeFake(): void
/** Remove the text area from the DOM. */
private removeFake()
{
if ( this.textarea )
{

View File

@@ -0,0 +1,54 @@
import { Component, Input, OnInit } from '@angular/core';
import * as moment from 'moment';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/interval';
@Component({
selector : 'fuse-countdown',
templateUrl: './countdown.component.html',
styleUrls : ['./countdown.component.scss']
})
export class FuseCountdownComponent implements OnInit
{
@Input('eventDate') eventDate;
countdown: any;
constructor()
{
this.countdown = {
days : '',
hours : '',
minutes: '',
seconds: ''
};
}
ngOnInit()
{
const currDate = moment();
const eventDate = moment(this.eventDate);
let diff = eventDate.diff(currDate, 'seconds');
const countDown =
Observable
.interval(1000)
.map(value => {
return diff = diff - 1;
})
.map(value => {
const timeLeft = moment.duration(value, 'seconds');
return {
days : timeLeft.asDays().toFixed(0),
hours : timeLeft.hours(),
minutes: timeLeft.minutes(),
seconds: timeLeft.seconds()
};
});
countDown.subscribe(value => {
this.countdown = value;
});
}
}

View File

@@ -0,0 +1,75 @@
<!-- DEMO CONTENT -->
<div class="demo-content">
<img src="assets/images/beach.jpg" alt="beach" style="max-width: 640px; width: 100%;">
<h1>Early Sunrise</h1>
<h4 class="secondary-text">Demo Content</h4>
<p>
One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a
horrible vermin. He lay on his armour-like back, and if he lifted his head a little he could see his
brown belly, slightly domed and divided by arches into stiff sections.
</p>
<blockquote>
<p>
The bedding was hardly able to cover it and seemed ready to slide off any moment. His many legs,
pitifully thin compared with the size of the rest of him, waved about helplessly as he looked. "What's
happened to me? " he thought. It wasn't a dream.
</p>
<footer>
John Doe
</footer>
</blockquote>
<p>
His room, a proper human room although a little too small, lay peacefully between its four familiar
walls. A collection of textile samples lay spread out on the table - Samsa was a travelling salesman -
and above it there hung a picture that he had recently cut out of an illustrated magazine and housed in
a nice, gilded frame.
</p>
<p>
It showed a lady fitted out with a fur hat and fur boa who sat upright, raising a heavy fur muff that
covered the whole of her lower arm towards the viewer. Gregor then turned to look out the window at the
dull weather. Drops of rain could be heard hitting the pane, which made him feel quite sad.
</p>
<p>
"How about if I sleep a little bit longer and forget all this nonsense", he thought, but that was
something he was unable to do because he was used to sleeping on his right, and in his present state
couldn't get into that position. However hard he threw himself onto his right, he always rolled back to
where he was.
</p>
<p>
He must have tried it a hundred times, shut his eyes so that he wouldn't have to look at the floundering
legs, and only stopped when he began to feel a mild, dull pain there that he had never felt before. "Oh,
God", he thought, "what a strenuous career it is that I've chosen!
</p>
<p>
Travelling day in and day out. Doing business like this takes much more effort than doing your own
business at home, and on top of that there's the curse of travelling, worries about making train
connections, bad and irregular food, contact with different people all the time so that you can never
get to know anyone or become friendly with them.
</p>
<p>
"He felt a slight itch up on his belly; pushed himself slowly up on his back towards the headboard so
that he could lift his head better; found where the itch was, and saw that it was covered with lots of
little white spots which he didn't know what to make of; and when he tried to feel the place with one of
his legs he drew it quickly back because as soon as he touched it he was overcome by a cold shudder. He
slid back into his former position.
</p>
<p>
"Getting up early all the time", he thought, "it makes you stupid. You've got to get enough sleep. Other
travelling salesmen live a life of luxury. For instance, whenever I go back to the guest house during
the morning to copy out the contract, these gentlemen are always still sitting there eating their
breakfasts. I ought to just try that with my boss; I'd get kicked out on the spot. But who knows, maybe
that would be the best thing for me...
</p>
</div>
<!-- / DEMO CONTENT -->

View File

@@ -7,9 +7,6 @@ import { Component } from '@angular/core';
})
export class FuseDemoContentComponent
{
/**
* Constructor
*/
constructor()
{
}

View File

@@ -1,99 +1,99 @@
<div class="demo-sidebar">
<div class="demo-sidenav">
<mat-list>
<h3 matSubheader>Sidebar Demo</h3>
<h3 matSubheader>Sidenav Demo</h3>
<mat-list-item>
<span>Sidebar Item 1</span>
<span>Sidenav Item 1</span>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item>
<span>Sidebar Item 2</span>
<span>Sidenav Item 2</span>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item>
<span>Sidebar Item 3</span>
<span>Sidenav Item 3</span>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item>
<span>Sidebar Item 4</span>
<span>Sidenav Item 4</span>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item>
<span>Sidebar Item 5</span>
<span>Sidenav Item 5</span>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item>
<span>Sidebar Item 6</span>
<span>Sidenav Item 6</span>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item>
<span>Sidebar Item 7</span>
<span>Sidenav Item 7</span>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item>
<span>Sidebar Item 8</span>
<span>Sidenav Item 8</span>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item>
<span>Sidebar Item 9</span>
<span>Sidenav Item 9</span>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item>
<span>Sidebar Item 10</span>
<span>Sidenav Item 10</span>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item>
<span>Sidebar Item 11</span>
<span>Sidenav Item 11</span>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item>
<span>Sidebar Item 12</span>
<span>Sidenav Item 12</span>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item>
<span>Sidebar Item 13</span>
<span>Sidenav Item 13</span>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item>
<span>Sidebar Item 14</span>
<span>Sidenav Item 14</span>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item>
<span>Sidebar Item 15</span>
<span>Sidenav Item 15</span>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item>
<span>Sidebar Item 16</span>
<span>Sidenav Item 16</span>
</mat-list-item>
</mat-list>

View File

@@ -0,0 +1,13 @@
import { Component } from '@angular/core';
@Component({
selector : 'fuse-demo-sidenav',
templateUrl: './demo-sidenav.component.html',
styleUrls : ['./demo-sidenav.component.scss']
})
export class FuseDemoSidenavComponent
{
constructor()
{
}
}

View File

@@ -1,25 +1,21 @@
import { NgModule } from '@angular/core';
import { SharedModule } from '../../modules/shared.module';
import { RouterModule } from '@angular/router';
import { MatDividerModule, MatListModule } from '@angular/material';
import { FuseDemoContentComponent } from './demo-content/demo-content.component';
import { FuseDemoSidebarComponent } from './demo-sidebar/demo-sidebar.component';
import { FuseDemoSidenavComponent } from './demo-sidenav/demo-sidenav.component';
@NgModule({
declarations: [
FuseDemoContentComponent,
FuseDemoSidebarComponent
FuseDemoSidenavComponent
],
imports : [
RouterModule,
MatDividerModule,
MatListModule
SharedModule,
RouterModule
],
exports : [
FuseDemoContentComponent,
FuseDemoSidebarComponent
FuseDemoSidenavComponent
]
})
export class FuseDemoModule

View File

@@ -0,0 +1,58 @@
import { Component, ContentChild, ElementRef, Input, OnInit } from '@angular/core';
import * as hljs from 'highlight.js';
@Component({
selector : 'fuse-hljs',
template : ' ',
styleUrls: ['./hljs.component.scss']
})
export class FuseHljsComponent implements OnInit
{
hljs: any;
@ContentChild('source') source: ElementRef;
@Input('lang') lang: string;
constructor(
private elementRef: ElementRef
)
{
this.hljs = hljs;
}
ngOnInit()
{
const originalSource = this.source.nativeElement.value;
if ( !originalSource || !this.lang )
{
return;
}
// Split the source into lines
const sourceLines = originalSource.split('\n');
// Find the first non-whitespace char index in
// the first line of the source code
const indexOfFirstChar = sourceLines[0].search(/\S|$/);
// Generate the trimmed source
let source = '';
// Iterate through all the lines and trim the
// beginning white space depending on the index
sourceLines.forEach((line, index) => {
source = source + line.substr(indexOfFirstChar, line.length);
if ( index !== sourceLines.length - 1 )
{
source = source + '\n';
}
});
this.elementRef.nativeElement.innerHTML =
`<pre><code class="highlight">` + this.hljs.highlight(this.lang, source).value + `</code></pre>`;
}
}

View File

@@ -9,8 +9,10 @@
<mat-menu #colorMenu="matMenu" class="fuse-material-color-picker-menu">
<header [ngClass]="selectedColor?.class || 'mat-accent-bg'" class="mat-elevation-z4"
fxLayout="row" fxLayoutAlign="space-between center">
<header [ngClass]="selectedColor?.class || 'mat-accent-bg'"
class="mat-elevation-z4"
fxLayout="row"
fxLayoutAlign="space-between center">
<button mat-icon-button
[style.visibility]="view==='hues'?'visible':'hidden'"
@@ -28,7 +30,7 @@
<button mat-icon-button
class="remove-color-button"
(click)="$event.stopPropagation();removeColor()"
(click)="removeColor()"
aria-label="Remove Color">
<mat-icon class="s-20">delete</mat-icon>
</button>
@@ -37,9 +39,13 @@
<div [ngSwitch]="view" class="views">
<div class="view" *ngSwitchCase="'palettes'">
<div class="view"
*ngSwitchCase="'palettes'"
[@slideInLeft]>
<div fxLayout="row wrap" fxLayoutAlign="start start" class="colors" fusePerfectScrollbar>
<div fxLayout="row" fxLayoutWrap
fxLayoutAlign="start start"
class="colors" fusePerfectScrollbar>
<div class="color"
[ngClass]="'mat-'+color.key+'-bg'"
*ngFor="let color of (colors | keys)"
@@ -52,12 +58,18 @@
</div>
</div>
<div class="view" *ngSwitchCase="'hues'" >
<div fxLayout="row wrap" fxLayoutAlign="start start" class="colors" fusePerfectScrollbar>
<div class="color" *ngFor="let hue of hues"
<div class="view"
*ngSwitchCase="'hues'"
[@slideInRight]>
<div fxLayout="row" fxLayoutWrap
fxLayoutAlign="start start"
class="colors" fusePerfectScrollbar>
<div class="color"
*ngFor="let hue of hues"
[fxHide]="selectedPalette === 'white' && hue !== '500'|| selectedPalette === 'black' && hue !== '500'"
[ngClass]="'mat-'+selectedPalette+'-'+hue+'-bg'"
(click)="selectHue(hue)" fxLayout="row" fxLayoutAlign="start end" mat-ink-ripple>
(click)="selectHue(hue)"
fxLayout="row" fxLayoutAlign="start end" mat-ink-ripple>
<span class="label">
{{hue}}
</span>

View File

@@ -1,7 +1,6 @@
import { Component, EventEmitter, Input, OnChanges, Output, ViewEncapsulation } from '@angular/core';
import { fuseAnimations } from '@fuse/animations';
import { MatColors } from '@fuse/mat-colors';
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { MatColors } from '../../matColors';
import { fuseAnimations } from '../../animations';
@Component({
selector : 'fuse-material-color-picker',
@@ -10,81 +9,25 @@ import { MatColors } from '@fuse/mat-colors';
animations : fuseAnimations,
encapsulation: ViewEncapsulation.None
})
export class FuseMaterialColorPickerComponent implements OnChanges
export class FuseMaterialColorPickerComponent implements OnInit, OnChanges
{
colors: any;
hues: string[];
selectedColor: any;
view: string;
hues: string[];
view = 'palettes';
@Input()
selectedPalette: string;
@Input() selectedPalette = '';
@Input() selectedHue = '';
@Input() selectedFg = '';
@Input() value: any;
@Output() onValueChange = new EventEmitter();
@Output() selectedPaletteChange = new EventEmitter();
@Output() selectedHueChange = new EventEmitter();
@Output() selectedClassChange = new EventEmitter();
@Output() selectedBgChange = new EventEmitter();
@Output() selectedFgChange = new EventEmitter();
@Input()
selectedHue: string;
@Input()
selectedFg: string;
@Input()
value: any;
@Output()
onValueChange: EventEmitter<any>;
@Output()
selectedPaletteChange: EventEmitter<any>;
@Output()
selectedHueChange: EventEmitter<any>;
@Output()
selectedClassChange: EventEmitter<any>;
@Output()
selectedBgChange: EventEmitter<any>;
@Output()
selectedFgChange: EventEmitter<any>;
// Private
_selectedClass: string;
_selectedBg: string;
/**
* Constructor
*/
constructor()
{
// Set the defaults
this.colors = MatColors.all;
this.hues = ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900', 'A100', 'A200', 'A400', 'A700'];
this.selectedFg = '';
this.selectedHue = '';
this.selectedPalette = '';
this.view = 'palettes';
this.onValueChange = new EventEmitter();
this.selectedPaletteChange = new EventEmitter();
this.selectedHueChange = new EventEmitter();
this.selectedClassChange = new EventEmitter();
this.selectedBgChange = new EventEmitter();
this.selectedFgChange = new EventEmitter();
// Set the private defaults
this._selectedClass = '';
this._selectedBg = '';
}
// -----------------------------------------------------------------------------------------------------
// @ Accessors
// -----------------------------------------------------------------------------------------------------
/**
* Selected class
*
* @param value
*/
_selectedClass = '';
@Input()
set selectedClass(value)
{
@@ -110,11 +53,7 @@ export class FuseMaterialColorPickerComponent implements OnChanges
return this._selectedClass;
}
/**
* Selected bg
*
* @param value
*/
_selectedBg = '';
@Input()
set selectedBg(value)
{
@@ -146,72 +85,38 @@ export class FuseMaterialColorPickerComponent implements OnChanges
return this._selectedBg;
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On changes
*
* @param changes
*/
ngOnChanges(changes: any): void
constructor()
{
if ( changes.selectedBg && changes.selectedBg.currentValue === '' ||
changes.selectedClass && changes.selectedClass.currentValue === '' ||
changes.selectedPalette && changes.selectedPalette.currentValue === '' )
{
this.removeColor();
return;
}
if ( changes.selectedPalette || changes.selectedHue || changes.selectedClass || changes.selectedBg )
{
this.updateSelectedColor();
}
this.colors = MatColors.all;
this.hues = ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900', 'A100', 'A200', 'A400', 'A700'];
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
ngOnInit()
{
/**
* Select palette
*
* @param palette
*/
selectPalette(palette): void
}
selectPalette(palette)
{
this.selectedPalette = palette;
this.updateSelectedColor();
this.view = 'hues';
}
/**
* Select hue
*
* @param hue
*/
selectHue(hue): void
selectHue(hue)
{
this.selectedHue = hue;
this.updateSelectedColor();
}
/**
* Remove color
*/
removeColor(): void
removeColor()
{
this.selectedPalette = '';
this.selectedHue = '';
this.updateSelectedColor();
this.view = 'palettes';
}
/**
* Update selected color
*/
updateSelectedColor(): void
updateSelectedColor()
{
setTimeout(() => {
@@ -251,18 +156,12 @@ export class FuseMaterialColorPickerComponent implements OnChanges
});
}
/**
* Go back to palette selection
*/
backToPaletteSelection(): void
backToPaletteSelection()
{
this.view = 'palettes';
}
/**
* On menu open
*/
onMenuOpen(): void
onMenuOpen()
{
if ( this.selectedPalette === '' )
{
@@ -273,4 +172,19 @@ export class FuseMaterialColorPickerComponent implements OnChanges
this.view = 'hues';
}
}
ngOnChanges(changes: any)
{
if ( changes.selectedBg && changes.selectedBg.currentValue === '' ||
changes.selectedClass && changes.selectedClass.currentValue === '' ||
changes.selectedPalette && changes.selectedPalette.currentValue === '' )
{
this.removeColor();
return;
}
if ( changes.selectedPalette || changes.selectedHue || changes.selectedClass || changes.selectedBg )
{
this.updateSelectedColor();
}
}
}

Some files were not shown because too many files have changed in this diff Show More