mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-12-22 16:17:07 +00:00
Compare commits
244 Commits
v1.0.4-ske
...
v6.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2187e0134 | ||
|
|
a1cf7dba91 | ||
|
|
b8039899db | ||
|
|
26e55d7f3d | ||
|
|
1a9229a3ae | ||
|
|
ebf865e2c7 | ||
|
|
5fd146b8da | ||
|
|
3401a67959 | ||
|
|
10dad46d7c | ||
|
|
1c4983c756 | ||
|
|
f4636d9a37 | ||
|
|
02df48ab4e | ||
|
|
831d48f5a3 | ||
|
|
ca42f71b0e | ||
|
|
ed4a3cb8d7 | ||
|
|
5c66d95951 | ||
|
|
44663342f4 | ||
|
|
4e6207fef5 | ||
|
|
bd67b660c8 | ||
|
|
174789930d | ||
|
|
7af9c57977 | ||
|
|
874ef26f0b | ||
|
|
329fbb5a38 | ||
|
|
7db4715eb2 | ||
|
|
e57061b133 | ||
|
|
096e1b47d2 | ||
|
|
9c0f89953c | ||
|
|
20bb52df50 | ||
|
|
ddcd7c6831 | ||
|
|
30825e7927 | ||
|
|
535dbdfe57 | ||
|
|
8c4a714d39 | ||
|
|
c9168717a4 | ||
|
|
2e76bf398f | ||
|
|
2803fd6e90 | ||
|
|
681a75e683 | ||
|
|
ae6bc37664 | ||
|
|
583e74d99f | ||
|
|
82ca0329e9 | ||
|
|
7b474e54f0 | ||
|
|
ab61faaba5 | ||
|
|
863fa5cc46 | ||
|
|
2509ad4e71 | ||
|
|
6108679f46 | ||
|
|
b34f7fca20 | ||
|
|
fa53e773ae | ||
|
|
397c304ab2 | ||
|
|
3dfb79423a | ||
|
|
51bd636ba6 | ||
|
|
e55a385858 | ||
|
|
43b85ca3b6 | ||
|
|
99696cabf7 | ||
|
|
f246fab1f4 | ||
|
|
b0101a1f8c | ||
|
|
8f5e947c28 | ||
|
|
dfd430712d | ||
|
|
8431c19133 | ||
|
|
6ee6934e0d | ||
|
|
3253fbfaf4 | ||
|
|
985a8dd3a9 | ||
|
|
0c99c075f3 | ||
|
|
c79db27092 | ||
|
|
a92cb8b7b6 | ||
|
|
bb3d6d4839 | ||
|
|
9c06622efb | ||
|
|
8b590408b0 | ||
|
|
18b2bdf5ab | ||
|
|
ba49621e79 | ||
|
|
416f1997a9 | ||
|
|
fcfbedfd74 | ||
|
|
35f3512e89 | ||
|
|
2288905cbd | ||
|
|
5a40116c7b | ||
|
|
b7c10a515c | ||
|
|
65e637eeb9 | ||
|
|
b56088948c | ||
|
|
0c5066e7d0 | ||
|
|
751497556a | ||
|
|
5f2372cc08 | ||
|
|
6f315aa38e | ||
|
|
0653b5f36b | ||
|
|
f13120bc01 | ||
|
|
a6c56518bc | ||
|
|
ecae48f3d0 | ||
|
|
c74751e0f4 | ||
|
|
2b755fa669 | ||
|
|
ca0f46b414 | ||
|
|
528fa31df6 | ||
|
|
abfb2a6706 | ||
|
|
b1ab11393e | ||
|
|
786883eb10 | ||
|
|
e477f797d0 | ||
|
|
fb196c3864 | ||
|
|
5cf44962fc | ||
|
|
06b0c3775a | ||
|
|
26690990f0 | ||
|
|
377092d9ec | ||
|
|
abede386c8 | ||
|
|
242feaa169 | ||
|
|
7c2494a82c | ||
|
|
5c2e717a40 | ||
|
|
6ae0a9760d | ||
|
|
2a10f3e443 | ||
|
|
db7a00440c | ||
|
|
0e1c589399 | ||
|
|
2f419b1af5 | ||
|
|
effd3cefcb | ||
|
|
21fd488a8e | ||
|
|
37a5c69269 | ||
|
|
9f440b1bf2 | ||
|
|
a65f61cce4 | ||
|
|
0d8fe0be72 | ||
|
|
2bbc90af64 | ||
|
|
ad21d9fed5 | ||
|
|
4c6ef29e20 | ||
|
|
a74c5108fd | ||
|
|
19fdbbdbcb | ||
|
|
8bbabd7437 | ||
|
|
5a9cd36282 | ||
|
|
297bb95a2e | ||
|
|
2511a03b66 | ||
|
|
76358f996e | ||
|
|
142fc982ca | ||
|
|
22d9279e3b | ||
|
|
a1bec98d44 | ||
|
|
e8449e340d | ||
|
|
4cb8009c69 | ||
|
|
7f357306eb | ||
|
|
06679343a4 | ||
|
|
f35d83567e | ||
|
|
c97fd77c13 | ||
|
|
62904cdb42 | ||
|
|
d9c36cad82 | ||
|
|
d2bfc152a0 | ||
|
|
f013b2b667 | ||
|
|
9fbcc20623 | ||
|
|
0fd8a75f7d | ||
|
|
99d9552813 | ||
|
|
3bca193bcc | ||
|
|
f73ff363a5 | ||
|
|
1bf689f154 | ||
|
|
3499d89098 | ||
|
|
685cd76da2 | ||
|
|
786180958d | ||
|
|
a2f72c92d5 | ||
|
|
6b368d2e79 | ||
|
|
47c2cc721e | ||
|
|
5574e3f729 | ||
|
|
1934bad3eb | ||
|
|
ee29f20304 | ||
|
|
93c2eab584 | ||
|
|
b0f45980be | ||
|
|
7b10b2ad86 | ||
|
|
3fc510469d | ||
|
|
5d56b3bcd6 | ||
|
|
aaa14eb1e9 | ||
|
|
f43608f93b | ||
|
|
9ecd921722 | ||
|
|
98e2ff0e1e | ||
|
|
b7cb09b087 | ||
|
|
fe8b44b14c | ||
|
|
ca8ed939ae | ||
|
|
4469a2c25a | ||
|
|
895291c37c | ||
|
|
ac7e6f75bc | ||
|
|
bd8b02c82d | ||
|
|
6d594d63db | ||
|
|
6656410696 | ||
|
|
470b851eae | ||
|
|
fbe9cb83a2 | ||
|
|
13a09164ae | ||
|
|
56d9830176 | ||
|
|
be820804f2 | ||
|
|
7615bc1d03 | ||
|
|
3198663430 | ||
|
|
ad432ca31d | ||
|
|
7d26beff3d | ||
|
|
4711a27814 | ||
|
|
8205a4d5b5 | ||
|
|
4f451a74e9 | ||
|
|
8518408254 | ||
|
|
72f968b594 | ||
|
|
688b443ea8 | ||
|
|
cb89da4647 | ||
|
|
cc4a04afcb | ||
|
|
bc239571a1 | ||
|
|
c025563145 | ||
|
|
c06e99dc97 | ||
|
|
c0a1dc7c37 | ||
|
|
55e1d8b2bc | ||
|
|
533f5f3f3f | ||
|
|
4a7b70c874 | ||
|
|
c101c432dc | ||
|
|
04d1b2eff8 | ||
|
|
f800dc3286 | ||
|
|
619433f101 | ||
|
|
3e9ae83aae | ||
|
|
9400c3d748 | ||
|
|
5e4940fed9 | ||
|
|
8910e6f5dc | ||
|
|
52c5e6a18b | ||
|
|
3d9ded9a44 | ||
|
|
1be3f0066b | ||
|
|
21c96c76da | ||
|
|
5e2e2b7d53 | ||
|
|
dcff423943 | ||
|
|
6747610771 | ||
|
|
e6ee5d017e | ||
|
|
cb2b544526 | ||
|
|
5ace09f782 | ||
|
|
678dde8c0e | ||
|
|
236cf1eb06 | ||
|
|
f4efbe07f7 | ||
|
|
671287b55a | ||
|
|
19c85c964b | ||
|
|
e5cf4fdafb | ||
|
|
098dacf2a5 | ||
|
|
2f8539e987 | ||
|
|
f688a58656 | ||
|
|
9cb8c0c96b | ||
|
|
05575d3f82 | ||
|
|
b9198e3717 | ||
|
|
769e67c2f3 | ||
|
|
32960abd7c | ||
|
|
126e32d9e7 | ||
|
|
d6d74cb998 | ||
|
|
6d20c1d62d | ||
|
|
b55bce2de4 | ||
|
|
6f4dc36a3d | ||
|
|
fe7e6d173b | ||
|
|
b377d99c66 | ||
|
|
d4374e6df0 | ||
|
|
c74fad84b6 | ||
|
|
e09ef05e02 | ||
|
|
2c0fc76b8a | ||
|
|
752660f5dc | ||
|
|
01f00121ba | ||
|
|
dde2333c8a | ||
|
|
babf6dc47b | ||
|
|
55288bbbd4 | ||
|
|
7297a9b4a4 | ||
|
|
4cbbd3a1d6 | ||
|
|
2f4ce6221e | ||
|
|
44cdadaec9 |
@@ -1,57 +0,0 @@
|
||||
{
|
||||
"$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",
|
||||
"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,3 +1,4 @@
|
||||
# Editor configuration, see http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -30,13 +30,10 @@
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# e2e
|
||||
/e2e/*.js
|
||||
/e2e/*.map
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
14
README.md
14
README.md
@@ -1,6 +1,12 @@
|
||||
# Fuse2
|
||||
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.1.3.
|
||||
Material Design Admin Template with Angular 6+ and Angular Material 2
|
||||
|
||||
## The Community
|
||||
|
||||
Share your ideas, discuss Fuse and help each other.
|
||||
|
||||
[Click here](http://fusetheme.com/community) to see our Community page.
|
||||
|
||||
## Development server
|
||||
|
||||
@@ -8,11 +14,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|module`.
|
||||
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`.
|
||||
|
||||
## 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
|
||||
|
||||
@@ -21,8 +27,8 @@ 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/).
|
||||
Before running the tests make sure you are serving the app via `ng serve`.
|
||||
|
||||
## 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).
|
||||
|
||||
|
||||
140
angular.json
Normal file
140
angular.json
Normal file
@@ -0,0 +1,140 @@
|
||||
{
|
||||
"$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/content/components/angular-material"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.scss"
|
||||
],
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "fuse:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "fuse:build:production"
|
||||
},
|
||||
"hmr": {
|
||||
"hmr": true,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.hmr.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"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/fuse-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/fuse-fake-db/**/*",
|
||||
"**/src/assets/angular-material-examples/**/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "fuse"
|
||||
}
|
||||
@@ -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 app!!');
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import { browser, by, element } from 'protractor';
|
||||
|
||||
export class Fuse2Page {
|
||||
navigateTo() {
|
||||
return browser.get('/');
|
||||
}
|
||||
|
||||
getParagraphText() {
|
||||
return element(by.css('app-root h1')).getText();
|
||||
}
|
||||
}
|
||||
31
e2e/protractor.conf.js
Normal file
31
e2e/protractor.conf.js
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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}}));
|
||||
}
|
||||
};
|
||||
14
e2e/src/app.e2e-spec.ts
Normal file
14
e2e/src/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 Fuse2!');
|
||||
});
|
||||
});
|
||||
11
e2e/src/app.po.ts
Normal file
11
e2e/src/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,12 +1,13 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/e2e",
|
||||
"outDir": "../out-tsc/app",
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"jasminewd2",
|
||||
"node"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
// 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
|
||||
});
|
||||
};
|
||||
13454
package-lock.json
generated
13454
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
125
package.json
125
package.json
@@ -1,69 +1,88 @@
|
||||
{
|
||||
"name": "fuse2",
|
||||
"version": "1.0.4",
|
||||
"license": "",
|
||||
"name": "fuse",
|
||||
"version": "6.0.0",
|
||||
"license": "https://themeforest.net/licenses/terms/regular",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"start": "ng serve --open",
|
||||
"start-hmr": "ng serve --configuration hmr -sm=false",
|
||||
"start-hmr-sourcemaps": "ng serve --hmr -e=hmr",
|
||||
"build": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --dev",
|
||||
"build-stats": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --dev --stats-json",
|
||||
"build-prod": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --prod",
|
||||
"build-prod-stats": "node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build --prod --stats-json",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
"e2e": "ng e2e",
|
||||
"bundle-report": "webpack-bundle-analyzer dist/stats.json"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "4.3.5",
|
||||
"@angular/cdk": "2.0.0-beta.10",
|
||||
"@angular/common": "4.3.5",
|
||||
"@angular/compiler": "4.3.5",
|
||||
"@angular/core": "4.3.5",
|
||||
"@angular/flex-layout": "2.0.0-beta.9",
|
||||
"@angular/forms": "4.3.5",
|
||||
"@angular/http": "4.3.5",
|
||||
"@angular/material": "2.0.0-beta.10",
|
||||
"@angular/platform-browser": "4.3.5",
|
||||
"@angular/platform-browser-dynamic": "4.3.5",
|
||||
"@angular/router": "4.3.5",
|
||||
"@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.3.2",
|
||||
"@agm/core": "1.0.0-beta.2",
|
||||
"@angular/animations": "6.0.0",
|
||||
"@angular/cdk": "6.0.0",
|
||||
"@angular/common": "6.0.0",
|
||||
"@angular/compiler": "6.0.0",
|
||||
"@angular/core": "6.0.0",
|
||||
"@angular/flex-layout": "6.0.0-beta.15",
|
||||
"@angular/forms": "6.0.0",
|
||||
"@angular/http": "6.0.0",
|
||||
"@angular/material": "6.0.0",
|
||||
"@angular/material-moment-adapter": "6.0.0",
|
||||
"@angular/platform-browser": "6.0.0",
|
||||
"@angular/platform-browser-dynamic": "6.0.0",
|
||||
"@angular/router": "6.0.0",
|
||||
"@ngrx/effects": "5.2.0",
|
||||
"@ngrx/router-store": "5.2.0",
|
||||
"@ngrx/store": "5.2.0",
|
||||
"@ngrx/store-devtools": "5.2.0",
|
||||
"@ngx-translate/core": "10.0.1",
|
||||
"@swimlane/ngx-charts": "7.3.0",
|
||||
"@swimlane/ngx-datatable": "11.3.2",
|
||||
"@swimlane/ngx-dnd": "3.2.0",
|
||||
"@types/prismjs": "1.9.0",
|
||||
"angular-calendar": "0.24.0",
|
||||
"angular-in-memory-web-api": "0.6.0",
|
||||
"chart.js": "2.7.2",
|
||||
"classlist.js": "1.1.20150312",
|
||||
"core-js": "2.5.0",
|
||||
"d3": "4.10.0",
|
||||
"core-js": "2.5.5",
|
||||
"d3": "5.1.0",
|
||||
"hammerjs": "2.0.8",
|
||||
"highlight.js": "9.12.0",
|
||||
"intl": "1.2.5",
|
||||
"moment": "2.18.1",
|
||||
"ngx-color-picker": "4.3.1",
|
||||
"ngx-cookie-service": "1.0.7",
|
||||
"ngx-perfect-scrollbar": "4.5.6",
|
||||
"rxjs": "5.4.3",
|
||||
"lodash": "4.17.10",
|
||||
"moment": "2.22.1",
|
||||
"ng2-charts": "1.6.0",
|
||||
"ngrx-store-freeze": "0.2.2",
|
||||
"ngx-color-picker": "5.3.8",
|
||||
"ngx-cookie-service": "1.0.10",
|
||||
"perfect-scrollbar": "1.3.0",
|
||||
"prismjs": "1.14.0",
|
||||
"rxjs": "6.1.0",
|
||||
"rxjs-compat": "6.1.0",
|
||||
"web-animations-js": "2.3.1",
|
||||
"zone.js": "0.8.17"
|
||||
"zone.js": "0.8.26"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/cli": "^1.3.2",
|
||||
"@angular/compiler-cli": "4.3.5",
|
||||
"@angular/language-service": "4.3.5",
|
||||
"@ngtools/webpack": "^1.6.2",
|
||||
"@types/jasmine": "^2.5.54",
|
||||
"@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",
|
||||
"@angular/cli": "6.0.0",
|
||||
"@angular/compiler-cli": "6.0.0",
|
||||
"@angular/language-service": "6.0.0",
|
||||
"@angular-devkit/build-angular": "0.6.0",
|
||||
"@angularclass/hmr": "2.1.3",
|
||||
"@types/jasmine": "2.8.7",
|
||||
"@types/jasminewd2": "2.0.3",
|
||||
"@types/lodash": "4.14.108",
|
||||
"@types/node": "8.9.5",
|
||||
"codelyzer": "4.2.1",
|
||||
"jasmine-core": "2.99.1",
|
||||
"jasmine-spec-reporter": "4.2.1",
|
||||
"karma": "1.7.1",
|
||||
"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",
|
||||
"node-sass": "^4.5.3",
|
||||
"protractor": "~5.1.2",
|
||||
"ts-node": "~3.0.4",
|
||||
"tslint": "~5.3.2",
|
||||
"typescript": "~2.3.3"
|
||||
"karma-chrome-launcher": "2.2.0",
|
||||
"karma-coverage-istanbul-reporter": "1.4.2",
|
||||
"karma-jasmine": "1.1.2",
|
||||
"karma-jasmine-html-reporter": "0.2.2",
|
||||
"protractor": "5.3.1",
|
||||
"ts-node": "5.0.1",
|
||||
"tslint": "5.9.1",
|
||||
"typescript": "2.7.2",
|
||||
"webpack-bundle-analyzer": "2.11.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +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: [
|
||||
'./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,10 +1,69 @@
|
||||
import { sequence, trigger, stagger, animate, style, group, query, transition, keyframes, animateChild, state } from '@angular/animations';
|
||||
import { sequence, trigger, animate, style, group, query, transition, animateChild, state, animation, useAnimation, stagger } from '@angular/animations';
|
||||
|
||||
// const query = (s, a, o = {optional: true}) => q(s, a, o);
|
||||
const customAnimation = animation([
|
||||
style({
|
||||
opacity : '{{opacity}}',
|
||||
transform: 'scale({{scale}}) translate3d({{x}}, {{y}}, {{z}})'
|
||||
}),
|
||||
animate('{{duration}} {{delay}} cubic-bezier(0.0, 0.0, 0.2, 1)', style('*'))
|
||||
], {
|
||||
params: {
|
||||
duration: '200ms',
|
||||
delay : '0ms',
|
||||
opacity : '0',
|
||||
scale : '1',
|
||||
x : '0',
|
||||
y : '0',
|
||||
z : '0'
|
||||
}
|
||||
});
|
||||
|
||||
export class Animations
|
||||
{
|
||||
public static slideInOut = trigger('slideInOut', [
|
||||
export const fuseAnimations = [
|
||||
|
||||
trigger('animate', [transition('void => *', [useAnimation(customAnimation)])]),
|
||||
|
||||
trigger('animateStagger', [
|
||||
state('50', style('*')),
|
||||
state('100', style('*')),
|
||||
state('200', style('*')),
|
||||
|
||||
transition('void => 50',
|
||||
query('@*',
|
||||
[
|
||||
stagger('50ms', [
|
||||
animateChild()
|
||||
])
|
||||
], {optional: true})),
|
||||
transition('void => 100',
|
||||
query('@*',
|
||||
[
|
||||
stagger('100ms', [
|
||||
animateChild()
|
||||
])
|
||||
], {optional: true})),
|
||||
transition('void => 200',
|
||||
query('@*',
|
||||
[
|
||||
stagger('200ms', [
|
||||
animateChild()
|
||||
])
|
||||
], {optional: true}))
|
||||
]),
|
||||
|
||||
trigger('fadeInOut', [
|
||||
state('0', style({
|
||||
display: 'none',
|
||||
opacity: 0
|
||||
})),
|
||||
state('1', style({
|
||||
display: 'block',
|
||||
opacity: 1
|
||||
})),
|
||||
transition('1 => 0', animate('300ms ease-out')),
|
||||
transition('0 => 1', animate('300ms ease-in'))
|
||||
]),
|
||||
|
||||
trigger('slideInOut', [
|
||||
state('0', style({
|
||||
height : '0px',
|
||||
display: 'none'
|
||||
@@ -15,9 +74,56 @@ export class Animations
|
||||
})),
|
||||
transition('1 => 0', animate('300ms ease-out')),
|
||||
transition('0 => 1', animate('300ms ease-in'))
|
||||
]);
|
||||
]),
|
||||
|
||||
public static slideInLeft = trigger('slideInLeft', [
|
||||
trigger('slideIn', [
|
||||
transition('void => left', [
|
||||
style({
|
||||
transform: 'translateX(100%)'
|
||||
}),
|
||||
animate('300ms ease-in',
|
||||
style({
|
||||
transform: 'translateX(0)'
|
||||
})
|
||||
)
|
||||
]
|
||||
),
|
||||
transition('left => void', [
|
||||
style({
|
||||
transform: 'translateX(0)'
|
||||
}),
|
||||
animate('300ms ease-in',
|
||||
style({
|
||||
transform: 'translateX(-100%)'
|
||||
})
|
||||
)
|
||||
]
|
||||
),
|
||||
transition('void => right', [
|
||||
style({
|
||||
transform: 'translateX(-100%)'
|
||||
}),
|
||||
animate('300ms ease-in',
|
||||
style({
|
||||
transform: 'translateX(0)'
|
||||
})
|
||||
)
|
||||
]
|
||||
),
|
||||
transition('right => void', [
|
||||
style({
|
||||
transform: 'translateX(0)'
|
||||
}),
|
||||
animate('300ms ease-in',
|
||||
style({
|
||||
transform: 'translateX(100%)'
|
||||
})
|
||||
)
|
||||
]
|
||||
),
|
||||
]),
|
||||
|
||||
trigger('slideInLeft', [
|
||||
state('void', style({
|
||||
transform: 'translateX(-100%)',
|
||||
display : 'none'
|
||||
@@ -28,9 +134,9 @@ export class Animations
|
||||
})),
|
||||
transition('void => *', animate('300ms')),
|
||||
transition('* => void', animate('300ms'))
|
||||
]);
|
||||
]),
|
||||
|
||||
public static slideInRight = trigger('slideInRight', [
|
||||
trigger('slideInRight', [
|
||||
state('void', style({
|
||||
transform: 'translateX(100%)',
|
||||
display : 'none'
|
||||
@@ -41,9 +147,9 @@ export class Animations
|
||||
})),
|
||||
transition('void => *', animate('300ms')),
|
||||
transition('* => void', animate('300ms'))
|
||||
]);
|
||||
]),
|
||||
|
||||
public static slideInTop = trigger('slideInTop', [
|
||||
trigger('slideInTop', [
|
||||
state('void', style({
|
||||
transform: 'translateY(-100%)',
|
||||
display : 'none'
|
||||
@@ -54,9 +160,9 @@ export class Animations
|
||||
})),
|
||||
transition('void => *', animate('300ms')),
|
||||
transition('* => void', animate('300ms'))
|
||||
]);
|
||||
]),
|
||||
|
||||
public static slideInBottom = trigger('slideInBottom', [
|
||||
trigger('slideInBottom', [
|
||||
state('void',
|
||||
style({
|
||||
transform: 'translateY(100%)',
|
||||
@@ -68,9 +174,20 @@ export class Animations
|
||||
})),
|
||||
transition('void => *', animate('300ms')),
|
||||
transition('* => void', animate('300ms'))
|
||||
]);
|
||||
]),
|
||||
|
||||
public static routerTransitionLeft = trigger('routerTransitionLeft', [
|
||||
trigger('expandCollapse', [
|
||||
state('void', style({
|
||||
height: '0px'
|
||||
})),
|
||||
state('*', style({
|
||||
height: '*'
|
||||
})),
|
||||
transition('void => *', animate('300ms ease-out')),
|
||||
transition('* => void', animate('300ms ease-in'))
|
||||
]),
|
||||
|
||||
trigger('routerTransitionLeft', [
|
||||
|
||||
transition('* => *', [
|
||||
query('fuse-content > :enter, fuse-content > :leave', [
|
||||
@@ -95,7 +212,7 @@ export class Animations
|
||||
transform: 'translateX(0)',
|
||||
opacity : 1
|
||||
}),
|
||||
animate('400ms cubic-bezier(0.250, 0.460, 0.450, 0.940)',
|
||||
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
|
||||
style({
|
||||
transform: 'translateX(-100%)',
|
||||
opacity : 0
|
||||
@@ -103,7 +220,7 @@ export class Animations
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
style({transform: 'translateX(100%)'}),
|
||||
animate('400ms cubic-bezier(0.250, 0.460, 0.450, 0.940)',
|
||||
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
|
||||
style({
|
||||
transform: 'translateX(0%)',
|
||||
opacity : 1
|
||||
@@ -114,9 +231,9 @@ export class Animations
|
||||
query('fuse-content > :enter', animateChild(), {optional: true})
|
||||
])
|
||||
])
|
||||
]);
|
||||
]),
|
||||
|
||||
public static routerTransitionRight = trigger('routerTransitionRight', [
|
||||
trigger('routerTransitionRight', [
|
||||
|
||||
transition('* => *', [
|
||||
query('fuse-content > :enter, fuse-content > :leave', [
|
||||
@@ -141,7 +258,7 @@ export class Animations
|
||||
transform: 'translateX(0)',
|
||||
opacity : 1
|
||||
}),
|
||||
animate('400ms cubic-bezier(0.250, 0.460, 0.450, 0.940)',
|
||||
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
|
||||
style({
|
||||
transform: 'translateX(100%)',
|
||||
opacity : 0
|
||||
@@ -149,7 +266,7 @@ export class Animations
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
style({transform: 'translateX(-100%)'}),
|
||||
animate('400ms cubic-bezier(0.250, 0.460, 0.450, 0.940)',
|
||||
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
|
||||
style({
|
||||
transform: 'translateX(0%)',
|
||||
opacity : 1
|
||||
@@ -160,9 +277,9 @@ export class Animations
|
||||
query('fuse-content > :enter', animateChild(), {optional: true})
|
||||
])
|
||||
])
|
||||
]);
|
||||
]),
|
||||
|
||||
public static routerTransitionUp = trigger('routerTransitionUp', [
|
||||
trigger('routerTransitionUp', [
|
||||
|
||||
transition('* => *', [
|
||||
query('fuse-content > :enter, fuse-content > :leave', [
|
||||
@@ -180,35 +297,33 @@ export class Animations
|
||||
opacity : 0
|
||||
})
|
||||
], {optional: true}),
|
||||
sequence([
|
||||
group([
|
||||
query('fuse-content > :leave', [
|
||||
group([
|
||||
query('fuse-content > :leave', [
|
||||
style({
|
||||
transform: 'translateY(0)',
|
||||
opacity : 1
|
||||
}),
|
||||
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
|
||||
style({
|
||||
transform: 'translateY(0)',
|
||||
transform: 'translateY(-100%)',
|
||||
opacity : 0
|
||||
}))
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
style({transform: 'translateY(100%)'}),
|
||||
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
|
||||
style({
|
||||
transform: 'translateY(0%)',
|
||||
opacity : 1
|
||||
}),
|
||||
animate('400ms cubic-bezier(0.250, 0.460, 0.450, 0.940)',
|
||||
style({
|
||||
transform: 'translateY(-100%)',
|
||||
opacity : 0
|
||||
}))
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
style({transform: 'translateY(100%)'}),
|
||||
animate('400ms cubic-bezier(0.250, 0.460, 0.450, 0.940)',
|
||||
style({
|
||||
transform: 'translateY(0%)',
|
||||
opacity : 1
|
||||
}))
|
||||
], {optional: true})
|
||||
]),
|
||||
query('fuse-content > :leave', animateChild(), {optional: true}),
|
||||
query('fuse-content > :enter', animateChild(), {optional: true})
|
||||
])
|
||||
}))
|
||||
], {optional: true})
|
||||
]),
|
||||
query('fuse-content > :leave', animateChild(), {optional: true}),
|
||||
query('fuse-content > :enter', animateChild(), {optional: true})
|
||||
])
|
||||
]);
|
||||
]),
|
||||
|
||||
public static routerTransitionDown = trigger('routerTransitionDown', [
|
||||
trigger('routerTransitionDown', [
|
||||
|
||||
transition('* => *', [
|
||||
query('fuse-content > :enter, fuse-content > :leave', [
|
||||
@@ -233,7 +348,7 @@ export class Animations
|
||||
transform: 'translateY(0)',
|
||||
opacity : 1
|
||||
}),
|
||||
animate('400ms cubic-bezier(0.250, 0.460, 0.450, 0.940)',
|
||||
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
|
||||
style({
|
||||
transform: 'translateY(100%)',
|
||||
opacity : 0
|
||||
@@ -241,7 +356,7 @@ export class Animations
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
style({transform: 'translateY(-100%)'}),
|
||||
animate('400ms cubic-bezier(0.250, 0.460, 0.450, 0.940)',
|
||||
animate('600ms cubic-bezier(0.0, 0.0, 0.2, 1)',
|
||||
style({
|
||||
transform: 'translateY(0%)',
|
||||
opacity : 1
|
||||
@@ -252,11 +367,11 @@ export class Animations
|
||||
query('fuse-content > :enter', animateChild(), {optional: true})
|
||||
])
|
||||
])
|
||||
]);
|
||||
]),
|
||||
|
||||
public static routerTransitionFade = trigger('routerTransitionFade', [
|
||||
trigger('routerTransitionFade', [
|
||||
|
||||
transition('* => *', [
|
||||
transition('* => *', group([
|
||||
|
||||
query('fuse-content > :enter, fuse-content > :leave ', [
|
||||
style({
|
||||
@@ -267,33 +382,32 @@ export class Animations
|
||||
right : 0
|
||||
})
|
||||
], {optional: true}),
|
||||
|
||||
query('fuse-content > :enter', [
|
||||
style({
|
||||
opacity: 0
|
||||
})
|
||||
], {optional: true}),
|
||||
// sequence([
|
||||
query('fuse-content > :leave', [
|
||||
style({
|
||||
opacity: 1
|
||||
}),
|
||||
animate('300ms cubic-bezier(0.250, 0.460, 0.450, 0.940)',
|
||||
style({
|
||||
opacity: 0
|
||||
}))
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
query('fuse-content > :leave', [
|
||||
style({
|
||||
opacity: 1
|
||||
}),
|
||||
animate('300ms cubic-bezier(0.0, 0.0, 0.2, 1)',
|
||||
style({
|
||||
opacity: 0
|
||||
}),
|
||||
animate('300ms cubic-bezier(0.250, 0.460, 0.450, 0.940)',
|
||||
style({
|
||||
opacity: 1
|
||||
}))
|
||||
], {optional: true}),
|
||||
// ]),
|
||||
}))
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', [
|
||||
style({
|
||||
opacity: 0
|
||||
}),
|
||||
animate('300ms cubic-bezier(0.0, 0.0, 0.2, 1)',
|
||||
style({
|
||||
opacity: 1
|
||||
}))
|
||||
], {optional: true}),
|
||||
query('fuse-content > :enter', animateChild(), {optional: true}),
|
||||
query('fuse-content > :leave', animateChild(), {optional: true})
|
||||
])
|
||||
]);
|
||||
}
|
||||
]))
|
||||
])
|
||||
];
|
||||
@@ -0,0 +1,6 @@
|
||||
<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>
|
||||
@@ -0,0 +1,17 @@
|
||||
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(public dialogRef: MatDialogRef<FuseConfirmDialogComponent>)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
20
src/@fuse/components/confirm-dialog/confirm-dialog.module.ts
Normal file
20
src/@fuse/components/confirm-dialog/confirm-dialog.module.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
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,6 +1,8 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import 'rxjs/add/observable/interval';
|
||||
|
||||
import * as moment from 'moment';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-countdown',
|
||||
15
src/@fuse/components/countdown/countdown.module.ts
Normal file
15
src/@fuse/components/countdown/countdown.module.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { FuseCountdownComponent } from '@fuse/components/countdown/countdown.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
FuseCountdownComponent
|
||||
],
|
||||
exports: [
|
||||
FuseCountdownComponent
|
||||
],
|
||||
})
|
||||
export class FuseCountdownModule
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<!-- DEMO CONTENT -->
|
||||
<div class="demo-content">
|
||||
|
||||
<img src="assets/images/beach.jpg" alt="beach" style="max-width: 640px; width: 100%;">
|
||||
|
||||
<h1>Early Sunrise</h1>
|
||||
<h4 class="secondary-text">Demo Content</h4>
|
||||
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse tortor nibh, convallis sed purus nec,
|
||||
auctor venenatis nisl. Suspendisse potenti. Nullam sagittis nulla in diam finibus, sed pharetra velit
|
||||
vestibulum. Suspendisse euismod in urna eu posuere.
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<p>
|
||||
Nunc vel lacinia lorem. Nullam tincidunt sed purus eu placerat. Donec id dictum erat. Etiam enim ex, dapibus
|
||||
et tortor id, posuere pretium est. Maecenas fringilla ipsum vitae neque elementum, at eleifend ante
|
||||
sollicitudin. Donec viverra augue dolor, a venenatis tellus consectetur sit amet.
|
||||
</p>
|
||||
<footer>
|
||||
John Doe
|
||||
</footer>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
Ut ornare sit amet velit vel congue. Ut nec tristique eros. Lorem ipsum dolor sit amet, consectetur adipiscing
|
||||
elit. Vivamus sed lorem quis nibh porta iaculis. Vestibulum ut eleifend ante, at semper mi. Nam imperdiet est
|
||||
nisi, quis hendrerit tellus convallis et. Morbi in luctus neque. Curabitur elementum ut est et gravida. In hac
|
||||
habitasse platea dictumst.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In et placerat eros, eu tempor turpis. Curabitur ac felis finibus, elementum lectus vitae, venenatis est.
|
||||
Integer mollis nisl a eros scelerisque varius. Etiam venenatis lectus vel erat condimentum tristique vel vel mi.
|
||||
Nulla id euismod mi, et mollis tellus.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Class aptent taciti
|
||||
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur vitae sagittis odio.
|
||||
Suspendisse ullamcorper nunc non pellentesque laoreet. Curabitur eu tortor id quam pretium mattis. Proin ut quam
|
||||
velit.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Quisque sit amet risus enim. Aliquam sit amet interdum justo, at ultricies sapien. Suspendisse et semper urna,
|
||||
in gravida eros. Quisque id nibh iaculis, euismod urna sed, egestas nisi. Donec eros metus, congue a imperdiet
|
||||
feugiat, sagittis nec ipsum. Quisque dapibus mollis felis non tristique.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Ut auctor, metus sed dapibus tempus, urna diam auctor odio, in malesuada odio risus vitae nisi. Etiam blandit
|
||||
ante urna, vitae placerat massa mollis in. Duis nec urna ac purus semper dictum ut eget justo. Aenean non
|
||||
sagittis augue. Sed venenatis rhoncus enim eget ornare. Donec viverra sed felis at venenatis. Mauris aliquam
|
||||
fringilla nulla, sit amet congue felis dignissim at.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Quisque accumsan augue tempor ante mollis, sed placerat diam porttitor. Vestibulum dignissim sem vel velit
|
||||
eleifend, non pellentesque quam convallis. Pellentesque est dolor, dignissim ac tortor tristique, hendrerit
|
||||
iaculis metus. Praesent pulvinar quam eu leo consectetur faucibus. Vestibulum purus diam, gravida sagittis
|
||||
feugiat sit amet, tincidunt in ligula. Sed semper vestibulum magna. Lorem ipsum dolor sit amet, consectetur
|
||||
adipiscing elit. Suspendisse tortor nibh, convallis sed purus nec, auctor venenatis nisl. Suspendisse potenti.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Nullam sagittis nulla in diam finibus, sed pharetra velit vestibulum. Suspendisse euismod in urna eu posuere.
|
||||
Etiam blandit nunc arcu, et consectetur orci blandit a. Aliquam condimentum pharetra quam at ultricies. Nunc vel
|
||||
lacinia lorem. Nullam tincidunt sed purus eu placerat. Donec id dictum erat. Etiam enim ex, dapibus et tortor
|
||||
id, posuere pretium est. Maecenas fringilla ipsum vitae neque elementum, at eleifend ante sollicitudin. Donec
|
||||
viverra augue dolor, a venenatis tellus consectetur sit amet...
|
||||
</p>
|
||||
</div>
|
||||
<!-- / DEMO CONTENT -->
|
||||
@@ -0,0 +1,100 @@
|
||||
<div class="demo-sidenav">
|
||||
<mat-list>
|
||||
<h3 matSubheader>Sidenav Demo</h3>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 1</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 2</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 3</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 4</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 5</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 6</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 7</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 8</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 9</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 10</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 11</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 12</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 13</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 14</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 15</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<mat-list-item>
|
||||
<span>Sidenav Item 16</span>
|
||||
</mat-list-item>
|
||||
|
||||
</mat-list>
|
||||
</div>
|
||||
@@ -1,6 +1,8 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { SharedModule } from '../../modules/shared.module';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { MatDividerModule, MatListModule } from '@angular/material';
|
||||
|
||||
import { FuseDemoContentComponent } from './demo-content/demo-content.component';
|
||||
import { FuseDemoSidenavComponent } from './demo-sidenav/demo-sidenav.component';
|
||||
|
||||
@@ -10,8 +12,10 @@ import { FuseDemoSidenavComponent } from './demo-sidenav/demo-sidenav.component'
|
||||
FuseDemoSidenavComponent
|
||||
],
|
||||
imports : [
|
||||
SharedModule,
|
||||
RouterModule
|
||||
RouterModule,
|
||||
|
||||
MatDividerModule,
|
||||
MatListModule
|
||||
],
|
||||
exports : [
|
||||
FuseDemoContentComponent,
|
||||
6
src/@fuse/components/highlight/highlight.component.scss
Normal file
6
src/@fuse/components/highlight/highlight.component.scss
Normal file
@@ -0,0 +1,6 @@
|
||||
:host {
|
||||
display: block;
|
||||
padding: 8px;
|
||||
background: #263238;
|
||||
cursor: text;
|
||||
}
|
||||
102
src/@fuse/components/highlight/highlight.component.ts
Normal file
102
src/@fuse/components/highlight/highlight.component.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { Component, ContentChild, ElementRef, Input, OnInit } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
|
||||
import * as Prism from 'prismjs/prism';
|
||||
import './prism-languages';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-highlight',
|
||||
template : ' ',
|
||||
styleUrls: ['./highlight.component.scss']
|
||||
})
|
||||
export class FuseHighlightComponent implements OnInit
|
||||
{
|
||||
@ContentChild('source') source: ElementRef;
|
||||
@Input('lang') lang: string;
|
||||
@Input('path') path: string;
|
||||
|
||||
constructor(
|
||||
private elementRef: ElementRef,
|
||||
private http: HttpClient
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
// If there is no language defined, return...
|
||||
if ( !this.lang )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If the path is defined...
|
||||
if ( this.path )
|
||||
{
|
||||
// Get the source
|
||||
this.http.get(this.path, {responseType: 'text'}).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);
|
||||
}
|
||||
}
|
||||
|
||||
highlight(sourceCode)
|
||||
{
|
||||
// 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>';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
15
src/@fuse/components/highlight/highlight.module.ts
Normal file
15
src/@fuse/components/highlight/highlight.module.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { FuseHighlightComponent } from '@fuse/components/highlight/highlight.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
FuseHighlightComponent
|
||||
],
|
||||
exports: [
|
||||
FuseHighlightComponent
|
||||
],
|
||||
})
|
||||
export class FuseHighlightModule
|
||||
{
|
||||
}
|
||||
17
src/@fuse/components/highlight/prism-languages.ts
Normal file
17
src/@fuse/components/highlight/prism-languages.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import 'prismjs/prism';
|
||||
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';
|
||||
11
src/@fuse/components/index.ts
Normal file
11
src/@fuse/components/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export * from './confirm-dialog/confirm-dialog.module';
|
||||
export * from './countdown/countdown.module';
|
||||
export * from './demo/demo.module';
|
||||
export * from './highlight/highlight.module';
|
||||
export * from './material-color-picker/material-color-picker.module';
|
||||
export * from './navigation/navigation.module';
|
||||
export * from './search-bar/search-bar.module';
|
||||
export * from './shortcuts/shortcuts.module';
|
||||
export * from './sidebar/sidebar.module';
|
||||
export * from './theme-options/theme-options.module';
|
||||
export * from './widget/widget.module';
|
||||
@@ -0,0 +1,70 @@
|
||||
<button mat-icon-button
|
||||
type="button"
|
||||
class="mat-elevation-z1"
|
||||
[matMenuTriggerFor]="colorMenu"
|
||||
(menuOpened)="onMenuOpen()"
|
||||
[ngClass]="'mat-'+selectedPalette+'-'+selectedHue+'-bg'">
|
||||
<mat-icon>palette</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-menu #colorMenu="matMenu" class="fuse-material-color-picker-menu">
|
||||
|
||||
<header [ngClass]="selectedColor?.class || 'mat-accent-bg'" class="mat-elevation-z4"
|
||||
fxLayout="row" fxLayoutAlign="space-between center">
|
||||
|
||||
<button mat-icon-button
|
||||
[style.visibility]="view==='hues'?'visible':'hidden'"
|
||||
(click)="$event.stopPropagation();backToPaletteSelection()" 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 Color
|
||||
</span>
|
||||
|
||||
<button mat-icon-button
|
||||
class="remove-color-button"
|
||||
(click)="$event.stopPropagation();removeColor()"
|
||||
aria-label="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"
|
||||
[ngClass]="'mat-'+color.key+'-bg'"
|
||||
*ngFor="let color of (colors | keys)"
|
||||
(click)="$event.stopPropagation();selectPalette(color.key)"
|
||||
fxLayout="row" fxLayoutAlign="start end" mat-ink-ripple>
|
||||
<span class="label">
|
||||
{{color.key}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="view" *ngSwitchCase="'hues'" >
|
||||
<div fxLayout="row wrap" fxLayoutAlign="start start" class="colors" fusePerfectScrollbar>
|
||||
<div class="color" *ngFor="let hue of hues"
|
||||
[fxHide]="selectedPalette === 'white' && hue !== '500'|| selectedPalette === 'black' && hue !== '500'"
|
||||
[ngClass]="'mat-'+selectedPalette+'-'+hue+'-bg'"
|
||||
(click)="selectHue(hue)" fxLayout="row" fxLayoutAlign="start end" mat-ink-ripple>
|
||||
<span class="label">
|
||||
{{hue}}
|
||||
</span>
|
||||
<mat-icon *ngIf="selectedHue === hue" class="s-16">check</mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</mat-menu>
|
||||
@@ -11,7 +11,7 @@
|
||||
overflow: hidden;
|
||||
min-height: 258px;
|
||||
height: 308px;
|
||||
background-color: #f7f7f7;
|
||||
background-color: #F7F7F7;
|
||||
|
||||
.view {
|
||||
position: absolute;
|
||||
@@ -39,7 +39,7 @@
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
md-icon {
|
||||
mat-icon {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
@@ -1,15 +1,16 @@
|
||||
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, ViewEncapsulation } from '@angular/core';
|
||||
import { MatColors } from '../../matColors';
|
||||
import { Animations } from '../../animations';
|
||||
import { Component, EventEmitter, Input, OnChanges, Output, ViewEncapsulation } from '@angular/core';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { MatColors } from '@fuse/mat-colors';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-material-color-picker',
|
||||
templateUrl : './material-color-picker.component.html',
|
||||
styleUrls : ['./material-color-picker.component.scss'],
|
||||
animations : [Animations.slideInLeft, Animations.slideInRight],
|
||||
animations : fuseAnimations,
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class FuseMaterialColorPickerComponent implements OnInit, OnChanges
|
||||
export class FuseMaterialColorPickerComponent implements OnChanges
|
||||
{
|
||||
colors: any;
|
||||
selectedColor: any;
|
||||
@@ -91,11 +92,21 @@ export class FuseMaterialColorPickerComponent implements OnInit, OnChanges
|
||||
this.hues = ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900', 'A100', 'A200', 'A400', 'A700'];
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
ngOnChanges(changes: any)
|
||||
{
|
||||
|
||||
if ( changes.selectedBg && changes.selectedBg.currentValue === '' ||
|
||||
changes.selectedClass && changes.selectedClass.currentValue === '' ||
|
||||
changes.selectedPalette && changes.selectedPalette.currentValue === '' )
|
||||
{
|
||||
this.removeColor();
|
||||
return;
|
||||
}
|
||||
if ( changes.selectedPalette || changes.selectedHue || changes.selectedClass || changes.selectedBg )
|
||||
{
|
||||
this.updateSelectedColor();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
selectPalette(palette)
|
||||
{
|
||||
this.selectedPalette = palette;
|
||||
@@ -114,6 +125,7 @@ export class FuseMaterialColorPickerComponent implements OnInit, OnChanges
|
||||
this.selectedPalette = '';
|
||||
this.selectedHue = '';
|
||||
this.updateSelectedColor();
|
||||
this.view = 'palettes';
|
||||
}
|
||||
|
||||
updateSelectedColor()
|
||||
@@ -129,7 +141,7 @@ export class FuseMaterialColorPickerComponent implements OnInit, OnChanges
|
||||
{
|
||||
this.selectedBg = MatColors.getColor(this.selectedPalette)[this.selectedHue];
|
||||
this.selectedFg = MatColors.getColor(this.selectedPalette).contrast[this.selectedHue];
|
||||
this.selectedClass = 'md-' + this.selectedPalette + '-' + this.selectedHue + '-bg';
|
||||
this.selectedClass = 'mat-' + this.selectedPalette + '-' + this.selectedHue + '-bg';
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -172,19 +184,4 @@ export class FuseMaterialColorPickerComponent implements OnInit, OnChanges
|
||||
this.view = 'hues';
|
||||
}
|
||||
}
|
||||
|
||||
ngOnChanges(changes: any)
|
||||
{
|
||||
if ( changes.selectedBg && changes.selectedBg.currentValue === '' ||
|
||||
changes.selectedClass && changes.selectedClass.currentValue === '' ||
|
||||
changes.selectedPalette && changes.selectedPalette.currentValue === '' )
|
||||
{
|
||||
this.removeColor();
|
||||
return;
|
||||
}
|
||||
if ( changes.selectedPalette || changes.selectedHue || changes.selectedClass || changes.selectedBg )
|
||||
{
|
||||
this.updateSelectedColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
|
||||
import { MatButtonModule, MatIconModule, MatMenuModule, MatRippleModule } from '@angular/material';
|
||||
|
||||
import { FusePipesModule } from '@fuse/pipes/pipes.module';
|
||||
|
||||
import { FuseMaterialColorPickerComponent } from '@fuse/components/material-color-picker/material-color-picker.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
FuseMaterialColorPickerComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
|
||||
FlexLayoutModule,
|
||||
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatMenuModule,
|
||||
MatRippleModule,
|
||||
|
||||
FusePipesModule
|
||||
],
|
||||
exports: [
|
||||
FuseMaterialColorPickerComponent
|
||||
],
|
||||
})
|
||||
export class FuseMaterialColorPickerModule
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<ng-container *ngIf="!item.hidden">
|
||||
|
||||
<!-- normal collapse -->
|
||||
<a class="nav-link" *ngIf="!item.url && !item.function" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.url -->
|
||||
<a class="nav-link" *ngIf="item.url && !item.function"
|
||||
[routerLink]="[item.url]" routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.function -->
|
||||
<span class="nav-link" *ngIf="!item.url && item.function" (click)="item.function()" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</span>
|
||||
|
||||
<!-- item.url && item.function -->
|
||||
<a class="nav-link" *ngIf="item.url && item.function" (click)="item.function()"
|
||||
[routerLink]="[item.url]" routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<ng-template #itemContent>
|
||||
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
|
||||
<span class="nav-link-title" [translate]="item.translate">{{item.title}}</span>
|
||||
<span class="nav-link-badge" *ngIf="item.badge" [translate]="item.badge.translate"
|
||||
[ngStyle]="{'background-color': item.badge.bg,'color': item.badge.fg}">
|
||||
{{item.badge.title}}
|
||||
</span>
|
||||
<mat-icon class="collapse-arrow">keyboard_arrow_right</mat-icon>
|
||||
</ng-template>
|
||||
|
||||
<div class="children" [ngClass]="{'open': isOpen}">
|
||||
|
||||
<div class="{{fuseSettings.colorClasses.navbar}}">
|
||||
|
||||
<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-collapse *ngIf="item.type=='collapse'"
|
||||
[item]="item"></fuse-nav-horizontal-collapse>
|
||||
<fuse-nav-horizontal-collapse *ngIf="item.type=='group'" [item]="item"></fuse-nav-horizontal-collapse>
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { Component, HostBinding, HostListener, Input, OnDestroy } from '@angular/core';
|
||||
import { fuseAnimations } from '../../../../animations/index';
|
||||
import { FuseConfigService } from '../../../../services/config.service';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-nav-horizontal-collapse',
|
||||
templateUrl: './nav-horizontal-collapse.component.html',
|
||||
styleUrls : ['./nav-horizontal-collapse.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class FuseNavHorizontalCollapseComponent implements OnDestroy
|
||||
{
|
||||
onConfigChanged: Subscription;
|
||||
fuseSettings: any;
|
||||
isOpen = false;
|
||||
|
||||
@HostBinding('class') classes = 'nav-item nav-collapse';
|
||||
@Input() item: any;
|
||||
|
||||
@HostListener('mouseenter')
|
||||
open()
|
||||
{
|
||||
this.isOpen = true;
|
||||
}
|
||||
|
||||
@HostListener('mouseleave')
|
||||
close()
|
||||
{
|
||||
this.isOpen = false;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private fuseConfig: FuseConfigService
|
||||
)
|
||||
{
|
||||
this.onConfigChanged =
|
||||
this.fuseConfig.onConfigChanged
|
||||
.subscribe(
|
||||
(newSettings) => {
|
||||
this.fuseSettings = newSettings;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
{
|
||||
this.onConfigChanged.unsubscribe();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<ng-container *ngIf="!item.hidden">
|
||||
|
||||
<!-- item.url -->
|
||||
<a class="nav-link" *ngIf="item.url" [routerLink]="[item.url]" routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.function -->
|
||||
<span class="nav-link" *ngIf="item.function" (click)="item.function()" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</span>
|
||||
|
||||
<!-- item.url && item.function -->
|
||||
<a class="nav-link" *ngIf="item.url && item.function" (click)="item.function()"
|
||||
[routerLink]="[item.url]" routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<ng-template #itemContent>
|
||||
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
|
||||
<span class="nav-link-title" [translate]="item.translate">{{item.title}}</span>
|
||||
<span class="nav-link-badge" *ngIf="item.badge" [translate]="item.badge.translate"
|
||||
[ngStyle]="{'background-color': item.badge.bg,'color': item.badge.fg}">
|
||||
{{item.badge.title}}
|
||||
</span>
|
||||
</ng-template>
|
||||
|
||||
</ng-container>
|
||||
@@ -0,0 +1,3 @@
|
||||
:host {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Component, HostBinding, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-nav-horizontal-item',
|
||||
templateUrl: './nav-horizontal-item.component.html',
|
||||
styleUrls : ['./nav-horizontal-item.component.scss']
|
||||
})
|
||||
export class FuseNavHorizontalItemComponent
|
||||
{
|
||||
@HostBinding('class') classes = 'nav-item';
|
||||
@Input() item: any;
|
||||
}
|
||||
32
src/@fuse/components/navigation/navigation.component.html
Normal file
32
src/@fuse/components/navigation/navigation.component.html
Normal file
@@ -0,0 +1,32 @@
|
||||
<div id="main-navigation" 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-collapse *ngIf="item.type=='collapse'" [item]="item"></fuse-nav-vertical-collapse>
|
||||
<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-collapse *ngIf="item.type=='group'" [item]="item"></fuse-nav-horizontal-collapse>
|
||||
<fuse-nav-horizontal-collapse *ngIf="item.type=='collapse'" [item]="item"></fuse-nav-horizontal-collapse>
|
||||
<fuse-nav-horizontal-item *ngIf="item.type=='item'" [item]="item"></fuse-nav-horizontal-item>
|
||||
|
||||
</ng-container>
|
||||
|
||||
</ng-container>
|
||||
<!-- / Horizontal Navigation Layout -->
|
||||
|
||||
</div>
|
||||
12
src/@fuse/components/navigation/navigation.component.scss
Normal file
12
src/@fuse/components/navigation/navigation.component.scss
Normal file
@@ -0,0 +1,12 @@
|
||||
@import 'src/@fuse/scss/fuse';
|
||||
|
||||
fuse-navigation {
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
|
||||
#main-navigation {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
18
src/@fuse/components/navigation/navigation.component.ts
Normal file
18
src/@fuse/components/navigation/navigation.component.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Component, Input, ViewEncapsulation } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-navigation',
|
||||
templateUrl : './navigation.component.html',
|
||||
styleUrls : ['./navigation.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class FuseNavigationComponent
|
||||
{
|
||||
@Input() layout = 'vertical';
|
||||
@Input() navigation: any;
|
||||
|
||||
constructor()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
39
src/@fuse/components/navigation/navigation.module.ts
Normal file
39
src/@fuse/components/navigation/navigation.module.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
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/nav-item/nav-vertical-item.component';
|
||||
import { FuseNavVerticalCollapseComponent } from './vertical/nav-collapse/nav-vertical-collapse.component';
|
||||
import { FuseNavVerticalGroupComponent } from './vertical/nav-group/nav-vertical-group.component';
|
||||
import { FuseNavHorizontalItemComponent } from './horizontal/nav-item/nav-horizontal-item.component';
|
||||
import { FuseNavHorizontalCollapseComponent } from './horizontal/nav-collapse/nav-horizontal-collapse.component';
|
||||
|
||||
@NgModule({
|
||||
imports : [
|
||||
CommonModule,
|
||||
RouterModule,
|
||||
|
||||
MatIconModule,
|
||||
MatRippleModule,
|
||||
|
||||
TranslateModule.forChild()
|
||||
],
|
||||
exports : [
|
||||
FuseNavigationComponent
|
||||
],
|
||||
declarations: [
|
||||
FuseNavigationComponent,
|
||||
FuseNavVerticalGroupComponent,
|
||||
FuseNavVerticalItemComponent,
|
||||
FuseNavVerticalCollapseComponent,
|
||||
FuseNavHorizontalItemComponent,
|
||||
FuseNavHorizontalCollapseComponent
|
||||
]
|
||||
})
|
||||
export class FuseNavigationModule
|
||||
{
|
||||
}
|
||||
48
src/@fuse/components/navigation/navigation.service.ts
Normal file
48
src/@fuse/components/navigation/navigation.service.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { EventEmitter, Injectable } from '@angular/core';
|
||||
import { Subject } from 'rxjs/Subject';
|
||||
|
||||
@Injectable()
|
||||
export class FuseNavigationService
|
||||
{
|
||||
flatNavigation: any[] = [];
|
||||
|
||||
onItemCollapsed: Subject<any> = new Subject;
|
||||
onItemCollapseToggled: Subject<any> = new Subject;
|
||||
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get flattened navigation array
|
||||
* @param navigation
|
||||
* @returns {any[]}
|
||||
*/
|
||||
getFlatNavigation(navigation)
|
||||
{
|
||||
for ( const navItem of navigation )
|
||||
{
|
||||
if ( navItem.type === 'item' )
|
||||
{
|
||||
this.flatNavigation.push({
|
||||
title: navItem.title,
|
||||
type : navItem.type,
|
||||
icon : navItem.icon || false,
|
||||
url : navItem.url
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( navItem.type === 'collapse' || navItem.type === 'group' )
|
||||
{
|
||||
if ( navItem.children )
|
||||
{
|
||||
this.getFlatNavigation(navItem.children);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.flatNavigation;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<ng-container *ngIf="!item.hidden">
|
||||
|
||||
<!-- normal collapse -->
|
||||
<a class="nav-link" *ngIf="!item.url && !item.function" (click)="toggleOpen($event)" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.url -->
|
||||
<a class="nav-link" *ngIf="item.url && !item.function" (click)="toggleOpen($event)"
|
||||
[routerLink]="[item.url]" routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.function -->
|
||||
<span class="nav-link" *ngIf="!item.url && item.function" (click)="toggleOpen($event);item.function()" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</span>
|
||||
|
||||
<!-- item.url && item.function -->
|
||||
<a class="nav-link" *ngIf="item.url && item.function" (click)="toggleOpen($event);item.function()"
|
||||
[routerLink]="[item.url]" routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<ng-template #itemContent>
|
||||
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
|
||||
<span class="nav-link-title" [translate]="item.translate">{{item.title}}</span>
|
||||
<span class="nav-link-badge" *ngIf="item.badge" [translate]="item.badge.translate"
|
||||
[ngStyle]="{'background-color': item.badge.bg,'color': item.badge.fg}">
|
||||
{{item.badge.title}}
|
||||
</span>
|
||||
<mat-icon class="collapse-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-collapse *ngIf="item.type=='collapse'" [item]="item"></fuse-nav-vertical-collapse>
|
||||
<fuse-nav-vertical-group *ngIf="item.type=='group'" [item]="item"></fuse-nav-vertical-group>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
@@ -1,6 +1,7 @@
|
||||
:host {
|
||||
|
||||
.folded:not(.folded-open) & {
|
||||
.folded:not(.unfolded) & {
|
||||
|
||||
.nav-link {
|
||||
|
||||
> span {
|
||||
@@ -8,9 +9,17 @@
|
||||
transition: opacity 200ms ease;
|
||||
}
|
||||
}
|
||||
|
||||
&.open {
|
||||
|
||||
.children {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
|
||||
.collapse-arrow {
|
||||
transition: transform .3s ease-in-out, opacity .25s ease-in-out .1s;
|
||||
transform: rotate(0);
|
||||
@@ -0,0 +1,193 @@
|
||||
import { Component, HostBinding, Input, OnInit } from '@angular/core';
|
||||
import { FuseNavigationService } from '../../navigation.service';
|
||||
import { NavigationEnd, Router } from '@angular/router';
|
||||
import { fuseAnimations } from '../../../../animations/index';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-nav-vertical-collapse',
|
||||
templateUrl: './nav-vertical-collapse.component.html',
|
||||
styleUrls : ['./nav-vertical-collapse.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class FuseNavVerticalCollapseComponent implements OnInit
|
||||
{
|
||||
@Input() item: any;
|
||||
@HostBinding('class') classes = 'nav-collapse nav-item';
|
||||
@HostBinding('class.open') public isOpen = false;
|
||||
|
||||
constructor(
|
||||
private navigationService: FuseNavigationService,
|
||||
private router: Router
|
||||
)
|
||||
{
|
||||
// Listen for route changes
|
||||
router.events.subscribe(
|
||||
(event) => {
|
||||
if ( event instanceof 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.navigationService.onItemCollapsed
|
||||
.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();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle collapse
|
||||
*
|
||||
* @param ev
|
||||
*/
|
||||
toggleOpen(ev)
|
||||
{
|
||||
ev.preventDefault();
|
||||
|
||||
this.isOpen = !this.isOpen;
|
||||
|
||||
// Navigation collapse toggled...
|
||||
this.navigationService.onItemCollapsed.next(this.item);
|
||||
this.navigationService.onItemCollapseToggled.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand the collapsable navigation
|
||||
*/
|
||||
expand()
|
||||
{
|
||||
if ( this.isOpen )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.isOpen = true;
|
||||
this.navigationService.onItemCollapseToggled.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Collapse the collapsable navigation
|
||||
*/
|
||||
collapse()
|
||||
{
|
||||
if ( !this.isOpen )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.isOpen = false;
|
||||
this.navigationService.onItemCollapseToggled.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given parent has the
|
||||
* given item in one of its children
|
||||
*
|
||||
* @param parent
|
||||
* @param item
|
||||
* @return {any}
|
||||
*/
|
||||
isChildrenOf(parent, item)
|
||||
{
|
||||
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 {any}
|
||||
*/
|
||||
isUrlInChildren(parent, url)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<ng-container *ngIf="!item.hidden">
|
||||
|
||||
<div class="group-title">
|
||||
<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-collapse *ngIf="item.type=='collapse'" [item]="item"></fuse-nav-vertical-collapse>
|
||||
<fuse-nav-vertical-item *ngIf="item.type=='item'" [item]="item"></fuse-nav-vertical-item>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
@@ -0,0 +1,23 @@
|
||||
:host {
|
||||
|
||||
.folded:not(.unfolded) & {
|
||||
|
||||
> .group-title {
|
||||
align-items: center;
|
||||
|
||||
> span {
|
||||
opacity: 0;
|
||||
transition: opacity 200ms ease;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
min-width: 1.6rem;
|
||||
border-top: 2px solid;
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Component, HostBinding, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-nav-vertical-group',
|
||||
templateUrl: './nav-vertical-group.component.html',
|
||||
styleUrls : ['./nav-vertical-group.component.scss']
|
||||
})
|
||||
export class FuseNavVerticalGroupComponent
|
||||
{
|
||||
@HostBinding('class') classes = 'nav-group nav-item';
|
||||
@Input() item: any;
|
||||
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<ng-container *ngIf="!item.hidden">
|
||||
|
||||
<!-- item.url -->
|
||||
<a class="nav-link" *ngIf="item.url && !item.function"
|
||||
[routerLink]="[item.url]" routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<!-- item.function -->
|
||||
<span class="nav-link" *ngIf="!item.url && item.function" (click)="item.function()" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</span>
|
||||
|
||||
<!-- item.url && item.function -->
|
||||
<a class="nav-link" *ngIf="item.url && item.function" (click)="item.function()"
|
||||
[routerLink]="[item.url]" routerLinkActive="active"
|
||||
[routerLinkActiveOptions]="{exact: item.exactMatch || false}" matRipple>
|
||||
<ng-container *ngTemplateOutlet="itemContent"></ng-container>
|
||||
</a>
|
||||
|
||||
<ng-template #itemContent>
|
||||
<mat-icon class="nav-link-icon" *ngIf="item.icon">{{item.icon}}</mat-icon>
|
||||
<span class="nav-link-title" [translate]="item.translate">{{item.title}}</span>
|
||||
<span class="nav-link-badge" *ngIf="item.badge" [translate]="item.badge.translate"
|
||||
[ngStyle]="{'background-color': item.badge.bg,'color': item.badge.fg}">
|
||||
{{item.badge.title}}
|
||||
</span>
|
||||
</ng-template>
|
||||
|
||||
</ng-container>
|
||||
@@ -1,6 +1,6 @@
|
||||
:host {
|
||||
|
||||
.folded:not(.folded-open) & {
|
||||
.folded:not(.unfolded) & {
|
||||
|
||||
.nav-link {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Component, HostBinding, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-nav-vertical-item',
|
||||
templateUrl: './nav-vertical-item.component.html',
|
||||
styleUrls : ['./nav-vertical-item.component.scss']
|
||||
})
|
||||
export class FuseNavVerticalItemComponent
|
||||
{
|
||||
@HostBinding('class') classes = 'nav-item';
|
||||
@Input() item: any;
|
||||
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
}
|
||||
25
src/@fuse/components/search-bar/search-bar.component.html
Normal file
25
src/@fuse/components/search-bar/search-bar.component.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<div class="fuse-search-bar" [ngClass]="{'expanded':!collapsed}">
|
||||
|
||||
<div class="fuse-search-bar-content" [ngClass]="toolbarColor">
|
||||
|
||||
<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">search</mat-icon>
|
||||
</button>
|
||||
<!--<span class="fuse-search-bar-loader" fxLayout="row" fxLayoutAlign="center center" *ngIf="!collapsed">
|
||||
<mat-progress-spinner color="mat-accent" mode="indeterminate"></mat-progress-spinner>
|
||||
</span>-->
|
||||
</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">close</mat-icon>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
91
src/@fuse/components/search-bar/search-bar.component.scss
Normal file
91
src/@fuse/components/search-bar/search-bar.component.scss
Normal file
@@ -0,0 +1,91 @@
|
||||
@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('sm') {
|
||||
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('sm') {
|
||||
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('sm') {
|
||||
height: 56px !important;
|
||||
line-height: 56px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.fuse-search-bar-collapser {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#fuse-search-bar-input {
|
||||
display: none;
|
||||
flex: 1 0 auto;
|
||||
min-height: 64px;
|
||||
background-color: transparent;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&.expanded {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
|
||||
.fuse-search-bar-content {
|
||||
|
||||
#fuse-search-bar-input {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.fuse-search-bar-collapser {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
|
||||
&.fuse-search-bar-expanded {
|
||||
|
||||
#toolbar {
|
||||
z-index: 999 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,27 @@
|
||||
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
|
||||
import { FuseConfigService } from '../../services/config.service';
|
||||
import { Component, EventEmitter, Output } from '@angular/core';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
|
||||
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
|
||||
export class FuseSearchBarComponent
|
||||
{
|
||||
collapsed: boolean;
|
||||
toolbarColor: string;
|
||||
@Output() onInput: EventEmitter<any> = new EventEmitter();
|
||||
onSettingsChanged: Subscription;
|
||||
onConfigChanged: Subscription;
|
||||
|
||||
constructor(
|
||||
private fuseConfig: FuseConfigService
|
||||
)
|
||||
{
|
||||
this.collapsed = true;
|
||||
this.onSettingsChanged =
|
||||
this.fuseConfig.onSettingsChanged
|
||||
this.onConfigChanged =
|
||||
this.fuseConfig.onConfigChanged
|
||||
.subscribe(
|
||||
(newSettings) => {
|
||||
this.toolbarColor = newSettings.colorClasses.toolbar;
|
||||
@@ -28,11 +29,6 @@ export class FuseSearchBarComponent implements OnInit
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
collapse()
|
||||
{
|
||||
this.collapsed = true;
|
||||
@@ -1,7 +1,9 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { SharedModule } from '../../modules/shared.module';
|
||||
import { MatButtonModule, MatIconModule } from '@angular/material';
|
||||
|
||||
import { FuseSearchBarComponent } from './search-bar.component';
|
||||
|
||||
@NgModule({
|
||||
@@ -9,8 +11,11 @@ import { FuseSearchBarComponent } from './search-bar.component';
|
||||
FuseSearchBarComponent
|
||||
],
|
||||
imports : [
|
||||
SharedModule,
|
||||
RouterModule
|
||||
CommonModule,
|
||||
RouterModule,
|
||||
|
||||
MatButtonModule,
|
||||
MatIconModule
|
||||
],
|
||||
exports : [
|
||||
FuseSearchBarComponent
|
||||
113
src/@fuse/components/shortcuts/shortcuts.component.html
Normal file
113
src/@fuse/components/shortcuts/shortcuts.component.html
Normal file
@@ -0,0 +1,113 @@
|
||||
<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 [ngClass]="toolbarColor">
|
||||
|
||||
<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,4 +1,4 @@
|
||||
@import 'src/app/core/scss/fuse';
|
||||
@import 'src/@fuse/scss/fuse';
|
||||
|
||||
:host {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { Component, ElementRef, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core';
|
||||
import { FuseNavigationService } from '../navigation/navigation.service';
|
||||
import { Component, ElementRef, Input, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { ObservableMedia } from '@angular/flex-layout';
|
||||
import { FuseMatchMedia } from '../../services/match-media.service';
|
||||
import { FuseConfigService } from '../../services/config.service';
|
||||
import { CookieService } from 'ngx-cookie-service';
|
||||
|
||||
import { FuseMatchMediaService } from '@fuse/services/match-media.service';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
import { FuseConfigService } from '@fuse/services/config.service';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-shortcuts',
|
||||
templateUrl: './shortcuts.component.html',
|
||||
@@ -20,7 +21,9 @@ export class FuseShortcutsComponent implements OnInit, OnDestroy
|
||||
mobileShortcutsPanelActive = false;
|
||||
toolbarColor: string;
|
||||
matchMediaSubscription: Subscription;
|
||||
onSettingsChanged: Subscription;
|
||||
onConfigChanged: Subscription;
|
||||
|
||||
@Input() navigation: any;
|
||||
|
||||
@ViewChild('searchInput') searchInputField;
|
||||
@ViewChild('shortcuts') shortcutsEl: ElementRef;
|
||||
@@ -28,16 +31,14 @@ export class FuseShortcutsComponent implements OnInit, OnDestroy
|
||||
constructor(
|
||||
private renderer: Renderer2,
|
||||
private observableMedia: ObservableMedia,
|
||||
private fuseMatchMedia: FuseMatchMedia,
|
||||
private fuseMatchMedia: FuseMatchMediaService,
|
||||
private fuseNavigationService: FuseNavigationService,
|
||||
private fuseConfig: FuseConfigService,
|
||||
private cookieService: CookieService
|
||||
)
|
||||
{
|
||||
this.filteredNavigationItems = this.navigationItems = this.fuseNavigationService.getFlatNavigation();
|
||||
|
||||
this.onSettingsChanged =
|
||||
this.fuseConfig.onSettingsChanged
|
||||
this.onConfigChanged =
|
||||
this.fuseConfig.onConfigChanged
|
||||
.subscribe(
|
||||
(newSettings) => {
|
||||
this.toolbarColor = newSettings.colorClasses.toolbar;
|
||||
@@ -47,6 +48,9 @@ export class FuseShortcutsComponent implements OnInit, OnDestroy
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
// 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 )
|
||||
@@ -149,7 +153,9 @@ export class FuseShortcutsComponent implements OnInit, OnDestroy
|
||||
|
||||
onMenuOpen()
|
||||
{
|
||||
this.searchInputField.nativeElement.focus();
|
||||
setTimeout(() => {
|
||||
this.searchInputField.nativeElement.focus();
|
||||
});
|
||||
}
|
||||
|
||||
showMobileShortcutsPanel()
|
||||
38
src/@fuse/components/shortcuts/shortcuts.module.ts
Normal file
38
src/@fuse/components/shortcuts/shortcuts.module.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
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
src/@fuse/components/sidebar/sidebar.component.html
Normal file
1
src/@fuse/components/sidebar/sidebar.component.html
Normal file
@@ -0,0 +1 @@
|
||||
<ng-content></ng-content>
|
||||
60
src/@fuse/components/sidebar/sidebar.component.scss
Normal file
60
src/@fuse/components/sidebar/sidebar.component.scss
Normal file
@@ -0,0 +1,60 @@
|
||||
fuse-sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 0 auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
width: 280px;
|
||||
min-width: 280px;
|
||||
max-width: 280px;
|
||||
z-index: 1000;
|
||||
transition-property: transform, width, min-width, max-width;
|
||||
transition-duration: 150ms;
|
||||
transition-timing-function: ease-in-out;
|
||||
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.35);
|
||||
|
||||
&.left-aligned {
|
||||
left: 0;
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
&.right-aligned {
|
||||
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;
|
||||
|
||||
&:not(.unfolded) {
|
||||
width: 64px;
|
||||
min-width: 64px;
|
||||
max-width: 64px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fuse-sidebar-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 3;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
opacity: 0;
|
||||
}
|
||||
442
src/@fuse/components/sidebar/sidebar.component.ts
Normal file
442
src/@fuse/components/sidebar/sidebar.component.ts
Normal file
@@ -0,0 +1,442 @@
|
||||
import { Component, ElementRef, HostBinding, HostListener, Input, OnDestroy, OnInit, Renderer2, ViewEncapsulation } from '@angular/core';
|
||||
import { animate, AnimationBuilder, AnimationPlayer, style } from '@angular/animations';
|
||||
import { ObservableMedia } from '@angular/flex-layout';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
|
||||
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;
|
||||
|
||||
// Align
|
||||
@Input()
|
||||
align: 'left' | 'right';
|
||||
|
||||
// Open
|
||||
@HostBinding('class.open')
|
||||
opened: boolean;
|
||||
|
||||
// Locked Open
|
||||
@Input()
|
||||
lockedOpen: string;
|
||||
|
||||
// isLockedOpen
|
||||
@HostBinding('class.locked-open')
|
||||
isLockedOpen: boolean;
|
||||
|
||||
// Folded
|
||||
@HostBinding('class.folded')
|
||||
@Input()
|
||||
set folded(value: boolean)
|
||||
{
|
||||
// Only work if the sidebar is not closed
|
||||
if ( !this.opened )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the folded
|
||||
this._folded = value;
|
||||
|
||||
// Programmatically add/remove margin to the element
|
||||
// that comes after or before based on the alignment
|
||||
let sibling,
|
||||
styleRule;
|
||||
|
||||
const styleValue = '64px';
|
||||
|
||||
// Get the sibling and set the style rule
|
||||
if ( this.align === 'left' )
|
||||
{
|
||||
sibling = this.elementRef.nativeElement.nextElementSibling;
|
||||
styleRule = 'marginLeft';
|
||||
}
|
||||
else
|
||||
{
|
||||
sibling = this.elementRef.nativeElement.previousElementSibling;
|
||||
styleRule = 'marginRight';
|
||||
}
|
||||
|
||||
// If there is no sibling, return...
|
||||
if ( !sibling )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If folded...
|
||||
if ( value )
|
||||
{
|
||||
// Set the style
|
||||
this.renderer.setStyle(sibling, styleRule, styleValue);
|
||||
}
|
||||
// If unfolded...
|
||||
else
|
||||
{
|
||||
// Remove the style
|
||||
this.renderer.removeStyle(sibling, styleRule);
|
||||
}
|
||||
}
|
||||
|
||||
get folded(): boolean
|
||||
{
|
||||
return this._folded;
|
||||
}
|
||||
|
||||
// Folded unfolded
|
||||
@HostBinding('class.unfolded')
|
||||
unfolded: boolean;
|
||||
|
||||
// Private
|
||||
private _folded: boolean;
|
||||
private _wasActive: boolean;
|
||||
private _backdrop: HTMLElement | null = null;
|
||||
private _player: AnimationPlayer;
|
||||
private _onMediaChangeSubscription: Subscription;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {Renderer2} renderer
|
||||
* @param {ElementRef} elementRef
|
||||
* @param {AnimationBuilder} animationBuilder
|
||||
* @param {ObservableMedia} observableMedia
|
||||
* @param {FuseConfigService} fuseConfigService
|
||||
* @param {FuseSidebarService} fuseSidebarService
|
||||
* @param {FuseMatchMediaService} fuseMatchMediaService
|
||||
*/
|
||||
constructor(
|
||||
private renderer: Renderer2,
|
||||
private elementRef: ElementRef,
|
||||
private animationBuilder: AnimationBuilder,
|
||||
private observableMedia: ObservableMedia,
|
||||
private fuseConfigService: FuseConfigService,
|
||||
private fuseSidebarService: FuseSidebarService,
|
||||
private fuseMatchMediaService: FuseMatchMediaService
|
||||
)
|
||||
{
|
||||
// Set the defaults
|
||||
this.opened = false;
|
||||
this.folded = false;
|
||||
this.align = 'left';
|
||||
}
|
||||
|
||||
/**
|
||||
* On init
|
||||
*/
|
||||
ngOnInit(): void
|
||||
{
|
||||
// Register the sidebar
|
||||
this.fuseSidebarService.register(this.name, this);
|
||||
|
||||
// Setup alignment
|
||||
this._setupAlignment();
|
||||
|
||||
// Setup lockedOpen
|
||||
this._setupLockedOpen();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 the media watcher subscription
|
||||
this._onMediaChangeSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the sidebar alignment
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _setupAlignment(): void
|
||||
{
|
||||
// Add the correct class name to the sidebar
|
||||
// element depending on the align attribute
|
||||
if ( this.align === 'right' )
|
||||
{
|
||||
this.renderer.addClass(this.elementRef.nativeElement, 'right-aligned');
|
||||
}
|
||||
else
|
||||
{
|
||||
this.renderer.addClass(this.elementRef.nativeElement, 'left-aligned');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the lockedOpen handler
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private _setupLockedOpen(): void
|
||||
{
|
||||
// Return if the lockedOpen wasn't set
|
||||
if ( !this.lockedOpen )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the wasActive for the first time
|
||||
this._wasActive = false;
|
||||
|
||||
// Act on every media change
|
||||
this._onMediaChangeSubscription =
|
||||
|
||||
this.fuseMatchMediaService.onMediaChange.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;
|
||||
|
||||
// Force the the opened status to true
|
||||
this.opened = true;
|
||||
|
||||
// Read the folded setting from the config
|
||||
// and fold the sidebar if it's true
|
||||
if ( this.fuseConfigService.config.layout.navigationFolded )
|
||||
{
|
||||
this.fold();
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Store the new active status
|
||||
this._wasActive = isActive;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the sidebar
|
||||
*/
|
||||
open(): void
|
||||
{
|
||||
if ( this.opened || this.isLockedOpen )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Show the backdrop
|
||||
this.showBackdrop();
|
||||
|
||||
// Set the opened status
|
||||
this.opened = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the sidebar
|
||||
*/
|
||||
close(): void
|
||||
{
|
||||
if ( !this.opened || this.isLockedOpen )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Hide the backdrop
|
||||
this.hideBackdrop();
|
||||
|
||||
// Set the opened status
|
||||
this.opened = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle open/close the sidebar
|
||||
*/
|
||||
toggleOpen(): void
|
||||
{
|
||||
if ( this.opened )
|
||||
{
|
||||
this.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.open();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mouseenter
|
||||
*/
|
||||
@HostListener('mouseenter')
|
||||
onMouseEnter(): void
|
||||
{
|
||||
// Only work if the sidebar is folded
|
||||
if ( !this.folded )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Unfold the sidebar temporarily
|
||||
this.unfolded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mouseleave
|
||||
*/
|
||||
@HostListener('mouseleave')
|
||||
onMouseLeave(): void
|
||||
{
|
||||
// Only work if the sidebar is folded
|
||||
if ( !this.folded )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Fold the sidebar back
|
||||
this.unfolded = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fold the sidebar permanently
|
||||
*/
|
||||
fold(): void
|
||||
{
|
||||
// Only work if the sidebar is not folded
|
||||
if ( this.folded )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Fold
|
||||
this.folded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unfold the sidebar permanently
|
||||
*/
|
||||
unfold(): void
|
||||
{
|
||||
// Only work if the sidebar is folded
|
||||
if ( !this.folded )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Unfold
|
||||
this.folded = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the sidebar fold/unfold permanently
|
||||
*/
|
||||
toggleFold(): void
|
||||
{
|
||||
if ( this.folded )
|
||||
{
|
||||
this.unfold();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.fold();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the backdrop
|
||||
*/
|
||||
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');
|
||||
|
||||
// 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();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the backdrop
|
||||
*/
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
15
src/@fuse/components/sidebar/sidebar.module.ts
Normal file
15
src/@fuse/components/sidebar/sidebar.module.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { FuseSidebarComponent } from './sidebar.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
FuseSidebarComponent
|
||||
],
|
||||
exports : [
|
||||
FuseSidebarComponent
|
||||
]
|
||||
})
|
||||
export class FuseSidebarModule
|
||||
{
|
||||
}
|
||||
75
src/@fuse/components/sidebar/sidebar.service.ts
Normal file
75
src/@fuse/components/sidebar/sidebar.service.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { FuseSidebarComponent } from './sidebar.component';
|
||||
|
||||
@Injectable()
|
||||
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];
|
||||
}
|
||||
}
|
||||
105
src/@fuse/components/theme-options/theme-options.component.html
Normal file
105
src/@fuse/components/theme-options/theme-options.component.html
Normal file
@@ -0,0 +1,105 @@
|
||||
<button #openButton mat-icon-button class="open-button mat-primary-bg mat-elevation-z2" (click)="openBar()">
|
||||
<mat-icon>settings</mat-icon>
|
||||
</button>
|
||||
|
||||
<div class="theme-options-panel-overlay" #overlay [fxHide]="barClosed" [@fadeInOut]="!barClosed"></div>
|
||||
|
||||
<div #panel class="theme-options-panel mat-white-bg mat-elevation-z8">
|
||||
|
||||
<button mat-icon-button class="close-button" (click)="closeBar()">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
|
||||
<div class="theme-options-panel-inner" fxLayout="column" fxLayoutAlign="start start">
|
||||
|
||||
<h3>Navigation:</h3>
|
||||
<mat-radio-group [(ngModel)]="config.layout.navigation" (ngModelChange)="onSettingsChange()"
|
||||
fxLayout="column" fxLayout.gt-xs="row wrap" fxLayoutAlign="start start">
|
||||
<mat-radio-button class="mr-8 mb-8" value="top">Top</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="left">Left</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="right">Right</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="none">None</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
<h3>Navigation Fold (for vertical navigation):</h3>
|
||||
<mat-slide-toggle [(ngModel)]="config.layout.navigationFolded"
|
||||
(change)="onSettingsChange()">
|
||||
Folded
|
||||
</mat-slide-toggle>
|
||||
|
||||
<h3 class="mt-24">Toolbar:</h3>
|
||||
<mat-radio-group [(ngModel)]="config.layout.toolbar" (ngModelChange)="onSettingsChange()"
|
||||
fxLayout="column" fxLayout.gt-xs="row wrap" fxLayoutAlign="start start">
|
||||
<mat-radio-button class="mr-8 mb-8" value="below">Below</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="above">Above</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="none">None</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
<h3 class="mt-24">Footer:</h3>
|
||||
<mat-radio-group [(ngModel)]="config.layout.footer" (ngModelChange)="onSettingsChange()"
|
||||
fxLayout="column" fxLayout.gt-xs="row wrap" fxLayoutAlign="start start">
|
||||
<mat-radio-button class="mr-8 mb-8" value="below">Below</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="above">Above</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="none">None</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
<h3 class="mt-24">Layout Mode:</h3>
|
||||
<mat-radio-group [(ngModel)]="config.layout.mode" (ngModelChange)="onSettingsChange()"
|
||||
fxLayout="column" fxLayout.gt-xs="row wrap" fxLayoutAlign="start start">
|
||||
<mat-radio-button class="mr-8 mb-8" value="boxed">Boxed</mat-radio-button>
|
||||
<mat-radio-button class="mr-8 mb-8" value="fullwidth">Fullwidth</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<h3>Colors:</h3>
|
||||
<div class="colors">
|
||||
|
||||
<div fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<h4 class="mr-8">Toolbar Color</h4>
|
||||
<fuse-material-color-picker [(selectedClass)]="config.colorClasses.toolbar"
|
||||
(onValueChange)="onSettingsChange()"></fuse-material-color-picker>
|
||||
</div>
|
||||
|
||||
<div fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<h4 class="mr-8">Navigation Bar Color</h4>
|
||||
<fuse-material-color-picker [(selectedClass)]="config.colorClasses.navbar"
|
||||
(onValueChange)="onSettingsChange()"></fuse-material-color-picker>
|
||||
</div>
|
||||
|
||||
<div fxFlex fxLayout="row" fxLayoutAlign="space-between center">
|
||||
<h4 class="mr-8">Footer Color</h4>
|
||||
<fuse-material-color-picker [(selectedClass)]="config.colorClasses.footer"
|
||||
(onValueChange)="onSettingsChange()"></fuse-material-color-picker>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<h3>Router Animation:</h3>
|
||||
<mat-form-field class="w-100-p">
|
||||
<mat-select class="p-0" [(ngModel)]="config.routerAnimation">
|
||||
<mat-option value="none">
|
||||
None
|
||||
</mat-option>
|
||||
<mat-option value="slideUp">
|
||||
Slide up
|
||||
</mat-option>
|
||||
<mat-option value="slideDown">
|
||||
Slide down
|
||||
</mat-option>
|
||||
<mat-option value="slideRight">
|
||||
Slide right
|
||||
</mat-option>
|
||||
<mat-option value="slideLeft">
|
||||
Slide left
|
||||
</mat-option>
|
||||
<mat-option value="fadeIn">
|
||||
Fade in
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
115
src/@fuse/components/theme-options/theme-options.component.scss
Normal file
115
src/@fuse/components/theme-options/theme-options.component.scss
Normal file
@@ -0,0 +1,115 @@
|
||||
@import "src/@fuse/scss/fuse";
|
||||
|
||||
@keyframes rotating {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
:host {
|
||||
position: fixed;
|
||||
display: block;
|
||||
right: 0;
|
||||
top: 160px;
|
||||
z-index: 998;
|
||||
|
||||
&.bar-closed .theme-options-panel {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.theme-options-panel {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 360px;
|
||||
transform: translate3d(100%, 0, 0);
|
||||
z-index: 999;
|
||||
max-height: calc(100vh - 200px);
|
||||
padding: 24px;
|
||||
overflow: auto;
|
||||
|
||||
@include media-breakpoint-down('xs') {
|
||||
top: -120px;
|
||||
max-height: calc(100vh - 100px);
|
||||
width: 90vw;
|
||||
}
|
||||
|
||||
.close-button {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
|
||||
.mat-divider {
|
||||
display: block !important;
|
||||
width: 100%;
|
||||
margin: 24px 0 16px 0;
|
||||
}
|
||||
|
||||
.colors {
|
||||
display: block !important;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.theme-options-panel-overlay {
|
||||
position: fixed;
|
||||
display: block;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 998;
|
||||
|
||||
@include media-breakpoint-down('sm') {
|
||||
background: rgba(0, 0, 0, 0.37);
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-list .mat-list-item {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.mat-divider {
|
||||
margin: 16px;
|
||||
}
|
||||
|
||||
.open-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -48px;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
border-radius: 0;
|
||||
margin: 0;
|
||||
pointer-events: auto;
|
||||
opacity: .75;
|
||||
z-index: 998;
|
||||
|
||||
mat-icon {
|
||||
animation: rotating 3s linear infinite;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
114
src/@fuse/components/theme-options/theme-options.component.ts
Normal file
114
src/@fuse/components/theme-options/theme-options.component.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
import { Component, ElementRef, HostBinding, Input, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core';
|
||||
import { style, animate, AnimationBuilder, AnimationPlayer } from '@angular/animations';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
|
||||
import { fuseAnimations } from '@fuse/animations';
|
||||
import { FuseConfigService } from '@fuse/services/config.service';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-theme-options',
|
||||
templateUrl: './theme-options.component.html',
|
||||
styleUrls : ['./theme-options.component.scss'],
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class FuseThemeOptionsComponent implements OnInit, OnDestroy
|
||||
{
|
||||
@Input() navigation;
|
||||
@ViewChild('openButton') openButton;
|
||||
@ViewChild('panel') panel;
|
||||
@ViewChild('overlay') overlay: ElementRef;
|
||||
|
||||
public player: AnimationPlayer;
|
||||
config: any;
|
||||
|
||||
onConfigChanged: Subscription;
|
||||
|
||||
@HostBinding('class.bar-closed') barClosed: boolean;
|
||||
|
||||
constructor(
|
||||
private animationBuilder: AnimationBuilder,
|
||||
private fuseConfig: FuseConfigService,
|
||||
private navigationService: FuseNavigationService,
|
||||
private renderer: Renderer2
|
||||
)
|
||||
{
|
||||
this.barClosed = true;
|
||||
|
||||
this.onConfigChanged =
|
||||
this.fuseConfig.onConfigChanged
|
||||
.subscribe(
|
||||
(newConfig) => {
|
||||
this.config = newConfig;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
this.renderer.listen(this.overlay.nativeElement, 'click', () => {
|
||||
this.closeBar();
|
||||
});
|
||||
|
||||
// Get the nav model and add customize nav item
|
||||
// that opens the bar programmatically
|
||||
const nav: any = this.navigation;
|
||||
|
||||
nav.push({
|
||||
'id' : 'custom-function',
|
||||
'title' : 'Custom Function',
|
||||
'type' : 'group',
|
||||
'children': [
|
||||
{
|
||||
'id' : 'customize',
|
||||
'title' : 'Customize',
|
||||
'type' : 'item',
|
||||
'icon' : 'settings',
|
||||
'function': () => {
|
||||
this.openBar();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
{
|
||||
this.onConfigChanged.unsubscribe();
|
||||
}
|
||||
|
||||
onSettingsChange()
|
||||
{
|
||||
this.fuseConfig.setConfig(this.config);
|
||||
}
|
||||
|
||||
closeBar()
|
||||
{
|
||||
this.player =
|
||||
this.animationBuilder
|
||||
.build([
|
||||
style({transform: 'translate3d(0,0,0)'}),
|
||||
animate('400ms ease', style({transform: 'translate3d(100%,0,0)'}))
|
||||
]).create(this.panel.nativeElement);
|
||||
|
||||
this.player.play();
|
||||
|
||||
this.player.onDone(() => {
|
||||
this.barClosed = true;
|
||||
});
|
||||
}
|
||||
|
||||
openBar()
|
||||
{
|
||||
this.barClosed = false;
|
||||
|
||||
this.player =
|
||||
this.animationBuilder
|
||||
.build([
|
||||
style({transform: 'translate3d(100%,0,0)'}),
|
||||
animate('400ms ease', style({transform: 'translate3d(0,0,0)'}))
|
||||
]).create(this.panel.nativeElement);
|
||||
|
||||
this.player.play();
|
||||
}
|
||||
}
|
||||
37
src/@fuse/components/theme-options/theme-options.module.ts
Normal file
37
src/@fuse/components/theme-options/theme-options.module.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { MatButtonModule, MatDividerModule, MatFormFieldModule, MatIconModule, MatOptionModule, MatRadioModule, MatSelectModule, MatSlideToggleModule } from '@angular/material';
|
||||
|
||||
import { FuseMaterialColorPickerModule } from '@fuse/components/material-color-picker/material-color-picker.module';
|
||||
import { FuseThemeOptionsComponent } from '@fuse/components/theme-options/theme-options.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
FuseThemeOptionsComponent
|
||||
],
|
||||
imports : [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
|
||||
FlexLayoutModule,
|
||||
|
||||
MatButtonModule,
|
||||
MatDividerModule,
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
MatOptionModule,
|
||||
MatRadioModule,
|
||||
MatSelectModule,
|
||||
MatSlideToggleModule,
|
||||
|
||||
FuseMaterialColorPickerModule
|
||||
],
|
||||
exports : [
|
||||
FuseThemeOptionsComponent
|
||||
]
|
||||
})
|
||||
export class FuseThemeOptionsModule
|
||||
{
|
||||
}
|
||||
11
src/@fuse/components/widget/widget-toggle.directive.ts
Normal file
11
src/@fuse/components/widget/widget-toggle.directive.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Directive, ElementRef } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[fuseWidgetToggle]'
|
||||
})
|
||||
export class FuseWidgetToggleDirective
|
||||
{
|
||||
constructor(public el: ElementRef)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -62,4 +62,23 @@ fuse-widget {
|
||||
transform: rotateY(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.mat-form-field {
|
||||
|
||||
&.mat-form-field-type-mat-select {
|
||||
|
||||
.mat-form-field-wrapper {
|
||||
padding: 16px 0;
|
||||
|
||||
.mat-form-field-infix {
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-form-field-underline {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AfterContentInit, Component, ContentChildren, ElementRef, HostBinding, OnInit, QueryList, Renderer2, ViewEncapsulation } from '@angular/core';
|
||||
import { AfterContentInit, Component, ContentChildren, ElementRef, HostBinding, QueryList, Renderer2, ViewEncapsulation } from '@angular/core';
|
||||
import { FuseWidgetToggleDirective } from './widget-toggle.directive';
|
||||
|
||||
@Component({
|
||||
@@ -8,7 +8,7 @@ import { FuseWidgetToggleDirective } from './widget-toggle.directive';
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
|
||||
export class FuseWidgetComponent implements OnInit, AfterContentInit
|
||||
export class FuseWidgetComponent implements AfterContentInit
|
||||
{
|
||||
@HostBinding('class.flipped') flipped = false;
|
||||
@ContentChildren(FuseWidgetToggleDirective, {descendants: true}) toggleButtons: QueryList<FuseWidgetToggleDirective>;
|
||||
@@ -17,17 +17,14 @@ export class FuseWidgetComponent implements OnInit, AfterContentInit
|
||||
{
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ngAfterContentInit()
|
||||
{
|
||||
setTimeout(() => {
|
||||
|
||||
this.toggleButtons.forEach(flipButton => {
|
||||
this.renderer.listen(flipButton.el.nativeElement, 'click', () => {
|
||||
this.renderer.listen(flipButton.el.nativeElement, 'click', (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.toggle();
|
||||
});
|
||||
});
|
||||
@@ -1,20 +1,17 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { SharedModule } from '../../modules/shared.module';
|
||||
|
||||
import { FuseWidgetComponent } from './widget.component';
|
||||
import { FuseWidgetToggleDirective } from './widget-toggle.directive';
|
||||
|
||||
@NgModule({
|
||||
imports : [
|
||||
SharedModule
|
||||
declarations: [
|
||||
FuseWidgetComponent,
|
||||
FuseWidgetToggleDirective
|
||||
],
|
||||
exports : [
|
||||
FuseWidgetComponent,
|
||||
FuseWidgetToggleDirective
|
||||
],
|
||||
declarations: [
|
||||
FuseWidgetComponent,
|
||||
FuseWidgetToggleDirective
|
||||
]
|
||||
})
|
||||
export class FuseWidgetModule
|
||||
{
|
||||
24
src/@fuse/directives/directives.ts
Normal file
24
src/@fuse/directives/directives.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { FuseIfOnDomDirective } from '@fuse/directives/fuse-if-on-dom/fuse-if-on-dom.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,
|
||||
FuseMatSidenavHelperDirective,
|
||||
FuseMatSidenavTogglerDirective,
|
||||
FusePerfectScrollbarDirective
|
||||
],
|
||||
imports : [],
|
||||
exports : [
|
||||
FuseIfOnDomDirective,
|
||||
FuseMatSidenavHelperDirective,
|
||||
FuseMatSidenavTogglerDirective,
|
||||
FusePerfectScrollbarDirective
|
||||
]
|
||||
})
|
||||
export class FuseDirectivesModule
|
||||
{
|
||||
}
|
||||
@@ -21,7 +21,7 @@ export class FuseIfOnDomDirective implements AfterContentChecked
|
||||
{
|
||||
setTimeout(() => {
|
||||
this.viewContainer.createEmbeddedView(this.templateRef);
|
||||
}, 0);
|
||||
}, 300);
|
||||
this.isCreated = true;
|
||||
}
|
||||
else if ( this.isCreated && !document.body.contains(this.element.nativeElement) )
|
||||
@@ -0,0 +1,83 @@
|
||||
import { Directive, Input, OnInit, HostListener, OnDestroy, HostBinding } from '@angular/core';
|
||||
import { MatSidenav } from '@angular/material';
|
||||
import { ObservableMedia } from '@angular/flex-layout';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
|
||||
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
|
||||
{
|
||||
matchMediaSubscription: Subscription;
|
||||
@HostBinding('class.mat-is-locked-open') isLockedOpen = true;
|
||||
@Input('fuseMatSidenavHelper') id: string;
|
||||
@Input('mat-is-locked-open') matIsLockedOpenBreakpoint: string;
|
||||
|
||||
constructor(
|
||||
private fuseMatSidenavService: FuseMatSidenavHelperService,
|
||||
private fuseMatchMedia: FuseMatchMediaService,
|
||||
private observableMedia: ObservableMedia,
|
||||
private matSidenav: MatSidenav
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
this.fuseMatSidenavService.setSidenav(this.id, this.matSidenav);
|
||||
|
||||
if ( this.observableMedia.isActive(this.matIsLockedOpenBreakpoint) )
|
||||
{
|
||||
this.isLockedOpen = true;
|
||||
this.matSidenav.mode = 'side';
|
||||
this.matSidenav.toggle(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.isLockedOpen = false;
|
||||
this.matSidenav.mode = 'over';
|
||||
this.matSidenav.toggle(false);
|
||||
}
|
||||
|
||||
this.matchMediaSubscription = this.fuseMatchMedia.onMediaChange.subscribe(() => {
|
||||
if ( this.observableMedia.isActive(this.matIsLockedOpenBreakpoint) )
|
||||
{
|
||||
this.isLockedOpen = true;
|
||||
this.matSidenav.mode = 'side';
|
||||
this.matSidenav.toggle(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.isLockedOpen = false;
|
||||
this.matSidenav.mode = 'over';
|
||||
this.matSidenav.toggle(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
{
|
||||
this.matchMediaSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
@Directive({
|
||||
selector: '[fuseMatSidenavToggler]'
|
||||
})
|
||||
export class FuseMatSidenavTogglerDirective
|
||||
{
|
||||
@Input('fuseMatSidenavToggler') id;
|
||||
|
||||
constructor(private fuseMatSidenavService: FuseMatSidenavHelperService)
|
||||
{
|
||||
}
|
||||
|
||||
@HostListener('click')
|
||||
onClick()
|
||||
{
|
||||
this.fuseMatSidenavService.getSidenav(this.id).toggle();
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MdSidenav } from '@angular/material';
|
||||
import { MatSidenav } from '@angular/material';
|
||||
|
||||
@Injectable()
|
||||
export class FuseMdSidenavHelperService
|
||||
export class FuseMatSidenavHelperService
|
||||
{
|
||||
sidenavInstances: MdSidenav[];
|
||||
sidenavInstances: MatSidenav[];
|
||||
|
||||
constructor()
|
||||
{
|
||||
@@ -0,0 +1,186 @@
|
||||
import { AfterViewInit, Directive, ElementRef, HostListener, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Platform } from '@angular/cdk/platform';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
|
||||
import PerfectScrollbar from 'perfect-scrollbar';
|
||||
|
||||
import { FuseConfigService } from '@fuse/services/config.service';
|
||||
|
||||
@Directive({
|
||||
selector: '[fusePerfectScrollbar]'
|
||||
})
|
||||
export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnDestroy
|
||||
{
|
||||
onConfigChanged: Subscription;
|
||||
isDisableCustomScrollbars = false;
|
||||
isMobile = false;
|
||||
isInitialized = true;
|
||||
ps: PerfectScrollbar;
|
||||
|
||||
constructor(
|
||||
public element: ElementRef,
|
||||
private fuseConfig: FuseConfigService,
|
||||
private platform: Platform
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
this.onConfigChanged =
|
||||
this.fuseConfig.onConfigChanged.subscribe(
|
||||
(settings) => {
|
||||
this.isDisableCustomScrollbars = !settings.customScrollbars;
|
||||
}
|
||||
);
|
||||
|
||||
if ( this.platform.ANDROID || this.platform.IOS )
|
||||
{
|
||||
this.isMobile = true;
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterViewInit()
|
||||
{
|
||||
if ( this.isMobile || this.isDisableCustomScrollbars )
|
||||
{
|
||||
this.isInitialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the perfect-scrollbar
|
||||
this.ps = new PerfectScrollbar(this.element.nativeElement, {
|
||||
wheelPropagation: true
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
{
|
||||
if ( !this.isInitialized || !this.ps )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.onConfigChanged.unsubscribe();
|
||||
|
||||
// Destroy the perfect-scrollbar
|
||||
this.ps.destroy();
|
||||
}
|
||||
|
||||
@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()
|
||||
{
|
||||
if ( !this.isInitialized )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the perfect-scrollbar
|
||||
this.ps.update();
|
||||
}
|
||||
|
||||
destroy()
|
||||
{
|
||||
this.ngOnDestroy();
|
||||
}
|
||||
|
||||
scrollToX(x: number, speed?: number)
|
||||
{
|
||||
this.animateScrolling('scrollLeft', x, speed);
|
||||
}
|
||||
|
||||
scrollToY(y: number, speed?: number)
|
||||
{
|
||||
this.animateScrolling('scrollTop', y, speed);
|
||||
}
|
||||
|
||||
scrollToTop(offset?: number, speed?: number)
|
||||
{
|
||||
this.animateScrolling('scrollTop', (offset || 0), speed);
|
||||
}
|
||||
|
||||
scrollToLeft(offset?: number, speed?: number)
|
||||
{
|
||||
this.animateScrolling('scrollLeft', (offset || 0), speed);
|
||||
}
|
||||
|
||||
scrollToRight(offset?: number, speed?: number)
|
||||
{
|
||||
const width = this.element.nativeElement.scrollWidth;
|
||||
|
||||
this.animateScrolling('scrollLeft', width - (offset || 0), speed);
|
||||
}
|
||||
|
||||
scrollToBottom(offset?: number, speed?: number)
|
||||
{
|
||||
const height = this.element.nativeElement.scrollHeight;
|
||||
|
||||
this.animateScrolling('scrollTop', height - (offset || 0), speed);
|
||||
}
|
||||
|
||||
animateScrolling(target: string, value: number, speed?: number)
|
||||
{
|
||||
if ( !speed )
|
||||
{
|
||||
this.element.nativeElement[target] = value;
|
||||
|
||||
// PS has weird event sending order, this is a workaround for that
|
||||
this.update();
|
||||
this.update();
|
||||
}
|
||||
else if ( value !== this.element.nativeElement[target] )
|
||||
{
|
||||
let newValue = 0;
|
||||
let scrollCount = 0;
|
||||
|
||||
let oldTimestamp = performance.now();
|
||||
let oldValue = this.element.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.element.nativeElement[target] === oldValue )
|
||||
{
|
||||
if ( scrollCount >= Math.PI )
|
||||
{
|
||||
this.element.nativeElement[target] = value;
|
||||
|
||||
// PS has weird event sending order, this is a workaround for that
|
||||
this.update();
|
||||
|
||||
this.update();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.element.nativeElement[target] = oldValue = newValue;
|
||||
|
||||
oldTimestamp = newTimestamp;
|
||||
|
||||
window.requestAnimationFrame(step);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.requestAnimationFrame(step);
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/@fuse/fuse.module.ts
Normal file
47
src/@fuse/fuse.module.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';
|
||||
|
||||
import { FUSE_CONFIG, FuseConfigService } from '@fuse/services/config.service';
|
||||
import { FuseCopierService } from '@fuse/services/copier.service';
|
||||
import { FuseMatchMediaService } from '@fuse/services/match-media.service';
|
||||
import { FuseMatSidenavHelperService } from '@fuse/directives/fuse-mat-sidenav/fuse-mat-sidenav.service';
|
||||
import { FuseNavigationService } from '@fuse/components/navigation/navigation.service';
|
||||
import { FuseSidebarService } from '@fuse/components/sidebar/sidebar.service';
|
||||
import { FuseSplashScreenService } from '@fuse/services/splash-screen.service';
|
||||
import { FuseTranslationLoaderService } from '@fuse/services/translation-loader.service';
|
||||
|
||||
@NgModule({
|
||||
entryComponents: [],
|
||||
providers : [
|
||||
FuseConfigService,
|
||||
FuseCopierService,
|
||||
FuseMatchMediaService,
|
||||
FuseMatSidenavHelperService,
|
||||
FuseNavigationService,
|
||||
FuseSidebarService,
|
||||
FuseSplashScreenService,
|
||||
FuseTranslationLoaderService
|
||||
]
|
||||
})
|
||||
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
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -681,6 +681,7 @@ const matColors = {
|
||||
}
|
||||
};
|
||||
|
||||
// tslint:disable-next-line
|
||||
const matPresetColors = [
|
||||
'#ffebee', '#ffcdd2', '#ef9a9a', '#e57373', '#ef5350', '#f44336', '#e53935', '#d32f2f', '#c62828', '#b71c1c', '#ff8a80', '#ff5252', '#ff1744', '#d50000', '#fce4ec', '#f8bbd0', '#f48fb1', '#f06292', '#ec407a', '#e91e63', '#d81b60', '#c2185b', '#ad1457', '#880e4f', '#ff80ab', '#ff4081', '#f50057', '#c51162', '#f3e5f5', '#e1bee7', '#ce93d8', '#ba68c8', '#ab47bc', '#9c27b0', '#8e24aa', '#7b1fa2', '#6a1b9a', '#4a148c', '#ea80fc', '#e040fb', '#d500f9', '#aa00ff', '#ede7f6', '#d1c4e9', '#b39ddb', '#9575cd', '#7e57c2', '#673ab7', '#5e35b1', '#512da8', '#4527a0', '#311b92', '#b388ff', '#7c4dff', '#651fff', '#6200ea', '#e8eaf6', '#c5cae9', '#9fa8da', '#7986cb', '#5c6bc0', '#3f51b5', '#3949ab', '#303f9f', '#283593', '#1a237e', '#8c9eff', '#536dfe', '#3d5afe', '#304ffe', '#e3f2fd', '#bbdefb', '#90caf9', '#64b5f6', '#42a5f5', '#2196f3', '#1e88e5', '#1976d2', '#1565c0', '#0d47a1', '#82b1ff', '#448aff', '#2979ff', '#2962ff', '#e1f5fe', '#b3e5fc', '#81d4fa', '#4fc3f7', '#29b6f6', '#03a9f4', '#039be5', '#0288d1', '#0277bd', '#01579b', '#80d8ff', '#40c4ff', '#00b0ff', '#0091ea', '#e0f7fa', '#b2ebf2', '#80deea', '#4dd0e1', '#26c6da', '#00bcd4', '#00acc1', '#0097a7', '#00838f', '#006064', '#84ffff', '#18ffff', '#00e5ff', '#00b8d4', '#e0f2f1', '#b2dfdb', '#80cbc4', '#4db6ac', '#26a69a', '#009688', '#00897b', '#00796b', '#00695c', '#004d40', '#a7ffeb', '#64ffda', '#1de9b6', '#00bfa5', '#e8f5e9', '#c8e6c9', '#a5d6a7', '#81c784', '#66bb6a', '#4caf50', '#43a047', '#388e3c', '#2e7d32', '#1b5e20', '#b9f6ca', '#69f0ae', '#00e676', '#00c853', '#f1f8e9', '#dcedc8', '#c5e1a5', '#aed581', '#9ccc65', '#8bc34a', '#7cb342', '#689f38', '#558b2f', '#33691e', '#ccff90', '#b2ff59', '#76ff03', '#64dd17', '#f9fbe7', '#f0f4c3', '#e6ee9c', '#dce775', '#d4e157', '#cddc39', '#c0ca33', '#afb42b', '#9e9d24', '#827717', '#f4ff81', '#eeff41', '#c6ff00', '#aeea00', '#fffde7', '#fff9c4', '#fff59d', '#fff176', '#ffee58', '#ffeb3b', '#fdd835', '#fbc02d', '#f9a825', '#f57f17', '#ffff8d', '#ffff00', '#ffea00', '#ffd600', '#fff8e1', '#ffecb3', '#ffe082', '#ffd54f', '#ffca28', '#ffc107', '#ffb300', '#ffa000', '#ff8f00', '#ff6f00', '#ffe57f', '#ffd740', '#ffc400', '#ffab00', '#fff3e0', '#ffe0b2', '#ffcc80', '#ffb74d', '#ffa726', '#ff9800', '#fb8c00', '#f57c00', '#ef6c00', '#e65100', '#ffd180', '#ffab40', '#ff9100', '#ff6d00', '#fbe9e7', '#ffccbc', '#ffab91', '#ff8a65', '#ff7043', '#ff5722', '#f4511e', '#e64a19', '#d84315', '#bf360c', '#ff9e80', '#ff6e40', '#ff3d00', '#dd2c00', '#efebe9', '#d7ccc8', '#bcaaa4', '#a1887f', '#8d6e63', '#795548', '#6d4c41', '#5d4037', '#4e342e', '#3e2723', '#d7ccc8', '#bcaaa4', '#8d6e63', '#5d4037', '#fafafa', '#f5f5f5', '#eeeeee', '#e0e0e0', '#bdbdbd', '#9e9e9e', '#757575', '#616161', '#424242', '#212121', '#ffffff', '#eeeeee', '#bdbdbd', '#616161', '#eceff1', '#cfd8dc', '#b0bec5', '#90a4ae', '#78909c', '#607d8b', '#546e7a', '#455a64', '#37474f', '#263238', '#cfd8dc', '#b0bec5', '#78909c', '#455a64'
|
||||
];
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { FuseUtils } from '../fuseUtils';
|
||||
import { FuseUtils } from '@fuse/utils';
|
||||
|
||||
@Pipe({name: 'filter'})
|
||||
export class FilterPipe implements PipeTransform
|
||||
@@ -13,7 +13,6 @@ import { CamelCaseToDashPipe } from './camelCaseToDash.pipe';
|
||||
HtmlToPlaintextPipe,
|
||||
FilterPipe,
|
||||
CamelCaseToDashPipe
|
||||
|
||||
],
|
||||
imports : [],
|
||||
exports : [
|
||||
@@ -24,8 +23,6 @@ import { CamelCaseToDashPipe } from './camelCaseToDash.pipe';
|
||||
CamelCaseToDashPipe
|
||||
]
|
||||
})
|
||||
|
||||
export class FusePipesModule
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,16 +1,22 @@
|
||||
// This file meant to be imported only once! Use fuse.scss to access
|
||||
// to the core Fuse and Angular Material mixins
|
||||
|
||||
// ngx-datatable
|
||||
@import '~@swimlane/ngx-datatable/release/index.css';
|
||||
@import '~@swimlane/ngx-datatable/release/themes/material.css';
|
||||
@import '~@swimlane/ngx-datatable/release/assets/icons.css';
|
||||
// Perfect Scrollbar
|
||||
@import "~perfect-scrollbar/src/css/main";
|
||||
@import '~@swimlane/ngx-datatable/release/themes/material';
|
||||
|
||||
// Perfect scrollbar
|
||||
@import '~perfect-scrollbar/css/perfect-scrollbar';
|
||||
|
||||
// Fuse
|
||||
@import "fuse";
|
||||
|
||||
// Theming
|
||||
// Include core Angular Material styles
|
||||
@include mat-core();
|
||||
|
||||
// Include theme styles for core and each component used in your app.
|
||||
// Setup the typography
|
||||
@include angular-material-typography($typography);
|
||||
|
||||
// Create an Angular Material theme from the $theme map
|
||||
@include angular-material-theme($theme);
|
||||
|
||||
// Partials
|
||||
@@ -25,6 +31,7 @@
|
||||
@import "partials/angular-material-fix";
|
||||
@import "partials/typography";
|
||||
@import "partials/page-layouts";
|
||||
@import "partials/cards";
|
||||
@import "partials/navigation";
|
||||
@import "partials/forms";
|
||||
@import "partials/toolbar";
|
||||
5
src/@fuse/scss/fuse.scss
Normal file
5
src/@fuse/scss/fuse.scss
Normal file
@@ -0,0 +1,5 @@
|
||||
// Material theming
|
||||
@import "theming";
|
||||
|
||||
// Breakpoint mixins
|
||||
@import "mixins/breakpoints";
|
||||
87
src/@fuse/scss/partials/_angular-material-fix.scss
Normal file
87
src/@fuse/scss/partials/_angular-material-fix.scss
Normal file
@@ -0,0 +1,87 @@
|
||||
// Fix: "Icon button ripple radius is not correct on Edge & Safari"
|
||||
.mat-icon-button {
|
||||
|
||||
.mat-button-ripple {
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
// Fix: "Inconsistent font sizes across elements"
|
||||
.mat-form-field-wrapper {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.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: "Some idiots using 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;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user