├── .angular-cli.json ├── .editorconfig ├── .gitignore ├── .stylelintrc.json ├── .travis.yml ├── LICENSE ├── README.md ├── e2e ├── app.e2e-spec.ts ├── app.po.ts └── tsconfig.e2e.json ├── karma.conf.js ├── package.json ├── protractor.conf.js ├── server.js ├── src ├── app │ ├── app-routing.module.ts │ ├── app.component.html │ ├── app.component.scss │ ├── app.component.spec.ts │ ├── app.component.ts │ ├── app.module.ts │ ├── dashboard │ │ ├── dashboard-routing.module.ts │ │ ├── dashboard.component.html │ │ ├── dashboard.component.ts │ │ └── dashboard.module.ts │ ├── plong │ │ ├── plong-routing.module.ts │ │ ├── plong.component.html │ │ ├── plong.component.ts │ │ └── plong.module.ts │ └── shared │ │ ├── components │ │ ├── alert │ │ │ ├── alert.component.html │ │ │ └── alert.component.ts │ │ ├── footerbar │ │ │ ├── footerbar.component.html │ │ │ └── footerbar.component.ts │ │ ├── headerbar │ │ │ ├── headerbar.component.html │ │ │ └── headerbar.component.ts │ │ ├── layout-admin │ │ │ ├── layout-admin.component.html │ │ │ └── layout-admin.component.ts │ │ ├── shared-components.module.ts │ │ └── sidebar │ │ │ ├── sidebar.component.html │ │ │ └── sidebar.component.ts │ │ ├── models │ │ └── alert.model.ts │ │ ├── services │ │ ├── alert.service.ts │ │ ├── api.service.ts │ │ └── services.module.ts │ │ ├── shared-lazy.module.ts │ │ └── shared.module.ts ├── assets │ ├── .gitkeep │ └── i18n │ │ ├── de.json │ │ └── en.json ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── favicon.ico ├── index.html ├── main.ts ├── polyfills.ts ├── scss │ ├── _alert.scss │ ├── _footerbar.scss │ ├── _headerbar.scss │ ├── _layout-admin.scss │ ├── _mainbar.scss │ ├── _mixins.scss │ ├── _sidebar.scss │ ├── _variables.scss │ └── bootstrap_overwrite │ │ ├── _variables.scss │ │ └── bootstrap.scss ├── styles.scss ├── test.ts ├── tsconfig.app.json ├── tsconfig.spec.json └── typings.d.ts ├── tsconfig.json ├── tslint.json └── yarn.lock /.angular-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "project": { 4 | "name": "tox-ngx" 5 | }, 6 | "apps": [ 7 | { 8 | "root": "src", 9 | "outDir": "dist", 10 | "assets": [ 11 | "assets", 12 | "favicon.ico", 13 | { 14 | "glob": "**/*", 15 | "input": "../node_modules/font-awesome/fonts", 16 | "output": "./assets/fonts" 17 | }, 18 | { 19 | "glob": "**/*", 20 | "input": "../node_modules/font-awesome/css", 21 | "output": "./assets/css" 22 | } 23 | ], 24 | "index": "index.html", 25 | "main": "main.ts", 26 | "polyfills": "polyfills.ts", 27 | "test": "test.ts", 28 | "tsconfig": "tsconfig.app.json", 29 | "testTsconfig": "tsconfig.spec.json", 30 | "prefix": "tox", 31 | "styles": [ 32 | "styles.scss" 33 | ], 34 | "scripts": [], 35 | "environmentSource": "environments/environment.ts", 36 | "environments": { 37 | "dev": "environments/environment.ts", 38 | "prod": "environments/environment.prod.ts" 39 | } 40 | } 41 | ], 42 | "e2e": { 43 | "protractor": { 44 | "config": "./protractor.conf.js" 45 | } 46 | }, 47 | "lint": [ 48 | { 49 | "project": "src/tsconfig.app.json" 50 | }, 51 | { 52 | "project": "src/tsconfig.spec.json" 53 | }, 54 | { 55 | "project": "e2e/tsconfig.e2e.json" 56 | } 57 | ], 58 | "test": { 59 | "karma": { 60 | "config": "./karma.conf.js" 61 | } 62 | }, 63 | "defaults": { 64 | "styleExt": "scss", 65 | "component": {} 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | dist/ 61 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "stylelint-config-sass-guidelines", 3 | "rules": { 4 | "string-quotes": "double", 5 | "number-leading-zero": "never", 6 | "scss/dollar-variable-colon-space-after": null, 7 | "order/properties-alphabetical-order": null, 8 | "max-nesting-depth": null, 9 | "selector-max-compound-selectors": null, 10 | "selector-max-id": null 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # https://docs.travis-ci.com/user/reference/overview/ 2 | dist: trusty 3 | group: travis_lts 4 | sudo: false 5 | language: node_js 6 | node_js: 7 | - '6' 8 | - '7' 9 | - '8' 10 | 11 | cache: 12 | yarn: true 13 | directories: 14 | - ./node_modules 15 | 16 | addons: 17 | apt: 18 | sources: 19 | - google-chrome 20 | packages: 21 | - google-chrome-stable 22 | 23 | before_install: 24 | - export CHROME_BIN=chromium-browser 25 | - export DISPLAY=:99.0 26 | - sh -e /etc/init.d/xvfb start 27 | 28 | script: 29 | - yarn run lint 30 | - yarn run test 31 | - yarn run e2e 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Enrico Hoffmann 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![github tag][github-tag-image]][github-tag-url] 2 | [![Build Status][travis-image]][travis-url] 3 | [![Dependency Status][david-image]][david-url] 4 | [![DevDependencies Status][david-dev-image]][david-dev-url] 5 | [![DependencyCI Status][dependencyci-image]][dependencyci-url] 6 | [![License][license-image]][license-url] 7 | 8 | *** 9 | 10 | # tox-ngx 11 | 12 | playground of angular 4 app ... admin dasgboard ... 13 | 14 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.0.0. 15 | 16 | [Demo](https://tox-ngx.herokuapp.com/) 17 | 18 | ### some ToDos 19 | 20 | * ✅ (v0.2.0) bootstrap 4.0.0-beta 21 | * ✅ (v0.1.0) font awesome 4.7 22 | * loading bar 23 | * ✅ (v0.3.0) ng-bootstrap 24 | * ng-formly 25 | * ng-formly incl. custom types 26 | * favicons for multiple devices 27 | * main font as part of dist (not linked via cdn) 28 | * ✅ (v0.7.0) basic api service 29 | * ✅ (v0.7.0) basic alert service 30 | * ✅ (v0.6.0) translation (samples in en/de) 31 | * ✅ (v0.5.0) spinner at app loading page 32 | * ✅ (v0.4.0) heroku instance incl auto deployment 33 | 34 | ## Development server 35 | 36 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 37 | 38 | ## Code scaffolding 39 | 40 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class/module`. 41 | 42 | ## Build 43 | 44 | 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. 45 | 46 | ## Running unit tests 47 | 48 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 49 | 50 | ## Running end-to-end tests 51 | 52 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 53 | Before running the tests make sure you are serving the app via `ng serve`. 54 | 55 | ## Further help 56 | 57 | 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). 58 | 59 | *** 60 | 61 | [github-tag-image]: https://img.shields.io/github/tag/dasrick/tox-ngx.svg?style=flat-square 62 | [github-tag-url]: https://github.com/dasrick/tox-ngx 63 | 64 | [travis-image]: https://img.shields.io/travis/dasrick/tox-ngx.svg?style=flat-square 65 | [travis-url]: https://travis-ci.org/dasrick/tox-ngx 66 | 67 | [david-image]: https://img.shields.io/david/dasrick/tox-ngx.svg?style=flat-square 68 | [david-url]: https://david-dm.org/dasrick/tox-ngx 69 | [david-dev-image]: https://img.shields.io/david/dev/dasrick/tox-ngx.svg?style=flat-square 70 | [david-dev-url]: https://david-dm.org/dasrick/tox-ngx?type=dev 71 | 72 | [dependencyci-image]: https://dependencyci.com/github/dasrick/tox-ngx/badge 73 | [dependencyci-url]: https://dependencyci.com/github/dasrick/tox-ngx 74 | 75 | [david-optional-image]: https://img.shields.io/david/optional/dasrick/tox-ngx.svg?style=flat-square 76 | [david-peer-image]: https://img.shields.io/david/peer/dasrick/tox-ngx.svg?style=flat-square 77 | 78 | [license-image]: https://img.shields.io/github/license/dasrick/tox-ngx.svg?style=flat-square 79 | [license-url]: https://github.com/dasrick/tox-ngx/blob/master/LICENSE 80 | -------------------------------------------------------------------------------- /e2e/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { ToxNgxPage } from './app.po'; 2 | 3 | describe('tox-ngx App', () => { 4 | let page: ToxNgxPage; 5 | 6 | beforeEach(() => { 7 | page = new ToxNgxPage(); 8 | }); 9 | 10 | it('should display message saying app works', () => { 11 | page.navigateTo(); 12 | // expect(page.getParagraphText()).toEqual('tox works!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /e2e/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, element, by } from 'protractor'; 2 | 3 | export class ToxNgxPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('tox-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types":[ 8 | "jasmine", 9 | "node" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/0.13/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular/cli'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular/cli/plugins/karma') 14 | ], 15 | client:{ 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | files: [ 19 | { pattern: './src/test.ts', watched: false } 20 | ], 21 | preprocessors: { 22 | './src/test.ts': ['@angular/cli'] 23 | }, 24 | mime: { 25 | 'text/x-typescript': ['ts','tsx'] 26 | }, 27 | coverageIstanbulReporter: { 28 | reports: [ 'html', 'lcovonly' ], 29 | fixWebpackSourcePaths: true 30 | }, 31 | angularCli: { 32 | environment: 'dev' 33 | }, 34 | reporters: config.angularCli && config.angularCli.codeCoverage 35 | ? ['progress', 'coverage-istanbul'] 36 | : ['progress', 'kjhtml'], 37 | port: 9876, 38 | colors: true, 39 | logLevel: config.LOG_INFO, 40 | autoWatch: true, 41 | browsers: ['Chrome'], 42 | singleRun: false 43 | }); 44 | }; 45 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tox-ngx", 3 | "version": "0.9.0", 4 | "license": "MIT", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/dasrick/tox-ngx.git" 8 | }, 9 | "bugs": { 10 | "url": "https://github.com/dasrick/tox-ngx/issues" 11 | }, 12 | "homepage": "https://github.com/dasrick/tox-ngx#readme", 13 | "scripts": { 14 | "ng": "ng", 15 | "start": "node server.js", 16 | "build": "ng build -prod -aot", 17 | "test": "ng test --single-run --code-coverage", 18 | "e2e": "ng e2e", 19 | "lint": "npm-run-all lint:*", 20 | "lint:ts": "ng lint --type-check", 21 | "lint:scss": "stylelint src/*.scss src/**/*.scss src/**/**/*.scss", 22 | "postinstall": "ng build --aot -prod" 23 | }, 24 | "dependencies": { 25 | "@angular/cli": "^1.4.2", 26 | "@angular/common": "^5.0.5", 27 | "@angular/compiler": "^5.0.5", 28 | "@angular/compiler-cli": "^5.0.5", 29 | "@angular/core": "^5.0.5", 30 | "@angular/forms": "^5.0.5", 31 | "@angular/http": "^5.0.5", 32 | "@angular/platform-browser": "^5.0.5", 33 | "@angular/platform-browser-dynamic": "^5.0.5", 34 | "@angular/router": "^5.0.5", 35 | "@ng-bootstrap/ng-bootstrap": "^1.0.0-beta.6", 36 | "@ngx-translate/core": "^9.0.1", 37 | "@ngx-translate/http-loader": "^2.0.0", 38 | "bootstrap": "4.0.0-beta", 39 | "core-js": "^2.4.1", 40 | "express": "^4.15.4", 41 | "font-awesome": "^4.7.0", 42 | "rxjs": "^5.5.5", 43 | "typescript": "2.4.2", 44 | "zone.js": "^0.8.4" 45 | }, 46 | "devDependencies": { 47 | "@types/jasmine": "^2.5.54", 48 | "@types/node": "^8.0.25", 49 | "codelyzer": "^4.0.1", 50 | "jasmine-core": "^2.8.0", 51 | "jasmine-spec-reporter": "^4.2.1", 52 | "karma": "^1.7.0", 53 | "karma-chrome-launcher": "^2.2.0", 54 | "karma-cli": "~1.0.1", 55 | "karma-coverage-istanbul-reporter": "^1.3.0", 56 | "karma-jasmine": "~1.1.0", 57 | "karma-jasmine-html-reporter": "^0.2.2", 58 | "npm-run-all": "^4.1.1", 59 | "postcss": "^6.0.14", 60 | "postcss-sass": "^0.2.0", 61 | "protractor": "~5.2.0", 62 | "stylelint": "^8.0.0", 63 | "stylelint-config-sass-guidelines": "^4.0.1", 64 | "stylelint-order": "^0.8.0", 65 | "stylelint-scss": "^2.2.0", 66 | "ts-node": "^3.0.0", 67 | "tslint": "^5.6.0" 68 | }, 69 | "engines": { 70 | "node": ">=8.2.1" 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './e2e/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | beforeLaunch: function() { 23 | require('ts-node').register({ 24 | project: 'e2e/tsconfig.e2e.json' 25 | }); 26 | }, 27 | onPrepare() { 28 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const express = require('express'); 3 | const app = express(); 4 | 5 | // If an incoming request uses 6 | // a protocol other than HTTPS, 7 | // redirect that request to the 8 | // same url but with HTTPS 9 | const forceSSL = function() { 10 | return function (req, res, next) { 11 | if (req.headers['x-forwarded-proto'] !== 'https') { 12 | return res.redirect(['https://', req.get('Host'), req.url].join('')); 13 | } 14 | next(); 15 | } 16 | }; 17 | 18 | // Instruct the app 19 | // to use the forceSSL 20 | // middleware 21 | app.use(forceSSL()); 22 | 23 | // Run the app by serving the static files 24 | // in the dist directory 25 | app.use(express.static(__dirname + '/dist')); 26 | 27 | // For all GET requests, send back index.html 28 | // so that PathLocationStrategy can be used 29 | app.get('/*', function(req, res) { 30 | res.sendFile(path.join(__dirname + '/dist/index.html')); 31 | }); 32 | 33 | // Start the app by listening on the default 34 | // Heroku port 35 | app.listen(process.env.PORT || 8080); 36 | -------------------------------------------------------------------------------- /src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | 4 | // Layouts 5 | import { LayoutAdminComponent } from './shared/components/layout-admin/layout-admin.component'; 6 | // import { LayoutSimpleComponent } from './shared/layouts/simple/simple.component'; 7 | 8 | const routes: Routes = [ 9 | { 10 | path: '', 11 | redirectTo: 'dashboard', 12 | pathMatch: 'full', 13 | }, 14 | { 15 | path: '', 16 | component: LayoutAdminComponent, 17 | children: [ 18 | { 19 | path: 'dashboard', 20 | loadChildren: './dashboard/dashboard.module#DashboardModule' 21 | }, 22 | { 23 | path: 'plong', 24 | loadChildren: './plong/plong.module#PlongModule' 25 | }, 26 | // { 27 | // path: 'offerassets', 28 | // loadChildren: './offerassets/offerassets.module#OfferassetsModule' 29 | // }, 30 | // { 31 | // path: 'offersetups', 32 | // loadChildren: './offersetups/offersetups.module#OffersetupsModule' 33 | // }, 34 | // { 35 | // path: 'offertemplates', 36 | // loadChildren: './offertemplates/offertemplates.module#OffertemplatesModule' 37 | // }, 38 | // { 39 | // path: 'offerteasers', 40 | // loadChildren: './offerteasers/offerteasers.module#OfferteasersModule' 41 | // }, 42 | ] 43 | }, 44 | // { 45 | // path: '', 46 | // component: LayoutSimpleComponent, 47 | // children: [ 48 | // { 49 | // path: 'error', 50 | // loadChildren: './error/error.module#ErrorModule' 51 | // }, 52 | // ] 53 | // }, 54 | {path: '**', redirectTo: 'error'} 55 | ]; 56 | 57 | @NgModule({ 58 | imports: [RouterModule.forRoot(routes)], 59 | exports: [RouterModule] 60 | }) 61 | export class AppRoutingModule { 62 | } 63 | -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/app/app.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dasrick/tox-ngx/6df7372ed983c71b181c5488fd0ee220808cced0/src/app/app.component.scss -------------------------------------------------------------------------------- /src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { RouterTestingModule } from '@angular/router/testing'; 3 | 4 | import { AppComponent } from './app.component'; 5 | // import { AlertComponent } from './shared/components/alert/alert.component'; 6 | 7 | // import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 8 | // import { SharedModule } from './shared/shared.module'; 9 | // import { TranslateModule } from '@ngx-translate/core'; 10 | 11 | import { ServicesModule } from './shared/services/services.module'; 12 | import { SharedComponentsModule } from './shared/components/shared-components.module'; 13 | 14 | describe('AppComponent', () => { 15 | beforeEach(async(() => { 16 | TestBed.configureTestingModule({ 17 | imports: [ 18 | RouterTestingModule, 19 | // NgbModule.forRoot(), 20 | // TranslateModule.forRoot(), 21 | // SharedModule, 22 | 23 | ServicesModule.forRoot(), 24 | SharedComponentsModule, 25 | ], 26 | declarations: [ 27 | AppComponent, 28 | // AlertComponent 29 | ], 30 | }).compileComponents(); 31 | })); 32 | 33 | it('should create the app', async(() => { 34 | const fixture = TestBed.createComponent(AppComponent); 35 | const app = fixture.debugElement.componentInstance; 36 | expect(app).toBeTruthy(); 37 | })); 38 | 39 | it(`should have as title 'tox works!'`, async(() => { 40 | const fixture = TestBed.createComponent(AppComponent); 41 | const app = fixture.debugElement.componentInstance; 42 | expect(app.title).toEqual('tox works!'); 43 | })); 44 | 45 | // it('should render title in a h1 tag', async(() => { 46 | // const fixture = TestBed.createComponent(AppComponent); 47 | // fixture.detectChanges(); 48 | // const compiled = fixture.debugElement.nativeElement; 49 | // expect(compiled.querySelector('h1').textContent).toContain('tox works!'); 50 | // })); 51 | }); 52 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { TranslateService } from '@ngx-translate/core'; 3 | 4 | @Component({ 5 | selector: 'tox-root', 6 | templateUrl: './app.component.html', 7 | styleUrls: ['./app.component.scss'] 8 | }) 9 | export class AppComponent { 10 | title = 'tox works!'; 11 | 12 | constructor(translate: TranslateService) { 13 | // this language will be used as a fallback when a translation isn't found in the current language 14 | // translate.setDefaultLang('en'); 15 | 16 | // the lang to use, if the lang isn't available, it will use the current loader to get them 17 | // translate.use('en'); 18 | 19 | // combined version of translation setup and browser language detection 20 | // translate.addLangs(['en', 'de']); 21 | // const browserLang: string = translate.getBrowserLang(); 22 | // translate.use(browserLang.match(/en|de/) ? browserLang : 'en'); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | import { LocationStrategy, HashLocationStrategy } from '@angular/common'; 5 | import { AppRoutingModule } from './app-routing.module'; 6 | import { AppComponent } from './app.component'; 7 | 8 | // shared components/pipes/services structure ... https://github.com/housseindjirdeh/angular2-hn 9 | // lazy shared structure ... https://github.com/ngx-translate/core/issues/209 10 | import { SharedModule } from './shared/shared.module'; 11 | import { ServicesModule } from './shared/services/services.module'; 12 | import { SharedComponentsModule } from './shared/components/shared-components.module'; 13 | 14 | // shared pipes module 15 | 16 | @NgModule({ 17 | declarations: [ 18 | AppComponent, 19 | ], 20 | imports: [ 21 | BrowserModule, 22 | AppRoutingModule, 23 | 24 | SharedModule, 25 | ServicesModule.forRoot(), 26 | SharedComponentsModule, 27 | ], 28 | providers: [ 29 | { 30 | provide: LocationStrategy, 31 | useClass: HashLocationStrategy 32 | }, 33 | ], 34 | bootstrap: [AppComponent] 35 | }) 36 | export class AppModule { 37 | } 38 | -------------------------------------------------------------------------------- /src/app/dashboard/dashboard-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | 4 | import { DashboardComponent } from './dashboard.component'; 5 | 6 | const routes: Routes = [ 7 | { 8 | path: '', 9 | component: DashboardComponent, 10 | } 11 | ]; 12 | 13 | @NgModule({ 14 | imports: [RouterModule.forChild(routes)], 15 | exports: [RouterModule] 16 | }) 17 | export class DashboardRoutingModule { 18 | } 19 | -------------------------------------------------------------------------------- /src/app/dashboard/dashboard.component.html: -------------------------------------------------------------------------------- 1 |

2 | {{title}} 3 |

4 |

font awesome example

5 |

boostrap example Button

6 |

translate: {{ 'teststring' | translate }} - {{ 'common.hello' | translate }}

7 | 8 |

ng-bootstrap example

9 | {{ 'common.hello' | translate }} 10 | 11 |
12 |
13 |
14 | 15 |
16 |

Hello World!

17 | 62 |
63 | 64 |
65 | 66 |
67 |
68 | 69 |
70 |

Hello, world!

71 |

This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.

72 |

It uses utility classes for typography and spacing to space content out within the larger container.

73 |

Learn more

74 |
75 | 76 |
77 |
78 |

Recent Orders

79 | 80 | 89 | 90 |
91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 |
Order #ProductCustomerStatus
0001Product Name 1Customer 1Complete
0002Product Name 2Customer 2Complete
0003Product Name 3Customer 3Processing
0004Product Name 4Customer 4Pending
146 |
147 |
148 |
149 | 150 |
151 |
152 |

Articles

153 | 154 | 163 | 164 |
Latest news
165 | 166 |
167 | 168 |
169 |
170 |
171 |
172 |
173 |
30
174 | 175 |
Jun
176 |
177 | 178 |
179 |

Lorem ipsum dolor sit amet

180 | 181 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer at sodales nisl. Donec malesuada orci ornare risus finibus feugiat.

182 |
183 |
184 |
185 | 186 |
187 |
188 | 189 |
190 |
191 |
192 |
193 |
30
194 | 195 |
Jun
196 |
197 | 198 |
199 |

Lorem ipsum dolor sit amet

200 | 201 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer at sodales nisl. Donec malesuada orci ornare risus finibus feugiat.

202 |
203 |
204 |
205 | 206 |
207 |
208 | 209 |
210 |
211 |
212 |
213 |
30
214 | 215 |
Jun
216 |
217 | 218 |
219 |

Lorem ipsum dolor sit amet

220 | 221 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer at sodales nisl. Donec malesuada orci ornare risus finibus feugiat.

222 |
223 |
224 |
225 | 226 |
227 |
228 |
229 |
230 |
231 |
232 | 233 |
234 |
235 |
236 |

Top Users

237 | 238 |
Most active this week
239 | 240 |
241 |
242 | profile photo 243 |
244 | 245 |
246 |
Username 1
247 | 248 |
249 |
250 |
251 |
252 | 253 |
254 |
75%
255 |
256 |
257 | 258 |
259 |
260 | profile photo 261 |
262 | 263 |
264 |
Username 2
265 | 266 |
267 |
268 |
269 |
270 | 271 |
272 |
50%
273 |
274 |
275 | 276 |
277 |
278 | profile photo 279 |
280 | 281 |
282 |
Username 3
283 | 284 |
285 |
286 |
287 |
288 | 289 |
290 |
25%
291 |
292 |
293 | 294 |
295 | 296 |
297 | 298 |
299 | 300 |

Timeline

301 | 302 |
What's coming up
303 | 304 |
    305 |
  • 306 |
    307 | 308 |
    309 |
    310 |
    Lorem ipsum
    311 |
    312 | 313 |
    314 |

    Lorem ipsum dolor sit amet, consectetur adipiscing elit.

    315 |
    316 |
    317 |
  • 318 |
  • 319 |
    320 | 321 |
    322 |
    323 |
    Dolor
    324 |
    325 | 326 |
    327 |

    Lorem ipsum dolor sit amet, consectetur adipiscing elit.

    328 |
    329 |
    330 |
  • 331 |
  • 332 |
    333 | 334 |
    335 |
    336 |
    Sit amet
    337 |
    338 | 339 |
    340 |

    Lorem ipsum dolor sit amet, consectetur adipiscing elit.

    341 |
    342 |
    343 |
  • 344 |
345 |
346 |
347 | 348 |
349 |
350 |

Todo List

351 | 352 | 359 | 360 |
A simple checklist
361 | 362 |
    363 |
  • 364 |
    365 | 366 | 367 | 368 | 369 |
    370 |
    371 |
  • 372 |
  • 373 |
    374 | 375 | 376 | 377 | 378 |
    379 |
    380 |
  • 381 |
  • 382 |
    383 | 384 | 385 | 386 | 387 |
    388 |
    389 |
  • 390 |
  • 391 |
    392 | 393 | 394 | 395 | 396 |
    397 |
    398 |
  • 399 |
  • 400 |
    401 | 402 | 403 | 404 | 405 |
    406 |
    407 |
  • 408 |
409 | 410 | 416 |
417 |
418 |
419 |
420 | 421 |
422 |
423 |
424 |
425 |

Top Users

426 | 427 | 434 | 435 |
Most active this week
436 | 437 |
438 |
439 | profile photo 440 |
441 | 442 |
443 |
Username 1
444 | 445 |
446 |
447 |
448 |
449 | 450 |
451 |
75%
452 |
453 |
454 | 455 |
456 |
457 | profile photo 458 |
459 | 460 |
461 |
Username 2
462 | 463 |
464 |
465 |
466 |
467 | 468 |
469 |
50%
470 |
471 |
472 | 473 |
474 |
475 | profile photo 476 |
477 | 478 |
479 |
Username 3
480 | 481 |
482 |
483 |
484 |
485 | 486 |
487 |
25%
488 |
489 |
490 |
491 |
492 | 493 |
494 |
495 |

Todo List

496 | 497 | 504 | 505 |
A simple checklist
506 | 507 |
    508 |
  • 509 |
    510 | 511 | 512 | 513 | 514 |
    515 |
    516 |
  • 517 |
  • 518 |
    519 | 520 | 521 | 522 | 523 |
    524 |
    525 |
  • 526 |
  • 527 |
    528 | 529 | 530 | 531 | 532 |
    533 |
    534 |
  • 535 |
  • 536 |
    537 | 538 | 539 | 540 | 541 |
    542 |
    543 |
  • 544 |
  • 545 |
    546 | 547 | 548 | 549 | 550 |
    551 |
    552 |
  • 553 |
554 | 555 | 561 |
562 |
563 | 564 |
565 |
566 |

Calendar

567 | 568 | 575 | 576 |
What's coming up
577 | 578 |
579 |
580 |
581 |
582 | 583 |
584 |
585 |
586 |

Contact Form

587 | 588 | 595 | 596 |
Subtitle
597 | 598 |
599 |
600 | 601 |
602 | 603 | 604 |
605 | 606 |
607 |
608 | 609 | 610 |
611 | 612 | 613 |
614 | 615 |
616 |
617 | 618 | 619 |
620 | 621 | 622 |
623 | 624 |
625 |
626 | 627 | 628 |
629 |
630 | 631 |
632 |
633 |
634 |
635 |
636 |
637 | 638 |
639 |
640 |

Timeline

641 | 642 | 649 | 650 |
Vertical Layout
651 | 652 |
    653 |
  • 654 |
    655 | 656 |
    657 |
    658 |
    Lorem ipsum
    659 |
    660 | 661 |
    662 |

    Lorem ipsum dolor sit amet, consectetur adipiscing elit.

    663 |
    664 |
    665 |
  • 666 |
  • 667 |
    668 | 669 |
    670 |
    671 |
    Dolor
    672 |
    673 | 674 |
    675 |

    Lorem ipsum dolor sit amet, consectetur adipiscing elit.

    676 |
    677 |
    678 |
  • 679 |
  • 680 |
    681 | 682 |
    683 |
    684 |
    Sit amet
    685 |
    686 | 687 |
    688 |

    Lorem ipsum dolor sit amet, consectetur adipiscing elit.

    689 |
    690 |
    691 |
  • 692 |
693 |
694 |
695 |
696 |
697 | 698 |
699 |
700 |

Buttons

701 | 702 |
Small
703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 |
Medium
719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 |
Large
735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 |
750 |
751 | 752 |
753 |
754 |

Alerts

755 | 756 | 763 | 769 | 776 | 783 | 790 | 797 | 803 | 809 |
810 |
811 | 812 |
813 |
814 |

Basic Cards

815 |
816 | 817 |
818 |
819 |
Header
820 |
821 |

Primary card title

822 |

Some quick example text to build on the card title and make up the bulk of the card's content.

823 |
824 |
825 |
826 | 827 |
828 |
829 |
Header
830 |
831 |

Primary card title

832 |

Some quick example text to build on the card title and make up the bulk of the card's content.

833 |
834 |
835 |
836 | 837 |
838 |
839 |
Header
840 |
841 |

Secondary card title

842 |

Some quick example text to build on the card title and make up the bulk of the card's content.

843 |
844 |
845 |
846 | 847 |
848 |
849 |
Header
850 |
851 |

Success card title

852 |

Some quick example text to build on the card title and make up the bulk of the card's content.

853 |
854 |
855 |
856 | 857 |
858 |
859 |
Header
860 |
861 |

Danger card title

862 |

Some quick example text to build on the card title and make up the bulk of the card's content.

863 |
864 |
865 |
866 | 867 |
868 |
869 |
Header
870 |
871 |

Warning card title

872 |

Some quick example text to build on the card title and make up the bulk of the card's content.

873 |
874 |
875 |
876 | 877 |
878 |
879 |
Header
880 |
881 |

Info card title

882 |

Some quick example text to build on the card title and make up the bulk of the card's content.

883 |
884 |
885 |
886 | 887 |
888 |
889 |
Header
890 |
891 |

Light card title

892 |

Some quick example text to build on the card title and make up the bulk of the card's content.

893 |
894 |
895 |
896 | 897 |
898 |
899 |
Header
900 |
901 |

Dark card title

902 |

Some quick example text to build on the card title and make up the bulk of the card's content.

903 |
904 |
905 |
906 | 907 |
908 | 909 |
910 |
911 |

Cards with Navigation

912 |
913 | 914 |
915 |
916 |
917 | 922 |
923 | 924 |
925 |

Special title treatment

926 | 927 |

With supporting text below as a natural lead-in to additional content.

928 | Go somewhere
929 |
930 |
931 | 932 |
933 |
934 |
935 | 940 |
941 | 942 |
943 |

Special title treatment

944 | 945 |

With supporting text below as a natural lead-in to additional content.

946 | Go somewhere
947 |
948 |
949 |
950 | -------------------------------------------------------------------------------- /src/app/dashboard/dashboard.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import { AlertService } from '../shared/services/alert.service'; 4 | 5 | @Component({ 6 | templateUrl: 'dashboard.component.html' 7 | }) 8 | export class DashboardComponent implements OnInit { 9 | 10 | title = 'Dashboard'; // ToDo recheck need 11 | 12 | // public status: { isopen: boolean } = { isopen: false }; 13 | 14 | constructor(private alertService: AlertService) { 15 | } 16 | 17 | // public toggleDropdown($event:MouseEvent):void { 18 | // $event.preventDefault(); 19 | // $event.stopPropagation(); 20 | // this.status.isopen = !this.status.isopen; 21 | // } 22 | 23 | 24 | ngOnInit(): void { 25 | this.alertService.success('success'); 26 | // this.alertService.info('info'); 27 | // this.alertService.warning('warning'); 28 | // this.alertService.danger('danger'); 29 | // this.alertService.primary('primary'); 30 | // this.alertService.secondary('secondary'); 31 | // this.alertService.light('light'); 32 | // this.alertService.dark('dark'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/app/dashboard/dashboard.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | 3 | import { SharedLazyModule } from '../shared/shared-lazy.module'; 4 | 5 | import { DashboardComponent } from './dashboard.component'; 6 | import { DashboardRoutingModule } from './dashboard-routing.module'; 7 | 8 | @NgModule({ 9 | imports: [ 10 | SharedLazyModule, 11 | DashboardRoutingModule, 12 | ], 13 | declarations: [DashboardComponent] 14 | }) 15 | export class DashboardModule { 16 | } 17 | -------------------------------------------------------------------------------- /src/app/plong/plong-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | 4 | import { PlongComponent } from './plong.component'; 5 | 6 | const routes: Routes = [ 7 | { 8 | path: '', 9 | component: PlongComponent, 10 | } 11 | ]; 12 | 13 | @NgModule({ 14 | imports: [RouterModule.forChild(routes)], 15 | exports: [RouterModule] 16 | }) 17 | export class PlongRoutingModule { 18 | } 19 | -------------------------------------------------------------------------------- /src/app/plong/plong.component.html: -------------------------------------------------------------------------------- 1 |

2 | {{title}} 3 |

4 |

font awesome example

5 |

boostrap example Button

6 |

translate: {{ 'teststring' | translate }} - {{ 'common.hello' | translate }}

7 | 8 |

ng-bootstrap example

9 | 10 | 11 |
12 |
13 |
14 | -------------------------------------------------------------------------------- /src/app/plong/plong.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import { AlertService } from '../shared/services/alert.service'; 4 | 5 | @Component({ 6 | templateUrl: 'plong.component.html' 7 | }) 8 | export class PlongComponent implements OnInit { 9 | 10 | title = 'Plong'; // ToDo recheck need 11 | 12 | // public status: { isopen: boolean } = { isopen: false }; 13 | 14 | constructor(private alertService: AlertService) { 15 | } 16 | 17 | // public toggleDropdown($event:MouseEvent):void { 18 | // $event.preventDefault(); 19 | // $event.stopPropagation(); 20 | // this.status.isopen = !this.status.isopen; 21 | // } 22 | 23 | 24 | ngOnInit(): void { 25 | this.alertService.danger('danger'); 26 | // this.alertService.info('info'); 27 | // this.alertService.warning('warning'); 28 | // this.alertService.danger('danger'); 29 | // this.alertService.primary('primary'); 30 | // this.alertService.secondary('secondary'); 31 | // this.alertService.light('light'); 32 | // this.alertService.dark('dark'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/app/plong/plong.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | 3 | import { SharedLazyModule } from '../shared/shared-lazy.module'; 4 | 5 | import { PlongComponent } from './plong.component'; 6 | import { PlongRoutingModule } from './plong-routing.module'; 7 | 8 | @NgModule({ 9 | imports: [ 10 | SharedLazyModule, 11 | PlongRoutingModule, 12 | ], 13 | declarations: [PlongComponent] 14 | }) 15 | export class PlongModule { 16 | } 17 | -------------------------------------------------------------------------------- /src/app/shared/components/alert/alert.component.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | {{ alert.message }} 4 |

5 |
6 | -------------------------------------------------------------------------------- /src/app/shared/components/alert/alert.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import { Alert } from '../../models/alert.model'; 4 | import { AlertService } from '../../services/alert.service'; 5 | 6 | // import { debounceTime } from 'rxjs/operator/debounceTime'; 7 | 8 | @Component({ 9 | moduleId: module.id, 10 | selector: 'tox-alert', 11 | templateUrl: 'alert.component.html' 12 | }) 13 | 14 | export class AlertComponent implements OnInit { 15 | alerts: Alert[] = []; 16 | 17 | constructor(private alertService: AlertService) { 18 | } 19 | 20 | ngOnInit() { 21 | this.alertService.getAlert().subscribe((alert: Alert) => { 22 | if (!alert) { 23 | // clear alerts when an empty alert is received 24 | this.alerts = []; 25 | return; 26 | } 27 | 28 | // add alert to array 29 | this.alerts.push(alert); 30 | // debounceTime.call(alert, 5000).subscribe(() => { 31 | // console.log('all lal la'); 32 | // }); 33 | }); 34 | 35 | 36 | } 37 | 38 | public closeAlert(alert: IAlert) { 39 | const index: number = this.alerts.indexOf(alert); 40 | this.alerts.splice(index, 1); 41 | } 42 | } 43 | 44 | export interface IAlert { 45 | id: number; 46 | type: string; 47 | message: string; 48 | } 49 | -------------------------------------------------------------------------------- /src/app/shared/components/footerbar/footerbar.component.html: -------------------------------------------------------------------------------- 1 |
2 | footer-bar 3 |
4 | -------------------------------------------------------------------------------- /src/app/shared/components/footerbar/footerbar.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'tox-footerbar', 5 | templateUrl: './footerbar.component.html', 6 | }) 7 | export class FooterbarComponent implements OnInit { 8 | 9 | constructor() { } 10 | 11 | ngOnInit() { 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/app/shared/components/headerbar/headerbar.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | - -->{{ sidebarVisible }}<<- 4 |
5 | -------------------------------------------------------------------------------- /src/app/shared/components/headerbar/headerbar.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Renderer2, HostListener } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'tox-headerbar', 5 | templateUrl: './headerbar.component.html', 6 | }) 7 | export class HeaderbarComponent implements OnInit { 8 | 9 | sidebarVisible: boolean; 10 | 11 | @HostListener('window:resize', ['$event']) 12 | onResize(event) { 13 | this.setSidebar(event); 14 | } 15 | 16 | constructor(private renderer: Renderer2) { 17 | } 18 | 19 | ngOnInit(): void { 20 | this.setSidebarByWidth(window.innerWidth); 21 | } 22 | 23 | toggleSidebar() { 24 | if (this.sidebarVisible) { 25 | this.hideSidebar(); 26 | } else { 27 | this.showSidebar(); 28 | } 29 | } 30 | 31 | setSidebar(event) { 32 | const width = (event.target.innerWidth > 0) ? event.target.innerWidth : event.screen.width; 33 | this.setSidebarByWidth(width); 34 | } 35 | 36 | setSidebarByWidth(width) { 37 | if (width < 992) { 38 | this.hideSidebar(); 39 | } else { 40 | this.showSidebar(); 41 | } 42 | } 43 | 44 | showSidebar() { 45 | this.sidebarVisible = true; 46 | this.renderer.addClass(document.body, 'show-sidebar'); 47 | } 48 | 49 | hideSidebar() { 50 | this.sidebarVisible = false; 51 | this.renderer.removeClass(document.body, 'show-sidebar'); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/app/shared/components/layout-admin/layout-admin.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 |
6 |
7 | 8 |
9 |
10 | 11 | 12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /src/app/shared/components/layout-admin/layout-admin.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'tox-layout-admin', 5 | templateUrl: './layout-admin.component.html' 6 | }) 7 | export class LayoutAdminComponent implements OnInit { 8 | 9 | constructor() { 10 | } 11 | 12 | ngOnInit(): void { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/shared/components/shared-components.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | // import { CommonModule } from '@angular/common'; 3 | // import { RouterModule } from '@angular/router'; 4 | 5 | import { SharedModule } from '../shared.module'; 6 | 7 | // global used modules ... also used by components of next section 8 | // import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 9 | // import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; 10 | // import { TranslateHttpLoader } from '@ngx-translate/http-loader'; 11 | // import { HttpClientModule, HttpClient } from '@angular/common/http'; 12 | 13 | // own components 14 | import { AlertComponent } from './alert/alert.component'; 15 | import { HeaderbarComponent } from './headerbar/headerbar.component'; 16 | import { SidebarComponent } from './sidebar/sidebar.component'; 17 | import { FooterbarComponent } from './footerbar/footerbar.component'; 18 | import { LayoutAdminComponent } from './layout-admin/layout-admin.component'; 19 | 20 | // AoT requires an exported function for factories 21 | // export function HttpLoaderFactory(http: HttpClient) { 22 | // return new TranslateHttpLoader(http); 23 | // } 24 | 25 | @NgModule({ 26 | imports: [ 27 | SharedModule 28 | // CommonModule, 29 | // RouterModule, 30 | // NgbModule.forRoot(), 31 | // HttpClientModule, 32 | // TranslateModule.forRoot({ 33 | // loader: { 34 | // provide: TranslateLoader, 35 | // useFactory: HttpLoaderFactory, 36 | // deps: [HttpClient] 37 | // } 38 | // }), 39 | ], 40 | declarations: [ 41 | AlertComponent, 42 | HeaderbarComponent, 43 | SidebarComponent, 44 | FooterbarComponent, 45 | LayoutAdminComponent, 46 | ], 47 | exports: [ 48 | AlertComponent, 49 | HeaderbarComponent, 50 | SidebarComponent, 51 | FooterbarComponent, 52 | LayoutAdminComponent, 53 | ] 54 | }) 55 | export class SharedComponentsModule { 56 | } 57 | -------------------------------------------------------------------------------- /src/app/shared/components/sidebar/sidebar.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |

Menu Headline

6 | 14 | 15 |
16 | 17 |
18 | -------------------------------------------------------------------------------- /src/app/shared/components/sidebar/sidebar.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | // routing for ----- 4 | export interface RouteInfo { 5 | path: string; 6 | title: string; 7 | iconClass: string; 8 | } 9 | 10 | // duplicates to routing configs ... i know 11 | export const ROUTES: RouteInfo[] = [ 12 | {path: '/dashboard', title: 'Dashboard', iconClass: 'fa fa-tachometer'}, 13 | {path: '/plong', title: 'Plong', iconClass: 'fa fa-tachometer'}, 14 | // {path: '/offerteasers', title: 'Teasers', iconClass: 'fa fa-gift'}, 15 | // {path: '/offerassets', title: 'Assets', iconClass: 'fa fa-image'}, 16 | // {path: '/offersetups', title: 'Setups', iconClass: 'fa fa-cog'}, 17 | // {path: '/offertemplates', title: 'Templates', iconClass: 'fa fa-file-code-o'}, 18 | ]; 19 | 20 | export interface SidebarItemTypes { 21 | type: 'headline' | 'menu'; 22 | data?: string; 23 | } 24 | 25 | // routing for ----- 26 | 27 | @Component({ 28 | selector: 'tox-sidebar', 29 | templateUrl: './sidebar.component.html', 30 | }) 31 | export class SidebarComponent implements OnInit { 32 | 33 | public menuItems: any[]; 34 | 35 | constructor() { 36 | } 37 | 38 | ngOnInit() { 39 | this.menuItems = ROUTES.filter(menuItem => menuItem); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/app/shared/models/alert.model.ts: -------------------------------------------------------------------------------- 1 | export class Alert { 2 | type: string; 3 | message: string; 4 | } 5 | -------------------------------------------------------------------------------- /src/app/shared/services/alert.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Router, NavigationStart } from '@angular/router'; 3 | import { Observable } from 'rxjs/Observable'; 4 | import { Subject } from 'rxjs/Subject'; 5 | 6 | // import { debounceTime } from 'rxjs/operator/debounceTime'; 7 | 8 | import { Alert } from '../models/alert.model'; 9 | 10 | @Injectable() 11 | export class AlertService { 12 | private subject = new Subject(); 13 | private keepAfterRouteChange = false; 14 | 15 | constructor(private router: Router) { 16 | // clear alert messages on route change unless 'keepAfterRouteChange' flag is true 17 | router.events.subscribe(event => { 18 | if (event instanceof NavigationStart) { 19 | if (this.keepAfterRouteChange) { 20 | // only keep for a single route change 21 | this.keepAfterRouteChange = false; 22 | } else { 23 | // clear alert messages 24 | this.clear(); 25 | } 26 | } 27 | }); 28 | } 29 | 30 | getAlert(): Observable { 31 | return this.subject.asObservable(); 32 | } 33 | 34 | alert(type: string, message: string, keepAfterRouteChange = false) { 35 | this.keepAfterRouteChange = keepAfterRouteChange; 36 | this.subject.next({type: type, message: message}); 37 | 38 | // debounceTime.call(this.subject, 5000).subscribe(() => { 39 | // console.log('hui buh'); 40 | // }); 41 | } 42 | 43 | clear() { 44 | // clear alerts 45 | this.subject.next(); 46 | } 47 | 48 | // ============================================================================================================================== 49 | 50 | success(message: string, keepAfterRouteChange = false) { 51 | this.alert('success', message, keepAfterRouteChange); 52 | } 53 | 54 | info(message: string, keepAfterRouteChange = false) { 55 | this.alert('info', message, keepAfterRouteChange); 56 | } 57 | 58 | warning(message: string, keepAfterRouteChange = false) { 59 | this.alert('warning', message, keepAfterRouteChange); 60 | } 61 | 62 | danger(message: string, keepAfterRouteChange = false) { 63 | this.alert('danger', message, keepAfterRouteChange); 64 | } 65 | 66 | primary(message: string, keepAfterRouteChange = false) { 67 | this.alert('primary', message, keepAfterRouteChange); 68 | } 69 | 70 | secondary(message: string, keepAfterRouteChange = false) { 71 | this.alert('secondary', message, keepAfterRouteChange); 72 | } 73 | 74 | light(message: string, keepAfterRouteChange = false) { 75 | this.alert('light', message, keepAfterRouteChange); 76 | } 77 | 78 | dark(message: string, keepAfterRouteChange = false) { 79 | this.alert('dark', message, keepAfterRouteChange); 80 | } 81 | 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/app/shared/services/api.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Headers, Http, Response } from '@angular/http'; 3 | import { Observable } from 'rxjs/Rx'; 4 | import 'rxjs/add/operator/map'; 5 | import 'rxjs/add/operator/catch'; 6 | 7 | import { environment } from '../../../environments/environment'; 8 | 9 | @Injectable() 10 | export class ApiService { 11 | 12 | config; 13 | 14 | constructor(private http: Http) { 15 | this.config = environment; 16 | } 17 | 18 | // provided basic methods 19 | get (path: string): Observable { 20 | return this.http.get( 21 | this.getApiUrl() + path, 22 | {headers: this.setHeaders()} 23 | ) 24 | .catch(this.formatErrors) 25 | .map((res: Response) => res.json()); 26 | } 27 | 28 | put(path: string, body: Object = {}): Observable { 29 | return this.http.put( 30 | this.getApiUrl() + path, 31 | JSON.stringify(body), 32 | {headers: this.setHeaders()} 33 | ) 34 | .catch(this.formatErrors) 35 | .map((res: Response) => res.json()); 36 | } 37 | 38 | post(path: string, body: Object = {}): Observable { 39 | return this.http.post( 40 | this.getApiUrl() + path, 41 | JSON.stringify(body), 42 | {headers: this.setHeaders()} 43 | ) 44 | .catch(this.formatErrors) 45 | .map((res: Response) => { 46 | return res.headers.get('Location'); 47 | }) 48 | ; 49 | } 50 | 51 | delete(path): Observable { 52 | return this.http.delete( 53 | this.getApiUrl() + path, 54 | {headers: this.setHeaders()} 55 | ) 56 | .catch(this.formatErrors) 57 | .map((res: Response) => res.json()); 58 | } 59 | 60 | // private helper 61 | private setHeaders(): Headers { 62 | const headersConfig = { 63 | 'Content-Type': 'application/json', 64 | 'Accept': 'application/json' 65 | }; 66 | 67 | return new Headers(headersConfig); 68 | } 69 | 70 | private formatErrors(error: any) { 71 | return Observable.throw(error.json()); 72 | } 73 | 74 | private getApiUrl() { 75 | return this.config.api_url; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/app/shared/services/services.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | 3 | import { AlertService } from './alert.service'; 4 | import { ApiService } from './api.service'; 5 | 6 | @NgModule({ 7 | imports: [], 8 | exports: [], 9 | declarations: [], 10 | providers: [] 11 | }) 12 | export class ServicesModule { 13 | static forRoot() { 14 | return { 15 | ngModule: ServicesModule, 16 | providers: [ 17 | AlertService, 18 | ApiService, 19 | ] 20 | } 21 | } 22 | } 23 | 24 | 25 | export { 26 | AlertService, 27 | ApiService, 28 | } 29 | -------------------------------------------------------------------------------- /src/app/shared/shared-lazy.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { HttpClientModule } from '@angular/common/http'; 3 | import { CommonModule } from '@angular/common'; 4 | import { FormsModule } from '@angular/forms'; 5 | import { RouterModule } from '@angular/router'; 6 | 7 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 8 | import { TranslateModule } from '@ngx-translate/core'; 9 | 10 | @NgModule({ 11 | imports: [ 12 | HttpClientModule, 13 | CommonModule, 14 | FormsModule, 15 | RouterModule, 16 | NgbModule, 17 | TranslateModule.forChild(), 18 | ], 19 | declarations: [ 20 | ], 21 | exports: [ 22 | CommonModule, 23 | FormsModule, 24 | RouterModule, 25 | TranslateModule, 26 | NgbModule, 27 | ] 28 | }) 29 | export class SharedLazyModule { 30 | } 31 | -------------------------------------------------------------------------------- /src/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { HttpClientModule } from '@angular/common/http'; 3 | import { CommonModule } from '@angular/common'; 4 | import { FormsModule } from '@angular/forms'; 5 | import { RouterModule } from '@angular/router'; 6 | 7 | // // global used modules ... also used by components of next section 8 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 9 | import { TranslateModule, TranslateLoader, TranslateService } from '@ngx-translate/core'; 10 | import { TranslateHttpLoader } from '@ngx-translate/http-loader'; 11 | import { HttpClient } from '@angular/common/http'; 12 | 13 | // AoT requires an exported function for factories 14 | export function HttpLoaderFactory(http: HttpClient) { 15 | return new TranslateHttpLoader(http); 16 | } 17 | 18 | @NgModule({ 19 | imports: [ 20 | HttpClientModule, 21 | CommonModule, 22 | FormsModule, 23 | RouterModule, 24 | NgbModule.forRoot(), 25 | TranslateModule.forRoot({ 26 | loader: { 27 | provide: TranslateLoader, 28 | useFactory: HttpLoaderFactory, 29 | deps: [HttpClient] 30 | } 31 | }), 32 | ], 33 | declarations: [], 34 | exports: [ 35 | CommonModule, 36 | FormsModule, 37 | RouterModule, 38 | TranslateModule, 39 | NgbModule, 40 | ] 41 | }) 42 | export class SharedModule { 43 | constructor(private translate: TranslateService) { 44 | translate.addLangs(['en', 'de']); 45 | translate.setDefaultLang('en'); 46 | const browserLang: string = translate.getBrowserLang(); 47 | translate.use(browserLang.match(/en|de/) ? browserLang : 'en'); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dasrick/tox-ngx/6df7372ed983c71b181c5488fd0ee220808cced0/src/assets/.gitkeep -------------------------------------------------------------------------------- /src/assets/i18n/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "teststring": "Die deutsche Testzeichenkette.", 3 | "common.hello": "Hallo Welt!" 4 | } 5 | -------------------------------------------------------------------------------- /src/assets/i18n/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "teststring": "The english/default test string.", 3 | "common.hello": "Hello World!" 4 | } 5 | -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | api_url: 'https://production-api.example.com/api/v1' 4 | }; 5 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false, 8 | api_url: 'https://testing-api.example.com/api/v1' 9 | }; 10 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dasrick/tox-ngx/6df7372ed983c71b181c5488fd0ee220808cced0/src/favicon.ico -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ToxNgx 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 44 |
45 |
46 | 47 | 48 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | import { environment } from './environments/environment'; 4 | import { AppModule } from './app/app.module'; 5 | 6 | if (environment.production) { 7 | enableProdMode(); 8 | } 9 | 10 | platformBrowserDynamic().bootstrapModule(AppModule); 11 | -------------------------------------------------------------------------------- /src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/set'; 35 | 36 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 37 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 38 | 39 | /** IE10 and IE11 requires the following to support `@angular/animation`. */ 40 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 41 | 42 | 43 | /** Evergreen browsers require these. **/ 44 | import 'core-js/es6/reflect'; 45 | import 'core-js/es7/reflect'; 46 | 47 | 48 | /** ALL Firefox browsers require the following to support `@angular/animation`. **/ 49 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 50 | 51 | 52 | 53 | /*************************************************************************************************** 54 | * Zone JS is required by Angular itself. 55 | */ 56 | import 'zone.js/dist/zone'; // Included with Angular CLI. 57 | 58 | 59 | 60 | /*************************************************************************************************** 61 | * APPLICATION IMPORTS 62 | */ 63 | 64 | /** 65 | * Date, currency, decimal and percent pipes. 66 | * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 67 | */ 68 | // import 'intl'; // Run `npm install --save intl`. 69 | -------------------------------------------------------------------------------- /src/scss/_alert.scss: -------------------------------------------------------------------------------- 1 | .alerts { 2 | // ToDo whole positioning NOT final ... 3 | position: absolute; 4 | top: 70px; 5 | left: 0; 6 | right: 0; 7 | z-index: 5; 8 | } 9 | 10 | .show-sidebar { 11 | .alerts { 12 | left: $sidebar-width; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/scss/_footerbar.scss: -------------------------------------------------------------------------------- 1 | .fb { 2 | display: none; 3 | } 4 | -------------------------------------------------------------------------------- /src/scss/_headerbar.scss: -------------------------------------------------------------------------------- 1 | .hb { 2 | background-color: #52bfff; 3 | } 4 | -------------------------------------------------------------------------------- /src/scss/_layout-admin.scss: -------------------------------------------------------------------------------- 1 | // WIP ... temp vars ... maybe with or without responsive suffix 2 | 3 | $header-height: 70px; 4 | $footer-height: 0; 5 | $sidebar-width: 200px; 6 | 7 | html, 8 | body, 9 | .pc { 10 | height: 100%; 11 | } 12 | 13 | .pc { 14 | position: relative; 15 | } 16 | 17 | .hb { 18 | height: $header-height; 19 | top: 0; 20 | z-index: 3; 21 | } 22 | 23 | .sb { 24 | width: $sidebar-width; 25 | left: 0; 26 | transform: translateX(($sidebar-width * -1)) translateY(0) translateZ(0); 27 | z-index: 2; 28 | } 29 | 30 | .mb { 31 | right: 0; 32 | left: 0; 33 | } 34 | 35 | .fb { 36 | height: $footer-height; 37 | bottom: 0; 38 | } 39 | 40 | .hb, 41 | .fb, 42 | .sb, 43 | .mb { 44 | position: absolute; 45 | } 46 | 47 | .hb, 48 | .fb { 49 | width: 100%; 50 | } 51 | 52 | .sb, 53 | .mb { 54 | top: $header-height; 55 | bottom: $footer-height; 56 | 57 | transition: transform .26s cubic-bezier(.47, 0, .745, .715); 58 | will-change: transform; 59 | 60 | overflow-x: hidden; 61 | overflow-y: auto; 62 | } 63 | 64 | .show-sidebar { 65 | .sb { 66 | transform: translateX(0) translateY(0) translateZ(0); 67 | } 68 | 69 | .mb { 70 | left: $sidebar-width; 71 | } 72 | } 73 | 74 | // ===================================================================================================================== 75 | // responsive section 76 | 77 | // responsive section - up 78 | //@include media-breakpoint-up(xs) { ... } 79 | //@include media-breakpoint-up(sm) { ... } 80 | //@include media-breakpoint-up(md) { ... } 81 | //@include media-breakpoint-up(lg) { ... } 82 | //@include media-breakpoint-up(xl) { ... } 83 | 84 | // responsive section - down 85 | //@include media-breakpoint-down(xs) {} 86 | //@include media-breakpoint-down(sm) {} 87 | //@include media-breakpoint-down(md) {} 88 | //@include media-breakpoint-down(lg) {} 89 | -------------------------------------------------------------------------------- /src/scss/_mainbar.scss: -------------------------------------------------------------------------------- 1 | .mb { 2 | //background-color: #feffbe; 3 | } 4 | -------------------------------------------------------------------------------- /src/scss/_mixins.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dasrick/tox-ngx/6df7372ed983c71b181c5488fd0ee220808cced0/src/scss/_mixins.scss -------------------------------------------------------------------------------- /src/scss/_sidebar.scss: -------------------------------------------------------------------------------- 1 | @mixin sb-colors($color, $bg) { 2 | color: $color; 3 | background-color: $bg; 4 | } 5 | 6 | .sb { 7 | @include sb-colors($gray-600, $gray-900); 8 | 9 | //.nav { 10 | //} 11 | 12 | //.nav-item { 13 | //} 14 | 15 | .nav-link { 16 | @include sb-colors($gray-300, $gray-900); 17 | 18 | &:hover { 19 | @include sb-colors($white, darken($gray-900, 5%)); 20 | } 21 | 22 | &.active { 23 | @include sb-colors(theme-color("primary"), darken($gray-900, 5%)); 24 | } 25 | 26 | > i { 27 | color: $gray-600; 28 | width: 1rem; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/scss/_variables.scss: -------------------------------------------------------------------------------- 1 | // common vars 2 | 3 | // pc - page-content 4 | 5 | // hb - header-bar 6 | 7 | // sb - sides-bar 8 | 9 | // mb - main-bar 10 | 11 | // fb - footer-bar 12 | -------------------------------------------------------------------------------- /src/scss/bootstrap_overwrite/_variables.scss: -------------------------------------------------------------------------------- 1 | /* stylelint-disable function-comma-space-after */ 2 | /* stylelint-disable declaration-bang-space-before */ 3 | 4 | // Variables 5 | // 6 | // Copy settings from this file into the provided `_custom.scss` to override 7 | // the Bootstrap defaults without modifying key, versioned files. 8 | // 9 | // Variables should follow the `$component-state-property-size` formula for 10 | // consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs. 11 | 12 | // Table of Contents 13 | // 14 | // Color system 15 | // Options 16 | // Spacing 17 | // Body 18 | // Links 19 | // Paragraphs 20 | // Grid breakpoints 21 | // Grid containers 22 | // Grid columns 23 | // Fonts 24 | // Components 25 | // Tables 26 | // Buttons 27 | // Forms 28 | // Dropdowns 29 | // Z-index master list 30 | // Navs 31 | // Navbar 32 | // Pagination 33 | // Jumbotron 34 | // Form states and alerts 35 | // Cards 36 | // Tooltips 37 | // Popovers 38 | // Badges 39 | // Modals 40 | // Alerts 41 | // Progress bars 42 | // List group 43 | // Image thumbnails 44 | // Figures 45 | // Breadcrumbs 46 | // Carousel 47 | // Close 48 | // Code 49 | 50 | 51 | // 52 | // Color system 53 | // 54 | 55 | $white: #fff !default; 56 | $gray-100: #f8f9fa !default; 57 | $gray-200: #e9ecef !default; 58 | $gray-300: #dee2e6 !default; 59 | $gray-400: #ced4da !default; 60 | $gray-500: #adb5bd !default; 61 | $gray-600: #868e96 !default; 62 | $gray-700: #495057 !default; 63 | $gray-800: #343a40 !default; 64 | $gray-900: #212529 !default; 65 | $black: #000 !default; 66 | 67 | $grays: ( 68 | 100: $gray-100, 69 | 200: $gray-200, 70 | 300: $gray-300, 71 | 400: $gray-400, 72 | 500: $gray-500, 73 | 600: $gray-600, 74 | 700: $gray-700, 75 | 800: $gray-800, 76 | 900: $gray-900 77 | ) !default; 78 | 79 | $blue: #007bff !default; 80 | $indigo: #6610f2 !default; 81 | $purple: #6f42c1 !default; 82 | $pink: #e83e8c !default; 83 | $red: #dc3545 !default; 84 | $orange: #fd7e14 !default; 85 | $yellow: #ffc107 !default; 86 | $green: #28a745 !default; 87 | $teal: #20c997 !default; 88 | $cyan: #17a2b8 !default; 89 | 90 | $colors: ( 91 | blue: $blue, 92 | indigo: $indigo, 93 | purple: $purple, 94 | pink: $pink, 95 | red: $red, 96 | orange: $orange, 97 | yellow: $yellow, 98 | green: $green, 99 | teal: $teal, 100 | cyan: $cyan, 101 | white: $white, 102 | gray: $gray-600, 103 | gray-dark: $gray-800 104 | ) !default; 105 | 106 | $theme-colors: ( 107 | primary: $blue, 108 | secondary: $gray-600, 109 | success: $green, 110 | info: $cyan, 111 | warning: $yellow, 112 | danger: $red, 113 | light: $gray-100, 114 | dark: $gray-800 115 | ) !default; 116 | 117 | // Set a specific jump point for requesting color jumps 118 | $theme-color-interval: 8% !default; 119 | 120 | 121 | // Options 122 | // 123 | // Quickly modify global styling by enabling or disabling optional features. 124 | 125 | $enable-rounded: true !default; 126 | $enable-shadows: false !default; 127 | $enable-gradients: false !default; 128 | $enable-transitions: true !default; 129 | $enable-hover-media-query: false !default; 130 | $enable-grid-classes: true !default; 131 | $enable-print-styles: true !default; 132 | 133 | 134 | // Spacing 135 | // 136 | // Control the default styling of most Bootstrap elements by modifying these 137 | // variables. Mostly focused on spacing. 138 | // You can add more entries to the $spacers map, should you need more variation. 139 | 140 | $spacer: 1rem !default; 141 | $spacers: ( 142 | 0: 0, 143 | 1: ($spacer * .25), 144 | 2: ($spacer * .5), 145 | 3: $spacer, 146 | 4: ($spacer * 1.5), 147 | 5: ($spacer * 3) 148 | ) !default; 149 | 150 | // This variable affects the `.h-*` and `.w-*` classes. 151 | $sizes: ( 152 | 25: 25%, 153 | 50: 50%, 154 | 75: 75%, 155 | 100: 100% 156 | ) !default; 157 | 158 | // Body 159 | // 160 | // Settings for the `` element. 161 | 162 | $body-bg: $gray-100; //$white !default; 163 | $body-color: $gray-900 !default; 164 | 165 | // Links 166 | // 167 | // Style anchor elements. 168 | 169 | $link-color: theme-color("primary") !default; 170 | $link-decoration: none !default; 171 | $link-hover-color: darken($link-color, 15%) !default; 172 | $link-hover-decoration: underline !default; 173 | 174 | // Paragraphs 175 | // 176 | // Style p element. 177 | 178 | $paragraph-margin-bottom: 1rem; 179 | 180 | 181 | // Grid breakpoints 182 | // 183 | // Define the minimum dimensions at which your layout will change, 184 | // adapting to different screen sizes, for use in media queries. 185 | 186 | $grid-breakpoints: ( 187 | xs: 0, 188 | sm: 576px, 189 | md: 768px, 190 | lg: 992px, 191 | xl: 1200px 192 | ) !default; 193 | @include _assert-ascending($grid-breakpoints, "$grid-breakpoints"); 194 | @include _assert-starts-at-zero($grid-breakpoints); 195 | 196 | 197 | // Grid containers 198 | // 199 | // Define the maximum width of `.container` for different screen sizes. 200 | 201 | $container-max-widths: ( 202 | sm: 540px, 203 | md: 720px, 204 | lg: 960px, 205 | xl: 1140px 206 | ) !default; 207 | @include _assert-ascending($container-max-widths, "$container-max-widths"); 208 | 209 | 210 | // Grid columns 211 | // 212 | // Set the number of columns and specify the width of the gutters. 213 | 214 | $grid-columns: 12 !default; 215 | $grid-gutter-width: 30px !default; 216 | 217 | // Components 218 | // 219 | // Define common padding and border radius sizes and more. 220 | 221 | $line-height-lg: 1.5 !default; 222 | $line-height-sm: 1.5 !default; 223 | 224 | $border-width: 1px !default; 225 | $border-color: $gray-200 !default; 226 | 227 | $border-radius: .25rem !default; 228 | $border-radius-lg: .3rem !default; 229 | $border-radius-sm: .2rem !default; 230 | 231 | $component-active-color: $white !default; 232 | $component-active-bg: theme-color("primary") !default; 233 | 234 | $caret-width: .3em !default; 235 | 236 | $transition-base: all .2s ease-in-out !default; 237 | $transition-fade: opacity .15s linear !default; 238 | $transition-collapse: height .35s ease !default; 239 | 240 | 241 | // Fonts 242 | // 243 | // Font, line-height, and color for body text, headings, and more. 244 | 245 | $font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default; 246 | $font-family-monospace: "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default; 247 | $font-family-base: $font-family-sans-serif !default; 248 | 249 | $font-size-base: 1rem !default; // Assumes the browser default, typically `16px` 250 | $font-size-lg: 1.25rem !default; 251 | $font-size-sm: .875rem !default; 252 | 253 | $font-weight-light: 300 !default; 254 | $font-weight-normal: normal !default; 255 | $font-weight-bold: bold !default; 256 | 257 | $font-weight-base: $font-weight-normal !default; 258 | $line-height-base: 1.5 !default; 259 | 260 | $h1-font-size: 2.5rem !default; 261 | $h2-font-size: 2rem !default; 262 | $h3-font-size: 1.75rem !default; 263 | $h4-font-size: 1.5rem !default; 264 | $h5-font-size: 1.25rem !default; 265 | $h6-font-size: 1rem !default; 266 | 267 | $headings-margin-bottom: ($spacer / 2) !default; 268 | $headings-font-family: inherit !default; 269 | $headings-font-weight: 500 !default; 270 | $headings-line-height: 1.1 !default; 271 | $headings-color: inherit !default; 272 | 273 | $display1-size: 6rem !default; 274 | $display2-size: 5.5rem !default; 275 | $display3-size: 4.5rem !default; 276 | $display4-size: 3.5rem !default; 277 | 278 | $display1-weight: 300 !default; 279 | $display2-weight: 300 !default; 280 | $display3-weight: 300 !default; 281 | $display4-weight: 300 !default; 282 | $display-line-height: $headings-line-height !default; 283 | 284 | $lead-font-size: 1.25rem !default; 285 | $lead-font-weight: 300 !default; 286 | 287 | $small-font-size: 80% !default; 288 | 289 | $text-muted: $gray-600 !default; 290 | 291 | $blockquote-small-color: $gray-600 !default; 292 | $blockquote-font-size: ($font-size-base * 1.25) !default; 293 | 294 | $hr-border-color: rgba($black,.1) !default; 295 | $hr-border-width: $border-width !default; 296 | 297 | $mark-padding: .2em !default; 298 | 299 | $dt-font-weight: $font-weight-bold !default; 300 | 301 | $kbd-box-shadow: inset 0 -.1rem 0 rgba($black,.25) !default; 302 | $nested-kbd-font-weight: $font-weight-bold !default; 303 | 304 | $list-inline-padding: 5px !default; 305 | 306 | $mark-bg: #fcf8e3 !default; 307 | 308 | 309 | // Tables 310 | // 311 | // Customizes the `.table` component with basic values, each used across all table variations. 312 | 313 | $table-cell-padding: .75rem !default; 314 | $table-cell-padding-sm: .3rem !default; 315 | 316 | $table-bg: transparent !default; 317 | $table-accent-bg: rgba($black,.05) !default; 318 | $table-hover-bg: rgba($black,.075) !default; 319 | $table-active-bg: $table-hover-bg !default; 320 | 321 | $table-border-width: $border-width !default; 322 | $table-border-color: $gray-200 !default; 323 | 324 | $table-head-bg: $gray-200 !default; 325 | $table-head-color: $gray-700 !default; 326 | 327 | $table-inverse-bg: $gray-900 !default; 328 | $table-inverse-accent-bg: rgba($white, .05) !default; 329 | $table-inverse-hover-bg: rgba($white, .075) !default; 330 | $table-inverse-border-color: lighten($gray-900, 7.5%) !default; 331 | $table-inverse-color: $body-bg !default; 332 | 333 | 334 | // Buttons 335 | // 336 | // For each of Bootstrap's buttons, define text, background and border color. 337 | 338 | $input-btn-padding-y: .5rem !default; 339 | $input-btn-padding-x: .75rem !default; 340 | $input-btn-line-height: 1.25 !default; 341 | 342 | $input-btn-padding-y-sm: .25rem !default; 343 | $input-btn-padding-x-sm: .5rem !default; 344 | $input-btn-line-height-sm: 1.5 !default; 345 | 346 | $input-btn-padding-y-lg: .5rem !default; 347 | $input-btn-padding-x-lg: 1rem !default; 348 | $input-btn-line-height-lg: 1.5 !default; 349 | 350 | $btn-font-weight: $font-weight-normal !default; 351 | $btn-box-shadow: inset 0 1px 0 rgba($white,.15), 0 1px 1px rgba($black,.075) !default; 352 | $btn-focus-box-shadow: 0 0 0 3px rgba(theme-color("primary"), .25) !default; 353 | $btn-active-box-shadow: inset 0 3px 5px rgba($black,.125) !default; 354 | 355 | $btn-link-disabled-color: $gray-600 !default; 356 | 357 | $btn-block-spacing-y: .5rem !default; 358 | 359 | // Allows for customizing button radius independently from global border radius 360 | $btn-border-radius: $border-radius !default; 361 | $btn-border-radius-lg: $border-radius-lg !default; 362 | $btn-border-radius-sm: $border-radius-sm !default; 363 | 364 | $btn-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default; 365 | 366 | 367 | // Forms 368 | 369 | $input-bg: $white !default; 370 | $input-disabled-bg: $gray-200 !default; 371 | 372 | $input-color: $gray-700 !default; 373 | $input-border-color: rgba($black,.15) !default; 374 | $input-btn-border-width: $border-width !default; // For form controls and buttons 375 | $input-box-shadow: inset 0 1px 1px rgba($black,.075) !default; 376 | 377 | $input-border-radius: $border-radius !default; 378 | $input-border-radius-lg: $border-radius-lg !default; 379 | $input-border-radius-sm: $border-radius-sm !default; 380 | 381 | $input-focus-bg: $input-bg !default; 382 | $input-focus-border-color: lighten(theme-color("primary"), 25%) !default; 383 | $input-focus-box-shadow: $input-box-shadow, $btn-focus-box-shadow !default; 384 | $input-focus-color: $input-color !default; 385 | 386 | $input-placeholder-color: $gray-600 !default; 387 | 388 | $input-height-border: $input-btn-border-width * 2 !default; 389 | 390 | $input-height-inner: ($font-size-base * $input-btn-line-height) + ($input-btn-padding-y * 2) !default; 391 | $input-height: calc(#{$input-height-inner} + #{$input-height-border}) !default; 392 | 393 | $input-height-inner-sm: ($font-size-sm * $input-btn-line-height-sm) + ($input-btn-padding-y-sm * 2) !default; 394 | $input-height-sm: calc(#{$input-height-inner-sm} + #{$input-height-border}) !default; 395 | 396 | $input-height-inner-lg: ($font-size-lg * $input-btn-line-height-lg) + ($input-btn-padding-y-lg * 2) !default; 397 | $input-height-lg: calc(#{$input-height-inner-lg} + #{$input-height-border}) !default; 398 | 399 | $input-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s !default; 400 | 401 | $form-text-margin-top: .25rem !default; 402 | 403 | $form-check-margin-bottom: .5rem !default; 404 | $form-check-input-gutter: 1.25rem !default; 405 | $form-check-input-margin-y: .25rem !default; 406 | $form-check-input-margin-x: .25rem !default; 407 | 408 | $form-check-inline-margin-x: .75rem !default; 409 | 410 | $form-group-margin-bottom: 1rem !default; 411 | 412 | $input-group-addon-color: $input-color !default; 413 | $input-group-addon-bg: $gray-200 !default; 414 | $input-group-addon-border-color: $input-border-color !default; 415 | $input-group-btn-border-color: $input-border-color !default; 416 | 417 | $custom-control-gutter: 1.5rem !default; 418 | $custom-control-spacer-y: .25rem !default; 419 | $custom-control-spacer-x: 1rem !default; 420 | 421 | $custom-control-indicator-size: 1rem !default; 422 | $custom-control-indicator-bg: #ddd !default; 423 | $custom-control-indicator-bg-size: 50% 50% !default; 424 | $custom-control-indicator-box-shadow: inset 0 .25rem .25rem rgba($black,.1) !default; 425 | 426 | $custom-control-indicator-disabled-bg: $gray-200 !default; 427 | $custom-control-description-disabled-color: $gray-600 !default; 428 | 429 | $custom-control-indicator-checked-color: $white !default; 430 | $custom-control-indicator-checked-bg: theme-color("primary") !default; 431 | $custom-control-indicator-checked-box-shadow: none !default; 432 | 433 | $custom-control-indicator-focus-box-shadow: 0 0 0 1px $body-bg, 0 0 0 3px theme-color("primary") !default; 434 | 435 | $custom-control-indicator-active-color: $white !default; 436 | $custom-control-indicator-active-bg: lighten(theme-color("primary"), 35%) !default; 437 | $custom-control-indicator-active-box-shadow: none !default; 438 | 439 | $custom-checkbox-indicator-border-radius: $border-radius !default; 440 | $custom-checkbox-indicator-icon-checked: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#{$custom-control-indicator-checked-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"), "#", "%23") !default; 441 | 442 | $custom-checkbox-indicator-indeterminate-bg: theme-color("primary") !default; 443 | $custom-checkbox-indicator-indeterminate-color: $custom-control-indicator-checked-color !default; 444 | $custom-checkbox-indicator-icon-indeterminate: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='#{$custom-checkbox-indicator-indeterminate-color}' d='M0 2h4'/%3E%3C/svg%3E"), "#", "%23") !default; 445 | $custom-checkbox-indicator-indeterminate-box-shadow: none !default; 446 | 447 | $custom-radio-indicator-border-radius: 50% !default; 448 | $custom-radio-indicator-icon-checked: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='#{$custom-control-indicator-checked-color}'/%3E%3C/svg%3E"), "#", "%23") !default; 449 | 450 | $custom-select-padding-y: .375rem !default; 451 | $custom-select-padding-x: .75rem !default; 452 | $custom-select-height: $input-height !default; 453 | $custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator 454 | $custom-select-line-height: $input-btn-line-height !default; 455 | $custom-select-color: $input-color !default; 456 | $custom-select-disabled-color: $gray-600 !default; 457 | $custom-select-bg: $white !default; 458 | $custom-select-disabled-bg: $gray-200 !default; 459 | $custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions 460 | $custom-select-indicator-color: #333 !default; 461 | $custom-select-indicator: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E"), "#", "%23") !default; 462 | $custom-select-border-width: $input-btn-border-width !default; 463 | $custom-select-border-color: $input-border-color !default; 464 | $custom-select-border-radius: $border-radius !default; 465 | 466 | $custom-select-focus-border-color: lighten(theme-color("primary"), 25%) !default; 467 | $custom-select-focus-box-shadow: inset 0 1px 2px rgba($black, .075), 0 0 5px rgba($custom-select-focus-border-color, .5) !default; 468 | 469 | $custom-select-font-size-sm: 75% !default; 470 | $custom-select-height-sm: $input-height-sm !default; 471 | 472 | $custom-file-height: $input-height !default; 473 | $custom-file-width: 14rem !default; 474 | $custom-file-focus-box-shadow: 0 0 0 .075rem $white, 0 0 0 .2rem theme-color("primary") !default; 475 | 476 | $custom-file-padding-y: $input-btn-padding-y !default; 477 | $custom-file-padding-x: $input-btn-padding-x !default; 478 | $custom-file-line-height: $input-btn-line-height !default; 479 | $custom-file-color: $input-color !default; 480 | $custom-file-bg: $input-bg !default; 481 | $custom-file-border-width: $input-btn-border-width !default; 482 | $custom-file-border-color: $input-border-color !default; 483 | $custom-file-border-radius: $input-border-radius !default; 484 | $custom-file-box-shadow: $input-box-shadow !default; 485 | $custom-file-button-color: $custom-file-color !default; 486 | $custom-file-button-bg: $input-group-addon-bg !default; 487 | $custom-file-text: ( 488 | placeholder: ( 489 | en: "Choose file..." 490 | ), 491 | button-label: ( 492 | en: "Browse" 493 | ) 494 | ) !default; 495 | 496 | 497 | // Form validation 498 | $form-feedback-valid-color: theme-color("success") !default; 499 | $form-feedback-invalid-color: theme-color("danger") !default; 500 | 501 | 502 | // Dropdowns 503 | // 504 | // Dropdown menu container and contents. 505 | 506 | $dropdown-min-width: 10rem !default; 507 | $dropdown-padding-y: .5rem !default; 508 | $dropdown-spacer: .125rem !default; 509 | $dropdown-bg: $white !default; 510 | $dropdown-border-color: rgba($black,.15) !default; 511 | $dropdown-border-width: $border-width !default; 512 | $dropdown-divider-bg: $gray-200 !default; 513 | $dropdown-box-shadow: 0 .5rem 1rem rgba($black,.175) !default; 514 | 515 | $dropdown-link-color: $gray-900 !default; 516 | $dropdown-link-hover-color: darken($gray-900, 5%) !default; 517 | $dropdown-link-hover-bg: $gray-100 !default; 518 | 519 | $dropdown-link-active-color: $component-active-color !default; 520 | $dropdown-link-active-bg: $component-active-bg !default; 521 | 522 | $dropdown-link-disabled-color: $gray-600 !default; 523 | 524 | $dropdown-item-padding-y: .25rem !default; 525 | $dropdown-item-padding-x: 1.5rem !default; 526 | 527 | $dropdown-header-color: $gray-600 !default; 528 | 529 | 530 | // Z-index master list 531 | // 532 | // Warning: Avoid customizing these values. They're used for a bird's eye view 533 | // of components dependent on the z-axis and are designed to all work together. 534 | 535 | $zindex-dropdown: 1000 !default; 536 | $zindex-sticky: 1020 !default; 537 | $zindex-fixed: 1030 !default; 538 | $zindex-modal-backdrop: 1040 !default; 539 | $zindex-modal: 1050 !default; 540 | $zindex-popover: 1060 !default; 541 | $zindex-tooltip: 1070 !default; 542 | 543 | // Navs 544 | 545 | $nav-link-padding-y: .5rem !default; 546 | $nav-link-padding-x: 1rem !default; 547 | $nav-link-disabled-color: $gray-600 !default; 548 | 549 | $nav-tabs-border-color: #ddd !default; 550 | $nav-tabs-border-width: $border-width !default; 551 | $nav-tabs-border-radius: $border-radius !default; 552 | $nav-tabs-link-hover-border-color: $gray-200 !default; 553 | $nav-tabs-link-active-color: $gray-700 !default; 554 | $nav-tabs-link-active-bg: $body-bg !default; 555 | $nav-tabs-link-active-border-color: #ddd !default; 556 | 557 | $nav-pills-border-radius: $border-radius !default; 558 | $nav-pills-link-active-color: $component-active-color !default; 559 | $nav-pills-link-active-bg: $component-active-bg !default; 560 | 561 | // Navbar 562 | 563 | $navbar-padding-y: ($spacer / 2) !default; 564 | $navbar-padding-x: $spacer !default; 565 | 566 | $navbar-brand-font-size: $font-size-lg !default; 567 | // Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link 568 | $nav-link-height: $navbar-brand-font-size * $line-height-base !default; 569 | $navbar-brand-height: ($font-size-base * $line-height-base + $nav-link-padding-y * 2) !default; 570 | $navbar-brand-padding-y: ($navbar-brand-height - $nav-link-height) / 2 !default; 571 | 572 | $navbar-toggler-padding-y: .25rem !default; 573 | $navbar-toggler-padding-x: .75rem !default; 574 | $navbar-toggler-font-size: $font-size-lg !default; 575 | $navbar-toggler-border-radius: $btn-border-radius !default; 576 | 577 | $navbar-dark-color: rgba($white,.5) !default; 578 | $navbar-dark-hover-color: rgba($white,.75) !default; 579 | $navbar-dark-active-color: rgba($white,1) !default; 580 | $navbar-dark-disabled-color: rgba($white,.25) !default; 581 | $navbar-dark-toggler-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$navbar-dark-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"), "#", "%23") !default; 582 | $navbar-dark-toggler-border-color: rgba($white,.1) !default; 583 | 584 | $navbar-light-color: rgba($black,.5) !default; 585 | $navbar-light-hover-color: rgba($black,.7) !default; 586 | $navbar-light-active-color: rgba($black,.9) !default; 587 | $navbar-light-disabled-color: rgba($black,.3) !default; 588 | $navbar-light-toggler-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$navbar-light-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"), "#", "%23") !default; 589 | $navbar-light-toggler-border-color: rgba($black,.1) !default; 590 | 591 | // Pagination 592 | 593 | $pagination-padding-y: .5rem !default; 594 | $pagination-padding-x: .75rem !default; 595 | $pagination-padding-y-sm: .25rem !default; 596 | $pagination-padding-x-sm: .5rem !default; 597 | $pagination-padding-y-lg: .75rem !default; 598 | $pagination-padding-x-lg: 1.5rem !default; 599 | $pagination-line-height: 1.25 !default; 600 | 601 | $pagination-color: $link-color !default; 602 | $pagination-bg: $white !default; 603 | $pagination-border-width: $border-width !default; 604 | $pagination-border-color: #ddd !default; 605 | 606 | $pagination-hover-color: $link-hover-color !default; 607 | $pagination-hover-bg: $gray-200 !default; 608 | $pagination-hover-border-color: #ddd !default; 609 | 610 | $pagination-active-color: $white !default; 611 | $pagination-active-bg: theme-color("primary") !default; 612 | $pagination-active-border-color: theme-color("primary") !default; 613 | 614 | $pagination-disabled-color: $gray-600 !default; 615 | $pagination-disabled-bg: $white !default; 616 | $pagination-disabled-border-color: #ddd !default; 617 | 618 | 619 | // Jumbotron 620 | 621 | $jumbotron-padding: 2rem !default; 622 | $jumbotron-bg: $gray-200 !default; 623 | 624 | 625 | // Cards 626 | 627 | $card-spacer-y: .75rem !default; 628 | $card-spacer-x: 1.25rem !default; 629 | $card-border-width: 1px !default; 630 | $card-border-radius: $border-radius !default; 631 | $card-border-color: rgba($black,.125) !default; 632 | $card-inner-border-radius: calc(#{$card-border-radius} - #{$card-border-width}) !default; 633 | $card-cap-bg: rgba($black, .03) !default; 634 | $card-bg: $white !default; 635 | 636 | $card-img-overlay-padding: 1.25rem !default; 637 | 638 | $card-deck-margin: ($grid-gutter-width / 2) !default; 639 | 640 | $card-columns-count: 3 !default; 641 | $card-columns-gap: 1.25rem !default; 642 | $card-columns-margin: $card-spacer-y !default; 643 | 644 | 645 | // Tooltips 646 | 647 | $tooltip-max-width: 200px !default; 648 | $tooltip-color: $white !default; 649 | $tooltip-bg: $black !default; 650 | $tooltip-opacity: .9 !default; 651 | $tooltip-padding-y: 3px !default; 652 | $tooltip-padding-x: 8px !default; 653 | $tooltip-margin: 0 !default; 654 | 655 | 656 | $tooltip-arrow-width: 5px !default; 657 | $tooltip-arrow-height: 5px !default; 658 | $tooltip-arrow-color: $tooltip-bg !default; 659 | 660 | 661 | // Popovers 662 | 663 | $popover-inner-padding: 1px !default; 664 | $popover-bg: $white !default; 665 | $popover-max-width: 276px !default; 666 | $popover-border-width: $border-width !default; 667 | $popover-border-color: rgba($black,.2) !default; 668 | $popover-box-shadow: 0 5px 10px rgba($black,.2) !default; 669 | 670 | $popover-header-bg: darken($popover-bg, 3%) !default; 671 | $popover-header-color: $headings-color !default; 672 | $popover-header-padding-y: 8px !default; 673 | $popover-header-padding-x: 14px !default; 674 | 675 | $popover-body-color: $body-color !default; 676 | $popover-body-padding-y: 9px !default; 677 | $popover-body-padding-x: 14px !default; 678 | 679 | $popover-arrow-width: 10px !default; 680 | $popover-arrow-height: 5px !default; 681 | $popover-arrow-color: $popover-bg !default; 682 | 683 | $popover-arrow-outer-width: ($popover-arrow-width + 1px) !default; 684 | $popover-arrow-outer-color: fade-in($popover-border-color, .05) !default; 685 | 686 | 687 | // Badges 688 | 689 | $badge-color: $white !default; 690 | $badge-font-size: 75% !default; 691 | $badge-font-weight: $font-weight-bold !default; 692 | $badge-padding-y: .25em !default; 693 | $badge-padding-x: .4em !default; 694 | 695 | $badge-pill-padding-x: .6em !default; 696 | // Use a higher than normal value to ensure completely rounded edges when 697 | // customizing padding or font-size on labels. 698 | $badge-pill-border-radius: 10rem !default; 699 | 700 | 701 | // Modals 702 | 703 | // Padding applied to the modal body 704 | $modal-inner-padding: 15px !default; 705 | 706 | $modal-dialog-margin: 10px !default; 707 | $modal-dialog-margin-y-sm-up: 30px !default; 708 | 709 | $modal-title-line-height: $line-height-base !default; 710 | 711 | $modal-content-bg: $white !default; 712 | $modal-content-border-color: rgba($black,.2) !default; 713 | $modal-content-border-width: $border-width !default; 714 | $modal-content-box-shadow-xs: 0 3px 9px rgba($black,.5) !default; 715 | $modal-content-box-shadow-sm-up: 0 5px 15px rgba($black,.5) !default; 716 | 717 | $modal-backdrop-bg: $black !default; 718 | $modal-backdrop-opacity: .5 !default; 719 | $modal-header-border-color: $gray-200 !default; 720 | $modal-footer-border-color: $modal-header-border-color !default; 721 | $modal-header-border-width: $modal-content-border-width !default; 722 | $modal-footer-border-width: $modal-header-border-width !default; 723 | $modal-header-padding: 15px !default; 724 | 725 | $modal-lg: 800px !default; 726 | $modal-md: 500px !default; 727 | $modal-sm: 300px !default; 728 | 729 | $modal-transition: transform .3s ease-out !default; 730 | 731 | 732 | // Alerts 733 | // 734 | // Define alert colors, border radius, and padding. 735 | 736 | $alert-padding-y: .75rem !default; 737 | $alert-padding-x: 1.25rem !default; 738 | $alert-margin-bottom: 1rem !default; 739 | $alert-border-radius: $border-radius !default; 740 | $alert-link-font-weight: $font-weight-bold !default; 741 | $alert-border-width: $border-width !default; 742 | 743 | 744 | // Progress bars 745 | 746 | $progress-height: 1rem !default; 747 | $progress-font-size: .75rem !default; 748 | $progress-bg: $gray-200 !default; 749 | $progress-border-radius: $border-radius !default; 750 | $progress-box-shadow: inset 0 .1rem .1rem rgba($black,.1) !default; 751 | $progress-bar-color: $white !default; 752 | $progress-bar-bg: theme-color("primary") !default; 753 | $progress-bar-animation-timing: 1s linear infinite !default; 754 | $progress-bar-transition: width .6s ease !default; 755 | 756 | // List group 757 | 758 | $list-group-bg: $white !default; 759 | $list-group-border-color: rgba($black,.125) !default; 760 | $list-group-border-width: $border-width !default; 761 | $list-group-border-radius: $border-radius !default; 762 | 763 | $list-group-item-padding-y: .75rem !default; 764 | $list-group-item-padding-x: 1.25rem !default; 765 | 766 | $list-group-hover-bg: $gray-100 !default; 767 | $list-group-active-color: $component-active-color !default; 768 | $list-group-active-bg: $component-active-bg !default; 769 | $list-group-active-border-color: $list-group-active-bg !default; 770 | 771 | $list-group-disabled-color: $gray-600 !default; 772 | $list-group-disabled-bg: $list-group-bg !default; 773 | 774 | $list-group-action-color: $gray-700 !default; 775 | $list-group-action-hover-color: $list-group-action-color !default; 776 | 777 | $list-group-action-active-color: $body-color !default; 778 | $list-group-action-active-bg: $gray-200 !default; 779 | 780 | 781 | // Image thumbnails 782 | 783 | $thumbnail-padding: .25rem !default; 784 | $thumbnail-bg: $body-bg !default; 785 | $thumbnail-border-width: $border-width !default; 786 | $thumbnail-border-color: #ddd !default; 787 | $thumbnail-border-radius: $border-radius !default; 788 | $thumbnail-box-shadow: 0 1px 2px rgba($black,.075) !default; 789 | $thumbnail-transition: all .2s ease-in-out !default; 790 | 791 | 792 | // Figures 793 | 794 | $figure-caption-font-size: 90% !default; 795 | $figure-caption-color: $gray-600 !default; 796 | 797 | 798 | // Breadcrumbs 799 | 800 | $breadcrumb-padding-y: .75rem !default; 801 | $breadcrumb-padding-x: 1rem !default; 802 | $breadcrumb-item-padding: .5rem !default; 803 | 804 | $breadcrumb-margin-bottom: 1rem !default; 805 | 806 | $breadcrumb-bg: $gray-200 !default; 807 | $breadcrumb-divider-color: $gray-600 !default; 808 | $breadcrumb-active-color: $gray-600 !default; 809 | $breadcrumb-divider: "/" !default; 810 | 811 | 812 | // Carousel 813 | 814 | $carousel-control-color: $white !default; 815 | $carousel-control-width: 15% !default; 816 | $carousel-control-opacity: .5 !default; 817 | 818 | $carousel-indicator-width: 30px !default; 819 | $carousel-indicator-height: 3px !default; 820 | $carousel-indicator-spacer: 3px !default; 821 | $carousel-indicator-active-bg: $white !default; 822 | 823 | $carousel-caption-width: 70% !default; 824 | $carousel-caption-color: $white !default; 825 | 826 | $carousel-control-icon-width: 20px !default; 827 | 828 | $carousel-control-prev-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3E%3Cpath d='M4 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E"), "#", "%23") !default; 829 | $carousel-control-next-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3E%3Cpath d='M1.5 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E"), "#", "%23") !default; 830 | 831 | $carousel-transition: transform .6s ease !default; 832 | 833 | 834 | // Close 835 | 836 | $close-font-size: $font-size-base * 1.5 !default; 837 | $close-font-weight: $font-weight-bold !default; 838 | $close-color: $black !default; 839 | $close-text-shadow: 0 1px 0 $white !default; 840 | 841 | // Code 842 | 843 | $code-font-size: 90% !default; 844 | $code-padding-y: .2rem !default; 845 | $code-padding-x: .4rem !default; 846 | $code-color: #bd4147 !default; 847 | $code-bg: $gray-100 !default; 848 | 849 | $kbd-color: $white !default; 850 | $kbd-bg: $gray-900 !default; 851 | 852 | $pre-color: $gray-900 !default; 853 | $pre-scrollable-max-height: 340px !default; 854 | -------------------------------------------------------------------------------- /src/scss/bootstrap_overwrite/bootstrap.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v4.0.0-beta (https://getbootstrap.com) 3 | * Copyright 2011-2017 The Bootstrap Authors 4 | * Copyright 2011-2017 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | */ 7 | 8 | @import "../../../node_modules/bootstrap/scss/functions"; 9 | @import "variables"; 10 | @import "../../../node_modules/bootstrap/scss/mixins"; 11 | @import "../../../node_modules/bootstrap/scss/print"; 12 | @import "../../../node_modules/bootstrap/scss/reboot"; 13 | @import "../../../node_modules/bootstrap/scss/type"; 14 | @import "../../../node_modules/bootstrap/scss/images"; 15 | @import "../../../node_modules/bootstrap/scss/code"; 16 | @import "../../../node_modules/bootstrap/scss/grid"; 17 | @import "../../../node_modules/bootstrap/scss/tables"; 18 | @import "../../../node_modules/bootstrap/scss/forms"; 19 | @import "../../../node_modules/bootstrap/scss/buttons"; 20 | @import "../../../node_modules/bootstrap/scss/transitions"; 21 | @import "../../../node_modules/bootstrap/scss/dropdown"; 22 | @import "../../../node_modules/bootstrap/scss/button-group"; 23 | @import "../../../node_modules/bootstrap/scss/input-group"; 24 | @import "../../../node_modules/bootstrap/scss/custom-forms"; 25 | @import "../../../node_modules/bootstrap/scss/nav"; 26 | @import "../../../node_modules/bootstrap/scss/navbar"; 27 | @import "../../../node_modules/bootstrap/scss/card"; 28 | @import "../../../node_modules/bootstrap/scss/breadcrumb"; 29 | @import "../../../node_modules/bootstrap/scss/pagination"; 30 | @import "../../../node_modules/bootstrap/scss/badge"; 31 | @import "../../../node_modules/bootstrap/scss/jumbotron"; 32 | @import "../../../node_modules/bootstrap/scss/alert"; 33 | @import "../../../node_modules/bootstrap/scss/progress"; 34 | @import "../../../node_modules/bootstrap/scss/media"; 35 | @import "../../../node_modules/bootstrap/scss/list-group"; 36 | @import "../../../node_modules/bootstrap/scss/close"; 37 | @import "../../../node_modules/bootstrap/scss/modal"; 38 | @import "../../../node_modules/bootstrap/scss/tooltip"; 39 | @import "../../../node_modules/bootstrap/scss/popover"; 40 | @import "../../../node_modules/bootstrap/scss/carousel"; 41 | @import "../../../node_modules/bootstrap/scss/utilities"; 42 | -------------------------------------------------------------------------------- /src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | // bootstrap overwrite 4 | @import "../node_modules/bootstrap/scss/bootstrap"; 5 | @import "./scss/bootstrap_overwrite/bootstrap"; 6 | 7 | // own vars/mixins 8 | @import "scss/variables"; 9 | @import "scss/mixins"; 10 | 11 | // own components 12 | @import "scss/layout-admin"; 13 | 14 | @import "scss/headerbar"; 15 | @import "scss/footerbar"; 16 | @import "scss/sidebar"; 17 | @import "scss/mainbar"; 18 | @import "scss/alert"; 19 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/long-stack-trace-zone'; 4 | import 'zone.js/dist/proxy.js'; 5 | import 'zone.js/dist/sync-test'; 6 | import 'zone.js/dist/jasmine-patch'; 7 | import 'zone.js/dist/async-test'; 8 | import 'zone.js/dist/fake-async-test'; 9 | import { getTestBed } from '@angular/core/testing'; 10 | import { 11 | BrowserDynamicTestingModule, 12 | platformBrowserDynamicTesting 13 | } from '@angular/platform-browser-dynamic/testing'; 14 | 15 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. 16 | declare var __karma__: any; 17 | declare var require: any; 18 | 19 | // Prevent Karma from running prematurely. 20 | __karma__.loaded = function () {}; 21 | 22 | // First, initialize the Angular testing environment. 23 | getTestBed().initTestEnvironment( 24 | BrowserDynamicTestingModule, 25 | platformBrowserDynamicTesting() 26 | ); 27 | // Then we find all the tests. 28 | const context = require.context('./', true, /\.spec\.ts$/); 29 | // And load the modules. 30 | context.keys().map(context); 31 | // Finally, start Karma to run the tests. 32 | __karma__.start(); 33 | -------------------------------------------------------------------------------- /src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "es2015", 6 | "baseUrl": "", 7 | "types": [] 8 | }, 9 | "exclude": [ 10 | "test.ts", 11 | "**/*.spec.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "baseUrl": "", 8 | "types": [ 9 | "jasmine", 10 | "node" 11 | ] 12 | }, 13 | "files": [ 14 | "test.ts" 15 | ], 16 | "include": [ 17 | "**/*.spec.ts", 18 | "**/*.d.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc", 5 | "baseUrl": "src", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "moduleResolution": "node", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es5", 12 | "typeRoots": [ 13 | "node_modules/@types" 14 | ], 15 | "lib": [ 16 | "es2016", 17 | "dom" 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "callable-types": true, 7 | "class-name": true, 8 | "comment-format": [ 9 | true, 10 | "check-space" 11 | ], 12 | "curly": true, 13 | "eofline": true, 14 | "forin": true, 15 | "import-blacklist": [true, "rxjs"], 16 | "import-spacing": true, 17 | "indent": [ 18 | true, 19 | "spaces" 20 | ], 21 | "interface-over-type-literal": true, 22 | "label-position": true, 23 | "max-line-length": [ 24 | true, 25 | 140 26 | ], 27 | "member-access": false, 28 | "member-ordering": [ 29 | true, 30 | "static-before-instance", 31 | "variables-before-functions" 32 | ], 33 | "no-arg": true, 34 | "no-bitwise": true, 35 | "no-console": [ 36 | true, 37 | "debug", 38 | "info", 39 | "time", 40 | "timeEnd", 41 | "trace" 42 | ], 43 | "no-construct": true, 44 | "no-debugger": true, 45 | "no-duplicate-variable": true, 46 | "no-empty": false, 47 | "no-empty-interface": true, 48 | "no-eval": true, 49 | "no-inferrable-types": [true, "ignore-params"], 50 | "no-shadowed-variable": true, 51 | "no-string-literal": false, 52 | "no-string-throw": true, 53 | "no-switch-case-fall-through": true, 54 | "no-trailing-whitespace": true, 55 | "no-unused-expression": true, 56 | "no-use-before-declare": true, 57 | "no-var-keyword": true, 58 | "object-literal-sort-keys": false, 59 | "one-line": [ 60 | true, 61 | "check-open-brace", 62 | "check-catch", 63 | "check-else", 64 | "check-whitespace" 65 | ], 66 | "prefer-const": true, 67 | "quotemark": [ 68 | true, 69 | "single" 70 | ], 71 | "radix": true, 72 | "semicolon": [ 73 | "always" 74 | ], 75 | "triple-equals": [ 76 | true, 77 | "allow-null-check" 78 | ], 79 | "typedef-whitespace": [ 80 | true, 81 | { 82 | "call-signature": "nospace", 83 | "index-signature": "nospace", 84 | "parameter": "nospace", 85 | "property-declaration": "nospace", 86 | "variable-declaration": "nospace" 87 | } 88 | ], 89 | "typeof-compare": true, 90 | "unified-signatures": true, 91 | "variable-name": false, 92 | "whitespace": [ 93 | true, 94 | "check-branch", 95 | "check-decl", 96 | "check-operator", 97 | "check-separator", 98 | "check-type" 99 | ], 100 | 101 | "directive-selector": [true, "attribute", "tox", "camelCase"], 102 | "component-selector": [true, "element", "tox", "kebab-case"], 103 | "use-input-property-decorator": true, 104 | "use-output-property-decorator": true, 105 | "use-host-property-decorator": true, 106 | "no-input-rename": true, 107 | "no-output-rename": true, 108 | "use-life-cycle-interface": true, 109 | "use-pipe-transform-interface": true, 110 | "component-class-suffix": true, 111 | "directive-class-suffix": true, 112 | "no-access-missing-member": true, 113 | "templates-use-public": true, 114 | "invoke-injectable": true 115 | } 116 | } 117 | --------------------------------------------------------------------------------