feat: demo version additions

This commit is contained in:
Sergey Andrievskiy 2019-07-15 18:52:01 +03:00
parent 06cda13fd0
commit 62e6828680
36 changed files with 1494 additions and 65 deletions

View file

@ -22,6 +22,7 @@
"src/assets",
"src/favicon.ico",
"src/favicon.png",
"src/google46533d2e7a851062.html",
{
"glob": "**/*",
"input": "node_modules/leaflet/dist/images",
@ -123,6 +124,7 @@
"src/assets",
"src/favicon.ico",
"src/favicon.png",
"src/google46533d2e7a851062.html",
{
"glob": "**/*",
"input": "node_modules/leaflet/dist/images",

305
package-lock.json generated
View file

@ -1579,6 +1579,34 @@
"resolved": "https://registry.npmjs.org/@asymmetrik/ngx-leaflet/-/ngx-leaflet-3.0.1.tgz",
"integrity": "sha512-rQaqLM/n9gIPMKkNDOd3+H1kiQiuXtY5KVOM5cPJCoetaN9oIJrCATQHPRO47j1os8Wqcv5I0BKEH/EtTtVuiA=="
},
"@babel/code-frame": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
"integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
"dev": true,
"requires": {
"@babel/highlight": "^7.0.0"
}
},
"@babel/highlight": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
"integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
},
"dependencies": {
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
}
}
},
"@compodoc/compodoc": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@compodoc/compodoc/-/compodoc-1.0.1.tgz",
@ -1612,6 +1640,12 @@
"integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
"dev": true
},
"marked": {
"version": "0.3.19",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
"integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==",
"dev": true
},
"typescript": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.5.2.tgz",
@ -2200,6 +2234,28 @@
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
},
"angular-cli-ghpages": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/angular-cli-ghpages/-/angular-cli-ghpages-0.5.0.tgz",
"integrity": "sha1-UWbm62HBOAcH5RLHkS+ZFDd1DJk=",
"dev": true,
"requires": {
"commander": "~2.9.0",
"denodeify": "~1.2.1",
"gh-pages": "~0.12.0"
},
"dependencies": {
"commander": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
"integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
"dev": true,
"requires": {
"graceful-readlink": ">= 1.0.0"
}
}
}
},
"angular-tree-component": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/angular-tree-component/-/angular-tree-component-7.2.0.tgz",
@ -3655,6 +3711,15 @@
"object-visit": "^1.0.0"
}
},
"collections": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/collections/-/collections-0.2.2.tgz",
"integrity": "sha1-HyMCay7zb5J+7MkB6ZxfDUj6M04=",
"dev": true,
"requires": {
"weak-map": "1.0.0"
}
},
"color-convert": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz",
@ -5473,6 +5538,12 @@
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
},
"denodeify": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz",
"integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=",
"dev": true
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
@ -5777,6 +5848,14 @@
}
}
},
"dom7": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/dom7/-/dom7-2.1.3.tgz",
"integrity": "sha512-QTxHHDox+M6ZFz1zHPAHZKI3JOHY5iY4i9BK2uctlggxKQwRhO3q3HHFq1BKsT25Bm/ySSj70K6Wk/G4bs9rMQ==",
"requires": {
"ssr-window": "^1.0.1"
}
},
"domain-browser": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
@ -7750,6 +7829,72 @@
}
}
},
"gh-pages": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-0.12.0.tgz",
"integrity": "sha1-2VHj7Zi4VpnUsEGOsaFbGgSYjcE=",
"dev": true,
"requires": {
"async": "2.1.2",
"commander": "2.9.0",
"globby": "^6.1.0",
"graceful-fs": "4.1.10",
"q": "1.4.1",
"q-io": "1.13.2",
"rimraf": "^2.5.4"
},
"dependencies": {
"async": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/async/-/async-2.1.2.tgz",
"integrity": "sha1-YSpKtF70KnDN6Aa62G7m2wR+g4U=",
"dev": true,
"requires": {
"lodash": "^4.14.0"
}
},
"commander": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
"integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
"dev": true,
"requires": {
"graceful-readlink": ">= 1.0.0"
}
},
"globby": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
"integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
"dev": true,
"requires": {
"array-union": "^1.0.1",
"glob": "^7.0.3",
"object-assign": "^4.0.1",
"pify": "^2.0.0",
"pinkie-promise": "^2.0.0"
}
},
"graceful-fs": {
"version": "4.1.10",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.10.tgz",
"integrity": "sha1-8tcgwiCS90Mih3XHXjYSYyUB8TE=",
"dev": true
},
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
},
"q": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz",
"integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=",
"dev": true
}
}
},
"git-raw-commits": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.3.4.tgz",
@ -8158,6 +8303,12 @@
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
},
"graceful-readlink": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
"integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
"dev": true
},
"gulp-util": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz",
@ -8500,6 +8651,11 @@
"sntp": "1.x.x"
}
},
"highlight.js": {
"version": "9.15.8",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.8.tgz",
"integrity": "sha512-RrapkKQWwE+wKdF73VsOa2RQdIoO3mxwJ4P8mhbI6KYJUraUHRKM5w5zQQKXNk0xNL4UVRdulV9SBJcmzJNzVA=="
},
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@ -11179,10 +11335,9 @@
}
},
"marked": {
"version": "0.3.16",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.3.16.tgz",
"integrity": "sha512-diLiAxHidES67uJ1P5unXBUB4CyOFwodKrctuK0U4Ogw865N9Aw4dLmY0BK0tGKOy3xvkdMGgUXPD6W9z1Ne0Q==",
"dev": true
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.5.2.tgz",
"integrity": "sha512-fdZvBa7/vSQIZCi4uuwo2N3q+7jJURpMVCcbaX0S1Mg65WZ5ilXvC67MviJAsdjqqgD+CEq4RKo5AYGgINkVAA=="
},
"mathml-tag-names": {
"version": "2.0.1",
@ -11332,6 +11487,12 @@
"mime-db": "~1.33.0"
}
},
"mimeparse": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/mimeparse/-/mimeparse-0.1.4.tgz",
"integrity": "sha1-2vsCdSNw/SJgk64xUsJxrwGsJUo=",
"dev": true
},
"mimic-fn": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
@ -11652,6 +11813,11 @@
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
"dev": true
},
"ng-lazyload-image": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ng-lazyload-image/-/ng-lazyload-image-5.0.0.tgz",
"integrity": "sha512-3EGTO2Evd28NLFioDXfKBWqwCdtciV3klMuUW3e6r2kctvbrZ5jQV7uzwNKoK53j88mD2O2BAojoQ6Otd6Gt0A=="
},
"ng2-ckeditor": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/ng2-ckeditor/-/ng2-ckeditor-1.2.2.tgz",
@ -11685,6 +11851,14 @@
"tslib": "^1.9.0"
}
},
"ngx-swiper-wrapper": {
"version": "7.2.1",
"resolved": "https://registry.npmjs.org/ngx-swiper-wrapper/-/ngx-swiper-wrapper-7.2.1.tgz",
"integrity": "sha512-u2uv1P3EuErfDG+317Mn3QfC7jOGIihmNRYtJacHP8quqZJ/xCyxid4IVpq3535uPB+xgzZARqmXMsKqVs/5HQ==",
"requires": {
"swiper": "^4.4.0"
}
},
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
@ -13757,6 +13931,28 @@
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
"dev": true
},
"q-io": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/q-io/-/q-io-1.13.2.tgz",
"integrity": "sha1-7qEw1IHdteGqG8WmaFX3OR0G8AM=",
"dev": true,
"requires": {
"collections": "^0.2.0",
"mime": "^1.2.11",
"mimeparse": "^0.1.4",
"q": "^1.0.1",
"qs": "^1.2.1",
"url2": "^0.0.0"
},
"dependencies": {
"qs": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-1.2.2.tgz",
"integrity": "sha1-GbV/8k3CqZzh+L32r82ln472H4g=",
"dev": true
}
}
},
"qjobs": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz",
@ -16330,6 +16526,11 @@
}
}
},
"ssr-window": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-1.0.1.tgz",
"integrity": "sha512-dgFqB+f00LJTEgb6UXhx0h+SrG50LJvti2yMKMqAgzfUmUXZrLSv2fjULF7AWGwK25EXu8+smLR3jYsJQChPsg=="
},
"ssri": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
@ -16982,6 +17183,15 @@
"integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=",
"dev": true
},
"swiper": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/swiper/-/swiper-4.5.0.tgz",
"integrity": "sha512-jRCd/CGet9kaHwthHdd/sL/YU8CI157PWLyItnIcn/o/jP4haVky3zTF6f9F3JDpmQIw7jdWihISiYx0/oTHsg==",
"requires": {
"dom7": "^2.1.3",
"ssr-window": "^1.0.1"
}
},
"symbol-observable": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
@ -17381,21 +17591,80 @@
"integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ=="
},
"tslint": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.7.0.tgz",
"integrity": "sha1-wl4NDJL6EgHCvDDoROCOaCtPNVI=",
"version": "5.18.0",
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.18.0.tgz",
"integrity": "sha512-Q3kXkuDEijQ37nXZZLKErssQVnwCV/+23gFEMROi8IlbaBG6tXqLPQJ5Wjcyt/yHPKBC+hD5SzuGaMora+ZS6w==",
"dev": true,
"requires": {
"babel-code-frame": "^6.22.0",
"colors": "^1.1.2",
"commander": "^2.9.0",
"@babel/code-frame": "^7.0.0",
"builtin-modules": "^1.1.1",
"chalk": "^2.3.0",
"commander": "^2.12.1",
"diff": "^3.2.0",
"glob": "^7.1.1",
"js-yaml": "^3.13.1",
"minimatch": "^3.0.4",
"mkdirp": "^0.5.1",
"resolve": "^1.3.2",
"semver": "^5.3.0",
"tslib": "^1.7.1",
"tsutils": "^2.8.1"
"tslib": "^1.8.0",
"tsutils": "^2.29.0"
},
"dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"js-yaml": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
"tslint-language-service": {
@ -17862,6 +18131,12 @@
"requires-port": "^1.0.0"
}
},
"url2": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/url2/-/url2-0.0.0.tgz",
"integrity": "sha1-Tqq9HVw6yQ1iq0SFyZhCKGWgSxo=",
"dev": true
},
"use": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
@ -18955,6 +19230,12 @@
"minimalistic-assert": "^1.0.0"
}
},
"weak-map": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.0.tgz",
"integrity": "sha1-tm5Wqd8L0lp2u/G1FNsSkIBhSjc=",
"dev": true
},
"web-animations-js": {
"version": "github:angular/web-animations-js#96635c1a82a730fc71cc5d6cabe5dfe7c8349ec5",
"from": "github:angular/web-animations-js#release_pr208"

View file

@ -11,10 +11,12 @@
},
"scripts": {
"ng": "ng",
"ngh": "ngh",
"conventional-changelog": "conventional-changelog",
"start": "ng serve",
"build": "ng build",
"build:prod": "npm run build -- --prod --aot",
"build:demo:prod": "npm run build -- --prod --aot --base-href /ngx-admin/",
"test": "ng test",
"test:coverage": "rimraf coverage && npm run test -- --code-coverage",
"lint": "ng lint",
@ -55,15 +57,19 @@
"core-js": "2.5.1",
"echarts": "^4.0.2",
"eva-icons": "^1.1.0",
"highlight.js": "^9.13.1",
"intl": "1.2.5",
"ionicons": "2.0.1",
"leaflet": "1.2.0",
"marked": "^0.5.2",
"nebular-icons": "1.1.0",
"ng-lazyload-image": "5.0.0",
"ng2-ckeditor": "^1.2.2",
"ng2-completer": "2.0.8",
"ng2-smart-table": "1.3.5",
"ngx-echarts": "^4.0.1",
"node-sass": "^4.12.0",
"ngx-swiper-wrapper": "^7.1.1",
"normalize.css": "6.0.0",
"pace-js": "1.0.2",
"roboto-fontface": "0.8.0",
@ -89,6 +95,7 @@
"@types/jasminewd2": "2.0.3",
"@types/leaflet": "1.2.3",
"@types/node": "6.0.90",
"angular-cli-ghpages": "0.5.0",
"codelyzer": "^5.0.1",
"conventional-changelog-cli": "1.3.4",
"husky": "0.13.3",

View file

@ -51,6 +51,7 @@ import { StatsProgressBarService } from './mock/stats-progress-bar.service';
import { VisitorsAnalyticsService } from './mock/visitors-analytics.service';
import { SecurityCamerasService } from './mock/security-cameras.service';
import { MockDataModule } from './mock/mock-data.module';
import { AbService } from './utils/ab.service';
const socialLinks = [
{
@ -141,6 +142,7 @@ export const NB_CORE_PROVIDERS = [
LayoutService,
PlayerService,
StateService,
AbService,
];
@NgModule({

View file

@ -0,0 +1,45 @@
import { Injectable } from '@angular/core';
import { fromEvent as observableFromEvent } from 'rxjs/observable/fromEvent';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { filter } from 'rxjs/operators/filter';
@Injectable()
export class AbService {
static readonly VARIANT_THEME_DEFAULT = 'theme-change-default';
static readonly VARIANT_THEME_COSMIC = 'theme-change-cosmic';
static readonly VARIANT_THEME_DARK = 'theme-change-dark';
static readonly VARIANT_THEME_CORPORATE = 'theme-change-corporate';
static readonly VARIANT_HIGHLIGHT_HIRE = 'highlight-hire';
static readonly VARIANT_DEVELOPERS_HIRE = 'developers-hire';
static readonly VARIANT_SOLUTION_HIRE = 'solution-hire';
static readonly VARIANT_HIDE_CALL_ACTION = 'call-action-hide';
// static readonly VARIANT_BANNER_HIRE = 'banner-hire';
private static readonly EVENT_NAME = 'ab-variant';
private static readonly AB_ENABLED = true;
private events$ = new BehaviorSubject<{ name: string }>(null);
constructor() {
if (AbService.AB_ENABLED) {
observableFromEvent<any>(document, AbService.EVENT_NAME)
.subscribe((e: { detail: any }) => {
if (e && e.detail) {
this.events$.next(e.detail);
}
});
}
}
onAbEvent(name: string = ''): Observable<{ name: string }> {
return this.events$.asObservable()
.pipe(
filter(e => !!(e && e.name)),
filter(e => name ? e.name === name : true),
);
}
}

View file

@ -1,16 +1,17 @@
import { Injectable } from '@angular/core';
import { Inject, Injectable } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { Location } from '@angular/common';
import { filter } from 'rxjs/operators';
declare const ga: any;
import { NB_WINDOW } from '@nebular/theme';
@Injectable()
export class AnalyticsService {
private enabled: boolean;
private enabled = false;
constructor(private location: Location, private router: Router) {
this.enabled = false;
constructor(@Inject(NB_WINDOW) private window,
private location: Location,
private router: Router) {
this.enabled = this.window.location.href.indexOf('akveo.com') >= 0;
}
trackPageViews() {
@ -19,14 +20,18 @@ export class AnalyticsService {
filter((event) => event instanceof NavigationEnd),
)
.subscribe(() => {
ga('send', {hitType: 'pageview', page: this.location.path()});
this.gtmPushToDataLayer({event: 'pageView' , path: this.location.path()});
});
}
}
trackEvent(eventName: string) {
trackEvent(eventName: string, eventVal: string = '') {
if (this.enabled) {
ga('send', 'event', eventName);
this.gtmPushToDataLayer({ event: eventName, eventValue: eventVal });
}
}
private gtmPushToDataLayer(params) {
this.window.dataLayer.push(params);
}
}

View file

@ -1,11 +1,4 @@
import { LayoutService } from './layout.service';
import { AnalyticsService } from './analytics.service';
import { PlayerService } from './player.service';
import { StateService } from './state.service';
export {
LayoutService,
AnalyticsService,
PlayerService,
StateService,
};
export { LayoutService } from './layout.service';
export { AnalyticsService } from './analytics.service';
export { PlayerService } from './player.service';
export { StateService } from './state.service';

View file

@ -0,0 +1,64 @@
@import '../../../@theme/styles/themes';
@import '~bootstrap/scss/mixins/breakpoints';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
nb-card {
flex-direction: row;
align-items: center;
height: 6rem;
}
.icon-container {
height: 100%;
padding: 0.625rem;
}
.icon {
background-color: nb-theme(color-primary-default);
border-radius: nb-theme(card-border-radius);
display: flex;
align-items: center;
justify-content: center;
width: 5.75rem;
height: 100%;
transition: width 0.4s ease;
transform: translate3d(0, 0, 0);
-webkit-transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
::ng-deep svg {
fill: nb-theme(text-control-color);
}
}
nb-icon {
font-size: 2.5rem;
}
.details {
flex: 1 1 auto;
display: flex;
flex-direction: column;
justify-content: center;
height: 100%;
@include nb-ltr(padding, 0 0.5rem 0 0.625rem);
@include nb-rtl(padding, 0 0.625rem 0 0.5rem);
border-left: 1px solid transparent;
}
.title {
margin: 0;
}
.actions {
@include nb-ltr(padding, 0 1.15rem 0 0.5rem);
@include nb-rtl(padding, 0 0.5rem 0 1.15rem);
}
@include media-breakpoint-down(md) {
.icon-container {
display: none;
}
}
}

View file

@ -0,0 +1,78 @@
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { NbComponentSize, NbComponentStatus, NbMediaBreakpointsService, NbThemeService } from '@nebular/theme';
import { map, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
@Component({
selector: 'ngx-call-action-card',
styleUrls: ['./call-action-card.component.scss'],
template: `
<nb-card>
<div class="icon-container">
<div class="icon">
<nb-icon [icon]="type"></nb-icon>
</div>
</div>
<div class="details">
<div class="title h6">{{ title }}</div>
</div>
<div class="actions">
<a nbButton [size]="buttonSize" [status]="getButtonStatus()" hero [href]="link">
{{ linkTitle }}
</a>
</div>
</nb-card>
`,
})
export class CallActionCardComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>();
@Input() title: string;
@Input() type: string;
@Input() link: string;
@Input() linkTitle: string;
currentTheme: string;
buttonSize: NbComponentSize;
constructor(
private themeService: NbThemeService,
private breakpointService: NbMediaBreakpointsService,
) {}
ngOnInit() {
this.themeService.getJsTheme()
.pipe(takeUntil(this.destroy$))
.subscribe(theme => {
this.currentTheme = theme.name;
});
const { xxl } = this.breakpointService.getBreakpointsMap();
this.themeService.onMediaQueryChange()
.pipe(
map(([, currentBreakpoint]) => currentBreakpoint.width < xxl),
takeUntil(this.destroy$),
)
.subscribe((isLessThanXxl: boolean) => {
this.buttonSize = isLessThanXxl
? 'small'
: 'large';
});
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
getButtonStatus(): NbComponentStatus {
switch (this.currentTheme) {
case 'cosmic': return 'primary';
case 'corporate': return 'warning';
default: return 'danger';
}
}
}

View file

@ -4,12 +4,21 @@ import { Component } from '@angular/core';
selector: 'ngx-footer',
styleUrls: ['./footer.component.scss'],
template: `
<span class="created-by">Created with by <b><a href="https://akveo.com" target="_blank">Akveo</a></b> 2019</span>
<span class="created-by">
Created with by <b><a href="http://akveo.com?utm_source=ngx-admin-demo&utm_medium=footer"
target="_blank">Akveo</a></b> 2019.
Made with
<b>
<a href="https://akveo.github.io/nebular/?utm_source=ngx-admin&utm_medium=footer_link" target="_blank">
Nebular.
</a>
</b>
</span>
<div class="socials">
<a href="#" target="_blank" class="ion ion-social-github"></a>
<a href="#" target="_blank" class="ion ion-social-facebook"></a>
<a href="#" target="_blank" class="ion ion-social-twitter"></a>
<a href="#" target="_blank" class="ion ion-social-linkedin"></a>
<a href="https://github.com/akveo/ngx-admin" target="_blank" class="ion ion-social-github"></a>
<a href="https://www.facebook.com/akveo/" target="_blank" class="ion ion-social-facebook"></a>
<a href="https://twitter.com/akveo_inc" target="_blank" class="ion ion-social-twitter"></a>
<a href="https://www.linkedin.com/company/akveo" target="_blank" class="ion ion-social-linkedin"></a>
</div>
`,
})

View file

@ -5,19 +5,37 @@
</a>
<a class="logo" href="#" (click)="navigateHome()">ngx-<span>admin</span></a>
</div>
<nb-select [selected]="currentTheme" (selectedChange)="changeTheme($event)" status="primary">
<nb-option *ngFor="let theme of themes" [value]="theme.value"> {{ theme.name }}</nb-option>
<nb-select [selected]="currentTheme" (selectedChange)="changeTheme($event)" status="primary" class="theme-select">
<nb-option *ngFor="let theme of themes" [value]="theme.value">{{ theme.name }}</nb-option>
</nb-select>
</div>
<div class="header-container">
<nb-actions size="small">
<nb-action class="control-item">
<nb-search type="rotate-layout"></nb-search>
<nb-action class="control-item github-stars">
<span class="subtitle text">Support us: </span>
<iframe src="https://ghbtns.com/github-btn.html?user=akveo&repo=ngx-admin&type=star&count=true"
frameborder="0"
scrolling="0"
width="170px"
height="20px">
</iframe>
</nb-action>
<nb-action class="control-item" icon="email-outline"></nb-action>
<nb-action class="control-item" icon="bell-outline"></nb-action>
<nb-action class="control-item downloads-count">
<nb-icon icon="download"></nb-icon>
<span class="subtitle number">358.000</span>
</nb-action>
<nb-action class="control-item contact-us">
<a nbButton ghost href="mailto:contact@akveo.com" (click)="trackEmailClick()">
<nb-icon icon="email-outline" pack="eva"></nb-icon>
<span>contact@akveo.com</span>
</a>
</nb-action>
<nb-action class="control-item search">
<nb-search type="rotate-layout" (click)="startSearch()"></nb-search>
</nb-action>
<nb-action class="control-item email" icon="email-outline"></nb-action>
<nb-action class="control-item notifications" icon="bell-outline"></nb-action>
<nb-action class="user-action" *nbIsGranted="['view', 'user']" >
<nb-user [nbContextMenu]="userMenu"
[onlyPicture]="userPictureOnly"

View file

@ -23,10 +23,30 @@
cursor: pointer;
}
.subtitle {
font-family: nb-theme(text-subtitle-font-family);
font-size: nb-theme(text-subtitle-font-size);
font-weight: nb-theme(text-subtitle-font-weight);
line-height: nb-theme(text-subtitle-line-height);
}
.downloads-count .number {
@include nb-ltr(margin-left, 0.5rem);
@include nb-rtl(margin-right, 0.5rem);
}
::ng-deep nb-search button {
padding: 0!important;
}
.contact-us {
padding: 0;
nb-icon {
font-size: 1.25rem;
}
}
.header-container {
display: flex;
align-items: center;
@ -52,18 +72,55 @@
}
}
@include media-breakpoint-down(sm) {
.control-item {
.github-stars {
width: 245px;
display: flex;
iframe {
width: 100px;
@include nb-ltr(margin-left, 1rem);
@include nb-rtl(margin-right, 1rem);
}
}
@include media-breakpoint-down(xl) {
.control-item.search,
.control-item.notifications,
.control-item.email,
.control-item.github-stars .text {
display: none;
}
.user-action {
border: none;
padding: 0;
.control-item.github-stars {
width: auto;
iframe {
margin: 0;
}
}
}
@include media-breakpoint-down(lg) {
.downloads-count {
display: none;
}
}
@include media-breakpoint-down(md) {
.theme-select {
display: none;
}
}
@include media-breakpoint-down(sm) {
.contact-us {
display: none;
}
}
@include media-breakpoint-down(is) {
nb-select {
.github-stars,
.user-action {
display: none;
}
}

View file

@ -2,7 +2,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
import { NbMediaBreakpointsService, NbMenuService, NbSidebarService, NbThemeService } from '@nebular/theme';
import { UserData } from '../../../@core/data/users';
import { LayoutService } from '../../../@core/utils';
import { AnalyticsService, LayoutService } from '../../../@core/utils';
import { map, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
@ -45,8 +45,9 @@ export class HeaderComponent implements OnInit, OnDestroy {
private themeService: NbThemeService,
private userService: UserData,
private layoutService: LayoutService,
private breakpointService: NbMediaBreakpointsService) {
}
private breakpointService: NbMediaBreakpointsService,
private analytics: AnalyticsService,
) {}
ngOnInit() {
this.currentTheme = this.themeService.currentTheme;
@ -91,4 +92,12 @@ export class HeaderComponent implements OnInit, OnDestroy {
this.menuService.navigateHome();
return false;
}
startSearch() {
this.analytics.trackEvent('startSearch');
}
trackEmailClick() {
this.analytics.trackEvent('clickContactEmail', 'click');
}
}

View file

@ -2,3 +2,8 @@ export * from './header/header.component';
export * from './footer/footer.component';
export * from './search-input/search-input.component';
export * from './tiny-mce/tiny-mce.component';
export * from './call-action-card/call-action-card.component';
export * from './theme-settings/theme-settings.component';
export * from './switcher/switcher.component';
export * from './layout-direction-switcher/layout-direction-switcher.component';
export * from './toggle-settings-button/toggle-settings-button.component';

View file

@ -0,0 +1,45 @@
import { Component, OnDestroy, Input } from '@angular/core';
import { NbLayoutDirectionService, NbLayoutDirection } from '@nebular/theme';
import { takeWhile } from 'rxjs/operators';
import { AnalyticsService } from '../../../@core/utils/analytics.service';
@Component({
selector: 'ngx-layout-direction-switcher',
template: `
<ngx-switcher
[firstValue]="directions.RTL"
[secondValue]="directions.LTR"
[firstValueLabel]="'RTL'"
[secondValueLabel]="'LTR'"
[value]="currentDirection"
(valueChange)="toggleDirection($event)"
[vertical]="vertical">
</ngx-switcher>
`,
})
export class LayoutDirectionSwitcherComponent implements OnDestroy {
directions = NbLayoutDirection;
currentDirection: NbLayoutDirection;
alive = true;
@Input() vertical: boolean = false;
constructor(private directionService: NbLayoutDirectionService,
private analyticsService: AnalyticsService) {
this.currentDirection = this.directionService.getDirection();
this.directionService.onDirectionChange()
.pipe(takeWhile(() => this.alive))
.subscribe(newDirection => this.currentDirection = newDirection);
}
toggleDirection(newDirection) {
this.directionService.setDirection(newDirection);
this.analyticsService.trackEvent('toggleDirection', newDirection);
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -0,0 +1,91 @@
@import '../../styles/themes';
@import '~bootstrap/scss/mixins/breakpoints';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
.switch-label {
display: flex;
justify-content: space-around;
align-items: center;
cursor: pointer;
margin: 0;
&.vertical {
flex-direction: column;
align-items: flex-start;
.first,
.second {
padding: 0;
}
.switch {
margin-top: 0.5em;
}
}
& > span {
transition: opacity 0.3s ease;
color: nb-theme(text-hint-color);
&.first {
@include nb-ltr(padding-right, 10px);
@include nb-rtl(padding-left, 10px);
}
&.second {
@include nb-ltr(padding-left, 10px);
@include nb-rtl(padding-right, 10px);
}
&.active {
color: nb-theme(text-basic-color);
}
&:active {
opacity: 0.78;
}
}
}
.switch {
position: relative;
display: inline-block;
width: 3rem;
height: 1.5rem;
margin: 0;
input {
display: none;
&:checked + .slider::before {
@include nb-ltr(transform, translateX(1.5rem));
@include nb-rtl(transform, translateX(-1.5rem));
}
}
.slider {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 1.75rem;
background-color: nb-theme(background-basic-color-2);
}
.slider::before {
position: absolute;
content: '';
height: 1.5rem;
width: 1.5rem;
border-radius: 50%;
background-color: nb-theme(color-primary-default);
transition: 0.2s;
}
}
@include media-breakpoint-down(xs) {
align-items: flex-end;
}
}

View file

@ -0,0 +1,58 @@
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'ngx-switcher',
styleUrls: ['./switcher.component.scss'],
template: `
<label class="switch-label" [class.vertical]="vertical">
<span class="first" [class.active]="vertical || isFirstValue()">
{{vertical ? currentValueLabel() : firstValueLabel}}
</span>
<div class="switch">
<input type="checkbox" [checked]="isSecondValue()" (change)="changeValue()">
<span class="slider"></span>
</div>
<span *ngIf="!vertical"
class="second"
[class.active]="isSecondValue()">
{{secondValueLabel}}
</span>
</label>
`,
})
export class SwitcherComponent {
@Input() firstValue: any;
@Input() secondValue: any;
@Input() firstValueLabel: string;
@Input() secondValueLabel: string;
@Input() vertical: boolean;
@Input() value: any;
@Output() valueChange = new EventEmitter<any>();
isFirstValue() {
return this.value === this.firstValue;
}
isSecondValue() {
return this.value === this.secondValue;
}
currentValueLabel() {
return this.isFirstValue()
? this.firstValueLabel
: this.secondValueLabel;
}
changeValue() {
this.value = this.isFirstValue()
? this.secondValue
: this.firstValue;
this.valueChange.emit(this.value);
}
}

View file

@ -0,0 +1,35 @@
@import '../../styles/themes';
@include nb-install-component() {
.subheader {
display: block;
font-family: nb-theme(text-subtitle-font-family);
font-size: nb-theme(text-subtitle-font-size);
font-weight: nb-theme(text-subtitle-font-weight);
line-height: nb-theme(text-subtitle-line-height);
margin-bottom: 0.875rem;
text-align: center;
}
.layout-setting-heading {
margin-bottom: 1.2rem;
}
.setting-icon {
font-size: 1.5rem;
}
.settings-row {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
width: 100%;
margin: 0 0 2.575rem;
}
.switcher {
width: 12rem;
}
}

View file

@ -0,0 +1,75 @@
import { Component } from '@angular/core';
import { StateService } from '../../../@core/utils';
@Component({
selector: 'ngx-theme-settings',
styleUrls: ['./theme-settings.component.scss'],
template: `
<span class="subheader">Layouts</span>
<div class="settings-row">
<button *ngFor="let layout of layouts"
nbButton
[appearance]="layout.selected ? 'outline' : 'ghost'"
[attr.aria-label]="layout.name"
(click)="layoutSelect(layout)"
class="select-button">
<i [attr.class]="layout.icon + ' setting-icon'"></i>
</button>
</div>
<span class="subheader">Sidebar</span>
<div class="settings-row">
<button *ngFor="let sidebar of sidebars"
nbButton
[appearance]="sidebar.selected ? 'outline' : 'ghost'"
[attr.aria-label]="sidebar.name"
(click)="sidebarSelect(sidebar)"
class="select-button">
<i [attr.class]="sidebar.icon + ' setting-icon'"></i>
</button>
</div>
<span class="subheader layout-setting-heading">Layout direction</span>
<div class="settings-row">
<div class="switcher">
<ngx-layout-direction-switcher></ngx-layout-direction-switcher>
</div>
</div>
`,
})
export class ThemeSettingsComponent {
layouts = [];
sidebars = [];
constructor(protected stateService: StateService) {
this.stateService.getLayoutStates()
.subscribe((layouts: any[]) => this.layouts = layouts);
this.stateService.getSidebarStates()
.subscribe((sidebars: any[]) => this.sidebars = sidebars);
}
layoutSelect(layout: any): boolean {
this.layouts = this.layouts.map((l: any) => {
l.selected = false;
return l;
});
layout.selected = true;
this.stateService.setLayoutState(layout);
return false;
}
sidebarSelect(sidebar: any): boolean {
this.sidebars = this.sidebars.map((s: any) => {
s.selected = false;
return s;
});
sidebar.selected = true;
this.stateService.setSidebarState(sidebar);
return false;
}
}

View file

@ -0,0 +1,112 @@
@import '../../styles/themes';
@import '~bootstrap/scss/mixins/breakpoints';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
border-radius: nb-theme(button-rectangle-border-radius);
box-shadow: nb-theme(card-shadow);
position: fixed;
top: 50%;
transition: transform 0.3s ease;
z-index: 998;
@include nb-ltr() {
&.position-start {
left: 0;
&,
.toggle-settings {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
&.expanded {
transform: translateX(nb-theme(sidebar-width));
}
}
&.position-end {
right: 0;
&,
.toggle-settings {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
&.expanded {
transform: translateX(-#{nb-theme(sidebar-width)});
}
}
}
@include nb-rtl() {
&.position-start {
right: 0;
&,
.toggle-settings {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
&.expanded {
transform: translateX(-#{nb-theme(sidebar-width)});
}
}
&.position-end {
left: 0;
&,
.toggle-settings {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
&.expanded {
transform: translateX(nb-theme(sidebar-width));
}
}
}
.toggle-settings {
background: nb-theme(color-basic-100);
box-shadow: none;
border: none;
height: 3rem;
width: 3rem;
padding: 0;
text-align: center;
}
.icon {
font-size: 1.65rem;
&.icon-pulse {
animation-name: gear-pulse;
animation-duration: 1s;
animation-iteration-count: infinite;
}
}
@keyframes gear-pulse {
from {
transform: scale3d(1, 1, 1);
}
50% {
transform: scale3d(1.2, 1.2, 1.2);
}
to {
transform: scale3d(1, 1, 1);
}
}
@include media-breakpoint-down(sm) {
.toggle-settings {
display: none;
}
}
}

View file

@ -0,0 +1,53 @@
import { Component, HostBinding, OnDestroy, OnInit } from '@angular/core';
import { NbSidebarService } from '@nebular/theme';
import { StateService } from '../../../@core/utils';
import { Subject } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
@Component({
selector: 'ngx-toggle-settings-button',
styleUrls: ['./toggle-settings-button.component.scss'],
template: `
<button nbButton appearance="outline" class="toggle-settings" (click)="toggleSettings()">
<nb-icon class="icon" [class.icon-pulse]="enablePulse" icon="settings-2-outline" pack="eva"></nb-icon>
</button>
`,
})
export class ToggleSettingsButtonComponent implements OnInit, OnDestroy {
protected destroy$ = new Subject<void>();
enablePulse = true;
@HostBinding('class.position-start') positionStart = false;
@HostBinding('class.position-end') positionEnd = false;
@HostBinding('class.expanded') expanded = false;
constructor(
protected sidebarService: NbSidebarService,
protected stateService: StateService,
) {}
ngOnInit() {
this.stateService.onSidebarState()
.pipe(
map(sidebar => sidebar.id !== 'end'),
takeUntil(this.destroy$),
)
.subscribe((isSettingsSidebarEnd: boolean) => {
this.positionEnd = isSettingsSidebarEnd;
this.positionStart = !isSettingsSidebarEnd;
});
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
toggleSettings() {
this.sidebarService.toggle(false, 'settings-sidebar');
this.expanded = !this.expanded;
this.enablePulse = false;
}
}

View file

@ -1,3 +1,4 @@
export * from './one-column/one-column.layout';
export * from './two-columns/two-columns.layout';
export * from './three-columns/three-columns.layout';
export * from './sample/sample.layout';

View file

@ -0,0 +1,25 @@
@import '../../styles/themes';
@import '~bootstrap/scss/mixins/breakpoints';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
nb-layout-column.small {
flex: 0.15 !important;
}
nb-sidebar.settings-sidebar {
$sidebar-width: 19rem;
transition: transform 0.3s ease;
@include nb-ltr(transform, translate3d(100%, 0, 0));
@include nb-rtl(transform, translate3d(-100%, 0, 0));
&.start {
@include nb-ltr(transform, translate3d(-100%, 0, 0));
@include nb-rtl(transform, translate3d(100%, 0, 0));
}
&.expanded, &.expanded.start {
transform: translate3d(0, 0, 0);
}
}
}

View file

@ -0,0 +1,159 @@
import { Component, Inject, OnDestroy, OnInit, PLATFORM_ID, ViewChild } from '@angular/core';
import { Subject } from 'rxjs';
import { delay, withLatestFrom, takeUntil } from 'rxjs/operators';
import {
NbLayoutComponent,
NbMediaBreakpoint,
NbMediaBreakpointsService,
NbMenuItem,
NbMenuService,
NbSidebarService,
NbThemeService,
} from '@nebular/theme';
import { StateService } from '../../../@core/utils';
@Component({
selector: 'ngx-sample-layout',
styleUrls: ['./sample.layout.scss'],
template: `
<nb-layout [center]="layout.id === 'center-column'" windowMode>
<nb-layout-header fixed>
<ngx-header></ngx-header>
<ngx-toggle-settings-button></ngx-toggle-settings-button>
</nb-layout-header>
<nb-sidebar class="menu-sidebar"
tag="menu-sidebar"
responsive
[end]="isMenuSidebarPositionEnd()">
<ng-content select="nb-menu"></ng-content>
</nb-sidebar>
<nb-layout-column class="main-content">
<ng-content select="router-outlet"></ng-content>
</nb-layout-column>
<nb-layout-column start class="small" *ngIf="layout.id === 'two-column' || layout.id === 'three-column'">
<nb-menu [items]="subMenu"></nb-menu>
</nb-layout-column>
<nb-layout-column class="small" *ngIf="layout.id === 'three-column'">
<nb-menu [items]="subMenu"></nb-menu>
</nb-layout-column>
<nb-layout-footer fixed>
<ngx-footer></ngx-footer>
</nb-layout-footer>
<nb-sidebar class="settings-sidebar"
tag="settings-sidebar"
state="collapsed"
fixed
[end]="isSettingsSidebarPositionEnd()">
<ngx-theme-settings></ngx-theme-settings>
</nb-sidebar>
</nb-layout>
`,
})
export class SampleLayoutComponent implements OnInit, OnDestroy {
protected destroy$ = new Subject<void>();
subMenu: NbMenuItem[] = [
{
title: 'PAGE LEVEL MENU',
group: true,
},
{
title: 'Buttons',
icon: 'ion ion-android-radio-button-off',
link: '/pages/ui-features/buttons',
},
{
title: 'Grid',
icon: 'ion ion-android-radio-button-off',
link: '/pages/ui-features/grid',
},
{
title: 'Icons',
icon: 'ion ion-android-radio-button-off',
link: '/pages/ui-features/icons',
},
{
title: 'Modals',
icon: 'ion ion-android-radio-button-off',
link: '/pages/ui-features/modals',
},
{
title: 'Typography',
icon: 'ion ion-android-radio-button-off',
link: '/pages/ui-features/typography',
},
{
title: 'Animated Searches',
icon: 'ion ion-android-radio-button-off',
link: '/pages/ui-features/search-fields',
},
{
title: 'Tabs',
icon: 'ion ion-android-radio-button-off',
link: '/pages/ui-features/tabs',
},
];
layout: any = {};
sidebar: any = {};
currentTheme: string;
@ViewChild(NbLayoutComponent, { static: false }) layoutComponent: NbLayoutComponent;
constructor(protected stateService: StateService,
protected menuService: NbMenuService,
protected themeService: NbThemeService,
protected bpService: NbMediaBreakpointsService,
protected sidebarService: NbSidebarService,
@Inject(PLATFORM_ID) protected platformId,
) {}
ngOnInit() {
this.stateService.onLayoutState()
.pipe(takeUntil(this.destroy$))
.subscribe(layout => this.layout = layout);
this.stateService.onSidebarState()
.pipe(takeUntil(this.destroy$))
.subscribe(sidebar => this.sidebar = sidebar);
const isBp = this.bpService.getByName('is');
this.menuService.onItemSelect()
.pipe(
withLatestFrom(this.themeService.onMediaQueryChange()),
delay(20),
takeUntil(this.destroy$),
)
.subscribe(([item, [bpFrom, bpTo]]: [any, [NbMediaBreakpoint, NbMediaBreakpoint]]) => {
if (bpTo.width <= isBp.width) {
this.sidebarService.collapse('menu-sidebar');
}
});
this.themeService.getJsTheme()
.pipe(takeUntil(this.destroy$))
.subscribe(theme => this.currentTheme = theme.name);
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
isMenuSidebarPositionEnd(): boolean {
return this.sidebar.id === 'end';
}
isSettingsSidebarPositionEnd(): boolean {
return !this.isMenuSidebarPositionEnd();
}
}

View file

@ -12,6 +12,7 @@ import {
NbSelectModule,
NbIconModule,
NbThemeModule,
NbCardModule,
} from '@nebular/theme';
import { NbEvaIconsModule } from '@nebular/eva-icons';
import { NbSecurityModule } from '@nebular/security';
@ -21,6 +22,11 @@ import {
HeaderComponent,
SearchInputComponent,
TinyMCEComponent,
CallActionCardComponent,
ToggleSettingsButtonComponent,
LayoutDirectionSwitcherComponent,
SwitcherComponent,
ThemeSettingsComponent,
} from './components';
import {
CapitalizePipe,
@ -33,6 +39,7 @@ import {
OneColumnLayoutComponent,
ThreeColumnsLayoutComponent,
TwoColumnsLayoutComponent,
SampleLayoutComponent,
} from './layouts';
import { DEFAULT_THEME } from './styles/theme.default';
import { COSMIC_THEME } from './styles/theme.cosmic';
@ -52,6 +59,7 @@ const NB_MODULES = [
NbSelectModule,
NbIconModule,
NbEvaIconsModule,
NbCardModule,
];
const COMPONENTS = [
HeaderComponent,
@ -61,6 +69,12 @@ const COMPONENTS = [
OneColumnLayoutComponent,
ThreeColumnsLayoutComponent,
TwoColumnsLayoutComponent,
CallActionCardComponent,
ToggleSettingsButtonComponent,
LayoutDirectionSwitcherComponent,
SwitcherComponent,
SampleLayoutComponent,
ThemeSettingsComponent,
];
const PIPES = [
CapitalizePipe,

View file

@ -4,7 +4,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { NbThemeService } from '@nebular/theme';
import { AnalyticsService } from './@core/utils/analytics.service';
import { AbService } from './@core/utils/ab.service';
import { withLatestFrom, filter } from 'rxjs/operators';
@Component({
selector: 'ngx-app',
@ -12,10 +17,46 @@ import { AnalyticsService } from './@core/utils/analytics.service';
})
export class AppComponent implements OnInit {
constructor(private analytics: AnalyticsService) {
themes = ['default', 'cosmic', 'corporate', 'dark'];
constructor(private analytics: AnalyticsService,
private activatedRoute: ActivatedRoute,
private abService: AbService,
private themeService: NbThemeService) {
this.themeService.onThemeChange()
.subscribe((theme: any) => {
this.analytics.trackEvent('changeTheme', theme.name);
});
this.activatedRoute.queryParams
.subscribe((params: any) => {
if (params.theme && this.themes.includes(params.theme)) {
this.themeService.changeTheme(params.theme);
}
});
}
ngOnInit(): void {
const variants = [
AbService.VARIANT_THEME_CORPORATE,
AbService.VARIANT_THEME_DEFAULT,
AbService.VARIANT_THEME_COSMIC,
AbService.VARIANT_THEME_DARK,
];
this.analytics.trackPageViews();
this.abService.onAbEvent()
.pipe(
withLatestFrom(this.activatedRoute.queryParams),
filter(([e, params]: [{ name: string }, any]) => !params.theme),
)
.subscribe(([e, params]: [{ name: string }, any]) => {
const themeName = e.name.replace('theme-change-', '');
if (variants.includes(e.name) && this.themes.includes(themeName)) {
this.themeService.changeTheme(themeName);
}
});
}
}

View file

@ -1,3 +1,19 @@
<div class="row" *ngIf="showCallAction">
<div class="col-12 col-md-6">
<ngx-call-action-card title="Hire us to customize ngx-admin"
type="pantone"
link="https://www.akveo.com/contacts?utm_source=ngx_admin_demo&utm_medium=ramp_up_contact_card"
linkTitle="Contact us">
</ngx-call-action-card>
</div>
<div class="col-12 col-md-6">
<ngx-call-action-card title="Documentation and customization articles"
type="briefcase"
link="https://akveo.github.io/ngx-admin?utm_source=ngx_admin_demo&utm_medium=ramp_up_contact_card"
linkTitle="Learn more">
</ngx-call-action-card>
</div>
</div>
<div class="row">
<div class="col-xxxl-3 col-md-6" *ngFor="let statusCard of statusCards">
<ngx-status-card [title]="statusCard.title" [type]="statusCard.type">

View file

@ -1,7 +1,8 @@
import {Component, OnDestroy} from '@angular/core';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { takeWhile } from 'rxjs/operators' ;
import { SolarData } from '../../@core/data/solar';
import { AbService } from '../../@core/utils/ab.service';
interface CardSettings {
title: string;
@ -14,9 +15,10 @@ interface CardSettings {
styleUrls: ['./dashboard.component.scss'],
templateUrl: './dashboard.component.html',
})
export class DashboardComponent implements OnDestroy {
export class DashboardComponent implements OnInit, OnDestroy {
private alive = true;
showCallAction = true;
solarValue: number;
lightCard: CardSettings = {
@ -79,7 +81,8 @@ export class DashboardComponent implements OnDestroy {
};
constructor(private themeService: NbThemeService,
private solarService: SolarData) {
private solarService: SolarData,
private abService: AbService) {
this.themeService.getJsTheme()
.pipe(takeWhile(() => this.alive))
.subscribe(theme => {
@ -93,6 +96,12 @@ export class DashboardComponent implements OnDestroy {
});
}
ngOnInit() {
this.abService.onAbEvent(AbService.VARIANT_HIDE_CALL_ACTION)
.pipe(takeWhile(() => this.alive))
.subscribe(() => this.showCallAction = false );
}
ngOnDestroy() {
this.alive = false;
}

View file

@ -1,3 +1,19 @@
<div class="row" *ngIf="showCallAction">
<div class="col-12 col-md-6">
<ngx-call-action-card title="Hire us to customize ngx-admin"
type="pantone"
link="https://www.akveo.com/contacts?utm_source=ngx_admin_demo&utm_medium=ramp_up_contact_card"
linkTitle="Contact us">
</ngx-call-action-card>
</div>
<div class="col-12 col-md-6">
<ngx-call-action-card title="Documentation and customization articles"
type="briefcase"
link="https://akveo.github.io/ngx-admin?utm_source=ngx_admin_demo&utm_medium=ramp_up_contact_card"
linkTitle="Learn more">
</ngx-call-action-card>
</div>
</div>
<div class="row">
<div class="col-xxl-5">
<div class="row">

View file

@ -1,8 +1,26 @@
import { Component } from '@angular/core';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { takeWhile } from 'rxjs/operators';
import { AbService } from '../../@core/utils/ab.service';
@Component({
selector: 'ngx-ecommerce',
templateUrl: './e-commerce.component.html',
})
export class ECommerceComponent {
export class ECommerceComponent implements OnInit, OnDestroy {
private alive = true;
showCallAction = true;
constructor (private abService: AbService) {}
ngOnInit() {
this.abService.onAbEvent(AbService.VARIANT_HIDE_CALL_ACTION)
.pipe(takeWhile(() => this.alive))
.subscribe(() => this.showCallAction = false );
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -1,4 +1,4 @@
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { MENU_ITEMS } from './pages-menu';
@ -6,13 +6,19 @@ import { MENU_ITEMS } from './pages-menu';
selector: 'ngx-pages',
styleUrls: ['pages.component.scss'],
template: `
<ngx-one-column-layout>
<ngx-sample-layout>
<nb-menu [items]="menu"></nb-menu>
<router-outlet></router-outlet>
</ngx-one-column-layout>
</ngx-sample-layout>
`,
})
export class PagesComponent {
export class PagesComponent implements OnInit {
menu = MENU_ITEMS;
ngOnInit() {
if (window['dataLayer']) {
window['dataLayer'].push({'event': 'optimize.activate'});
}
}
}

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="46px" height="41px" viewBox="0 0 46 41" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 51.3 (57544) - http://www.bohemiancoding.com/sketch -->
<title>2</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Homepage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Banner-Blue" transform="translate(-36.000000, -35.000000)" fill-rule="nonzero">
<g id="2" transform="translate(36.000000, 35.000000)">
<g id="Page-1" transform="translate(11.500000, 0.000000)" fill="#728BB7">
<path d="M0.818882143,0.254015675 L1.31584643,1.29279656" id="Fill-23"></path>
</g>
<g id="Page-1" fill="#FFFFFF">
<path d="M25.9279,7.70327639 C24.0952381,7.63259259 21.9047619,7.63259259 20.0251143,7.70327639 C20.0251143,6.06937777 21.3467929,4.74579642 22.9765071,4.74579642 C24.6062214,4.74579642 25.9279,6.06937777 25.9279,7.70327639 Z" id="Fill-1"></path>
<path d="M26.2857143,37.6177778 C26.2857143,39.3600981 24.8152185,40.8888889 23,40.8888889 C21.1847815,40.8888889 19.7142857,39.3592627 19.7142857,37.6177778 L26.2857143,37.6177778 Z" id="Combined-Shape"></path>
<path d="M22.9765071,38.1586528 L38.1310429,38.1586528 C38.1310429,31.204912 33.7405071,35.9098815 33.7405071,19.7923153 C33.7405071,13.0756338 29.3499714,7.70311176 22.9765071,7.70311176 C16.6030429,7.70311176 12.2125071,13.0756338 12.2125071,19.7923153 C12.2125071,35.9098815 7.82279286,31.2040888 7.82279286,38.1586528 L22.9765071,38.1586528 Z" id="Fill-7" fill-opacity="0.3"></path>
<path d="M24.620925,35.958528 L37.316925,35.958528 C37.316925,29.7735838 33.6393893,33.9583398 33.6393893,19.6228343 C33.6393893,13.6502558 29.9610321,8.87202835 24.620925,8.87202835 C19.2816393,8.87202835 15.6032821,13.6502558 15.6032821,19.6228343 C15.6032821,33.0520817 12.3758893,30.2287707 11.9676393,34.9024616 C11.9183536,35.4654775 12.3290679,35.958528 12.8613536,35.958528 L24.620925,35.958528 Z" id="Fill-9" fill-opacity="0.3"></path>
<path d="M9.01222143,38.9817755 C7.85793169,38.9817755 6.94637071,37.9813615 7.06120453,36.8306604 C7.21523002,35.2690855 7.60988701,34.3401154 8.45000733,33.1886378 C8.53261933,33.075409 8.8324557,32.6736616 8.89441519,32.5892593 C9.06434674,32.3577754 9.19872982,32.1650315 9.32697216,31.9654834 C10.6913769,29.8424381 11.3910786,26.5543001 11.3910786,19.7923153 C11.3910786,12.487826 16.257961,6.87998903 22.9765071,6.87998903 C29.6950532,6.87998903 34.5619357,12.487826 34.5619357,19.7923153 C34.5619357,26.5550082 35.2617508,29.8429901 36.6264928,31.965988 C36.7547005,32.1654284 36.8890484,32.3580806 37.0589304,32.5894549 C37.1209192,32.6738818 37.4206585,33.0754285 37.5032257,33.1885727 C38.3435539,34.3400985 38.7383491,35.2689984 38.892637,36.8307194 C39.0060885,37.9817856 38.094914,38.9817755 36.9416143,38.9817755 L9.01222143,38.9817755 Z M36.9416143,37.3355301 C37.1266604,37.3355301 37.2754476,37.17224 37.257753,36.9927124 C37.134751,35.7476709 36.854787,35.0889535 36.1771057,34.1603074 C36.1011278,34.0561928 35.8033263,33.6572421 35.7356452,33.5650624 C35.5471912,33.3083935 35.394303,33.0891549 35.2453778,32.8574863 C33.6814134,30.4245773 32.9190786,26.8428552 32.9190786,19.7923153 C32.9190786,13.3498889 28.732766,8.52623449 22.9765071,8.52623449 C17.2202483,8.52623449 13.0339357,13.3498889 13.0339357,19.7923153 C13.0339357,26.8420854 12.2717409,30.4239004 10.7081964,32.8568117 C10.5592284,33.0886094 10.4062969,33.3079572 10.2177846,33.5647521 C10.1501295,33.656913 9.85223844,34.0560539 9.77622237,34.1602424 C9.09875195,35.0887902 8.81890193,35.74752 8.69600198,36.9935256 C8.67812468,37.1726674 8.82652251,37.3355301 9.01222143,37.3355301 L36.9416143,37.3355301 Z" id="Stroke-11"></path>
<path d="M29.3128429,15.9061883 C29.3128429,17.6240454 28.3024857,19.0167691 27.0547357,19.0167691 C25.8078071,19.0167691 24.7966286,17.6240454 24.7966286,15.9061883 C24.7966286,14.187508 25.8078071,12.7947843 27.0547357,12.7947843 C28.3024857,12.7947843 29.3128429,14.187508 29.3128429,15.9061883" id="Fill-13"></path>
<path d="M14.0775467,3.4475639 L14.7891536,3.03640007 L15.6097888,4.46254921 L14.8981818,4.87371303 C9.91246081,7.7544441 6.77629286,13.0733488 6.77629286,18.9430996 L6.77629286,19.7662223 L5.13343571,19.7662223 L5.13343571,18.9430996 C5.13343571,12.4786305 8.58829126,6.6192353 14.0775467,3.4475639 Z" id="Stroke-15"></path>
<path d="M40.81925,18.9430996 L40.81925,19.7662223 L39.1763929,19.7662223 L39.1763929,18.9430996 C39.1763929,13.0733488 36.0402249,7.7544441 31.0545039,4.87371303 L30.342897,4.46254921 L31.1635321,3.03640007 L31.875139,3.4475639 C37.3643945,6.6192353 40.81925,12.4786305 40.81925,18.9430996 Z" id="Stroke-17"></path>
<path d="M11.517838,0.41146011 L12.2294604,0.000323336602 L13.0500416,1.42650367 L12.3384192,1.83764044 C5.77341126,5.63054503 1.64302143,12.6354563 1.64302143,20.364221 L1.64302143,21.1873437 L0.000164285714,21.1873437 L0.000164285714,20.364221 C0.000164285714,12.0407205 4.44926147,4.49529929 11.517838,0.41146011 Z" id="Stroke-19"></path>
<path d="M45.9531786,20.364221 L45.9531786,21.1873437 L44.3103214,21.1873437 L44.3103214,20.364221 C44.3103214,12.6354563 40.1799316,5.63054503 33.6149237,1.83764044 L32.9033012,1.42650367 L33.7238824,0.000323336602 L34.4355049,0.41146011 C41.5040814,4.49529929 45.9531786,12.0407205 45.9531786,20.364221 Z" id="Stroke-21"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="47px" height="42px" viewBox="0 0 47 42" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 51.3 (57544) - http://www.bohemiancoding.com/sketch -->
<title>1</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Homepage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Banner-White" transform="translate(-36.000000, -34.000000)">
<g id="Group-3-Copy" transform="translate(12.000000, 7.000000)">
<g id="1" transform="translate(24.000000, 27.000000)">
<g id="Page-1" transform="translate(12.493243, 0.000000)" fill="#728BB7" fill-rule="nonzero">
<path d="M0.818401014,0.254141176 L1.31507331,1.29343529" id="Fill-23"></path>
</g>
<g id="Group-3" transform="translate(0.200000, 0.200000)">
<g id="Page-1">
<path d="M22.9630074,4.74814118 C24.5917642,4.74814118 25.9126662,6.07237647 25.9126662,7.70708235 C25.9126662,9.34096471 24.5917642,10.6660235 22.9630074,10.6660235 C21.3342507,10.6660235 20.0133486,9.34096471 20.0133486,7.70708235 C20.0133486,6.07237647 21.3342507,4.74814118 22.9630074,4.74814118" id="Fill-1" fill="#3366FF" fill-rule="nonzero"></path>
<path d="M26.3196912,36.0808824 L26.3196912,38.0886471 C26.3196912,39.9481765 24.8173601,41.4552353 22.9628432,41.4552353 C21.1083264,41.4552353 19.6059953,39.9473529 19.6059953,38.0886471 L19.6059953,36.0808824 L26.3196912,36.0808824 Z" id="Fill-3" fill="#457AE6" fill-rule="nonzero"></path>
<path d="M22.9630074,36.0808824 L22.9630074,41.4552353 C24.8175243,41.4552353 26.3198554,39.9481765 26.3198554,38.0886471 L26.3198554,36.0808824 L22.9630074,36.0808824 Z" id="Fill-5" fill="#3366FF" fill-rule="nonzero"></path>
<path d="M22.9630074,38.1775059 L38.1086392,38.1775059 C38.1086392,31.2203294 33.7206831,35.9276235 33.7206831,19.8020941 C33.7206831,13.0820941 29.332727,7.70691765 22.9630074,7.70691765 C16.5932878,7.70691765 12.2053318,13.0820941 12.2053318,19.8020941 C12.2053318,35.9276235 7.81819662,31.2195059 7.81819662,38.1775059 L22.9630074,38.1775059 Z" id="Fill-7" fill="#6193FF"></path>
<path d="M24.6064591,35.9762941 L37.2949997,35.9762941 C37.2949997,29.7882941 33.6196247,33.9751176 33.6196247,19.6325294 C33.6196247,13.657 29.9434287,8.87641176 24.6064591,8.87641176 C19.2703105,8.87641176 15.5941145,13.657 15.5941145,19.6325294 C15.5941145,33.0684118 12.3686179,30.2437059 11.9606078,34.9197059 C11.911351,35.483 12.321824,35.9762941 12.853797,35.9762941 L24.6064591,35.9762941 Z" id="Fill-9" fill="#99C0FF"></path>
<path d="M9.00692635,39.0010353 C7.85331481,39.0010353 6.94228941,38.000127 7.05705576,36.8488574 C7.21099075,35.2865109 7.60541586,34.3570819 8.44504257,33.2050354 C8.52760604,33.0917506 8.82726625,32.6898047 8.88918933,32.6053607 C9.05902104,32.3737625 9.19332517,32.1809233 9.32149215,31.9812766 C10.6850953,29.8571824 11.3843858,26.5674198 11.3843858,19.8020941 C11.3843858,12.4939959 16.2484088,6.88338824 22.9630074,6.88338824 C29.6776061,6.88338824 34.5416291,12.4939959 34.5416291,19.8020941 C34.5416291,26.5681283 35.241033,29.8577347 36.6049732,31.9817815 C36.7331055,32.1813204 36.8673745,32.3740678 37.0371566,32.6055564 C37.099109,32.690025 37.3986722,33.0917701 37.4811909,33.2049702 C38.3210254,34.3570649 38.7155886,35.2864238 38.8697859,36.8489164 C38.9831707,38.0005513 38.0725315,39.0010353 36.9199095,39.0010353 L9.00692635,39.0010353 Z M36.9199095,37.3539765 C37.1048468,37.3539765 37.2535467,37.1906058 37.2358624,37.0109894 C37.1129327,35.7653328 36.8331332,35.10629 36.1558501,34.177185 C36.0799168,34.073019 35.7822903,33.6738712 35.7146489,33.5816459 C35.5263057,33.3248502 35.3735073,33.1055033 35.2246695,32.8737202 C33.6616241,30.4396092 32.8997372,26.8561175 32.8997372,19.8020941 C32.8997372,13.3564846 28.7158843,8.53044706 22.9630074,8.53044706 C17.2101306,8.53044706 13.0262777,13.3564846 13.0262777,19.8020941 C13.0262777,26.8553473 12.2645307,30.4389319 10.7019049,32.8730453 C10.5530244,33.1049575 10.4001827,33.3244137 10.2117812,33.5813354 C10.1441659,33.6735419 9.84644981,34.07288 9.77047841,34.1771199 C9.09340603,35.1061266 8.81372043,35.7651818 8.69089269,37.011803 C8.6730259,37.1910334 8.82133654,37.3539765 9.00692635,37.3539765 L36.9199095,37.3539765 Z" id="Stroke-11" fill="#3366FF" fill-rule="nonzero"></path>
<path d="M29.2956203,15.9140471 C29.2956203,17.6327529 28.2858568,19.0261647 27.0388399,19.0261647 C25.7926439,19.0261647 24.7820595,17.6327529 24.7820595,15.9140471 C24.7820595,14.1945176 25.7926439,12.8011059 27.0388399,12.8011059 C28.2858568,12.8011059 29.2956203,14.1945176 29.2956203,15.9140471" id="Fill-13" fill="#FFFFFF" fill-rule="nonzero"></path>
<path d="M14.0692756,3.44926724 L14.7804643,3.03790027 L15.6006173,4.46475402 L14.8894285,4.87612099 C9.90663681,7.75827535 6.77231149,13.079808 6.77231149,18.9524588 L6.77231149,19.7759882 L5.13041959,19.7759882 L5.13041959,18.9524588 C5.13041959,12.4847958 8.58324526,6.62250567 14.0692756,3.44926724 Z" id="Stroke-15" fill="#3366FF" fill-rule="nonzero"></path>
<path d="M40.7952669,18.9524588 L40.7952669,19.7759882 L39.153375,19.7759882 L39.153375,18.9524588 C39.153375,13.079808 36.0190497,7.75827535 31.036258,4.87612099 L30.3250692,4.46475402 L31.1452222,3.03790027 L31.8564109,3.44926724 C37.3424412,6.62250567 40.7952669,12.4847958 40.7952669,18.9524588 Z" id="Stroke-17" fill="#3366FF" fill-rule="nonzero"></path>
<path d="M11.5110707,0.4116634 L12.2222751,0.000323496353 L13.0423742,1.42720846 L12.3311698,1.83854836 C5.77001913,5.63332692 1.64205608,12.6416991 1.64205608,20.3742824 L1.64205608,21.1978118 L0.000164189189,21.1978118 L0.000164189189,20.3742824 C0.000164189189,12.0466694 4.44664733,4.49752028 11.5110707,0.4116634 Z" id="Stroke-19" fill="#3366FF" fill-rule="nonzero"></path>
<path d="M45.9261791,20.3742824 L45.9261791,21.1978118 L44.2842872,21.1978118 L44.2842872,20.3742824 C44.2842872,12.6416991 40.1563241,5.63332692 33.5951734,1.83854836 L32.8839691,1.42720846 L33.7040681,0.000323496353 L34.4152725,0.4116634 C41.4796959,4.49752028 45.9261791,12.0466694 45.9261791,20.3742824 Z" id="Stroke-21" fill="#3366FF" fill-rule="nonzero"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1 @@
google-site-verification: google46533d2e7a851062.html

View file

@ -2,18 +2,36 @@
<html>
<head>
<meta charset="utf-8">
<title>ngx-admin Demo Application</title>
<title>ngx-admin - Angular 8, Bootstrap 4 Admin dashboard template</title>
<meta name="description" content="Free Angular 7 Bootstrap admin dashboard template.">
<meta name="keywords" content="admin,dashboard,template,angular 7,bootstrap,panel,html,css,javascript">
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="favicon.png">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<!-- Google Tag Manager -->
<script>
dataLayer = [];
</script>
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-KT9L237');</script>
<!-- End Google Tag Manager -->
</head>
<body>
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-KT9L237"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<ngx-app>Loading...</ngx-app>
<style>@-webkit-keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@-moz-keyframes spin{0%{-moz-transform:rotate(0)}100%{-moz-transform:rotate(360deg)}}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.spinner{position:fixed;top:0;left:0;width:100%;height:100%;z-index:1003;background: #000000;overflow:hidden} .spinner div:first-child{display:block;position:relative;left:50%;top:50%;width:150px;height:150px;margin:-75px 0 0 -75px;border-radius:50%;box-shadow:0 3px 3px 0 rgba(255,56,106,1);transform:translate3d(0,0,0);animation:spin 2s linear infinite} .spinner div:first-child:after,.spinner div:first-child:before{content:'';position:absolute;border-radius:50%} .spinner div:first-child:before{top:5px;left:5px;right:5px;bottom:5px;box-shadow:0 3px 3px 0 rgb(255, 228, 32);-webkit-animation:spin 3s linear infinite;animation:spin 3s linear infinite} .spinner div:first-child:after{top:15px;left:15px;right:15px;bottom:15px;box-shadow:0 3px 3px 0 rgba(61, 175, 255,1);animation:spin 1.5s linear infinite}</style>
<style>@-webkit-keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@-moz-keyframes spin{0%{-moz-transform:rotate(0)}100%{-moz-transform:rotate(360deg)}}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.spinner{position:fixed;top:0;left:0;width:100%;height:100%;z-index:1003;background: #000000;overflow:hidden} .spinner div:first-child{display:block;position:relative;left:50%;top:50%;width:150px;height:150px;margin:-75px 0 0 -75px;border-radius:50%;box-shadow:0 3px 3px 0 #ff3d71;transform:translate3d(0,0,0);animation:spin 2s linear infinite} .spinner div:first-child:after,.spinner div:first-child:before{content:'';position:absolute;border-radius:50%} .spinner div:first-child:before{top:5px;left:5px;right:5px;bottom:5px;box-shadow:0 3px 3px 0 #ffaa00;-webkit-animation:spin 3s linear infinite;animation:spin 3s linear infinite} .spinner div:first-child:after{top:15px;left:15px;right:15px;bottom:15px;box-shadow:0 3px 3px 0 #0095ff;animation:spin 1.5s linear infinite}</style>
<div id="nb-global-spinner" class="spinner">
<div class="blob blob-0"></div>
<div class="blob blob-1"></div>