diff --git a/.gitignore b/.gitignore index 5148e52..e9a3d6e 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,4 @@ jspm_packages .npm # Optional REPL history -.node_repl_history +.node_repl_history \ No newline at end of file diff --git a/LICENSE b/LICENSE index 089ab33..6f2c402 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 NerdCats +Copyright (c) 2016 NerdCats Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..dc0c387 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,36 @@ +# AppVeyor file +# http://www.appveyor.com/docs/appveyor-yml +# This file: cloned from https://github.com/gruntjs/grunt/blob/master/appveyor.yml + +# Build version format +version: "{build}" + +# Test against this version of Node.js +environment: + nodejs_version: "5.5.0" + +build: off + +clone_depth: 10 + +# Fix line endings on Windows +init: + - git config --global core.autocrlf true + +install: + - ps: Install-Product node $env:nodejs_version + - npm install -g npm + - ps: $env:path = $env:appdata + "\npm;" + $env:path + - npm install + +test_script: + # Output useful info for debugging. + - node --version && npm --version + - node -e 'console.log(process.env);' + # We test multiple Windows shells because of prior stdout buffering issues + # filed against Grunt. https://github.com/joyent/node/issues/3584 + - ps: "npm test # PowerShell" # Pass comment to PS for easier debugging + - cmd: npm test + +cache: + - node_modules -> package.json # local npm modules diff --git a/config/env/env.ts b/config/env/env.ts new file mode 100644 index 0000000..6100db6 --- /dev/null +++ b/config/env/env.ts @@ -0,0 +1,16 @@ +/** + * THIS FILE IS GENERATED by `gulp env` command from `env.json` + * Generated on <%= new Date() %> + * + * Make sure the keys in `env.model.ts` exist in `env.json` + * otherwise it'll throw message like this + * Property '' is missing in type '{}' + * + * Feel free to modify for direct updates in development + */ + +import { AppEnv } from './env.model'; + +export const ENV: AppEnv = {<% _.forEach(env, function(v, k) { %> + <%= k %>: <%= _.isString(v) ? "\'"+v+"\'" : v %>,<% }) %> +}; diff --git a/config/gulp/config.js b/config/gulp/config.js new file mode 100644 index 0000000..61dee8b --- /dev/null +++ b/config/gulp/config.js @@ -0,0 +1,121 @@ +var envConfig = require('./utils/env'); + +module.exports = function () { + var root = '', + src = root + 'src/', + config = root + 'config/', + app = src + 'app/', + test = src + 'test/', + tmp = src + 'tmp/', + tmpApp = tmp + 'app/', + tmpTest = tmp + 'test/', + testHelper = test + 'test-helpers/', + e2e = root + 'e2e/', + assets = src + 'assets/', + assetsPath = { + styles: assets + 'styles/', + images: assets + 'images/', + fonts: assets + 'fonts/' + }, + index = src + 'index.html', + tsFiles = [ + app + '**/!(*.spec)+(.ts)' + ], + tsTestFiles = { + unit: [app + '**/*.spec.ts'], + e2e: [e2e + '**/*.ts'], + helper: [testHelper + '**/*.ts'] + }, + build = { + path: 'build/', + app: 'build/app/', + fonts: 'build/fonts', + assetPath: 'build/assets/', + assets: { + lib: { + js: 'lib.js', + css: 'lib.css' + } + } + }, + report = { + path: 'report/' + }; + + var e2eConfig = { + seleniumTarget: 'http://127.0.0.1:3000' + }; + + var systemJs = { + builder: { + normalize: true, + minify: true, + mangle: true, + runtime: false, + globalDefs: { + DEBUG: false, + ENV: 'production' + } + } + }; + + var gulpConfig = { + root: root, + config: config, + src: src, + app: app, + test: test, + tmp: tmp, + tmpApp: tmpApp, + tmpTest: tmpTest, + testHelper: testHelper, + e2e: e2e, + e2eConfig: e2eConfig, + assets: assets, + index: index, + build: build, + report: report, + assetsPath: assetsPath, + tsFiles: tsFiles, + tsTestFiles: tsTestFiles, + systemJs: systemJs + }; + + if (envConfig.ENV === envConfig.ENVS.DEV) + { + var historyApiFallback = require('connect-history-api-fallback'); + var browserSync = { + dev: { + port: 3000, + injectChanges: false, + server: { + baseDir: './src/', + middleware: [historyApiFallback()], + routes: { + "/node_modules": "node_modules", + "/src": "src" + } + }, + files: [ + src + "index.html", + src + "systemjs.conf.js", + assetsPath.styles + "main.css", + tmpApp + "**/*.js", + app + "**/*.css", + app + "**/*.html" + ] + }, + prod: { + port: 3001, + server: { + baseDir: './' + build.path, + middleware: [historyApiFallback()] + } + } + }; + + gulpConfig.browserSync = browserSync; + } + + return gulpConfig; +}; diff --git a/config/gulp/tasks/build.js b/config/gulp/tasks/build.js new file mode 100644 index 0000000..a0a46a0 --- /dev/null +++ b/config/gulp/tasks/build.js @@ -0,0 +1,75 @@ +var gulp = require('gulp'); +var util = require('gulp-util'); +var runSequence = require('run-sequence'); +var config = require('../config')(); +var useref = require('gulp-useref'); +var gulpif = require('gulp-if'); +var rev = require('gulp-rev'); +var revReplace = require('gulp-rev-replace'); +var uglify = require('gulp-uglify'); +var cssnano = require('gulp-cssnano'); +var gulpTemplate = require('gulp-template'); +var flatten = require('gulp-flatten'); + +var envVars = require('../utils/env-vars'); + +require('@ngstarter/systemjs-extension')(config); + +gulp.task('build', function (done) { + runSequence('test', 'build-systemjs', 'build-assets', done); +}); + +/* Concat and minify/uglify all css, js, and copy fonts */ +gulp.task('build-assets', function (done) { + runSequence('clean-build', ['sass', 'fonts'], function () { + gulp.src(config.app + '**/*.html') + .pipe(flatten()) + .pipe(gulp.dest(config.build.path)); + + gulp.src(config.app + '**/*.css') + .pipe(cssnano({zindex: false})) + .pipe(flatten()) + .pipe(gulp.dest(config.build.path)); + + gulp.src(config.src + 'favicon.ico') + .pipe(gulp.dest(config.build.path)); + + gulp.src(config.assetsPath.images + '**/*.*', { + base: config.assetsPath.images + }) + .pipe(gulp.dest(config.build.assetPath + 'images')); + + gulp.src(config.index) + .pipe(useref()) + .pipe(gulpif('assets/lib.js', uglify())) + .pipe(gulpif('*.css', cssnano())) + .pipe(gulpif('!*.html', rev())) + .pipe(revReplace()) + .pipe(gulp.dest(config.build.path)) + .on('finish', done); + }); +}); + +/* Copy fonts in packages */ +gulp.task('fonts', function () { + gulp.src(config.assetsPath.fonts + '**/*.*', { + base: config.assetsPath.fonts + }) + .pipe(gulp.dest(config.build.fonts)); + + gulp.src([ + 'node_modules/font-awesome/fonts/*.*' + ]) + .pipe(gulp.dest(config.build.fonts)); +}); + +gulp.task('env', function () { + return gulp.src(config.config + 'env/env.ts') + .pipe(gulpTemplate({ + env: envVars || {} + })) + .pipe(gulp.dest(config.app + 'shared/constant')) + .on('finish', function () { + util.log(config.app + 'shared/constant/env.ts is generated successfully'); + }); +}); diff --git a/config/gulp/tasks/clean.js b/config/gulp/tasks/clean.js new file mode 100644 index 0000000..39a2370 --- /dev/null +++ b/config/gulp/tasks/clean.js @@ -0,0 +1,29 @@ +var gulp = require('gulp'); +var config = require('../config')(); +var del = require('del'); + +/* Run all clean tasks */ +gulp.task('clean', ['clean-build', 'clean-report', 'clean-ts']); + +/* Clean build folder */ +gulp.task('clean-build', function () { + return del([config.build.path]); +}); + +/* Clean report folder */ +gulp.task('clean-report', function () { + return del([config.report.path]); +}); + +/* Clean js and map */ +gulp.task('clean-ts', function () { + return del([config.tmp]); +}); + +gulp.task('clean-ts-app', function () { + return del([config.tmpApp]); +}); + +gulp.task('clean-ts-test', function () { + return del([config.tmpTest]); +}); \ No newline at end of file diff --git a/config/gulp/tasks/component.js b/config/gulp/tasks/component.js new file mode 100644 index 0000000..26343ca --- /dev/null +++ b/config/gulp/tasks/component.js @@ -0,0 +1,37 @@ +var gulp = require('gulp'); +var path = require('path'); + +var config = require('../config')(); + +gulp.task('html', function () { + return gulp.src(config.app + '**/*.html') + .pipe(gulp.dest(config.tmpApp)); +}); + +gulp.task('watch-html', function () { + gulp.watch(config.app + '**/*.html', function(file) { + var des = convertToTmpPath(file); + + return gulp.src(file.path) + .pipe(gulp.dest(path.dirname(des))); + }); +}); + +gulp.task('css', function () { + return gulp.src(config.app + '**/*.css') + .pipe(gulp.dest(config.tmpApp)); +}); + +gulp.task('watch-css', function () { + gulp.watch(config.app + '**/*.css', function(file) { + var des = convertToTmpPath(file); + + return gulp.src(file.path) + .pipe(gulp.dest(path.dirname(des))); + }); +}); + +function convertToTmpPath(file) { + var unixPath = file.path.replace(/\\/g, "/"); + return unixPath.replace(/src\/app\//, config.tmpApp); +} diff --git a/config/gulp/tasks/sass.js b/config/gulp/tasks/sass.js new file mode 100644 index 0000000..7d60677 --- /dev/null +++ b/config/gulp/tasks/sass.js @@ -0,0 +1,13 @@ +var gulp = require('gulp'); +var sass = require('gulp-sass'); +var config = require('../config')(); + +gulp.task('sass', function () { + return gulp.src(config.assetsPath.styles + 'main.scss') + .pipe(sass().on('error', sass.logError)) + .pipe(gulp.dest(config.assetsPath.styles)); +}); + +gulp.task('watch-sass', function () { + gulp.watch(config.assetsPath.styles + '**/*.scss', ['sass']); +}); diff --git a/config/gulp/tasks/serve.js b/config/gulp/tasks/serve.js new file mode 100644 index 0000000..9571059 --- /dev/null +++ b/config/gulp/tasks/serve.js @@ -0,0 +1,34 @@ +var runSequence = require('run-sequence'); + +var envConfig = require('../utils/env'); + +if (envConfig.ENV === envConfig.ENVS.DEV) +{ + var gulp = require('gulp'); + var config = require('../config')(); + var bs = require("browser-sync"); + + function startBrowsersync (config) + { + bsIns = bs.create(); + bsIns.init(config); + bsIns.reload(); + } + + /* Start live server dev mode */ + gulp.task('serve-dev', function () + { + runSequence( + ['sass', 'tsc-app'], + ['html', 'css'], + ['watch-sass', 'watch-ts', 'watch-html', 'watch-css'], function() { + startBrowsersync(config.browserSync.dev); + }); + }); + + /* Start live server production mode */ + gulp.task('serve-build', ['build'], function () + { + startBrowsersync(config.browserSync.prod); + }); +} diff --git a/config/gulp/tasks/test.js b/config/gulp/tasks/test.js new file mode 100644 index 0000000..b3a8596 --- /dev/null +++ b/config/gulp/tasks/test.js @@ -0,0 +1,70 @@ +var gulp = require('gulp'); +var util = require('gulp-util'); +var config = require('../config')(); +var Server = require('karma').Server; +var gulpProtractor = require('gulp-protractor'); +var remapIstanbul = require('remap-istanbul/lib/gulpRemapIstanbul'); +var runSequence = require('run-sequence'); +var argv = require('yargs') + .alias('w', 'watch') + .argv; + +gulp.task('test', ['clean-report', 'unit-test']); + +gulp.task('unit-test', ['tsc'], function (done) { + var watch = argv.watch || false; + + runSequence(['html', 'css'], copyComponentFilesDone); + + if (watch) { + runSequence(['watch-ts', 'watch-html', 'watch-css']); + console.log('=== Unit Test Watch Mode ==='); + console.log('- It will autowatch the changed files and re-run the test'); + console.log('- Press Cmd/Ctrl + C to exit and get the coverage result'); + console.log('- Press Cmd/Ctrl + C again to close the TSC watch.'); + } + + function copyComponentFilesDone() { + new Server({ + configFile: __dirname + '/../../test/karma.conf.js', + singleRun: !watch + }, karmaDone).start(); + } + + function karmaDone (exitCode) { + remapCoverage(done, exitCode); + } +}); + +gulp.task('e2e', ['e2e-test']); +gulp.task('driver-update', gulpProtractor['webdriver_update']); +gulp.task('e2e-test', ['driver-update'], function () { + gulp.src(config.e2e + '**/*.spec.ts') + .pipe(gulpProtractor.protractor({ + configFile: 'config/test/protractor.conf.js', + args: ['--baseUrl', config.e2eConfig.seleniumTarget] + })) + .on('error', function(e) { + util.log('Error running E2E testing'); + process.exit(1); + }); +}); + +function remapCoverage (done, exitCode) { + util.log('Remapping coverage to TypeScript format...'); + gulp.src(config.report.path + 'report-json/coverage-final.json') + .pipe(remapIstanbul({ + basePath: config.src, + reports: { + 'lcovonly': config.report.path + 'remap/lcov.info', + 'json': config.report.path + 'remap/coverage.json', + 'html': config.report.path + 'remap/html-report', + 'text-summary': config.report.path + 'remap/text-summary.txt' + } + })) + .on('finish', function () { + util.log('Test Done with exit code: ' + exitCode); + done(exitCode); + util.log('Remapping done! View the result in report/remap/html-report'); + }); +} diff --git a/config/gulp/tasks/typescript.js b/config/gulp/tasks/typescript.js new file mode 100644 index 0000000..1c10e9b --- /dev/null +++ b/config/gulp/tasks/typescript.js @@ -0,0 +1,85 @@ +var gulp = require('gulp'); +var util = require('gulp-util'); +var config = require('../config')(); +var ts = require('gulp-typescript'); +var tslint = require('gulp-tslint'); +var sourcemaps = require('gulp-sourcemaps'); +var argv = require('yargs').argv; + +/* Initialize TS Project */ +var typingFiles = [ + config.src + 'manual_typings/**/*.d.ts' +]; +var tsUnitFiles = [].concat(config.tsTestFiles.unit, config.tsTestFiles.helper); +var tsFiles = [].concat(config.tsFiles, tsUnitFiles); + +/* Watch changed typescripts file and compile it */ +gulp.task('watch-ts', function () { + return gulp.watch(tsFiles, function (file) { + util.log('Compiling ' + file.path + '...'); + return compileTs(file.path, true); + }); +}); + +/* Compile typescripts */ +gulp.task('tsc', ['clean-ts', 'env'], function () { + return compileTs(tsFiles); +}); + +gulp.task('tsc-app', ['env'], function () { + return compileTs(config.tsFiles); +}); + +gulp.task('tsc-unit', ['clean-ts-test'], function () { + return compileTs(tsUnitFiles); +}); + +/* Lint typescripts */ +gulp.task('tslint', function () { + return lintTs(tsFiles); +}); + +gulp.task('tslint-app', function () { + return lintTs(config.tsFiles); +}); + +gulp.task('tslint-unit', function () { + return lintTs(tsUnitFiles); +}); + +function lintTs(files) { + return gulp.src(files) + .pipe(tslint({ + formatter: 'verbose' + })) + .pipe(tslint.report()); +} + +function compileTs(files, watchMode) { + var inline = !argv.excludeSource; + watchMode = watchMode || false; + + var tsProject = ts.createProject('tsconfig.json'); + var allFiles = [].concat(files, typingFiles); + var res = gulp.src(allFiles, { + base: config.src, + outDir: config.tmp + }) + .pipe(tslint({ + formatter: 'verbose' + })) + .pipe(tslint.report()) + .pipe(sourcemaps.init()) + .pipe(tsProject()) + .on('error', function () { + if (watchMode) { + return; + } + process.exit(1); + }); + return res.js + .pipe(sourcemaps.write('.', { + includeContent: inline + })) + .pipe(gulp.dest(config.tmp)); +} \ No newline at end of file diff --git a/config/gulp/utils/dashboard.js b/config/gulp/utils/dashboard.js new file mode 100644 index 0000000..8cb9928 --- /dev/null +++ b/config/gulp/utils/dashboard.js @@ -0,0 +1,31 @@ +var envVars = require('../utils/env-vars'), + envConfig = require('../utils/env'), + util = require('gulp-util'), + _ = require('lodash'), + envStatusMessage; + +var color; +var colorMap = { + 'development': 'bgGreen', + 'production': 'bgCyan' +}; +color = colorMap[envConfig.ENV] || 'bgMagenta'; + +var StarterDashboard = { + show: function() { + if (envVars) { + envStatusMessage = '- env.json is detected. ' + _.toArray(envVars).length + + ' values loaded.'; + } else { + envStatusMessage = '- env.json is not detected. You can create one on project root'; + } + + console.log('============ DataCat dash ============'); + console.log('Current environment: ' + util.colors[color](envConfig.ENV)); + console.log('- Change environment via --env or NODE_ENV'); + console.log(envStatusMessage); + console.log('==========================================='); + } +}; + +module.exports = StarterDashboard; diff --git a/config/gulp/utils/env-vars.js b/config/gulp/utils/env-vars.js new file mode 100644 index 0000000..7e49647 --- /dev/null +++ b/config/gulp/utils/env-vars.js @@ -0,0 +1,7 @@ +var ENV_VARS; + +try { + ENV_VARS = require('../../../env.json'); +} catch(e) {} + +module.exports = ENV_VARS; diff --git a/config/gulp/utils/env.js b/config/gulp/utils/env.js new file mode 100644 index 0000000..fa9b512 --- /dev/null +++ b/config/gulp/utils/env.js @@ -0,0 +1,14 @@ +var argv = require('yargs').argv; + +var ENVS = { + DEV: 'development', + PROD: 'production', + TEST: 'testing' +}; + +var ENV = argv.env || process.env.NODE_ENV || ENVS.DEV; + +module.exports = { + ENV: ENV, + ENVS: ENVS +}; diff --git a/config/test/karma-test-shim.js b/config/test/karma-test-shim.js new file mode 100644 index 0000000..f7b1976 --- /dev/null +++ b/config/test/karma-test-shim.js @@ -0,0 +1,40 @@ +// Turn on full stack traces in errors to help debugging +Error.stackTraceLimit=Infinity; + +jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; + +// Cancel Karma's synchronous start, +// we will call `__karma__.start()` later, once all the specs are loaded. +__karma__.loaded = function() {}; + +System.import('test/test-helpers/setup') +.then(function() { + return Promise.all( + Object.keys(window.__karma__.files) + .filter(onlySpecFiles) + .map(file2moduleName) + .map(importModules) + ); +}) +.then(function() { + __karma__.start(); +}, function(error) { + __karma__.error(error.name + ": " + error.message); +}); + +// Filter spec files +function onlySpecFiles(path) { + return /\.spec\.js$/.test(path); +} + +// Normalize paths to module names. +function file2moduleName(filePath) { + return filePath.replace(/\\/g, '/') + .replace(/^\/base\//, '') + .replace(/\.js/, ''); +} + +// Import module path +function importModules(path) { + return System.import(path); +} diff --git a/config/test/karma.conf.js b/config/test/karma.conf.js new file mode 100644 index 0000000..af04eaa --- /dev/null +++ b/config/test/karma.conf.js @@ -0,0 +1,97 @@ +module.exports = function(config) { + var gulpConfig = require('../gulp/config')(); + + /** + * List of npm packages that imported via `import` syntax + */ + var dependencies = [ + '@angular', + 'lodash', + 'rxjs' + ]; + + var configuration = { + basePath: '../../', + + frameworks: ['jasmine'], + browsers: ['PhantomJS'], + reporters: ['progress', 'coverage'], + + preprocessors: {}, + + // Generate json used for remap-istanbul + coverageReporter: { + dir: 'report/', + reporters: [ + { type: 'json', subdir: 'report-json' } + ] + }, + + files: [ + 'node_modules/core-js/client/shim.min.js', + 'node_modules/zone.js/dist/zone.js', + 'node_modules/zone.js/dist/long-stack-trace-zone.js', + 'node_modules/zone.js/dist/proxy.js', + 'node_modules/zone.js/dist/sync-test.js', + 'node_modules/zone.js/dist/jasmine-patch.js', + 'node_modules/zone.js/dist/async-test.js', + 'node_modules/zone.js/dist/fake-async-test.js', + 'node_modules/systemjs/dist/system.src.js' + ], + + // proxied base paths + proxies: { + // required for component assests fetched by Angular's compiler + "/src/": "/base/src/", + "/app/": "/base/src/app/", + "/tmp/": "/base/src/tmp/", + "/node_modules/": "/base/node_modules/" + }, + + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true + }; + + configuration.preprocessors[gulpConfig.tmpApp + '**/!(*.spec)+(.js)'] = ['coverage']; + configuration.preprocessors[gulpConfig.tmpApp + '**/*.js'] = ['sourcemap']; + configuration.preprocessors[gulpConfig.tmpTest + '**/*.js'] = ['sourcemap']; + + var files = [ + gulpConfig.tmpTest + 'test-helpers/global/**/*.js', + gulpConfig.src + 'systemjs.conf.js', + 'config/test/karma-test-shim.js', + createFilePattern(gulpConfig.tmpApp + '**/*.js', { included: false }), + createFilePattern(gulpConfig.tmpTest + 'test-helpers/*.js', { included: false }), + createFilePattern(gulpConfig.app + '**/*.html', { included: false }), + createFilePattern(gulpConfig.tmpApp + '**/*.html', { included: false }), + createFilePattern(gulpConfig.app + '**/*.css', { included: false }), + createFilePattern(gulpConfig.app + '**/*.ts', { included: false, watched: false }), + createFilePattern(gulpConfig.tmpApp + '**/*.js.map', { included: false, watched: false }) + ]; + + configuration.files = configuration.files.concat(files); + + dependencies.forEach(function(key) { + configuration.files.push({ + pattern: 'node_modules/' + key + '/**/!(*.spec)+(.js)', + included: false, + watched: false + }); + }); + + if (process.env.APPVEYOR) { + configuration.browsers = ['IE']; + configuration.singleRun = true; + configuration.browserNoActivityTimeout = 90000; // Note: default value (10000) is not enough + } + + config.set(configuration); + + // Helpers + function createFilePattern(path, config) { + config.pattern = path; + return config; + } +} diff --git a/config/test/protractor.conf.js b/config/test/protractor.conf.js new file mode 100644 index 0000000..20d91ed --- /dev/null +++ b/config/test/protractor.conf.js @@ -0,0 +1,23 @@ +require('ts-node/register'); + +var glob = require('glob'); +var seleniumPath = '../node_modules/gulp-protractor/node_modules/protractor/selenium/'; +var seleniumJarPath = ''; + +glob(seleniumPath + '*.jar', + function(err, files) { + seleniumJarPath = files[0]; + }); + +exports.config = { + seleniumServerJar: seleniumJarPath, + capabilities: { + 'browserName': 'chrome' + }, + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 60000 + }, + allScriptsTimeout: 30000, + useAllAngular2AppRoots: true +}; diff --git a/e2e/home/home.spec.ts b/e2e/home/home.spec.ts new file mode 100644 index 0000000..691e427 --- /dev/null +++ b/e2e/home/home.spec.ts @@ -0,0 +1,12 @@ +describe('Home page', () => { + beforeAll(done => { + browser.get('/') + .then(done); + }); + + it('should have image', () => { + browser.sleep(1000); + let ng2Img = element(by.css('img')); + expect(ng2Img.isDisplayed()).toBeTruthy(); + }); +}); diff --git a/env.example.json b/env.example.json new file mode 100644 index 0000000..73fe5c3 --- /dev/null +++ b/env.example.json @@ -0,0 +1,4 @@ +{ + "API_BASE": "http://localhost:5000/api/", + "AUTH_BASE": "http://fetchdev.gobd.co/api/" +} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..380fa1e --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,9 @@ +var gulp = require('gulp'), + requireDir = require('require-dir'), + tasks = requireDir('./config/gulp/tasks'), + dashboard = require('./config/gulp/utils/dashboard'); + +dashboard.show(); + +/* Default task */ +gulp.task('default', ['serve-dev']); diff --git a/package.json b/package.json new file mode 100644 index 0000000..91d2b74 --- /dev/null +++ b/package.json @@ -0,0 +1,102 @@ +{ + "name": "datacat-dash", + "version": "1.0.0", + "author": "NerdCats", + "description": "Client dashboard for DataCat", + "main": "src/tmp/app/main.js", + "repository": { + "type": "git", + "url": "https://github.com/NerdCats/DataCat.git" + }, + "engines": { + "node": ">=4.3", + "npm": "~3.0.0" + }, + "scripts": { + "start": "gulp serve-dev", + "test": "gulp test", + "e2e": "gulp e2e", + "env": "gulp env", + "build": "gulp build", + "serve-build": "gulp serve-build", + "clean": "gulp clean", + "coverage": "coveralls < ./report/remap/lcov.info" + }, + "keywords": [ + "angular2", + "starter", + "seed", + "gulp", + "webpack", + "extensible", + "systemjs", + "systemjs builder", + "travis", + "karma", + "jasmine", + "istanbul" + ], + "license": "MIT", + "dependencies": { + "@angular/common": "^2.3.0", + "@angular/compiler": "^2.3.0", + "@angular/core": "^2.3.0", + "@angular/forms": "^2.3.0", + "@angular/http": "^2.3.0", + "@angular/platform-browser": "^2.3.0", + "@angular/platform-browser-dynamic": "^2.3.0", + "@angular/router": "^3.0.0", + "@ngstarter/systemjs-extension": "1.0.0-rc.4", + "@types/core-js": "^0.9.34", + "@types/jasmine": "^2.5.36", + "@types/lodash": "^4.14.37", + "@types/selenium-webdriver": "^2.44.28", + "angular2-jwt": "^0.1.27", + "bootstrap": "^3.3.7", + "chart.js": "^2.5.0", + "codelyzer": "~1.0.0-beta.4", + "core-js": "^2.4.1", + "del": "~2.2.2", + "font-awesome": "^4.7.0", + "glob": "^7.0.6", + "gulp": "^3.9.1", + "gulp-cssnano": "^2.1.2", + "gulp-flatten": "^0.3.1", + "gulp-if": "~2.0.1", + "gulp-protractor": "^3.0.0", + "gulp-rev": "^7.1.2", + "gulp-rev-replace": "^0.4.3", + "gulp-sass": "^2.3.2", + "gulp-sourcemaps": "^2.2.0", + "gulp-template": "^4.0.0", + "gulp-tslint": "6.1.2", + "gulp-typescript": "~3.1.2", + "gulp-uglify": "~2.0.0", + "gulp-useref": "~3.1.2", + "jasmine-core": "~2.5.0", + "jquery": "^3.1.0", + "karma": "~1.3.0", + "karma-coverage": "~1.1.1", + "karma-ie-launcher": "^1.0.0", + "karma-jasmine": "~1.0.2", + "karma-phantomjs-launcher": "~1.0.2", + "karma-sourcemap-loader": "^0.3.7", + "lodash": "^4.15.0", + "ng2-charts": "^1.5.0", + "phantomjs-prebuilt": "^2.1.12", + "remap-istanbul": "~0.6.4", + "require-dir": "~0.3.0", + "run-sequence": "~1.2.2", + "rxjs": "^5.0.1", + "systemjs": "^0.19.40", + "tslint": "~3.15.1", + "typescript": "~2.1.4", + "yargs": "^6.3.0", + "zone.js": "^0.7.0" + }, + "devDependencies": { + "browser-sync": "^2.17.5", + "connect-history-api-fallback": "^1.2.0", + "ts-node": "^1.6.1" + } +} diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts new file mode 100644 index 0000000..7a0fc09 --- /dev/null +++ b/src/app/app.component.spec.ts @@ -0,0 +1,51 @@ +import { + RouterTestingModule +} from '@angular/router/testing'; +import { + async, + TestBed, + ComponentFixture +} from '@angular/core/testing'; +import { provideRoutes, Routes, RouterModule } from '@angular/router'; +import { Component } from '@angular/core'; + +import { AppComponent } from './app.component'; + +@Component({ + selector: 'as-test-cmp', + template: '
Hello test
' +}) +class TestRouterComponent { +} + +let config: Routes = [ + { + path: '', component: TestRouterComponent + } +]; + +describe('AppComponent', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ + TestRouterComponent, + AppComponent + ], + imports: [ RouterTestingModule, RouterModule ], + providers: [ provideRoutes(config) ] + }); + }); + + it('should have title Hello world', async(() => { + TestBed.compileComponents().then(() => { + let fixture: ComponentFixture; + fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + + let compiled = fixture.debugElement.nativeElement; + expect(compiled).toBeDefined(); + // TODO: find a way to compile the routed component + // expect(compiled.querySelector('div.title')).toMatch('Hello world'); + }); + })); +}); diff --git a/src/app/app.component.ts b/src/app/app.component.ts new file mode 100644 index 0000000..4144431 --- /dev/null +++ b/src/app/app.component.ts @@ -0,0 +1,18 @@ +import { Component } from '@angular/core'; +import { Title } from '@angular/platform-browser'; + +import { CONSTANTS } from './shared'; + +@Component({ + moduleId: module.id, + selector: 'as-main-app', + templateUrl: 'app.html' +}) +export class AppComponent { + public appBrand: string; + + constructor(private titleService: Title) { + this.appBrand = CONSTANTS.MAIN.APP.BRAND; + this.titleService.setTitle(this.appBrand); + } +} diff --git a/src/app/app.html b/src/app/app.html new file mode 100644 index 0000000..353a45a --- /dev/null +++ b/src/app/app.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/src/app/app.module.ts b/src/app/app.module.ts new file mode 100644 index 0000000..fd27c1f --- /dev/null +++ b/src/app/app.module.ts @@ -0,0 +1,25 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { HttpModule } from '@angular/http'; + +import { APP_PROVIDERS } from './app.providers'; +import { AppComponent } from './app.component'; +import { appRoutingProviders, routing } from './app.routing'; +import { LoginModule } from './login/login.module'; +import { DashboardModule } from './dashboard/dashboard.module'; + +@NgModule({ + declarations: [ + AppComponent, + ], + imports: [ + BrowserModule, + HttpModule, + DashboardModule, + LoginModule, + routing + ], + providers: [APP_PROVIDERS, appRoutingProviders], + bootstrap: [AppComponent] +}) +export class AppModule { } diff --git a/src/app/app.providers.ts b/src/app/app.providers.ts new file mode 100644 index 0000000..534c0bf --- /dev/null +++ b/src/app/app.providers.ts @@ -0,0 +1,8 @@ +import { LOCAL_STORAGE_PROVIDERS, LOGGER_PROVIDERS } from './shared'; +import { AuthGuard } from './auth/auth.guard'; + +export const APP_PROVIDERS = [ + AuthGuard, + ...LOCAL_STORAGE_PROVIDERS, + ...LOGGER_PROVIDERS +]; diff --git a/src/app/app.routing.ts b/src/app/app.routing.ts new file mode 100644 index 0000000..28994c7 --- /dev/null +++ b/src/app/app.routing.ts @@ -0,0 +1,31 @@ +import { Routes, RouterModule } from '@angular/router'; + +import { LoginRoute } from './login/index'; +import { DashboardRoutes } from './dashboard/index'; + +import { AuthGuard } from './auth/auth.guard'; + +const securedRoutes: Routes = [ + ...DashboardRoutes +]; + +for (let route of securedRoutes) { + if (route) { + route.canActivate = [AuthGuard]; + } +} + +const publicRoutes: Routes = [ + LoginRoute +]; + +const appRoutes: Routes = [ + ...publicRoutes, + ...securedRoutes +]; + +export const appRoutingProviders: any[] = [ + +]; + +export const routing = RouterModule.forRoot(appRoutes); diff --git a/src/app/auth/auth.constants.ts b/src/app/auth/auth.constants.ts new file mode 100644 index 0000000..91cdb40 --- /dev/null +++ b/src/app/auth/auth.constants.ts @@ -0,0 +1,3 @@ +export class AuthConstants { + public static AUTH_TOKEN_KEY: string = 'currentUser'; +}; diff --git a/src/app/auth/auth.guard.ts b/src/app/auth/auth.guard.ts new file mode 100644 index 0000000..cd95327 --- /dev/null +++ b/src/app/auth/auth.guard.ts @@ -0,0 +1,27 @@ +import { Injectable } from '@angular/core'; +import { Router, CanActivate } from '@angular/router'; +import { AuthConstants } from './auth.constants'; + +@Injectable() +export class AuthGuard implements CanActivate { + + private _loginRoute: string; + public get loginRoute(): string { + return this._loginRoute; + } + public set loginRoute(v: string) { + this._loginRoute = v; + } + + /** + * AuthGuard should block components from loading if authentication denies so + */ + constructor(private router: Router) { } + + canActivate() { + if (localStorage.getItem(AuthConstants.AUTH_TOKEN_KEY)) { + return true; + } + this.router.navigate([this.loginRoute || '/login']); + } +} diff --git a/src/app/auth/auth.module.ts b/src/app/auth/auth.module.ts new file mode 100644 index 0000000..8f9ce3e --- /dev/null +++ b/src/app/auth/auth.module.ts @@ -0,0 +1,13 @@ +import { NgModule } from '@angular/core'; +import { AuthConstants, AuthGuard, AuthService} from './index'; +import { JwtHelper } from 'angular2-jwt'; + +@NgModule({ + providers: [ + AuthService, + AuthConstants, + AuthGuard, + JwtHelper + ] +}) +export class AuthModule {} diff --git a/src/app/auth/auth.service.ts b/src/app/auth/auth.service.ts new file mode 100644 index 0000000..b32c6f0 --- /dev/null +++ b/src/app/auth/auth.service.ts @@ -0,0 +1,82 @@ +import { Injectable } from '@angular/core'; +import { Http, Headers, Response } from '@angular/http'; +import { Router } from '@angular/router'; +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/throw'; +import 'rxjs/add/operator/map'; +import 'rxjs/add/operator/catch'; +import { AuthConstants } from './auth.constants'; +import { JwtHelper } from 'angular2-jwt'; +import { CONSTANTS, LoggerService, LocalStorage } from '../shared/index'; + +@Injectable() +export class AuthService { + /** + * Authentication service for enterprise dashboard + */ + constructor( + private http: Http, + private localStorage: LocalStorage, + private jwtHelper: JwtHelper, + private router: Router, + private loggerService: LoggerService) { } + + login(username: string, password: string) { + let headers = new Headers(); + let tokenUrl = CONSTANTS.ENV.AUTH_BASE + 'auth/token'; // TODO: Need to definitely load from settings + + let urlEncodedParam = + 'grant_type=' + 'password' + + '&username=' + username + + '&password=' + password + + '&client_id=' + 'GoFetchDevWebApp'; // TODO: We need to load this from either environment or settings somewhere. + + headers.append('Content-Type', 'application/x-www-form-urlencoded'); + + return this.http.post(tokenUrl, urlEncodedParam, { headers }) + .map((res: Response) => { + if (res.status < 200 || res.status >= 300) { + throw new Error('Response status: ' + res.status); + } + return this._extractAndSaveAuthData(res); + }) + .catch((error: Response) => { + return this._extractAuthError(error); + }); + } + + logout() { + localStorage.removeItem(AuthConstants.AUTH_TOKEN_KEY); + /** + * INFO: We don't know at this point what would be the login route + * of this app. Since we are guarding it by canActivate we can safely + * expect that navigating to the login route will the do the right thing + * and move the app to the login page. But we don't yet know that is the + * proper route. May be at some point we would want it to have a way + * to know which would be the proper login route for the app + */ + this.router.navigate(['/login']); + } + + private _extractAndSaveAuthData(res: Response) { + let data = res.json(); + if (!data) { + throw new Error('Invalid/blank auth data, Fatal Error'); + } + try { + let userData = this.jwtHelper.decodeToken(data.access_token); + data.userData = userData; + this.localStorage.setObject(AuthConstants.AUTH_TOKEN_KEY, data); + } catch (ex) { + throw new Error('Fatal error, failed to parse token'); + } + return true; + } + + private _extractAuthError(res: Response) { + let error = res.json(); + let errorMsg = error.error_description || 'Server error'; + this.loggerService.error(errorMsg); + return Observable.throw(errorMsg); + } +} diff --git a/src/app/auth/index.ts b/src/app/auth/index.ts new file mode 100644 index 0000000..2214ad1 --- /dev/null +++ b/src/app/auth/index.ts @@ -0,0 +1,4 @@ +export * from './auth.service'; +export {AuthConstants} from './auth.constants'; +export * from './auth.guard'; +export * from './auth.module'; diff --git a/src/app/bundle.ts b/src/app/bundle.ts new file mode 100644 index 0000000..9f8557c --- /dev/null +++ b/src/app/bundle.ts @@ -0,0 +1 @@ +// This file is for production only, please leave it blank diff --git a/src/app/dashboard/dashboard-event.service.ts b/src/app/dashboard/dashboard-event.service.ts new file mode 100644 index 0000000..b0187a2 --- /dev/null +++ b/src/app/dashboard/dashboard-event.service.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@angular/core'; +import { Subject } from 'rxjs/Subject'; + +export interface IDashboardComponetEvent { + Event: string; + Name: string; +} + +@Injectable() +export class DashboardEventService { + // TODO: Need to make sure the component updates are standardized + public componentUpdateSource = new Subject(); + + /** The stream to publish component update stream to other components */ + public componentUpdated$ = this.componentUpdateSource.asObservable(); + + public componentUpdated(value: IDashboardComponetEvent) { + this.componentUpdateSource.next(value); + } +} + +export const DASHBOARD_PROVIDERS: any[] = [ + { provide: DashboardEventService, useClass: DashboardEventService } +]; diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts new file mode 100644 index 0000000..f917789 --- /dev/null +++ b/src/app/dashboard/dashboard.component.ts @@ -0,0 +1,8 @@ +import { Component } from '@angular/core'; + +@Component({ + moduleId: module.id, + selector: 'as-dashboard', + templateUrl: 'dashboard.html' +}) +export class DashboardComponent {} diff --git a/src/app/dashboard/dashboard.html b/src/app/dashboard/dashboard.html new file mode 100644 index 0000000..859442a --- /dev/null +++ b/src/app/dashboard/dashboard.html @@ -0,0 +1,28 @@ +
+ + + + + + + +
+ + + + +
+ + + +
+ +
+
+ +
+ + + + +
\ No newline at end of file diff --git a/src/app/dashboard/dashboard.module.ts b/src/app/dashboard/dashboard.module.ts new file mode 100644 index 0000000..faf79af --- /dev/null +++ b/src/app/dashboard/dashboard.module.ts @@ -0,0 +1,46 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; +import { ChartsModule } from 'ng2-charts'; +import { HttpModule } from '@angular/http'; + +// Local Modules +import { NavbarModule } from '../navbar/index'; +import { LetterAvatarModule } from '../shared/letter-avatar/index'; +import { DataModule } from '../data/index'; + + +import { DASHBOARD_PROVIDERS } from './dashboard-event.service'; + +// Local Components +import { DashboardComponent } from './index'; +import { SidebarComponent } from '../sidebar/index'; +import { FooterComponent } from '../footer/index'; +import { DashviewHeaderComponent } from '../dashview-header/index'; + +import { GlimpseComponent } from '../glimpse/index'; + +@NgModule({ + declarations: [ + DashboardComponent, + SidebarComponent, + FooterComponent, + DashviewHeaderComponent, + GlimpseComponent + ], + exports: [ + DashboardComponent, + ], + imports: [ + RouterModule, + CommonModule, + NavbarModule, + LetterAvatarModule, + ChartsModule, + HttpModule, + DataModule + ], + providers: [...DASHBOARD_PROVIDERS] +}) +export class DashboardModule { +} diff --git a/src/app/dashboard/dashboard.routes.ts b/src/app/dashboard/dashboard.routes.ts new file mode 100644 index 0000000..6ef2d1f --- /dev/null +++ b/src/app/dashboard/dashboard.routes.ts @@ -0,0 +1,15 @@ +import { Routes } from '@angular/router'; +import { DashboardComponent } from './dashboard.component'; +import { GlimpseComponent } from '../glimpse/index'; + +export const DashboardRoutes: Routes = [ + { path: '', redirectTo: 'dashboard', pathMatch: 'full' }, + { + path: 'dashboard', + component: DashboardComponent, + children: [ + { path: '', redirectTo: 'glimpse', pathMatch: 'full' }, + { path: 'glimpse', component: GlimpseComponent } + ] + } +]; diff --git a/src/app/dashboard/index.ts b/src/app/dashboard/index.ts new file mode 100644 index 0000000..278df60 --- /dev/null +++ b/src/app/dashboard/index.ts @@ -0,0 +1,4 @@ +export * from './dashboard.component'; +export * from './dashboard-event.service'; +export * from './dashboard.routes'; +export * from './dashboard.module'; diff --git a/src/app/dashview-header/dashview-header.component.ts b/src/app/dashview-header/dashview-header.component.ts new file mode 100644 index 0000000..c44cf8a --- /dev/null +++ b/src/app/dashview-header/dashview-header.component.ts @@ -0,0 +1,26 @@ +import { Component } from '@angular/core'; +import { DashboardEventService } from '../dashboard/dashboard-event.service'; + +@Component({ + moduleId: module.id, + selector: 'as-dashview-header', + templateUrl: 'dashview-header.html' +}) +export class DashviewHeaderComponent { + public pageHeader: string = 'Loading'; + public optionalDescription: string = ''; + + /**INFO: Not sure how to play this out here. + * The first one has to be the dashboard logo + * and the last one has to have class=active on + * it so we know which one is active here + */ + public breadcrumbDef: string[]; + + constructor(private dashboardEventService: DashboardEventService) { + this.dashboardEventService.componentUpdated$.subscribe(event => { + this.pageHeader = event.Name; + this.breadcrumbDef = [event.Name]; + }); + } +} diff --git a/src/app/dashview-header/dashview-header.html b/src/app/dashview-header/dashview-header.html new file mode 100644 index 0000000..587ec86 --- /dev/null +++ b/src/app/dashview-header/dashview-header.html @@ -0,0 +1,11 @@ +
+

+ {{pageHeader}} + {{optionalDescription}} +

+ +
\ No newline at end of file diff --git a/src/app/dashview-header/index.ts b/src/app/dashview-header/index.ts new file mode 100644 index 0000000..740a735 --- /dev/null +++ b/src/app/dashview-header/index.ts @@ -0,0 +1 @@ +export * from './dashview-header.component'; diff --git a/src/app/data/data.module.ts b/src/app/data/data.module.ts new file mode 100644 index 0000000..392c18a --- /dev/null +++ b/src/app/data/data.module.ts @@ -0,0 +1,9 @@ +import { NgModule } from '@angular/core'; +import { DataService } from './index'; + +@NgModule({ + providers: [ + DataService + ] +}) +export class DataModule {} diff --git a/src/app/data/data.service.ts b/src/app/data/data.service.ts new file mode 100644 index 0000000..071895f --- /dev/null +++ b/src/app/data/data.service.ts @@ -0,0 +1,53 @@ +import { Injectable } from '@angular/core'; +import { Http, Headers, Response } from '@angular/http'; +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/throw'; +import 'rxjs/add/operator/map'; +import 'rxjs/add/operator/catch'; +import { CONSTANTS, LoggerService } from '../shared/index'; + +@Injectable() +export class DataService { + /** + * Generic service towards DataCat + */ + constructor( + private http: Http, + private loggerService: LoggerService) { } + + executeAggregation(collectionName: string, aggregateDocument: any) { + let aggUrl = CONSTANTS.ENV.API_BASE + collectionName + '/a'; + + let headers = new Headers(); + headers.append('Content-Type', 'application/json'); + + return this.http.post(aggUrl, aggregateDocument) + .map((res: Response) => { + if (res.status < 200 || res.status >= 300) { + throw new Error('Response status: ' + res.status); + } + return this._extractAndSaveData(res); + }) + .catch((error: Response) => { + return this._extractError(error); + }); + } + + private _extractAndSaveData(res: Response) { + let body = res.json(); + return body || {}; + } + + private _extractError(error: Response | any) { + let errMsg: string; + if (error instanceof Response) { + const body = error.json() || ''; + const err = body.error || JSON.stringify(body); + errMsg = `${error.status} - ${error.statusText || ''} ${err}`; + } else { + errMsg = error.message ? error.message : error.toString(); + } + this.loggerService.error(errMsg); + return Observable.throw(errMsg); + } +} diff --git a/src/app/data/index.ts b/src/app/data/index.ts new file mode 100644 index 0000000..6c721c8 --- /dev/null +++ b/src/app/data/index.ts @@ -0,0 +1,2 @@ +export * from './data.service'; +export * from './data.module'; diff --git a/src/app/footer/footer.component.ts b/src/app/footer/footer.component.ts new file mode 100644 index 0000000..dbb3bad --- /dev/null +++ b/src/app/footer/footer.component.ts @@ -0,0 +1,22 @@ +import { Component } from '@angular/core'; +import { CONSTANTS } from '../shared/index'; + +@Component({ + moduleId: module.id, + selector: 'as-footer', + templateUrl: 'footer.html' +}) +export class FooterComponent { + public companyInfo: { title: string, url: string; tagline: string; }; + + /** + * Footer constructor + */ + constructor() { + this.companyInfo = { + title: CONSTANTS.MAIN.COMPANY.TITLE, + url: CONSTANTS.MAIN.COMPANY.URL, + tagline: CONSTANTS.MAIN.COMPANY.TAGLINE + }; + } +} diff --git a/src/app/footer/footer.html b/src/app/footer/footer.html new file mode 100644 index 0000000..5183a94 --- /dev/null +++ b/src/app/footer/footer.html @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/src/app/footer/index.ts b/src/app/footer/index.ts new file mode 100644 index 0000000..a50d573 --- /dev/null +++ b/src/app/footer/index.ts @@ -0,0 +1 @@ +export * from './footer.component'; diff --git a/src/app/glimpse/glimpse.component.ts b/src/app/glimpse/glimpse.component.ts new file mode 100644 index 0000000..126d598 --- /dev/null +++ b/src/app/glimpse/glimpse.component.ts @@ -0,0 +1,142 @@ +import { Component, OnInit } from '@angular/core'; +import { DashboardEventService } from '../dashboard/dashboard-event.service'; +import { DataService } from '../data/index'; +import { LoggerService } from '../shared/index'; + +@Component({ + moduleId: module.id, + selector: 'as-glimpse', + templateUrl: 'glimpse.html' +}) +export class GlimpseComponent implements OnInit { + public barChartOptions: any = { + scaleShowVerticalLines: false, + responsive: true, + scales: { + yAxes: [{ + display: true, + ticks: { + suggestedMin: 0, // minimum will be 0, unless there is a lower value. + // OR // + beginAtZero: true, // minimum value will be 0. + suggestedMax: 100, + max: 150 + } + }] + } + }; + + public isDataAvailable: boolean = false; + public barChartLabels: string[] = []; + public barChartType: string = 'bar'; + public barChartLegend: boolean = true; + public barChartData: any[]; + + constructor( + private dataService: DataService, + private loggerService: LoggerService, + private dashboarEventService: DashboardEventService) { + dashboarEventService.componentUpdated({ Event: 'loaded', Name: 'Glimpse' }); + } + + ngOnInit() { + let document: any = { + 'aggregate': [ + { '$sort': { 'CreateTime': -1 } }, + { + '$project': { + '_id': 1, + 'HRID': 1, + 'CreateTime': 1, + 'Order.Type': 1, + 'Order.Variant': 1, + 'User.Type': 1, + 'User.UserName': 1, + 'h': { + '$hour': '$CreateTime' + }, + 'm': { + '$minute': '$CreateTime' + }, + 's': { + '$second': '$CreateTime' + }, + 'ml': { + '$millisecond': '$CreateTime' + } + } + }, + { + '$project': { + '_id': 1, + 'HRID': 1, + 'Order.Type': 1, + 'Order.Variant': 1, + 'User.Type': 1, + 'User.UserName': 1, + 'CreateTime': { + '$subtract': [ + '$CreateTime', + { + '$add': [ + '$ml', + { + '$multiply': [ + '$s', + 1000 + ] + }, + { + '$multiply': [ + '$m', + 60, + 1000 + ] + }, + { + '$multiply': [ + '$h', + 60, + 60, + 1000 + ] + } + ] + } + ] + } + } + }, + { + '$group': { + '_id': { + 'CreateDate': '$CreateTime' + }, + 'count': { + '$sum': 1 + }, + 'jobs': { + '$push': '$HRID' + } + } + } + ] + }; + + this.dataService.executeAggregation('Jobs', document) + .subscribe(result => { + let jobCountArray: any[] = []; + if (result) { + // Need to parse this crap here + let res: any[] = result; + for (let entry of res) { + this.barChartLabels.push(new Date(entry._id.CreateDate.$date).toDateString()); + jobCountArray.push(entry.count); + } + } + this.barChartData = [{data: jobCountArray, label: 'Orders'}]; + this.isDataAvailable = true; + }, + error => { this.loggerService.error(error); }); + } +} diff --git a/src/app/glimpse/glimpse.html b/src/app/glimpse/glimpse.html new file mode 100644 index 0000000..9e6ef77 --- /dev/null +++ b/src/app/glimpse/glimpse.html @@ -0,0 +1,10 @@ +
+ +
\ No newline at end of file diff --git a/src/app/glimpse/index.ts b/src/app/glimpse/index.ts new file mode 100644 index 0000000..a82aa5d --- /dev/null +++ b/src/app/glimpse/index.ts @@ -0,0 +1 @@ +export * from './glimpse.component'; diff --git a/src/app/login/index.ts b/src/app/login/index.ts new file mode 100644 index 0000000..63ea091 --- /dev/null +++ b/src/app/login/index.ts @@ -0,0 +1,3 @@ +export * from './login.component'; +export * from './login.routes'; +export * from './login.module'; diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts new file mode 100644 index 0000000..12db106 --- /dev/null +++ b/src/app/login/login.component.ts @@ -0,0 +1,44 @@ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; + +import { AuthService } from '../auth/index'; +import { CONSTANTS, LoggerService } from '../shared/index'; + +@Component({ + moduleId: module.id, + selector: 'as-login', + templateUrl: 'login.html' +}) +export class LoginComponent implements OnInit { + model: any = {}; + loading = false; + error = ''; + appTitle = CONSTANTS.MAIN.APP.BRAND; + + /** + * Login component for TaskCat.Enterprise Dashboard + */ + constructor( + private router: Router, + private authService: AuthService, + private loggerService: LoggerService) {} + + ngOnInit() { + this.authService.logout(); + } + + login() { + this.loading = true; + this.authService.login(this.model.username, this.model.password) + .subscribe(result => { + if (result === true) { + this.router.navigate(['/']); + } + this.loading = false; + }, error => { + this.loggerService.error(error); + this.error = error; + this.loading = false; + }); + } +} diff --git a/src/app/login/login.html b/src/app/login/login.html new file mode 100644 index 0000000..03c312a --- /dev/null +++ b/src/app/login/login.html @@ -0,0 +1,54 @@ + + \ No newline at end of file diff --git a/src/app/login/login.module.ts b/src/app/login/login.module.ts new file mode 100644 index 0000000..9bdeb4e --- /dev/null +++ b/src/app/login/login.module.ts @@ -0,0 +1,26 @@ +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { LoginComponent, LoginRoute } from './index'; +import { AuthModule, AuthGuard } from '../auth/index'; + +@NgModule({ + declarations: [ + LoginComponent + ], + exports: [ + LoginComponent, + AuthModule + ], + imports: [ + AuthModule, + FormsModule + ] +}) +export class LoginModule { + /** + * TaskCat Enterprise dashboard login module + */ + constructor(private authGuard: AuthGuard) { + authGuard.loginRoute = '/' + LoginRoute.path; + } +} diff --git a/src/app/login/login.routes.ts b/src/app/login/login.routes.ts new file mode 100644 index 0000000..860964c --- /dev/null +++ b/src/app/login/login.routes.ts @@ -0,0 +1,3 @@ +import { LoginComponent } from './login.component'; + +export const LoginRoute = { path: 'login', component: LoginComponent }; diff --git a/src/app/main.ts b/src/app/main.ts new file mode 100644 index 0000000..a5b32f4 --- /dev/null +++ b/src/app/main.ts @@ -0,0 +1,12 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app.module'; + +declare var ENV: string; + +if (ENV === 'production') { + enableProdMode(); +} + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/src/app/navbar/index.ts b/src/app/navbar/index.ts new file mode 100644 index 0000000..5d50fad --- /dev/null +++ b/src/app/navbar/index.ts @@ -0,0 +1,2 @@ +export * from './navbar.component'; +export * from './navbar.module'; diff --git a/src/app/navbar/navbar.component.ts b/src/app/navbar/navbar.component.ts new file mode 100644 index 0000000..5181c86 --- /dev/null +++ b/src/app/navbar/navbar.component.ts @@ -0,0 +1,46 @@ +import { Component } from '@angular/core'; +import { LocalStorage } from '../shared/index'; +import { AuthConstants } from '../auth/index'; +import { CONSTANTS } from '../shared/index'; +import { AuthService } from '../auth/auth.service'; + +@Component({ + moduleId: module.id, + selector: 'as-navbar', + templateUrl: 'navbar.html' +}) +export class NavbarComponent { + /** + * TODO: This is definitely replicated code from DashboardComponent. + * We need to put this avatar configuration somewhere in a settings file + * if possible. + */ + + public avatarData: any = { + size: 40, + background: '#008d4c', // by default it will produce dynamic colors + fontColor: '#FFFFFF', + isSquare: false, + fixedColor: true + }; + + public userInfo: any = {}; + public productInfo: { platform_title: string; product_title: string }; + + // Navbar constructor + constructor(private localStorage: LocalStorage, private authService: AuthService) { + let userToken = localStorage.getObject(AuthConstants.AUTH_TOKEN_KEY); + this.avatarData.text = userToken.userData.sub; + this.userInfo.Name = userToken.userData.sub; + this.userInfo.Email = userToken.email; + + this.productInfo = { + platform_title: CONSTANTS.MAIN.APP.PLATFORM_TITLE, + product_title: CONSTANTS.MAIN.APP.PRODUCT_TITLE + }; + } + + public signout() { + this.authService.logout(); + } +} diff --git a/src/app/navbar/navbar.html b/src/app/navbar/navbar.html new file mode 100644 index 0000000..345e65d --- /dev/null +++ b/src/app/navbar/navbar.html @@ -0,0 +1,62 @@ +
+ + + + +
\ No newline at end of file diff --git a/src/app/navbar/navbar.module.ts b/src/app/navbar/navbar.module.ts new file mode 100644 index 0000000..47a58dd --- /dev/null +++ b/src/app/navbar/navbar.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { NavbarComponent } from './index'; +import { CommonModule } from '@angular/common'; +import { LetterAvatarModule } from '../shared/letter-avatar/index'; + +@NgModule({ + declarations: [ + NavbarComponent + ], + exports: [ + NavbarComponent + ], + imports: [ + CommonModule, + LetterAvatarModule + ] +}) +export class NavbarModule { } diff --git a/src/app/shared/constant/.gitignore b/src/app/shared/constant/.gitignore new file mode 100644 index 0000000..47a1b89 --- /dev/null +++ b/src/app/shared/constant/.gitignore @@ -0,0 +1 @@ +env.ts \ No newline at end of file diff --git a/src/app/shared/constant/env.model.ts b/src/app/shared/constant/env.model.ts new file mode 100644 index 0000000..7047150 --- /dev/null +++ b/src/app/shared/constant/env.model.ts @@ -0,0 +1,13 @@ +/** + * Only valid JSON data types can be used for types + * + * Make sure the keys in `env.model.ts` exist in `env.json` + * otherwise it'll throw message like this + * Property '' is missing in type '{}' + * + */ + +export interface AppEnv { + API_BASE?: string; + AUTH_BASE?: string; +} diff --git a/src/app/shared/constant/index.ts b/src/app/shared/constant/index.ts new file mode 100644 index 0000000..136f98b --- /dev/null +++ b/src/app/shared/constant/index.ts @@ -0,0 +1,7 @@ +import { MAIN } from './main'; +import { ENV } from './env'; + +export const CONSTANTS = { + MAIN, + ENV +}; diff --git a/src/app/shared/constant/main.ts b/src/app/shared/constant/main.ts new file mode 100644 index 0000000..cbae362 --- /dev/null +++ b/src/app/shared/constant/main.ts @@ -0,0 +1,12 @@ +export const MAIN = { + APP: { + BRAND: 'DataCat', + PLATFORM_TITLE: 'Data', + PRODUCT_TITLE: 'Cat' + }, + COMPANY: { + TITLE: 'NerdCats', + URL: 'http://facebook.com/nerdcats', + TAGLINE: 'Made with love by NerdCats' + } +}; diff --git a/src/app/shared/index.ts b/src/app/shared/index.ts new file mode 100644 index 0000000..f2f665c --- /dev/null +++ b/src/app/shared/index.ts @@ -0,0 +1,3 @@ +export * from './constant/index'; +export * from './local-storage.provider'; +export * from './logger/index'; diff --git a/src/app/shared/letter-avatar/index.ts b/src/app/shared/letter-avatar/index.ts new file mode 100644 index 0000000..214118c --- /dev/null +++ b/src/app/shared/letter-avatar/index.ts @@ -0,0 +1,2 @@ +export * from './letter-avatar.component'; +export * from './letter-avatar.module'; diff --git a/src/app/shared/letter-avatar/letter-avatar.component.ts b/src/app/shared/letter-avatar/letter-avatar.component.ts new file mode 100644 index 0000000..e81ee50 --- /dev/null +++ b/src/app/shared/letter-avatar/letter-avatar.component.ts @@ -0,0 +1,96 @@ +// taken from https://github.com/rajan-g/angular2-letter-avatar/blob/master/directives/letter-avatar.directive.ts +import { Component, ElementRef, Input, OnInit, ChangeDetectionStrategy, OnChanges } from '@angular/core'; + +@Component({ + moduleId: module.id, + selector: 'avatar', + templateUrl: 'letter-avatar.html', + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class LetterAvatarComponent implements OnInit, OnChanges { + @Input('avatardata') avatarData: any; + letterSrc: string; + background: string = 'red'; + fontSize: number = 49; + padding: number = 28; + letter: string = '?'; + size: number = 100; + fontColor: string = '#FFFFFF'; + border: string; + props: any = null; + private _el: HTMLElement; + + constructor(el: ElementRef) { + this._el = el.nativeElement; + } + test() { + this.generateLetter(); + } + + generateLetter() { + if (!this.avatarData) { + throw Error('LetterAvatarComponent config not provided'); + } + if (!this.avatarData.text) { + this.avatarData.text = '?'; + } + let size = this.avatarData && this.avatarData.size ? this.avatarData.size : 100; + this.fontColor = this.avatarData.fontColor ? this.avatarData.fontColor : '#FFFFFF'; + let isSquare = this.avatarData && this.avatarData.isSquare ? true : false; + let border = this.avatarData && this.avatarData.border ? this.avatarData.border : '1px solid #d3d3d3'; + let background = this.avatarData && this.avatarData.background ? this.avatarData.background : null; + let text = this.avatarData && this.avatarData.text ? this.avatarData.text : null; + this.background = background; + let textArray = text.split(' '); + let letter = textArray[0].substr(0, 1) + '' + (textArray.length > 1 ? textArray[1].substr(0, 1) : ''); + letter = letter.toUpperCase(); + this.fontSize = (39 * size) / 100; + this.padding = (28 * size) / 100; + this.letter = letter; + this.size = size; + this.props = {}; + this.props.size = size + 'px'; + this.props.lineheight = this.size + 'px'; + this.props.letter = letter; + this.props.fontSize = this.fontSize + 'px'; + if (isSquare) { + this.props.borderradius = '0%'; + } else { + this.props.borderradius = '50%'; + } + this.props.textalign = 'center'; + this.props.border = border; + this.props.background = background; + if (this.avatarData.fixedColor && !background) { + this.props.background = background || this.colorize(letter); + } else { + this.props.background = background || this.getRandomColor(); + } + return true; + }; + + getRandomColor() { + let letters = '0123456789ABCDEF'.split(''); + let color = '#'; + for (let i = 0; i < 6; i++) { + color += letters[Math.floor(Math.random() * 16)]; + } + return color; + } + colorize(str) { + let hash = 0; + for (let i = 0; i < str.length; i++) { + // tslint:disable-next-line:no-bitwise + hash = str.charCodeAt(i++) + ((hash << 5) - hash); + }; + let color = Math.floor(Math.abs((Math.sin(hash) * 10000) % 1 * 16777216)).toString(16); + return '#' + Array(6 - color.length + 1).join('0') + color; + } + + ngOnInit() { + this.generateLetter(); + } + ngOnChanges(...args: any[]) { + this.generateLetter(); + } +} diff --git a/src/app/shared/letter-avatar/letter-avatar.html b/src/app/shared/letter-avatar/letter-avatar.html new file mode 100644 index 0000000..740c9f9 --- /dev/null +++ b/src/app/shared/letter-avatar/letter-avatar.html @@ -0,0 +1,5 @@ +
+
{{props.letter}}
+
\ No newline at end of file diff --git a/src/app/shared/letter-avatar/letter-avatar.module.ts b/src/app/shared/letter-avatar/letter-avatar.module.ts new file mode 100644 index 0000000..72991ef --- /dev/null +++ b/src/app/shared/letter-avatar/letter-avatar.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { LetterAvatarComponent } from './index'; + +@NgModule({ + declarations: [ + LetterAvatarComponent + ], + exports: [ + LetterAvatarComponent + ], + imports: [ + CommonModule + ] +}) +export class LetterAvatarModule { } diff --git a/src/app/shared/local-storage.provider.ts b/src/app/shared/local-storage.provider.ts new file mode 100644 index 0000000..9a3e259 --- /dev/null +++ b/src/app/shared/local-storage.provider.ts @@ -0,0 +1,40 @@ +import {Injectable} from '@angular/core'; + +@Injectable() +export class LocalStorage { + public localStorage: any; + + constructor() { + if (!localStorage) { + throw new Error('Current browser does not support Local Storage'); + } + this.localStorage = localStorage; + } + + public set(key: string, value: string): void { + this.localStorage[key] = value; + } + + public get(key: string): string { + return this.localStorage[key] || false; + } + + public setObject(key: string, value: any): void { + this.localStorage[key] = JSON.stringify(value); + } + + public getObject(key: string): any { + if (this.localStorage[key]) { + return JSON.parse(this.localStorage[key]); + } + return null; + } + + public remove(key: string): any { + this.localStorage.removeItem(key); + } +} + +export const LOCAL_STORAGE_PROVIDERS: any[] = [ + { provide: LocalStorage, useClass: LocalStorage } +]; diff --git a/src/app/shared/logger/index.ts b/src/app/shared/logger/index.ts new file mode 100644 index 0000000..6820e22 --- /dev/null +++ b/src/app/shared/logger/index.ts @@ -0,0 +1 @@ +export * from './logger.service'; diff --git a/src/app/shared/logger/logger.service.ts b/src/app/shared/logger/logger.service.ts new file mode 100644 index 0000000..8586c2c --- /dev/null +++ b/src/app/shared/logger/logger.service.ts @@ -0,0 +1,63 @@ +import { Injectable } from '@angular/core'; + +export interface ILogger { + assert(...args: any[]): void; + error(...args: any[]): void; + group(...args: any[]): void; + groupEnd(...args: any[]): void; + info(...args: any[]): void; + log(...args: any[]): void; + warn(...args: any[]): void; +} + +declare var console: any; + +@Injectable() +export class LoggerService implements ILogger { + public assert(...args: any[]): void { + if (console && console.assert) { console.assert(...args); } + } + public error(...args: any[]): void { + if (console && console.error) { console.error(...args); } + } + public group(...args: any[]): void { + if (console && console.group) { console.group(...args); } + } + public groupEnd(...args: any[]): void { + if (console && console.groupEnd) { console.groupEnd(...args); } + } + public info(...args: any[]): void { + /* INFO: I know this is definitely going against our tslint rules. + * Since that essentially says that we shouldn't use console writing + * methods in production code of course. We have to find a way so we + * can turn proper logging level on and off in development and production + * mode so It's easier to debug when we want to and log in both modes. + */ + // tslint:disable-next-line:no-console + if (console && console.info) { console.info(...args); } + } + public log(...args: any[]): void { + if (console && console.log) { console.log(...args); } + } + public warn(...args: any[]): void { + if (console && console.warn) { console.warn(...args); } + } + + /** + * Generic logger service for console + */ + constructor() { + this.log('Logger Initialized'); + } +} + + +/* INFO: + * We will definitely need a default implementation of the ILogger if we + * ever decide we will go for a platform specific logger implementation. + * + * But as per YAGNI, this will do now. + */ +export const LOGGER_PROVIDERS: any[] = [ + { provide: LoggerService, useClass: LoggerService } +]; diff --git a/src/app/sidebar/index.ts b/src/app/sidebar/index.ts new file mode 100644 index 0000000..075e623 --- /dev/null +++ b/src/app/sidebar/index.ts @@ -0,0 +1 @@ +export * from './sidebar.component'; diff --git a/src/app/sidebar/sidebar.component.ts b/src/app/sidebar/sidebar.component.ts new file mode 100644 index 0000000..855a1a5 --- /dev/null +++ b/src/app/sidebar/sidebar.component.ts @@ -0,0 +1,31 @@ +import { Component } from '@angular/core'; +import { LocalStorage } from '../shared/index'; +import { AuthConstants } from '../auth/index'; + +@Component({ + moduleId: module.id, + selector: 'as-sidebar', + templateUrl: 'sidebar.html' +}) +export class SidebarComponent { + // TODO: Replication here again, need to put this somewhere in a settings. + public avatarData: any = { + size: 40, + background: '#008d4c', // by default it will produce dynamic colors + fontColor: '#FFFFFF', + isSquare: false, + fixedColor: true + }; + + public userInfo: any = {}; + + /** + * Sidebar constructor + */ + constructor(private localStorage: LocalStorage) { + let userToken = localStorage.getObject(AuthConstants.AUTH_TOKEN_KEY); + this.avatarData.text = userToken.userData.sub; + this.userInfo.Name = userToken.userData.sub; + this.userInfo.Email = userToken.email; + } +} diff --git a/src/app/sidebar/sidebar.html b/src/app/sidebar/sidebar.html new file mode 100644 index 0000000..a8abeca --- /dev/null +++ b/src/app/sidebar/sidebar.html @@ -0,0 +1,51 @@ + \ No newline at end of file diff --git a/src/assets/images/ng2.jpg b/src/assets/images/ng2.jpg new file mode 100644 index 0000000..748742f Binary files /dev/null and b/src/assets/images/ng2.jpg differ diff --git a/src/assets/js/app.min.js b/src/assets/js/app.min.js new file mode 100644 index 0000000..8ec5fe1 --- /dev/null +++ b/src/assets/js/app.min.js @@ -0,0 +1,13 @@ +/*! AdminLTE app.js + * ================ + * Main JS application file for AdminLTE v2. This file + * should be included in all pages. It controls some layout + * options and implements exclusive AdminLTE plugins. + * + * @Author Almsaeed Studio + * @Support + * @Email + * @version 2.3.2 + * @license MIT + */ +function _init(){"use strict";$.AdminLTE.layout={activate:function(){var a=this;a.fix(),a.fixSidebar(),$(window,".wrapper").resize(function(){a.fix(),a.fixSidebar()})},fix:function(){var a=$(".main-header").outerHeight()+$(".main-footer").outerHeight(),b=$(window).height(),c=$(".sidebar").height();if($("body").hasClass("fixed"))$(".content-wrapper, .right-side").css("min-height",b-$(".main-footer").outerHeight());else{var d;b>=c?($(".content-wrapper, .right-side").css("min-height",b-a),d=b-a):($(".content-wrapper, .right-side").css("min-height",c),d=c);var e=$($.AdminLTE.options.controlSidebarOptions.selector);"undefined"!=typeof e&&e.height()>d&&$(".content-wrapper, .right-side").css("min-height",e.height())}},fixSidebar:function(){return $("body").hasClass("fixed")?("undefined"==typeof $.fn.slimScroll&&window.console&&window.console.error("Error: the fixed layout requires the slimscroll plugin!"),void($.AdminLTE.options.sidebarSlimScroll&&"undefined"!=typeof $.fn.slimScroll&&($(".sidebar").slimScroll({destroy:!0}).height("auto"),$(".sidebar").slimscroll({height:$(window).height()-$(".main-header").height()+"px",color:"rgba(0,0,0,0.2)",size:"3px"})))):void("undefined"!=typeof $.fn.slimScroll&&$(".sidebar").slimScroll({destroy:!0}).height("auto"))}},$.AdminLTE.pushMenu={activate:function(a){var b=$.AdminLTE.options.screenSizes;$(document).on("click",a,function(a){a.preventDefault(),$(window).width()>b.sm-1?$("body").hasClass("sidebar-collapse")?$("body").removeClass("sidebar-collapse").trigger("expanded.pushMenu"):$("body").addClass("sidebar-collapse").trigger("collapsed.pushMenu"):$("body").hasClass("sidebar-open")?$("body").removeClass("sidebar-open").removeClass("sidebar-collapse").trigger("collapsed.pushMenu"):$("body").addClass("sidebar-open").trigger("expanded.pushMenu")}),$(".content-wrapper").click(function(){$(window).width()<=b.sm-1&&$("body").hasClass("sidebar-open")&&$("body").removeClass("sidebar-open")}),($.AdminLTE.options.sidebarExpandOnHover||$("body").hasClass("fixed")&&$("body").hasClass("sidebar-mini"))&&this.expandOnHover()},expandOnHover:function(){var a=this,b=$.AdminLTE.options.screenSizes.sm-1;$(".main-sidebar").hover(function(){$("body").hasClass("sidebar-mini")&&$("body").hasClass("sidebar-collapse")&&$(window).width()>b&&a.expand()},function(){$("body").hasClass("sidebar-mini")&&$("body").hasClass("sidebar-expanded-on-hover")&&$(window).width()>b&&a.collapse()})},expand:function(){$("body").removeClass("sidebar-collapse").addClass("sidebar-expanded-on-hover")},collapse:function(){$("body").hasClass("sidebar-expanded-on-hover")&&$("body").removeClass("sidebar-expanded-on-hover").addClass("sidebar-collapse")}},$.AdminLTE.tree=function(a){var b=this,c=$.AdminLTE.options.animationSpeed;$(a).on("click","li a",function(a){var d=$(this),e=d.next();if(e.is(".treeview-menu")&&e.is(":visible")&&!$("body").hasClass("sidebar-collapse"))e.slideUp(c,function(){e.removeClass("menu-open")}),e.parent("li").removeClass("active");else if(e.is(".treeview-menu")&&!e.is(":visible")){var f=d.parents("ul").first(),g=f.find("ul:visible").slideUp(c);g.removeClass("menu-open");var h=d.parent("li");e.slideDown(c,function(){e.addClass("menu-open"),f.find("li.active").removeClass("active"),h.addClass("active"),b.layout.fix()})}e.is(".treeview-menu")&&a.preventDefault()})},$.AdminLTE.controlSidebar={activate:function(){var a=this,b=$.AdminLTE.options.controlSidebarOptions,c=$(b.selector),d=$(b.toggleBtnSelector);d.on("click",function(d){d.preventDefault(),c.hasClass("control-sidebar-open")||$("body").hasClass("control-sidebar-open")?a.close(c,b.slide):a.open(c,b.slide)});var e=$(".control-sidebar-bg");a._fix(e),$("body").hasClass("fixed")?a._fixForFixed(c):$(".content-wrapper, .right-side").height() .box-body, > .box-footer, > form >.box-body, > form > .box-footer");c.hasClass("collapsed-box")?(a.children(":first").removeClass(b.icons.open).addClass(b.icons.collapse),d.slideDown(b.animationSpeed,function(){c.removeClass("collapsed-box")})):(a.children(":first").removeClass(b.icons.collapse).addClass(b.icons.open),d.slideUp(b.animationSpeed,function(){c.addClass("collapsed-box")}))},remove:function(a){var b=a.parents(".box").first();b.slideUp(this.animationSpeed)}}}if("undefined"==typeof jQuery)throw new Error("AdminLTE requires jQuery");$.AdminLTE={},$.AdminLTE.options={navbarMenuSlimscroll:!0,navbarMenuSlimscrollWidth:"3px",navbarMenuHeight:"200px",animationSpeed:500,sidebarToggleSelector:"[data-toggle='offcanvas']",sidebarPushMenu:!0,sidebarSlimScroll:!0,sidebarExpandOnHover:!1,enableBoxRefresh:!0,enableBSToppltip:!0,BSTooltipSelector:"[data-toggle='tooltip']",enableFastclick:!0,enableControlSidebar:!0,controlSidebarOptions:{toggleBtnSelector:"[data-toggle='control-sidebar']",selector:".control-sidebar",slide:!0},enableBoxWidget:!0,boxWidgetOptions:{boxWidgetIcons:{collapse:"fa-minus",open:"fa-plus",remove:"fa-times"},boxWidgetSelectors:{remove:'[data-widget="remove"]',collapse:'[data-widget="collapse"]'}},directChat:{enable:!0,contactToggleSelector:'[data-widget="chat-pane-toggle"]'},colors:{lightBlue:"#3c8dbc",red:"#f56954",green:"#00a65a",aqua:"#00c0ef",yellow:"#f39c12",blue:"#0073b7",navy:"#001F3F",teal:"#39CCCC",olive:"#3D9970",lime:"#01FF70",orange:"#FF851B",fuchsia:"#F012BE",purple:"#8E24AA",maroon:"#D81B60",black:"#222222",gray:"#d2d6de"},screenSizes:{xs:480,sm:768,md:992,lg:1200}},$(function(){"use strict";$("body").removeClass("hold-transition"),"undefined"!=typeof AdminLTEOptions&&$.extend(!0,$.AdminLTE.options,AdminLTEOptions);var a=$.AdminLTE.options;_init(),$.AdminLTE.layout.activate(),$.AdminLTE.tree(".sidebar"),a.enableControlSidebar&&$.AdminLTE.controlSidebar.activate(),a.navbarMenuSlimscroll&&"undefined"!=typeof $.fn.slimscroll&&$(".navbar .menu").slimscroll({height:a.navbarMenuHeight,alwaysVisible:!1,size:a.navbarMenuSlimscrollWidth}).css("width","100%"),a.sidebarPushMenu&&$.AdminLTE.pushMenu.activate(a.sidebarToggleSelector),a.enableBSToppltip&&$("body").tooltip({selector:a.BSTooltipSelector}),a.enableBoxWidget&&$.AdminLTE.boxWidget.activate(),a.enableFastclick&&"undefined"!=typeof FastClick&&FastClick.attach(document.body),a.directChat.enable&&$(document).on("click",a.directChat.contactToggleSelector,function(){var a=$(this).parents(".direct-chat").first();a.toggleClass("direct-chat-contacts-open")}),$('.btn-group[data-toggle="btn-toggle"]').each(function(){var a=$(this);$(this).find(".btn").on("click",function(b){a.find(".btn.active").removeClass("active"),$(this).addClass("active"),b.preventDefault()})})}),function(a){"use strict";a.fn.boxRefresh=function(b){function c(a){a.append(f),e.onLoadStart.call(a)}function d(a){a.find(f).remove(),e.onLoadDone.call(a)}var e=a.extend({trigger:".refresh-btn",source:"",onLoadStart:function(a){return a},onLoadDone:function(a){return a}},b),f=a('
');return this.each(function(){if(""===e.source)return void(window.console&&window.console.log("Please specify a source first - boxRefresh()"));var b=a(this),f=b.find(e.trigger).first();f.on("click",function(a){a.preventDefault(),c(b),b.find(".box-body").load(e.source,function(){d(b)})})})}}(jQuery),function(a){"use strict";a.fn.activateBox=function(){a.AdminLTE.boxWidget.activate(this)},a.fn.toggleBox=function(){var b=a(a.AdminLTE.boxWidget.selectors.collapse,this);a.AdminLTE.boxWidget.collapse(b)},a.fn.removeBox=function(){var b=a(a.AdminLTE.boxWidget.selectors.remove,this);a.AdminLTE.boxWidget.remove(b)}}(jQuery),function(a){"use strict";a.fn.todolist=function(b){var c=a.extend({onCheck:function(a){return a},onUncheck:function(a){return a}},b);return this.each(function(){"undefined"!=typeof a.fn.iCheck?(a("input",this).on("ifChecked",function(){var b=a(this).parents("li").first();b.toggleClass("done"),c.onCheck.call(b)}),a("input",this).on("ifUnchecked",function(){var b=a(this).parents("li").first();b.toggleClass("done"),c.onUncheck.call(b)})):a("input",this).on("change",function(){var b=a(this).parents("li").first();b.toggleClass("done"),a("input",b).is(":checked")?c.onCheck.call(b):c.onUncheck.call(b)})})}}(jQuery); \ No newline at end of file diff --git a/src/assets/styles/AdminLTE.min.css b/src/assets/styles/AdminLTE.min.css new file mode 100644 index 0000000..28c8b06 --- /dev/null +++ b/src/assets/styles/AdminLTE.min.css @@ -0,0 +1,7 @@ +@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic);/*! + * AdminLTE v2.3.2 + * Author: Almsaeed Studio + * Website: Almsaeed Studio + * License: Open source - MIT + * Please visit http://opensource.org/licenses/MIT for more information +!*/html,body{min-height:100%}.layout-boxed html,.layout-boxed body{height:100%}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:'Source Sans Pro','Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:400;overflow-x:hidden;overflow-y:auto}.wrapper{min-height:100%;position:relative;overflow:hidden}.wrapper:before,.wrapper:after{content:" ";display:table}.wrapper:after{clear:both}.layout-boxed .wrapper{max-width:1250px;margin:0 auto;min-height:100%;box-shadow:0 0 8px rgba(0,0,0,0.5);position:relative}.layout-boxed{background:url('../img/boxed-bg.jpg') repeat fixed}.content-wrapper,.right-side,.main-footer{-webkit-transition:-webkit-transform .3s ease-in-out,margin .3s ease-in-out;-moz-transition:-moz-transform .3s ease-in-out,margin .3s ease-in-out;-o-transition:-o-transform .3s ease-in-out,margin .3s ease-in-out;transition:transform .3s ease-in-out,margin .3s ease-in-out;margin-left:230px;z-index:820}.layout-top-nav .content-wrapper,.layout-top-nav .right-side,.layout-top-nav .main-footer{margin-left:0}@media (max-width:767px){.content-wrapper,.right-side,.main-footer{margin-left:0}}@media (min-width:768px){.sidebar-collapse .content-wrapper,.sidebar-collapse .right-side,.sidebar-collapse .main-footer{margin-left:0}}@media (max-width:767px){.sidebar-open .content-wrapper,.sidebar-open .right-side,.sidebar-open .main-footer{-webkit-transform:translate(230px, 0);-ms-transform:translate(230px, 0);-o-transform:translate(230px, 0);transform:translate(230px, 0)}}.content-wrapper,.right-side{min-height:100%;background-color:#ecf0f5;z-index:800}.main-footer{background:#fff;padding:15px;color:#444;border-top:1px solid #d2d6de}.fixed .main-header,.fixed .main-sidebar,.fixed .left-side{position:fixed}.fixed .main-header{top:0;right:0;left:0}.fixed .content-wrapper,.fixed .right-side{padding-top:50px}@media (max-width:767px){.fixed .content-wrapper,.fixed .right-side{padding-top:100px}}.fixed.layout-boxed .wrapper{max-width:100%}body.hold-transition .content-wrapper,body.hold-transition .right-side,body.hold-transition .main-footer,body.hold-transition .main-sidebar,body.hold-transition .left-side,body.hold-transition .main-header>.navbar,body.hold-transition .main-header .logo{-webkit-transition:none;-o-transition:none;transition:none}.content{min-height:250px;padding:15px;margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:'Source Sans Pro',sans-serif}a{color:#3c8dbc}a:hover,a:active,a:focus{outline:none;text-decoration:none;color:#72afd2}.page-header{margin:10px 0 20px 0;font-size:22px}.page-header>small{color:#666;display:block;margin-top:5px}.main-header{position:relative;max-height:100px;z-index:1030}.main-header>.navbar{-webkit-transition:margin-left .3s ease-in-out;-o-transition:margin-left .3s ease-in-out;transition:margin-left .3s ease-in-out;margin-bottom:0;margin-left:230px;border:none;min-height:50px;border-radius:0}.layout-top-nav .main-header>.navbar{margin-left:0}.main-header #navbar-search-input.form-control{background:rgba(255,255,255,0.2);border-color:transparent}.main-header #navbar-search-input.form-control:focus,.main-header #navbar-search-input.form-control:active{border-color:rgba(0,0,0,0.1);background:rgba(255,255,255,0.9)}.main-header #navbar-search-input.form-control::-moz-placeholder{color:#ccc;opacity:1}.main-header #navbar-search-input.form-control:-ms-input-placeholder{color:#ccc}.main-header #navbar-search-input.form-control::-webkit-input-placeholder{color:#ccc}.main-header .navbar-custom-menu,.main-header .navbar-right{float:right}@media (max-width:991px){.main-header .navbar-custom-menu a,.main-header .navbar-right a{color:inherit;background:transparent}}@media (max-width:767px){.main-header .navbar-right{float:none}.navbar-collapse .main-header .navbar-right{margin:7.5px -15px}.main-header .navbar-right>li{color:inherit;border:0}}.main-header .sidebar-toggle{float:left;background-color:transparent;background-image:none;padding:15px 15px;font-family:fontAwesome}.main-header .sidebar-toggle:before{content:"\f0c9"}.main-header .sidebar-toggle:hover{color:#fff}.main-header .sidebar-toggle:focus,.main-header .sidebar-toggle:active{background:transparent}.main-header .sidebar-toggle .icon-bar{display:none}.main-header .navbar .nav>li.user>a>.fa,.main-header .navbar .nav>li.user>a>.glyphicon,.main-header .navbar .nav>li.user>a>.ion{margin-right:5px}.main-header .navbar .nav>li>a>.label{position:absolute;top:9px;right:7px;text-align:center;font-size:9px;padding:2px 3px;line-height:.9}.main-header .logo{-webkit-transition:width .3s ease-in-out;-o-transition:width .3s ease-in-out;transition:width .3s ease-in-out;display:block;float:left;height:50px;font-size:20px;line-height:50px;text-align:center;width:230px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;padding:0 15px;font-weight:300;overflow:hidden}.main-header .logo .logo-lg{display:block}.main-header .logo .logo-mini{display:none}.main-header .navbar-brand{color:#fff}.content-header{position:relative;padding:15px 15px 0 15px}.content-header>h1{margin:0;font-size:24px}.content-header>h1>small{font-size:15px;display:inline-block;padding-left:4px;font-weight:300}.content-header>.breadcrumb{float:right;background:transparent;margin-top:0;margin-bottom:0;font-size:12px;padding:7px 5px;position:absolute;top:15px;right:10px;border-radius:2px}.content-header>.breadcrumb>li>a{color:#444;text-decoration:none;display:inline-block}.content-header>.breadcrumb>li>a>.fa,.content-header>.breadcrumb>li>a>.glyphicon,.content-header>.breadcrumb>li>a>.ion{margin-right:5px}.content-header>.breadcrumb>li+li:before{content:'>\00a0'}@media (max-width:991px){.content-header>.breadcrumb{position:relative;margin-top:5px;top:0;right:0;float:none;background:#d2d6de;padding-left:10px}.content-header>.breadcrumb li:before{color:#97a0b3}}.navbar-toggle{color:#fff;border:0;margin:0;padding:15px 15px}@media (max-width:991px){.navbar-custom-menu .navbar-nav>li{float:left}.navbar-custom-menu .navbar-nav{margin:0;float:left}.navbar-custom-menu .navbar-nav>li>a{padding-top:15px;padding-bottom:15px;line-height:20px}}@media (max-width:767px){.main-header{position:relative}.main-header .logo,.main-header .navbar{width:100%;float:none}.main-header .navbar{margin:0}.main-header .navbar-custom-menu{float:right}}@media (max-width:991px){.navbar-collapse.pull-left{float:none !important}.navbar-collapse.pull-left+.navbar-custom-menu{display:block;position:absolute;top:0;right:40px}}.main-sidebar,.left-side{position:absolute;top:0;left:0;padding-top:50px;min-height:100%;width:230px;z-index:810;-webkit-transition:-webkit-transform .3s ease-in-out,width .3s ease-in-out;-moz-transition:-moz-transform .3s ease-in-out,width .3s ease-in-out;-o-transition:-o-transform .3s ease-in-out,width .3s ease-in-out;transition:transform .3s ease-in-out,width .3s ease-in-out}@media (max-width:767px){.main-sidebar,.left-side{padding-top:100px}}@media (max-width:767px){.main-sidebar,.left-side{-webkit-transform:translate(-230px, 0);-ms-transform:translate(-230px, 0);-o-transform:translate(-230px, 0);transform:translate(-230px, 0)}}@media (min-width:768px){.sidebar-collapse .main-sidebar,.sidebar-collapse .left-side{-webkit-transform:translate(-230px, 0);-ms-transform:translate(-230px, 0);-o-transform:translate(-230px, 0);transform:translate(-230px, 0)}}@media (max-width:767px){.sidebar-open .main-sidebar,.sidebar-open .left-side{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}}.sidebar{padding-bottom:10px}.sidebar-form input:focus{border-color:transparent}.user-panel{position:relative;width:100%;padding:10px;overflow:hidden}.user-panel:before,.user-panel:after{content:" ";display:table}.user-panel:after{clear:both}.user-panel>.image>img{width:100%;max-width:45px;height:auto}.user-panel>.info{padding:5px 5px 5px 15px;line-height:1;position:absolute;left:55px}.user-panel>.info>p{font-weight:600;margin-bottom:9px}.user-panel>.info>a{text-decoration:none;padding-right:5px;margin-top:3px;font-size:11px}.user-panel>.info>a>.fa,.user-panel>.info>a>.ion,.user-panel>.info>a>.glyphicon{margin-right:3px}.sidebar-menu{list-style:none;margin:0;padding:0}.sidebar-menu>li{position:relative;margin:0;padding:0}.sidebar-menu>li>a{padding:12px 5px 12px 15px;display:block}.sidebar-menu>li>a>.fa,.sidebar-menu>li>a>.glyphicon,.sidebar-menu>li>a>.ion{width:20px}.sidebar-menu>li .label,.sidebar-menu>li .badge{margin-top:3px;margin-right:5px}.sidebar-menu li.header{padding:10px 25px 10px 15px;font-size:12px}.sidebar-menu li>a>.fa-angle-left{width:auto;height:auto;padding:0;margin-right:10px;margin-top:3px}.sidebar-menu li.active>a>.fa-angle-left{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}.sidebar-menu li.active>.treeview-menu{display:block}.sidebar-menu .treeview-menu{display:none;list-style:none;padding:0;margin:0;padding-left:5px}.sidebar-menu .treeview-menu .treeview-menu{padding-left:20px}.sidebar-menu .treeview-menu>li{margin:0}.sidebar-menu .treeview-menu>li>a{padding:5px 5px 5px 15px;display:block;font-size:14px}.sidebar-menu .treeview-menu>li>a>.fa,.sidebar-menu .treeview-menu>li>a>.glyphicon,.sidebar-menu .treeview-menu>li>a>.ion{width:20px}.sidebar-menu .treeview-menu>li>a>.fa-angle-left,.sidebar-menu .treeview-menu>li>a>.fa-angle-down{width:auto}@media (min-width:768px){.sidebar-mini.sidebar-collapse .content-wrapper,.sidebar-mini.sidebar-collapse .right-side,.sidebar-mini.sidebar-collapse .main-footer{margin-left:50px !important;z-index:840}.sidebar-mini.sidebar-collapse .main-sidebar{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0);width:50px !important;z-index:850}.sidebar-mini.sidebar-collapse .sidebar-menu>li{position:relative}.sidebar-mini.sidebar-collapse .sidebar-menu>li>a{margin-right:0}.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>span{border-top-right-radius:4px}.sidebar-mini.sidebar-collapse .sidebar-menu>li:not(.treeview)>a>span{border-bottom-right-radius:4px}.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{padding-top:5px;padding-bottom:5px;border-bottom-right-radius:4px}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>a>span:not(.pull-right),.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>.treeview-menu{display:block !important;position:absolute;width:180px;left:50px}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>a>span{top:0;margin-left:-3px;padding:12px 5px 12px 20px;background-color:inherit}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>.treeview-menu{top:44px;margin-left:0}.sidebar-mini.sidebar-collapse .main-sidebar .user-panel>.info,.sidebar-mini.sidebar-collapse .sidebar-form,.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>span,.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu,.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>.pull-right,.sidebar-mini.sidebar-collapse .sidebar-menu li.header{display:none !important;-webkit-transform:translateZ(0)}.sidebar-mini.sidebar-collapse .main-header .logo{width:50px}.sidebar-mini.sidebar-collapse .main-header .logo>.logo-mini{display:block;margin-left:-15px;margin-right:-15px;font-size:18px}.sidebar-mini.sidebar-collapse .main-header .logo>.logo-lg{display:none}.sidebar-mini.sidebar-collapse .main-header .navbar{margin-left:50px}}.sidebar-menu,.main-sidebar .user-panel,.sidebar-menu>li.header{white-space:nowrap;overflow:hidden}.sidebar-menu:hover{overflow:visible}.sidebar-form,.sidebar-menu>li.header{overflow:hidden;text-overflow:clip}.sidebar-menu li>a{position:relative}.sidebar-menu li>a>.pull-right{position:absolute;right:10px;top:50%;margin-top:-7px}.control-sidebar-bg{position:fixed;z-index:1000;bottom:0}.control-sidebar-bg,.control-sidebar{top:0;right:-230px;width:230px;-webkit-transition:right .3s ease-in-out;-o-transition:right .3s ease-in-out;transition:right .3s ease-in-out}.control-sidebar{position:absolute;padding-top:50px;z-index:1010}@media (max-width:768px){.control-sidebar{padding-top:100px}}.control-sidebar>.tab-content{padding:10px 15px}.control-sidebar.control-sidebar-open,.control-sidebar.control-sidebar-open+.control-sidebar-bg{right:0}.control-sidebar-open .control-sidebar-bg,.control-sidebar-open .control-sidebar{right:0}@media (min-width:768px){.control-sidebar-open .content-wrapper,.control-sidebar-open .right-side,.control-sidebar-open .main-footer{margin-right:230px}}.nav-tabs.control-sidebar-tabs>li:first-of-type>a,.nav-tabs.control-sidebar-tabs>li:first-of-type>a:hover,.nav-tabs.control-sidebar-tabs>li:first-of-type>a:focus{border-left-width:0}.nav-tabs.control-sidebar-tabs>li>a{border-radius:0}.nav-tabs.control-sidebar-tabs>li>a,.nav-tabs.control-sidebar-tabs>li>a:hover{border-top:none;border-right:none;border-left:1px solid transparent;border-bottom:1px solid transparent}.nav-tabs.control-sidebar-tabs>li>a .icon{font-size:16px}.nav-tabs.control-sidebar-tabs>li.active>a,.nav-tabs.control-sidebar-tabs>li.active>a:hover,.nav-tabs.control-sidebar-tabs>li.active>a:focus,.nav-tabs.control-sidebar-tabs>li.active>a:active{border-top:none;border-right:none;border-bottom:none}@media (max-width:768px){.nav-tabs.control-sidebar-tabs{display:table}.nav-tabs.control-sidebar-tabs>li{display:table-cell}}.control-sidebar-heading{font-weight:400;font-size:16px;padding:10px 0;margin-bottom:10px}.control-sidebar-subheading{display:block;font-weight:400;font-size:14px}.control-sidebar-menu{list-style:none;padding:0;margin:0 -15px}.control-sidebar-menu>li>a{display:block;padding:10px 15px}.control-sidebar-menu>li>a:before,.control-sidebar-menu>li>a:after{content:" ";display:table}.control-sidebar-menu>li>a:after{clear:both}.control-sidebar-menu>li>a>.control-sidebar-subheading{margin-top:0}.control-sidebar-menu .menu-icon{float:left;width:35px;height:35px;border-radius:50%;text-align:center;line-height:35px}.control-sidebar-menu .menu-info{margin-left:45px;margin-top:3px}.control-sidebar-menu .menu-info>.control-sidebar-subheading{margin:0}.control-sidebar-menu .menu-info>p{margin:0;font-size:11px}.control-sidebar-menu .progress{margin:0}.control-sidebar-dark{color:#b8c7ce}.control-sidebar-dark,.control-sidebar-dark+.control-sidebar-bg{background:#222d32}.control-sidebar-dark .nav-tabs.control-sidebar-tabs{border-bottom:#1c2529}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a{background:#181f23;color:#b8c7ce}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:focus{border-left-color:#141a1d;border-bottom-color:#141a1d}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:focus,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:active{background:#1c2529}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:hover{color:#fff}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a:hover,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a:focus,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a:active{background:#222d32;color:#fff}.control-sidebar-dark .control-sidebar-heading,.control-sidebar-dark .control-sidebar-subheading{color:#fff}.control-sidebar-dark .control-sidebar-menu>li>a:hover{background:#1e282c}.control-sidebar-dark .control-sidebar-menu>li>a .menu-info>p{color:#b8c7ce}.control-sidebar-light{color:#5e5e5e}.control-sidebar-light,.control-sidebar-light+.control-sidebar-bg{background:#f9fafc;border-left:1px solid #d2d6de}.control-sidebar-light .nav-tabs.control-sidebar-tabs{border-bottom:#d2d6de}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a{background:#e8ecf4;color:#444}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:focus{border-left-color:#d2d6de;border-bottom-color:#d2d6de}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:focus,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:active{background:#eff1f7}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a:hover,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a:focus,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a:active{background:#f9fafc;color:#111}.control-sidebar-light .control-sidebar-heading,.control-sidebar-light .control-sidebar-subheading{color:#111}.control-sidebar-light .control-sidebar-menu{margin-left:-14px}.control-sidebar-light .control-sidebar-menu>li>a:hover{background:#f4f4f5}.control-sidebar-light .control-sidebar-menu>li>a .menu-info>p{color:#5e5e5e}.dropdown-menu{box-shadow:none;border-color:#eee}.dropdown-menu>li>a{color:#777}.dropdown-menu>li>a>.glyphicon,.dropdown-menu>li>a>.fa,.dropdown-menu>li>a>.ion{margin-right:10px}.dropdown-menu>li>a:hover{background-color:#e1e3e9;color:#333}.dropdown-menu>.divider{background-color:#eee}.navbar-nav>.notifications-menu>.dropdown-menu,.navbar-nav>.messages-menu>.dropdown-menu,.navbar-nav>.tasks-menu>.dropdown-menu{width:280px;padding:0 0 0 0;margin:0;top:100%}.navbar-nav>.notifications-menu>.dropdown-menu>li,.navbar-nav>.messages-menu>.dropdown-menu>li,.navbar-nav>.tasks-menu>.dropdown-menu>li{position:relative}.navbar-nav>.notifications-menu>.dropdown-menu>li.header,.navbar-nav>.messages-menu>.dropdown-menu>li.header,.navbar-nav>.tasks-menu>.dropdown-menu>li.header{border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0;background-color:#ffffff;padding:7px 10px;border-bottom:1px solid #f4f4f4;color:#444444;font-size:14px}.navbar-nav>.notifications-menu>.dropdown-menu>li.footer>a,.navbar-nav>.messages-menu>.dropdown-menu>li.footer>a,.navbar-nav>.tasks-menu>.dropdown-menu>li.footer>a{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px;font-size:12px;background-color:#fff;padding:7px 10px;border-bottom:1px solid #eeeeee;color:#444 !important;text-align:center}@media (max-width:991px){.navbar-nav>.notifications-menu>.dropdown-menu>li.footer>a,.navbar-nav>.messages-menu>.dropdown-menu>li.footer>a,.navbar-nav>.tasks-menu>.dropdown-menu>li.footer>a{background:#fff !important;color:#444 !important}}.navbar-nav>.notifications-menu>.dropdown-menu>li.footer>a:hover,.navbar-nav>.messages-menu>.dropdown-menu>li.footer>a:hover,.navbar-nav>.tasks-menu>.dropdown-menu>li.footer>a:hover{text-decoration:none;font-weight:normal}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu,.navbar-nav>.messages-menu>.dropdown-menu>li .menu,.navbar-nav>.tasks-menu>.dropdown-menu>li .menu{max-height:200px;margin:0;padding:0;list-style:none;overflow-x:hidden}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a,.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a,.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a{display:block;white-space:nowrap;border-bottom:1px solid #f4f4f4}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a:hover,.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:hover,.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a:hover{background:#f4f4f4;text-decoration:none}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a{color:#444444;overflow:hidden;text-overflow:ellipsis;padding:10px}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a>.glyphicon,.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a>.fa,.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a>.ion{width:20px}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a{margin:0;padding:10px 10px}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>div>img{margin:auto 10px auto auto;width:40px;height:40px}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>h4{padding:0;margin:0 0 0 45px;color:#444444;font-size:15px;position:relative}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>h4>small{color:#999999;font-size:10px;position:absolute;top:0;right:0}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>p{margin:0 0 0 45px;font-size:12px;color:#888888}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:before,.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:after{content:" ";display:table}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:after{clear:both}.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a{padding:10px}.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a>h3{font-size:14px;padding:0;margin:0 0 10px 0;color:#666666}.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a>.progress{padding:0;margin:0}.navbar-nav>.user-menu>.dropdown-menu{border-top-right-radius:0;border-top-left-radius:0;padding:1px 0 0 0;border-top-width:0;width:280px}.navbar-nav>.user-menu>.dropdown-menu,.navbar-nav>.user-menu>.dropdown-menu>.user-body{border-bottom-right-radius:4px;border-bottom-left-radius:4px}.navbar-nav>.user-menu>.dropdown-menu>li.user-header{height:175px;padding:10px;text-align:center}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>img{z-index:5;height:90px;width:90px;border:3px solid;border-color:transparent;border-color:rgba(255,255,255,0.2)}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>p{z-index:5;color:#fff;color:rgba(255,255,255,0.8);font-size:17px;margin-top:10px}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>p>small{display:block;font-size:12px}.navbar-nav>.user-menu>.dropdown-menu>.user-body{padding:15px;border-bottom:1px solid #f4f4f4;border-top:1px solid #dddddd}.navbar-nav>.user-menu>.dropdown-menu>.user-body:before,.navbar-nav>.user-menu>.dropdown-menu>.user-body:after{content:" ";display:table}.navbar-nav>.user-menu>.dropdown-menu>.user-body:after{clear:both}.navbar-nav>.user-menu>.dropdown-menu>.user-body a{color:#444 !important}@media (max-width:991px){.navbar-nav>.user-menu>.dropdown-menu>.user-body a{background:#fff !important;color:#444 !important}}.navbar-nav>.user-menu>.dropdown-menu>.user-footer{background-color:#f9f9f9;padding:10px}.navbar-nav>.user-menu>.dropdown-menu>.user-footer:before,.navbar-nav>.user-menu>.dropdown-menu>.user-footer:after{content:" ";display:table}.navbar-nav>.user-menu>.dropdown-menu>.user-footer:after{clear:both}.navbar-nav>.user-menu>.dropdown-menu>.user-footer .btn-default{color:#666666}@media (max-width:991px){.navbar-nav>.user-menu>.dropdown-menu>.user-footer .btn-default:hover{background-color:#f9f9f9}}.navbar-nav>.user-menu .user-image{float:left;width:25px;height:25px;border-radius:50%;margin-right:10px;margin-top:-2px}@media (max-width:767px){.navbar-nav>.user-menu .user-image{float:none;margin-right:0;margin-top:-8px;line-height:10px}}.open:not(.dropup)>.animated-dropdown-menu{backface-visibility:visible !important;-webkit-animation:flipInX .7s both;-o-animation:flipInX .7s both;animation:flipInX .7s both}@keyframes flipInX{0%{transform:perspective(400px) rotate3d(1, 0, 0, 90deg);transition-timing-function:ease-in;opacity:0}40%{transform:perspective(400px) rotate3d(1, 0, 0, -20deg);transition-timing-function:ease-in}60%{transform:perspective(400px) rotate3d(1, 0, 0, 10deg);opacity:1}80%{transform:perspective(400px) rotate3d(1, 0, 0, -5deg)}100%{transform:perspective(400px)}}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, 90deg);-webkit-transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, -20deg);-webkit-transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, 10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, -5deg)}100%{-webkit-transform:perspective(400px)}}.navbar-custom-menu>.navbar-nav>li{position:relative}.navbar-custom-menu>.navbar-nav>li>.dropdown-menu{position:absolute;right:0;left:auto}@media (max-width:991px){.navbar-custom-menu>.navbar-nav{float:right}.navbar-custom-menu>.navbar-nav>li{position:static}.navbar-custom-menu>.navbar-nav>li>.dropdown-menu{position:absolute;right:5%;left:auto;border:1px solid #ddd;background:#fff}}.form-control{border-radius:0;box-shadow:none;border-color:#d2d6de}.form-control:focus{border-color:#3c8dbc;box-shadow:none}.form-control::-moz-placeholder,.form-control:-ms-input-placeholder,.form-control::-webkit-input-placeholder{color:#bbb;opacity:1}.form-control:not(select){-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-group.has-success label{color:#00a65a}.form-group.has-success .form-control{border-color:#00a65a;box-shadow:none}.form-group.has-warning label{color:#f39c12}.form-group.has-warning .form-control{border-color:#f39c12;box-shadow:none}.form-group.has-error label{color:#dd4b39}.form-group.has-error .form-control{border-color:#dd4b39;box-shadow:none}.input-group .input-group-addon{border-radius:0;border-color:#d2d6de;background-color:#fff}.btn-group-vertical .btn.btn-flat:first-of-type,.btn-group-vertical .btn.btn-flat:last-of-type{border-radius:0}.icheck>label{padding-left:0}.form-control-feedback.fa{line-height:34px}.input-lg+.form-control-feedback.fa,.input-group-lg+.form-control-feedback.fa,.form-group-lg .form-control+.form-control-feedback.fa{line-height:46px}.input-sm+.form-control-feedback.fa,.input-group-sm+.form-control-feedback.fa,.form-group-sm .form-control+.form-control-feedback.fa{line-height:30px}.progress,.progress>.progress-bar{-webkit-box-shadow:none;box-shadow:none}.progress,.progress>.progress-bar,.progress .progress-bar,.progress>.progress-bar .progress-bar{border-radius:1px}.progress.sm,.progress-sm{height:10px}.progress.sm,.progress-sm,.progress.sm .progress-bar,.progress-sm .progress-bar{border-radius:1px}.progress.xs,.progress-xs{height:7px}.progress.xs,.progress-xs,.progress.xs .progress-bar,.progress-xs .progress-bar{border-radius:1px}.progress.xxs,.progress-xxs{height:3px}.progress.xxs,.progress-xxs,.progress.xxs .progress-bar,.progress-xxs .progress-bar{border-radius:1px}.progress.vertical{position:relative;width:30px;height:200px;display:inline-block;margin-right:10px}.progress.vertical>.progress-bar{width:100%;position:absolute;bottom:0}.progress.vertical.sm,.progress.vertical.progress-sm{width:20px}.progress.vertical.xs,.progress.vertical.progress-xs{width:10px}.progress.vertical.xxs,.progress.vertical.progress-xxs{width:3px}.progress-group .progress-text{font-weight:600}.progress-group .progress-number{float:right}.table tr>td .progress{margin:0}.progress-bar-light-blue,.progress-bar-primary{background-color:#3c8dbc}.progress-striped .progress-bar-light-blue,.progress-striped .progress-bar-primary{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-green,.progress-bar-success{background-color:#00a65a}.progress-striped .progress-bar-green,.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-aqua,.progress-bar-info{background-color:#00c0ef}.progress-striped .progress-bar-aqua,.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-yellow,.progress-bar-warning{background-color:#f39c12}.progress-striped .progress-bar-yellow,.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-red,.progress-bar-danger{background-color:#dd4b39}.progress-striped .progress-bar-red,.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.small-box{border-radius:2px;position:relative;display:block;margin-bottom:20px;box-shadow:0 1px 1px rgba(0,0,0,0.1)}.small-box>.inner{padding:10px}.small-box>.small-box-footer{position:relative;text-align:center;padding:3px 0;color:#fff;color:rgba(255,255,255,0.8);display:block;z-index:10;background:rgba(0,0,0,0.1);text-decoration:none}.small-box>.small-box-footer:hover{color:#fff;background:rgba(0,0,0,0.15)}.small-box h3{font-size:38px;font-weight:bold;margin:0 0 10px 0;white-space:nowrap;padding:0}.small-box p{font-size:15px}.small-box p>small{display:block;color:#f9f9f9;font-size:13px;margin-top:5px}.small-box h3,.small-box p{z-index:5px}.small-box .icon{-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear;position:absolute;top:-10px;right:10px;z-index:0;font-size:90px;color:rgba(0,0,0,0.15)}.small-box:hover{text-decoration:none;color:#f9f9f9}.small-box:hover .icon{font-size:95px}@media (max-width:767px){.small-box{text-align:center}.small-box .icon{display:none}.small-box p{font-size:12px}}.box{position:relative;border-radius:3px;background:#ffffff;border-top:3px solid #d2d6de;margin-bottom:20px;width:100%;box-shadow:0 1px 1px rgba(0,0,0,0.1)}.box.box-primary{border-top-color:#3c8dbc}.box.box-info{border-top-color:#00c0ef}.box.box-danger{border-top-color:#dd4b39}.box.box-warning{border-top-color:#f39c12}.box.box-success{border-top-color:#00a65a}.box.box-default{border-top-color:#d2d6de}.box.collapsed-box .box-body,.box.collapsed-box .box-footer{display:none}.box .nav-stacked>li{border-bottom:1px solid #f4f4f4;margin:0}.box .nav-stacked>li:last-of-type{border-bottom:none}.box.height-control .box-body{max-height:300px;overflow:auto}.box .border-right{border-right:1px solid #f4f4f4}.box .border-left{border-left:1px solid #f4f4f4}.box.box-solid{border-top:0}.box.box-solid>.box-header .btn.btn-default{background:transparent}.box.box-solid>.box-header .btn:hover,.box.box-solid>.box-header a:hover{background:rgba(0,0,0,0.1)}.box.box-solid.box-default{border:1px solid #d2d6de}.box.box-solid.box-default>.box-header{color:#444;background:#d2d6de;background-color:#d2d6de}.box.box-solid.box-default>.box-header a,.box.box-solid.box-default>.box-header .btn{color:#444}.box.box-solid.box-primary{border:1px solid #3c8dbc}.box.box-solid.box-primary>.box-header{color:#fff;background:#3c8dbc;background-color:#3c8dbc}.box.box-solid.box-primary>.box-header a,.box.box-solid.box-primary>.box-header .btn{color:#fff}.box.box-solid.box-info{border:1px solid #00c0ef}.box.box-solid.box-info>.box-header{color:#fff;background:#00c0ef;background-color:#00c0ef}.box.box-solid.box-info>.box-header a,.box.box-solid.box-info>.box-header .btn{color:#fff}.box.box-solid.box-danger{border:1px solid #dd4b39}.box.box-solid.box-danger>.box-header{color:#fff;background:#dd4b39;background-color:#dd4b39}.box.box-solid.box-danger>.box-header a,.box.box-solid.box-danger>.box-header .btn{color:#fff}.box.box-solid.box-warning{border:1px solid #f39c12}.box.box-solid.box-warning>.box-header{color:#fff;background:#f39c12;background-color:#f39c12}.box.box-solid.box-warning>.box-header a,.box.box-solid.box-warning>.box-header .btn{color:#fff}.box.box-solid.box-success{border:1px solid #00a65a}.box.box-solid.box-success>.box-header{color:#fff;background:#00a65a;background-color:#00a65a}.box.box-solid.box-success>.box-header a,.box.box-solid.box-success>.box-header .btn{color:#fff}.box.box-solid>.box-header>.box-tools .btn{border:0;box-shadow:none}.box.box-solid[class*='bg']>.box-header{color:#fff}.box .box-group>.box{margin-bottom:5px}.box .knob-label{text-align:center;color:#333;font-weight:100;font-size:12px;margin-bottom:0.3em}.box>.overlay,.overlay-wrapper>.overlay,.box>.loading-img,.overlay-wrapper>.loading-img{position:absolute;top:0;left:0;width:100%;height:100%}.box .overlay,.overlay-wrapper .overlay{z-index:50;background:rgba(255,255,255,0.7);border-radius:3px}.box .overlay>.fa,.overlay-wrapper .overlay>.fa{position:absolute;top:50%;left:50%;margin-left:-15px;margin-top:-15px;color:#000;font-size:30px}.box .overlay.dark,.overlay-wrapper .overlay.dark{background:rgba(0,0,0,0.5)}.box-header:before,.box-body:before,.box-footer:before,.box-header:after,.box-body:after,.box-footer:after{content:" ";display:table}.box-header:after,.box-body:after,.box-footer:after{clear:both}.box-header{color:#444;display:block;padding:10px;position:relative}.box-header.with-border{border-bottom:1px solid #f4f4f4}.collapsed-box .box-header.with-border{border-bottom:none}.box-header>.fa,.box-header>.glyphicon,.box-header>.ion,.box-header .box-title{display:inline-block;font-size:18px;margin:0;line-height:1}.box-header>.fa,.box-header>.glyphicon,.box-header>.ion{margin-right:5px}.box-header>.box-tools{position:absolute;right:10px;top:5px}.box-header>.box-tools [data-toggle="tooltip"]{position:relative}.box-header>.box-tools.pull-right .dropdown-menu{right:0;left:auto}.btn-box-tool{padding:5px;font-size:12px;background:transparent;color:#97a0b3}.open .btn-box-tool,.btn-box-tool:hover{color:#606c84}.btn-box-tool.btn:active{box-shadow:none}.box-body{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;padding:10px}.no-header .box-body{border-top-right-radius:3px;border-top-left-radius:3px}.box-body>.table{margin-bottom:0}.box-body .fc{margin-top:5px}.box-body .full-width-chart{margin:-19px}.box-body.no-padding .full-width-chart{margin:-9px}.box-body .box-pane{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:3px}.box-body .box-pane-right{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:0}.box-footer{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border-top:1px solid #f4f4f4;padding:10px;background-color:#fff}.chart-legend{margin:10px 0}@media (max-width:991px){.chart-legend>li{float:left;margin-right:10px}}.box-comments{background:#f7f7f7}.box-comments .box-comment{padding:8px 0;border-bottom:1px solid #eee}.box-comments .box-comment:before,.box-comments .box-comment:after{content:" ";display:table}.box-comments .box-comment:after{clear:both}.box-comments .box-comment:last-of-type{border-bottom:0}.box-comments .box-comment:first-of-type{padding-top:0}.box-comments .box-comment img{float:left}.box-comments .comment-text{margin-left:40px;color:#555}.box-comments .username{color:#444;display:block;font-weight:600}.box-comments .text-muted{font-weight:400;font-size:12px}.todo-list{margin:0;padding:0;list-style:none;overflow:auto}.todo-list>li{border-radius:2px;padding:10px;background:#f4f4f4;margin-bottom:2px;border-left:2px solid #e6e7e8;color:#444}.todo-list>li:last-of-type{margin-bottom:0}.todo-list>li>input[type='checkbox']{margin:0 10px 0 5px}.todo-list>li .text{display:inline-block;margin-left:5px;font-weight:600}.todo-list>li .label{margin-left:10px;font-size:9px}.todo-list>li .tools{display:none;float:right;color:#dd4b39}.todo-list>li .tools>.fa,.todo-list>li .tools>.glyphicon,.todo-list>li .tools>.ion{margin-right:5px;cursor:pointer}.todo-list>li:hover .tools{display:inline-block}.todo-list>li.done{color:#999}.todo-list>li.done .text{text-decoration:line-through;font-weight:500}.todo-list>li.done .label{background:#d2d6de !important}.todo-list .danger{border-left-color:#dd4b39}.todo-list .warning{border-left-color:#f39c12}.todo-list .info{border-left-color:#00c0ef}.todo-list .success{border-left-color:#00a65a}.todo-list .primary{border-left-color:#3c8dbc}.todo-list .handle{display:inline-block;cursor:move;margin:0 5px}.chat{padding:5px 20px 5px 10px}.chat .item{margin-bottom:10px}.chat .item:before,.chat .item:after{content:" ";display:table}.chat .item:after{clear:both}.chat .item>img{width:40px;height:40px;border:2px solid transparent;border-radius:50%}.chat .item>.online{border:2px solid #00a65a}.chat .item>.offline{border:2px solid #dd4b39}.chat .item>.message{margin-left:55px;margin-top:-40px}.chat .item>.message>.name{display:block;font-weight:600}.chat .item>.attachment{border-radius:3px;background:#f4f4f4;margin-left:65px;margin-right:15px;padding:10px}.chat .item>.attachment>h4{margin:0 0 5px 0;font-weight:600;font-size:14px}.chat .item>.attachment>p,.chat .item>.attachment>.filename{font-weight:600;font-size:13px;font-style:italic;margin:0}.chat .item>.attachment:before,.chat .item>.attachment:after{content:" ";display:table}.chat .item>.attachment:after{clear:both}.box-input{max-width:200px}.modal .panel-body{color:#444}.info-box{display:block;min-height:90px;background:#fff;width:100%;box-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:2px;margin-bottom:15px}.info-box small{font-size:14px}.info-box .progress{background:rgba(0,0,0,0.2);margin:5px -10px 5px -10px;height:2px}.info-box .progress,.info-box .progress .progress-bar{border-radius:0}.info-box .progress .progress-bar{background:#fff}.info-box-icon{border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px;display:block;float:left;height:90px;width:90px;text-align:center;font-size:45px;line-height:90px;background:rgba(0,0,0,0.2)}.info-box-icon>img{max-width:100%}.info-box-content{padding:5px 10px;margin-left:90px}.info-box-number{display:block;font-weight:bold;font-size:18px}.progress-description,.info-box-text{display:block;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.info-box-text{text-transform:uppercase}.info-box-more{display:block}.progress-description{margin:0}.timeline{position:relative;margin:0 0 30px 0;padding:0;list-style:none}.timeline:before{content:'';position:absolute;top:0;bottom:0;width:4px;background:#ddd;left:31px;margin:0;border-radius:2px}.timeline>li{position:relative;margin-right:10px;margin-bottom:15px}.timeline>li:before,.timeline>li:after{content:" ";display:table}.timeline>li:after{clear:both}.timeline>li>.timeline-item{-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.1);box-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:3px;margin-top:0;background:#fff;color:#444;margin-left:60px;margin-right:15px;padding:0;position:relative}.timeline>li>.timeline-item>.time{color:#999;float:right;padding:10px;font-size:12px}.timeline>li>.timeline-item>.timeline-header{margin:0;color:#555;border-bottom:1px solid #f4f4f4;padding:10px;font-size:16px;line-height:1.1}.timeline>li>.timeline-item>.timeline-header>a{font-weight:600}.timeline>li>.timeline-item>.timeline-body,.timeline>li>.timeline-item>.timeline-footer{padding:10px}.timeline>li>.fa,.timeline>li>.glyphicon,.timeline>li>.ion{width:30px;height:30px;font-size:15px;line-height:30px;position:absolute;color:#666;background:#d2d6de;border-radius:50%;text-align:center;left:18px;top:0}.timeline>.time-label>span{font-weight:600;padding:5px;display:inline-block;background-color:#fff;border-radius:4px}.timeline-inverse>li>.timeline-item{background:#f0f0f0;border:1px solid #ddd;-webkit-box-shadow:none;box-shadow:none}.timeline-inverse>li>.timeline-item>.timeline-header{border-bottom-color:#ddd}.btn{border-radius:3px;-webkit-box-shadow:none;box-shadow:none;border:1px solid transparent}.btn.uppercase{text-transform:uppercase}.btn.btn-flat{border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;border-width:1px}.btn:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn:focus{outline:none}.btn.btn-file{position:relative;overflow:hidden}.btn.btn-file>input[type='file']{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:100px;text-align:right;opacity:0;filter:alpha(opacity=0);outline:none;background:white;cursor:inherit;display:block}.btn-default{background-color:#f4f4f4;color:#444;border-color:#ddd}.btn-default:hover,.btn-default:active,.btn-default.hover{background-color:#e7e7e7}.btn-primary{background-color:#3c8dbc;border-color:#367fa9}.btn-primary:hover,.btn-primary:active,.btn-primary.hover{background-color:#367fa9}.btn-success{background-color:#00a65a;border-color:#008d4c}.btn-success:hover,.btn-success:active,.btn-success.hover{background-color:#008d4c}.btn-info{background-color:#00c0ef;border-color:#00acd6}.btn-info:hover,.btn-info:active,.btn-info.hover{background-color:#00acd6}.btn-danger{background-color:#dd4b39;border-color:#d73925}.btn-danger:hover,.btn-danger:active,.btn-danger.hover{background-color:#d73925}.btn-warning{background-color:#f39c12;border-color:#e08e0b}.btn-warning:hover,.btn-warning:active,.btn-warning.hover{background-color:#e08e0b}.btn-outline{border:1px solid #fff;background:transparent;color:#fff}.btn-outline:hover,.btn-outline:focus,.btn-outline:active{color:rgba(255,255,255,0.7);border-color:rgba(255,255,255,0.7)}.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn[class*='bg-']:hover{-webkit-box-shadow:inset 0 0 100px rgba(0,0,0,0.2);box-shadow:inset 0 0 100px rgba(0,0,0,0.2)}.btn-app{border-radius:3px;position:relative;padding:15px 5px;margin:0 0 10px 10px;min-width:80px;height:60px;text-align:center;color:#666;border:1px solid #ddd;background-color:#f4f4f4;font-size:12px}.btn-app>.fa,.btn-app>.glyphicon,.btn-app>.ion{font-size:20px;display:block}.btn-app:hover{background:#f4f4f4;color:#444;border-color:#aaa}.btn-app:active,.btn-app:focus{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-app>.badge{position:absolute;top:-3px;right:-10px;font-size:10px;font-weight:400}.callout{border-radius:3px;margin:0 0 20px 0;padding:15px 30px 15px 15px;border-left:5px solid #eee}.callout a{color:#fff;text-decoration:underline}.callout a:hover{color:#eee}.callout h4{margin-top:0;font-weight:600}.callout p:last-child{margin-bottom:0}.callout code,.callout .highlight{background-color:#fff}.callout.callout-danger{border-color:#c23321}.callout.callout-warning{border-color:#c87f0a}.callout.callout-info{border-color:#0097bc}.callout.callout-success{border-color:#00733e}.alert{border-radius:3px}.alert h4{font-weight:600}.alert .icon{margin-right:10px}.alert .close{color:#000;opacity:.2;filter:alpha(opacity=20)}.alert .close:hover{opacity:.5;filter:alpha(opacity=50)}.alert a{color:#fff;text-decoration:underline}.alert-success{border-color:#008d4c}.alert-danger,.alert-error{border-color:#d73925}.alert-warning{border-color:#e08e0b}.alert-info{border-color:#00acd6}.nav>li>a:hover,.nav>li>a:active,.nav>li>a:focus{color:#444;background:#f7f7f7}.nav-pills>li>a{border-radius:0;border-top:3px solid transparent;color:#444}.nav-pills>li>a>.fa,.nav-pills>li>a>.glyphicon,.nav-pills>li>a>.ion{margin-right:5px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{border-top-color:#3c8dbc}.nav-pills>li.active>a{font-weight:600}.nav-stacked>li>a{border-radius:0;border-top:0;border-left:3px solid transparent;color:#444}.nav-stacked>li.active>a,.nav-stacked>li.active>a:hover{background:transparent;color:#444;border-top:0;border-left-color:#3c8dbc}.nav-stacked>li.header{border-bottom:1px solid #ddd;color:#777;margin-bottom:10px;padding:5px 10px;text-transform:uppercase}.nav-tabs-custom{margin-bottom:20px;background:#fff;box-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:3px}.nav-tabs-custom>.nav-tabs{margin:0;border-bottom-color:#f4f4f4;border-top-right-radius:3px;border-top-left-radius:3px}.nav-tabs-custom>.nav-tabs>li{border-top:3px solid transparent;margin-bottom:-2px;margin-right:5px}.nav-tabs-custom>.nav-tabs>li>a{color:#444;border-radius:0}.nav-tabs-custom>.nav-tabs>li>a.text-muted{color:#999}.nav-tabs-custom>.nav-tabs>li>a,.nav-tabs-custom>.nav-tabs>li>a:hover{background:transparent;margin:0}.nav-tabs-custom>.nav-tabs>li>a:hover{color:#999}.nav-tabs-custom>.nav-tabs>li:not(.active)>a:hover,.nav-tabs-custom>.nav-tabs>li:not(.active)>a:focus,.nav-tabs-custom>.nav-tabs>li:not(.active)>a:active{border-color:transparent}.nav-tabs-custom>.nav-tabs>li.active{border-top-color:#3c8dbc}.nav-tabs-custom>.nav-tabs>li.active>a,.nav-tabs-custom>.nav-tabs>li.active:hover>a{background-color:#fff;color:#444}.nav-tabs-custom>.nav-tabs>li.active>a{border-top-color:transparent;border-left-color:#f4f4f4;border-right-color:#f4f4f4}.nav-tabs-custom>.nav-tabs>li:first-of-type{margin-left:0}.nav-tabs-custom>.nav-tabs>li:first-of-type.active>a{border-left-color:transparent}.nav-tabs-custom>.nav-tabs.pull-right{float:none !important}.nav-tabs-custom>.nav-tabs.pull-right>li{float:right}.nav-tabs-custom>.nav-tabs.pull-right>li:first-of-type{margin-right:0}.nav-tabs-custom>.nav-tabs.pull-right>li:first-of-type>a{border-left-width:1px}.nav-tabs-custom>.nav-tabs.pull-right>li:first-of-type.active>a{border-left-color:#f4f4f4;border-right-color:transparent}.nav-tabs-custom>.nav-tabs>li.header{line-height:35px;padding:0 10px;font-size:20px;color:#444}.nav-tabs-custom>.nav-tabs>li.header>.fa,.nav-tabs-custom>.nav-tabs>li.header>.glyphicon,.nav-tabs-custom>.nav-tabs>li.header>.ion{margin-right:5px}.nav-tabs-custom>.tab-content{background:#fff;padding:10px;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.nav-tabs-custom .dropdown.open>a:active,.nav-tabs-custom .dropdown.open>a:focus{background:transparent;color:#999}.nav-tabs-custom.tab-primary>.nav-tabs>li.active{border-top-color:#3c8dbc}.nav-tabs-custom.tab-info>.nav-tabs>li.active{border-top-color:#00c0ef}.nav-tabs-custom.tab-danger>.nav-tabs>li.active{border-top-color:#dd4b39}.nav-tabs-custom.tab-warning>.nav-tabs>li.active{border-top-color:#f39c12}.nav-tabs-custom.tab-success>.nav-tabs>li.active{border-top-color:#00a65a}.nav-tabs-custom.tab-default>.nav-tabs>li.active{border-top-color:#d2d6de}.pagination>li>a{background:#fafafa;color:#666}.pagination.pagination-flat>li>a{border-radius:0 !important}.products-list{list-style:none;margin:0;padding:0}.products-list>.item{border-radius:3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.1);box-shadow:0 1px 1px rgba(0,0,0,0.1);padding:10px 0;background:#fff}.products-list>.item:before,.products-list>.item:after{content:" ";display:table}.products-list>.item:after{clear:both}.products-list .product-img{float:left}.products-list .product-img img{width:50px;height:50px}.products-list .product-info{margin-left:60px}.products-list .product-title{font-weight:600}.products-list .product-description{display:block;color:#999;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.product-list-in-box>.item{-webkit-box-shadow:none;box-shadow:none;border-radius:0;border-bottom:1px solid #f4f4f4}.product-list-in-box>.item:last-of-type{border-bottom-width:0}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{border-top:1px solid #f4f4f4}.table>thead>tr>th{border-bottom:2px solid #f4f4f4}.table tr td .progress{margin-top:5px}.table-bordered{border:1px solid #f4f4f4}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #f4f4f4}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table.no-border,.table.no-border td,.table.no-border th{border:0}table.text-center,table.text-center td,table.text-center th{text-align:center}.table.align th{text-align:left}.table.align td{text-align:right}.label-default{background-color:#d2d6de;color:#444}.direct-chat .box-body{border-bottom-right-radius:0;border-bottom-left-radius:0;position:relative;overflow-x:hidden;padding:0}.direct-chat.chat-pane-open .direct-chat-contacts{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.direct-chat-messages{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0);padding:10px;height:250px;overflow:auto}.direct-chat-msg,.direct-chat-text{display:block}.direct-chat-msg{margin-bottom:10px}.direct-chat-msg:before,.direct-chat-msg:after{content:" ";display:table}.direct-chat-msg:after{clear:both}.direct-chat-messages,.direct-chat-contacts{-webkit-transition:-webkit-transform .5s ease-in-out;-moz-transition:-moz-transform .5s ease-in-out;-o-transition:-o-transform .5s ease-in-out;transition:transform .5s ease-in-out}.direct-chat-text{border-radius:5px;position:relative;padding:5px 10px;background:#d2d6de;border:1px solid #d2d6de;margin:5px 0 0 50px;color:#444}.direct-chat-text:after,.direct-chat-text:before{position:absolute;right:100%;top:15px;border:solid transparent;border-right-color:#d2d6de;content:' ';height:0;width:0;pointer-events:none}.direct-chat-text:after{border-width:5px;margin-top:-5px}.direct-chat-text:before{border-width:6px;margin-top:-6px}.right .direct-chat-text{margin-right:50px;margin-left:0}.right .direct-chat-text:after,.right .direct-chat-text:before{right:auto;left:100%;border-right-color:transparent;border-left-color:#d2d6de}.direct-chat-img{border-radius:50%;float:left;width:40px;height:40px}.right .direct-chat-img{float:right}.direct-chat-info{display:block;margin-bottom:2px;font-size:12px}.direct-chat-name{font-weight:600}.direct-chat-timestamp{color:#999}.direct-chat-contacts-open .direct-chat-contacts{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.direct-chat-contacts{-webkit-transform:translate(101%, 0);-ms-transform:translate(101%, 0);-o-transform:translate(101%, 0);transform:translate(101%, 0);position:absolute;top:0;bottom:0;height:250px;width:100%;background:#222d32;color:#fff;overflow:auto}.contacts-list>li{border-bottom:1px solid rgba(0,0,0,0.2);padding:10px;margin:0}.contacts-list>li:before,.contacts-list>li:after{content:" ";display:table}.contacts-list>li:after{clear:both}.contacts-list>li:last-of-type{border-bottom:none}.contacts-list-img{border-radius:50%;width:40px;float:left}.contacts-list-info{margin-left:45px;color:#fff}.contacts-list-name,.contacts-list-status{display:block}.contacts-list-name{font-weight:600}.contacts-list-status{font-size:12px}.contacts-list-date{color:#aaa;font-weight:normal}.contacts-list-msg{color:#999}.direct-chat-danger .right>.direct-chat-text{background:#dd4b39;border-color:#dd4b39;color:#fff}.direct-chat-danger .right>.direct-chat-text:after,.direct-chat-danger .right>.direct-chat-text:before{border-left-color:#dd4b39}.direct-chat-primary .right>.direct-chat-text{background:#3c8dbc;border-color:#3c8dbc;color:#fff}.direct-chat-primary .right>.direct-chat-text:after,.direct-chat-primary .right>.direct-chat-text:before{border-left-color:#3c8dbc}.direct-chat-warning .right>.direct-chat-text{background:#f39c12;border-color:#f39c12;color:#fff}.direct-chat-warning .right>.direct-chat-text:after,.direct-chat-warning .right>.direct-chat-text:before{border-left-color:#f39c12}.direct-chat-info .right>.direct-chat-text{background:#00c0ef;border-color:#00c0ef;color:#fff}.direct-chat-info .right>.direct-chat-text:after,.direct-chat-info .right>.direct-chat-text:before{border-left-color:#00c0ef}.direct-chat-success .right>.direct-chat-text{background:#00a65a;border-color:#00a65a;color:#fff}.direct-chat-success .right>.direct-chat-text:after,.direct-chat-success .right>.direct-chat-text:before{border-left-color:#00a65a}.users-list>li{width:25%;float:left;padding:10px;text-align:center}.users-list>li img{border-radius:50%;max-width:100%;height:auto}.users-list>li>a:hover,.users-list>li>a:hover .users-list-name{color:#999}.users-list-name,.users-list-date{display:block}.users-list-name{font-weight:600;color:#444;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.users-list-date{color:#999;font-size:12px}.carousel-control.left,.carousel-control.right{background-image:none}.carousel-control>.fa{font-size:40px;position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-20px}.modal{background:rgba(0,0,0,0.3)}.modal-content{border-radius:0;-webkit-box-shadow:0 2px 3px rgba(0,0,0,0.125);box-shadow:0 2px 3px rgba(0,0,0,0.125);border:0}@media (min-width:768px){.modal-content{-webkit-box-shadow:0 2px 3px rgba(0,0,0,0.125);box-shadow:0 2px 3px rgba(0,0,0,0.125)}}.modal-header{border-bottom-color:#f4f4f4}.modal-footer{border-top-color:#f4f4f4}.modal-primary .modal-header,.modal-primary .modal-footer{border-color:#307095}.modal-warning .modal-header,.modal-warning .modal-footer{border-color:#c87f0a}.modal-info .modal-header,.modal-info .modal-footer{border-color:#0097bc}.modal-success .modal-header,.modal-success .modal-footer{border-color:#00733e}.modal-danger .modal-header,.modal-danger .modal-footer{border-color:#c23321}.box-widget{border:none;position:relative}.widget-user .widget-user-header{padding:20px;height:120px;border-top-right-radius:3px;border-top-left-radius:3px}.widget-user .widget-user-username{margin-top:0;margin-bottom:5px;font-size:25px;font-weight:300;text-shadow:0 1px 1px rgba(0,0,0,0.2)}.widget-user .widget-user-desc{margin-top:0}.widget-user .widget-user-image{position:absolute;top:65px;left:50%;margin-left:-45px}.widget-user .widget-user-image>img{width:90px;height:auto;border:3px solid #fff}.widget-user .box-footer{padding-top:30px}.widget-user-2 .widget-user-header{padding:20px;border-top-right-radius:3px;border-top-left-radius:3px}.widget-user-2 .widget-user-username{margin-top:5px;margin-bottom:5px;font-size:25px;font-weight:300}.widget-user-2 .widget-user-desc{margin-top:0}.widget-user-2 .widget-user-username,.widget-user-2 .widget-user-desc{margin-left:75px}.widget-user-2 .widget-user-image>img{width:65px;height:auto;float:left}.mailbox-messages>.table{margin:0}.mailbox-controls{padding:5px}.mailbox-controls.with-border{border-bottom:1px solid #f4f4f4}.mailbox-read-info{border-bottom:1px solid #f4f4f4;padding:10px}.mailbox-read-info h3{font-size:20px;margin:0}.mailbox-read-info h5{margin:0;padding:5px 0 0 0}.mailbox-read-time{color:#999;font-size:13px}.mailbox-read-message{padding:10px}.mailbox-attachments li{float:left;width:200px;border:1px solid #eee;margin-bottom:10px;margin-right:10px}.mailbox-attachment-name{font-weight:bold;color:#666}.mailbox-attachment-icon,.mailbox-attachment-info,.mailbox-attachment-size{display:block}.mailbox-attachment-info{padding:10px;background:#f4f4f4}.mailbox-attachment-size{color:#999;font-size:12px}.mailbox-attachment-icon{text-align:center;font-size:65px;color:#666;padding:20px 10px}.mailbox-attachment-icon.has-img{padding:0}.mailbox-attachment-icon.has-img>img{max-width:100%;height:auto}.lockscreen{background:#d2d6de}.lockscreen-logo{font-size:35px;text-align:center;margin-bottom:25px;font-weight:300}.lockscreen-logo a{color:#444}.lockscreen-wrapper{max-width:400px;margin:0 auto;margin-top:10%}.lockscreen .lockscreen-name{text-align:center;font-weight:600}.lockscreen-item{border-radius:4px;padding:0;background:#fff;position:relative;margin:10px auto 30px auto;width:290px}.lockscreen-image{border-radius:50%;position:absolute;left:-10px;top:-25px;background:#fff;padding:5px;z-index:10}.lockscreen-image>img{border-radius:50%;width:70px;height:70px}.lockscreen-credentials{margin-left:70px}.lockscreen-credentials .form-control{border:0}.lockscreen-credentials .btn{background-color:#fff;border:0;padding:0 10px}.lockscreen-footer{margin-top:10px}.login-logo,.register-logo{font-size:35px;text-align:center;margin-bottom:25px;font-weight:300}.login-logo a,.register-logo a{color:#444}.login-page,.register-page{background:#d2d6de}.login-box,.register-box{width:360px;margin:7% auto}@media (max-width:768px){.login-box,.register-box{width:90%;margin-top:20px}}.login-box-body,.register-box-body{background:#fff;padding:20px;border-top:0;color:#666}.login-box-body .form-control-feedback,.register-box-body .form-control-feedback{color:#777}.login-box-msg,.register-box-msg{margin:0;text-align:center;padding:0 20px 20px 20px}.social-auth-links{margin:10px 0}.error-page{width:600px;margin:20px auto 0 auto}@media (max-width:991px){.error-page{width:100%}}.error-page>.headline{float:left;font-size:100px;font-weight:300}@media (max-width:991px){.error-page>.headline{float:none;text-align:center}}.error-page>.error-content{margin-left:190px;display:block}@media (max-width:991px){.error-page>.error-content{margin-left:0}}.error-page>.error-content>h3{font-weight:300;font-size:25px}@media (max-width:991px){.error-page>.error-content>h3{text-align:center}}.invoice{position:relative;background:#fff;border:1px solid #f4f4f4;padding:20px;margin:10px 25px}.invoice-title{margin-top:0}.profile-user-img{margin:0 auto;width:100px;padding:3px;border:3px solid #d2d6de}.profile-username{font-size:21px;margin-top:5px}.post{border-bottom:1px solid #d2d6de;margin-bottom:15px;padding-bottom:15px;color:#666}.post:last-of-type{border-bottom:0;margin-bottom:0;padding-bottom:0}.post .user-block{margin-bottom:15px}.btn-social{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.btn-social>:first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)}.btn-social.btn-lg{padding-left:61px}.btn-social.btn-lg>:first-child{line-height:45px;width:45px;font-size:1.8em}.btn-social.btn-sm{padding-left:38px}.btn-social.btn-sm>:first-child{line-height:28px;width:28px;font-size:1.4em}.btn-social.btn-xs{padding-left:30px}.btn-social.btn-xs>:first-child{line-height:20px;width:20px;font-size:1.2em}.btn-social-icon{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:34px;width:34px;padding:0}.btn-social-icon>:first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)}.btn-social-icon.btn-lg{padding-left:61px}.btn-social-icon.btn-lg>:first-child{line-height:45px;width:45px;font-size:1.8em}.btn-social-icon.btn-sm{padding-left:38px}.btn-social-icon.btn-sm>:first-child{line-height:28px;width:28px;font-size:1.4em}.btn-social-icon.btn-xs{padding-left:30px}.btn-social-icon.btn-xs>:first-child{line-height:20px;width:20px;font-size:1.2em}.btn-social-icon>:first-child{border:none;text-align:center;width:100%}.btn-social-icon.btn-lg{height:45px;width:45px;padding-left:0;padding-right:0}.btn-social-icon.btn-sm{height:30px;width:30px;padding-left:0;padding-right:0}.btn-social-icon.btn-xs{height:22px;width:22px;padding-left:0;padding-right:0}.btn-adn{color:#fff;background-color:#d87a68;border-color:rgba(0,0,0,0.2)}.btn-adn:focus,.btn-adn.focus{color:#fff;background-color:#ce563f;border-color:rgba(0,0,0,0.2)}.btn-adn:hover{color:#fff;background-color:#ce563f;border-color:rgba(0,0,0,0.2)}.btn-adn:active,.btn-adn.active,.open>.dropdown-toggle.btn-adn{color:#fff;background-color:#ce563f;border-color:rgba(0,0,0,0.2)}.btn-adn:active,.btn-adn.active,.open>.dropdown-toggle.btn-adn{background-image:none}.btn-adn .badge{color:#d87a68;background-color:#fff}.btn-bitbucket{color:#fff;background-color:#205081;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:focus,.btn-bitbucket.focus{color:#fff;background-color:#163758;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:hover{color:#fff;background-color:#163758;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:active,.btn-bitbucket.active,.open>.dropdown-toggle.btn-bitbucket{color:#fff;background-color:#163758;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:active,.btn-bitbucket.active,.open>.dropdown-toggle.btn-bitbucket{background-image:none}.btn-bitbucket .badge{color:#205081;background-color:#fff}.btn-dropbox{color:#fff;background-color:#1087dd;border-color:rgba(0,0,0,0.2)}.btn-dropbox:focus,.btn-dropbox.focus{color:#fff;background-color:#0d6aad;border-color:rgba(0,0,0,0.2)}.btn-dropbox:hover{color:#fff;background-color:#0d6aad;border-color:rgba(0,0,0,0.2)}.btn-dropbox:active,.btn-dropbox.active,.open>.dropdown-toggle.btn-dropbox{color:#fff;background-color:#0d6aad;border-color:rgba(0,0,0,0.2)}.btn-dropbox:active,.btn-dropbox.active,.open>.dropdown-toggle.btn-dropbox{background-image:none}.btn-dropbox .badge{color:#1087dd;background-color:#fff}.btn-facebook{color:#fff;background-color:#3b5998;border-color:rgba(0,0,0,0.2)}.btn-facebook:focus,.btn-facebook.focus{color:#fff;background-color:#2d4373;border-color:rgba(0,0,0,0.2)}.btn-facebook:hover{color:#fff;background-color:#2d4373;border-color:rgba(0,0,0,0.2)}.btn-facebook:active,.btn-facebook.active,.open>.dropdown-toggle.btn-facebook{color:#fff;background-color:#2d4373;border-color:rgba(0,0,0,0.2)}.btn-facebook:active,.btn-facebook.active,.open>.dropdown-toggle.btn-facebook{background-image:none}.btn-facebook .badge{color:#3b5998;background-color:#fff}.btn-flickr{color:#fff;background-color:#ff0084;border-color:rgba(0,0,0,0.2)}.btn-flickr:focus,.btn-flickr.focus{color:#fff;background-color:#cc006a;border-color:rgba(0,0,0,0.2)}.btn-flickr:hover{color:#fff;background-color:#cc006a;border-color:rgba(0,0,0,0.2)}.btn-flickr:active,.btn-flickr.active,.open>.dropdown-toggle.btn-flickr{color:#fff;background-color:#cc006a;border-color:rgba(0,0,0,0.2)}.btn-flickr:active,.btn-flickr.active,.open>.dropdown-toggle.btn-flickr{background-image:none}.btn-flickr .badge{color:#ff0084;background-color:#fff}.btn-foursquare{color:#fff;background-color:#f94877;border-color:rgba(0,0,0,0.2)}.btn-foursquare:focus,.btn-foursquare.focus{color:#fff;background-color:#f71752;border-color:rgba(0,0,0,0.2)}.btn-foursquare:hover{color:#fff;background-color:#f71752;border-color:rgba(0,0,0,0.2)}.btn-foursquare:active,.btn-foursquare.active,.open>.dropdown-toggle.btn-foursquare{color:#fff;background-color:#f71752;border-color:rgba(0,0,0,0.2)}.btn-foursquare:active,.btn-foursquare.active,.open>.dropdown-toggle.btn-foursquare{background-image:none}.btn-foursquare .badge{color:#f94877;background-color:#fff}.btn-github{color:#fff;background-color:#444;border-color:rgba(0,0,0,0.2)}.btn-github:focus,.btn-github.focus{color:#fff;background-color:#2b2b2b;border-color:rgba(0,0,0,0.2)}.btn-github:hover{color:#fff;background-color:#2b2b2b;border-color:rgba(0,0,0,0.2)}.btn-github:active,.btn-github.active,.open>.dropdown-toggle.btn-github{color:#fff;background-color:#2b2b2b;border-color:rgba(0,0,0,0.2)}.btn-github:active,.btn-github.active,.open>.dropdown-toggle.btn-github{background-image:none}.btn-github .badge{color:#444;background-color:#fff}.btn-google{color:#fff;background-color:#dd4b39;border-color:rgba(0,0,0,0.2)}.btn-google:focus,.btn-google.focus{color:#fff;background-color:#c23321;border-color:rgba(0,0,0,0.2)}.btn-google:hover{color:#fff;background-color:#c23321;border-color:rgba(0,0,0,0.2)}.btn-google:active,.btn-google.active,.open>.dropdown-toggle.btn-google{color:#fff;background-color:#c23321;border-color:rgba(0,0,0,0.2)}.btn-google:active,.btn-google.active,.open>.dropdown-toggle.btn-google{background-image:none}.btn-google .badge{color:#dd4b39;background-color:#fff}.btn-instagram{color:#fff;background-color:#3f729b;border-color:rgba(0,0,0,0.2)}.btn-instagram:focus,.btn-instagram.focus{color:#fff;background-color:#305777;border-color:rgba(0,0,0,0.2)}.btn-instagram:hover{color:#fff;background-color:#305777;border-color:rgba(0,0,0,0.2)}.btn-instagram:active,.btn-instagram.active,.open>.dropdown-toggle.btn-instagram{color:#fff;background-color:#305777;border-color:rgba(0,0,0,0.2)}.btn-instagram:active,.btn-instagram.active,.open>.dropdown-toggle.btn-instagram{background-image:none}.btn-instagram .badge{color:#3f729b;background-color:#fff}.btn-linkedin{color:#fff;background-color:#007bb6;border-color:rgba(0,0,0,0.2)}.btn-linkedin:focus,.btn-linkedin.focus{color:#fff;background-color:#005983;border-color:rgba(0,0,0,0.2)}.btn-linkedin:hover{color:#fff;background-color:#005983;border-color:rgba(0,0,0,0.2)}.btn-linkedin:active,.btn-linkedin.active,.open>.dropdown-toggle.btn-linkedin{color:#fff;background-color:#005983;border-color:rgba(0,0,0,0.2)}.btn-linkedin:active,.btn-linkedin.active,.open>.dropdown-toggle.btn-linkedin{background-image:none}.btn-linkedin .badge{color:#007bb6;background-color:#fff}.btn-microsoft{color:#fff;background-color:#2672ec;border-color:rgba(0,0,0,0.2)}.btn-microsoft:focus,.btn-microsoft.focus{color:#fff;background-color:#125acd;border-color:rgba(0,0,0,0.2)}.btn-microsoft:hover{color:#fff;background-color:#125acd;border-color:rgba(0,0,0,0.2)}.btn-microsoft:active,.btn-microsoft.active,.open>.dropdown-toggle.btn-microsoft{color:#fff;background-color:#125acd;border-color:rgba(0,0,0,0.2)}.btn-microsoft:active,.btn-microsoft.active,.open>.dropdown-toggle.btn-microsoft{background-image:none}.btn-microsoft .badge{color:#2672ec;background-color:#fff}.btn-openid{color:#fff;background-color:#f7931e;border-color:rgba(0,0,0,0.2)}.btn-openid:focus,.btn-openid.focus{color:#fff;background-color:#da7908;border-color:rgba(0,0,0,0.2)}.btn-openid:hover{color:#fff;background-color:#da7908;border-color:rgba(0,0,0,0.2)}.btn-openid:active,.btn-openid.active,.open>.dropdown-toggle.btn-openid{color:#fff;background-color:#da7908;border-color:rgba(0,0,0,0.2)}.btn-openid:active,.btn-openid.active,.open>.dropdown-toggle.btn-openid{background-image:none}.btn-openid .badge{color:#f7931e;background-color:#fff}.btn-pinterest{color:#fff;background-color:#cb2027;border-color:rgba(0,0,0,0.2)}.btn-pinterest:focus,.btn-pinterest.focus{color:#fff;background-color:#9f191f;border-color:rgba(0,0,0,0.2)}.btn-pinterest:hover{color:#fff;background-color:#9f191f;border-color:rgba(0,0,0,0.2)}.btn-pinterest:active,.btn-pinterest.active,.open>.dropdown-toggle.btn-pinterest{color:#fff;background-color:#9f191f;border-color:rgba(0,0,0,0.2)}.btn-pinterest:active,.btn-pinterest.active,.open>.dropdown-toggle.btn-pinterest{background-image:none}.btn-pinterest .badge{color:#cb2027;background-color:#fff}.btn-reddit{color:#000;background-color:#eff7ff;border-color:rgba(0,0,0,0.2)}.btn-reddit:focus,.btn-reddit.focus{color:#000;background-color:#bcddff;border-color:rgba(0,0,0,0.2)}.btn-reddit:hover{color:#000;background-color:#bcddff;border-color:rgba(0,0,0,0.2)}.btn-reddit:active,.btn-reddit.active,.open>.dropdown-toggle.btn-reddit{color:#000;background-color:#bcddff;border-color:rgba(0,0,0,0.2)}.btn-reddit:active,.btn-reddit.active,.open>.dropdown-toggle.btn-reddit{background-image:none}.btn-reddit .badge{color:#eff7ff;background-color:#000}.btn-soundcloud{color:#fff;background-color:#f50;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:focus,.btn-soundcloud.focus{color:#fff;background-color:#c40;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:hover{color:#fff;background-color:#c40;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:active,.btn-soundcloud.active,.open>.dropdown-toggle.btn-soundcloud{color:#fff;background-color:#c40;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:active,.btn-soundcloud.active,.open>.dropdown-toggle.btn-soundcloud{background-image:none}.btn-soundcloud .badge{color:#f50;background-color:#fff}.btn-tumblr{color:#fff;background-color:#2c4762;border-color:rgba(0,0,0,0.2)}.btn-tumblr:focus,.btn-tumblr.focus{color:#fff;background-color:#1c2d3f;border-color:rgba(0,0,0,0.2)}.btn-tumblr:hover{color:#fff;background-color:#1c2d3f;border-color:rgba(0,0,0,0.2)}.btn-tumblr:active,.btn-tumblr.active,.open>.dropdown-toggle.btn-tumblr{color:#fff;background-color:#1c2d3f;border-color:rgba(0,0,0,0.2)}.btn-tumblr:active,.btn-tumblr.active,.open>.dropdown-toggle.btn-tumblr{background-image:none}.btn-tumblr .badge{color:#2c4762;background-color:#fff}.btn-twitter{color:#fff;background-color:#55acee;border-color:rgba(0,0,0,0.2)}.btn-twitter:focus,.btn-twitter.focus{color:#fff;background-color:#2795e9;border-color:rgba(0,0,0,0.2)}.btn-twitter:hover{color:#fff;background-color:#2795e9;border-color:rgba(0,0,0,0.2)}.btn-twitter:active,.btn-twitter.active,.open>.dropdown-toggle.btn-twitter{color:#fff;background-color:#2795e9;border-color:rgba(0,0,0,0.2)}.btn-twitter:active,.btn-twitter.active,.open>.dropdown-toggle.btn-twitter{background-image:none}.btn-twitter .badge{color:#55acee;background-color:#fff}.btn-vimeo{color:#fff;background-color:#1ab7ea;border-color:rgba(0,0,0,0.2)}.btn-vimeo:focus,.btn-vimeo.focus{color:#fff;background-color:#1295bf;border-color:rgba(0,0,0,0.2)}.btn-vimeo:hover{color:#fff;background-color:#1295bf;border-color:rgba(0,0,0,0.2)}.btn-vimeo:active,.btn-vimeo.active,.open>.dropdown-toggle.btn-vimeo{color:#fff;background-color:#1295bf;border-color:rgba(0,0,0,0.2)}.btn-vimeo:active,.btn-vimeo.active,.open>.dropdown-toggle.btn-vimeo{background-image:none}.btn-vimeo .badge{color:#1ab7ea;background-color:#fff}.btn-vk{color:#fff;background-color:#587ea3;border-color:rgba(0,0,0,0.2)}.btn-vk:focus,.btn-vk.focus{color:#fff;background-color:#466482;border-color:rgba(0,0,0,0.2)}.btn-vk:hover{color:#fff;background-color:#466482;border-color:rgba(0,0,0,0.2)}.btn-vk:active,.btn-vk.active,.open>.dropdown-toggle.btn-vk{color:#fff;background-color:#466482;border-color:rgba(0,0,0,0.2)}.btn-vk:active,.btn-vk.active,.open>.dropdown-toggle.btn-vk{background-image:none}.btn-vk .badge{color:#587ea3;background-color:#fff}.btn-yahoo{color:#fff;background-color:#720e9e;border-color:rgba(0,0,0,0.2)}.btn-yahoo:focus,.btn-yahoo.focus{color:#fff;background-color:#500a6f;border-color:rgba(0,0,0,0.2)}.btn-yahoo:hover{color:#fff;background-color:#500a6f;border-color:rgba(0,0,0,0.2)}.btn-yahoo:active,.btn-yahoo.active,.open>.dropdown-toggle.btn-yahoo{color:#fff;background-color:#500a6f;border-color:rgba(0,0,0,0.2)}.btn-yahoo:active,.btn-yahoo.active,.open>.dropdown-toggle.btn-yahoo{background-image:none}.btn-yahoo .badge{color:#720e9e;background-color:#fff}.fc-button{background:#f4f4f4;background-image:none;color:#444;border-color:#ddd;border-bottom-color:#ddd}.fc-button:hover,.fc-button:active,.fc-button.hover{background-color:#e9e9e9}.fc-header-title h2{font-size:15px;line-height:1.6em;color:#666;margin-left:10px}.fc-header-right{padding-right:10px}.fc-header-left{padding-left:10px}.fc-widget-header{background:#fafafa}.fc-grid{width:100%;border:0}.fc-widget-header:first-of-type,.fc-widget-content:first-of-type{border-left:0;border-right:0}.fc-widget-header:last-of-type,.fc-widget-content:last-of-type{border-right:0}.fc-toolbar{padding:10px;margin:0}.fc-day-number{font-size:20px;font-weight:300;padding-right:10px}.fc-color-picker{list-style:none;margin:0;padding:0}.fc-color-picker>li{float:left;font-size:30px;margin-right:5px;line-height:30px}.fc-color-picker>li .fa{-webkit-transition:-webkit-transform linear .3s;-moz-transition:-moz-transform linear .3s;-o-transition:-o-transform linear .3s;transition:transform linear .3s}.fc-color-picker>li .fa:hover{-webkit-transform:rotate(30deg);-ms-transform:rotate(30deg);-o-transform:rotate(30deg);transform:rotate(30deg)}#add-new-event{-webkit-transition:all linear .3s;-o-transition:all linear .3s;transition:all linear .3s}.external-event{padding:5px 10px;font-weight:bold;margin-bottom:4px;box-shadow:0 1px 1px rgba(0,0,0,0.1);text-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:3px;cursor:move}.external-event:hover{box-shadow:inset 0 0 90px rgba(0,0,0,0.2)}.select2-container--default.select2-container--focus,.select2-selection.select2-container--focus,.select2-container--default:focus,.select2-selection:focus,.select2-container--default:active,.select2-selection:active{outline:none}.select2-container--default .select2-selection--single,.select2-selection .select2-selection--single{border:1px solid #d2d6de;border-radius:0;padding:6px 12px;height:34px}.select2-container--default.select2-container--open{border-color:#3c8dbc}.select2-dropdown{border:1px solid #d2d6de;border-radius:0}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#3c8dbc;color:white}.select2-results__option{padding:6px 12px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{padding-left:0;padding-right:0;height:auto;margin-top:-4px}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:6px;padding-left:20px}.select2-container--default .select2-selection--single .select2-selection__arrow{height:28px;right:3px}.select2-container--default .select2-selection--single .select2-selection__arrow b{margin-top:0}.select2-dropdown .select2-search__field,.select2-search--inline .select2-search__field{border:1px solid #d2d6de}.select2-dropdown .select2-search__field:focus,.select2-search--inline .select2-search__field:focus{outline:none;border:1px solid #3c8dbc}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option[aria-selected=true],.select2-container--default .select2-results__option[aria-selected=true]:hover{color:#444}.select2-container--default .select2-selection--multiple{border:1px solid #d2d6de;border-radius:0}.select2-container--default .select2-selection--multiple:focus{border-color:#3c8dbc}.select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#d2d6de}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#3c8dbc;border-color:#367fa9;padding:1px 10px;color:#fff}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{margin-right:5px;color:rgba(255,255,255,0.7)}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container .select2-selection--single .select2-selection__rendered{padding-right:10px}.pad{padding:10px}.margin{margin:10px}.margin-bottom{margin-bottom:20px}.margin-bottom-none{margin-bottom:0}.margin-r-5{margin-right:5px}.inline{display:inline}.description-block{display:block;margin:10px 0;text-align:center}.description-block.margin-bottom{margin-bottom:25px}.description-block>.description-header{margin:0;padding:0;font-weight:600;font-size:16px}.description-block>.description-text{text-transform:uppercase}.bg-red,.bg-yellow,.bg-aqua,.bg-blue,.bg-light-blue,.bg-green,.bg-navy,.bg-teal,.bg-olive,.bg-lime,.bg-orange,.bg-fuchsia,.bg-purple,.bg-maroon,.bg-black,.bg-red-active,.bg-yellow-active,.bg-aqua-active,.bg-blue-active,.bg-light-blue-active,.bg-green-active,.bg-navy-active,.bg-teal-active,.bg-olive-active,.bg-lime-active,.bg-orange-active,.bg-fuchsia-active,.bg-purple-active,.bg-maroon-active,.bg-black-active,.callout.callout-danger,.callout.callout-warning,.callout.callout-info,.callout.callout-success,.alert-success,.alert-danger,.alert-error,.alert-warning,.alert-info,.label-danger,.label-info,.label-warning,.label-primary,.label-success,.modal-primary .modal-body,.modal-primary .modal-header,.modal-primary .modal-footer,.modal-warning .modal-body,.modal-warning .modal-header,.modal-warning .modal-footer,.modal-info .modal-body,.modal-info .modal-header,.modal-info .modal-footer,.modal-success .modal-body,.modal-success .modal-header,.modal-success .modal-footer,.modal-danger .modal-body,.modal-danger .modal-header,.modal-danger .modal-footer{color:#fff !important}.bg-gray{color:#000;background-color:#d2d6de !important}.bg-gray-light{background-color:#f7f7f7}.bg-black{background-color:#111 !important}.bg-red,.callout.callout-danger,.alert-danger,.alert-error,.label-danger,.modal-danger .modal-body{background-color:#dd4b39 !important}.bg-yellow,.callout.callout-warning,.alert-warning,.label-warning,.modal-warning .modal-body{background-color:#f39c12 !important}.bg-aqua,.callout.callout-info,.alert-info,.label-info,.modal-info .modal-body{background-color:#00c0ef !important}.bg-blue{background-color:#0073b7 !important}.bg-light-blue,.label-primary,.modal-primary .modal-body{background-color:#3c8dbc !important}.bg-green,.callout.callout-success,.alert-success,.label-success,.modal-success .modal-body{background-color:#00a65a !important}.bg-navy{background-color:#001f3f !important}.bg-teal{background-color:#39cccc !important}.bg-olive{background-color:#3d9970 !important}.bg-lime{background-color:#01ff70 !important}.bg-orange{background-color:#ff851b !important}.bg-fuchsia{background-color:#f012be !important}.bg-purple{background-color:#605ca8 !important}.bg-maroon{background-color:#d81b60 !important}.bg-gray-active{color:#000;background-color:#b5bbc8 !important}.bg-black-active{background-color:#000 !important}.bg-red-active,.modal-danger .modal-header,.modal-danger .modal-footer{background-color:#d33724 !important}.bg-yellow-active,.modal-warning .modal-header,.modal-warning .modal-footer{background-color:#db8b0b !important}.bg-aqua-active,.modal-info .modal-header,.modal-info .modal-footer{background-color:#00a7d0 !important}.bg-blue-active{background-color:#005384 !important}.bg-light-blue-active,.modal-primary .modal-header,.modal-primary .modal-footer{background-color:#357ca5 !important}.bg-green-active,.modal-success .modal-header,.modal-success .modal-footer{background-color:#008d4c !important}.bg-navy-active{background-color:#001a35 !important}.bg-teal-active{background-color:#30bbbb !important}.bg-olive-active{background-color:#368763 !important}.bg-lime-active{background-color:#00e765 !important}.bg-orange-active{background-color:#ff7701 !important}.bg-fuchsia-active{background-color:#db0ead !important}.bg-purple-active{background-color:#555299 !important}.bg-maroon-active{background-color:#ca195a !important}[class^="bg-"].disabled{opacity:.65;filter:alpha(opacity=65)}.text-red{color:#dd4b39 !important}.text-yellow{color:#f39c12 !important}.text-aqua{color:#00c0ef !important}.text-blue{color:#0073b7 !important}.text-black{color:#111 !important}.text-light-blue{color:#3c8dbc !important}.text-green{color:#00a65a !important}.text-gray{color:#d2d6de !important}.text-navy{color:#001f3f !important}.text-teal{color:#39cccc !important}.text-olive{color:#3d9970 !important}.text-lime{color:#01ff70 !important}.text-orange{color:#ff851b !important}.text-fuchsia{color:#f012be !important}.text-purple{color:#605ca8 !important}.text-maroon{color:#d81b60 !important}.link-muted{color:#7a869d}.link-muted:hover,.link-muted:focus{color:#606c84}.link-black{color:#666}.link-black:hover,.link-black:focus{color:#999}.hide{display:none !important}.no-border{border:0 !important}.no-padding{padding:0 !important}.no-margin{margin:0 !important}.no-shadow{box-shadow:none !important}.list-unstyled,.chart-legend,.contacts-list,.users-list,.mailbox-attachments{list-style:none;margin:0;padding:0}.list-group-unbordered>.list-group-item{border-left:0;border-right:0;border-radius:0;padding-left:0;padding-right:0}.flat{border-radius:0 !important}.text-bold,.text-bold.table td,.text-bold.table th{font-weight:700}.text-sm{font-size:12px}.jqstooltip{padding:5px !important;width:auto !important;height:auto !important}.bg-teal-gradient{background:#39cccc !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #39cccc), color-stop(1, #7adddd)) !important;background:-ms-linear-gradient(bottom, #39cccc, #7adddd) !important;background:-moz-linear-gradient(center bottom, #39cccc 0, #7adddd 100%) !important;background:-o-linear-gradient(#7adddd, #39cccc) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#7adddd', endColorstr='#39cccc', GradientType=0) !important;color:#fff}.bg-light-blue-gradient{background:#3c8dbc !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #3c8dbc), color-stop(1, #67a8ce)) !important;background:-ms-linear-gradient(bottom, #3c8dbc, #67a8ce) !important;background:-moz-linear-gradient(center bottom, #3c8dbc 0, #67a8ce 100%) !important;background:-o-linear-gradient(#67a8ce, #3c8dbc) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#67a8ce', endColorstr='#3c8dbc', GradientType=0) !important;color:#fff}.bg-blue-gradient{background:#0073b7 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #0073b7), color-stop(1, #0089db)) !important;background:-ms-linear-gradient(bottom, #0073b7, #0089db) !important;background:-moz-linear-gradient(center bottom, #0073b7 0, #0089db 100%) !important;background:-o-linear-gradient(#0089db, #0073b7) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0089db', endColorstr='#0073b7', GradientType=0) !important;color:#fff}.bg-aqua-gradient{background:#00c0ef !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #00c0ef), color-stop(1, #14d1ff)) !important;background:-ms-linear-gradient(bottom, #00c0ef, #14d1ff) !important;background:-moz-linear-gradient(center bottom, #00c0ef 0, #14d1ff 100%) !important;background:-o-linear-gradient(#14d1ff, #00c0ef) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#14d1ff', endColorstr='#00c0ef', GradientType=0) !important;color:#fff}.bg-yellow-gradient{background:#f39c12 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #f39c12), color-stop(1, #f7bc60)) !important;background:-ms-linear-gradient(bottom, #f39c12, #f7bc60) !important;background:-moz-linear-gradient(center bottom, #f39c12 0, #f7bc60 100%) !important;background:-o-linear-gradient(#f7bc60, #f39c12) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7bc60', endColorstr='#f39c12', GradientType=0) !important;color:#fff}.bg-purple-gradient{background:#605ca8 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #605ca8), color-stop(1, #9491c4)) !important;background:-ms-linear-gradient(bottom, #605ca8, #9491c4) !important;background:-moz-linear-gradient(center bottom, #605ca8 0, #9491c4 100%) !important;background:-o-linear-gradient(#9491c4, #605ca8) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#9491c4', endColorstr='#605ca8', GradientType=0) !important;color:#fff}.bg-green-gradient{background:#00a65a !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #00a65a), color-stop(1, #00ca6d)) !important;background:-ms-linear-gradient(bottom, #00a65a, #00ca6d) !important;background:-moz-linear-gradient(center bottom, #00a65a 0, #00ca6d 100%) !important;background:-o-linear-gradient(#00ca6d, #00a65a) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ca6d', endColorstr='#00a65a', GradientType=0) !important;color:#fff}.bg-red-gradient{background:#dd4b39 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #dd4b39), color-stop(1, #e47365)) !important;background:-ms-linear-gradient(bottom, #dd4b39, #e47365) !important;background:-moz-linear-gradient(center bottom, #dd4b39 0, #e47365 100%) !important;background:-o-linear-gradient(#e47365, #dd4b39) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e47365', endColorstr='#dd4b39', GradientType=0) !important;color:#fff}.bg-black-gradient{background:#111 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #111), color-stop(1, #2b2b2b)) !important;background:-ms-linear-gradient(bottom, #111, #2b2b2b) !important;background:-moz-linear-gradient(center bottom, #111 0, #2b2b2b 100%) !important;background:-o-linear-gradient(#2b2b2b, #111) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#2b2b2b', endColorstr='#111111', GradientType=0) !important;color:#fff}.bg-maroon-gradient{background:#d81b60 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #d81b60), color-stop(1, #e73f7c)) !important;background:-ms-linear-gradient(bottom, #d81b60, #e73f7c) !important;background:-moz-linear-gradient(center bottom, #d81b60 0, #e73f7c 100%) !important;background:-o-linear-gradient(#e73f7c, #d81b60) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e73f7c', endColorstr='#d81b60', GradientType=0) !important;color:#fff}.description-block .description-icon{font-size:16px}.no-pad-top{padding-top:0}.position-static{position:static !important}.list-header{font-size:15px;padding:10px 4px;font-weight:bold;color:#666}.list-seperator{height:1px;background:#f4f4f4;margin:15px 0 9px 0}.list-link>a{padding:4px;color:#777}.list-link>a:hover{color:#222}.font-light{font-weight:300}.user-block:before,.user-block:after{content:" ";display:table}.user-block:after{clear:both}.user-block img{width:40px;height:40px;float:left}.user-block .username,.user-block .description,.user-block .comment{display:block;margin-left:50px}.user-block .username{font-size:16px;font-weight:600}.user-block .description{color:#999;font-size:13px}.user-block.user-block-sm .username,.user-block.user-block-sm .description,.user-block.user-block-sm .comment{margin-left:40px}.user-block.user-block-sm .username{font-size:14px}.img-sm,.img-md,.img-lg,.box-comments .box-comment img,.user-block.user-block-sm img{float:left}.img-sm,.box-comments .box-comment img,.user-block.user-block-sm img{width:30px !important;height:30px !important}.img-sm+.img-push{margin-left:40px}.img-md{width:60px;height:60px}.img-md+.img-push{margin-left:70px}.img-lg{width:100px;height:100px}.img-lg+.img-push{margin-left:110px}.img-bordered{border:3px solid #d2d6de;padding:3px}.img-bordered-sm{border:2px solid #d2d6de;padding:2px}.attachment-block{border:1px solid #f4f4f4;padding:5px;margin-bottom:10px;background:#f7f7f7}.attachment-block .attachment-img{max-width:100px;max-height:100px;height:auto;float:left}.attachment-block .attachment-pushed{margin-left:110px}.attachment-block .attachment-heading{margin:0}.attachment-block .attachment-text{color:#555}.connectedSortable{min-height:100px}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sort-highlight{background:#f4f4f4;border:1px dashed #ddd;margin-bottom:10px}.full-opacity-hover{opacity:.65;filter:alpha(opacity=65)}.full-opacity-hover:hover{opacity:1;filter:alpha(opacity=100)}.chart{position:relative;overflow:hidden;width:100%}.chart svg,.chart canvas{width:100% !important}@media print{.no-print,.main-sidebar,.left-side,.main-header,.content-header{display:none !important}.content-wrapper,.right-side,.main-footer{margin-left:0 !important;min-height:0 !important;-webkit-transform:translate(0, 0) !important;-ms-transform:translate(0, 0) !important;-o-transform:translate(0, 0) !important;transform:translate(0, 0) !important}.fixed .content-wrapper,.fixed .right-side{padding-top:0 !important}.invoice{width:100%;border:0;margin:0;padding:0}.invoice-col{float:left;width:33.3333333%}.table-responsive{overflow:auto}.table-responsive>.table tr th,.table-responsive>.table tr td{white-space:normal !important}} \ No newline at end of file diff --git a/src/assets/styles/skin-green.min.css b/src/assets/styles/skin-green.min.css new file mode 100644 index 0000000..8f885ed --- /dev/null +++ b/src/assets/styles/skin-green.min.css @@ -0,0 +1 @@ +.skin-green .main-header .navbar{background-color:#00a65a}.skin-green .main-header .navbar .nav>li>a{color:#fff}.skin-green .main-header .navbar .nav>li>a:hover,.skin-green .main-header .navbar .nav>li>a:active,.skin-green .main-header .navbar .nav>li>a:focus,.skin-green .main-header .navbar .nav .open>a,.skin-green .main-header .navbar .nav .open>a:hover,.skin-green .main-header .navbar .nav .open>a:focus,.skin-green .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-green .main-header .navbar .sidebar-toggle{color:#fff}.skin-green .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-green .main-header .navbar .sidebar-toggle{color:#fff}.skin-green .main-header .navbar .sidebar-toggle:hover{background-color:#008d4c}@media (max-width:767px){.skin-green .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-green .main-header .navbar .dropdown-menu li a{color:#fff}.skin-green .main-header .navbar .dropdown-menu li a:hover{background:#008d4c}}.skin-green .main-header .logo{background-color:#008d4c;color:#fff;border-bottom:0 solid transparent}.skin-green .main-header .logo:hover{background-color:#008749}.skin-green .main-header li.user-header{background-color:#00a65a}.skin-green .content-header{background:transparent}.skin-green .wrapper,.skin-green .main-sidebar,.skin-green .left-side{background-color:#222d32}.skin-green .user-panel>.info,.skin-green .user-panel>.info>a{color:#fff}.skin-green .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-green .sidebar-menu>li>a{border-left:3px solid transparent}.skin-green .sidebar-menu>li:hover>a,.skin-green .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#00a65a}.skin-green .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-green .sidebar a{color:#b8c7ce}.skin-green .sidebar a:hover{text-decoration:none}.skin-green .treeview-menu>li>a{color:#8aa4af}.skin-green .treeview-menu>li.active>a,.skin-green .treeview-menu>li>a:hover{color:#fff}.skin-green .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-green .sidebar-form input[type="text"],.skin-green .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-green .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-green .sidebar-form input[type="text"]:focus,.skin-green .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-green .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-green .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0} \ No newline at end of file diff --git a/src/extra/dashboard.html b/src/extra/dashboard.html new file mode 100644 index 0000000..fcb1a6a --- /dev/null +++ b/src/extra/dashboard.html @@ -0,0 +1,76 @@ + + + + +
\ No newline at end of file diff --git a/src/extra/info.txt b/src/extra/info.txt new file mode 100644 index 0000000..ac0a039 --- /dev/null +++ b/src/extra/info.txt @@ -0,0 +1,2 @@ +This is a folder where we keep unused examples for html files and templates. +Keeping the file name same is important so we know where it belongs. \ No newline at end of file diff --git a/src/extra/navbar.html b/src/extra/navbar.html new file mode 100644 index 0000000..8662f5a --- /dev/null +++ b/src/extra/navbar.html @@ -0,0 +1,104 @@ + + \ No newline at end of file diff --git a/src/favicon.ico b/src/favicon.ico new file mode 100644 index 0000000..303266b Binary files /dev/null and b/src/favicon.ico differ diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..3211f29 --- /dev/null +++ b/src/index.html @@ -0,0 +1,50 @@ + + + Loading... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/manual_typings/jasmine.d.ts b/src/manual_typings/jasmine.d.ts new file mode 100644 index 0000000..92a45d7 --- /dev/null +++ b/src/manual_typings/jasmine.d.ts @@ -0,0 +1,5 @@ +declare module jasmine { + interface Matchers { + toContainText(text: string): boolean; + } +} diff --git a/src/systemjs.conf.js b/src/systemjs.conf.js new file mode 100644 index 0000000..c0d5add --- /dev/null +++ b/src/systemjs.conf.js @@ -0,0 +1,101 @@ +/* + * This config is only used during development and build phase only + * It will not be available on production + * + */ + +(function(global) { + // ENV + global.ENV = global.ENV || 'development'; + + // map tells the System loader where to look for things + var map = { + 'app': 'src/tmp/app', + 'test': 'src/tmp/test' + }; + + // packages tells the System loader how to load when no filename and/or no extension + var packages = { + 'app': { + defaultExtension: 'js' + }, + 'test': { + defaultExtension: 'js' + }, + 'rxjs': { + defaultExtension: 'js' + }, + 'angular2-jwt': { + main: 'angular2-jwt.js', + defaultExtension: 'js' + }, + 'angular2-letter-avatar': { + defaultExtension: 'js' + }, + 'chart.js': { + main: 'dist/Chart.js', + defaultExtension: 'js' + }, + 'ng2-charts': { + main: 'ng2-charts.js', + defaultExtension: 'js' + } + }; + + // List npm packages here + var npmPackages = [ + '@angular', + 'rxjs', + 'lodash', + 'angular2-jwt', + 'angular2-letter-avatar', + 'chart.js', + 'ng2-charts' + ]; + + // Add package entries for packages that expose barrels using index.js + var packageNames = [ + // App barrels + 'app/shared', + // 3rd party barrels + 'lodash' + ]; + + // Add package entries for angular packages + var ngPackageNames = [ + 'common', + 'compiler', + 'core', + 'forms', + 'http', + 'platform-browser', + 'platform-browser-dynamic', + 'router' + ]; + + npmPackages.forEach(function (pkgName) { + map[pkgName] = 'node_modules/' + pkgName; + }); + + packageNames.forEach(function(pkgName) { + packages[pkgName] = { main: 'index.js', defaultExtension: 'js' }; + }); + + ngPackageNames.forEach(function(pkgName) { + map['@angular/' + pkgName] = 'node_modules/@angular/' + pkgName + + '/bundles/' + pkgName + '.umd.js'; + map['@angular/' + pkgName+'/testing'] = 'node_modules/@angular/' + pkgName + + '/bundles/' + pkgName + '-testing.umd.js'; + }); + + var config = { + map: map, + packages: packages + }; + + // filterSystemConfig - index.html's chance to modify config before we register it. + if (global.filterSystemConfig) { global.filterSystemConfig(config); } + + System.config(config); + +})(this); diff --git a/src/test/test-helpers/global/env.js b/src/test/test-helpers/global/env.js new file mode 100644 index 0000000..8d54e1c --- /dev/null +++ b/src/test/test-helpers/global/env.js @@ -0,0 +1,5 @@ +// This lets systemjs.conf.js knows how to load the module during testing +(function (global) { + global.ENV = 'testing'; +})(this); +//# sourceMappingURL=env.js.map \ No newline at end of file diff --git a/src/test/test-helpers/global/env.js.map b/src/test/test-helpers/global/env.js.map new file mode 100644 index 0000000..4ff5cf8 --- /dev/null +++ b/src/test/test-helpers/global/env.js.map @@ -0,0 +1 @@ +{"version":3,"file":"env.js","sourceRoot":"","sources":["env.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,CAAC,UAAC,MAAM;IACJ,MAAM,CAAC,GAAG,GAAG,SAAS,CAAC;AAC3B,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC"} \ No newline at end of file diff --git a/src/test/test-helpers/global/env.ts b/src/test/test-helpers/global/env.ts new file mode 100644 index 0000000..c469895 --- /dev/null +++ b/src/test/test-helpers/global/env.ts @@ -0,0 +1,4 @@ +// This lets systemjs.conf.js knows how to load the module during testing +((global) => { + global.ENV = 'testing'; +})(this); diff --git a/src/test/test-helpers/global/matchers.js b/src/test/test-helpers/global/matchers.js new file mode 100644 index 0000000..40e0204 --- /dev/null +++ b/src/test/test-helpers/global/matchers.js @@ -0,0 +1,16 @@ +beforeEach(function () { + jasmine.addMatchers({ + toContainText: function () { + return { + compare: function (actual, expectedText) { + var actualText = actual.textContent; + return { + pass: actualText.indexOf(expectedText) > -1, + get message() { return 'Expected ' + actualText + ' to contain ' + expectedText; } + }; + } + }; + } + }); +}); +//# sourceMappingURL=matchers.js.map \ No newline at end of file diff --git a/src/test/test-helpers/global/matchers.js.map b/src/test/test-helpers/global/matchers.js.map new file mode 100644 index 0000000..e439b68 --- /dev/null +++ b/src/test/test-helpers/global/matchers.js.map @@ -0,0 +1 @@ +{"version":3,"file":"matchers.js","sourceRoot":"","sources":["matchers.ts"],"names":[],"mappings":"AAAA,UAAU,CAAC;IACP,OAAO,CAAC,WAAW,CAAC;QAChB,aAAa,EAAE;YACX,MAAM,CAAC;gBACH,OAAO,EAAE,UAAC,MAAM,EAAE,YAAY;oBAC1B,IAAI,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC;oBACpC,MAAM,CAAC;wBACH,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;wBAC3C,IAAI,OAAO,KAAK,MAAM,CAAC,WAAW,GAAG,UAAU,GAAG,cAAc,GAAG,YAAY,CAAC,CAAC,CAAC;qBACrF,CAAC;gBACN,CAAC;aACJ,CAAC;QACN,CAAC;KACJ,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/src/test/test-helpers/global/matchers.ts b/src/test/test-helpers/global/matchers.ts new file mode 100644 index 0000000..eb40932 --- /dev/null +++ b/src/test/test-helpers/global/matchers.ts @@ -0,0 +1,15 @@ +beforeEach(() => { + jasmine.addMatchers({ + toContainText: () => { + return { + compare: (actual, expectedText) => { + let actualText = actual.textContent; + return { + pass: actualText.indexOf(expectedText) > -1, + get message() { return 'Expected ' + actualText + ' to contain ' + expectedText; } + }; + } + }; + } + }); +}); diff --git a/src/test/test-helpers/setup.js b/src/test/test-helpers/setup.js new file mode 100644 index 0000000..22c4edc --- /dev/null +++ b/src/test/test-helpers/setup.js @@ -0,0 +1,5 @@ +"use strict"; +var testing_1 = require("@angular/core/testing"); +var testing_2 = require("@angular/platform-browser-dynamic/testing"); +testing_1.TestBed.initTestEnvironment(testing_2.BrowserDynamicTestingModule, testing_2.platformBrowserDynamicTesting()); +//# sourceMappingURL=setup.js.map \ No newline at end of file diff --git a/src/test/test-helpers/setup.js.map b/src/test/test-helpers/setup.js.map new file mode 100644 index 0000000..3a23157 --- /dev/null +++ b/src/test/test-helpers/setup.js.map @@ -0,0 +1 @@ +{"version":3,"file":"setup.js","sourceRoot":"","sources":["setup.ts"],"names":[],"mappings":";AAAA,iDAAgD;AAChD,qEAGmD;AAEnD,iBAAO,CAAC,mBAAmB,CACvB,qCAA2B,EAC3B,uCAA6B,EAAE,CAClC,CAAC"} \ No newline at end of file diff --git a/src/test/test-helpers/setup.ts b/src/test/test-helpers/setup.ts new file mode 100644 index 0000000..2ad01d4 --- /dev/null +++ b/src/test/test-helpers/setup.ts @@ -0,0 +1,10 @@ +import { TestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +TestBed.initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); diff --git a/src/tmp/app/app.component.js b/src/tmp/app/app.component.js new file mode 100644 index 0000000..ec2d6c9 --- /dev/null +++ b/src/tmp/app/app.component.js @@ -0,0 +1,32 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var core_1 = require("@angular/core"); +var platform_browser_1 = require("@angular/platform-browser"); +var shared_1 = require("./shared"); +var AppComponent = (function () { + function AppComponent(titleService) { + this.titleService = titleService; + this.appBrand = shared_1.CONSTANTS.MAIN.APP.BRAND; + this.titleService.setTitle(this.appBrand); + } + return AppComponent; +}()); +AppComponent = __decorate([ + core_1.Component({ + moduleId: module.id, + selector: 'as-main-app', + templateUrl: 'app.html' + }), + __metadata("design:paramtypes", [platform_browser_1.Title]) +], AppComponent); +exports.AppComponent = AppComponent; + +//# sourceMappingURL=app.component.js.map diff --git a/src/tmp/app/app.component.js.map b/src/tmp/app/app.component.js.map new file mode 100644 index 0000000..647486a --- /dev/null +++ b/src/tmp/app/app.component.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/app.component.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,sCAA0C;AAC1C,8DAAkD;AAElD,mCAAqC;AAOrC,IAAa,YAAY;IAGrB,sBAAoB,YAAmB;QAAnB,iBAAY,GAAZ,YAAY,CAAO;QACnC,IAAI,CAAC,QAAQ,GAAG,kBAAS,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;QACzC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IACL,mBAAC;AAAD,CAPA,AAOC,IAAA;AAPY,YAAY;IALxB,gBAAS,CAAC;QACP,QAAQ,EAAE,MAAM,CAAC,EAAE;QACnB,QAAQ,EAAE,aAAa;QACvB,WAAW,EAAE,UAAU;KAC1B,CAAC;qCAIoC,wBAAK;GAH9B,YAAY,CAOxB;AAPY,oCAAY","file":"app.component.js","sourcesContent":["import { Component } from '@angular/core';\r\nimport { Title } from '@angular/platform-browser';\r\n\r\nimport { CONSTANTS } from './shared';\r\n\r\n@Component({\r\n moduleId: module.id,\r\n selector: 'as-main-app',\r\n templateUrl: 'app.html'\r\n})\r\nexport class AppComponent {\r\n public appBrand: string;\r\n\r\n constructor(private titleService: Title) {\r\n this.appBrand = CONSTANTS.MAIN.APP.BRAND;\r\n this.titleService.setTitle(this.appBrand);\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/app.html b/src/tmp/app/app.html new file mode 100644 index 0000000..353a45a --- /dev/null +++ b/src/tmp/app/app.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/src/tmp/app/app.module.js b/src/tmp/app/app.module.js new file mode 100644 index 0000000..a0c4e85 --- /dev/null +++ b/src/tmp/app/app.module.js @@ -0,0 +1,39 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var core_1 = require("@angular/core"); +var platform_browser_1 = require("@angular/platform-browser"); +var http_1 = require("@angular/http"); +var app_providers_1 = require("./app.providers"); +var app_component_1 = require("./app.component"); +var app_routing_1 = require("./app.routing"); +var login_module_1 = require("./login/login.module"); +var dashboard_module_1 = require("./dashboard/dashboard.module"); +var AppModule = (function () { + function AppModule() { + } + return AppModule; +}()); +AppModule = __decorate([ + core_1.NgModule({ + declarations: [ + app_component_1.AppComponent, + ], + imports: [ + platform_browser_1.BrowserModule, + http_1.HttpModule, + dashboard_module_1.DashboardModule, + login_module_1.LoginModule, + app_routing_1.routing + ], + providers: [app_providers_1.APP_PROVIDERS, app_routing_1.appRoutingProviders], + bootstrap: [app_component_1.AppComponent] + }) +], AppModule); +exports.AppModule = AppModule; + +//# sourceMappingURL=app.module.js.map diff --git a/src/tmp/app/app.module.js.map b/src/tmp/app/app.module.js.map new file mode 100644 index 0000000..75f9718 --- /dev/null +++ b/src/tmp/app/app.module.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/app.module.ts"],"names":[],"mappings":";;;;;;;AAAA,sCAAyC;AACzC,8DAA0D;AAC1D,sCAA2C;AAE3C,iDAAgD;AAChD,iDAA+C;AAC/C,6CAA6D;AAC7D,qDAAmD;AACnD,iEAA+D;AAgB/D,IAAa,SAAS;IAAtB;IAAyB,CAAC;IAAD,gBAAC;AAAD,CAAzB,AAA0B,IAAA;AAAb,SAAS;IAdrB,eAAQ,CAAC;QACN,YAAY,EAAE;YACV,4BAAY;SACf;QACD,OAAO,EAAE;YACL,gCAAa;YACb,iBAAU;YACV,kCAAe;YACf,0BAAW;YACX,qBAAO;SACV;QACD,SAAS,EAAE,CAAC,6BAAa,EAAE,iCAAmB,CAAC;QAC/C,SAAS,EAAE,CAAC,4BAAY,CAAC;KAC5B,CAAC;GACW,SAAS,CAAI;AAAb,8BAAS","file":"app.module.js","sourcesContent":["import { NgModule } from '@angular/core';\r\nimport { BrowserModule } from '@angular/platform-browser';\r\nimport { HttpModule } from '@angular/http';\r\n\r\nimport { APP_PROVIDERS } from './app.providers';\r\nimport { AppComponent } from './app.component';\r\nimport { appRoutingProviders, routing } from './app.routing';\r\nimport { LoginModule } from './login/login.module';\r\nimport { DashboardModule } from './dashboard/dashboard.module';\r\n\r\n@NgModule({\r\n declarations: [\r\n AppComponent,\r\n ],\r\n imports: [\r\n BrowserModule,\r\n HttpModule,\r\n DashboardModule,\r\n LoginModule,\r\n routing\r\n ],\r\n providers: [APP_PROVIDERS, appRoutingProviders],\r\n bootstrap: [AppComponent]\r\n})\r\nexport class AppModule { }\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/app.providers.js b/src/tmp/app/app.providers.js new file mode 100644 index 0000000..3073d3d --- /dev/null +++ b/src/tmp/app/app.providers.js @@ -0,0 +1,8 @@ +"use strict"; +var shared_1 = require("./shared"); +var auth_guard_1 = require("./auth/auth.guard"); +exports.APP_PROVIDERS = [ + auth_guard_1.AuthGuard +].concat(shared_1.LOCAL_STORAGE_PROVIDERS, shared_1.LOGGER_PROVIDERS); + +//# sourceMappingURL=app.providers.js.map diff --git a/src/tmp/app/app.providers.js.map b/src/tmp/app/app.providers.js.map new file mode 100644 index 0000000..4756231 --- /dev/null +++ b/src/tmp/app/app.providers.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/app.providers.ts"],"names":[],"mappings":";AAAA,mCAAqE;AACrE,gDAA8C;AAEjC,QAAA,aAAa;IACtB,sBAAS;SACN,gCAAuB,EACvB,yBAAgB,EACrB","file":"app.providers.js","sourcesContent":["import { LOCAL_STORAGE_PROVIDERS, LOGGER_PROVIDERS } from './shared';\r\nimport { AuthGuard } from './auth/auth.guard';\r\n\r\nexport const APP_PROVIDERS = [\r\n AuthGuard,\r\n ...LOCAL_STORAGE_PROVIDERS,\r\n ...LOGGER_PROVIDERS\r\n];\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/app.routing.js b/src/tmp/app/app.routing.js new file mode 100644 index 0000000..75c5e8d --- /dev/null +++ b/src/tmp/app/app.routing.js @@ -0,0 +1,20 @@ +"use strict"; +var router_1 = require("@angular/router"); +var index_1 = require("./login/index"); +var index_2 = require("./dashboard/index"); +var auth_guard_1 = require("./auth/auth.guard"); +var securedRoutes = index_2.DashboardRoutes.slice(); +for (var _i = 0, securedRoutes_1 = securedRoutes; _i < securedRoutes_1.length; _i++) { + var route = securedRoutes_1[_i]; + if (route) { + route.canActivate = [auth_guard_1.AuthGuard]; + } +} +var publicRoutes = [ + index_1.LoginRoute +]; +var appRoutes = publicRoutes.concat(securedRoutes); +exports.appRoutingProviders = []; +exports.routing = router_1.RouterModule.forRoot(appRoutes); + +//# sourceMappingURL=app.routing.js.map diff --git a/src/tmp/app/app.routing.js.map b/src/tmp/app/app.routing.js.map new file mode 100644 index 0000000..d12a6b2 --- /dev/null +++ b/src/tmp/app/app.routing.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/app.routing.ts"],"names":[],"mappings":";AAAA,0CAAuD;AAEvD,uCAA2C;AAC3C,2CAAoD;AAEpD,gDAA8C;AAE9C,IAAM,aAAa,GACZ,uBAAe,QACrB,CAAC;AAEF,GAAG,CAAC,CAAc,UAAa,EAAb,+BAAa,EAAb,2BAAa,EAAb,IAAa;IAA1B,IAAI,KAAK,sBAAA;IACV,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACR,KAAK,CAAC,WAAW,GAAG,CAAC,sBAAS,CAAC,CAAC;IACpC,CAAC;CACJ;AAED,IAAM,YAAY,GAAW;IACzB,kBAAU;CACb,CAAC;AAEF,IAAM,SAAS,GACR,YAAY,QACZ,aAAa,CACnB,CAAC;AAEW,QAAA,mBAAmB,GAAU,EAEzC,CAAC;AAEW,QAAA,OAAO,GAAG,qBAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC","file":"app.routing.js","sourcesContent":["import { Routes, RouterModule } from '@angular/router';\r\n\r\nimport { LoginRoute } from './login/index';\r\nimport { DashboardRoutes } from './dashboard/index';\r\n\r\nimport { AuthGuard } from './auth/auth.guard';\r\n\r\nconst securedRoutes: Routes = [\r\n ...DashboardRoutes\r\n];\r\n\r\nfor (let route of securedRoutes) {\r\n if (route) {\r\n route.canActivate = [AuthGuard];\r\n }\r\n}\r\n\r\nconst publicRoutes: Routes = [\r\n LoginRoute\r\n];\r\n\r\nconst appRoutes: Routes = [\r\n ...publicRoutes,\r\n ...securedRoutes\r\n];\r\n\r\nexport const appRoutingProviders: any[] = [\r\n\r\n];\r\n\r\nexport const routing = RouterModule.forRoot(appRoutes);\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/auth/auth.constants.js b/src/tmp/app/auth/auth.constants.js new file mode 100644 index 0000000..9266ca1 --- /dev/null +++ b/src/tmp/app/auth/auth.constants.js @@ -0,0 +1,11 @@ +"use strict"; +var AuthConstants = (function () { + function AuthConstants() { + } + return AuthConstants; +}()); +AuthConstants.AUTH_TOKEN_KEY = 'currentUser'; +exports.AuthConstants = AuthConstants; +; + +//# sourceMappingURL=auth.constants.js.map diff --git a/src/tmp/app/auth/auth.constants.js.map b/src/tmp/app/auth/auth.constants.js.map new file mode 100644 index 0000000..94806db --- /dev/null +++ b/src/tmp/app/auth/auth.constants.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/auth/auth.constants.ts"],"names":[],"mappings":";AAAA;IAAA;IAEA,CAAC;IAAD,oBAAC;AAAD,CAFA,AAEC;AADiB,4BAAc,GAAW,aAAa,CAAC;AAD5C,sCAAa;AAEzB,CAAC","file":"auth.constants.js","sourcesContent":["export class AuthConstants {\r\n public static AUTH_TOKEN_KEY: string = 'currentUser';\r\n};\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/auth/auth.guard.js b/src/tmp/app/auth/auth.guard.js new file mode 100644 index 0000000..3827aba --- /dev/null +++ b/src/tmp/app/auth/auth.guard.js @@ -0,0 +1,45 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var core_1 = require("@angular/core"); +var router_1 = require("@angular/router"); +var auth_constants_1 = require("./auth.constants"); +var AuthGuard = (function () { + /** + * AuthGuard should block components from loading if authentication denies so + */ + function AuthGuard(router) { + this.router = router; + } + Object.defineProperty(AuthGuard.prototype, "loginRoute", { + get: function () { + return this._loginRoute; + }, + set: function (v) { + this._loginRoute = v; + }, + enumerable: true, + configurable: true + }); + AuthGuard.prototype.canActivate = function () { + if (localStorage.getItem(auth_constants_1.AuthConstants.AUTH_TOKEN_KEY)) { + return true; + } + this.router.navigate([this.loginRoute || '/login']); + }; + return AuthGuard; +}()); +AuthGuard = __decorate([ + core_1.Injectable(), + __metadata("design:paramtypes", [router_1.Router]) +], AuthGuard); +exports.AuthGuard = AuthGuard; + +//# sourceMappingURL=auth.guard.js.map diff --git a/src/tmp/app/auth/auth.guard.js.map b/src/tmp/app/auth/auth.guard.js.map new file mode 100644 index 0000000..1b97b79 --- /dev/null +++ b/src/tmp/app/auth/auth.guard.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/auth/auth.guard.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,sCAA2C;AAC3C,0CAAsD;AACtD,mDAAiD;AAGjD,IAAa,SAAS;IAUlB;;OAEG;IACH,mBAAoB,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;IAAI,CAAC;IAVvC,sBAAW,iCAAU;aAArB;YACI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;QAC5B,CAAC;aACD,UAAsB,CAAS;YAC3B,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACzB,CAAC;;;OAHA;IAUD,+BAAW,GAAX;QACI,EAAE,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,8BAAa,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC;QAChB,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,IAAI,QAAQ,CAAC,CAAC,CAAC;IACxD,CAAC;IACL,gBAAC;AAAD,CArBA,AAqBC,IAAA;AArBY,SAAS;IADrB,iBAAU,EAAE;qCAcmB,eAAM;GAbzB,SAAS,CAqBrB;AArBY,8BAAS","file":"auth.guard.js","sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { Router, CanActivate } from '@angular/router';\r\nimport { AuthConstants } from './auth.constants';\r\n\r\n@Injectable()\r\nexport class AuthGuard implements CanActivate {\r\n\r\n private _loginRoute: string;\r\n public get loginRoute(): string {\r\n return this._loginRoute;\r\n }\r\n public set loginRoute(v: string) {\r\n this._loginRoute = v;\r\n }\r\n\r\n /**\r\n * AuthGuard should block components from loading if authentication denies so\r\n */\r\n constructor(private router: Router) { }\r\n\r\n canActivate() {\r\n if (localStorage.getItem(AuthConstants.AUTH_TOKEN_KEY)) {\r\n return true;\r\n }\r\n this.router.navigate([this.loginRoute || '/login']);\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/auth/auth.module.js b/src/tmp/app/auth/auth.module.js new file mode 100644 index 0000000..99db9e6 --- /dev/null +++ b/src/tmp/app/auth/auth.module.js @@ -0,0 +1,28 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var core_1 = require("@angular/core"); +var index_1 = require("./index"); +var angular2_jwt_1 = require("angular2-jwt"); +var AuthModule = (function () { + function AuthModule() { + } + return AuthModule; +}()); +AuthModule = __decorate([ + core_1.NgModule({ + providers: [ + index_1.AuthService, + index_1.AuthConstants, + index_1.AuthGuard, + angular2_jwt_1.JwtHelper + ] + }) +], AuthModule); +exports.AuthModule = AuthModule; + +//# sourceMappingURL=auth.module.js.map diff --git a/src/tmp/app/auth/auth.module.js.map b/src/tmp/app/auth/auth.module.js.map new file mode 100644 index 0000000..746c910 --- /dev/null +++ b/src/tmp/app/auth/auth.module.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/auth/auth.module.ts"],"names":[],"mappings":";;;;;;;AAAA,sCAAyC;AACzC,iCAA+D;AAC/D,6CAAyC;AAUzC,IAAa,UAAU;IAAvB;IAAyB,CAAC;IAAD,iBAAC;AAAD,CAAzB,AAA0B,IAAA;AAAb,UAAU;IARtB,eAAQ,CAAC;QACN,SAAS,EAAE;YACP,mBAAW;YACX,qBAAa;YACb,iBAAS;YACT,wBAAS;SACZ;KACJ,CAAC;GACW,UAAU,CAAG;AAAb,gCAAU","file":"auth.module.js","sourcesContent":["import { NgModule } from '@angular/core';\r\nimport { AuthConstants, AuthGuard, AuthService} from './index';\r\nimport { JwtHelper } from 'angular2-jwt';\r\n\r\n@NgModule({\r\n providers: [\r\n AuthService,\r\n AuthConstants,\r\n AuthGuard,\r\n JwtHelper\r\n ]\r\n})\r\nexport class AuthModule {}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/auth/auth.service.js b/src/tmp/app/auth/auth.service.js new file mode 100644 index 0000000..b375eba --- /dev/null +++ b/src/tmp/app/auth/auth.service.js @@ -0,0 +1,97 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var core_1 = require("@angular/core"); +var http_1 = require("@angular/http"); +var router_1 = require("@angular/router"); +var Observable_1 = require("rxjs/Observable"); +require("rxjs/add/observable/throw"); +require("rxjs/add/operator/map"); +require("rxjs/add/operator/catch"); +var auth_constants_1 = require("./auth.constants"); +var angular2_jwt_1 = require("angular2-jwt"); +var index_1 = require("../shared/index"); +var AuthService = (function () { + /** + * Authentication service for enterprise dashboard + */ + function AuthService(http, localStorage, jwtHelper, router, loggerService) { + this.http = http; + this.localStorage = localStorage; + this.jwtHelper = jwtHelper; + this.router = router; + this.loggerService = loggerService; + } + AuthService.prototype.login = function (username, password) { + var _this = this; + var headers = new http_1.Headers(); + var tokenUrl = index_1.CONSTANTS.ENV.AUTH_BASE + 'auth/token'; // TODO: Need to definitely load from settings + var urlEncodedParam = 'grant_type=' + 'password' + + '&username=' + username + + '&password=' + password + + '&client_id=' + 'GoFetchDevWebApp'; // TODO: We need to load this from either environment or settings somewhere. + headers.append('Content-Type', 'application/x-www-form-urlencoded'); + return this.http.post(tokenUrl, urlEncodedParam, { headers: headers }) + .map(function (res) { + if (res.status < 200 || res.status >= 300) { + throw new Error('Response status: ' + res.status); + } + return _this._extractAndSaveAuthData(res); + }) + .catch(function (error) { + return _this._extractAuthError(error); + }); + }; + AuthService.prototype.logout = function () { + localStorage.removeItem(auth_constants_1.AuthConstants.AUTH_TOKEN_KEY); + /** + * INFO: We don't know at this point what would be the login route + * of this app. Since we are guarding it by canActivate we can safely + * expect that navigating to the login route will the do the right thing + * and move the app to the login page. But we don't yet know that is the + * proper route. May be at some point we would want it to have a way + * to know which would be the proper login route for the app + */ + this.router.navigate(['/login']); + }; + AuthService.prototype._extractAndSaveAuthData = function (res) { + var data = res.json(); + if (!data) { + throw new Error('Invalid/blank auth data, Fatal Error'); + } + try { + var userData = this.jwtHelper.decodeToken(data.access_token); + data.userData = userData; + this.localStorage.setObject(auth_constants_1.AuthConstants.AUTH_TOKEN_KEY, data); + } + catch (ex) { + throw new Error('Fatal error, failed to parse token'); + } + return true; + }; + AuthService.prototype._extractAuthError = function (res) { + var error = res.json(); + var errorMsg = error.error_description || 'Server error'; + this.loggerService.error(errorMsg); + return Observable_1.Observable.throw(errorMsg); + }; + return AuthService; +}()); +AuthService = __decorate([ + core_1.Injectable(), + __metadata("design:paramtypes", [http_1.Http, + index_1.LocalStorage, + angular2_jwt_1.JwtHelper, + router_1.Router, + index_1.LoggerService]) +], AuthService); +exports.AuthService = AuthService; + +//# sourceMappingURL=auth.service.js.map diff --git a/src/tmp/app/auth/auth.service.js.map b/src/tmp/app/auth/auth.service.js.map new file mode 100644 index 0000000..cba9839 --- /dev/null +++ b/src/tmp/app/auth/auth.service.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/auth/auth.service.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,sCAA2C;AAC3C,sCAAwD;AACxD,0CAAyC;AACzC,8CAA6C;AAC7C,qCAAmC;AACnC,iCAA+B;AAC/B,mCAAiC;AACjC,mDAAiD;AACjD,6CAAyC;AACzC,yCAAyE;AAGzE,IAAa,WAAW;IACpB;;OAEG;IACH,qBACY,IAAU,EACV,YAA0B,EAC1B,SAAoB,EACpB,MAAc,EACd,aAA4B;QAJ5B,SAAI,GAAJ,IAAI,CAAM;QACV,iBAAY,GAAZ,YAAY,CAAc;QAC1B,cAAS,GAAT,SAAS,CAAW;QACpB,WAAM,GAAN,MAAM,CAAQ;QACd,kBAAa,GAAb,aAAa,CAAe;IAAI,CAAC;IAE7C,2BAAK,GAAL,UAAM,QAAgB,EAAE,QAAgB;QAAxC,iBAsBC;QArBG,IAAI,OAAO,GAAG,IAAI,cAAO,EAAE,CAAC;QAC5B,IAAI,QAAQ,GAAG,iBAAS,CAAC,GAAG,CAAC,SAAS,GAAG,YAAY,CAAC,CAAC,8CAA8C;QAErG,IAAI,eAAe,GACf,aAAa,GAAG,UAAU;YAC1B,YAAY,GAAG,QAAQ;YACvB,YAAY,GAAG,QAAQ;YACvB,aAAa,GAAG,kBAAkB,CAAC,CAAC,4EAA4E;QAEpH,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,mCAAmC,CAAC,CAAC;QAEpE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,EAAE,EAAE,OAAO,SAAA,EAAE,CAAC;aACxD,GAAG,CAAC,UAAC,GAAa;YACf,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC;gBACxC,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;YACtD,CAAC;YACD,MAAM,CAAC,KAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAC7C,CAAC,CAAC;aACD,KAAK,CAAC,UAAC,KAAe;YACnB,MAAM,CAAC,KAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACX,CAAC;IAED,4BAAM,GAAN;QACI,YAAY,CAAC,UAAU,CAAC,8BAAa,CAAC,cAAc,CAAC,CAAC;QACtD;;;;;;;UAOE;QACF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IACrC,CAAC;IAEO,6CAAuB,GAA/B,UAAgC,GAAa;QACzC,IAAI,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACtB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACR,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,CAAC;YACD,IAAI,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC7D,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;YACzB,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,8BAAa,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QACpE,CAAC;QAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,CAAC,IAAI,CAAC;IAChB,CAAC;IAEO,uCAAiB,GAAzB,UAA0B,GAAa;QACnC,IAAI,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACvB,IAAI,QAAQ,GAAG,KAAK,CAAC,iBAAiB,IAAI,cAAc,CAAC;QACzD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,CAAC,uBAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;IACL,kBAAC;AAAD,CArEA,AAqEC,IAAA;AArEY,WAAW;IADvB,iBAAU,EAAE;qCAMS,WAAI;QACI,oBAAY;QACf,wBAAS;QACZ,eAAM;QACC,qBAAa;GAT/B,WAAW,CAqEvB;AArEY,kCAAW","file":"auth.service.js","sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { Http, Headers, Response } from '@angular/http';\r\nimport { Router } from '@angular/router';\r\nimport { Observable } from 'rxjs/Observable';\r\nimport 'rxjs/add/observable/throw';\r\nimport 'rxjs/add/operator/map';\r\nimport 'rxjs/add/operator/catch';\r\nimport { AuthConstants } from './auth.constants';\r\nimport { JwtHelper } from 'angular2-jwt';\r\nimport { CONSTANTS, LoggerService, LocalStorage } from '../shared/index';\r\n\r\n@Injectable()\r\nexport class AuthService {\r\n /**\r\n * Authentication service for enterprise dashboard\r\n */\r\n constructor(\r\n private http: Http,\r\n private localStorage: LocalStorage,\r\n private jwtHelper: JwtHelper,\r\n private router: Router,\r\n private loggerService: LoggerService) { }\r\n\r\n login(username: string, password: string) {\r\n let headers = new Headers();\r\n let tokenUrl = CONSTANTS.ENV.AUTH_BASE + 'auth/token'; // TODO: Need to definitely load from settings\r\n\r\n let urlEncodedParam =\r\n 'grant_type=' + 'password' +\r\n '&username=' + username +\r\n '&password=' + password +\r\n '&client_id=' + 'GoFetchDevWebApp'; // TODO: We need to load this from either environment or settings somewhere.\r\n\r\n headers.append('Content-Type', 'application/x-www-form-urlencoded');\r\n\r\n return this.http.post(tokenUrl, urlEncodedParam, { headers })\r\n .map((res: Response) => {\r\n if (res.status < 200 || res.status >= 300) {\r\n throw new Error('Response status: ' + res.status);\r\n }\r\n return this._extractAndSaveAuthData(res);\r\n })\r\n .catch((error: Response) => {\r\n return this._extractAuthError(error);\r\n });\r\n }\r\n\r\n logout() {\r\n localStorage.removeItem(AuthConstants.AUTH_TOKEN_KEY);\r\n /**\r\n * INFO: We don't know at this point what would be the login route\r\n * of this app. Since we are guarding it by canActivate we can safely\r\n * expect that navigating to the login route will the do the right thing\r\n * and move the app to the login page. But we don't yet know that is the\r\n * proper route. May be at some point we would want it to have a way\r\n * to know which would be the proper login route for the app\r\n */\r\n this.router.navigate(['/login']);\r\n }\r\n\r\n private _extractAndSaveAuthData(res: Response) {\r\n let data = res.json();\r\n if (!data) {\r\n throw new Error('Invalid/blank auth data, Fatal Error');\r\n }\r\n try {\r\n let userData = this.jwtHelper.decodeToken(data.access_token);\r\n data.userData = userData;\r\n this.localStorage.setObject(AuthConstants.AUTH_TOKEN_KEY, data);\r\n } catch (ex) {\r\n throw new Error('Fatal error, failed to parse token');\r\n }\r\n return true;\r\n }\r\n\r\n private _extractAuthError(res: Response) {\r\n let error = res.json();\r\n let errorMsg = error.error_description || 'Server error';\r\n this.loggerService.error(errorMsg);\r\n return Observable.throw(errorMsg);\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/auth/index.js b/src/tmp/app/auth/index.js new file mode 100644 index 0000000..0ed6595 --- /dev/null +++ b/src/tmp/app/auth/index.js @@ -0,0 +1,11 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./auth.service")); +var auth_constants_1 = require("./auth.constants"); +exports.AuthConstants = auth_constants_1.AuthConstants; +__export(require("./auth.guard")); +__export(require("./auth.module")); + +//# sourceMappingURL=index.js.map diff --git a/src/tmp/app/auth/index.js.map b/src/tmp/app/auth/index.js.map new file mode 100644 index 0000000..7342440 --- /dev/null +++ b/src/tmp/app/auth/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/auth/index.ts"],"names":[],"mappings":";;;;AAAA,oCAA+B;AAC/B,mDAA+C;AAAvC,yCAAA,aAAa,CAAA;AACrB,kCAA6B;AAC7B,mCAA8B","file":"index.js","sourcesContent":["export * from './auth.service';\r\nexport {AuthConstants} from './auth.constants';\r\nexport * from './auth.guard';\r\nexport * from './auth.module';\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/bundle.js b/src/tmp/app/bundle.js new file mode 100644 index 0000000..44fda75 --- /dev/null +++ b/src/tmp/app/bundle.js @@ -0,0 +1,3 @@ +// This file is for production only, please leave it blank + +//# sourceMappingURL=bundle.js.map diff --git a/src/tmp/app/bundle.js.map b/src/tmp/app/bundle.js.map new file mode 100644 index 0000000..adb063f --- /dev/null +++ b/src/tmp/app/bundle.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/bundle.ts"],"names":[],"mappings":"AAAA,0DAA0D","file":"bundle.js","sourcesContent":["// This file is for production only, please leave it blank\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/dashboard/dashboard-event.service.js b/src/tmp/app/dashboard/dashboard-event.service.js new file mode 100644 index 0000000..89a4204 --- /dev/null +++ b/src/tmp/app/dashboard/dashboard-event.service.js @@ -0,0 +1,30 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var core_1 = require("@angular/core"); +var Subject_1 = require("rxjs/Subject"); +var DashboardEventService = (function () { + function DashboardEventService() { + // TODO: Need to make sure the component updates are standardized + this.componentUpdateSource = new Subject_1.Subject(); + /** The stream to publish component update stream to other components */ + this.componentUpdated$ = this.componentUpdateSource.asObservable(); + } + DashboardEventService.prototype.componentUpdated = function (value) { + this.componentUpdateSource.next(value); + }; + return DashboardEventService; +}()); +DashboardEventService = __decorate([ + core_1.Injectable() +], DashboardEventService); +exports.DashboardEventService = DashboardEventService; +exports.DASHBOARD_PROVIDERS = [ + { provide: DashboardEventService, useClass: DashboardEventService } +]; + +//# sourceMappingURL=dashboard-event.service.js.map diff --git a/src/tmp/app/dashboard/dashboard-event.service.js.map b/src/tmp/app/dashboard/dashboard-event.service.js.map new file mode 100644 index 0000000..b7dd46b --- /dev/null +++ b/src/tmp/app/dashboard/dashboard-event.service.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/dashboard/dashboard-event.service.ts"],"names":[],"mappings":";;;;;;;AAAA,sCAA2C;AAC3C,wCAAuC;AAQvC,IAAa,qBAAqB;IADlC;QAEI,iEAAiE;QAC1D,0BAAqB,GAAG,IAAI,iBAAO,EAA2B,CAAC;QAEtE,wEAAwE;QACjE,sBAAiB,GAAG,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,CAAC;IAKzE,CAAC;IAHU,gDAAgB,GAAvB,UAAwB,KAA8B;QAClD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IACL,4BAAC;AAAD,CAVA,AAUC,IAAA;AAVY,qBAAqB;IADjC,iBAAU,EAAE;GACA,qBAAqB,CAUjC;AAVY,sDAAqB;AAYrB,QAAA,mBAAmB,GAAU;IACtC,EAAE,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,qBAAqB,EAAE;CACtE,CAAC","file":"dashboard-event.service.js","sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { Subject } from 'rxjs/Subject';\r\n\r\nexport interface IDashboardComponetEvent {\r\n Event: string;\r\n Name: string;\r\n}\r\n\r\n@Injectable()\r\nexport class DashboardEventService {\r\n // TODO: Need to make sure the component updates are standardized\r\n public componentUpdateSource = new Subject();\r\n\r\n /** The stream to publish component update stream to other components */\r\n public componentUpdated$ = this.componentUpdateSource.asObservable();\r\n\r\n public componentUpdated(value: IDashboardComponetEvent) {\r\n this.componentUpdateSource.next(value);\r\n }\r\n}\r\n\r\nexport const DASHBOARD_PROVIDERS: any[] = [\r\n { provide: DashboardEventService, useClass: DashboardEventService }\r\n];\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/dashboard/dashboard.component.js b/src/tmp/app/dashboard/dashboard.component.js new file mode 100644 index 0000000..95bd770 --- /dev/null +++ b/src/tmp/app/dashboard/dashboard.component.js @@ -0,0 +1,23 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var core_1 = require("@angular/core"); +var DashboardComponent = (function () { + function DashboardComponent() { + } + return DashboardComponent; +}()); +DashboardComponent = __decorate([ + core_1.Component({ + moduleId: module.id, + selector: 'as-dashboard', + templateUrl: 'dashboard.html' + }) +], DashboardComponent); +exports.DashboardComponent = DashboardComponent; + +//# sourceMappingURL=dashboard.component.js.map diff --git a/src/tmp/app/dashboard/dashboard.component.js.map b/src/tmp/app/dashboard/dashboard.component.js.map new file mode 100644 index 0000000..e9c8efa --- /dev/null +++ b/src/tmp/app/dashboard/dashboard.component.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/dashboard/dashboard.component.ts"],"names":[],"mappings":";;;;;;;AAAA,sCAA0C;AAO1C,IAAa,kBAAkB;IAA/B;IAAiC,CAAC;IAAD,yBAAC;AAAD,CAAjC,AAAkC,IAAA;AAArB,kBAAkB;IAL9B,gBAAS,CAAC;QACP,QAAQ,EAAE,MAAM,CAAC,EAAE;QACnB,QAAQ,EAAE,cAAc;QACxB,WAAW,EAAE,gBAAgB;KAChC,CAAC;GACW,kBAAkB,CAAG;AAArB,gDAAkB","file":"dashboard.component.js","sourcesContent":["import { Component } from '@angular/core';\r\n\r\n@Component({\r\n moduleId: module.id,\r\n selector: 'as-dashboard',\r\n templateUrl: 'dashboard.html'\r\n})\r\nexport class DashboardComponent {}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/dashboard/dashboard.html b/src/tmp/app/dashboard/dashboard.html new file mode 100644 index 0000000..859442a --- /dev/null +++ b/src/tmp/app/dashboard/dashboard.html @@ -0,0 +1,28 @@ +
+ + + + + + + +
+ + + + +
+ + + +
+ +
+
+ +
+ + + + +
\ No newline at end of file diff --git a/src/tmp/app/dashboard/dashboard.module.js b/src/tmp/app/dashboard/dashboard.module.js new file mode 100644 index 0000000..37593b3 --- /dev/null +++ b/src/tmp/app/dashboard/dashboard.module.js @@ -0,0 +1,55 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var core_1 = require("@angular/core"); +var common_1 = require("@angular/common"); +var router_1 = require("@angular/router"); +var ng2_charts_1 = require("ng2-charts"); +var http_1 = require("@angular/http"); +// Local Modules +var index_1 = require("../navbar/index"); +var index_2 = require("../shared/letter-avatar/index"); +var index_3 = require("../data/index"); +var dashboard_event_service_1 = require("./dashboard-event.service"); +// Local Components +var index_4 = require("./index"); +var index_5 = require("../sidebar/index"); +var index_6 = require("../footer/index"); +var index_7 = require("../dashview-header/index"); +var index_8 = require("../glimpse/index"); +var DashboardModule = (function () { + function DashboardModule() { + } + return DashboardModule; +}()); +DashboardModule = __decorate([ + core_1.NgModule({ + declarations: [ + index_4.DashboardComponent, + index_5.SidebarComponent, + index_6.FooterComponent, + index_7.DashviewHeaderComponent, + index_8.GlimpseComponent + ], + exports: [ + index_4.DashboardComponent, + ], + imports: [ + router_1.RouterModule, + common_1.CommonModule, + index_1.NavbarModule, + index_2.LetterAvatarModule, + ng2_charts_1.ChartsModule, + http_1.HttpModule, + index_3.DataModule + ], + providers: dashboard_event_service_1.DASHBOARD_PROVIDERS.slice() + }) +], DashboardModule); +exports.DashboardModule = DashboardModule; + +//# sourceMappingURL=dashboard.module.js.map diff --git a/src/tmp/app/dashboard/dashboard.module.js.map b/src/tmp/app/dashboard/dashboard.module.js.map new file mode 100644 index 0000000..039bbd8 --- /dev/null +++ b/src/tmp/app/dashboard/dashboard.module.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/dashboard/dashboard.module.ts"],"names":[],"mappings":";;;;;;;AAAA,sCAAyC;AACzC,0CAA+C;AAC/C,0CAA+C;AAC/C,yCAA0C;AAC1C,sCAA2C;AAE3C,gBAAgB;AAChB,yCAA+C;AAC/C,uDAAmE;AACnE,uCAA2C;AAG3C,qEAAgE;AAEhE,mBAAmB;AACnB,iCAA6C;AAC7C,0CAAoD;AACpD,yCAAkD;AAClD,kDAAmE;AAEnE,0CAAoD;AAwBpD,IAAa,eAAe;IAA5B;IACA,CAAC;IAAD,sBAAC;AAAD,CADA,AACC,IAAA;AADY,eAAe;IAtB3B,eAAQ,CAAC;QACN,YAAY,EAAE;YACV,0BAAkB;YAClB,wBAAgB;YAChB,uBAAe;YACf,+BAAuB;YACvB,wBAAgB;SACnB;QACD,OAAO,EAAE;YACL,0BAAkB;SACrB;QACD,OAAO,EAAE;YACL,qBAAY;YACZ,qBAAY;YACZ,oBAAY;YACZ,0BAAkB;YAClB,yBAAY;YACZ,iBAAU;YACV,kBAAU;SACb;QACD,SAAS,EAAM,6CAAmB,QAAC;KACtC,CAAC;GACW,eAAe,CAC3B;AADY,0CAAe","file":"dashboard.module.js","sourcesContent":["import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { RouterModule } from '@angular/router';\r\nimport { ChartsModule } from 'ng2-charts';\r\nimport { HttpModule } from '@angular/http';\r\n\r\n// Local Modules\r\nimport { NavbarModule } from '../navbar/index';\r\nimport { LetterAvatarModule } from '../shared/letter-avatar/index';\r\nimport { DataModule } from '../data/index';\r\n\r\n\r\nimport { DASHBOARD_PROVIDERS } from './dashboard-event.service';\r\n\r\n// Local Components\r\nimport { DashboardComponent } from './index';\r\nimport { SidebarComponent } from '../sidebar/index';\r\nimport { FooterComponent } from '../footer/index';\r\nimport { DashviewHeaderComponent } from '../dashview-header/index';\r\n\r\nimport { GlimpseComponent } from '../glimpse/index';\r\n\r\n@NgModule({\r\n declarations: [\r\n DashboardComponent,\r\n SidebarComponent,\r\n FooterComponent,\r\n DashviewHeaderComponent,\r\n GlimpseComponent\r\n ],\r\n exports: [\r\n DashboardComponent,\r\n ],\r\n imports: [\r\n RouterModule,\r\n CommonModule,\r\n NavbarModule,\r\n LetterAvatarModule,\r\n ChartsModule,\r\n HttpModule,\r\n DataModule\r\n ],\r\n providers: [...DASHBOARD_PROVIDERS]\r\n})\r\nexport class DashboardModule {\r\n}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/dashboard/dashboard.routes.js b/src/tmp/app/dashboard/dashboard.routes.js new file mode 100644 index 0000000..88302de --- /dev/null +++ b/src/tmp/app/dashboard/dashboard.routes.js @@ -0,0 +1,16 @@ +"use strict"; +var dashboard_component_1 = require("./dashboard.component"); +var index_1 = require("../glimpse/index"); +exports.DashboardRoutes = [ + { path: '', redirectTo: 'dashboard', pathMatch: 'full' }, + { + path: 'dashboard', + component: dashboard_component_1.DashboardComponent, + children: [ + { path: '', redirectTo: 'glimpse', pathMatch: 'full' }, + { path: 'glimpse', component: index_1.GlimpseComponent } + ] + } +]; + +//# sourceMappingURL=dashboard.routes.js.map diff --git a/src/tmp/app/dashboard/dashboard.routes.js.map b/src/tmp/app/dashboard/dashboard.routes.js.map new file mode 100644 index 0000000..604b0d9 --- /dev/null +++ b/src/tmp/app/dashboard/dashboard.routes.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/dashboard/dashboard.routes.ts"],"names":[],"mappings":";AACA,6DAA2D;AAC3D,0CAAoD;AAEvC,QAAA,eAAe,GAAW;IACnC,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE;IACxD;QACI,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,wCAAkB;QAC7B,QAAQ,EAAE;YACN,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE;YACtD,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,wBAAgB,EAAE;SACnD;KACJ;CACJ,CAAC","file":"dashboard.routes.js","sourcesContent":["import { Routes } from '@angular/router';\r\nimport { DashboardComponent } from './dashboard.component';\r\nimport { GlimpseComponent } from '../glimpse/index';\r\n\r\nexport const DashboardRoutes: Routes = [\r\n { path: '', redirectTo: 'dashboard', pathMatch: 'full' },\r\n {\r\n path: 'dashboard',\r\n component: DashboardComponent,\r\n children: [\r\n { path: '', redirectTo: 'glimpse', pathMatch: 'full' },\r\n { path: 'glimpse', component: GlimpseComponent }\r\n ]\r\n }\r\n];\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/dashboard/index.js b/src/tmp/app/dashboard/index.js new file mode 100644 index 0000000..6aa0afd --- /dev/null +++ b/src/tmp/app/dashboard/index.js @@ -0,0 +1,10 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./dashboard.component")); +__export(require("./dashboard-event.service")); +__export(require("./dashboard.routes")); +__export(require("./dashboard.module")); + +//# sourceMappingURL=index.js.map diff --git a/src/tmp/app/dashboard/index.js.map b/src/tmp/app/dashboard/index.js.map new file mode 100644 index 0000000..61c7e3a --- /dev/null +++ b/src/tmp/app/dashboard/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/dashboard/index.ts"],"names":[],"mappings":";;;;AAAA,2CAAsC;AACtC,+CAA0C;AAC1C,wCAAmC;AACnC,wCAAmC","file":"index.js","sourcesContent":["export * from './dashboard.component';\r\nexport * from './dashboard-event.service';\r\nexport * from './dashboard.routes';\r\nexport * from './dashboard.module';\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/dashview-header/dashview-header.component.js b/src/tmp/app/dashview-header/dashview-header.component.js new file mode 100644 index 0000000..e39b126 --- /dev/null +++ b/src/tmp/app/dashview-header/dashview-header.component.js @@ -0,0 +1,36 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var core_1 = require("@angular/core"); +var dashboard_event_service_1 = require("../dashboard/dashboard-event.service"); +var DashviewHeaderComponent = (function () { + function DashviewHeaderComponent(dashboardEventService) { + var _this = this; + this.dashboardEventService = dashboardEventService; + this.pageHeader = 'Loading'; + this.optionalDescription = ''; + this.dashboardEventService.componentUpdated$.subscribe(function (event) { + _this.pageHeader = event.Name; + _this.breadcrumbDef = [event.Name]; + }); + } + return DashviewHeaderComponent; +}()); +DashviewHeaderComponent = __decorate([ + core_1.Component({ + moduleId: module.id, + selector: 'as-dashview-header', + templateUrl: 'dashview-header.html' + }), + __metadata("design:paramtypes", [dashboard_event_service_1.DashboardEventService]) +], DashviewHeaderComponent); +exports.DashviewHeaderComponent = DashviewHeaderComponent; + +//# sourceMappingURL=dashview-header.component.js.map diff --git a/src/tmp/app/dashview-header/dashview-header.component.js.map b/src/tmp/app/dashview-header/dashview-header.component.js.map new file mode 100644 index 0000000..a9402ec --- /dev/null +++ b/src/tmp/app/dashview-header/dashview-header.component.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/dashview-header/dashview-header.component.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,sCAA0C;AAC1C,gFAA6E;AAO7E,IAAa,uBAAuB;IAWhC,iCAAoB,qBAA4C;QAAhE,iBAKC;QALmB,0BAAqB,GAArB,qBAAqB,CAAuB;QAVzD,eAAU,GAAW,SAAS,CAAC;QAC/B,wBAAmB,GAAW,EAAE,CAAC;QAUpC,IAAI,CAAC,qBAAqB,CAAC,iBAAiB,CAAC,SAAS,CAAC,UAAA,KAAK;YACxD,KAAI,CAAC,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC;YAC7B,KAAI,CAAC,aAAa,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACP,CAAC;IACL,8BAAC;AAAD,CAjBA,AAiBC,IAAA;AAjBY,uBAAuB;IALnC,gBAAS,CAAC;QACP,QAAQ,EAAE,MAAM,CAAC,EAAE;QACnB,QAAQ,EAAE,oBAAoB;QAC9B,WAAW,EAAE,sBAAsB;KACtC,CAAC;qCAY6C,+CAAqB;GAXvD,uBAAuB,CAiBnC;AAjBY,0DAAuB","file":"dashview-header.component.js","sourcesContent":["import { Component } from '@angular/core';\r\nimport { DashboardEventService } from '../dashboard/dashboard-event.service';\r\n\r\n@Component({\r\n moduleId: module.id,\r\n selector: 'as-dashview-header',\r\n templateUrl: 'dashview-header.html'\r\n})\r\nexport class DashviewHeaderComponent {\r\n public pageHeader: string = 'Loading';\r\n public optionalDescription: string = '';\r\n\r\n /**INFO: Not sure how to play this out here.\r\n * The first one has to be the dashboard logo\r\n * and the last one has to have class=active on\r\n * it so we know which one is active here\r\n */\r\n public breadcrumbDef: string[];\r\n\r\n constructor(private dashboardEventService: DashboardEventService) {\r\n this.dashboardEventService.componentUpdated$.subscribe(event => {\r\n this.pageHeader = event.Name;\r\n this.breadcrumbDef = [event.Name];\r\n });\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/dashview-header/dashview-header.html b/src/tmp/app/dashview-header/dashview-header.html new file mode 100644 index 0000000..587ec86 --- /dev/null +++ b/src/tmp/app/dashview-header/dashview-header.html @@ -0,0 +1,11 @@ +
+

+ {{pageHeader}} + {{optionalDescription}} +

+ +
\ No newline at end of file diff --git a/src/tmp/app/dashview-header/index.js b/src/tmp/app/dashview-header/index.js new file mode 100644 index 0000000..bad7130 --- /dev/null +++ b/src/tmp/app/dashview-header/index.js @@ -0,0 +1,7 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./dashview-header.component")); + +//# sourceMappingURL=index.js.map diff --git a/src/tmp/app/dashview-header/index.js.map b/src/tmp/app/dashview-header/index.js.map new file mode 100644 index 0000000..cba0ed9 --- /dev/null +++ b/src/tmp/app/dashview-header/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/dashview-header/index.ts"],"names":[],"mappings":";;;;AAAA,iDAA4C","file":"index.js","sourcesContent":["export * from './dashview-header.component';\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/data/data.module.js b/src/tmp/app/data/data.module.js new file mode 100644 index 0000000..e10b1c8 --- /dev/null +++ b/src/tmp/app/data/data.module.js @@ -0,0 +1,24 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var core_1 = require("@angular/core"); +var index_1 = require("./index"); +var DataModule = (function () { + function DataModule() { + } + return DataModule; +}()); +DataModule = __decorate([ + core_1.NgModule({ + providers: [ + index_1.DataService + ] + }) +], DataModule); +exports.DataModule = DataModule; + +//# sourceMappingURL=data.module.js.map diff --git a/src/tmp/app/data/data.module.js.map b/src/tmp/app/data/data.module.js.map new file mode 100644 index 0000000..4527f20 --- /dev/null +++ b/src/tmp/app/data/data.module.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/data/data.module.ts"],"names":[],"mappings":";;;;;;;AAAA,sCAAyC;AACzC,iCAAsC;AAOtC,IAAa,UAAU;IAAvB;IAAyB,CAAC;IAAD,iBAAC;AAAD,CAAzB,AAA0B,IAAA;AAAb,UAAU;IALtB,eAAQ,CAAC;QACN,SAAS,EAAE;YACP,mBAAW;SACd;KACJ,CAAC;GACW,UAAU,CAAG;AAAb,gCAAU","file":"data.module.js","sourcesContent":["import { NgModule } from '@angular/core';\r\nimport { DataService } from './index';\r\n\r\n@NgModule({\r\n providers: [\r\n DataService\r\n ]\r\n})\r\nexport class DataModule {}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/data/data.service.js b/src/tmp/app/data/data.service.js new file mode 100644 index 0000000..f4bfd70 --- /dev/null +++ b/src/tmp/app/data/data.service.js @@ -0,0 +1,68 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var core_1 = require("@angular/core"); +var http_1 = require("@angular/http"); +var Observable_1 = require("rxjs/Observable"); +require("rxjs/add/observable/throw"); +require("rxjs/add/operator/map"); +require("rxjs/add/operator/catch"); +var index_1 = require("../shared/index"); +var DataService = (function () { + /** + * Generic service towards DataCat + */ + function DataService(http, loggerService) { + this.http = http; + this.loggerService = loggerService; + } + DataService.prototype.executeAggregation = function (collectionName, aggregateDocument) { + var _this = this; + var aggUrl = index_1.CONSTANTS.ENV.API_BASE + collectionName + '/a'; + var headers = new http_1.Headers(); + headers.append('Content-Type', 'application/json'); + return this.http.post(aggUrl, aggregateDocument) + .map(function (res) { + if (res.status < 200 || res.status >= 300) { + throw new Error('Response status: ' + res.status); + } + return _this._extractAndSaveData(res); + }) + .catch(function (error) { + return _this._extractError(error); + }); + }; + DataService.prototype._extractAndSaveData = function (res) { + var body = res.json(); + return body || {}; + }; + DataService.prototype._extractError = function (error) { + var errMsg; + if (error instanceof http_1.Response) { + var body = error.json() || ''; + var err = body.error || JSON.stringify(body); + errMsg = error.status + " - " + (error.statusText || '') + " " + err; + } + else { + errMsg = error.message ? error.message : error.toString(); + } + this.loggerService.error(errMsg); + return Observable_1.Observable.throw(errMsg); + }; + return DataService; +}()); +DataService = __decorate([ + core_1.Injectable(), + __metadata("design:paramtypes", [http_1.Http, + index_1.LoggerService]) +], DataService); +exports.DataService = DataService; + +//# sourceMappingURL=data.service.js.map diff --git a/src/tmp/app/data/data.service.js.map b/src/tmp/app/data/data.service.js.map new file mode 100644 index 0000000..20bc76a --- /dev/null +++ b/src/tmp/app/data/data.service.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/data/data.service.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,sCAA2C;AAC3C,sCAAwD;AACxD,8CAA6C;AAC7C,qCAAmC;AACnC,iCAA+B;AAC/B,mCAAiC;AACjC,yCAA2D;AAG3D,IAAa,WAAW;IACpB;;OAEG;IACH,qBACY,IAAU,EACV,aAA4B;QAD5B,SAAI,GAAJ,IAAI,CAAM;QACV,kBAAa,GAAb,aAAa,CAAe;IAAI,CAAC;IAE7C,wCAAkB,GAAlB,UAAmB,cAAsB,EAAE,iBAAsB;QAAjE,iBAgBC;QAfG,IAAI,MAAM,GAAG,iBAAS,CAAC,GAAG,CAAC,QAAQ,GAAG,cAAc,GAAG,IAAI,CAAC;QAE5D,IAAI,OAAO,GAAG,IAAI,cAAO,EAAE,CAAC;QAC5B,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;QAEnD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,iBAAiB,CAAC;aAC3C,GAAG,CAAC,UAAC,GAAa;YACf,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC;gBACxC,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;YACtD,CAAC;YACD,MAAM,CAAC,KAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QACzC,CAAC,CAAC;aACD,KAAK,CAAC,UAAC,KAAe;YACnB,MAAM,CAAC,KAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACX,CAAC;IAEO,yCAAmB,GAA3B,UAA4B,GAAa;QACrC,IAAI,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACtB,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;IACtB,CAAC;IAEO,mCAAa,GAArB,UAAsB,KAAqB;QACvC,IAAI,MAAc,CAAC;QACnB,EAAE,CAAC,CAAC,KAAK,YAAY,eAAQ,CAAC,CAAC,CAAC;YAC5B,IAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;YAChC,IAAM,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC/C,MAAM,GAAM,KAAK,CAAC,MAAM,YAAM,KAAK,CAAC,UAAU,IAAI,EAAE,UAAI,GAAK,CAAC;QAClE,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,MAAM,GAAG,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,CAAC,uBAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IACL,kBAAC;AAAD,CA3CA,AA2CC,IAAA;AA3CY,WAAW;IADvB,iBAAU,EAAE;qCAMS,WAAI;QACK,qBAAa;GAN/B,WAAW,CA2CvB;AA3CY,kCAAW","file":"data.service.js","sourcesContent":["import { Injectable } from '@angular/core';\r\nimport { Http, Headers, Response } from '@angular/http';\r\nimport { Observable } from 'rxjs/Observable';\r\nimport 'rxjs/add/observable/throw';\r\nimport 'rxjs/add/operator/map';\r\nimport 'rxjs/add/operator/catch';\r\nimport { CONSTANTS, LoggerService } from '../shared/index';\r\n\r\n@Injectable()\r\nexport class DataService {\r\n /**\r\n * Generic service towards DataCat\r\n */\r\n constructor(\r\n private http: Http,\r\n private loggerService: LoggerService) { }\r\n\r\n executeAggregation(collectionName: string, aggregateDocument: any) {\r\n let aggUrl = CONSTANTS.ENV.API_BASE + collectionName + '/a';\r\n\r\n let headers = new Headers();\r\n headers.append('Content-Type', 'application/json');\r\n\r\n return this.http.post(aggUrl, aggregateDocument)\r\n .map((res: Response) => {\r\n if (res.status < 200 || res.status >= 300) {\r\n throw new Error('Response status: ' + res.status);\r\n }\r\n return this._extractAndSaveData(res);\r\n })\r\n .catch((error: Response) => {\r\n return this._extractError(error);\r\n });\r\n }\r\n\r\n private _extractAndSaveData(res: Response) {\r\n let body = res.json();\r\n return body || {};\r\n }\r\n\r\n private _extractError(error: Response | any) {\r\n let errMsg: string;\r\n if (error instanceof Response) {\r\n const body = error.json() || '';\r\n const err = body.error || JSON.stringify(body);\r\n errMsg = `${error.status} - ${error.statusText || ''} ${err}`;\r\n } else {\r\n errMsg = error.message ? error.message : error.toString();\r\n }\r\n this.loggerService.error(errMsg);\r\n return Observable.throw(errMsg);\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/data/index.js b/src/tmp/app/data/index.js new file mode 100644 index 0000000..55aefa2 --- /dev/null +++ b/src/tmp/app/data/index.js @@ -0,0 +1,8 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./data.service")); +__export(require("./data.module")); + +//# sourceMappingURL=index.js.map diff --git a/src/tmp/app/data/index.js.map b/src/tmp/app/data/index.js.map new file mode 100644 index 0000000..dc4f2ce --- /dev/null +++ b/src/tmp/app/data/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/data/index.ts"],"names":[],"mappings":";;;;AAAA,oCAA+B;AAC/B,mCAA8B","file":"index.js","sourcesContent":["export * from './data.service';\r\nexport * from './data.module';\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/footer/footer.component.js b/src/tmp/app/footer/footer.component.js new file mode 100644 index 0000000..b306087 --- /dev/null +++ b/src/tmp/app/footer/footer.component.js @@ -0,0 +1,36 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var core_1 = require("@angular/core"); +var index_1 = require("../shared/index"); +var FooterComponent = (function () { + /** + * Footer constructor + */ + function FooterComponent() { + this.companyInfo = { + title: index_1.CONSTANTS.MAIN.COMPANY.TITLE, + url: index_1.CONSTANTS.MAIN.COMPANY.URL, + tagline: index_1.CONSTANTS.MAIN.COMPANY.TAGLINE + }; + } + return FooterComponent; +}()); +FooterComponent = __decorate([ + core_1.Component({ + moduleId: module.id, + selector: 'as-footer', + templateUrl: 'footer.html' + }), + __metadata("design:paramtypes", []) +], FooterComponent); +exports.FooterComponent = FooterComponent; + +//# sourceMappingURL=footer.component.js.map diff --git a/src/tmp/app/footer/footer.component.js.map b/src/tmp/app/footer/footer.component.js.map new file mode 100644 index 0000000..1555df9 --- /dev/null +++ b/src/tmp/app/footer/footer.component.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/footer/footer.component.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,sCAA0C;AAC1C,yCAA4C;AAO5C,IAAa,eAAe;IAGxB;;OAEG;IACH;QACI,IAAI,CAAC,WAAW,GAAG;YACf,KAAK,EAAE,iBAAS,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK;YACnC,GAAG,EAAE,iBAAS,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG;YAC/B,OAAO,EAAE,iBAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO;SAC1C,CAAC;IACN,CAAC;IACL,sBAAC;AAAD,CAbA,AAaC,IAAA;AAbY,eAAe;IAL3B,gBAAS,CAAC;QACP,QAAQ,EAAE,MAAM,CAAC,EAAE;QACnB,QAAQ,EAAE,WAAW;QACrB,WAAW,EAAE,aAAa;KAC7B,CAAC;;GACW,eAAe,CAa3B;AAbY,0CAAe","file":"footer.component.js","sourcesContent":["import { Component } from '@angular/core';\r\nimport { CONSTANTS } from '../shared/index';\r\n\r\n@Component({\r\n moduleId: module.id,\r\n selector: 'as-footer',\r\n templateUrl: 'footer.html'\r\n})\r\nexport class FooterComponent {\r\n public companyInfo: { title: string, url: string; tagline: string; };\r\n\r\n /**\r\n * Footer constructor\r\n */\r\n constructor() {\r\n this.companyInfo = {\r\n title: CONSTANTS.MAIN.COMPANY.TITLE,\r\n url: CONSTANTS.MAIN.COMPANY.URL,\r\n tagline: CONSTANTS.MAIN.COMPANY.TAGLINE\r\n };\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/footer/footer.html b/src/tmp/app/footer/footer.html new file mode 100644 index 0000000..5183a94 --- /dev/null +++ b/src/tmp/app/footer/footer.html @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/src/tmp/app/footer/index.js b/src/tmp/app/footer/index.js new file mode 100644 index 0000000..a0d7fd1 --- /dev/null +++ b/src/tmp/app/footer/index.js @@ -0,0 +1,7 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./footer.component")); + +//# sourceMappingURL=index.js.map diff --git a/src/tmp/app/footer/index.js.map b/src/tmp/app/footer/index.js.map new file mode 100644 index 0000000..da7b452 --- /dev/null +++ b/src/tmp/app/footer/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/footer/index.ts"],"names":[],"mappings":";;;;AAAA,wCAAmC","file":"index.js","sourcesContent":["export * from './footer.component';\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/glimpse/glimpse.component.js b/src/tmp/app/glimpse/glimpse.component.js new file mode 100644 index 0000000..d3fc172 --- /dev/null +++ b/src/tmp/app/glimpse/glimpse.component.js @@ -0,0 +1,156 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var core_1 = require("@angular/core"); +var dashboard_event_service_1 = require("../dashboard/dashboard-event.service"); +var index_1 = require("../data/index"); +var index_2 = require("../shared/index"); +var GlimpseComponent = (function () { + function GlimpseComponent(dataService, loggerService, dashboarEventService) { + this.dataService = dataService; + this.loggerService = loggerService; + this.dashboarEventService = dashboarEventService; + this.barChartOptions = { + scaleShowVerticalLines: false, + responsive: true, + scales: { + yAxes: [{ + display: true, + ticks: { + suggestedMin: 0, + // OR // + beginAtZero: true, + suggestedMax: 100, + max: 150 + } + }] + } + }; + this.isDataAvailable = false; + this.barChartLabels = []; + this.barChartType = 'bar'; + this.barChartLegend = true; + dashboarEventService.componentUpdated({ Event: 'loaded', Name: 'Glimpse' }); + } + GlimpseComponent.prototype.ngOnInit = function () { + var _this = this; + var document = { + 'aggregate': [ + { '$sort': { 'CreateTime': -1 } }, + { + '$project': { + '_id': 1, + 'HRID': 1, + 'CreateTime': 1, + 'Order.Type': 1, + 'Order.Variant': 1, + 'User.Type': 1, + 'User.UserName': 1, + 'h': { + '$hour': '$CreateTime' + }, + 'm': { + '$minute': '$CreateTime' + }, + 's': { + '$second': '$CreateTime' + }, + 'ml': { + '$millisecond': '$CreateTime' + } + } + }, + { + '$project': { + '_id': 1, + 'HRID': 1, + 'Order.Type': 1, + 'Order.Variant': 1, + 'User.Type': 1, + 'User.UserName': 1, + 'CreateTime': { + '$subtract': [ + '$CreateTime', + { + '$add': [ + '$ml', + { + '$multiply': [ + '$s', + 1000 + ] + }, + { + '$multiply': [ + '$m', + 60, + 1000 + ] + }, + { + '$multiply': [ + '$h', + 60, + 60, + 1000 + ] + } + ] + } + ] + } + } + }, + { + '$group': { + '_id': { + 'CreateDate': '$CreateTime' + }, + 'count': { + '$sum': 1 + }, + 'jobs': { + '$push': '$HRID' + } + } + } + ] + }; + this.dataService.executeAggregation('Jobs', document) + .subscribe(function (result) { + var jobCountArray = []; + if (result) { + // Need to parse this crap here + var res = result; + for (var _i = 0, res_1 = res; _i < res_1.length; _i++) { + var entry = res_1[_i]; + _this.barChartLabels.push(new Date(entry._id.CreateDate.$date).toDateString()); + jobCountArray.push(entry.count); + } + } + _this.barChartData = [{ data: jobCountArray, label: 'Orders' }]; + _this.isDataAvailable = true; + }, function (error) { _this.loggerService.error(error); }); + }; + return GlimpseComponent; +}()); +GlimpseComponent = __decorate([ + core_1.Component({ + moduleId: module.id, + selector: 'as-glimpse', + templateUrl: 'glimpse.html' + }), + __metadata("design:paramtypes", [index_1.DataService, + index_2.LoggerService, + dashboard_event_service_1.DashboardEventService]) +], GlimpseComponent); +exports.GlimpseComponent = GlimpseComponent; + +//# sourceMappingURL=glimpse.component.js.map diff --git a/src/tmp/app/glimpse/glimpse.component.js.map b/src/tmp/app/glimpse/glimpse.component.js.map new file mode 100644 index 0000000..f8836b7 --- /dev/null +++ b/src/tmp/app/glimpse/glimpse.component.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/glimpse/glimpse.component.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,sCAAkD;AAClD,gFAA6E;AAC7E,uCAA4C;AAC5C,yCAAgD;AAOhD,IAAa,gBAAgB;IAwBzB,0BACY,WAAwB,EACxB,aAA4B,EAC5B,oBAA2C;QAF3C,gBAAW,GAAX,WAAW,CAAa;QACxB,kBAAa,GAAb,aAAa,CAAe;QAC5B,yBAAoB,GAApB,oBAAoB,CAAuB;QA1BhD,oBAAe,GAAQ;YAC1B,sBAAsB,EAAE,KAAK;YAC7B,UAAU,EAAE,IAAI;YAChB,MAAM,EAAE;gBACJ,KAAK,EAAE,CAAC;wBACJ,OAAO,EAAE,IAAI;wBACb,KAAK,EAAE;4BACH,YAAY,EAAE,CAAC;4BACf,QAAQ;4BACR,WAAW,EAAE,IAAI;4BACjB,YAAY,EAAE,GAAG;4BACjB,GAAG,EAAE,GAAG;yBACX;qBACJ,CAAC;aACL;SACJ,CAAC;QAEK,oBAAe,GAAY,KAAK,CAAC;QACjC,mBAAc,GAAa,EAAE,CAAC;QAC9B,iBAAY,GAAW,KAAK,CAAC;QAC7B,mBAAc,GAAY,IAAI,CAAC;QAOlC,oBAAoB,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IAChF,CAAC;IAED,mCAAQ,GAAR;QAAA,iBAmGC;QAlGG,IAAI,QAAQ,GAAQ;YAChB,WAAW,EAAE;gBACT,EAAE,OAAO,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE;gBACjC;oBACI,UAAU,EAAE;wBACR,KAAK,EAAE,CAAC;wBACR,MAAM,EAAE,CAAC;wBACT,YAAY,EAAE,CAAC;wBACf,YAAY,EAAE,CAAC;wBACf,eAAe,EAAE,CAAC;wBAClB,WAAW,EAAE,CAAC;wBACd,eAAe,EAAE,CAAC;wBAClB,GAAG,EAAE;4BACD,OAAO,EAAE,aAAa;yBACzB;wBACD,GAAG,EAAE;4BACD,SAAS,EAAE,aAAa;yBAC3B;wBACD,GAAG,EAAE;4BACD,SAAS,EAAE,aAAa;yBAC3B;wBACD,IAAI,EAAE;4BACF,cAAc,EAAE,aAAa;yBAChC;qBACJ;iBACJ;gBACD;oBACI,UAAU,EAAE;wBACR,KAAK,EAAE,CAAC;wBACR,MAAM,EAAE,CAAC;wBACT,YAAY,EAAE,CAAC;wBACf,eAAe,EAAE,CAAC;wBAClB,WAAW,EAAE,CAAC;wBACd,eAAe,EAAE,CAAC;wBAClB,YAAY,EAAE;4BACV,WAAW,EAAE;gCACT,aAAa;gCACb;oCACI,MAAM,EAAE;wCACJ,KAAK;wCACL;4CACI,WAAW,EAAE;gDACT,IAAI;gDACJ,IAAI;6CACP;yCACJ;wCACD;4CACI,WAAW,EAAE;gDACT,IAAI;gDACJ,EAAE;gDACF,IAAI;6CACP;yCACJ;wCACD;4CACI,WAAW,EAAE;gDACT,IAAI;gDACJ,EAAE;gDACF,EAAE;gDACF,IAAI;6CACP;yCACJ;qCACJ;iCACJ;6BACJ;yBACJ;qBACJ;iBACJ;gBACD;oBACI,QAAQ,EAAE;wBACN,KAAK,EAAE;4BACH,YAAY,EAAE,aAAa;yBAC9B;wBACD,OAAO,EAAE;4BACL,MAAM,EAAE,CAAC;yBACZ;wBACD,MAAM,EAAE;4BACJ,OAAO,EAAE,OAAO;yBACnB;qBACJ;iBACJ;aACJ;SACJ,CAAC;QAEF,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC;aAChD,SAAS,CAAC,UAAA,MAAM;YACb,IAAI,aAAa,GAAU,EAAE,CAAC;YAC9B,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;gBACT,+BAA+B;gBAC/B,IAAI,GAAG,GAAU,MAAM,CAAC;gBACxB,GAAG,CAAC,CAAc,UAAG,EAAH,WAAG,EAAH,iBAAG,EAAH,IAAG;oBAAhB,IAAI,KAAK,YAAA;oBACV,KAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;oBAC9E,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;iBACnC;YACL,CAAC;YACD,KAAI,CAAC,YAAY,GAAG,CAAC,EAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAC,CAAC,CAAC;YAC7D,KAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAChC,CAAC,EACD,UAAA,KAAK,IAAM,KAAI,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;IACL,uBAAC;AAAD,CAnIA,AAmIC,IAAA;AAnIY,gBAAgB;IAL5B,gBAAS,CAAC;QACP,QAAQ,EAAE,MAAM,CAAC,EAAE;QACnB,QAAQ,EAAE,YAAY;QACtB,WAAW,EAAE,cAAc;KAC9B,CAAC;qCA0B2B,mBAAW;QACT,qBAAa;QACN,+CAAqB;GA3B9C,gBAAgB,CAmI5B;AAnIY,4CAAgB","file":"glimpse.component.js","sourcesContent":["import { Component, OnInit } from '@angular/core';\r\nimport { DashboardEventService } from '../dashboard/dashboard-event.service';\r\nimport { DataService } from '../data/index';\r\nimport { LoggerService } from '../shared/index';\r\n\r\n@Component({\r\n moduleId: module.id,\r\n selector: 'as-glimpse',\r\n templateUrl: 'glimpse.html'\r\n})\r\nexport class GlimpseComponent implements OnInit {\r\n public barChartOptions: any = {\r\n scaleShowVerticalLines: false,\r\n responsive: true,\r\n scales: {\r\n yAxes: [{\r\n display: true,\r\n ticks: {\r\n suggestedMin: 0, // minimum will be 0, unless there is a lower value.\r\n // OR //\r\n beginAtZero: true, // minimum value will be 0.\r\n suggestedMax: 100,\r\n max: 150\r\n }\r\n }]\r\n }\r\n };\r\n\r\n public isDataAvailable: boolean = false;\r\n public barChartLabels: string[] = [];\r\n public barChartType: string = 'bar';\r\n public barChartLegend: boolean = true;\r\n public barChartData: any[];\r\n\r\n constructor(\r\n private dataService: DataService,\r\n private loggerService: LoggerService,\r\n private dashboarEventService: DashboardEventService) {\r\n dashboarEventService.componentUpdated({ Event: 'loaded', Name: 'Glimpse' });\r\n }\r\n\r\n ngOnInit() {\r\n let document: any = {\r\n 'aggregate': [\r\n { '$sort': { 'CreateTime': -1 } },\r\n {\r\n '$project': {\r\n '_id': 1,\r\n 'HRID': 1,\r\n 'CreateTime': 1,\r\n 'Order.Type': 1,\r\n 'Order.Variant': 1,\r\n 'User.Type': 1,\r\n 'User.UserName': 1,\r\n 'h': {\r\n '$hour': '$CreateTime'\r\n },\r\n 'm': {\r\n '$minute': '$CreateTime'\r\n },\r\n 's': {\r\n '$second': '$CreateTime'\r\n },\r\n 'ml': {\r\n '$millisecond': '$CreateTime'\r\n }\r\n }\r\n },\r\n {\r\n '$project': {\r\n '_id': 1,\r\n 'HRID': 1,\r\n 'Order.Type': 1,\r\n 'Order.Variant': 1,\r\n 'User.Type': 1,\r\n 'User.UserName': 1,\r\n 'CreateTime': {\r\n '$subtract': [\r\n '$CreateTime',\r\n {\r\n '$add': [\r\n '$ml',\r\n {\r\n '$multiply': [\r\n '$s',\r\n 1000\r\n ]\r\n },\r\n {\r\n '$multiply': [\r\n '$m',\r\n 60,\r\n 1000\r\n ]\r\n },\r\n {\r\n '$multiply': [\r\n '$h',\r\n 60,\r\n 60,\r\n 1000\r\n ]\r\n }\r\n ]\r\n }\r\n ]\r\n }\r\n }\r\n },\r\n {\r\n '$group': {\r\n '_id': {\r\n 'CreateDate': '$CreateTime'\r\n },\r\n 'count': {\r\n '$sum': 1\r\n },\r\n 'jobs': {\r\n '$push': '$HRID'\r\n }\r\n }\r\n }\r\n ]\r\n };\r\n\r\n this.dataService.executeAggregation('Jobs', document)\r\n .subscribe(result => {\r\n let jobCountArray: any[] = [];\r\n if (result) {\r\n // Need to parse this crap here\r\n let res: any[] = result;\r\n for (let entry of res) {\r\n this.barChartLabels.push(new Date(entry._id.CreateDate.$date).toDateString());\r\n jobCountArray.push(entry.count);\r\n }\r\n }\r\n this.barChartData = [{data: jobCountArray, label: 'Orders'}];\r\n this.isDataAvailable = true;\r\n },\r\n error => { this.loggerService.error(error); });\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/glimpse/glimpse.html b/src/tmp/app/glimpse/glimpse.html new file mode 100644 index 0000000..9e6ef77 --- /dev/null +++ b/src/tmp/app/glimpse/glimpse.html @@ -0,0 +1,10 @@ +
+ +
\ No newline at end of file diff --git a/src/tmp/app/glimpse/index.js b/src/tmp/app/glimpse/index.js new file mode 100644 index 0000000..bee4671 --- /dev/null +++ b/src/tmp/app/glimpse/index.js @@ -0,0 +1,7 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./glimpse.component")); + +//# sourceMappingURL=index.js.map diff --git a/src/tmp/app/glimpse/index.js.map b/src/tmp/app/glimpse/index.js.map new file mode 100644 index 0000000..af2f452 --- /dev/null +++ b/src/tmp/app/glimpse/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/glimpse/index.ts"],"names":[],"mappings":";;;;AAAA,yCAAoC","file":"index.js","sourcesContent":["export * from './glimpse.component';\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/login/index.js b/src/tmp/app/login/index.js new file mode 100644 index 0000000..39e2f09 --- /dev/null +++ b/src/tmp/app/login/index.js @@ -0,0 +1,9 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./login.component")); +__export(require("./login.routes")); +__export(require("./login.module")); + +//# sourceMappingURL=index.js.map diff --git a/src/tmp/app/login/index.js.map b/src/tmp/app/login/index.js.map new file mode 100644 index 0000000..49de2a0 --- /dev/null +++ b/src/tmp/app/login/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/login/index.ts"],"names":[],"mappings":";;;;AAAA,uCAAkC;AAClC,oCAA+B;AAC/B,oCAA+B","file":"index.js","sourcesContent":["export * from './login.component';\r\nexport * from './login.routes';\r\nexport * from './login.module';\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/login/login.component.js b/src/tmp/app/login/login.component.js new file mode 100644 index 0000000..b6f62fd --- /dev/null +++ b/src/tmp/app/login/login.component.js @@ -0,0 +1,60 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var core_1 = require("@angular/core"); +var router_1 = require("@angular/router"); +var index_1 = require("../auth/index"); +var index_2 = require("../shared/index"); +var LoginComponent = (function () { + /** + * Login component for TaskCat.Enterprise Dashboard + */ + function LoginComponent(router, authService, loggerService) { + this.router = router; + this.authService = authService; + this.loggerService = loggerService; + this.model = {}; + this.loading = false; + this.error = ''; + this.appTitle = index_2.CONSTANTS.MAIN.APP.BRAND; + } + LoginComponent.prototype.ngOnInit = function () { + this.authService.logout(); + }; + LoginComponent.prototype.login = function () { + var _this = this; + this.loading = true; + this.authService.login(this.model.username, this.model.password) + .subscribe(function (result) { + if (result === true) { + _this.router.navigate(['/']); + } + _this.loading = false; + }, function (error) { + _this.loggerService.error(error); + _this.error = error; + _this.loading = false; + }); + }; + return LoginComponent; +}()); +LoginComponent = __decorate([ + core_1.Component({ + moduleId: module.id, + selector: 'as-login', + templateUrl: 'login.html' + }), + __metadata("design:paramtypes", [router_1.Router, + index_1.AuthService, + index_2.LoggerService]) +], LoginComponent); +exports.LoginComponent = LoginComponent; + +//# sourceMappingURL=login.component.js.map diff --git a/src/tmp/app/login/login.component.js.map b/src/tmp/app/login/login.component.js.map new file mode 100644 index 0000000..acc2ec7 --- /dev/null +++ b/src/tmp/app/login/login.component.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/login/login.component.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,sCAAkD;AAClD,0CAAyC;AAEzC,uCAA4C;AAC5C,yCAA2D;AAO3D,IAAa,cAAc;IAMvB;;OAEG;IACH,wBACY,MAAc,EACd,WAAwB,EACxB,aAA4B;QAF5B,WAAM,GAAN,MAAM,CAAQ;QACd,gBAAW,GAAX,WAAW,CAAa;QACxB,kBAAa,GAAb,aAAa,CAAe;QAXxC,UAAK,GAAQ,EAAE,CAAC;QAChB,YAAO,GAAG,KAAK,CAAC;QAChB,UAAK,GAAG,EAAE,CAAC;QACX,aAAQ,GAAG,iBAAS,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;IAQO,CAAC;IAE5C,iCAAQ,GAAR;QACI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;IAC9B,CAAC;IAED,8BAAK,GAAL;QAAA,iBAaC;QAZG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;aAC3D,SAAS,CAAC,UAAA,MAAM;YACb,EAAE,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC;gBAClB,KAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAChC,CAAC;YACD,KAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACzB,CAAC,EAAE,UAAA,KAAK;YACJ,KAAI,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChC,KAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YACnB,KAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACzB,CAAC,CAAC,CAAC;IACX,CAAC;IACL,qBAAC;AAAD,CAhCA,AAgCC,IAAA;AAhCY,cAAc;IAL1B,gBAAS,CAAC;QACP,QAAQ,EAAE,MAAM,CAAC,EAAE;QACnB,QAAQ,EAAE,UAAU;QACpB,WAAW,EAAE,YAAY;KAC5B,CAAC;qCAWsB,eAAM;QACD,mBAAW;QACT,qBAAa;GAZ/B,cAAc,CAgC1B;AAhCY,wCAAc","file":"login.component.js","sourcesContent":["import { Component, OnInit } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\n\r\nimport { AuthService } from '../auth/index';\r\nimport { CONSTANTS, LoggerService } from '../shared/index';\r\n\r\n@Component({\r\n moduleId: module.id,\r\n selector: 'as-login',\r\n templateUrl: 'login.html'\r\n})\r\nexport class LoginComponent implements OnInit {\r\n model: any = {};\r\n loading = false;\r\n error = '';\r\n appTitle = CONSTANTS.MAIN.APP.BRAND;\r\n\r\n /**\r\n * Login component for TaskCat.Enterprise Dashboard\r\n */\r\n constructor(\r\n private router: Router,\r\n private authService: AuthService,\r\n private loggerService: LoggerService) {}\r\n\r\n ngOnInit() {\r\n this.authService.logout();\r\n }\r\n\r\n login() {\r\n this.loading = true;\r\n this.authService.login(this.model.username, this.model.password)\r\n .subscribe(result => {\r\n if (result === true) {\r\n this.router.navigate(['/']);\r\n }\r\n this.loading = false;\r\n }, error => {\r\n this.loggerService.error(error);\r\n this.error = error;\r\n this.loading = false;\r\n });\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/login/login.html b/src/tmp/app/login/login.html new file mode 100644 index 0000000..03c312a --- /dev/null +++ b/src/tmp/app/login/login.html @@ -0,0 +1,54 @@ + + \ No newline at end of file diff --git a/src/tmp/app/login/login.module.js b/src/tmp/app/login/login.module.js new file mode 100644 index 0000000..18c03d6 --- /dev/null +++ b/src/tmp/app/login/login.module.js @@ -0,0 +1,43 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var core_1 = require("@angular/core"); +var forms_1 = require("@angular/forms"); +var index_1 = require("./index"); +var index_2 = require("../auth/index"); +var LoginModule = (function () { + /** + * TaskCat Enterprise dashboard login module + */ + function LoginModule(authGuard) { + this.authGuard = authGuard; + authGuard.loginRoute = '/' + index_1.LoginRoute.path; + } + return LoginModule; +}()); +LoginModule = __decorate([ + core_1.NgModule({ + declarations: [ + index_1.LoginComponent + ], + exports: [ + index_1.LoginComponent, + index_2.AuthModule + ], + imports: [ + index_2.AuthModule, + forms_1.FormsModule + ] + }), + __metadata("design:paramtypes", [index_2.AuthGuard]) +], LoginModule); +exports.LoginModule = LoginModule; + +//# sourceMappingURL=login.module.js.map diff --git a/src/tmp/app/login/login.module.js.map b/src/tmp/app/login/login.module.js.map new file mode 100644 index 0000000..3d9b6c8 --- /dev/null +++ b/src/tmp/app/login/login.module.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/login/login.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,sCAAyC;AACzC,wCAA6C;AAC7C,iCAAqD;AACrD,uCAAsD;AAetD,IAAa,WAAW;IACpB;;OAEG;IACH,qBAAoB,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;QACpC,SAAS,CAAC,UAAU,GAAG,GAAG,GAAG,kBAAU,CAAC,IAAI,CAAC;IACjD,CAAC;IACL,kBAAC;AAAD,CAPA,AAOC,IAAA;AAPY,WAAW;IAbvB,eAAQ,CAAC;QACN,YAAY,EAAE;YACV,sBAAc;SACjB;QACD,OAAO,EAAE;YACL,sBAAc;YACd,kBAAU;SACb;QACD,OAAO,EAAE;YACL,kBAAU;YACV,mBAAW;SACd;KACJ,CAAC;qCAKiC,iBAAS;GAJ/B,WAAW,CAOvB;AAPY,kCAAW","file":"login.module.js","sourcesContent":["import { NgModule } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { LoginComponent, LoginRoute } from './index';\r\nimport { AuthModule, AuthGuard } from '../auth/index';\r\n\r\n@NgModule({\r\n declarations: [\r\n LoginComponent\r\n ],\r\n exports: [\r\n LoginComponent,\r\n AuthModule\r\n ],\r\n imports: [\r\n AuthModule,\r\n FormsModule\r\n ]\r\n})\r\nexport class LoginModule {\r\n /**\r\n * TaskCat Enterprise dashboard login module\r\n */\r\n constructor(private authGuard: AuthGuard) {\r\n authGuard.loginRoute = '/' + LoginRoute.path;\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/login/login.routes.js b/src/tmp/app/login/login.routes.js new file mode 100644 index 0000000..92d8cde --- /dev/null +++ b/src/tmp/app/login/login.routes.js @@ -0,0 +1,5 @@ +"use strict"; +var login_component_1 = require("./login.component"); +exports.LoginRoute = { path: 'login', component: login_component_1.LoginComponent }; + +//# sourceMappingURL=login.routes.js.map diff --git a/src/tmp/app/login/login.routes.js.map b/src/tmp/app/login/login.routes.js.map new file mode 100644 index 0000000..de6d533 --- /dev/null +++ b/src/tmp/app/login/login.routes.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/login/login.routes.ts"],"names":[],"mappings":";AAAA,qDAAmD;AAEtC,QAAA,UAAU,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,gCAAc,EAAE,CAAC","file":"login.routes.js","sourcesContent":["import { LoginComponent } from './login.component';\r\n\r\nexport const LoginRoute = { path: 'login', component: LoginComponent };\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/main.js b/src/tmp/app/main.js new file mode 100644 index 0000000..c972b8f --- /dev/null +++ b/src/tmp/app/main.js @@ -0,0 +1,10 @@ +"use strict"; +var core_1 = require("@angular/core"); +var platform_browser_dynamic_1 = require("@angular/platform-browser-dynamic"); +var app_module_1 = require("./app.module"); +if (ENV === 'production') { + core_1.enableProdMode(); +} +platform_browser_dynamic_1.platformBrowserDynamic().bootstrapModule(app_module_1.AppModule); + +//# sourceMappingURL=main.js.map diff --git a/src/tmp/app/main.js.map b/src/tmp/app/main.js.map new file mode 100644 index 0000000..3db4f55 --- /dev/null +++ b/src/tmp/app/main.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/main.ts"],"names":[],"mappings":";AAAA,sCAA+C;AAC/C,8EAA2E;AAE3E,2CAAyC;AAIzC,EAAE,CAAC,CAAC,GAAG,KAAK,YAAY,CAAC,CAAC,CAAC;IACvB,qBAAc,EAAE,CAAC;AACrB,CAAC;AAED,iDAAsB,EAAE,CAAC,eAAe,CAAC,sBAAS,CAAC,CAAC","file":"main.js","sourcesContent":["import { enableProdMode } from '@angular/core';\r\nimport { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\r\n\r\nimport { AppModule } from './app.module';\r\n\r\ndeclare var ENV: string;\r\n\r\nif (ENV === 'production') {\r\n enableProdMode();\r\n}\r\n\r\nplatformBrowserDynamic().bootstrapModule(AppModule);\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/navbar/index.js b/src/tmp/app/navbar/index.js new file mode 100644 index 0000000..05e0ed1 --- /dev/null +++ b/src/tmp/app/navbar/index.js @@ -0,0 +1,8 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./navbar.component")); +__export(require("./navbar.module")); + +//# sourceMappingURL=index.js.map diff --git a/src/tmp/app/navbar/index.js.map b/src/tmp/app/navbar/index.js.map new file mode 100644 index 0000000..e03a53d --- /dev/null +++ b/src/tmp/app/navbar/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/navbar/index.ts"],"names":[],"mappings":";;;;AAAA,wCAAmC;AACnC,qCAAgC","file":"index.js","sourcesContent":["export * from './navbar.component';\r\nexport * from './navbar.module';\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/navbar/navbar.component.js b/src/tmp/app/navbar/navbar.component.js new file mode 100644 index 0000000..47dc06b --- /dev/null +++ b/src/tmp/app/navbar/navbar.component.js @@ -0,0 +1,58 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var core_1 = require("@angular/core"); +var index_1 = require("../shared/index"); +var index_2 = require("../auth/index"); +var index_3 = require("../shared/index"); +var auth_service_1 = require("../auth/auth.service"); +var NavbarComponent = (function () { + // Navbar constructor + function NavbarComponent(localStorage, authService) { + this.localStorage = localStorage; + this.authService = authService; + /** + * TODO: This is definitely replicated code from DashboardComponent. + * We need to put this avatar configuration somewhere in a settings file + * if possible. + */ + this.avatarData = { + size: 40, + background: '#008d4c', + fontColor: '#FFFFFF', + isSquare: false, + fixedColor: true + }; + this.userInfo = {}; + var userToken = localStorage.getObject(index_2.AuthConstants.AUTH_TOKEN_KEY); + this.avatarData.text = userToken.userData.sub; + this.userInfo.Name = userToken.userData.sub; + this.userInfo.Email = userToken.email; + this.productInfo = { + platform_title: index_3.CONSTANTS.MAIN.APP.PLATFORM_TITLE, + product_title: index_3.CONSTANTS.MAIN.APP.PRODUCT_TITLE + }; + } + NavbarComponent.prototype.signout = function () { + this.authService.logout(); + }; + return NavbarComponent; +}()); +NavbarComponent = __decorate([ + core_1.Component({ + moduleId: module.id, + selector: 'as-navbar', + templateUrl: 'navbar.html' + }), + __metadata("design:paramtypes", [index_1.LocalStorage, auth_service_1.AuthService]) +], NavbarComponent); +exports.NavbarComponent = NavbarComponent; + +//# sourceMappingURL=navbar.component.js.map diff --git a/src/tmp/app/navbar/navbar.component.js.map b/src/tmp/app/navbar/navbar.component.js.map new file mode 100644 index 0000000..e428320 --- /dev/null +++ b/src/tmp/app/navbar/navbar.component.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/navbar/navbar.component.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,sCAA0C;AAC1C,yCAA+C;AAC/C,uCAA8C;AAC9C,yCAA4C;AAC5C,qDAAmD;AAOnD,IAAa,eAAe;IAkBxB,qBAAqB;IACrB,yBAAoB,YAA0B,EAAU,WAAwB;QAA5D,iBAAY,GAAZ,YAAY,CAAc;QAAU,gBAAW,GAAX,WAAW,CAAa;QAlBhF;;;;WAIG;QAEI,eAAU,GAAQ;YACrB,IAAI,EAAE,EAAE;YACR,UAAU,EAAE,SAAS;YACrB,SAAS,EAAE,SAAS;YACpB,QAAQ,EAAE,KAAK;YACf,UAAU,EAAE,IAAI;SACnB,CAAC;QAEK,aAAQ,GAAQ,EAAE,CAAC;QAKtB,IAAI,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC,qBAAa,CAAC,cAAc,CAAC,CAAC;QACrE,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC;QAC9C,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC;QAC5C,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;QAEtC,IAAI,CAAC,WAAW,GAAG;YACf,cAAc,EAAE,iBAAS,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc;YACjD,aAAa,EAAE,iBAAS,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa;SAClD,CAAC;IACN,CAAC;IAEM,iCAAO,GAAd;QACI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;IAC9B,CAAC;IACL,sBAAC;AAAD,CAlCA,AAkCC,IAAA;AAlCY,eAAe;IAL3B,gBAAS,CAAC;QACP,QAAQ,EAAE,MAAM,CAAC,EAAE;QACnB,QAAQ,EAAE,WAAW;QACrB,WAAW,EAAE,aAAa;KAC7B,CAAC;qCAoBoC,oBAAY,EAAuB,0BAAW;GAnBvE,eAAe,CAkC3B;AAlCY,0CAAe","file":"navbar.component.js","sourcesContent":["import { Component } from '@angular/core';\r\nimport { LocalStorage } from '../shared/index';\r\nimport { AuthConstants } from '../auth/index';\r\nimport { CONSTANTS } from '../shared/index';\r\nimport { AuthService } from '../auth/auth.service';\r\n\r\n@Component({\r\n moduleId: module.id,\r\n selector: 'as-navbar',\r\n templateUrl: 'navbar.html'\r\n})\r\nexport class NavbarComponent {\r\n /**\r\n * TODO: This is definitely replicated code from DashboardComponent.\r\n * We need to put this avatar configuration somewhere in a settings file\r\n * if possible.\r\n */\r\n\r\n public avatarData: any = {\r\n size: 40,\r\n background: '#008d4c', // by default it will produce dynamic colors\r\n fontColor: '#FFFFFF',\r\n isSquare: false,\r\n fixedColor: true\r\n };\r\n\r\n public userInfo: any = {};\r\n public productInfo: { platform_title: string; product_title: string };\r\n\r\n // Navbar constructor\r\n constructor(private localStorage: LocalStorage, private authService: AuthService) {\r\n let userToken = localStorage.getObject(AuthConstants.AUTH_TOKEN_KEY);\r\n this.avatarData.text = userToken.userData.sub;\r\n this.userInfo.Name = userToken.userData.sub;\r\n this.userInfo.Email = userToken.email;\r\n\r\n this.productInfo = {\r\n platform_title: CONSTANTS.MAIN.APP.PLATFORM_TITLE,\r\n product_title: CONSTANTS.MAIN.APP.PRODUCT_TITLE\r\n };\r\n }\r\n\r\n public signout() {\r\n this.authService.logout();\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/navbar/navbar.html b/src/tmp/app/navbar/navbar.html new file mode 100644 index 0000000..345e65d --- /dev/null +++ b/src/tmp/app/navbar/navbar.html @@ -0,0 +1,62 @@ +
+ + + + +
\ No newline at end of file diff --git a/src/tmp/app/navbar/navbar.module.js b/src/tmp/app/navbar/navbar.module.js new file mode 100644 index 0000000..9e3635a --- /dev/null +++ b/src/tmp/app/navbar/navbar.module.js @@ -0,0 +1,33 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var core_1 = require("@angular/core"); +var index_1 = require("./index"); +var common_1 = require("@angular/common"); +var index_2 = require("../shared/letter-avatar/index"); +var NavbarModule = (function () { + function NavbarModule() { + } + return NavbarModule; +}()); +NavbarModule = __decorate([ + core_1.NgModule({ + declarations: [ + index_1.NavbarComponent + ], + exports: [ + index_1.NavbarComponent + ], + imports: [ + common_1.CommonModule, + index_2.LetterAvatarModule + ] + }) +], NavbarModule); +exports.NavbarModule = NavbarModule; + +//# sourceMappingURL=navbar.module.js.map diff --git a/src/tmp/app/navbar/navbar.module.js.map b/src/tmp/app/navbar/navbar.module.js.map new file mode 100644 index 0000000..fe31e7e --- /dev/null +++ b/src/tmp/app/navbar/navbar.module.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/navbar/navbar.module.ts"],"names":[],"mappings":";;;;;;;AAAA,sCAAyC;AACzC,iCAA0C;AAC1C,0CAA+C;AAC/C,uDAAmE;AAcnE,IAAa,YAAY;IAAzB;IAA4B,CAAC;IAAD,mBAAC;AAAD,CAA5B,AAA6B,IAAA;AAAhB,YAAY;IAZxB,eAAQ,CAAC;QACN,YAAY,EAAE;YACV,uBAAe;SAClB;QACD,OAAO,EAAE;YACL,uBAAe;SAClB;QACD,OAAO,EAAE;YACL,qBAAY;YACZ,0BAAkB;SACrB;KACJ,CAAC;GACW,YAAY,CAAI;AAAhB,oCAAY","file":"navbar.module.js","sourcesContent":["import { NgModule } from '@angular/core';\r\nimport { NavbarComponent } from './index';\r\nimport { CommonModule } from '@angular/common';\r\nimport { LetterAvatarModule } from '../shared/letter-avatar/index';\r\n\r\n@NgModule({\r\n declarations: [\r\n NavbarComponent\r\n ],\r\n exports: [\r\n NavbarComponent\r\n ],\r\n imports: [\r\n CommonModule,\r\n LetterAvatarModule\r\n ]\r\n})\r\nexport class NavbarModule { }\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/shared/constant/env.js b/src/tmp/app/shared/constant/env.js new file mode 100644 index 0000000..0a0024e --- /dev/null +++ b/src/tmp/app/shared/constant/env.js @@ -0,0 +1,14 @@ +/** + * THIS FILE IS GENERATED by `gulp env` command from `env.json` + * Generated on Wed Feb 15 2017 19:45:29 GMT+0100 (W. Europe Standard Time) + * + * Make sure the keys in `env.model.ts` exist in `env.json` + * otherwise it'll throw message like this + * Property '' is missing in type '{}' + * + * Feel free to modify for direct updates in development + */ +"use strict"; +exports.ENV = {}; + +//# sourceMappingURL=env.js.map diff --git a/src/tmp/app/shared/constant/env.js.map b/src/tmp/app/shared/constant/env.js.map new file mode 100644 index 0000000..078f91c --- /dev/null +++ b/src/tmp/app/shared/constant/env.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/shared/constant/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;;AAIU,QAAA,GAAG,GAAW,EAC1B,CAAC","file":"env.js","sourcesContent":["/**\r\n * THIS FILE IS GENERATED by `gulp env` command from `env.json`\r\n * Generated on Wed Feb 15 2017 19:45:29 GMT+0100 (W. Europe Standard Time)\r\n *\r\n * Make sure the keys in `env.model.ts` exist in `env.json`\r\n * otherwise it'll throw message like this\r\n * Property '' is missing in type '{}'\r\n *\r\n * Feel free to modify for direct updates in development\r\n */\r\n\r\nimport { AppEnv } from './env.model';\r\n\r\nexport const ENV: AppEnv = {\r\n};\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/shared/constant/env.model.js b/src/tmp/app/shared/constant/env.model.js new file mode 100644 index 0000000..7a8a6d4 --- /dev/null +++ b/src/tmp/app/shared/constant/env.model.js @@ -0,0 +1,11 @@ +/** + * Only valid JSON data types can be used for types + * + * Make sure the keys in `env.model.ts` exist in `env.json` + * otherwise it'll throw message like this + * Property '' is missing in type '{}' + * + */ +"use strict"; + +//# sourceMappingURL=env.model.js.map diff --git a/src/tmp/app/shared/constant/env.model.js.map b/src/tmp/app/shared/constant/env.model.js.map new file mode 100644 index 0000000..2ed47a0 --- /dev/null +++ b/src/tmp/app/shared/constant/env.model.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/shared/constant/env.model.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG","file":"env.model.js","sourcesContent":["/**\r\n * Only valid JSON data types can be used for types\r\n *\r\n * Make sure the keys in `env.model.ts` exist in `env.json`\r\n * otherwise it'll throw message like this\r\n * Property '' is missing in type '{}'\r\n *\r\n */\r\n\r\nexport interface AppEnv {\r\n API_BASE?: string;\r\n AUTH_BASE?: string;\r\n}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/shared/constant/index.js b/src/tmp/app/shared/constant/index.js new file mode 100644 index 0000000..edc5acc --- /dev/null +++ b/src/tmp/app/shared/constant/index.js @@ -0,0 +1,9 @@ +"use strict"; +var main_1 = require("./main"); +var env_1 = require("./env"); +exports.CONSTANTS = { + MAIN: main_1.MAIN, + ENV: env_1.ENV +}; + +//# sourceMappingURL=index.js.map diff --git a/src/tmp/app/shared/constant/index.js.map b/src/tmp/app/shared/constant/index.js.map new file mode 100644 index 0000000..2027026 --- /dev/null +++ b/src/tmp/app/shared/constant/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/shared/constant/index.ts"],"names":[],"mappings":";AAAA,+BAA8B;AAC9B,6BAA4B;AAEf,QAAA,SAAS,GAAG;IACrB,IAAI,aAAA;IACJ,GAAG,WAAA;CACN,CAAC","file":"index.js","sourcesContent":["import { MAIN } from './main';\r\nimport { ENV } from './env';\r\n\r\nexport const CONSTANTS = {\r\n MAIN,\r\n ENV\r\n};\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/shared/constant/main.js b/src/tmp/app/shared/constant/main.js new file mode 100644 index 0000000..b3d6e87 --- /dev/null +++ b/src/tmp/app/shared/constant/main.js @@ -0,0 +1,15 @@ +"use strict"; +exports.MAIN = { + APP: { + BRAND: 'DataCat', + PLATFORM_TITLE: 'Data', + PRODUCT_TITLE: 'Cat' + }, + COMPANY: { + TITLE: 'NerdCats', + URL: 'http://facebook.com/nerdcats', + TAGLINE: 'Made with love by NerdCats' + } +}; + +//# sourceMappingURL=main.js.map diff --git a/src/tmp/app/shared/constant/main.js.map b/src/tmp/app/shared/constant/main.js.map new file mode 100644 index 0000000..b1e3c43 --- /dev/null +++ b/src/tmp/app/shared/constant/main.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/shared/constant/main.ts"],"names":[],"mappings":";AAAa,QAAA,IAAI,GAAG;IAChB,GAAG,EAAE;QACD,KAAK,EAAE,SAAS;QAChB,cAAc,EAAE,MAAM;QACtB,aAAa,EAAE,KAAK;KACvB;IACD,OAAO,EAAE;QACL,KAAK,EAAE,UAAU;QACjB,GAAG,EAAE,8BAA8B;QACnC,OAAO,EAAE,4BAA4B;KACxC;CACJ,CAAC","file":"main.js","sourcesContent":["export const MAIN = {\r\n APP: {\r\n BRAND: 'DataCat',\r\n PLATFORM_TITLE: 'Data',\r\n PRODUCT_TITLE: 'Cat'\r\n },\r\n COMPANY: {\r\n TITLE: 'NerdCats',\r\n URL: 'http://facebook.com/nerdcats',\r\n TAGLINE: 'Made with love by NerdCats'\r\n }\r\n};\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/shared/index.js b/src/tmp/app/shared/index.js new file mode 100644 index 0000000..e9193ac --- /dev/null +++ b/src/tmp/app/shared/index.js @@ -0,0 +1,9 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./constant/index")); +__export(require("./local-storage.provider")); +__export(require("./logger/index")); + +//# sourceMappingURL=index.js.map diff --git a/src/tmp/app/shared/index.js.map b/src/tmp/app/shared/index.js.map new file mode 100644 index 0000000..371598f --- /dev/null +++ b/src/tmp/app/shared/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/shared/index.ts"],"names":[],"mappings":";;;;AAAA,sCAAiC;AACjC,8CAAyC;AACzC,oCAA+B","file":"index.js","sourcesContent":["export * from './constant/index';\r\nexport * from './local-storage.provider';\r\nexport * from './logger/index';\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/shared/letter-avatar/index.js b/src/tmp/app/shared/letter-avatar/index.js new file mode 100644 index 0000000..bdf3e4f --- /dev/null +++ b/src/tmp/app/shared/letter-avatar/index.js @@ -0,0 +1,8 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./letter-avatar.component")); +__export(require("./letter-avatar.module")); + +//# sourceMappingURL=index.js.map diff --git a/src/tmp/app/shared/letter-avatar/index.js.map b/src/tmp/app/shared/letter-avatar/index.js.map new file mode 100644 index 0000000..a8153e9 --- /dev/null +++ b/src/tmp/app/shared/letter-avatar/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/shared/letter-avatar/index.ts"],"names":[],"mappings":";;;;AAAA,+CAA0C;AAC1C,4CAAuC","file":"index.js","sourcesContent":["export * from './letter-avatar.component';\r\nexport * from './letter-avatar.module';\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/shared/letter-avatar/letter-avatar.component.js b/src/tmp/app/shared/letter-avatar/letter-avatar.component.js new file mode 100644 index 0000000..becbd53 --- /dev/null +++ b/src/tmp/app/shared/letter-avatar/letter-avatar.component.js @@ -0,0 +1,116 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +// taken from https://github.com/rajan-g/angular2-letter-avatar/blob/master/directives/letter-avatar.directive.ts +var core_1 = require("@angular/core"); +var LetterAvatarComponent = (function () { + function LetterAvatarComponent(el) { + this.background = 'red'; + this.fontSize = 49; + this.padding = 28; + this.letter = '?'; + this.size = 100; + this.fontColor = '#FFFFFF'; + this.props = null; + this._el = el.nativeElement; + } + LetterAvatarComponent.prototype.test = function () { + this.generateLetter(); + }; + LetterAvatarComponent.prototype.generateLetter = function () { + if (!this.avatarData) { + throw Error('LetterAvatarComponent config not provided'); + } + if (!this.avatarData.text) { + this.avatarData.text = '?'; + } + var size = this.avatarData && this.avatarData.size ? this.avatarData.size : 100; + this.fontColor = this.avatarData.fontColor ? this.avatarData.fontColor : '#FFFFFF'; + var isSquare = this.avatarData && this.avatarData.isSquare ? true : false; + var border = this.avatarData && this.avatarData.border ? this.avatarData.border : '1px solid #d3d3d3'; + var background = this.avatarData && this.avatarData.background ? this.avatarData.background : null; + var text = this.avatarData && this.avatarData.text ? this.avatarData.text : null; + this.background = background; + var textArray = text.split(' '); + var letter = textArray[0].substr(0, 1) + '' + (textArray.length > 1 ? textArray[1].substr(0, 1) : ''); + letter = letter.toUpperCase(); + this.fontSize = (39 * size) / 100; + this.padding = (28 * size) / 100; + this.letter = letter; + this.size = size; + this.props = {}; + this.props.size = size + 'px'; + this.props.lineheight = this.size + 'px'; + this.props.letter = letter; + this.props.fontSize = this.fontSize + 'px'; + if (isSquare) { + this.props.borderradius = '0%'; + } + else { + this.props.borderradius = '50%'; + } + this.props.textalign = 'center'; + this.props.border = border; + this.props.background = background; + if (this.avatarData.fixedColor && !background) { + this.props.background = background || this.colorize(letter); + } + else { + this.props.background = background || this.getRandomColor(); + } + return true; + }; + ; + LetterAvatarComponent.prototype.getRandomColor = function () { + var letters = '0123456789ABCDEF'.split(''); + var color = '#'; + for (var i = 0; i < 6; i++) { + color += letters[Math.floor(Math.random() * 16)]; + } + return color; + }; + LetterAvatarComponent.prototype.colorize = function (str) { + var hash = 0; + for (var i = 0; i < str.length; i++) { + // tslint:disable-next-line:no-bitwise + hash = str.charCodeAt(i++) + ((hash << 5) - hash); + } + ; + var color = Math.floor(Math.abs((Math.sin(hash) * 10000) % 1 * 16777216)).toString(16); + return '#' + Array(6 - color.length + 1).join('0') + color; + }; + LetterAvatarComponent.prototype.ngOnInit = function () { + this.generateLetter(); + }; + LetterAvatarComponent.prototype.ngOnChanges = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + this.generateLetter(); + }; + return LetterAvatarComponent; +}()); +__decorate([ + core_1.Input('avatardata'), + __metadata("design:type", Object) +], LetterAvatarComponent.prototype, "avatarData", void 0); +LetterAvatarComponent = __decorate([ + core_1.Component({ + moduleId: module.id, + selector: 'avatar', + templateUrl: 'letter-avatar.html', + changeDetection: core_1.ChangeDetectionStrategy.OnPush + }), + __metadata("design:paramtypes", [core_1.ElementRef]) +], LetterAvatarComponent); +exports.LetterAvatarComponent = LetterAvatarComponent; + +//# sourceMappingURL=letter-avatar.component.js.map diff --git a/src/tmp/app/shared/letter-avatar/letter-avatar.component.js.map b/src/tmp/app/shared/letter-avatar/letter-avatar.component.js.map new file mode 100644 index 0000000..fe7b420 --- /dev/null +++ b/src/tmp/app/shared/letter-avatar/letter-avatar.component.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/shared/letter-avatar/letter-avatar.component.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,iHAAiH;AACjH,sCAAyG;AAQzG,IAAa,qBAAqB;IAa9B,+BAAY,EAAc;QAV1B,eAAU,GAAW,KAAK,CAAC;QAC3B,aAAQ,GAAW,EAAE,CAAC;QACtB,YAAO,GAAW,EAAE,CAAC;QACrB,WAAM,GAAW,GAAG,CAAC;QACrB,SAAI,GAAW,GAAG,CAAC;QACnB,cAAS,GAAW,SAAS,CAAC;QAE9B,UAAK,GAAQ,IAAI,CAAC;QAId,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,aAAa,CAAC;IAChC,CAAC;IACD,oCAAI,GAAJ;QACI,IAAI,CAAC,cAAc,EAAE,CAAC;IAC1B,CAAC;IAED,8CAAc,GAAd;QACI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YACnB,MAAM,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC7D,CAAC;QACD,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YACxB,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC;QAC/B,CAAC;QACD,IAAI,IAAI,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC;QAChF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,GAAG,SAAS,CAAC;QACnF,IAAI,QAAQ,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,GAAG,IAAI,GAAG,KAAK,CAAC;QAC1E,IAAI,MAAM,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,mBAAmB,CAAC;QACtG,IAAI,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC;QACnG,IAAI,IAAI,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC;QACjF,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QACtG,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QAC9B,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;QACjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACzC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC3C,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACX,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;QACnC,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC;QAChC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;QACnC,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YAC5C,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,UAAU,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAChE,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,UAAU,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;QAChE,CAAC;QACD,MAAM,CAAC,IAAI,CAAC;IAChB,CAAC;IAAA,CAAC;IAEF,8CAAc,GAAd;QACI,IAAI,OAAO,GAAG,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC3C,IAAI,KAAK,GAAG,GAAG,CAAC;QAChB,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACrD,CAAC;QACD,MAAM,CAAC,KAAK,CAAC;IACjB,CAAC;IACD,wCAAQ,GAAR,UAAS,GAAG;QACR,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,sCAAsC;YACtC,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACtD,CAAC;QAAA,CAAC;QACF,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACvF,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC/D,CAAC;IAED,wCAAQ,GAAR;QACI,IAAI,CAAC,cAAc,EAAE,CAAC;IAC1B,CAAC;IACD,2CAAW,GAAX;QAAY,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QACtB,IAAI,CAAC,cAAc,EAAE,CAAC;IAC1B,CAAC;IACL,4BAAC;AAAD,CAtFA,AAsFC,IAAA;AArFwB;IAApB,YAAK,CAAC,YAAY,CAAC;;yDAAiB;AAD5B,qBAAqB;IANjC,gBAAS,CAAC;QACP,QAAQ,EAAE,MAAM,CAAC,EAAE;QACnB,QAAQ,EAAE,QAAQ;QAClB,WAAW,EAAE,oBAAoB;QACjC,eAAe,EAAE,8BAAuB,CAAC,MAAM;KAClD,CAAC;qCAckB,iBAAU;GAbjB,qBAAqB,CAsFjC;AAtFY,sDAAqB","file":"letter-avatar.component.js","sourcesContent":["// taken from https://github.com/rajan-g/angular2-letter-avatar/blob/master/directives/letter-avatar.directive.ts\r\nimport { Component, ElementRef, Input, OnInit, ChangeDetectionStrategy, OnChanges } from '@angular/core';\r\n\r\n@Component({\r\n moduleId: module.id,\r\n selector: 'avatar',\r\n templateUrl: 'letter-avatar.html',\r\n changeDetection: ChangeDetectionStrategy.OnPush\r\n})\r\nexport class LetterAvatarComponent implements OnInit, OnChanges {\r\n @Input('avatardata') avatarData: any;\r\n letterSrc: string;\r\n background: string = 'red';\r\n fontSize: number = 49;\r\n padding: number = 28;\r\n letter: string = '?';\r\n size: number = 100;\r\n fontColor: string = '#FFFFFF';\r\n border: string;\r\n props: any = null;\r\n private _el: HTMLElement;\r\n\r\n constructor(el: ElementRef) {\r\n this._el = el.nativeElement;\r\n }\r\n test() {\r\n this.generateLetter();\r\n }\r\n\r\n generateLetter() {\r\n if (!this.avatarData) {\r\n throw Error('LetterAvatarComponent config not provided');\r\n }\r\n if (!this.avatarData.text) {\r\n this.avatarData.text = '?';\r\n }\r\n let size = this.avatarData && this.avatarData.size ? this.avatarData.size : 100;\r\n this.fontColor = this.avatarData.fontColor ? this.avatarData.fontColor : '#FFFFFF';\r\n let isSquare = this.avatarData && this.avatarData.isSquare ? true : false;\r\n let border = this.avatarData && this.avatarData.border ? this.avatarData.border : '1px solid #d3d3d3';\r\n let background = this.avatarData && this.avatarData.background ? this.avatarData.background : null;\r\n let text = this.avatarData && this.avatarData.text ? this.avatarData.text : null;\r\n this.background = background;\r\n let textArray = text.split(' ');\r\n let letter = textArray[0].substr(0, 1) + '' + (textArray.length > 1 ? textArray[1].substr(0, 1) : '');\r\n letter = letter.toUpperCase();\r\n this.fontSize = (39 * size) / 100;\r\n this.padding = (28 * size) / 100;\r\n this.letter = letter;\r\n this.size = size;\r\n this.props = {};\r\n this.props.size = size + 'px';\r\n this.props.lineheight = this.size + 'px';\r\n this.props.letter = letter;\r\n this.props.fontSize = this.fontSize + 'px';\r\n if (isSquare) {\r\n this.props.borderradius = '0%';\r\n } else {\r\n this.props.borderradius = '50%';\r\n }\r\n this.props.textalign = 'center';\r\n this.props.border = border;\r\n this.props.background = background;\r\n if (this.avatarData.fixedColor && !background) {\r\n this.props.background = background || this.colorize(letter);\r\n } else {\r\n this.props.background = background || this.getRandomColor();\r\n }\r\n return true;\r\n };\r\n\r\n getRandomColor() {\r\n let letters = '0123456789ABCDEF'.split('');\r\n let color = '#';\r\n for (let i = 0; i < 6; i++) {\r\n color += letters[Math.floor(Math.random() * 16)];\r\n }\r\n return color;\r\n }\r\n colorize(str) {\r\n let hash = 0;\r\n for (let i = 0; i < str.length; i++) {\r\n // tslint:disable-next-line:no-bitwise\r\n hash = str.charCodeAt(i++) + ((hash << 5) - hash);\r\n };\r\n let color = Math.floor(Math.abs((Math.sin(hash) * 10000) % 1 * 16777216)).toString(16);\r\n return '#' + Array(6 - color.length + 1).join('0') + color;\r\n }\r\n\r\n ngOnInit() {\r\n this.generateLetter();\r\n }\r\n ngOnChanges(...args: any[]) {\r\n this.generateLetter();\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/shared/letter-avatar/letter-avatar.html b/src/tmp/app/shared/letter-avatar/letter-avatar.html new file mode 100644 index 0000000..740c9f9 --- /dev/null +++ b/src/tmp/app/shared/letter-avatar/letter-avatar.html @@ -0,0 +1,5 @@ +
+
{{props.letter}}
+
\ No newline at end of file diff --git a/src/tmp/app/shared/letter-avatar/letter-avatar.module.js b/src/tmp/app/shared/letter-avatar/letter-avatar.module.js new file mode 100644 index 0000000..6b0c9ed --- /dev/null +++ b/src/tmp/app/shared/letter-avatar/letter-avatar.module.js @@ -0,0 +1,31 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var core_1 = require("@angular/core"); +var common_1 = require("@angular/common"); +var index_1 = require("./index"); +var LetterAvatarModule = (function () { + function LetterAvatarModule() { + } + return LetterAvatarModule; +}()); +LetterAvatarModule = __decorate([ + core_1.NgModule({ + declarations: [ + index_1.LetterAvatarComponent + ], + exports: [ + index_1.LetterAvatarComponent + ], + imports: [ + common_1.CommonModule + ] + }) +], LetterAvatarModule); +exports.LetterAvatarModule = LetterAvatarModule; + +//# sourceMappingURL=letter-avatar.module.js.map diff --git a/src/tmp/app/shared/letter-avatar/letter-avatar.module.js.map b/src/tmp/app/shared/letter-avatar/letter-avatar.module.js.map new file mode 100644 index 0000000..40f2ebf --- /dev/null +++ b/src/tmp/app/shared/letter-avatar/letter-avatar.module.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/shared/letter-avatar/letter-avatar.module.ts"],"names":[],"mappings":";;;;;;;AAAA,sCAAyC;AACzC,0CAA+C;AAC/C,iCAAgD;AAahD,IAAa,kBAAkB;IAA/B;IAAkC,CAAC;IAAD,yBAAC;AAAD,CAAlC,AAAmC,IAAA;AAAtB,kBAAkB;IAX9B,eAAQ,CAAC;QACN,YAAY,EAAE;YACV,6BAAqB;SACxB;QACD,OAAO,EAAE;YACL,6BAAqB;SACxB;QACD,OAAO,EAAE;YACL,qBAAY;SACf;KACJ,CAAC;GACW,kBAAkB,CAAI;AAAtB,gDAAkB","file":"letter-avatar.module.js","sourcesContent":["import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { LetterAvatarComponent } from './index';\r\n\r\n@NgModule({\r\n declarations: [\r\n LetterAvatarComponent\r\n ],\r\n exports: [\r\n LetterAvatarComponent\r\n ],\r\n imports: [\r\n CommonModule\r\n ]\r\n})\r\nexport class LetterAvatarModule { }\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/shared/local-storage.provider.js b/src/tmp/app/shared/local-storage.provider.js new file mode 100644 index 0000000..9e9d445 --- /dev/null +++ b/src/tmp/app/shared/local-storage.provider.js @@ -0,0 +1,48 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var core_1 = require("@angular/core"); +var LocalStorage = (function () { + function LocalStorage() { + if (!localStorage) { + throw new Error('Current browser does not support Local Storage'); + } + this.localStorage = localStorage; + } + LocalStorage.prototype.set = function (key, value) { + this.localStorage[key] = value; + }; + LocalStorage.prototype.get = function (key) { + return this.localStorage[key] || false; + }; + LocalStorage.prototype.setObject = function (key, value) { + this.localStorage[key] = JSON.stringify(value); + }; + LocalStorage.prototype.getObject = function (key) { + if (this.localStorage[key]) { + return JSON.parse(this.localStorage[key]); + } + return null; + }; + LocalStorage.prototype.remove = function (key) { + this.localStorage.removeItem(key); + }; + return LocalStorage; +}()); +LocalStorage = __decorate([ + core_1.Injectable(), + __metadata("design:paramtypes", []) +], LocalStorage); +exports.LocalStorage = LocalStorage; +exports.LOCAL_STORAGE_PROVIDERS = [ + { provide: LocalStorage, useClass: LocalStorage } +]; + +//# sourceMappingURL=local-storage.provider.js.map diff --git a/src/tmp/app/shared/local-storage.provider.js.map b/src/tmp/app/shared/local-storage.provider.js.map new file mode 100644 index 0000000..fb30afb --- /dev/null +++ b/src/tmp/app/shared/local-storage.provider.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/shared/local-storage.provider.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,sCAAyC;AAGzC,IAAa,YAAY;IAGrB;QACI,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;IAEM,0BAAG,GAAV,UAAW,GAAW,EAAE,KAAa;QACjC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnC,CAAC;IAEM,0BAAG,GAAV,UAAW,GAAW;QAClB,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC;IAC3C,CAAC;IAEM,gCAAS,GAAhB,UAAiB,GAAW,EAAE,KAAU;QACpC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACnD,CAAC;IAEM,gCAAS,GAAhB,UAAiB,GAAW;QACxB,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,CAAC,IAAI,CAAC;IAChB,CAAC;IAEM,6BAAM,GAAb,UAAc,GAAW;QACrB,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;IACL,mBAAC;AAAD,CAhCA,AAgCC,IAAA;AAhCY,YAAY;IADxB,iBAAU,EAAE;;GACA,YAAY,CAgCxB;AAhCY,oCAAY;AAkCZ,QAAA,uBAAuB,GAAU;IAC1C,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE;CACpD,CAAC","file":"local-storage.provider.js","sourcesContent":["import {Injectable} from '@angular/core';\r\n\r\n@Injectable()\r\nexport class LocalStorage {\r\n public localStorage: any;\r\n\r\n constructor() {\r\n if (!localStorage) {\r\n throw new Error('Current browser does not support Local Storage');\r\n }\r\n this.localStorage = localStorage;\r\n }\r\n\r\n public set(key: string, value: string): void {\r\n this.localStorage[key] = value;\r\n }\r\n\r\n public get(key: string): string {\r\n return this.localStorage[key] || false;\r\n }\r\n\r\n public setObject(key: string, value: any): void {\r\n this.localStorage[key] = JSON.stringify(value);\r\n }\r\n\r\n public getObject(key: string): any {\r\n if (this.localStorage[key]) {\r\n return JSON.parse(this.localStorage[key]);\r\n }\r\n return null;\r\n }\r\n\r\n public remove(key: string): any {\r\n this.localStorage.removeItem(key);\r\n }\r\n}\r\n\r\nexport const LOCAL_STORAGE_PROVIDERS: any[] = [\r\n { provide: LocalStorage, useClass: LocalStorage }\r\n];\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/shared/logger/index.js b/src/tmp/app/shared/logger/index.js new file mode 100644 index 0000000..6a2e780 --- /dev/null +++ b/src/tmp/app/shared/logger/index.js @@ -0,0 +1,7 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./logger.service")); + +//# sourceMappingURL=index.js.map diff --git a/src/tmp/app/shared/logger/index.js.map b/src/tmp/app/shared/logger/index.js.map new file mode 100644 index 0000000..dc88508 --- /dev/null +++ b/src/tmp/app/shared/logger/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/shared/logger/index.ts"],"names":[],"mappings":";;;;AAAA,sCAAiC","file":"index.js","sourcesContent":["export * from './logger.service';\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/shared/logger/logger.service.js b/src/tmp/app/shared/logger/logger.service.js new file mode 100644 index 0000000..c194c84 --- /dev/null +++ b/src/tmp/app/shared/logger/logger.service.js @@ -0,0 +1,106 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var core_1 = require("@angular/core"); +var LoggerService = (function () { + /** + * Generic logger service for console + */ + function LoggerService() { + this.log('Logger Initialized'); + } + LoggerService.prototype.assert = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (console && console.assert) { + console.assert.apply(console, args); + } + }; + LoggerService.prototype.error = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (console && console.error) { + console.error.apply(console, args); + } + }; + LoggerService.prototype.group = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (console && console.group) { + console.group.apply(console, args); + } + }; + LoggerService.prototype.groupEnd = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (console && console.groupEnd) { + console.groupEnd.apply(console, args); + } + }; + LoggerService.prototype.info = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + /* INFO: I know this is definitely going against our tslint rules. + * Since that essentially says that we shouldn't use console writing + * methods in production code of course. We have to find a way so we + * can turn proper logging level on and off in development and production + * mode so It's easier to debug when we want to and log in both modes. + */ + // tslint:disable-next-line:no-console + if (console && console.info) { + console.info.apply(console, args); + } + }; + LoggerService.prototype.log = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (console && console.log) { + console.log.apply(console, args); + } + }; + LoggerService.prototype.warn = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (console && console.warn) { + console.warn.apply(console, args); + } + }; + return LoggerService; +}()); +LoggerService = __decorate([ + core_1.Injectable(), + __metadata("design:paramtypes", []) +], LoggerService); +exports.LoggerService = LoggerService; +/* INFO: + * We will definitely need a default implementation of the ILogger if we + * ever decide we will go for a platform specific logger implementation. + * + * But as per YAGNI, this will do now. + */ +exports.LOGGER_PROVIDERS = [ + { provide: LoggerService, useClass: LoggerService } +]; + +//# sourceMappingURL=logger.service.js.map diff --git a/src/tmp/app/shared/logger/logger.service.js.map b/src/tmp/app/shared/logger/logger.service.js.map new file mode 100644 index 0000000..c03ba62 --- /dev/null +++ b/src/tmp/app/shared/logger/logger.service.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/shared/logger/logger.service.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,sCAA2C;AAe3C,IAAa,aAAa;IA8BtB;;OAEG;IACH;QACI,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACnC,CAAC;IAlCM,8BAAM,GAAb;QAAc,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QACxB,EAAE,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;YAAC,OAAO,CAAC,MAAM,OAAd,OAAO,EAAW,IAAI,EAAE;QAAC,CAAC;IAC/D,CAAC;IACM,6BAAK,GAAZ;QAAa,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QACvB,EAAE,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;YAAC,OAAO,CAAC,KAAK,OAAb,OAAO,EAAU,IAAI,EAAE;QAAC,CAAC;IAC7D,CAAC;IACM,6BAAK,GAAZ;QAAa,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QACvB,EAAE,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;YAAC,OAAO,CAAC,KAAK,OAAb,OAAO,EAAU,IAAI,EAAE;QAAC,CAAC;IAC7D,CAAC;IACM,gCAAQ,GAAf;QAAgB,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QAC1B,EAAE,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAC,OAAO,CAAC,QAAQ,OAAhB,OAAO,EAAa,IAAI,EAAE;QAAC,CAAC;IACnE,CAAC;IACM,4BAAI,GAAX;QAAY,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QACtB;;;;;WAKG;QACH,sCAAsC;QACtC,EAAE,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YAAC,OAAO,CAAC,IAAI,OAAZ,OAAO,EAAS,IAAI,EAAE;QAAC,CAAC;IAC3D,CAAC;IACM,2BAAG,GAAV;QAAW,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QACrB,EAAE,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;YAAC,OAAO,CAAC,GAAG,OAAX,OAAO,EAAQ,IAAI,EAAE;QAAC,CAAC;IACzD,CAAC;IACM,4BAAI,GAAX;QAAY,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QACtB,EAAE,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YAAC,OAAO,CAAC,IAAI,OAAZ,OAAO,EAAS,IAAI,EAAE;QAAC,CAAC;IAC3D,CAAC;IAQL,oBAAC;AAAD,CApCA,AAoCC,IAAA;AApCY,aAAa;IADzB,iBAAU,EAAE;;GACA,aAAa,CAoCzB;AApCY,sCAAa;AAuC1B;;;;;GAKG;AACU,QAAA,gBAAgB,GAAU;IACnC,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,aAAa,EAAE;CACtD,CAAC","file":"logger.service.js","sourcesContent":["import { Injectable } from '@angular/core';\r\n\r\nexport interface ILogger {\r\n assert(...args: any[]): void;\r\n error(...args: any[]): void;\r\n group(...args: any[]): void;\r\n groupEnd(...args: any[]): void;\r\n info(...args: any[]): void;\r\n log(...args: any[]): void;\r\n warn(...args: any[]): void;\r\n}\r\n\r\ndeclare var console: any;\r\n\r\n@Injectable()\r\nexport class LoggerService implements ILogger {\r\n public assert(...args: any[]): void {\r\n if (console && console.assert) { console.assert(...args); }\r\n }\r\n public error(...args: any[]): void {\r\n if (console && console.error) { console.error(...args); }\r\n }\r\n public group(...args: any[]): void {\r\n if (console && console.group) { console.group(...args); }\r\n }\r\n public groupEnd(...args: any[]): void {\r\n if (console && console.groupEnd) { console.groupEnd(...args); }\r\n }\r\n public info(...args: any[]): void {\r\n /* INFO: I know this is definitely going against our tslint rules.\r\n * Since that essentially says that we shouldn't use console writing\r\n * methods in production code of course. We have to find a way so we\r\n * can turn proper logging level on and off in development and production\r\n * mode so It's easier to debug when we want to and log in both modes.\r\n */\r\n // tslint:disable-next-line:no-console\r\n if (console && console.info) { console.info(...args); }\r\n }\r\n public log(...args: any[]): void {\r\n if (console && console.log) { console.log(...args); }\r\n }\r\n public warn(...args: any[]): void {\r\n if (console && console.warn) { console.warn(...args); }\r\n }\r\n\r\n /**\r\n * Generic logger service for console\r\n */\r\n constructor() {\r\n this.log('Logger Initialized');\r\n }\r\n}\r\n\r\n\r\n/* INFO:\r\n * We will definitely need a default implementation of the ILogger if we\r\n * ever decide we will go for a platform specific logger implementation.\r\n *\r\n * But as per YAGNI, this will do now.\r\n */\r\nexport const LOGGER_PROVIDERS: any[] = [\r\n { provide: LoggerService, useClass: LoggerService }\r\n];\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/sidebar/index.js b/src/tmp/app/sidebar/index.js new file mode 100644 index 0000000..17f3196 --- /dev/null +++ b/src/tmp/app/sidebar/index.js @@ -0,0 +1,7 @@ +"use strict"; +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./sidebar.component")); + +//# sourceMappingURL=index.js.map diff --git a/src/tmp/app/sidebar/index.js.map b/src/tmp/app/sidebar/index.js.map new file mode 100644 index 0000000..f2a5876 --- /dev/null +++ b/src/tmp/app/sidebar/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/sidebar/index.ts"],"names":[],"mappings":";;;;AAAA,yCAAoC","file":"index.js","sourcesContent":["export * from './sidebar.component';\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/sidebar/sidebar.component.js b/src/tmp/app/sidebar/sidebar.component.js new file mode 100644 index 0000000..1841766 --- /dev/null +++ b/src/tmp/app/sidebar/sidebar.component.js @@ -0,0 +1,46 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var core_1 = require("@angular/core"); +var index_1 = require("../shared/index"); +var index_2 = require("../auth/index"); +var SidebarComponent = (function () { + /** + * Sidebar constructor + */ + function SidebarComponent(localStorage) { + this.localStorage = localStorage; + // TODO: Replication here again, need to put this somewhere in a settings. + this.avatarData = { + size: 40, + background: '#008d4c', + fontColor: '#FFFFFF', + isSquare: false, + fixedColor: true + }; + this.userInfo = {}; + var userToken = localStorage.getObject(index_2.AuthConstants.AUTH_TOKEN_KEY); + this.avatarData.text = userToken.userData.sub; + this.userInfo.Name = userToken.userData.sub; + this.userInfo.Email = userToken.email; + } + return SidebarComponent; +}()); +SidebarComponent = __decorate([ + core_1.Component({ + moduleId: module.id, + selector: 'as-sidebar', + templateUrl: 'sidebar.html' + }), + __metadata("design:paramtypes", [index_1.LocalStorage]) +], SidebarComponent); +exports.SidebarComponent = SidebarComponent; + +//# sourceMappingURL=sidebar.component.js.map diff --git a/src/tmp/app/sidebar/sidebar.component.js.map b/src/tmp/app/sidebar/sidebar.component.js.map new file mode 100644 index 0000000..a0f6396 --- /dev/null +++ b/src/tmp/app/sidebar/sidebar.component.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["app/sidebar/sidebar.component.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,sCAA0C;AAC1C,yCAA+C;AAC/C,uCAA8C;AAO9C,IAAa,gBAAgB;IAYzB;;OAEG;IACH,0BAAoB,YAA0B;QAA1B,iBAAY,GAAZ,YAAY,CAAc;QAd9C,0EAA0E;QACnE,eAAU,GAAQ;YACrB,IAAI,EAAE,EAAE;YACR,UAAU,EAAE,SAAS;YACrB,SAAS,EAAE,SAAS;YACpB,QAAQ,EAAE,KAAK;YACf,UAAU,EAAE,IAAI;SACnB,CAAC;QAEK,aAAQ,GAAQ,EAAE,CAAC;QAMtB,IAAI,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC,qBAAa,CAAC,cAAc,CAAC,CAAC;QACrE,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC;QAC9C,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC;QAC5C,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;IAC1C,CAAC;IACL,uBAAC;AAAD,CArBA,AAqBC,IAAA;AArBY,gBAAgB;IAL5B,gBAAS,CAAC;QACP,QAAQ,EAAE,MAAM,CAAC,EAAE;QACnB,QAAQ,EAAE,YAAY;QACtB,WAAW,EAAE,cAAc;KAC9B,CAAC;qCAgBoC,oBAAY;GAfrC,gBAAgB,CAqB5B;AArBY,4CAAgB","file":"sidebar.component.js","sourcesContent":["import { Component } from '@angular/core';\r\nimport { LocalStorage } from '../shared/index';\r\nimport { AuthConstants } from '../auth/index';\r\n\r\n@Component({\r\n moduleId: module.id,\r\n selector: 'as-sidebar',\r\n templateUrl: 'sidebar.html'\r\n})\r\nexport class SidebarComponent {\r\n // TODO: Replication here again, need to put this somewhere in a settings.\r\n public avatarData: any = {\r\n size: 40,\r\n background: '#008d4c', // by default it will produce dynamic colors\r\n fontColor: '#FFFFFF',\r\n isSquare: false,\r\n fixedColor: true\r\n };\r\n\r\n public userInfo: any = {};\r\n\r\n /**\r\n * Sidebar constructor\r\n */\r\n constructor(private localStorage: LocalStorage) {\r\n let userToken = localStorage.getObject(AuthConstants.AUTH_TOKEN_KEY);\r\n this.avatarData.text = userToken.userData.sub;\r\n this.userInfo.Name = userToken.userData.sub;\r\n this.userInfo.Email = userToken.email;\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/src/tmp/app/sidebar/sidebar.html b/src/tmp/app/sidebar/sidebar.html new file mode 100644 index 0000000..a8abeca --- /dev/null +++ b/src/tmp/app/sidebar/sidebar.html @@ -0,0 +1,51 @@ + \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..df27654 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "removeComments": false, + "noImplicitAny": false + }, + "exclude": [ + "node_modules" + ] +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..4c77924 --- /dev/null +++ b/tslint.json @@ -0,0 +1,86 @@ +{ + "rulesDirectory": [ + "node_modules/codelyzer" + ], + "rules": { + "class-name": true, + "comment-format": [true, "check-space"], + "curly": true, + "eofline": true, + "forin": true, + "indent": [true, "spaces"], + "label-position": true, + "label-undefined": true, + "max-line-length": [true, 140], + "member-access": false, + "member-ordering": [true, + "public-before-private", + "static-before-instance", + "variables-before-functions" + ], + "no-arg": true, + "no-bitwise": true, + "no-console": [true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": true, + "no-duplicate-key": true, + "no-duplicate-variable": true, + "no-empty": true, + "no-eval": true, + "no-inferrable-types": true, + "no-shadowed-variable": true, + "no-string-literal": true, + "no-switch-case-fall-through": true, + "trailing-comma": true, + "no-trailing-whitespace": true, + "no-unused-expression": true, + "no-unused-variable": true, + "no-unreachable": true, + "no-use-before-declare": true, + "no-var-keyword": true, + "object-literal-sort-keys": false, + "one-line": [true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "quotemark": [true, "single"], + "radix": true, + "semicolon": [true, "always"], + "triple-equals": [true, "allow-null-check"], + "typedef-whitespace": [true, { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + }], + "variable-name": false, + "whitespace": [true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ], + "directive-selector-name": [true, "camelCase"], + "component-selector-name": [true, "kebab-case"], + "directive-selector-type": [true, "attribute"], + "component-selector-type": [true, "element"], + "directive-selector-prefix": [true, "as"], + "component-selector-prefix": [true, "as"], + "use-input-property-decorator": true, + "use-output-property-decorator": true, + "use-host-property-decorator": true, + "no-attribute-parameter-decorator": true, + "no-forward-ref": true, + "pipe-naming": [true, "camelCase", "as"] + } +} \ No newline at end of file diff --git a/typings.json b/typings.json new file mode 100644 index 0000000..685725f --- /dev/null +++ b/typings.json @@ -0,0 +1,5 @@ +{ + "globalDependencies": { + "elasticsearch": "registry:dt/elasticsearch#5.0.0+20170117233756" + } +}