mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-12-22 15:07:05 +00:00
Compare commits
23 Commits
v6.3.1
...
v1.1.1-ske
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d81e37a0f | ||
|
|
83f0ed5ec1 | ||
|
|
e486413872 | ||
|
|
576e167ef1 | ||
|
|
cf9e9fc209 | ||
|
|
ff0f2933d9 | ||
|
|
62467c8ddf | ||
|
|
024ab15b25 | ||
|
|
915ad52863 | ||
|
|
97bfaa9979 | ||
|
|
6ae3e154c3 | ||
|
|
49b6ff7292 | ||
|
|
903688ab43 | ||
|
|
19f822cbab | ||
|
|
1d21a14d0e | ||
|
|
4bf2ba73ad | ||
|
|
6a3972fff8 | ||
|
|
dca16238eb | ||
|
|
2b91119d00 | ||
|
|
ff4899e8d2 | ||
|
|
e818c53f1d | ||
|
|
ca96fffadf | ||
|
|
d7003711ee |
58
.angular-cli.json
Normal file
58
.angular-cli.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"$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"
|
||||
},
|
||||
{
|
||||
"project": "src/tsconfig.spec.json"
|
||||
},
|
||||
{
|
||||
"project": "e2e/tsconfig.e2e.json"
|
||||
}
|
||||
],
|
||||
"test": {
|
||||
"karma": {
|
||||
"config": "./karma.conf.js"
|
||||
}
|
||||
},
|
||||
"defaults": {
|
||||
"styleExt": "scss",
|
||||
"component": {}
|
||||
}
|
||||
}
|
||||
@@ -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
5
.gitignore
vendored
@@ -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
|
||||
|
||||
20
README.md
20
README.md
@@ -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 4+ 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`.
|
||||
|
||||
151
angular.json
151
angular.json
@@ -1,151 +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": [],
|
||||
"showCircularDependencies": false
|
||||
},
|
||||
"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"
|
||||
}
|
||||
14
e2e/app.e2e-spec.ts
Normal file
14
e2e/app.e2e-spec.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Fuse2Page } from './app.po';
|
||||
|
||||
describe('fuse2 App', () => {
|
||||
let page: Fuse2Page;
|
||||
|
||||
beforeEach(() => {
|
||||
page = new Fuse2Page();
|
||||
});
|
||||
|
||||
it('should display welcome message', () => {
|
||||
page.navigateTo();
|
||||
expect(page.getParagraphText()).toEqual('Welcome to app!!');
|
||||
});
|
||||
});
|
||||
11
e2e/app.po.ts
Normal file
11
e2e/app.po.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { browser, by, element } from 'protractor';
|
||||
|
||||
export class Fuse2Page {
|
||||
navigateTo() {
|
||||
return browser.get('/');
|
||||
}
|
||||
|
||||
getParagraphText() {
|
||||
return element(by.css('app-root h1')).getText();
|
||||
}
|
||||
}
|
||||
@@ -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}}));
|
||||
}
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
import { Fuse2Page } from './app.po';
|
||||
|
||||
describe('Fuse2 App', () => {
|
||||
let page: Fuse2Page;
|
||||
|
||||
beforeEach(() => {
|
||||
page = new Fuse2Page();
|
||||
});
|
||||
|
||||
it('should display welcome message', () => {
|
||||
page.navigateTo();
|
||||
expect(page.getParagraphText()).toEqual('Welcome to Fuse2!');
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import { browser, by, element } from 'protractor';
|
||||
|
||||
export class Fuse2Page {
|
||||
navigateTo(): any {
|
||||
return browser.get('/');
|
||||
}
|
||||
|
||||
getParagraphText(): any {
|
||||
return element(by.css('app-root h1')).getText();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/app",
|
||||
"outDir": "../out-tsc/e2e",
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"jasminewd2",
|
||||
"node"
|
||||
]
|
||||
}
|
||||
|
||||
33
karma.conf.js
Normal file
33
karma.conf.js
Normal file
@@ -0,0 +1,33 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/0.13/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
|
||||
});
|
||||
};
|
||||
11556
package-lock.json
generated
11556
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
128
package.json
128
package.json
@@ -1,89 +1,75 @@
|
||||
{
|
||||
"name": "fuse",
|
||||
"version": "6.3.0",
|
||||
"license": "https://themeforest.net/licenses/terms/regular",
|
||||
"name": "fuse2",
|
||||
"version": "1.1.1",
|
||||
"license": "",
|
||||
"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",
|
||||
"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",
|
||||
"start": "ng serve",
|
||||
"start-hmr": "ng serve --hmr -e=hmr -sm=false",
|
||||
"start-hmr-sourcemaps": "ng serve --hmr -e=hmr",
|
||||
"build": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build",
|
||||
"build-prod": "node --max_old_space_size=4096 ./node_modules/@angular/cli/bin/ng build --prod",
|
||||
"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.1.6",
|
||||
"@angular/cdk": "6.4.6",
|
||||
"@angular/common": "6.1.6",
|
||||
"@angular/compiler": "6.1.6",
|
||||
"@angular/core": "6.1.6",
|
||||
"@angular/flex-layout": "6.0.0-beta.16",
|
||||
"@angular/forms": "6.1.6",
|
||||
"@angular/http": "6.1.6",
|
||||
"@angular/material": "6.4.6",
|
||||
"@angular/material-moment-adapter": "6.4.6",
|
||||
"@angular/platform-browser": "6.1.6",
|
||||
"@angular/platform-browser-dynamic": "6.1.6",
|
||||
"@angular/router": "6.1.6",
|
||||
"@ngrx/effects": "6.1.0",
|
||||
"@ngrx/router-store": "6.1.0",
|
||||
"@ngrx/store": "6.1.0",
|
||||
"@ngrx/store-devtools": "6.1.0",
|
||||
"@ngx-translate/core": "10.0.2",
|
||||
"@swimlane/dragula": "3.7.3",
|
||||
"@swimlane/ngx-charts": "9.0.0",
|
||||
"@swimlane/ngx-datatable": "13.1.0",
|
||||
"@swimlane/ngx-dnd": "5.0.6",
|
||||
"@types/prismjs": "1.9.0",
|
||||
"angular-calendar": "0.25.2",
|
||||
"angular-in-memory-web-api": "0.6.1",
|
||||
"chart.js": "2.7.2",
|
||||
"@angular/animations": "4.4.3",
|
||||
"@angular/cdk": "2.0.0-beta.11",
|
||||
"@angular/common": "4.4.3",
|
||||
"@angular/compiler": "4.4.3",
|
||||
"@angular/core": "4.4.3",
|
||||
"@angular/flex-layout": "2.0.0-beta.9",
|
||||
"@angular/forms": "4.4.3",
|
||||
"@angular/http": "4.4.3",
|
||||
"@angular/material": "2.0.0-beta.11",
|
||||
"@angular/platform-browser": "4.4.3",
|
||||
"@angular/platform-browser-dynamic": "4.4.3",
|
||||
"@angular/router": "4.4.3",
|
||||
"@swimlane/ngx-charts": "6.0.2",
|
||||
"@swimlane/ngx-datatable": "9.3.1",
|
||||
"@swimlane/ngx-dnd": "3.0.0",
|
||||
"angular-calendar": "0.19.0",
|
||||
"angular-in-memory-web-api": "0.4.6",
|
||||
"classlist.js": "1.1.20150312",
|
||||
"core-js": "2.5.7",
|
||||
"d3": "5.7.0",
|
||||
"core-js": "2.5.0",
|
||||
"d3": "4.10.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.6.0",
|
||||
"ngx-cookie-service": "1.0.10",
|
||||
"perfect-scrollbar": "1.4.0",
|
||||
"prismjs": "1.15.0",
|
||||
"rxjs": "6.2.2",
|
||||
"rxjs-compat": "6.2.2",
|
||||
"highlight.js": "9.12.0",
|
||||
"intl": "1.2.5",
|
||||
"md2": "0.0.28",
|
||||
"moment": "2.18.1",
|
||||
"ngx-color-picker": "4.3.1",
|
||||
"ngx-cookie-service": "1.0.7",
|
||||
"ngx-perfect-scrollbar": "4.6.2",
|
||||
"perfect-scrollbar": "0.8.1",
|
||||
"rxjs": "5.4.3",
|
||||
"web-animations-js": "2.3.1",
|
||||
"zone.js": "0.8.26"
|
||||
"zone.js": "0.8.17"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/cli": "6.1.5",
|
||||
"@angular/compiler-cli": "6.1.6",
|
||||
"@angular/language-service": "6.1.6",
|
||||
"@angular-devkit/build-angular": "0.7.5",
|
||||
"@angular/cli": "1.4.2",
|
||||
"@angular/compiler-cli": "4.4.3",
|
||||
"@angular/language-service": "4.4.3",
|
||||
"@angularclass/hmr": "2.1.3",
|
||||
"@types/jasmine": "2.8.8",
|
||||
"@types/jasminewd2": "2.0.3",
|
||||
"@types/lodash": "4.14.116",
|
||||
"@types/node": "8.9.5",
|
||||
"codelyzer": "4.2.1",
|
||||
"jasmine-core": "2.99.1",
|
||||
"jasmine-spec-reporter": "4.2.1",
|
||||
"@ngtools/webpack": "1.7.1",
|
||||
"@types/jasmine": "2.6.0",
|
||||
"@types/jasminewd2": "2.0.2",
|
||||
"@types/node": "6.0.88",
|
||||
"codelyzer": "3.0.1",
|
||||
"jasmine-core": "2.6.2",
|
||||
"jasmine-spec-reporter": "4.1.0",
|
||||
"karma": "1.7.1",
|
||||
"karma-chrome-launcher": "2.2.0",
|
||||
"karma-coverage-istanbul-reporter": "2.0.2",
|
||||
"karma-jasmine": "1.1.2",
|
||||
"karma-chrome-launcher": "2.1.1",
|
||||
"karma-cli": "1.0.1",
|
||||
"karma-coverage-istanbul-reporter": "1.2.1",
|
||||
"karma-jasmine": "1.1.0",
|
||||
"karma-jasmine-html-reporter": "0.2.2",
|
||||
"protractor": "5.4.0",
|
||||
"ts-node": "5.0.1",
|
||||
"tslint": "5.9.1",
|
||||
"typescript": "2.7.2",
|
||||
"webpack-bundle-analyzer": "2.13.1"
|
||||
"node-sass": "4.5.3",
|
||||
"protractor": "5.1.2",
|
||||
"ts-node": "3.0.4",
|
||||
"tslint": "5.3.2",
|
||||
"typescript": "2.3.3"
|
||||
}
|
||||
}
|
||||
|
||||
28
protractor.conf.js
Normal file
28
protractor.conf.js
Normal 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 } }));
|
||||
}
|
||||
};
|
||||
@@ -1,6 +0,0 @@
|
||||
<h1 matDialogTitle>Confirm</h1>
|
||||
<div mat-dialog-content>{{confirmMessage}}</div>
|
||||
<div mat-dialog-actions class="pt-24">
|
||||
<button mat-raised-button class="mat-accent mr-16" (click)="dialogRef.close(true)">Confirm</button>
|
||||
<button mat-button (click)="dialogRef.close(false)">Cancel</button>
|
||||
</div>
|
||||
@@ -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>
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
import { Component, Input, OnDestroy, OnInit, ViewEncapsulation } 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'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
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 in seconds
|
||||
let diff = eventDate.diff(currDate, 'seconds');
|
||||
|
||||
// Calculate the remaining time for the first time so there will be no
|
||||
// delay on the countdown
|
||||
this.countdown = this._secondsToRemaining(diff);
|
||||
|
||||
// Create a subscribable interval
|
||||
const countDown = interval(1000)
|
||||
.pipe(
|
||||
map(value => {
|
||||
return diff = diff - 1;
|
||||
}),
|
||||
map(value => {
|
||||
return this._secondsToRemaining(value);
|
||||
})
|
||||
);
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Private methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Converts given seconds to a remaining time
|
||||
*
|
||||
* @param seconds
|
||||
* @private
|
||||
*/
|
||||
private _secondsToRemaining(seconds): any
|
||||
{
|
||||
const timeLeft = moment.duration(seconds, 'seconds');
|
||||
|
||||
return {
|
||||
days : timeLeft.asDays().toFixed(0),
|
||||
hours : timeLeft.hours(),
|
||||
minutes: timeLeft.minutes(),
|
||||
seconds: timeLeft.seconds()
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
@mixin fuse-countdown-theme($theme) {
|
||||
|
||||
$foreground: map-get($theme, foreground);
|
||||
|
||||
fuse-countdown {
|
||||
|
||||
.fuse-countdown {
|
||||
|
||||
.time {
|
||||
|
||||
.title {
|
||||
color: map-get($foreground, secondary-text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
<!-- DEMO CONTENT -->
|
||||
<div class="demo-content line-height-1.75">
|
||||
|
||||
<h1 class="m-0">Early Sunrise in Winter</h1>
|
||||
<h4 class="mt-0 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 class="my-24">
|
||||
<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
|
||||
<b>adipiscing elit</b>. 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. 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>
|
||||
|
||||
<img class="mt-24 w-100-p" src="assets/images/etc/early-sunrise.jpg" style="max-width: 640px">
|
||||
|
||||
<p class="mt-8 mb-24 secondary-text">
|
||||
<em>Nullam tincidunt sed purus eu placerat. Donec id dictum erat. Etiam enim ex, dapibus et tortor id.</em>
|
||||
</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. <a href="#">Donec viverra sed felis at venenatis.</a>
|
||||
Mauris aliquam fringilla nulla, sit amet congue felis dignissim at.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Orci varius</li>
|
||||
<li>Magnis dis</li>
|
||||
<li>Conubia nostra</li>
|
||||
<li>Semper urna</li>
|
||||
<li>Donec viverra</li>
|
||||
</ul>
|
||||
|
||||
<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 -->
|
||||
@@ -1,100 +0,0 @@
|
||||
<div class="demo-sidebar">
|
||||
<mat-list>
|
||||
<h3 matSubheader>Sidebar Demo</h3>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 1</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 2</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 3</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 4</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 5</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 6</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 7</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 8</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 9</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 10</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 11</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 12</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 13</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 14</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 15</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidebar Item 16</span>
|
||||
</mat-list-item>
|
||||
|
||||
</mat-list>
|
||||
</div>
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
:host {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
background: #263238;
|
||||
cursor: text;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
@@ -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>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
@@ -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';
|
||||
@@ -1,12 +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 './progress-bar/progress-bar.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';
|
||||
@@ -1,65 +0,0 @@
|
||||
<button mat-icon-button
|
||||
class="mat-elevation-z1"
|
||||
[matMenuTriggerFor]="colorMenu"
|
||||
(menuOpened)="onMenuOpen()"
|
||||
[ngClass]="selectedPalette + '-' + selectedHue">
|
||||
<mat-icon>palette</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-menu #colorMenu="matMenu" class="fuse-material-color-picker-menu mat-elevation-z8">
|
||||
|
||||
<header [ngClass]="selectedColor?.class || 'accent'" class="mat-elevation-z4"
|
||||
fxLayout="row" fxLayoutAlign="space-between center">
|
||||
|
||||
<button mat-icon-button
|
||||
class="secondary-text"
|
||||
[style.visibility]="view === 'hues' ? 'visible' : 'hidden'"
|
||||
(click)="goToPalettesView($event)" aria-label="Palette">
|
||||
<mat-icon class="s-20">arrow_back</mat-icon>
|
||||
</button>
|
||||
|
||||
<span *ngIf="selectedColor?.palette">
|
||||
{{selectedColor.palette}} {{selectedColor.hue}}
|
||||
</span>
|
||||
|
||||
<span *ngIf="!selectedColor?.palette">
|
||||
Select a Color
|
||||
</span>
|
||||
|
||||
<button mat-icon-button
|
||||
class="remove-color-button secondary-text"
|
||||
(click)="removeColor($event)"
|
||||
aria-label="Remove color"
|
||||
matTooltip="Remove color">
|
||||
<mat-icon class="s-20">delete</mat-icon>
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<div [ngSwitch]="view" class="views">
|
||||
|
||||
<div class="view" *ngSwitchCase="'palettes'">
|
||||
|
||||
<div fxLayout="row wrap" fxLayoutAlign="start start" class="colors" fusePerfectScrollbar>
|
||||
<div class="color" fxLayout="row" fxLayoutAlign="center center"
|
||||
*ngFor="let color of (colors | keys)"
|
||||
[ngClass]="color.key"
|
||||
[class.selected]="selectedPalette === color.key"
|
||||
(click)="selectPalette($event, color.key)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="view" *ngSwitchCase="'hues'">
|
||||
<div fxLayout="row wrap" fxLayoutAlign="start start" class="colors" fusePerfectScrollbar>
|
||||
<div class="color" fxLayout="row" fxLayoutAlign="center center"
|
||||
*ngFor="let hue of hues"
|
||||
[fxHide]="selectedPalette === 'fuse-white' && hue !== '500' || selectedPalette === 'fuse-black' && hue !== '500'"
|
||||
[ngClass]="selectedPalette + '-' + hue"
|
||||
[class.selected]="selectedHue === hue"
|
||||
(click)="selectHue($event, hue)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</mat-menu>
|
||||
@@ -1,39 +0,0 @@
|
||||
.fuse-material-color-picker-menu {
|
||||
width: 245px;
|
||||
|
||||
.mat-menu-content {
|
||||
padding: 0;
|
||||
|
||||
.views {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 165px;
|
||||
|
||||
.view {
|
||||
overflow: hidden;
|
||||
|
||||
.colors {
|
||||
padding: 1px 0 0 0;
|
||||
margin-left: -1px;
|
||||
|
||||
.color {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin: 0 0 1px 1px;
|
||||
border-radius: 0;
|
||||
cursor: pointer;
|
||||
transition: border-radius .4s cubic-bezier(.25, .8, .25, 1);
|
||||
|
||||
&:hover {
|
||||
border-radius: 20%;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
border-radius: 50% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,261 +0,0 @@
|
||||
import { Component, EventEmitter, forwardRef, Input, Output, ViewEncapsulation } from '@angular/core';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { MatColors } from '@fuse/mat-colors';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
export const FUSE_MATERIAL_COLOR_PICKER_VALUE_ACCESSOR: any = {
|
||||
provide : NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => FuseMaterialColorPickerComponent),
|
||||
multi : true
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-material-color-picker',
|
||||
templateUrl : './material-color-picker.component.html',
|
||||
styleUrls : ['./material-color-picker.component.scss'],
|
||||
animations : fuseAnimations,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
providers : [FUSE_MATERIAL_COLOR_PICKER_VALUE_ACCESSOR]
|
||||
})
|
||||
export class FuseMaterialColorPickerComponent implements ControlValueAccessor
|
||||
{
|
||||
colors: any;
|
||||
hues: string[];
|
||||
view: string;
|
||||
selectedColor: any;
|
||||
selectedPalette: string;
|
||||
selectedHue: string;
|
||||
|
||||
// Color changed
|
||||
@Output()
|
||||
colorChanged: EventEmitter<any>;
|
||||
|
||||
// Private
|
||||
private _color: string;
|
||||
private _modelChange: (value: any) => void;
|
||||
private _modelTouched: (value: any) => void;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
constructor()
|
||||
{
|
||||
// Set the defaults
|
||||
this.colorChanged = new EventEmitter();
|
||||
this.colors = MatColors.all;
|
||||
this.hues = ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900', 'A100', 'A200', 'A400', 'A700'];
|
||||
this.selectedHue = '500';
|
||||
this.view = 'palettes';
|
||||
|
||||
// Set the private defaults
|
||||
this._color = '';
|
||||
this._modelChange = () => {
|
||||
};
|
||||
this._modelTouched = () => {
|
||||
};
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Accessors
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Selected class
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
@Input()
|
||||
set color(value)
|
||||
{
|
||||
if ( !value || value === '' || this._color === value )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Split the color value (red-400, blue-500, fuse-navy-700 etc.)
|
||||
const colorParts = value.split('-');
|
||||
|
||||
// Take the very last part as the selected hue value
|
||||
this.selectedHue = colorParts[colorParts.length - 1];
|
||||
|
||||
// Remove the last part
|
||||
colorParts.pop();
|
||||
|
||||
// Rejoin the remaining parts as the selected palette name
|
||||
this.selectedPalette = colorParts.join('-');
|
||||
|
||||
// Store the color value
|
||||
this._color = value;
|
||||
}
|
||||
|
||||
get color(): string
|
||||
{
|
||||
return this._color;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Control Value Accessor implementation
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Register on change function
|
||||
*
|
||||
* @param fn
|
||||
*/
|
||||
registerOnChange(fn: any): void
|
||||
{
|
||||
this._modelChange = fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register on touched function
|
||||
*
|
||||
* @param fn
|
||||
*/
|
||||
registerOnTouched(fn: any): void
|
||||
{
|
||||
this._modelTouched = fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write value to the view from model
|
||||
*
|
||||
* @param color
|
||||
*/
|
||||
writeValue(color: any): void
|
||||
{
|
||||
// Return if null
|
||||
if ( !color )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the color
|
||||
this.color = color;
|
||||
|
||||
// Update the selected color
|
||||
this.updateSelectedColor();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Select palette
|
||||
*
|
||||
* @param event
|
||||
* @param palette
|
||||
*/
|
||||
selectPalette(event, palette): void
|
||||
{
|
||||
// Stop propagation
|
||||
event.stopPropagation();
|
||||
|
||||
// Go to 'hues' view
|
||||
this.view = 'hues';
|
||||
|
||||
// Update the selected palette
|
||||
this.selectedPalette = palette;
|
||||
|
||||
// Update the selected color
|
||||
this.updateSelectedColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Select hue
|
||||
*
|
||||
* @param event
|
||||
* @param hue
|
||||
*/
|
||||
selectHue(event, hue): void
|
||||
{
|
||||
// Stop propagation
|
||||
event.stopPropagation();
|
||||
|
||||
// Update the selected huse
|
||||
this.selectedHue = hue;
|
||||
|
||||
// Update the selected color
|
||||
this.updateSelectedColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove color
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
removeColor(event): void
|
||||
{
|
||||
// Stop propagation
|
||||
event.stopPropagation();
|
||||
|
||||
// Return to the 'palettes' view
|
||||
this.view = 'palettes';
|
||||
|
||||
// Clear the selected palette and hue
|
||||
this.selectedPalette = '';
|
||||
this.selectedHue = '';
|
||||
|
||||
// Update the selected color
|
||||
this.updateSelectedColor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update selected color
|
||||
*/
|
||||
updateSelectedColor(): void
|
||||
{
|
||||
if ( this.selectedColor && this.selectedColor.palette === this.selectedPalette && this.selectedColor.hue === this.selectedHue )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the selected color object
|
||||
this.selectedColor = {
|
||||
palette: this.selectedPalette,
|
||||
hue : this.selectedHue,
|
||||
class : this.selectedPalette + '-' + this.selectedHue,
|
||||
bg : this.selectedPalette === '' ? '' : MatColors.getColor(this.selectedPalette)[this.selectedHue],
|
||||
fg : this.selectedPalette === '' ? '' : MatColors.getColor(this.selectedPalette).contrast[this.selectedHue]
|
||||
};
|
||||
|
||||
// Emit the color changed event
|
||||
this.colorChanged.emit(this.selectedColor);
|
||||
|
||||
// Mark the model as touched
|
||||
this._modelTouched(this.selectedColor.class);
|
||||
|
||||
// Update the model
|
||||
this._modelChange(this.selectedColor.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Go to palettes view
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
goToPalettesView(event): void
|
||||
{
|
||||
// Stop propagation
|
||||
event.stopPropagation();
|
||||
|
||||
this.view = 'palettes';
|
||||
}
|
||||
|
||||
/**
|
||||
* On menu open
|
||||
*/
|
||||
onMenuOpen(): void
|
||||
{
|
||||
if ( this.selectedPalette === '' )
|
||||
{
|
||||
this.view = 'palettes';
|
||||
}
|
||||
else
|
||||
{
|
||||
this.view = 'hues';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { MatButtonModule, MatIconModule, MatMenuModule, MatTooltipModule } 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,
|
||||
MatTooltipModule,
|
||||
|
||||
FusePipesModule
|
||||
],
|
||||
exports: [
|
||||
FuseMaterialColorPickerComponent
|
||||
],
|
||||
})
|
||||
export class FuseMaterialColorPickerModule
|
||||
{
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
@mixin fuse-material-color-picker-theme($theme) {
|
||||
|
||||
$background: map-get($theme, background);
|
||||
|
||||
.fuse-material-color-picker-menu {
|
||||
|
||||
.mat-menu-content {
|
||||
|
||||
.views {
|
||||
background: #303030;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
<ng-container *ngIf="!item.hidden">
|
||||
|
||||
<!-- normal collapse -->
|
||||
<a class="nav-link" [ngClass]="item.classes" *ngIf="!item.url && !item.function">
|
||||
<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', 'accent']"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
|
||||
[target]="item.openInNewTab ? '_blank' : '_self'">
|
||||
<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'">
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.function -->
|
||||
<span class="nav-link" [ngClass]="item.classes" *ngIf="!item.url && item.function"
|
||||
(click)="item.function()">
|
||||
<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', 'accent']"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}">
|
||||
<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'">
|
||||
<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.primaryBackground}}">
|
||||
|
||||
<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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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', 'accent']"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
|
||||
[target]="item.openInNewTab ? '_blank' : '_self'">
|
||||
<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'">
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.function -->
|
||||
<span class="nav-link" [ngClass]="item.classes" *ngIf="!item.url && item.function"
|
||||
(click)="item.function()">
|
||||
<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', 'accent']"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
|
||||
[target]="item.openInNewTab ? '_blank' : '_self'">
|
||||
<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'">
|
||||
<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>
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
<div class="nav" [ngClass]="{'horizontal':layout === 'horizontal', 'vertical':layout === 'vertical'}">
|
||||
|
||||
<!-- Vertical Navigation Layout -->
|
||||
<ng-container *ngIf="layout === 'vertical'">
|
||||
|
||||
<ng-container *ngFor="let item of navigation">
|
||||
|
||||
<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>
|
||||
|
||||
</ng-container>
|
||||
<!-- / Vertical Navigation Layout -->
|
||||
|
||||
<!-- Horizontal Navigation Layout -->
|
||||
<ng-container *ngIf="layout === 'horizontal'">
|
||||
|
||||
<ng-container *ngFor="let item of navigation">
|
||||
|
||||
<fuse-nav-horizontal-collapsable *ngIf="item.type=='group'" [item]="item"></fuse-nav-horizontal-collapsable>
|
||||
<fuse-nav-horizontal-collapsable *ngIf="item.type=='collapsable'"
|
||||
[item]="item"></fuse-nav-horizontal-collapsable>
|
||||
<fuse-nav-horizontal-item *ngIf="item.type=='item'" [item]="item"></fuse-nav-horizontal-item>
|
||||
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
<!-- / Horizontal Navigation Layout -->
|
||||
|
||||
</div>
|
||||
@@ -1,12 +0,0 @@
|
||||
@import 'src/@fuse/scss/fuse';
|
||||
|
||||
fuse-navigation {
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
|
||||
> .nav {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
<ng-container *ngIf="!item.hidden">
|
||||
|
||||
<!-- normal collapsable -->
|
||||
<a class="nav-link" [ngClass]="item.classes" *ngIf="!item.url && !item.function"
|
||||
(click)="toggleOpen($event)">
|
||||
<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', 'accent']"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
|
||||
[target]="item.openInNewTab ? '_blank' : '_self'">
|
||||
<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'">
|
||||
<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()">
|
||||
<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', 'accent']"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}">
|
||||
<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'">
|
||||
<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>
|
||||
@@ -1,237 +0,0 @@
|
||||
import { Component, HostBinding, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { Subject } from 'rxjs';
|
||||
import { filter, takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FuseNavigationItem } from '@fuse/types';
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-nav-vertical-collapsable',
|
||||
templateUrl: './collapsable.component.html',
|
||||
styleUrls : ['./collapsable.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class FuseNavVerticalCollapsableComponent implements OnInit, OnDestroy
|
||||
{
|
||||
@Input()
|
||||
item: FuseNavigationItem;
|
||||
|
||||
@HostBinding('class')
|
||||
classes = 'nav-collapsable nav-item';
|
||||
|
||||
@HostBinding('class.open')
|
||||
public isOpen = false;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FuseNavigationService} _fuseNavigationService
|
||||
* @param {Router} _router
|
||||
*/
|
||||
constructor(
|
||||
private _fuseNavigationService: FuseNavigationService,
|
||||
private _router: Router
|
||||
)
|
||||
{
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Listen for router events
|
||||
this._router.events
|
||||
.pipe(
|
||||
filter(event => event instanceof NavigationEnd),
|
||||
takeUntil(this._unsubscribeAll)
|
||||
)
|
||||
.subscribe((event: NavigationEnd) => {
|
||||
|
||||
// Check if the url can be found in
|
||||
// one of the children of this item
|
||||
if ( this.isUrlInChildren(this.item, event.urlAfterRedirects) )
|
||||
{
|
||||
this.expand();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.collapse();
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for collapsing of any navigation item
|
||||
this._fuseNavigationService.onItemCollapsed
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe(
|
||||
(clickedItem) => {
|
||||
if ( clickedItem && clickedItem.children )
|
||||
{
|
||||
// Check if the clicked item is one
|
||||
// of the children of this item
|
||||
if ( this.isChildrenOf(this.item, clickedItem) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the url can be found in
|
||||
// one of the children of this item
|
||||
if ( this.isUrlInChildren(this.item, this._router.url) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If the clicked item is not this item, collapse...
|
||||
if ( this.item !== clickedItem )
|
||||
{
|
||||
this.collapse();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Check if the url can be found in
|
||||
// one of the children of this item
|
||||
if ( this.isUrlInChildren(this.item, this._router.url) )
|
||||
{
|
||||
this.expand();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.collapse();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle collapse
|
||||
*
|
||||
* @param ev
|
||||
*/
|
||||
toggleOpen(ev): void
|
||||
{
|
||||
ev.preventDefault();
|
||||
|
||||
this.isOpen = !this.isOpen;
|
||||
|
||||
// Navigation collapse toggled...
|
||||
this._fuseNavigationService.onItemCollapsed.next(this.item);
|
||||
this._fuseNavigationService.onItemCollapseToggled.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand the collapsable navigation
|
||||
*/
|
||||
expand(): void
|
||||
{
|
||||
if ( this.isOpen )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.isOpen = true;
|
||||
this._fuseNavigationService.onItemCollapseToggled.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Collapse the collapsable navigation
|
||||
*/
|
||||
collapse(): void
|
||||
{
|
||||
if ( !this.isOpen )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.isOpen = false;
|
||||
this._fuseNavigationService.onItemCollapseToggled.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given parent has the
|
||||
* given item in one of its children
|
||||
*
|
||||
* @param parent
|
||||
* @param item
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isChildrenOf(parent, item): boolean
|
||||
{
|
||||
if ( !parent.children )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( parent.children.indexOf(item) !== -1 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for ( const children of parent.children )
|
||||
{
|
||||
if ( children.children )
|
||||
{
|
||||
return this.isChildrenOf(children, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given url can be found
|
||||
* in one of the given parent's children
|
||||
*
|
||||
* @param parent
|
||||
* @param url
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isUrlInChildren(parent, url): boolean
|
||||
{
|
||||
if ( !parent.children )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for ( let i = 0; i < parent.children.length; i++ )
|
||||
{
|
||||
if ( parent.children[i].children )
|
||||
{
|
||||
if ( this.isUrlInChildren(parent.children[i], url) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( parent.children[i].url === url || url.includes(parent.children[i].url) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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', 'accent']"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
|
||||
[target]="item.openInNewTab ? '_blank' : '_self'">
|
||||
<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'">
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.function -->
|
||||
<span class="nav-link" [ngClass]="item.classes" *ngIf="!item.url && item.function"
|
||||
(click)="item.function()">
|
||||
<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', 'accent']"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}"
|
||||
[target]="item.openInNewTab ? '_blank' : '_self'">
|
||||
<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'">
|
||||
<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>
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<ng-container *ngIf="visible">
|
||||
|
||||
<mat-progress-bar color="accent" [bufferValue]="bufferValue" [mode]="mode" [value]="value"></mat-progress-bar>
|
||||
|
||||
</ng-container>
|
||||
@@ -1,17 +0,0 @@
|
||||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
fuse-progress-bar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
z-index: 99998;
|
||||
|
||||
mat-progress-bar {
|
||||
|
||||
.mat-progress-bar-buffer {
|
||||
background-color: #C5C6CB !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { FuseProgressBarService } from '@fuse/components/progress-bar/progress-bar.service';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-progress-bar',
|
||||
templateUrl : './progress-bar.component.html',
|
||||
styleUrls : ['./progress-bar.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class FuseProgressBarComponent implements OnInit, OnDestroy
|
||||
{
|
||||
bufferValue: number;
|
||||
mode: 'determinate' | 'indeterminate' | 'buffer' | 'query';
|
||||
value: number;
|
||||
visible: boolean;
|
||||
|
||||
// Private
|
||||
private _unsubscribeAll: Subject<any>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FuseProgressBarService} _fuseProgressBarService
|
||||
*/
|
||||
constructor(
|
||||
private _fuseProgressBarService: FuseProgressBarService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
|
||||
// Set the private defaults
|
||||
this._unsubscribeAll = new Subject();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Lifecycle hooks
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Subscribe to the progress bar service properties
|
||||
|
||||
// Buffer value
|
||||
this._fuseProgressBarService.bufferValue
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((bufferValue) => {
|
||||
this.bufferValue = bufferValue;
|
||||
});
|
||||
|
||||
// Mode
|
||||
this._fuseProgressBarService.mode
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((mode) => {
|
||||
this.mode = mode;
|
||||
});
|
||||
|
||||
// Value
|
||||
this._fuseProgressBarService.value
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((value) => {
|
||||
this.value = value;
|
||||
});
|
||||
|
||||
// Visible
|
||||
this._fuseProgressBarService.visible
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((visible) => {
|
||||
this.visible = visible;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* On destroy
|
||||
*/
|
||||
ngOnDestroy(): void
|
||||
{
|
||||
// Unsubscribe from all subscriptions
|
||||
this._unsubscribeAll.next();
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { MatButtonModule, MatIconModule, MatProgressBarModule } from '@angular/material';
|
||||
|
||||
import { FuseProgressBarComponent } from './progress-bar.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
FuseProgressBarComponent
|
||||
],
|
||||
imports : [
|
||||
CommonModule,
|
||||
RouterModule,
|
||||
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatProgressBarModule
|
||||
],
|
||||
exports : [
|
||||
FuseProgressBarComponent
|
||||
]
|
||||
})
|
||||
export class FuseProgressBarModule
|
||||
{
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { filter } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class FuseProgressBarService
|
||||
{
|
||||
// Private
|
||||
private _bufferValue: BehaviorSubject<number>;
|
||||
private _mode: BehaviorSubject<string>;
|
||||
private _value: BehaviorSubject<number>;
|
||||
private _visible: BehaviorSubject<boolean>;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {Router} _router
|
||||
*/
|
||||
constructor(
|
||||
private _router: Router
|
||||
)
|
||||
{
|
||||
// Initialize the service
|
||||
this._init();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Accessors
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Buffer value
|
||||
*/
|
||||
get bufferValue(): Observable<any>
|
||||
{
|
||||
return this._bufferValue.asObservable();
|
||||
}
|
||||
|
||||
setBufferValue(value: number): void
|
||||
{
|
||||
this._bufferValue.next(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mode
|
||||
*/
|
||||
get mode(): Observable<any>
|
||||
{
|
||||
return this._mode.asObservable();
|
||||
}
|
||||
|
||||
setMode(value: 'determinate' | 'indeterminate' | 'buffer' | 'query'): void
|
||||
{
|
||||
this._mode.next(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Value
|
||||
*/
|
||||
get value(): Observable<any>
|
||||
{
|
||||
return this._value.asObservable();
|
||||
}
|
||||
|
||||
setValue(value: number): void
|
||||
{
|
||||
this._value.next(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visible
|
||||
*/
|
||||
get visible(): Observable<any>
|
||||
{
|
||||
return this._visible.asObservable();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Private methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _init(): void
|
||||
{
|
||||
// Initialize the behavior subjects
|
||||
this._bufferValue = new BehaviorSubject(0);
|
||||
this._mode = new BehaviorSubject('indeterminate');
|
||||
this._value = new BehaviorSubject(0);
|
||||
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.show();
|
||||
});
|
||||
|
||||
this._router.events
|
||||
.pipe(filter((event) => event instanceof NavigationEnd || event instanceof NavigationError || event instanceof NavigationCancel))
|
||||
.subscribe(() => {
|
||||
this.hide();
|
||||
});
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Show the progress bar
|
||||
*/
|
||||
show(): void
|
||||
{
|
||||
this._visible.next(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the progress bar
|
||||
*/
|
||||
hide(): void
|
||||
{
|
||||
this._visible.next(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<div class="fuse-search-bar" [ngClass]="{'expanded':!collapsed}">
|
||||
|
||||
<div class="fuse-search-bar-content">
|
||||
|
||||
<label for="fuse-search-bar-input">
|
||||
<button mat-icon-button class="fuse-search-bar-expander" aria-label="Expand Search Bar" (click)="expand()"
|
||||
*ngIf="collapsed">
|
||||
<mat-icon class="s-24 secondary-text">search</mat-icon>
|
||||
</button>
|
||||
</label>
|
||||
|
||||
<input id="fuse-search-bar-input" class="ml-24" type="text" placeholder="Search" (input)="search($event)"
|
||||
fxFlex>
|
||||
|
||||
<button mat-icon-button class="fuse-search-bar-collapser" (click)="collapse()"
|
||||
aria-label="Collapse Search Bar">
|
||||
<mat-icon class="s-24 secondary-text">close</mat-icon>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1,92 +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;
|
||||
font-size: 16px;
|
||||
background-color: transparent;
|
||||
color: currentColor;
|
||||
}
|
||||
}
|
||||
|
||||
&.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
@mixin fuse-search-bar-theme($theme) {
|
||||
|
||||
$background: map-get($theme, background);
|
||||
|
||||
.fuse-search-bar {
|
||||
|
||||
&.expanded {
|
||||
background-color: map-get($background, background);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
<div id="fuse-shortcuts" #shortcuts>
|
||||
|
||||
<div class="shortcuts-mobile-toggle" *ngIf="!mobileShortcutsPanelActive" fxLayout="row" fxLayoutAlign="start center"
|
||||
fxHide fxShow.lt-md>
|
||||
<button mat-icon-button (click)="showMobileShortcutsPanel()">
|
||||
<mat-icon class="amber-600-fg">star</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="shortcuts" fxHide fxShow.gt-sm>
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="space-between center" fxFlex="0 1 auto">
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<div class="w-40 h-40 p-4" fxLayout="row" fxLayoutAlign="center center"
|
||||
*ngFor="let shortcutItem of shortcutItems">
|
||||
|
||||
<a mat-icon-button matTooltip="{{shortcutItem.title}}" [routerLink]="shortcutItem.url">
|
||||
<mat-icon class="secondary-text" *ngIf="shortcutItem.icon">{{shortcutItem.icon}}</mat-icon>
|
||||
<span *ngIf="!shortcutItem.icon" class="h2 secondary-text text-bold">
|
||||
{{shortcutItem.title.substr(0, 1).toUpperCase()}}
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<button mat-icon-button [matMenuTriggerFor]="addMenu" matTooltip="Click to add/remove shortcut"
|
||||
(menuOpened)="onMenuOpen()">
|
||||
<mat-icon class="amber-600-fg">star</mat-icon>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="shortcuts-mobile-close" fxLayout="row" fxLayoutAlign="start center" fxHide fxShow.lt-md>
|
||||
<button mat-icon-button (click)="hideMobileShortcutsPanel()">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<mat-menu #addMenu="matMenu" class="w-240">
|
||||
|
||||
<mat-form-field class="px-16 w-100-p" (click)="$event.stopPropagation()" floatLabel="never">
|
||||
<input #searchInput matInput placeholder="Search for an app or a page" (input)="search($event)">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-nav-list *ngIf="!searching" style="max-height: 312px; overflow: auto" fusePerfectScrollbar>
|
||||
|
||||
<mat-list-item *ngFor="let shortcutItem of shortcutItems"
|
||||
(click)="toggleShortcut($event, shortcutItem)">
|
||||
|
||||
<div class="w-100-p" fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<mat-icon mat-list-icon class="mr-8 secondary-text" *ngIf="shortcutItem.icon">
|
||||
{{shortcutItem.icon}}
|
||||
</mat-icon>
|
||||
|
||||
<span class="h2 w-32 h-32 p-4 mr-8 secondary-text text-bold" fxLayout="row"
|
||||
fxLayoutAlign="center center" *ngIf="!shortcutItem.icon">
|
||||
{{shortcutItem.title.substr(0, 1).toUpperCase()}}
|
||||
</span>
|
||||
|
||||
<p matLine fxFlex>{{shortcutItem.title}}</p>
|
||||
|
||||
<mat-icon class="ml-8 amber-fg">star</mat-icon>
|
||||
|
||||
</div>
|
||||
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item *ngIf="shortcutItems.length === 0">
|
||||
<p>
|
||||
<small>No shortcuts yet!</small>
|
||||
</p>
|
||||
</mat-list-item>
|
||||
|
||||
</mat-nav-list>
|
||||
|
||||
<mat-nav-list *ngIf="searching" style="max-height: 312px; overflow: auto" fusePerfectScrollbar>
|
||||
|
||||
<mat-list-item *ngFor="let navigationItem of filteredNavigationItems"
|
||||
(click)="toggleShortcut($event, navigationItem)">
|
||||
|
||||
<div class="w-100-p" fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<mat-icon mat-list-icon class="mr-8 secondary-text" *ngIf="navigationItem.icon">
|
||||
{{navigationItem.icon}}
|
||||
</mat-icon>
|
||||
|
||||
<span class="h2 w-32 h-32 p-4 mr-8 secondary-text text-bold" fxLayout="row"
|
||||
fxLayoutAlign="center center" *ngIf="!navigationItem.icon">
|
||||
{{navigationItem.title.substr(0, 1).toUpperCase()}}
|
||||
</span>
|
||||
|
||||
<p matLine fxFlex>{{navigationItem.title}}</p>
|
||||
|
||||
<mat-icon class="ml-8 amber-fg" *ngIf="isInShortcuts(navigationItem)">star</mat-icon>
|
||||
|
||||
</div>
|
||||
|
||||
</mat-list-item>
|
||||
|
||||
</mat-nav-list>
|
||||
|
||||
</mat-menu>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
@mixin fuse-shortcuts-theme($theme) {
|
||||
|
||||
$background: map-get($theme, background);
|
||||
|
||||
#fuse-shortcuts {
|
||||
|
||||
&.show-mobile-panel {
|
||||
background-color: map-get($background, background);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
<ng-content></ng-content>
|
||||
@@ -1,65 +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;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
width: 280px;
|
||||
min-width: 280px;
|
||||
max-width: 280px;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.35);
|
||||
|
||||
@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;
|
||||
opacity: 0;
|
||||
}
|
||||
@@ -1,800 +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();
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { FuseSidebarComponent } from './sidebar.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
FuseSidebarComponent
|
||||
],
|
||||
exports : [
|
||||
FuseSidebarComponent
|
||||
]
|
||||
})
|
||||
export class FuseSidebarModule
|
||||
{
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
@mixin fuse-sidebar-theme($theme) {
|
||||
|
||||
$background: map-get($theme, background);
|
||||
|
||||
fuse-sidebar {
|
||||
background: map-get($background, background);
|
||||
}
|
||||
|
||||
.fuse-sidebar-overlay {
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
|
||||
&.fuse-sidebar-overlay-invisible {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,547 +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">
|
||||
|
||||
<!-- COLOR THEME -->
|
||||
<div class="group">
|
||||
|
||||
<h2>Color themes</h2>
|
||||
|
||||
<mat-radio-group fxLayout="column" fxLayoutAlign="start start" formControlName="colorTheme">
|
||||
<mat-radio-button class="mb-12" value="theme-default">Default Light</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="theme-yellow-light">Yellow Light</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="theme-blue-gray-dark">Blue-Gray Dark</mat-radio-button>
|
||||
<mat-radio-button class="mb-12" value="theme-pink-dark">Pink Dark</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 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-16 mb-8">Primary background:</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="primaryBackground"></fuse-material-color-picker>
|
||||
|
||||
<h3 class="mt-16 mb-8">Secondary background:</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="secondaryBackground"></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>
|
||||
|
||||
<mat-checkbox class="mt-24" formControlName="customBackgroundColor">
|
||||
Use custom background color
|
||||
</mat-checkbox>
|
||||
|
||||
<h3 class="mt-24 mb-8">Background color:</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="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>
|
||||
|
||||
<mat-checkbox class="mt-24" formControlName="customBackgroundColor">
|
||||
Use custom background color
|
||||
</mat-checkbox>
|
||||
|
||||
<h3 class="mt-24 mb-8">Color:</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="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-16 mb-8">Primary background:</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="primaryBackground"></fuse-material-color-picker>
|
||||
|
||||
<h3 class="mt-16 mb-8">Secondary background:</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="secondaryBackground"></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>
|
||||
|
||||
<mat-checkbox class="mt-24" formControlName="customBackgroundColor">
|
||||
Use custom background color
|
||||
</mat-checkbox>
|
||||
|
||||
<h3 class="mt-24 mb-8">Background color:</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="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>
|
||||
|
||||
<mat-checkbox class="mt-24" formControlName="customBackgroundColor">
|
||||
Use custom background color
|
||||
</mat-checkbox>
|
||||
|
||||
<h3 class="mt-24 mb-8">Background color:</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="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-16 mb-8">Primary background:</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="primaryBackground"></fuse-material-color-picker>
|
||||
|
||||
<h3 class="mt-16 mb-8">Secondary background:</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="secondaryBackground"></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>
|
||||
|
||||
<mat-checkbox class="mt-24" formControlName="customBackgroundColor">
|
||||
Use custom background color
|
||||
</mat-checkbox>
|
||||
|
||||
<h3 class="mt-24 mb-8">Background color:</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="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>
|
||||
|
||||
<mat-checkbox class="mt-24" formControlName="customBackgroundColor">
|
||||
Use custom background color
|
||||
</mat-checkbox>
|
||||
|
||||
<h3 class="mt-24 mb-8">Background color:</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="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-16 mb-8">Primary background:</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="primaryBackground">
|
||||
</fuse-material-color-picker>
|
||||
|
||||
<h3 class="mt-16 mb-8">Secondary background (Vertical):</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="secondaryBackground">
|
||||
</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>
|
||||
|
||||
<mat-checkbox class="mt-24" formControlName="customBackgroundColor">
|
||||
Use custom background color
|
||||
</mat-checkbox>
|
||||
|
||||
<h3 class="mt-24 mb-8">Background color:</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="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>
|
||||
|
||||
<mat-checkbox class="mt-24" formControlName="customBackgroundColor">
|
||||
Use custom background color
|
||||
</mat-checkbox>
|
||||
|
||||
<h3 class="mt-24 mb-8">Background color:</h3>
|
||||
<fuse-material-color-picker class="mb-16"
|
||||
formControlName="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>
|
||||
@@ -1,75 +0,0 @@
|
||||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
@keyframes rotating {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
fuse-theme-options {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
.theme-options-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 0 auto;
|
||||
padding: 40px 24px 24px 24px;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
.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-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;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
margin: 24px 0 16px 0;
|
||||
padding: 0;
|
||||
|
||||
&:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,342 +0,0 @@
|
||||
import { Component, HostBinding, Inject, OnDestroy, OnInit, Renderer2, ViewEncapsulation } from '@angular/core';
|
||||
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
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'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
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 {DOCUMENT} document
|
||||
* @param {FormBuilder} _formBuilder
|
||||
* @param {FuseConfigService} _fuseConfigService
|
||||
* @param {FuseNavigationService} _fuseNavigationService
|
||||
* @param {FuseSidebarService} _fuseSidebarService
|
||||
* @param {Renderer2} _renderer
|
||||
*/
|
||||
constructor(
|
||||
@Inject(DOCUMENT) private document: any,
|
||||
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({
|
||||
colorTheme : new FormControl(),
|
||||
customScrollbars: new FormControl(),
|
||||
layout : this._formBuilder.group({
|
||||
style : new FormControl(),
|
||||
width : new FormControl(),
|
||||
navbar : this._formBuilder.group({
|
||||
primaryBackground : new FormControl(),
|
||||
secondaryBackground: new FormControl(),
|
||||
folded : new FormControl(),
|
||||
hidden : new FormControl(),
|
||||
position : new FormControl(),
|
||||
variant : new FormControl()
|
||||
}),
|
||||
toolbar : this._formBuilder.group({
|
||||
background : new FormControl(),
|
||||
customBackgroundColor: new FormControl(),
|
||||
hidden : new FormControl(),
|
||||
position : new FormControl()
|
||||
}),
|
||||
footer : this._formBuilder.group({
|
||||
background : new FormControl(),
|
||||
customBackgroundColor: new FormControl(),
|
||||
hidden : new FormControl(),
|
||||
position : new FormControl()
|
||||
}),
|
||||
sidepanel: this._formBuilder.group({
|
||||
hidden : new FormControl(),
|
||||
position: 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 : {
|
||||
primaryBackground : 'fuse-navy-700',
|
||||
secondaryBackground: 'fuse-navy-900',
|
||||
folded : false,
|
||||
hidden : false,
|
||||
position : 'left',
|
||||
variant : 'vertical-style-1'
|
||||
},
|
||||
toolbar : {
|
||||
background : 'fuse-white-500',
|
||||
customBackgroundColor: false,
|
||||
hidden : false,
|
||||
position : 'below-static'
|
||||
},
|
||||
footer : {
|
||||
background : 'fuse-navy-900',
|
||||
customBackgroundColor: true,
|
||||
hidden : false,
|
||||
position : 'below-static'
|
||||
},
|
||||
sidepanel: {
|
||||
hidden : false,
|
||||
position: 'right'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Vertical Layout #2
|
||||
case 'vertical-layout-2':
|
||||
{
|
||||
this.form.patchValue({
|
||||
layout: {
|
||||
width : 'fullwidth',
|
||||
navbar : {
|
||||
primaryBackground : 'fuse-navy-700',
|
||||
secondaryBackground: 'fuse-navy-900',
|
||||
folded : false,
|
||||
hidden : false,
|
||||
position : 'left',
|
||||
variant : 'vertical-style-1'
|
||||
},
|
||||
toolbar : {
|
||||
background : 'fuse-white-500',
|
||||
customBackgroundColor: false,
|
||||
hidden : false,
|
||||
position : 'below'
|
||||
},
|
||||
footer : {
|
||||
background : 'fuse-navy-900',
|
||||
customBackgroundColor: true,
|
||||
hidden : false,
|
||||
position : 'below'
|
||||
},
|
||||
sidepanel: {
|
||||
hidden : false,
|
||||
position: 'right'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Vertical Layout #3
|
||||
case 'vertical-layout-3':
|
||||
{
|
||||
this.form.patchValue({
|
||||
layout: {
|
||||
width : 'fullwidth',
|
||||
navbar : {
|
||||
primaryBackground : 'fuse-navy-700',
|
||||
secondaryBackground: 'fuse-navy-900',
|
||||
folded : false,
|
||||
hidden : false,
|
||||
position : 'left',
|
||||
layout : 'vertical-style-1'
|
||||
},
|
||||
toolbar : {
|
||||
background : 'fuse-white-500',
|
||||
customBackgroundColor: false,
|
||||
hidden : false,
|
||||
position : 'above-static'
|
||||
},
|
||||
footer : {
|
||||
background : 'fuse-navy-900',
|
||||
customBackgroundColor: true,
|
||||
hidden : false,
|
||||
position : 'above-static'
|
||||
},
|
||||
sidepanel: {
|
||||
hidden : false,
|
||||
position: 'right'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Horizontal Layout #1
|
||||
case 'horizontal-layout-1':
|
||||
{
|
||||
this.form.patchValue({
|
||||
layout: {
|
||||
width : 'fullwidth',
|
||||
navbar : {
|
||||
primaryBackground : 'fuse-navy-700',
|
||||
secondaryBackground: 'fuse-navy-900',
|
||||
folded : false,
|
||||
hidden : false,
|
||||
position : 'top',
|
||||
variant : 'vertical-style-1'
|
||||
},
|
||||
toolbar : {
|
||||
background : 'fuse-white-500',
|
||||
customBackgroundColor: false,
|
||||
hidden : false,
|
||||
position : 'above'
|
||||
},
|
||||
footer : {
|
||||
background : 'fuse-navy-900',
|
||||
customBackgroundColor: true,
|
||||
hidden : false,
|
||||
position : 'above-fixed'
|
||||
},
|
||||
sidepanel: {
|
||||
hidden : false,
|
||||
position: 'right'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle sidebar open
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
toggleSidebarOpen(key): void
|
||||
{
|
||||
this._fuseSidebarService.getSidebar(key).toggleOpen();
|
||||
}
|
||||
}
|
||||
@@ -1,46 +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, MatCheckboxModule, MatDividerModule, MatFormFieldModule, MatIconModule, MatOptionModule, MatRadioModule, MatSelectModule, MatSlideToggleModule
|
||||
} from '@angular/material';
|
||||
|
||||
import { FuseDirectivesModule } from '@fuse/directives/directives';
|
||||
import { FuseMaterialColorPickerModule } from '@fuse/components/material-color-picker/material-color-picker.module';
|
||||
import { FuseSidebarModule } from '@fuse/components/sidebar/sidebar.module';
|
||||
|
||||
import { FuseThemeOptionsComponent } from '@fuse/components/theme-options/theme-options.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
FuseThemeOptionsComponent
|
||||
],
|
||||
imports : [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
|
||||
FlexLayoutModule,
|
||||
|
||||
MatButtonModule,
|
||||
MatCheckboxModule,
|
||||
MatDividerModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatOptionModule,
|
||||
MatRadioModule,
|
||||
MatSelectModule,
|
||||
MatSlideToggleModule,
|
||||
|
||||
FuseDirectivesModule,
|
||||
FuseMaterialColorPickerModule,
|
||||
FuseSidebarModule
|
||||
],
|
||||
exports : [
|
||||
FuseThemeOptionsComponent
|
||||
]
|
||||
})
|
||||
export class FuseThemeOptionsModule
|
||||
{
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
@mixin fuse-theme-options-theme($theme) {
|
||||
|
||||
$background: map-get($theme, background);
|
||||
$foreground: map-get($theme, foreground);
|
||||
|
||||
fuse-theme-options {
|
||||
|
||||
.theme-options-panel {
|
||||
|
||||
form {
|
||||
|
||||
.group {
|
||||
border: 1px solid map-get($foreground, divider);
|
||||
|
||||
h2 {
|
||||
background: map-get($background, background);
|
||||
color: map-get($foreground, secondary-text);
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: map-get($foreground, secondary-text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Directive, ElementRef } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[fuseWidgetToggle]'
|
||||
})
|
||||
export class FuseWidgetToggleDirective
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {ElementRef} elementRef
|
||||
*/
|
||||
constructor(
|
||||
public elementRef: ElementRef
|
||||
)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
@mixin fuse-widget-theme($theme) {
|
||||
|
||||
$background: map-get($theme, background);
|
||||
$foreground: map-get($theme, foreground);
|
||||
|
||||
fuse-widget {
|
||||
|
||||
> .fuse-widget-front,
|
||||
> .fuse-widget-back {
|
||||
background: map-get($background, card);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -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: string;
|
||||
|
||||
@Input()
|
||||
matIsLockedOpen: 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.fuseMatSidenavHelper, this._matSidenav);
|
||||
|
||||
if ( this._observableMedia.isActive(this.matIsLockedOpen) )
|
||||
{
|
||||
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.matIsLockedOpen) )
|
||||
{
|
||||
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: string;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {FuseMatSidenavHelperService} _fuseMatSidenavHelperService
|
||||
*/
|
||||
constructor(
|
||||
private _fuseMatSidenavHelperService: FuseMatSidenavHelperService)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Public methods
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* On click
|
||||
*/
|
||||
@HostListener('click')
|
||||
onClick(): void
|
||||
{
|
||||
this._fuseMatSidenavHelperService.getSidenav(this.fuseMatSidenavToggler).toggle();
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
// Material theming tools
|
||||
@import '~@angular/material/theming';
|
||||
|
||||
// Breakpoint mixins
|
||||
@import "mixins/breakpoints";
|
||||
@@ -1,93 +0,0 @@
|
||||
// Fix: "Icon button ripple radius is not correct on Edge & Safari"
|
||||
.mat-icon-button {
|
||||
|
||||
.mat-button-ripple {
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
// Fix: "Smooth scrolling for iOS"
|
||||
.mat-dialog-container {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
// Fix: "Inconsistent font sizes across elements"
|
||||
.mat-checkbox {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.mat-radio-button {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.mat-pseudo-checkbox-checked:after {
|
||||
width: 14px !important;
|
||||
height: 7px !important;
|
||||
}
|
||||
|
||||
// Fix: "Input underlines has wrong color opacity value"
|
||||
.mat-form-field-underline {
|
||||
background-color: rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
// Fix: "Table-cell and inline-table in mat-select"
|
||||
.mat-form-field {
|
||||
|
||||
&.mat-form-field-type-mat-select {
|
||||
|
||||
.mat-form-field-infix {
|
||||
display: inline-flex;
|
||||
width: auto;
|
||||
|
||||
.mat-select-trigger {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
.mat-select-value {
|
||||
display: flex;
|
||||
max-width: none;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.mat-select-arrow-wrapper {
|
||||
display: inline-flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fix: Stepper icons are broken due to Fuse's icon helpers
|
||||
mat-horizontal-stepper,
|
||||
mat-vertical-stepper {
|
||||
|
||||
mat-step-header {
|
||||
|
||||
mat-icon {
|
||||
height: 16px !important;
|
||||
width: 16px !important;
|
||||
min-width: 0 !important;
|
||||
min-height: 0 !important;
|
||||
color: inherit !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mat-vertical-stepper {
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
// Fix: Chip remove icon is broken due to Fuse's icon helpers
|
||||
mat-chip {
|
||||
|
||||
mat-icon {
|
||||
min-width: 0 !important;
|
||||
min-height: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Fix: Mat-card-image requires a bigger width than 100%
|
||||
.mat-card-image {
|
||||
max-width: none !important;
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Theming
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
@mixin cards-theme($theme) {
|
||||
|
||||
$background: map-get($theme, background);
|
||||
$foreground: map-get($theme, foreground);
|
||||
|
||||
.fuse-card {
|
||||
background: map-get($background, card);
|
||||
|
||||
.card-divider {
|
||||
border-top: 1px solid map-get($foreground, divider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Cards
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
.fuse-card {
|
||||
max-width: 320px;
|
||||
min-width: 320px;
|
||||
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 {
|
||||
margin: 16px;
|
||||
|
||||
&.full-width {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Expand Area
|
||||
.card-expand-area {
|
||||
overflow: hidden;
|
||||
|
||||
.card-expanded-content {
|
||||
padding: 8px 16px 16px 16px;
|
||||
line-height: 1.75;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,361 +0,0 @@
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Theming
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
@mixin colors-theme($theme) {
|
||||
|
||||
$is-dark: map-get($theme, is-dark);
|
||||
$background: map-get($theme, background);
|
||||
$foreground: map-get($theme, foreground);
|
||||
|
||||
// Base colors
|
||||
& {
|
||||
color: map-get($foreground, text);
|
||||
|
||||
// If it's a light theme, use a darker background
|
||||
// color other than the default #fafafa
|
||||
@if ($is-dark) {
|
||||
background: map-get($background, background);
|
||||
} @else {
|
||||
background: #F5F5F5;
|
||||
}
|
||||
}
|
||||
|
||||
.secondary-text {
|
||||
color: map-get($foreground, secondary-text);
|
||||
}
|
||||
|
||||
.icon,
|
||||
i {
|
||||
color: map-get($foreground, icon);
|
||||
}
|
||||
|
||||
.hint-text {
|
||||
color: map-get($foreground, hint-text);
|
||||
}
|
||||
|
||||
.disabled-text {
|
||||
color: map-get($foreground, disabled-text);
|
||||
}
|
||||
|
||||
.fade-text,
|
||||
.divider {
|
||||
color: map-get($foreground, divider);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Material colors map
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
$matPalettes: (
|
||||
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
|
||||
);
|
||||
|
||||
// Material color hues list
|
||||
$matHues: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, A100, A200, A400, A700;
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Text color levels generator
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
@mixin generate-text-color-levels($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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Material element colors generator
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
@mixin generate-material-element-colors($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 generate-color-classes($colorName, $color, $contrastColor, $hue) {
|
||||
|
||||
.#{$colorName}#{$hue}-bg {
|
||||
background-color: $color !important;
|
||||
}
|
||||
|
||||
.#{$colorName}#{$hue} {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Fuse color classes
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
@mixin fuse-color-classes($palettes) {
|
||||
|
||||
// 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 generate-color-classes($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('.#{$paletteName}-#{$hue}'), 'comma');
|
||||
}
|
||||
// if the contrast color is light
|
||||
@else {
|
||||
$light-contrasting-classes: append($light-contrasting-classes, unquote('.#{$paletteName}-#{$hue}'), 'comma');
|
||||
}
|
||||
|
||||
// Run the generator one more time for default values (500)
|
||||
// if we are not working with primary, accent or warn palettes
|
||||
@if ($hue == 500 and $paletteName != 'primary' and $paletteName != 'accent' and $paletteName != 'warn') {
|
||||
|
||||
// Generate color classes
|
||||
@include generate-color-classes($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('.#{$paletteName}'), 'comma');
|
||||
}
|
||||
// if the contrast color is light
|
||||
@else {
|
||||
$light-contrasting-classes: append($light-contrasting-classes, unquote('.#{$paletteName}'), 'comma');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run the generator again for the selected default hue values for
|
||||
// primary, accent and warn palettes
|
||||
//
|
||||
// We are doing this because the default hue value can be changed
|
||||
// by the user when the Material theme being generated.
|
||||
@if ($paletteName == 'primary' or $paletteName == 'accent' or $paletteName == 'warn') {
|
||||
|
||||
// Get the color and the contrasting color for the selected
|
||||
// default hue
|
||||
$color: map-get($palette, 'default');
|
||||
$contrast: map-get($palette, 'default-contrast');
|
||||
|
||||
// Generate color classes
|
||||
@include generate-color-classes($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('.#{$paletteName}'), 'comma');
|
||||
}
|
||||
// if the contrast color is light
|
||||
@else {
|
||||
$light-contrasting-classes: append($light-contrasting-classes, unquote('.#{$paletteName}'), 'comma');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate contrasting colors
|
||||
@include generate-text-color-levels($dark-contrasting-classes, 'dark');
|
||||
@include generate-text-color-levels($light-contrasting-classes, 'light');
|
||||
@include generate-material-element-colors($dark-contrasting-classes, 'dark');
|
||||
@include generate-material-element-colors($light-contrasting-classes, 'light');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Generate Fuse color classes for default Material palettes
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
@include fuse-color-classes($matPalettes);
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +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;
|
||||
}
|
||||
|
||||
body {
|
||||
|
||||
// Boxed
|
||||
&.boxed {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
|
||||
@include mat-elevation(8);
|
||||
}
|
||||
}
|
||||
@@ -1,245 +0,0 @@
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Position helpers
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||
|
||||
@include media-breakpoint-up($breakpoint) {
|
||||
|
||||
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
|
||||
|
||||
.position#{$infix}-relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.position#{$infix}-absolute {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.position#{$infix}-static {
|
||||
position: static;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Absolute position alignment helpers
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||
|
||||
@include media-breakpoint-up($breakpoint) {
|
||||
|
||||
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
|
||||
|
||||
.align#{$infix}-top {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.align#{$infix}-right {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.align#{$infix}-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.align#{$infix}-left {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Size helpers
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
@each $prop, $abbrev in (height: h, width: w) {
|
||||
|
||||
@for $index from 0 through 180 {
|
||||
$size: $index * 4;
|
||||
$length: #{$size}px;
|
||||
|
||||
.#{$abbrev}-#{$size} {
|
||||
#{$prop}: $length !important;
|
||||
min-#{$prop}: $length !important;
|
||||
max-#{$prop}: $length !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Percentage
|
||||
@for $i from 0 through 20 {
|
||||
$i-p: 5 * $i;
|
||||
$size-p: 5% * $i;
|
||||
|
||||
.#{$abbrev}-#{$i-p}-p {
|
||||
#{$prop}: $size-p !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Spacing helpers
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||
|
||||
@include media-breakpoint-up($breakpoint) {
|
||||
|
||||
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
|
||||
|
||||
@each $prop, $abbrev in (margin: m, padding: p) {
|
||||
|
||||
@for $index from 0 through 64 {
|
||||
$size: $index * 4;
|
||||
$length: #{$size}px;
|
||||
|
||||
.#{$abbrev}#{$infix}-#{$size} {
|
||||
#{$prop}: $length !important;
|
||||
}
|
||||
}
|
||||
|
||||
@for $index from 0 through 64 {
|
||||
$size: $index * 4;
|
||||
$length: #{$size}px;
|
||||
|
||||
.#{$abbrev}x#{$infix}-#{$size} {
|
||||
#{$prop}-right: $length !important;
|
||||
#{$prop}-left: $length !important;
|
||||
}
|
||||
|
||||
.#{$abbrev}y#{$infix}-#{$size} {
|
||||
#{$prop}-top: $length !important;
|
||||
#{$prop}-bottom: $length !important;
|
||||
}
|
||||
}
|
||||
|
||||
@for $index from 0 through 64 {
|
||||
$size: $index * 4;
|
||||
$length: #{$size}px;
|
||||
|
||||
.#{$abbrev}t#{$infix}-#{$size} {
|
||||
#{$prop}-top: $length !important;
|
||||
}
|
||||
|
||||
.#{$abbrev}r#{$infix}-#{$size} {
|
||||
#{$prop}-right: $length !important;
|
||||
}
|
||||
|
||||
.#{$abbrev}b#{$infix}-#{$size} {
|
||||
#{$prop}-bottom: $length !important;
|
||||
}
|
||||
|
||||
.#{$abbrev}l#{$infix}-#{$size} {
|
||||
#{$prop}-left: $length !important;
|
||||
}
|
||||
}
|
||||
|
||||
@if ($abbrev == m) {
|
||||
|
||||
// Some special margin utils for flex alignments
|
||||
.m#{$infix}-auto {
|
||||
margin: auto !important;
|
||||
}
|
||||
|
||||
.mt#{$infix}-auto {
|
||||
margin-top: auto !important;
|
||||
}
|
||||
|
||||
.mr#{$infix}-auto {
|
||||
margin-right: auto !important;
|
||||
}
|
||||
|
||||
.mb#{$infix}-auto {
|
||||
margin-bottom: auto !important;
|
||||
}
|
||||
|
||||
.ml#{$infix}-auto {
|
||||
margin-left: auto !important;
|
||||
}
|
||||
|
||||
.mx#{$infix}-auto {
|
||||
margin-right: auto !important;
|
||||
margin-left: auto !important;
|
||||
}
|
||||
|
||||
.my#{$infix}-auto {
|
||||
margin-top: auto !important;
|
||||
margin-bottom: auto !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Border helpers
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
$border-style: 1px solid rgba(0, 0, 0, 0.12);
|
||||
|
||||
.border,
|
||||
.b {
|
||||
border: $border-style;
|
||||
}
|
||||
|
||||
.border-top,
|
||||
.bt {
|
||||
border-top: $border-style;
|
||||
}
|
||||
|
||||
.border-right,
|
||||
.br {
|
||||
border-right: $border-style;
|
||||
}
|
||||
|
||||
.border-bottom,
|
||||
.bb {
|
||||
border-bottom: $border-style;
|
||||
}
|
||||
|
||||
.border-left,
|
||||
.bl {
|
||||
border-left: $border-style;
|
||||
}
|
||||
|
||||
.border-horizontal,
|
||||
.bx {
|
||||
border-left: $border-style;
|
||||
border-right: $border-style;
|
||||
}
|
||||
|
||||
.border-vertical,
|
||||
.by {
|
||||
border-top: $border-style;
|
||||
border-bottom: $border-style;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Border radius helpers
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
.border-radius-100 {
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.border-radius-2 {
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.border-radius-4 {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.border-radius-8 {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.border-radius-16 {
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Cursor helpers
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cursor-default {
|
||||
cursor: default;
|
||||
}
|
||||
@@ -1,712 +0,0 @@
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Theming
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
@mixin page-layouts-theme($theme) {
|
||||
|
||||
$background: map-get($theme, background);
|
||||
$foreground: map-get($theme, foreground);
|
||||
|
||||
.page-layout {
|
||||
|
||||
// Carded layout
|
||||
&.carded {
|
||||
|
||||
// Fullwidth
|
||||
&.fullwidth {
|
||||
|
||||
> .center {
|
||||
|
||||
> .content-card {
|
||||
background: map-get($background, card);
|
||||
|
||||
> .toolbar {
|
||||
border-bottom-color: map-get($foreground, divider);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Left / Right sidebar
|
||||
&.left-sidebar,
|
||||
&.right-sidebar {
|
||||
|
||||
> .center {
|
||||
|
||||
> .content-card {
|
||||
background: map-get($background, card);
|
||||
|
||||
> .toolbar {
|
||||
border-bottom-color: map-get($foreground, divider);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Simple layout
|
||||
&.simple {
|
||||
|
||||
// Left / Right sidebar
|
||||
&.left-sidebar,
|
||||
&.right-sidebar {
|
||||
|
||||
> .center {
|
||||
|
||||
> .content {
|
||||
background: map-get($background, card);
|
||||
}
|
||||
}
|
||||
|
||||
// Inner sidebar
|
||||
&.inner-sidebar {
|
||||
|
||||
> .content {
|
||||
|
||||
> .center {
|
||||
|
||||
> .content {
|
||||
background: map-get($background, card);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ 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%;
|
||||
height: 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;
|
||||
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 {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tabbed
|
||||
&.tabbed {
|
||||
|
||||
> .center {
|
||||
|
||||
> .content-card {
|
||||
|
||||
> .content {
|
||||
|
||||
> .mat-tab-group {
|
||||
|
||||
.mat-tab-body {
|
||||
|
||||
.mat-tab-body-content {
|
||||
|
||||
.tab-content {
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
width: 100%;
|
||||
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;
|
||||
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;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
}
|
||||
|
||||
> .center {
|
||||
flex: 1 1 auto;
|
||||
|
||||
> .content-card {
|
||||
flex: 1 1 auto;
|
||||
|
||||
> .content {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tabbed
|
||||
&.tabbed {
|
||||
|
||||
> .center {
|
||||
|
||||
> .content-card {
|
||||
|
||||
> .content {
|
||||
|
||||
> .mat-tab-group {
|
||||
|
||||
.mat-tab-body {
|
||||
|
||||
.mat-tab-body-content {
|
||||
|
||||
.tab-content {
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
width: 100%;
|
||||
@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;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
}
|
||||
|
||||
> .center {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
}
|
||||
|
||||
> .center {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/*----------------------------------------------------------------*/
|
||||
/* Print
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
@media all {
|
||||
|
||||
/* Never show page breaks in normal view */
|
||||
.page-break-after,
|
||||
.page-break-before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media print {
|
||||
|
||||
/* html and body tweaks */
|
||||
html, body {
|
||||
height: auto !important;
|
||||
overflow: initial !important;
|
||||
}
|
||||
|
||||
/* Page breaks */
|
||||
.page-break-after {
|
||||
display: block;
|
||||
page-break-after: always;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.page-break-before {
|
||||
display: block;
|
||||
page-break-before: always;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* General styles */
|
||||
app {
|
||||
|
||||
fuse-sidebar,
|
||||
navbar,
|
||||
toolbar,
|
||||
footer,
|
||||
.theme-options-button,
|
||||
fuse-theme-options,
|
||||
.ps > .ps__rail-x,
|
||||
.ps > .ps__rail-y {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.ps {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.mat-drawer-container,
|
||||
.mat-sidenav-container {
|
||||
background-color: white !important;
|
||||
|
||||
.mat-drawer-content,
|
||||
.mat-sidenav-content {
|
||||
overflow: initial !important;
|
||||
height: auto !important
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,436 +0,0 @@
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Theming
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
@mixin typography-theme($theme) {
|
||||
|
||||
$background: map-get($theme, background);
|
||||
$accent: map-get($theme, accent);
|
||||
$is-dark: map-get($theme, is-dark);
|
||||
|
||||
a {
|
||||
color: map-get($accent, default);
|
||||
}
|
||||
|
||||
code {
|
||||
|
||||
&:not(.highlight) {
|
||||
background-color: map-get($background, app-bar);
|
||||
}
|
||||
}
|
||||
|
||||
.changelog {
|
||||
|
||||
.entry {
|
||||
background-color: map-get($background, card);
|
||||
}
|
||||
}
|
||||
|
||||
.text-boxed {
|
||||
@if ($is-dark) {
|
||||
background-color: rgba(255, 255, 255, 0.12);
|
||||
color: rgba(255, 255, 255, 0.54);
|
||||
} @else {
|
||||
background-color: rgba(0, 0, 0, 0.12);
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Typography
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
html {
|
||||
font-size: 62.5%;
|
||||
font-family: 'Roboto', 'Helvetica Neue', 'Arial', sans-serif;
|
||||
line-height: 1.4 !important;
|
||||
letter-spacing: -0.1px !important;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
html, body {
|
||||
-webkit-font-smoothing: auto;
|
||||
-moz-osx-font-smoothing: auto;
|
||||
}
|
||||
|
||||
// Headings
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
.h1, .h2, .h3, .h4, .h5, .h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h1, .h1 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
h2, .h2 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
h3, .h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
h4, .h4 {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
h5, .h5 {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
h6, .h6 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
// Links
|
||||
a {
|
||||
text-decoration: none;
|
||||
|
||||
&:not(.mat-button):not(.mat-raised-button):not(.mat-icon-button) {
|
||||
|
||||
&:hover, &:active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Abbr
|
||||
abbr {
|
||||
cursor: help;
|
||||
border-bottom: 1px dotted rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
|
||||
// Blockquote
|
||||
blockquote {
|
||||
border-left: 3px solid rgba(0, 0, 0, 0.12);
|
||||
font-style: italic;
|
||||
margin: 1em 0;
|
||||
padding-left: 16px;
|
||||
|
||||
footer {
|
||||
font-style: normal;
|
||||
|
||||
&:before {
|
||||
content: '\2014 \00A0';
|
||||
}
|
||||
}
|
||||
|
||||
&.reverse {
|
||||
border-left: none;
|
||||
border-right: 3px solid rgba(0, 0, 0, 0.12);
|
||||
text-align: right;
|
||||
padding-left: 0;
|
||||
padding-right: 16px;
|
||||
|
||||
footer {
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: '\2014 \00A0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Code
|
||||
code {
|
||||
font-family: 'Monaco', 'Menlo', 'Consolas', 'Ubuntu Mono', monospace;;
|
||||
|
||||
&:not(.highlight) {
|
||||
color: #106CC8;
|
||||
padding: 2px 3px;
|
||||
border-radius: 2px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
}
|
||||
|
||||
// Definition lists
|
||||
dl {
|
||||
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin: 4px 0 16px 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Mark
|
||||
mark {
|
||||
background: #F7F49A;
|
||||
}
|
||||
|
||||
// Pre
|
||||
pre {
|
||||
line-height: 1.6;
|
||||
margin: 8px 16px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
// Small
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
// Table
|
||||
table {
|
||||
|
||||
thead {
|
||||
|
||||
tr {
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Text format helpers
|
||||
.text-italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.text-semibold {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.text-bold,
|
||||
strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.text-strike {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.text-super {
|
||||
vertical-align: super;
|
||||
}
|
||||
|
||||
.text-sub {
|
||||
vertical-align: sub;
|
||||
}
|
||||
|
||||
.text-capitalize {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.text-lowercase {
|
||||
text-transform: lowercase;
|
||||
}
|
||||
|
||||
.text-uppercase {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
// Text align helpers
|
||||
.text-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
// Font weight helpers
|
||||
@for $weight from 1 through 9 {
|
||||
|
||||
.font-weight-#{$weight * 100} {
|
||||
font-weight: #{$weight * 100};
|
||||
}
|
||||
}
|
||||
|
||||
// Font size helpers
|
||||
@for $size from 1 through 60 {
|
||||
|
||||
.font-size-#{$size * 2} {
|
||||
font-size: #{$size * 2}px;
|
||||
}
|
||||
}
|
||||
|
||||
// Line height helpers
|
||||
@for $lineHeight from 1 through 60 {
|
||||
|
||||
.line-height-#{$lineHeight * 2} {
|
||||
line-height: #{$lineHeight * 2}px;
|
||||
}
|
||||
}
|
||||
|
||||
.line-height-1 {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.line-height-1\.25 {
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.line-height-1\.5,
|
||||
.line-height-1\.50 {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.line-height-1\.75 {
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
// Letter spacing helpers
|
||||
.letter-spacing-condensed {
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.letter-spacing-normal {
|
||||
letter-spacing: normal;
|
||||
}
|
||||
|
||||
.letter-spacing-relaxed {
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
// Boxed text
|
||||
.text-boxed {
|
||||
border-radius: 2px;
|
||||
padding: 4px 8px;
|
||||
margin: 0 8px;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// Truncate
|
||||
.text-truncate {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// Nowrap
|
||||
.text-nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// Changelog
|
||||
.changelog {
|
||||
|
||||
.entry {
|
||||
margin-bottom: 24px;
|
||||
padding: 24px 32px;
|
||||
@include mat-elevation(2);
|
||||
|
||||
> .title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.version {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.date {
|
||||
margin-left: 8px;
|
||||
font-size: 17px;
|
||||
opacity: 0.54;
|
||||
}
|
||||
}
|
||||
|
||||
.groups {
|
||||
|
||||
div {
|
||||
margin-bottom: 32px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
display: inline-flex;
|
||||
font-size: 13px;
|
||||
color: white;
|
||||
letter-spacing: 0.015em;
|
||||
line-height: 1;
|
||||
padding: 5px 8px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.breaking-changes {
|
||||
|
||||
.title {
|
||||
background: #F44336;
|
||||
}
|
||||
}
|
||||
|
||||
.new {
|
||||
|
||||
.title {
|
||||
background: #43A047;
|
||||
}
|
||||
}
|
||||
|
||||
.improved {
|
||||
|
||||
.title {
|
||||
background: #673AB7;
|
||||
}
|
||||
}
|
||||
|
||||
.fixed {
|
||||
|
||||
.title {
|
||||
background: #2196F3;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 24px;
|
||||
|
||||
li {
|
||||
margin-bottom: 6px;
|
||||
letter-spacing: 0.015em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Message boxes
|
||||
.message-box {
|
||||
padding: 16px;
|
||||
background: #607D8B;
|
||||
border-left: 6px solid #37474F;
|
||||
color: rgba(255, 255, 255, 1);
|
||||
|
||||
&.error {
|
||||
background: #EF5350;
|
||||
border-left-color: #B71C1C;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
background: #FFECB3;
|
||||
border-left-color: #FFC107;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
|
||||
&.success {
|
||||
background: #4CAF50;
|
||||
border-left-color: #2E7D32;
|
||||
}
|
||||
|
||||
&.info {
|
||||
background: #B3E5FC;
|
||||
border-left-color: #03A9F4;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
}
|
||||
}
|
||||
@@ -1,252 +0,0 @@
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// @ Theming
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
@mixin ngx-datatable-theme($theme) {
|
||||
|
||||
$background: map-get($theme, background);
|
||||
$foreground: map-get($theme, foreground);
|
||||
|
||||
ngx-datatable {
|
||||
|
||||
&.material {
|
||||
background: map-get($background, card);
|
||||
color: map-get($foreground, text);
|
||||
|
||||
.datatable-header {
|
||||
|
||||
.datatable-header-cell {
|
||||
color: map-get($foreground, secondary-text);
|
||||
}
|
||||
}
|
||||
|
||||
.datatable-body {
|
||||
|
||||
.datatable-row-wrapper {
|
||||
border-bottom-color: map-get($foreground, divider);
|
||||
|
||||
&:first-child {
|
||||
border-top-color: map-get($foreground, divider);
|
||||
}
|
||||
|
||||
.datatable-body-row {
|
||||
|
||||
.datatable-body-cell {
|
||||
color: map-get($foreground, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.datatable-footer {
|
||||
color: map-get($foreground, secondary-text);
|
||||
|
||||
.datatable-pager {
|
||||
|
||||
a {
|
||||
color: map-get($foreground, secondary-text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.cell-selection) {
|
||||
|
||||
.datatable-body {
|
||||
|
||||
.datatable-row-wrapper {
|
||||
|
||||
.datatable-body-row {
|
||||
|
||||
&:hover {
|
||||
background-color: map-get($background, hover);
|
||||
|
||||
.datatable-row-group {
|
||||
background-color: map-get($background, hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ngx-datatable {
|
||||
|
||||
&.material {
|
||||
@include mat-elevation(4);
|
||||
|
||||
.empty-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
height: 56px;
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.datatable-header {
|
||||
border: none;
|
||||
min-height: 48px;
|
||||
|
||||
.datatable-header-cell {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
min-height: 48px;
|
||||
font-size: 13px;
|
||||
padding: 0 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.datatable-body {
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
|
||||
.datatable-scroll {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.datatable-row-left,
|
||||
.datatable-row-center,
|
||||
.datatable-row-right {
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
.datatable-row-wrapper {
|
||||
border-bottom: 1px solid;
|
||||
|
||||
&:first-child {
|
||||
border-top: 1px solid;
|
||||
}
|
||||
.datatable-body-cell {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
min-height: 48px;
|
||||
transition: none;
|
||||
padding: 0 24px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.datatable-footer {
|
||||
border: none;
|
||||
min-height: 56px;
|
||||
|
||||
.datatable-footer-inner {
|
||||
padding: 0 24px;
|
||||
|
||||
@include media-breakpoint('sm') {
|
||||
flex-direction: column;
|
||||
padding: 16px 0;
|
||||
height: auto !important;
|
||||
|
||||
.datatable-pager {
|
||||
margin: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.page-count {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.datatable-pager {
|
||||
margin: 0 0 0 24px;
|
||||
|
||||
.pager {
|
||||
|
||||
li {
|
||||
|
||||
a {
|
||||
text-decoration: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[class*="datatable-icon-"] {
|
||||
font-family: 'Material Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-feature-settings: 'liga';
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.datatable-icon-filter:before {
|
||||
content: "filter_list";
|
||||
}
|
||||
|
||||
.datatable-icon-collapse:before {
|
||||
content: "unfold_less";
|
||||
}
|
||||
|
||||
.datatable-icon-expand:before {
|
||||
content: "unfold_more";
|
||||
}
|
||||
|
||||
.datatable-icon-close:before {
|
||||
content: "close";
|
||||
}
|
||||
|
||||
.datatable-icon-up:before {
|
||||
content: "keyboard_arrow_up";
|
||||
}
|
||||
|
||||
.datatable-icon-down:before {
|
||||
content: "keyboard_arrow_down";
|
||||
}
|
||||
|
||||
.datatable-icon-sort:before {
|
||||
content: "sort";
|
||||
}
|
||||
|
||||
.datatable-icon-done:before {
|
||||
content: "done";
|
||||
}
|
||||
|
||||
.datatable-icon-done-all:before {
|
||||
content: "done_all";
|
||||
}
|
||||
|
||||
.datatable-icon-search:before {
|
||||
content: "search";
|
||||
}
|
||||
|
||||
.datatable-icon-pin:before {
|
||||
content: "lock";
|
||||
}
|
||||
|
||||
.datatable-icon-add:before {
|
||||
content: "add";
|
||||
}
|
||||
|
||||
.datatable-icon-left:before {
|
||||
content: "chevron_left";
|
||||
}
|
||||
|
||||
.datatable-icon-right:before {
|
||||
content: "chevron_right";
|
||||
}
|
||||
|
||||
.datatable-icon-skip:before {
|
||||
content: "skip_next";
|
||||
}
|
||||
|
||||
.datatable-icon-prev:before {
|
||||
content: "skip_previous";
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
@import "src/@fuse/components/countdown/countdown.theme";
|
||||
@import "src/@fuse/components/material-color-picker/material-color-picker.theme";
|
||||
@import "src/@fuse/components/search-bar/search-bar.theme";
|
||||
@import "src/@fuse/components/shortcuts/shortcuts.theme";
|
||||
@import "src/@fuse/components/sidebar/sidebar.theme";
|
||||
@import "src/@fuse/components/theme-options/theme-options.theme";
|
||||
@import "src/@fuse/components/widget/widget.theme";
|
||||
|
||||
@mixin fuse-core-theme($theme) {
|
||||
|
||||
// Theming for Fuse core styles
|
||||
@include colors-theme($theme);
|
||||
@include cards-theme($theme);
|
||||
@include material-theme($theme);
|
||||
@include page-layouts-theme($theme);
|
||||
@include typography-theme($theme);
|
||||
|
||||
// Theming for Fuse components
|
||||
@include fuse-countdown-theme($theme);
|
||||
@include fuse-search-bar-theme($theme);
|
||||
@include fuse-shortcuts-theme($theme);
|
||||
@include fuse-sidebar-theme($theme);
|
||||
@include fuse-theme-options-theme($theme);
|
||||
@include fuse-material-color-picker-theme($theme);
|
||||
@include fuse-widget-theme($theme);
|
||||
|
||||
// Theming for 3rd party components
|
||||
@include ngx-datatable-theme($theme);
|
||||
}
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
import { Inject, Injectable, InjectionToken } from '@angular/core';
|
||||
import { Router, RoutesRecognized } 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 layout config on every RoutesRecognized event
|
||||
// if the current layout config is different from the default one
|
||||
this._router.events
|
||||
.pipe(filter(event => event instanceof RoutesRecognized))
|
||||
.subscribe(() => {
|
||||
if ( !_.isEqual(this._configSubject.getValue().layout, this._defaultConfig.layout) )
|
||||
{
|
||||
// Clone the current config
|
||||
const config = _.cloneDeep(this._configSubject.getValue());
|
||||
|
||||
// Reset the layout from the default config
|
||||
config.layout = _.cloneDeep(this._defaultConfig.layout);
|
||||
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/**
|
||||
* This class is based on the code in the following projects:
|
||||
* 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
|
||||
{
|
||||
private textarea: HTMLTextAreaElement;
|
||||
|
||||
/**
|
||||
* Copy the text value to the clipboard
|
||||
*
|
||||
* @param {string} text
|
||||
* @returns {boolean}
|
||||
*/
|
||||
copyText(text: string): boolean
|
||||
{
|
||||
this.createTextareaAndSelect(text);
|
||||
|
||||
const copySuccessful = document.execCommand('copy');
|
||||
this._removeFake();
|
||||
|
||||
return copySuccessful;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
// Create a fake element to hold the contents to copy
|
||||
this.textarea = document.createElement('textarea');
|
||||
|
||||
// Prevent zooming on iOS
|
||||
this.textarea.style.fontSize = '12pt';
|
||||
|
||||
// Hide the element
|
||||
this.textarea.classList.add('cdk-visually-hidden');
|
||||
|
||||
// Move element to the same position vertically
|
||||
const yPosition = window.pageYOffset || document.documentElement.scrollTop;
|
||||
this.textarea.style.top = yPosition + 'px';
|
||||
|
||||
this.textarea.setAttribute('readonly', '');
|
||||
this.textarea.value = text;
|
||||
|
||||
document.body.appendChild(this.textarea);
|
||||
|
||||
this.textarea.select();
|
||||
this.textarea.setSelectionRange(0, this.textarea.value.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the text area from the DOM
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _removeFake(): void
|
||||
{
|
||||
if ( this.textarea )
|
||||
{
|
||||
document.body.removeChild(this.textarea);
|
||||
this.textarea = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
import { MediaChange, ObservableMedia } from '@angular/flex-layout';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
||||
|
||||
@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.asObservable()
|
||||
.pipe(
|
||||
debounceTime(500),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
.subscribe((change: MediaChange) => {
|
||||
if ( this.activeMediaQuery !== change.mqAlias )
|
||||
{
|
||||
this.activeMediaQuery = change.mqAlias;
|
||||
this.onMediaChange.next(change.mqAlias);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user