initial commit

keep-around/dc735e80914fa50c9bca8f6c78c100b7ed19408f
Florian Hartwich 2017-02-24 22:54:59 +01:00
commit c8587fe521
669 changed files with 175605 additions and 0 deletions

69
.gitignore vendored Normal file
View File

@ -0,0 +1,69 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Users Environment Variables
.lock-wscript
# OS generated files #
.DS_Store
ehthumbs.db
Icon?
Thumbs.db
# Node Files #
node_modules/
bower_components/
npm-debug.log
# Coverage #
/coverage/
# Typing #
/src/typings/tsd/
/typings/
/tsd_typings/
# Dist #
/dist
/public/__build__/
/src/*/__build__/
/__build__/**
/public/dist/
/src/*/dist/
/dist/**
.webpack.json
/build
/build/**
/compiled
/dll
# Doc #
/doc/
# IDE #
.idea/
*.swp
# Angular #
*.ngfactory.ts
*.css.shim.ts
*.ngsummary.json
*.shim.ngstyle.ts

112
ng2-admin/.bootstraprc Normal file
View File

@ -0,0 +1,112 @@
---
# Output debugging info
# loglevel: debug
# Major version of Bootstrap: 3 or 4
bootstrapVersion: 4
# If Bootstrap version 4 is used - turn on/off flexbox model
useFlexbox: false
# Webpack loaders, order matters
styleLoaders:
- style
- css
- postcss
- sass
# Extract styles to stand-alone css file
# Different settings for different environments can be used,
# It depends on value of NODE_ENV environment variable
# This param can also be set in webpack config:
# entry: 'bootstrap-loader/extractStyles'
extractStyles: false
# env:
# development:
# extractStyles: false
# production:
# extractStyles: true
# Customize Bootstrap variables that get imported before the original Bootstrap variables.
# Thus, derived Bootstrap variables can depend on values from here.
# See the Bootstrap _variables.scss file for examples of derived Bootstrap variables.
#
# preBootstrapCustomizations: ./path/to/bootstrap/pre-customizations.scss
# This gets loaded after bootstrap/variables is loaded
# Thus, you may customize Bootstrap variables
# based on the values established in the Bootstrap _variables.scss file
#
# bootstrapCustomizations: ./path/to/bootstrap/customizations.scss
# Import your custom styles here
# Usually this endpoint-file contains list of @imports of your application styles
#
# appStyles: ./path/to/your/app/styles/endpoint.scss
### Bootstrap styles
styles:
# Mixins
mixins: true
# Reset and dependencies
normalize: true
print: true
# Core CSS
reboot: true
type: true
images: true
code: true
grid: true
tables: true
forms: true
buttons: true
# Components
animation: true
dropdown: true
button-group: true
input-group: true
custom-forms: true
nav: true
navbar: true
card: true
breadcrumb: true
pagination: true
jumbotron: true
alert: true
progress: true
media: true
list-group: true
responsive-embed: true
close: true
tags: true
# Components w/ JavaScript
modal: true
tooltip: true
popover: true
carousel: true
# Utility classes
utilities: true
### Bootstrap scripts
scripts:
alert: true
button: true
carousel: true
collapse: true
dropdown: true
modal: true
popover: true
scrollspy: true
tab: true
tooltip: true
util: true

6
ng2-admin/.directory Normal file
View File

@ -0,0 +1,6 @@
[Dolphin]
Timestamp=2017,2,24,22,48,6
Version=3
[Settings]
HiddenFilesShown=true

15
ng2-admin/.editorconfig Normal file
View File

@ -0,0 +1,15 @@
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

30
ng2-admin/.travis.yml Normal file
View File

@ -0,0 +1,30 @@
sudo: false
language: node_js
node_js:
- "6"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
before_install:
- curl -o- -L https://yarnpkg.com/install.sh | bash
- export PATH=$HOME/.yarn/bin:$PATH
- npm config set spin false
before_script:
- npm i -g npm@4
install:
- yarn
script:
- yarn run build:ci
notifications:
slack: akveo:q559HckfZMSyZRb803aiLcjH

27
ng2-admin/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,27 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Chrome against localhost, with sourcemaps",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000/*",
"runtimeArgs": [
"--disable-web-security",
"--user-data-dir",
"--remote-debugging-port=9222"
],
"sourceMaps": true,
"webRoot": "${workspaceRoot}"
},
{
"name": "Attach to Chrome, with sourcemaps",
"type": "chrome",
"request": "attach",
"url": "http://localhost:3000/*",
"port": 9222,
"sourceMaps": true,
"webRoot": "${workspaceRoot}"
}
]
}

3
ng2-admin/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"typescript.tsdk": "node_modules/typescript/lib/"
}

261
ng2-admin/CHANGELOG.md Normal file
View File

@ -0,0 +1,261 @@
<a name="0.9.0"></a>
# 0.9.0 (2017-01-30)
### Features
* Angular 2.4.4
* Dependencies updated
* [AOT](https://angular.io/docs/ts/latest/cookbook/aot-compiler.html) :tada:
* DLL bundles
### Bug Fixes
### How to use AOT
* run `npm run build:aot`
* run `npm run server:prod`
### How to update
* Pull sources from git, merge accordingly
* remove `node_modules`
* run `npm install`
* replace `require` for templates and styles with `templateUrl` and `styleUrls`
* private, protected accessors should be changed to public for any members accessed from template
* replace default export on named export in modules
* remove ViewEncapsulation from components
* Enjoy!
<a name="0.8.0"></a>
# 0.8.0 (2016-11-25)
### Features
* Angular 2.2.3
* Dependencies updated
### Bug Fixes
### How to update
* Pull sources from git, merge accordingly
* remove `node_modules`
* run `npm install`
* Enjoy!
<a name="0.7.0"></a>
# 0.7.0 (2016-09-19)
### Note
Tree package does not support angular 2.0 currently so it was hidden from the menu.
### Features
* Angular 2.0
* Dependencies updated
### Bug Fixes
### How to update
* Pull sources from git, merge accordingly
* remove `node_modules`
* run `npm install`
* Remove all directives & pipes from components and move them to the ngModule declarations
* Enjoy!
<a name="0.6.0"></a>
# 0.6.0 (2016-09-19)
### Note
Tree package does not support RC6 currently so it was hidden from the menu.
### Features
* Angular rc.6
* Dependencies updated
### Bug Fixes
### How to update
* Pull sources from git, merge accordingly
* remove `node_modules`
* run `npm install`
* Remove all directives & pipes from components and move them to the ngModule declarations
* Enjoy!
<a name="0.5.0"></a>
# 0.5.0 (2016-08-30)
### Note
Not all packages used in ng2-admin support RC5 at the moment, so we suggest waiting until ng2-admin@0.5.1 version for a complete support of RC5.
### Features
* Angular rc.5 (ngModule)
* Webpack 2
* Dependencies updated
### Bug Fixes
### Breaking changes
Things to consider:
* We introduced NgaModule - wrapper for all ng2-admin features. At the moment it includes everything (directives, services, configs, etc). But, the important thing is that we are planning to refactor it and divide into smaller modules, so that if you don't need a whole list of features somewhere in your code - you can simply import a smaller part. [Here are some more details](https://github.com/akveo/ng2-admin/issues/179).
* Each page section now is a module (Feature Module as per angular documents) wrapped in pages.module.
* Routes configuration (again :( ) moved from one complete file to modules (page sections) configurations. Thus we just left menu configuration as it was before (in one file), just renamed it into app.menu.ts.
* We are planning to continue code refactoring and planning to change component names to follow angular recommendations. Thus we strongly recommend to not import Ba* directives directly and use NgaModule which will encapsulate the changes we are going to make. [Here are some more details](https://github.com/akveo/ng2-admin/issues/179).
### How to update
* Read Angluar RC4 -> RC5 [migration guide](https://angular.io/docs/ts/latest/cookbook/rc4-to-rc5.html)
* Pull sources from git, merge accordingly
* remove `node_modules`
* run `npm install`
* Wrap all your pages into modules, register them in the PagesModule
* Create separate routing files per module
* Remove all direct imports of Ba* components, directives, pipes, etc, instead change your modules the way to import NgaModule
* Enjoy!
<a name="0.4.4"></a>
# 0.4.4 (2016-08-29)
### Features
* Missed new component [ng2-smart-table](https://akveo.github.io/ng2-smart-table/) - [demo](http://akveo.com/ng2-admin/#/pages/tables/smarttables)
### How to update
* Pull sources from git
* run `npm install`
<a name="0.4.3"></a>
# 0.4.3 (2016-08-23)
### Bug Fixes
* Fix leaflet maps styles
* Fix license
* Remove tracing of typings (thanks to @GRoguelon)
* Update baContentTop to work with routerLink (thanks to @Kaizeras)
* Fix Chartist to handle data update dynamically (thanks to @bnayalivne)
### Features
* Finally get rid of bower (thanks to @GRoguelon)
* New component [ng2-smart-table](https://akveo.github.io/ng2-smart-table/) - [demo](http://akveo.com/ng2-admin/#/pages/tables/smarttables)
### How to update
* Pull sources from git
* run `npm install`
<a name="0.4.2"></a>
# 0.4.2 (2016-07-28)
### Bug Fixes
* Fix menu and router configuration
* Fix broken dependencies
### Features
* Dependencies updated
* Use @types instead of typings
### BREAKING CHANGES
* Typings were removed, now we use @types instead, more details [here](https://github.com/AngularClass/angular2-webpack-starter#types)
### How to update
* Remove node_modules folder
* Remove typings folder and move all custom typings to package.json
* run `npm install`
<a name="0.4.0"></a>
# 0.4.0 (2016-07-12)
### Bug Fixes
* Make source files generated correctly (thanks to @AlbertXingZhang)
* Fix docker configuration (thanks to @gavinzhou)
### Features
* Angular updated to rc.4
* Dependencies updated accordingly
* Angular Component Router instead or Router Deprecated (thanks to @RonnyRoos)
* New Angular Forms
* Sidebar rewritten, menu merged with routes configuration
* New CKEditor component
* New Image Uploader component
* New Tree view component
* New Rating component
* New Checkbox and multi-checkbox component
### BREAKING CHANGES
* Router is updated to Angular Router Component. Old beta router is removed.
That means that all the routes are moved to the `src/app/app.routes.ts` file. `src/app/app.menu.ts` is also merged into the routes configuration.
More details on how to configure a new route you can find [here](https://akveo.github.io/ng2-admin/articles/015-sidebar/).
* Forms are updated as well. Thus you need to reconfigure all your forms to use new Angular Forms. Checkout the `src/app/pages/login/login.component.ts`component for more details and example.
### How to update
* run `npm install`
<a name="0.3.0"></a>
# 0.3.0 (2016-06-29)
### Bug Fixes
* Sidebar menu angle fixed
* Sidebar menu selected item fixed
### Features
* Angular updated to rc.3
* Dependencies updated accordingly
### How to update
* Remove `node_modules` and `typings` folders
* run `npm install`
<a name="0.2.1"></a>
# 0.2.1 (2016-06-21)
### Bug Fixes
* Multiple bugfixes
### Features
* Angular updated to rc.2
* Dependencies updated accordingly
* Login page component [Demo](http://akveo.com/ng2-admin/#/login)
* Sign up page component [Demo](http://akveo.com/ng2-admin/#/register)
### BREAKING CHANGES
* `$` renamed to `jQuery` because of name resolution conflicts
### How to update
* Remove `node_modules` and `typings` folders
* run `npm install`

14
ng2-admin/Dockerfile Normal file
View File

@ -0,0 +1,14 @@
FROM node:6.9.5
RUN git clone https://github.com/akveo/ng2-admin.git /var/www \
&& cd /var/www \
&& npm install --global rimraf \
&& npm run clean \
&& npm install --global webpack webpack-dev-server typescript@2.1.5 \
&& npm install \
&& npm run prebuild:prod && npm run build:prod
EXPOSE 8080
WORKDIR /var/www
ENTRYPOINT ["npm", "run", "server:prod"]

22
ng2-admin/LICENSE Normal file
View File

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2016 akveo.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

52
ng2-admin/README.md Normal file
View File

@ -0,0 +1,52 @@
[![Build Status](https://travis-ci.org/akveo/ng2-admin.svg?branch=master)](https://travis-ci.org/akveo/ng2-admin)
[![Join the chat at https://gitter.im/ng2-admin/Lobby](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ng2-admin/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Dependency Status](https://david-dm.org/akveo/ng2-admin/status.svg)](https://david-dm.org/akveo/ng2-admin)
# Admin panel framework based on Angular 2, Bootstrap 4 and Webpack
Admin template made with :heart: by [Akveo team](http://akveo.com/). Follow us on [Twitter](https://twitter.com/akveo_inc) to get latest news about this template first!
### Demo
<a target="_blank" href="http://akveo.com/ng2-admin/"><img src="http://i.imgur.com/QK9AzHj.jpg" width="600" alt="Sky Blue"/></a>
<a target="_blank" href="http://akveo.com/ng2-admin/">Live Demo</a>
## Angular 1.x version
Here you can find Angular 1.x based version: [Blur Admin](http://akveo.github.io/blur-admin/)
## Documentation
Installation, customization and other useful articles: https://akveo.github.io/ng2-admin/
## Based on
Angular 2, Bootstrap 4, Webpack and lots of awesome modules and plugins
## How can I support developers?
- Star our GitHub repo :star:
- Create pull requests, submit bugs, suggest new features or documentation updates :wrench:
- Follow us on [Twitter](https://twitter.com/akveo_inc) :feet:
- Like our page on [Facebook](https://www.facebook.com/akveo/) :thumbsup:
## Can I hire you guys?
Yes! Visit [our homepage](http://akveo.com/) or simply leave us a note to [contact@akveo.com](mailto:contact@akveo.com). We will be happy to work with you!
## Features
* TypeScript
* Webpack
* Responsive layout
* High resolution
* Bootstrap 4 CSS Framework
* Sass
* Angular 2
* jQuery
* Charts (Chartist, Chart.js)
* Maps (Google, Leaflet, amMap)
* and many more!
##License
[MIT](LICENSE.txt) license.
### From akveo
Enjoy :metal:
We're always happy to hear your feedback!

1
ng2-admin/_VERSION Normal file
View File

@ -0,0 +1 @@
_VERSION=0.9.0

9
ng2-admin/build.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
_tag=$1
if [ -z "${_tag}" ]; then
source _VERSION
_tag=${_VERSION}
fi
docker build --tag "ng2-admin:${_tag}" --no-cache=true .

View File

@ -0,0 +1,38 @@
const helpers = require('./../helpers');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
entry: {
'main': './src/desktop.ts'
},
target: 'electron',
node: {
__dirname: false
},
output: {
path: helpers.root('build'),
filename: '[name].js'
},
resolve: {
extensions: ['.ts', '.js', '.json']
},
module: {
rules: [
{
test: /\.ts$/,
loaders: 'awesome-typescript-loader'
}
]
},
plugins: [
new CopyWebpackPlugin([{
from: 'src/package.json'
}])
]
};

View File

@ -0,0 +1,21 @@
const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const commonConfig = require('./webpack.electron.common.js');
const WebpackShellPlugin = require('./webpack-shell-plugin');
const ENV = process.env.NODE_ENV = process.env.ENV = 'development';
module.exports = webpackMerge(commonConfig, {
plugins: [
new WebpackShellPlugin({
//TODO: Kill electron process before build, to start the new one fresh.
onBuildStart: [''],
onBuildEnd: ['electron dist']
}),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(ENV)
}
})
]
});

View File

@ -0,0 +1,26 @@
const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const commonConfig = require('./webpack.electron.common.js');
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
module.exports = webpackMerge(commonConfig, {
plugins: [
// new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({
beautify: false,
mangle: {
screw_ie8: true
},
compress: {
screw_ie8: true
},
comments: false
}),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(ENV)
}
})
]
});

View File

@ -0,0 +1,70 @@
const helpers = require('./../helpers');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const METADATA = {
baseUrl: './',
ENV: 'renderer'
};
/*
* Webpack configuration
*
* See: http://webpack.github.io/docs/configuration.html#cli
*/
module.exports = function (env) {
METADATA.ENV = env
? env
: METADATA.ENV;
return {
/**
* The plataform target where the aplication is going to run in.
* It support target electron-renderer, but is not documented.
*
* See: https://webpack.github.io/docs/configuration.html#target
*/
target: 'electron-renderer',
/**
* Options affecting the output of the compilation.
*
* See: http://webpack.github.io/docs/configuration.html#output
*/
output: {
/**
* The output directory as absolute path (required).
*
* See: http://webpack.github.io/docs/configuration.html#output-path
*/
path: helpers.root('build')
},
/*
* Include polyfills or mocks for various node stuff
* Description: Node configuration
*
* See: https://webpack.github.io/docs/configuration.html#node
*/
node: {
global: true,
crypto: 'empty',
process: true,
module: false,
clearImmediate: false,
setImmediate: false
},
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html',
title: METADATA.title,
chunksSortMode: 'dependency',
metadata: METADATA,
inject: 'head'
})
]
};
};

View File

@ -0,0 +1,6 @@
const devConfig = require('./../webpack.dev');
const commonConfig = require('./webpack.renderer.common');
const webpackMerge = require('webpack-merge');
module.exports = webpackMerge(devConfig(), commonConfig(), {
});

View File

@ -0,0 +1,6 @@
const prodConfig = require('./../webpack.prod');
const commonConfig = require('./webpack.renderer.common');
const webpackMerge = require('webpack-merge');
module.exports = webpackMerge(prodConfig(), commonConfig(), {
});

View File

@ -0,0 +1,8 @@
module.exports = {
NgProbeToken: {},
HmrState: function() {},
_createConditionalRootRenderer: function(rootRenderer, extraTokens, coreTokens) {
return rootRenderer;
},
__platform_browser_private__: {}
};

View File

@ -0,0 +1,43 @@
/**
* Configuration for head elements added during the creation of index.html.
*
* All href attributes are added the publicPath (if exists) by default.
* You can explicitly hint to prefix a publicPath by setting a boolean value to a key that has
* the same name as the attribute you want to operate on, but prefix with =
*
* Example:
* { name: 'msapplication-TileImage', content: '/assets/icon/ms-icon-144x144.png', '=content': true },
* Will prefix the publicPath to content.
*
* { rel: 'apple-touch-icon', sizes: '57x57', href: '/assets/icon/apple-icon-57x57.png', '=href': false },
* Will not prefix the publicPath on href (href attributes are added by default
*
*/
module.exports = {
link: [
/** <link> tags for 'apple-touch-icon' (AKA Web Clips). **/
{ rel: 'apple-touch-icon', sizes: '57x57', href: 'assets/icon/apple-icon-57x57.png' },
{ rel: 'apple-touch-icon', sizes: '60x60', href: 'assets/icon/apple-icon-60x60.png' },
{ rel: 'apple-touch-icon', sizes: '72x72', href: 'assets/icon/apple-icon-72x72.png' },
{ rel: 'apple-touch-icon', sizes: '76x76', href: 'assets/icon/apple-icon-76x76.png' },
{ rel: 'apple-touch-icon', sizes: '114x114', href: 'assets/icon/apple-icon-114x114.png' },
{ rel: 'apple-touch-icon', sizes: '120x120', href: 'assets/icon/apple-icon-120x120.png' },
{ rel: 'apple-touch-icon', sizes: '144x144', href: 'assets/icon/apple-icon-144x144.png' },
{ rel: 'apple-touch-icon', sizes: '152x152', href: 'assets/icon/apple-icon-152x152.png' },
{ rel: 'apple-touch-icon', sizes: '180x180', href: 'assets/icon/apple-icon-180x180.png' },
/** <link> tags for android web app icons **/
{ rel: 'icon', type: 'image/png', sizes: '192x192', href: 'assets/icon/android-icon-192x192.png' },
/** <link> tags for favicons **/
{ rel: 'icon', type: 'image/png', sizes: '32x32', href: 'assets/icon/favicon-32x32.png' },
{ rel: 'icon', type: 'image/png', sizes: '96x96', href: 'assets/icon/favicon-96x96.png' },
{ rel: 'icon', type: 'image/png', sizes: '16x16', href: 'assets/icon/favicon-16x16.png' }
],
meta: [
{ name: 'msapplication-TileColor', content: '#ffffff' },
{ name: 'msapplication-TileImage', content: 'assets/icon/ms-icon-144x144.png', '=content': true },
{ name: 'theme-color', content: '#4691d1' }
]
};

View File

@ -0,0 +1,25 @@
var path = require('path');
const EVENT = process.env.npm_lifecycle_event || '';
// Helper functions
var ROOT = path.resolve(__dirname, '..');
function hasProcessFlag(flag) {
return process.argv.join('').indexOf(flag) > -1;
}
function hasNpmFlag(flag) {
return EVENT.includes(flag);
}
function isWebpackDevServer() {
return process.argv[1] && !! (/webpack-dev-server/.exec(process.argv[1]));
}
var root = path.join.bind(path, ROOT);
exports.hasProcessFlag = hasProcessFlag;
exports.hasNpmFlag = hasNpmFlag;
exports.isWebpackDevServer = isWebpackDevServer;
exports.root = root;

View File

@ -0,0 +1,111 @@
function HtmlElementsPlugin(locations) {
this.locations = locations;
}
HtmlElementsPlugin.prototype.apply = function (compiler) {
var self = this;
compiler.plugin('compilation', function (compilation) {
compilation.options.htmlElements = compilation.options.htmlElements || {};
compilation.plugin('html-webpack-plugin-before-html-generation', function (htmlPluginData, callback) {
const locations = self.locations;
if (locations) {
const publicPath = htmlPluginData.assets.publicPath;
Object.getOwnPropertyNames(locations).forEach(function (loc) {
compilation.options.htmlElements[loc] = getHtmlElementString(locations[loc], publicPath);
});
}
callback(null, htmlPluginData);
});
});
};
const RE_ENDS_WITH_BS = /\/$/;
/**
* Create an HTML tag with attributes from a map.
*
* Example:
* createTag('link', { rel: "manifest", href: "/assets/manifest.json" })
* // <link rel="manifest" href="/assets/manifest.json">
* @param tagName The name of the tag
* @param attrMap A Map of attribute names (keys) and their values.
* @param publicPath a path to add to eh start of static asset url
* @returns {string}
*/
function createTag(tagName, attrMap, publicPath) {
publicPath = publicPath || '';
// add trailing slash if we have a publicPath and it doesn't have one.
if (publicPath && !RE_ENDS_WITH_BS.test(publicPath)) {
publicPath += '/';
}
const attributes = Object.getOwnPropertyNames(attrMap)
.filter(function (name) {
return name[0] !== '=';
})
.map(function (name) {
var value = attrMap[name];
if (publicPath) {
// check if we have explicit instruction, use it if so (e.g: =herf: false)
// if no instruction, use public path if it's href attribute.
const usePublicPath = attrMap.hasOwnProperty('=' + name) ? !!attrMap['=' + name] : name === 'href';
if (usePublicPath) {
// remove a starting trailing slash if the value has one so we wont have //
value = publicPath + (value[0] === '/' ? value.substr(1) : value);
}
}
return `${name}="${value}"`;
});
const closingTag = tagName === 'script' ? '</script>' : '';
return `<${tagName} ${attributes.join(' ')}>${closingTag}`;
}
/**
* Returns a string representing all html elements defined in a data source.
*
* Example:
*
* const ds = {
* link: [
* { rel: "apple-touch-icon", sizes: "57x57", href: "/assets/icon/apple-icon-57x57.png" }
* ],
* meta: [
* { name: "msapplication-TileColor", content: "#00bcd4" }
* ]
* }
*
* getHeadTags(ds);
* // "<link rel="apple-touch-icon" sizes="57x57" href="/assets/icon/apple-icon-57x57.png">"
* "<meta name="msapplication-TileColor" content="#00bcd4">"
*
* @returns {string}
*/
function getHtmlElementString(dataSource, publicPath) {
return Object.getOwnPropertyNames(dataSource)
.map(function (name) {
if (Array.isArray(dataSource[name])) {
return dataSource[name].map(function (attrs) {
return createTag(name, attrs, publicPath);
});
} else {
return [createTag(name, dataSource[name], publicPath)];
}
})
.reduce(function (arr, curr) {
return arr.concat(curr);
}, [])
.join('\n\t');
}
module.exports = HtmlElementsPlugin;

View File

@ -0,0 +1,2 @@
exports.HmrState = function() {
};

View File

View File

@ -0,0 +1,402 @@
const webpack = require('webpack');
const path = require('path');
const helpers = require('./helpers');
/*
* Webpack Plugins
*/
// problem with copy-webpack-plugin
const AssetsPlugin = require('assets-webpack-plugin');
const NormalModuleReplacementPlugin = require('webpack/lib/NormalModuleReplacementPlugin');
const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
const HtmlElementsPlugin = require('./html-elements-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
const ngcWebpack = require('ngc-webpack');
/*
* Webpack Constants
*/
const HMR = helpers.hasProcessFlag('hot');
const AOT = helpers.hasNpmFlag('aot');
const METADATA = {
title: 'ng2-admin - Angular 2 Admin Template',
description: 'Free Angular 2 and Bootstrap 4 Admin Template',
baseUrl: '/',
isDevServer: helpers.isWebpackDevServer()
};
/*
* Webpack configuration
*
* See: http://webpack.github.io/docs/configuration.html#cli
*/
module.exports = function (options) {
isProd = options.env === 'production';
return {
/*
* Cache generated modules and chunks to improve performance for multiple incremental builds.
* This is enabled by default in watch mode.
* You can pass false to disable it.
*
* See: http://webpack.github.io/docs/configuration.html#cache
*/
//cache: false,
/*
* The entry point for the bundle
* Our Angular.js app
*
* See: http://webpack.github.io/docs/configuration.html#entry
*/
entry: {
'polyfills': './src/polyfills.browser.ts',
'vendor': './src/vendor.browser.ts',
'main': AOT ? './src/main.browser.aot.ts' : './src/main.browser.ts'
},
/*
* Options affecting the resolving of modules.
*
* See: http://webpack.github.io/docs/configuration.html#resolve
*/
resolve: {
/*
* An array of extensions that should be used to resolve modules.
*
* See: http://webpack.github.io/docs/configuration.html#resolve-extensions
*/
extensions: ['.ts', '.js', '.css', '.scss', '.json'],
// An array of directory names to be resolved to the current directory
modules: [helpers.root('src'), helpers.root('node_modules')],
},
/*
* Options affecting the normal modules.
*
* See: http://webpack.github.io/docs/configuration.html#module
*/
module: {
rules: [
/*
* Typescript loader support for .ts
*
* Component Template/Style integration using `angular2-template-loader`
* Angular 2 lazy loading (async routes) via `ng-router-loader`
*
* `ng-router-loader` expects vanilla JavaScript code, not TypeScript code. This is why the
* order of the loader matter.
*
* See: https://github.com/s-panferov/awesome-typescript-loader
* See: https://github.com/TheLarkInn/angular2-template-loader
* See: https://github.com/shlomiassaf/ng-router-loader
*/
{
test: /\.ts$/,
use: [
{
loader: '@angularclass/hmr-loader',
options: {
pretty: !isProd,
prod: isProd
}
},
{ // MAKE SURE TO CHAIN VANILLA JS CODE, I.E. TS COMPILATION OUTPUT.
loader: 'ng-router-loader',
options: {
loader: 'async-import',
genDir: 'compiled',
aot: AOT
}
},
{
loader: 'awesome-typescript-loader',
options: {
configFileName: 'tsconfig.webpack.json'
}
},
{
loader: 'angular2-template-loader'
}
],
exclude: [/\.(spec|e2e)\.ts$/]
},
/*
* Json loader support for *.json files.
*
* See: https://github.com/webpack/json-loader
*/
{
test: /\.json$/,
use: 'json-loader'
},
/*
* to string and css loader support for *.css files (from Angular components)
* Returns file content as string
*
*/
{
test: /\.css$/,
use: ['raw-loader']
},
{
test: /\.scss$/,
use: ['raw-loader', 'sass-loader']
},
{
test: /initial\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader!sass-loader?sourceMap'
})
},
{
test: /\.woff(2)?(\?v=.+)?$/,
use: 'url-loader?limit=10000&mimetype=application/font-woff'
},
{
test: /\.(ttf|eot|svg)(\?v=.+)?$/,
use: 'file-loader'
},
{
test: /bootstrap\/dist\/js\/umd\//,
use: 'imports-loader?jQuery=jquery'
},
/* Raw loader support for *.html
* Returns file content as string
*
* See: https://github.com/webpack/raw-loader
*/
{
test: /\.html$/,
use: 'raw-loader',
exclude: [helpers.root('src/index.html')]
},
/* File loader for supporting images, for example, in CSS files.
*/
{
test: /\.(jpg|png|gif)$/,
use: 'file-loader'
}
]
},
/*
* Add additional plugins to the compiler.
*
* See: http://webpack.github.io/docs/configuration.html#plugins
*/
plugins: [
new ExtractTextPlugin({filename: 'initial.css', allChunks: true}),
new AssetsPlugin({
path: helpers.root('dist'),
filename: 'webpack-assets.json',
prettyPrint: true
}),
/*
* Plugin: ForkCheckerPlugin
* Description: Do type checking in a separate process, so webpack don't need to wait.
*
* See: https://github.com/s-panferov/awesome-typescript-loader#forkchecker-boolean-defaultfalse
*/
new CheckerPlugin(),
/*
* Plugin: CommonsChunkPlugin
* Description: Shares common code between the pages.
* It identifies common modules and put them into a commons chunk.
*
* See: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
* See: https://github.com/webpack/docs/wiki/optimization#multi-page-app
*/
new CommonsChunkPlugin({
name: 'polyfills',
chunks: ['polyfills']
}),
// This enables tree shaking of the vendor modules
new CommonsChunkPlugin({
name: 'vendor',
chunks: ['main'],
minChunks: module => /node_modules/.test(module.resource)
}),
// Specify the correct order the scripts will be injected in
new CommonsChunkPlugin({
name: ['polyfills', 'vendor'].reverse()
}),
/**
* Plugin: ContextReplacementPlugin
* Description: Provides context to Angular's use of System.import
*
* See: https://webpack.github.io/docs/list-of-plugins.html#contextreplacementplugin
* See: https://github.com/angular/angular/issues/11580
*/
new ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)src(\\|\/)linker/,
helpers.root('src') // location of your src
),
/*
* Plugin: CopyWebpackPlugin
* Description: Copy files and directories in webpack.
*
* Copies project static assets.
*
* See: https://www.npmjs.com/package/copy-webpack-plugin
*/
new CopyWebpackPlugin([
{from: 'src/assets', to: 'assets'},
{from: 'node_modules/ckeditor', to: 'ckeditor'},
{from: 'src/meta'}
]),
/*
* Plugin: HtmlWebpackPlugin
* Description: Simplifies creation of HTML files to serve your webpack bundles.
* This is especially useful for webpack bundles that include a hash in the filename
* which changes every compilation.
*
* See: https://github.com/ampedandwired/html-webpack-plugin
*/
new HtmlWebpackPlugin({
template: 'src/index.html',
title: METADATA.title,
chunksSortMode: 'dependency',
metadata: METADATA,
inject: 'head'
}),
/*
* Plugin: ScriptExtHtmlWebpackPlugin
* Description: Enhances html-webpack-plugin functionality
* with different deployment options for your scripts including:
*
* See: https://github.com/numical/script-ext-html-webpack-plugin
*/
new ScriptExtHtmlWebpackPlugin({
defaultAttribute: 'defer'
}),
/*
* Plugin: HtmlHeadConfigPlugin
* Description: Generate html tags based on javascript maps.
*
* If a publicPath is set in the webpack output configuration, it will be automatically added to
* href attributes, you can disable that by adding a "=href": false property.
* You can also enable it to other attribute by settings "=attName": true.
*
* The configuration supplied is map between a location (key) and an element definition object (value)
* The location (key) is then exported to the template under then htmlElements property in webpack configuration.
*
* Example:
* Adding this plugin configuration
* new HtmlElementsPlugin({
* headTags: { ... }
* })
*
* Means we can use it in the template like this:
* <%= webpackConfig.htmlElements.headTags %>
*
* Dependencies: HtmlWebpackPlugin
*/
new HtmlElementsPlugin({
headTags: require('./head-config.common')
}),
/**
* Plugin LoaderOptionsPlugin (experimental)
*
* See: https://gist.github.com/sokra/27b24881210b56bbaff7
*/
new LoaderOptionsPlugin({}),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
Tether: "tether",
"window.Tether": "tether",
Tooltip: "exports-loader?Tooltip!bootstrap/js/dist/tooltip",
Alert: "exports-loader?Alert!bootstrap/js/dist/alert",
Button: "exports-loader?Button!bootstrap/js/dist/button",
Carousel: "exports-loader?Carousel!bootstrap/js/dist/carousel",
Collapse: "exports-loader?Collapse!bootstrap/js/dist/collapse",
Dropdown: "exports-loader?Dropdown!bootstrap/js/dist/dropdown",
Modal: "exports-loader?Modal!bootstrap/js/dist/modal",
Popover: "exports-loader?Popover!bootstrap/js/dist/popover",
Scrollspy: "exports-loader?Scrollspy!bootstrap/js/dist/scrollspy",
Tab: "exports-loader?Tab!bootstrap/js/dist/tab",
Util: "exports-loader?Util!bootstrap/js/dist/util"
}),
// Fix Angular 2
new NormalModuleReplacementPlugin(
/facade(\\|\/)async/,
helpers.root('node_modules/@angular/core/src/facade/async.js')
),
new NormalModuleReplacementPlugin(
/facade(\\|\/)collection/,
helpers.root('node_modules/@angular/core/src/facade/collection.js')
),
new NormalModuleReplacementPlugin(
/facade(\\|\/)errors/,
helpers.root('node_modules/@angular/core/src/facade/errors.js')
),
new NormalModuleReplacementPlugin(
/facade(\\|\/)lang/,
helpers.root('node_modules/@angular/core/src/facade/lang.js')
),
new NormalModuleReplacementPlugin(
/facade(\\|\/)math/,
helpers.root('node_modules/@angular/core/src/facade/math.js')
),
new ngcWebpack.NgcWebpackPlugin({
disabled: !AOT,
tsConfig: helpers.root('tsconfig.webpack.json'),
resourceOverride: helpers.root('config/resource-override.js')
})
],
/*
* Include polyfills or mocks for various node stuff
* Description: Node configuration
*
* See: https://webpack.github.io/docs/configuration.html#node
*/
node: {
global: true,
crypto: 'empty',
process: true,
module: false,
clearImmediate: false,
setImmediate: false
}
};
}

View File

@ -0,0 +1,228 @@
const helpers = require('./helpers');
const path = require('path');
const webpackMerge = require('webpack-merge'); // used to merge webpack configs
const webpackMergeDll = webpackMerge.strategy({plugins: 'replace'});
const commonConfig = require('./webpack.common.js'); // the settings that are common to prod and dev
/**
* Webpack Plugins
*/
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const NamedModulesPlugin = require('webpack/lib/NamedModulesPlugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
/**
* Webpack Constants
*/
const ENV = process.env.ENV = process.env.NODE_ENV = 'development';
const HOST = process.env.HOST || 'localhost';
const PORT = process.env.PORT || 3000;
const HMR = helpers.hasProcessFlag('hot');
const METADATA = webpackMerge(commonConfig({env: ENV}).metadata, {
host: HOST,
port: PORT,
ENV: ENV,
HMR: HMR
});
const DllBundlesPlugin = require('webpack-dll-bundles-plugin').DllBundlesPlugin;
/**
* Webpack configuration
*
* See: http://webpack.github.io/docs/configuration.html#cli
*/
module.exports = function (options) {
return webpackMerge(commonConfig({env: ENV}), {
/**
* Developer tool to enhance debugging
*
* See: http://webpack.github.io/docs/configuration.html#devtool
* See: https://github.com/webpack/docs/wiki/build-performance#sourcemaps
*/
devtool: 'cheap-module-source-map',
/**
* Options affecting the output of the compilation.
*
* See: http://webpack.github.io/docs/configuration.html#output
*/
output: {
/**
* The output directory as absolute path (required).
*
* See: http://webpack.github.io/docs/configuration.html#output-path
*/
path: helpers.root('dist'),
/**
* Specifies the name of each output file on disk.
* IMPORTANT: You must not specify an absolute path here!
*
* See: http://webpack.github.io/docs/configuration.html#output-filename
*/
filename: '[name].bundle.js',
/**
* The filename of the SourceMaps for the JavaScript files.
* They are inside the output.path directory.
*
* See: http://webpack.github.io/docs/configuration.html#output-sourcemapfilename
*/
sourceMapFilename: '[name].map',
/** The filename of non-entry chunks as relative path
* inside the output.path directory.
*
* See: http://webpack.github.io/docs/configuration.html#output-chunkfilename
*/
chunkFilename: '[id].chunk.js',
library: 'ac_[name]',
libraryTarget: 'var',
},
plugins: [
/**
* Plugin: DefinePlugin
* Description: Define free variables.
* Useful for having development builds with debug logging or adding global constants.
*
* Environment helpers
*
* See: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
*/
// NOTE: when adding more properties, make sure you include them in custom-typings.d.ts
new DefinePlugin({
'ENV': JSON.stringify(METADATA.ENV),
'HMR': METADATA.HMR,
'process.env': {
'ENV': JSON.stringify(METADATA.ENV),
'NODE_ENV': JSON.stringify(METADATA.ENV),
'HMR': METADATA.HMR,
}
}),
new DllBundlesPlugin({
bundles: {
polyfills: [
'core-js',
{
name: 'zone.js',
path: 'zone.js/dist/zone.js'
},
{
name: 'zone.js',
path: 'zone.js/dist/long-stack-trace-zone.js'
},
'ts-helpers',
],
vendor: [
'@angular/platform-browser',
'@angular/platform-browser-dynamic',
'@angular/core',
'@angular/common',
'@angular/forms',
'@angular/http',
'@angular/router',
'@angularclass/hmr',
'rxjs',
]
},
dllDir: helpers.root('dll'),
webpackConfig: webpackMergeDll(commonConfig({env: ENV}), {
devtool: 'cheap-module-source-map',
plugins: []
})
}),
/**
* Plugin: AddAssetHtmlPlugin
* Description: Adds the given JS or CSS file to the files
* Webpack knows about, and put it into the list of assets
* html-webpack-plugin injects into the generated html.
*
* See: https://github.com/SimenB/add-asset-html-webpack-plugin
*/
new AddAssetHtmlPlugin([
{ filepath: helpers.root(`dll/${DllBundlesPlugin.resolveFile('polyfills')}`) },
{ filepath: helpers.root(`dll/${DllBundlesPlugin.resolveFile('vendor')}`) }
]),
/**
* Plugin: NamedModulesPlugin (experimental)
* Description: Uses file names as module name.
*
* See: https://github.com/webpack/webpack/commit/a04ffb928365b19feb75087c63f13cadfc08e1eb
*/
// new NamedModulesPlugin(),
/**
* Plugin LoaderOptionsPlugin (experimental)
*
* See: https://gist.github.com/sokra/27b24881210b56bbaff7
*/
new LoaderOptionsPlugin({
debug: true,
options: {
context: helpers.root('src'),
output: {
path: helpers.root('dist')
},
/**
* Static analysis linter for TypeScript advanced options configuration
* Description: An extensible linter for the TypeScript language.
*
* See: https://github.com/wbuchwalter/tslint-loader
*/
tslint: {
emitErrors: false,
failOnHint: false,
resourcePath: 'src'
}
}
})
],
/**
* Webpack Development Server configuration
* Description: The webpack-dev-server is a little node.js Express server.
* The server emits information about the compilation state to the client,
* which reacts to those events.
*
* See: https://webpack.github.io/docs/webpack-dev-server.html
*/
devServer: {
port: METADATA.port,
host: METADATA.host,
historyApiFallback: {
index: '/index.html'
},
watchOptions: {
aggregateTimeout: 300,
poll: 1000
}
},
/*
* Include polyfills or mocks for various node stuff
* Description: Node configuration
*
* See: https://webpack.github.io/docs/configuration.html#node
*/
node: {
global: true,
crypto: 'empty',
process: true,
module: false,
clearImmediate: false,
setImmediate: false
}
});
};

View File

@ -0,0 +1,280 @@
const helpers = require('./helpers');
const webpackMerge = require('webpack-merge'); // used to merge webpack configs
const commonConfig = require('./webpack.common.js'); // the settings that are common to prod and dev
/**
* Webpack Plugins
*/
const DedupePlugin = require('webpack/lib/optimize/DedupePlugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const IgnorePlugin = require('webpack/lib/IgnorePlugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
const NormalModuleReplacementPlugin = require('webpack/lib/NormalModuleReplacementPlugin');
const ProvidePlugin = require('webpack/lib/ProvidePlugin');
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
const OptimizeJsPlugin = require('optimize-js-plugin');
/**
* Webpack Constants
*/
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
const HOST = process.env.HOST || 'localhost';
const PORT = process.env.PORT || 8080;
const METADATA = webpackMerge(commonConfig({env: ENV}).metadata, {
host: HOST,
port: PORT,
ENV: ENV,
HMR: false
});
module.exports = function (env) {
return webpackMerge(commonConfig({env: ENV}), {
/**
* Developer tool to enhance debugging
*
* See: http://webpack.github.io/docs/configuration.html#devtool
* See: https://github.com/webpack/docs/wiki/build-performance#sourcemaps
*/
devtool: 'source-map',
/**
* Options affecting the output of the compilation.
*
* See: http://webpack.github.io/docs/configuration.html#output
*/
output: {
/**
* The output directory as absolute path (required).
*
* See: http://webpack.github.io/docs/configuration.html#output-path
*/
path: helpers.root('dist'),
/**
* Specifies the name of each output file on disk.
* IMPORTANT: You must not specify an absolute path here!
*
* See: http://webpack.github.io/docs/configuration.html#output-filename
*/
filename: '[name].[chunkhash].bundle.js',
/**
* The filename of the SourceMaps for the JavaScript files.
* They are inside the output.path directory.
*
* See: http://webpack.github.io/docs/configuration.html#output-sourcemapfilename
*/
sourceMapFilename: '[name].[chunkhash].bundle.map',
/**
* The filename of non-entry chunks as relative path
* inside the output.path directory.
*
* See: http://webpack.github.io/docs/configuration.html#output-chunkfilename
*/
chunkFilename: '[id].[chunkhash].chunk.js'
},
/**
* Add additional plugins to the compiler.
*
* See: http://webpack.github.io/docs/configuration.html#plugins
*/
plugins: [
/**
* Webpack plugin to optimize a JavaScript file for faster initial load
* by wrapping eagerly-invoked functions.
*
* See: https://github.com/vigneshshanmugam/optimize-js-plugin
*/
new OptimizeJsPlugin({
sourceMap: false
}),
/**
* Plugin: DedupePlugin
* Description: Prevents the inclusion of duplicate code into your bundle
* and instead applies a copy of the function at runtime.
*
* See: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
* See: https://github.com/webpack/docs/wiki/optimization#deduplication
*/
// new DedupePlugin(), // see: https://github.com/angular/angular-cli/issues/1587
/**
* Plugin: DefinePlugin
* Description: Define free variables.
* Useful for having development builds with debug logging or adding global constants.
*
* Environment helpers
*
* See: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
*/
// NOTE: when adding more properties make sure you include them in custom-typings.d.ts
new DefinePlugin({
'ENV': JSON.stringify(METADATA.ENV),
'HMR': METADATA.HMR,
'process.env': {
'ENV': JSON.stringify(METADATA.ENV),
'NODE_ENV': JSON.stringify(METADATA.ENV),
'HMR': METADATA.HMR,
}
}),
/**
* Plugin: UglifyJsPlugin
* Description: Minimize all JavaScript output of chunks.
* Loaders are switched into minimizing mode.
*
* See: https://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
*/
// NOTE: To debug prod builds uncomment //debug lines and comment //prod lines
new UglifyJsPlugin({
// beautify: true, //debug
// mangle: false, //debug
// dead_code: false, //debug
// unused: false, //debug
// deadCode: false, //debug
// compress: {
// screw_ie8: true,
// keep_fnames: true,
// drop_debugger: false,
// dead_code: false,
// unused: false
// }, // debug
// comments: true, //debug
beautify: false, //prod
output: {
comments: false
},
mangle: {
screw_ie8: true
}, //prod
compress: {
screw_ie8: true,
warnings: false,
conditionals: true,
unused: true,
comparisons: true,
sequences: true,
dead_code: true,
evaluate: true,
if_return: true,
join_vars: true,
negate_iife: false // we need this for lazy v8
},
comments: false //prod
}),
/**
* Plugin: NormalModuleReplacementPlugin
* Description: Replace resources that matches resourceRegExp with newResource
*
* See: http://webpack.github.io/docs/list-of-plugins.html#normalmodulereplacementplugin
*/
new NormalModuleReplacementPlugin(
/angular2-hmr/,
helpers.root('config/empty.js')
),
new NormalModuleReplacementPlugin(
/zone\.js(\\|\/)dist(\\|\/)long-stack-trace-zone/,
helpers.root('config/empty.js')
),
/**
* Plugin: IgnorePlugin
* Description: Dont generate modules for requests matching the provided RegExp.
*
* See: http://webpack.github.io/docs/list-of-plugins.html#ignoreplugin
*/
// new IgnorePlugin(/angular2-hmr/),
/**
* Plugin: CompressionPlugin
* Description: Prepares compressed versions of assets to serve
* them with Content-Encoding
*
* See: https://github.com/webpack/compression-webpack-plugin
*/
// install compression-webpack-plugin
// new CompressionPlugin({
// regExp: /\.css$|\.html$|\.js$|\.map$/,
// threshold: 2 * 1024
// })
/**
* Plugin LoaderOptionsPlugin (experimental)
*
* See: https://gist.github.com/sokra/27b24881210b56bbaff7
*/
new LoaderOptionsPlugin({
minimize: true,
debug: false,
options: {
context: helpers.root('src'),
output: {
path: helpers.root('dist')
},
/**
* Static analysis linter for TypeScript advanced options configuration
* Description: An extensible linter for the TypeScript language.
*
* See: https://github.com/wbuchwalter/tslint-loader
*/
tslint: {
emitErrors: true,
failOnHint: true,
resourcePath: 'src'
},
/**
* Html loader advanced options
*
* See: https://github.com/webpack/html-loader#advanced-options
*/
// TODO: Need to workaround Angular 2's html syntax => #id [bind] (event) *ngFor
htmlLoader: {
minimize: true,
removeAttributeQuotes: false,
caseSensitive: true,
customAttrSurround: [
[/#/, /(?:)/],
[/\*/, /(?:)/],
[/\[?\(?/, /(?:)/]
],
customAttrAssign: [/\)?\]?=/]
},
}
}),
],
/*
* Include polyfills or mocks for various node stuff
* Description: Node configuration
*
* See: https://webpack.github.io/docs/configuration.html#node
*/
node: {
global: true,
crypto: 'empty',
process: false,
module: false,
clearImmediate: false,
setImmediate: false
}
});
};

12
ng2-admin/dist/webpack-assets.json vendored Normal file
View File

@ -0,0 +1,12 @@
{
"vendor": {
"js": "vendor.bundle.js"
},
"main": {
"js": "main.bundle.js",
"css": "initial.css"
},
"polyfills": {
"js": "polyfills.bundle.js"
}
}

View File

@ -0,0 +1,50 @@
{
"core-js": {
"bundle": "polyfills",
"version": "2.4.1"
},
"zone.js": {
"bundle": "polyfills",
"version": "0.7.7"
},
"ts-helpers": {
"bundle": "polyfills",
"version": "1.1.2"
},
"@angular/platform-browser": {
"bundle": "vendor",
"version": "2.4.7"
},
"@angular/platform-browser-dynamic": {
"bundle": "vendor",
"version": "2.4.7"
},
"@angular/core": {
"bundle": "vendor",
"version": "2.4.7"
},
"@angular/common": {
"bundle": "vendor",
"version": "2.4.7"
},
"@angular/forms": {
"bundle": "vendor",
"version": "2.4.7"
},
"@angular/http": {
"bundle": "vendor",
"version": "2.4.7"
},
"@angular/router": {
"bundle": "vendor",
"version": "3.4.7"
},
"@angularclass/hmr": {
"bundle": "vendor",
"version": "1.2.2"
},
"rxjs": {
"bundle": "vendor",
"version": "5.0.2"
}
}

File diff suppressed because it is too large Load Diff

10897
ng2-admin/dll/polyfills.dll.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

97616
ng2-admin/dll/vendor.dll.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,35 @@
{
"baseUrl": "/ng2-admin/",
"locals": {
"url": "http://localhost:8080",
"name": "ng2-admin blog",
"owner": "Akveo",
"description": ""
},
"plugins": [
"wintersmith-sassy",
"./plugins/paginator.coffee"
],
"sass": {
"debug": "undefined"
},
"require": {
"moment": "moment",
"_": "underscore",
"typogr": "typogr"
},
"jade": {
"pretty": true
},
"markdown": {
"smartLists": true,
"smartypants": true
},
"paginator": {
"perPage": 3,
"groupSort": {
"Quick Start": 1000,
"Customization": 900
}
}
}

View File

@ -0,0 +1,50 @@
---
title: Getting Started
author: vl
sort: 999
group: Quick Start
template: article.jade
---
## What is ng2-admin?
ng2-admin is a front-end Admin Dashboard template based on Angular 2, Bootstrap 4 and Webpack. That means all the
data you can see on graphs, charts and tables is mocked in Javascript so you can use the
backend of your choice with no limitations.
## How can it help me?
We believe that at the moment a lot of business applications have administration/management interfaces inside of them. Sometimes it's not that obvious, but a lot of web applications have dashboards with panels, charts analytics, etc.
ng2-admin aims to bootstrap the development of your product and provide an
ecosystem for building production-ready application or prototypes.
Frameworks like Bootstrap provide a number of components, but usually it's not enough to
build a real-world app. This template comes with lots of popular UI components with a unified color scheme,
plus it is based on a modern Angular 2 framework and has a flexible component based structure.
You can also use ng2-admin for the purpose of learning Angular 2.
## List of features
* Angular 2
* Webpack 2
* Bootstrap 4 CSS Framework
* SASS
* [Smart Table](http://akveo.com/ng2-admin/#/pages/tables/smarttables)
* [Forms](http://akveo.com/ng2-admin/#/pages/forms/inputs)
* [Editors](http://akveo.com/ng2-admin/#/pages/editors/ckeditor)
* [Charts (amChart, Chartist, Chart.js, Morris)](http://akveo.com/ng2-admin/#/pages/charts/chartist-js)
* [Maps (Google, Leaflet, amMap)](http://akveo.com/ng2-admin/#/pages/maps/googlemaps)
* Responsive layout
* High resolution
* and many more!
## I want to start developing with ng2-admin
Welcome aboard!
You can start with the [Installation Guidelines](/ng2-admin/articles/002-installation-guidelines/).
There we describe how you can download and run the template on your local machine.
Good luck and have fun!

View File

@ -0,0 +1,58 @@
---
title: Installation Guidelines
author: vl
sort: 500
group: Quick Start
template: article.jade
---
## Prerequisites
Although ng2-admin can be run without any development experience, it would be much easier if you already have some.
The following instructions allow you to run a local copy on your machine.
## Install tools
If you don't have any of these tools installed already, you will need to:
* Download and install [git](https://git-scm.com/)
* Download and install nodejs [https://nodejs.org](https://nodejs.org)
**Note**: Make sure you have Node version >= 4.0 and NPM >= 3
## Clone repository and install dependencies
You will need to clone the source code of ng2-admin GitHub repository:
```bash
git clone https://github.com/akveo/ng2-admin.git
```
After the repository is cloned, go inside of the repository directory and install dependencies:
```bash
cd ng2-admin
npm install
```
This will setup a working copy of ng2-admin on your local machine.
## Running local copy
To run a local copy in development mode, execute:
```bash
npm start
```
Go to http://0.0.0.0:3000 or http://localhost:3000 in your browser.
To run the local copy in production mode and build the sources, execute:
```bash
npm run prebuild:prod && npm run build:prod && npm run server:prod
```
This will clear up your dist folder (where release files are located), generate a release build and start the
built-in server.
Now you can copy the sources from the `dist` folder and use it with any backend framework or
simply put it under a web server.
For addition information about creating a build, please check out [Angular2 Webpack Starter documentation](https://github.com/AngularClass/angular2-webpack-starter)

View File

@ -0,0 +1,128 @@
---
title: Changing Color Scheme
author: vl
sort: 900
group: Customization
template: article.jade
---
We tried to make the process of color scheme customization as easy as possible.
By default ng2-admin has three built-in color profiles: ng2 (default blue sheme), mint and blur.
This article will help you to create your own color profile.
Let's say you want to make ng2-admin dark theme.
First we advise you to take some existing colorscheme file as a starting point.
For light themes we suggest taking `src/app/theme/sass/conf/colorScheme/_mint.scss` and for
dark `src/app/theme/sass/conf/colorScheme/_blue.scss`.
As we want a dark theme, we're taking `blue`.
1) Copy `src/app/theme/sass/conf/colorScheme/_mint.scss` to `src/app/theme/sass/conf/colorScheme/_dark.scss`:
<br><br>
2) Include your colorscheme file in `src/app/theme/sass/conf/conf.scss`.
To do this, replace
```scss
@import 'colorSchemes/ng2';
```
with
```scss
@import 'colorSchemes/dark';
```
<br><br>
3) Change the color scheme enabled:
Open `src/app/theme/theme.config.ts`.
Uncomment the following line
```javascript
//this._baConfig.changeTheme({name: 'my-theme'});
```
and put your theme name, in our case it is `dark`
```javascript
this._baConfig.changeTheme({name: 'dark'});
```
Beside notifying the system which scheme is currently enabled, this also puts a css class to a main element
of the page. Thus you can freely create theme-specific css selectors in your code without breakking other themes' styles.
For example like this:
```scss
. dark .card-body {
background-color: white;
}
```
<br><br>
4) Change the colors:
Now you can start changing the colors.
For example, after playing a bit with different colors, we changed the 2 first main variables in `_dark.scss` file:
```sass
$body-bg: #636363;
$bootstrap-panel-bg: rgba(#000000, 0.2);
```
After this is done, you need to setup javascript to use the **same colors**. These colors
are used for javascript charts and other components (maps, etc);
Let's completely change the JS colors to a new set.
To do this, add the following code to the configuration block inside `src/app/theme/theme.config.ts`:
```javascript
let colorScheme = {
primary: '#209e91',
info: '#2dacd1',
success: '#90b900',
warning: '#dfb81c',
danger: '#e85656',
};
this._baConfig.changeColors({
default: '#4e4e55',
defaultText: '#e2e2e2',
border: '#dddddd',
borderDark: '#aaaaaa',
primary: colorScheme.primary,
info: colorScheme.info,
success: colorScheme.success,
warning: colorScheme.warning,
danger: colorScheme.danger,
primaryLight: colorHelper.tint(colorScheme.primary, 30),
infoLight: colorHelper.tint(colorScheme.info, 30),
successLight: colorHelper.tint(colorScheme.success, 30),
warningLight: colorHelper.tint(colorScheme.warning, 30),
dangerLight: colorHelper.tint(colorScheme.danger, 30),
primaryDark: colorHelper.shade(colorScheme.primary, 15),
infoDark: colorHelper.shade(colorScheme.info, 15),
successDark: colorHelper.shade(colorScheme.success, 15),
warningDark: colorHelper.shade(colorScheme.warning, 15),
dangerDark: colorHelper.shade(colorScheme.danger, 15),
dashboard: {
blueStone: '#005562',
surfieGreen: '#0e8174',
silverTree: '#6eba8c',
gossip: '#b9f2a1',
white: '#10c4b5',
},
});
```
Here we defined a list of main colors `colorScheme` and then made light and dark versions of those using `colorHelper` methods.
We also defined a couple of custom colors for dashboard charts.
That's basically it! Right now your admin application should look like this:
![](new-color-scheme.png)
For further reference, please look in
- Colorscheme scss file (`src/app/theme/sass/conf/colorScheme/_ng2.scss`, `src/app/theme/sass/conf/colorScheme/_mint.scss` and `src/app/theme/sass/conf/colorScheme/_blur.scss`)
- `src/app/theme/theme.configProvider.js` to understand which javascript colors can be changed
- If you want to know how to change the theme to blur, read the [following article](/ng2-admin/articles/014-switch-to-blur-theme/)

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

View File

@ -0,0 +1,76 @@
---
title: Project Structure
author: vl
sort: 800
group: Customization
template: article.jade
---
The project structure is originally based on [Angular2 Webpack Starter](https://github.com/AngularClass/angular2-webpack-starter#file-structure). We made some changes we thought would be better in our particular case.
The directory structure of this template is as follows:
```
ng2-admin/
├──config/ * webpack build configuration
│ ├──head-config.common.js * configuration for head elements in index.html
│ │
│ ├──helpers.js * helper functions for our configuration files
│ │
│ ├──webpack.dev.js * development webpack config
│ │
│ ├──webpack.prod.js * production webpack config
│ │
│ ├──webpack.test.js * testing webpack config
│ │
│ ├──electron/ * electron webpack config
│ │
│ └──html-elements-plugin/ * html elements plugin
├──src/ * source files that will be compiled to javascript
│ ├──custom-typings.d.ts * custom typings for third-party modules
│ │
│ ├──desktop.ts * electron window initialization
│ │
│ ├──index.html * application layout
│ │
│ ├──main.browser.ts * entry file for our browser environment
│ │
│ ├──package.json * electrons package.json
│ │
│ ├──polyfills.browser.ts * polyfills file
│ │
│ ├──vendor.browser.ts * vendors file
│ │
│ ├──app/ * application code - our working directory
│ │ │
│ │ ├──app.component.ts * main application component
│ │ │
│ │ │
│ │ ├──app.menu.ts * menu pages routes
│ │ │
│ │ ├──app.module.ts * main application module
│ │ │
│ │ ├──app.routes.ts * application routes
│ │ │
│ │ ├──global.state.ts * global application state for data exchange between components
│ │ │
│ │ ├──environment.ts * environment provider
│ │ │
│ │ ├──app.scss * application styles
│ │ │
│ │ ├──pages/ * application pages components, place where you can create pages and fill them with components
│ │ │
│ │ └──theme/ * template global components/directives/pipes and styles
│ │
│ └──assets/ * static assets are served here
├──tslint.json * typescript lint config
├──typedoc.json * typescript documentation generator
├──tsconfig.json * config that webpack uses for typescript
└──package.json * what npm uses to manage it's dependencies
```
In our template we tried to separate the theme layer and presentation layer. We believe most of other templates
have them combined. That's why when you start developing using them, it gets very hard for you to remove things you
don't need.

View File

@ -0,0 +1,137 @@
---
title: Create New Page
author: vl
sort: 300
group: Customization
template: article.jade
---
ng2-admin uses [Angular 2 Component Router](https://angular.io/docs/ts/latest/guide/router.html) for navigation.
We strongly recommend to follow this page structure in your application.
If it does not fit your needs please create a GitHub issue and tell us why. We would be glad to discuss.
Basically any page is just a common Angular 2 Component with a route defined for it.
## Let's create a blank page in 6 easy steps
1) Create a new directory for our new page inside of `src/app/pages`. We can call the directory `new`.
<br><br>
2) Then let's create a blank angular 2 component for our page called 'new.component.ts' inside of `src/app/pages/new`:
```javascript
import {Component} from '@angular/core';
@Component({
selector: 'new',
template: `<strong>My page content here</strong>`
})
export class NewComponent {
constructor() {}
}
```
This will create a simple Angular 2 component. For more detail please check out [official Angular 2 documentation](https://angular.io/docs/ts/latest/guide/displaying-data.html).
<br><br>
3) After that we should create our component routing called `new.routing.ts` in the `new` directory.
```javascript
import { Routes, RouterModule } from '@angular/router';
import { NewComponent } from './new.component';
const routes: Routes = [
{
path: '',
component: NewComponent
}
];
export const routing = RouterModule.forChild(routes);
```
<br>
4) And now we should create `new.module.ts` in `src/app/pages/new` directory and import `new.component.ts` and `new.routing.ts` in it.
```javascript
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NewComponent } from './new.component';
import { routing } from './new.routing';
@NgModule({
imports: [
CommonModule,
routing
],
declarations: [
NewComponent
]
})
export default class NewModule {}
```
<br>
5) The penultimate thing we need to do is to declare a route in `src/app/pages/pages.menu.ts`.
Typically all pages are children of the `/pages` route and defined under the `children` property of the root `pages` route like this:
```javascript
export const PAGES_MENU = [
{
path: 'pages',
children: [
{
path: 'new', // path for our page
data: { // custom menu declaration
menu: {
title: 'New Page', // menu title
icon: 'ion-android-home', // menu icon
pathMatch: 'prefix', // use it if item children not displayed in menu
selected: false,
expanded: false,
order: 0
}
}
},
{
path: 'dashboard',
data: {
menu: {
title: 'Dashboard',
icon: 'ion-android-home',
selected: false,
expanded: false,
order: 0
}
}
}
}
}
]
```
If youd like to highlight menu item when current URL path partially match the menu item
path - use pathMatch: prefix. In this case if the menu item has no children in the menu and
you navigated to some child route - the item will be highlighted.
<br><br>
6) And in the end let's import our component in `src/app/pages/pages.routing.ts` like this:
```javascript
const routes: Routes = [
{
path: 'pages',
component: Pages,
children: [
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
{ path: 'dashboard', loadChildren: () => System.import('./dashboard/dashboard.module') },
{ path: 'new', loadChildren: () => System.import('./new/new.module') }
]
}
];
```
<br>
And that's it! Now your page is available by the following this url [http://localhost:3000/#/pages/new](http://localhost:3000/#/pages/new).
Plus, your page is registered inside the sidebar menu. If you don't want to have a link
in the menu - just remove the `menu` declaration from the `pages.menu.ts` file.

View File

@ -0,0 +1,85 @@
---
title: Enabling blur theme
author: kd
sort: 850
group: Customization
template: article.jade
---
If you want to switch theme to the blur, you need to follow 3 simple steps:
1) Blur color scheme needs some javascript to calculate initial background offsets for panels.
That's why we need to tell the system that we want to use blur theme by specifying this in `src/app/theme/theme.config.ts`:
```javascript
this._baConfig.changeTheme({name: 'blur'});
```
<br><br>
2) Also you need to change some colors.
For our blur theme we use the following configuration in `src/app/theme/theme.config.ts`:
```javascript
let colorScheme = {
primary: '#209e91',
info: '#2dacd1',
success: '#90b900',
warning: '#dfb81c',
danger: '#e85656',
};
this._baConfig.changeColors({
default: '#4e4e55',
defaultText: '#e2e2e2',
border: '#dddddd',
borderDark: '#aaaaaa',
primary: colorScheme.primary,
info: colorScheme.info,
success: colorScheme.success,
warning: colorScheme.warning,
danger: colorScheme.danger,
primaryLight: colorHelper.tint(colorScheme.primary, 30),
infoLight: colorHelper.tint(colorScheme.info, 30),
successLight: colorHelper.tint(colorScheme.success, 30),
warningLight: colorHelper.tint(colorScheme.warning, 30),
dangerLight: colorHelper.tint(colorScheme.danger, 30),
primaryDark: colorHelper.shade(colorScheme.primary, 15),
infoDark: colorHelper.shade(colorScheme.info, 15),
successDark: colorHelper.shade(colorScheme.success, 15),
warningDark: colorHelper.shade(colorScheme.warning, 15),
dangerDark: colorHelper.shade(colorScheme.danger, 15),
dashboard: {
blueStone: '#005562',
surfieGreen: '#0e8174',
silverTree: '#6eba8c',
gossip: '#b9f2a1',
white: '#10c4b5',
},
});
```
<br><br>
3) CSS should also be recompiled.
Before running build command, switch to *blur* color profile.
To do so replace theme in `src/app/theme/sass/conf/conf.scss`:
```scss
@import 'colorSchemes/ng2';
```
to
```scss
@import 'colorSchemes/blur';
```
Additionaly, if you would like to use some different background, replace the following images:
- `src/assets/img/blur-bg.jpg` (main background image)
- `src/assets/img/blur-bg-blurred.jpg` (blurred background image used on panels)
We suggest using 10px Gaussian blur to blur an original image.
<br><br>
That's it! You have successfully blurred your theme! Run `npm start` and check it out.

View File

@ -0,0 +1,97 @@
---
title: Sidebar
author: vl
sort: 900
group: Components
template: article.jade
---
The sidebar provides a convenient way to navigate the application.
Only one sidebar is supported per angular application.
This means that the sidebar is basically a singleton object.
The Sidebar can be added to the page using the `BaSidebar` component:
```html
<ba-sidebar></ba-sidebar>
```
The sidebar contains a `<ba-menu></ba-menu>` component which defines and renders the application menu based on routes provided. Generally the `ba-menu` component can be used separately from `ba-sidebar`.
All menu items information is defined inside the `data` property of a route.
## Menu Configuration
All menu items are located inside the `src/app/app.routes.ts` file. Each route item can have a `menu` property under `data` defining a menu item:
```javascript
{
// first, router configuration
path: 'dashboard',
component: Dashboard,
data: {
// here additionaly we define how the menu item should look
menu: {
title: 'Dashboard', // menu title
icon: 'ion-android-home', // menu icon
selected: false, // selected or not
expanded: false, // expanded or not (if item has children)
order: 0, // item order in the menu list,
hidden: true // hide menu item from a list but keep related features (breadcrumbs, page title)
}
}
}
```
You also can define a list of sub-menu items like this:
```javascript
{
// parent route
path: 'charts',
component: Charts,
data: {
// parent menu configuration
menu: {
title: 'Charts',
icon: 'ion-stats-bars',
selected: false,
expanded: false,
order: 200,
}
},
// children routes
children: [
{
path: 'chartist-js',
component: ChartistJs,
data: {
// children menu item configuration
menu: {
title: 'Chartist.Js',
}
}
}
]
}
```
# Custom menu items
You also can define a menu item not connected to any existing route in the application:
```javascript
{
path: '', // just leave the path empty
data: {
// and define your menu item
menu: {
title: 'External Link', // title
url: 'http://akveo.com', // custom url
icon: 'ion-android-exit', // icon
order: 800, // order
target: '_blank' // target property of <a> tag (_self, _blank, etc)
}
}
}
```

View File

@ -0,0 +1,61 @@
---
title: Theme Spinner
author: vl
sort: 950
group: Components
template: article.jade
---
Theme Spinner `BaThemeSpinner` is a small service helper allowing you to show a preloader spinner while
executing some long-running tasks.
This is the same spinner you can see after reloading a page - it is shown while the application is initializing Angular 2 and loading charts and images.
The user interface in quite simple: there are two public methods: `show` and `hide`.
Theme Spinner comes with another small helper called `BaThemePreloader`.
This service is globally integrated into the application and connected to the spinner.
You can register any promise in any part of the application so that the spinner will be
hidden only after your promise is completed (resolved).
You can find an example of usage inside of the `app.component.ts` file.
Here we are registering a loader (`this._imageLoader.load` just returns a `Promise`) which loads a background image:
```javascript
BaThemePreloader.registerLoader(this._imageLoader.load(layoutPaths.images.root + 'blur-bg-mobile.jpg'));
```
Then we are starting all the registered promises and once they all are done - hiding the spinner.
```javascript
BaThemePreloader.load().then((values) => {
this._spinner.hide();
});
```
## Example
You also can register a loader on any page you want.
Say you have a long-running task on the Charts page (you need to receive some data from a web service) and you want the spinner to be shown while the data is loading.
First thing you need to do is to import BaThemePreloader service:
```javascript
import {BaThemePreloader} from '../../../../theme/services';
```
Then, say you have a method loading some data called `_loadData`, in our case we just mocked this method with `setTimeout` to emulate the loading process:
```javascript
private _loadData():Promise<any> {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, 4000);
});
}
```
Last thing you need to do is to register your loader:
```javascript
BaThemePreloader.registerLoader(this._loadData());
```
That's basically it! Once your data is loaded and all other registered loaders are completed - the spinner will be hidden.

View File

@ -0,0 +1,920 @@
@mixin header {
margin: 10px 0;
font-family: inherit;
font-weight: bold;
color: inherit;
text-rendering: optimizelegibility;
}
html {
font-family: 'Source Sans Pro', sans-serif;
color: #484848;
line-height: 1.28
}
body {
position: relative;
min-width: 1060px;
}
p {
margin: 0 0 10px
}
em {
font-style: italic
}
h1 {
@include header;
line-height: 40px;
font-size: 39px
}
h2 {
@include header;
line-height: 40px;
margin-top: 30px;
font-size: 31px;
}
h3 {
@include header;
line-height: 40px;
font-size: 23px;
}
h4 {
@include header;
line-height: 20px;
font-size: 16px;
}
h5 {
@include header;
line-height: 40px;
text-transform: uppercase;
font-size: 14px;
}
h6 {
@include header;
line-height: 20px;
font-size: 11px;
}
h1 small {
font-size: 24px;
}
h2 small {
font-size: 18px;
}
h3 small {
font-size: 16px;
}
h4 small {
font-size: 14px;
}
ul, ol {
margin: 0 0 10px 25px;
padding: 0
}
ul ul, ul ol, ol ol, ol ul {
margin-bottom: 0
}
li {
line-height: 20px
}
a {
color: #285eb8;
text-decoration: none
}
a:hover, a:focus {
color: #234fb8;
text-decoration: underline
}
a:focus {
outline: thin dotted #333;
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px
}
.center {
text-align: center
}
body, pre {
border: none;
margin: 0;
padding: 0
}
html {
background: #f9f9f9
}
.browser-mockup {
border-top: 2em solid #F3F3F3;
position: relative;
border-radius: 3px 3px 0 0
}
.browser-mockup:before {
display: block;
position: absolute;
content: '';
top: -1.25em;
left: 1em;
width: 0.5em;
height: 0.5em;
border-radius: 50%;
background-color: #f44;
box-shadow: 0 0 0 2px #f44, 1.5em 0 0 2px #9b3, 3em 0 0 2px #fb5;
}
.browser-mockup a {
display: block;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
border: 1px solid #ddd;
width: 100%;
}
.left {
float: left
}
.right {
float: right
}
.container {
padding-top: 50px;
min-width: 1060px
}
.wrap {
width: 1060px;
box-sizing: border-box;
margin-left: auto;
margin-right: auto;
padding-left: 20px;
padding-right: 20px;
}
.skinnyWrap {
width: 690px;
box-sizing: border-box;
margin-left: auto;
margin-right: auto;
padding-left: 20px;
padding-right: 20px;
}
hr {
height: 0;
border-top: 1px solid #ccc;
border-bottom: 1px solid #eee
}
ul, li {
margin-left: 20px
}
li + li {
margin-top: 10px
}
h1 .anchor, h2 .anchor, h3 .anchor, h4 .anchor, h5 .anchor, h6 .anchor {
margin-top: -50px;
position: absolute
}
h1:hover .hash-link, h2:hover .hash-link, h3:hover .hash-link, h4:hover .hash-link, h5:hover .hash-link, h6:hover .hash-link {
display: inline
}
.hash-link {
color: #aaa;
display: none
}
.nav-main {
background: #222;
color: #fafafa;
position: fixed;
top: 0;
height: 50px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
width: 100%;
z-index: 100
}
.nav-main:after {
content: "";
display: table;
clear: both
}
.nav-main a {
color: #e9e9e9;
text-decoration: none
}
.nav-main .nav-site-internal {
margin: 0 0 0 20px
}
.nav-main .nav-site-external {
float: right;
margin: 0
}
.nav-main .nav-site li {
margin: 0
}
.nav-main .nav-site li > a {
box-sizing: content-box;
padding: 0 10px;
line-height: 50px;
display: inline-block;
height: 50px;
color: #ddd
}
.nav-main .nav-site li > a:hover {
color: #fff
}
.nav-main .nav-site li > a.active {
color: #fafafa;
border-bottom: 3px solid #00abff;
background: #333
}
.nav-main .nav-home {
color: #ffffff;
font-size: 24px;
line-height: 50px;
height: 50px;
display: inline-block
}
.nav-main .nav-home .blur-label {
color: #00abff;
}
.nav-main .nav-logo {
vertical-align: middle;
display: inline-block;
margin-bottom: 9px;
}
.nav-main ul {
display: inline-block;
vertical-align: top
}
.nav-main li {
display: inline
}
.hero {
padding-bottom: 75px;
}
.hero .hero-content {
color: #e9e9e9;
font-weight: 300;
background: #313131;
padding-top: 50px;
}
.hero .text {
font-size: 64px;
text-align: center
}
.hero .minitext {
font-size: 16px;
text-align: center;
text-transform: uppercase
}
.hero strong {
color: #00abff;
font-weight: 400
}
.white-text {
color: rgb(249, 249, 249);
}
.hero .admin-screenshots {
margin-top: 40px;
display: flex;
flex-direction: row;
}
.hero .admin-screenshot {
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 0 15px;
text-align: center;
}
.admin-screenshot img {
width: 100%;
}
.demo-link {
display: block;
position: relative;
line-height: 0;
}
.demo-link:before {
content: '';
position: absolute;
width: 100%;
bottom: 0;
left: 0;
height: 52px;
background-image: linear-gradient(to bottom, transparent, rgb(249, 259, 249));
}
.demo-link .demo-link-label {
display: flex;
align-items: center;
justify-content: center;
content: 'Demo';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: black;
background: rgba(0, 0, 0, 0.5);
color: rgb(249, 249, 249);
font-size: 32px;
opacity: 0;
transition: opacity 0.3s ease-out;
}
.demo-link:hover .demo-link-label {
opacity: 1;
}
.buttons-unit {
margin-top: 60px;
text-align: center
}
.buttons-unit a {
color: #61dafb
}
.buttons-unit .button {
font-size: 24px;
background: #00abff;
color: #fafafa;
}
.buttons-unit .button:active, .buttons-unit .button:focus {
background: #00abff;
text-decoration: none;
}
.index-block {
padding: 40px 0;
&:nth-child(even) {
background: #f2f2f2;
}
}
.centered {
text-align: center;
}
.why-items {
display: flex;
flex-direction: row;
align-items: baseline;
margin-top: 15px;
padding-top: 15px;
}
.why-item {
flex: 33%;
text-align: center;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 0 15px;
}
.why-item img {
width: 110px;
}
.nav-docs {
color: #2d2d2d;
font-size: 14px;
float: left;
width: 210px
}
.nav-docs ul {
list-style: none;
margin: 0
}
.nav-docs ul ul {
margin: 6px 0 0 20px
}
.nav-docs li {
line-height: 16px;
margin: 0 0 6px
}
.nav-docs a {
color: #666;
display: block
}
.nav-docs a:hover {
text-decoration: none;
color: #285eb8
}
.nav-docs a.active {
color: #285eb8
}
.nav-docs a.external:after {
content: "";
display: inline-block;
width: 10px;
height: 10px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding-left: 5px;
background: url("../img/external.png") 100% 0 no-repeat;
font-size: 10px;
line-height: 1em;
opacity: 0.5
}
@media only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen and (min--moz-device-pixel-ratio: 1.3), only screen and (-o-min-device-pixel-ratio: 1.3 / 1), only screen and (min-resolution: 125dpi), only screen and (min-resolution: 1.3dppx) {
.nav-docs a.external:after {
background-image: url("../img/external_2x.png");
background-size: 10px 10px
}
}
.nav-docs .nav-docs-section {
border-bottom: 1px solid #ccc;
border-top: 1px solid #eee;
padding: 12px 0
}
.nav-docs .nav-docs-section:first-child {
padding-top: 0;
border-top: 0
}
.nav-docs .nav-docs-section:last-child {
padding-bottom: 0;
border-bottom: 0
}
.nav-blog li {
margin-bottom: 5px
}
.nav-docs-right {
display: block;
float: right;
line-height: 50px;
}
.nav-docs-right a {
color: #00abff;
text-decoration: none;
}
.nav-docs-right a:hover {
text-decoration: underline;
}
.home-section {
margin: 50px 0
}
.home-divider {
border-top-color: #bbb;
margin: 0 auto;
width: 400px
}
.skinny-row:after {
content: "";
display: table;
clear: both
}
.skinny-col {
float: left;
margin-left: 40px;
width: 305px
}
.skinny-col:first-child {
margin-left: 0
}
.marketing-row {
margin: 50px 0
}
.marketing-row:after {
content: "";
display: table;
clear: both
}
.marketing-col {
float: left;
margin-left: 40px;
width: 280px;
}
.marketing-col p {
font-size: 16px
}
.marketing-col:first-child {
margin-left: 0
}
.home-bottom-section {
margin-bottom: 100px
}
.docs-nextprev:after {
content: "";
display: table;
clear: both
}
.jsxCompiler {
margin: 0 auto;
padding-top: 20px;
width: 1220px
}
.jsxCompiler .compiler-option {
display: block;
margin-top: 5px
}
.jsxCompiler .playgroundPreview {
padding: 0;
width: 600px;
word-wrap: break-word
}
.jsxCompiler .playgroundPreview pre {
font-family: 'source-code-pro', Menlo, Consolas, 'Courier New', monospace;
font-size: 13px;
line-height: 1.5
}
.jsxCompiler .playgroundError {
padding: 15px 20px
}
.docs-prev {
float: left
}
.docs-next {
float: right
}
footer {
font-size: 13px;
font-weight: 600;
margin-top: 66px;
margin-bottom: 18px;
overflow: auto
}
.blogContent {
padding-top: 20px
}
.blogContent:after {
content: "";
display: table;
clear: both
}
.blogContent blockquote {
padding: 5px 15px;
margin: 20px 0;
background-color: #f8f5ec;
border-left: 5px solid #f7ebc6
}
.blogContent code {
font-size: inherit;
line-height: inherit;
color: #555;
background-color: black;
background-color: rgba(0, 0, 0, 0.04)
}
.documentationContent {
padding-top: 20px
}
.documentationContent:after {
content: "";
display: table;
clear: both
}
.documentationContent blockquote {
padding: 15px 30px 15px 15px;
margin: 20px 0;
background-color: black;
background-color: rgba(204, 122, 111, 0.1);
border-left: 5px solid black;
border-left: 5px solid rgba(191, 87, 73, 0.2);
}
.documentationContent blockquote p {
margin-bottom: 0
}
.documentationContent blockquote p:first-child {
font-weight: bold;
font-size: 17.5px;
line-height: 20px;
margin-top: 0;
text-rendering: optimizelegibility
}
.docs-prevnext {
padding-top: 40px;
padding-bottom: 40px
}
.button {
background: -webkit-linear-gradient(#9a9a9a, #646464);
background: -moz-linear-gradient(#9a9a9a, #646464);
background: -ms-linear-gradient(#9a9a9a, #646464);
background: -o-linear-gradient(#9a9a9a, #646464);
background: -webkit-gradient(#9a9a9a, #646464);
background: linear-gradient(#9a9a9a, #646464);
border-radius: 4px;
padding: 8px 16px;
font-size: 18px;
font-weight: 400;
margin: 0 12px;
display: inline-block;
color: #fafafa;
text-decoration: none;
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
}
.button:hover {
text-decoration: none
}
.button:active {
box-shadow: none
}
.hero .button {
box-shadow: 1px 3px 3px rgba(0, 0, 0, 0.3)
}
.row {
padding-bottom: 4px
}
.row .span4 {
width: 33.33%;
display: table-cell
}
.row .span8 {
width: 66.66%;
display: table-cell
}
.row .span6 {
width: 50%;
display: table-cell
}
p {
margin: 10px 0
}
.highlight {
padding: 10px;
margin-bottom: 20px
}
figure {
text-align: center
}
.inner-content {
float: right;
width: 650px
}
.nosidebar .inner-content {
float: none;
margin: 0 auto
}
.inner-content img {
max-width: 100%;
}
.inner-content table {
border-collapse: collapse;
width: 100%;
}
.inner-content th, .inner-content td {
padding: 0.25rem;
text-align: left;
border: 1px solid #ccc;
}
.inner-content tbody tr:nth-child(odd) {
background: #eee;
}
h1:after {
content: "";
display: table;
clear: both
}
.edit-page-link {
float: right;
font-size: 16px;
font-weight: normal;
line-height: 20px;
margin-top: 17px
}
.post-list-item + .post-list-item {
margin-top: 60px
}
/* code styling */
code {
font-family: 'Anonymous Pro', sans-serif;
font-size: 0.85em;
color: #000;
}
pre code {
display: block;
line-height: 1.1;
color: #333333;
background: #f8f5ec;
padding: 30px 14px 14px;
position: relative;
overflow-x: auto;
}
pre code:before {
position: absolute;
top: 0;
right: 0;
left: 0;
padding: 3px 7px;
font-size: 12px;
font-weight: bold;
color: #c2c0bc;
background-color: #f1ede4;
content: "Code";
}
p code {
padding: 0.1em 0.3em 0.2em;
border-radius: 0.3em;
position: relative;
background: #fffff3;
white-space: nowrap;
}
/* syntax hl stuff */
code.lang-markdown {
color: #424242;
}
code.lang-markdown .header,
code.lang-markdown .strong {
font-weight: bold;
}
code.lang-markdown .emphasis {
font-style: italic;
}
code.lang-markdown .horizontal_rule,
code.lang-markdown .link_label,
code.lang-markdown .code,
code.lang-markdown .header,
code.lang-markdown .link_url {
color: #555;
}
code.lang-markdown .blockquote,
code.lang-markdown .bullet {
color: #bbb;
}
/* Tomorrow Theme */
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
/* Original theme - https://github.com/chriskempson/tomorrow-theme */
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
.tomorrow-comment, pre .comment, pre .title {
color: #8e908c;
}
.tomorrow-red, pre .variable, pre .attribute, pre .tag, pre .regexp, pre .ruby .constant, pre .xml .tag .title, pre .xml .pi, pre .xml .doctype, pre .html .doctype, pre .css .id, pre .css .class, pre .css .pseudo {
color: #c82829;
}
.tomorrow-orange, pre .number, pre .preprocessor, pre .built_in, pre .literal, pre .params, pre .constant {
color: #f5871f;
}
.tomorrow-yellow, pre .class, pre .ruby .class .title, pre .css .rules .attribute {
color: #eab700;
}
.tomorrow-green, pre .string, pre .value, pre .inheritance, pre .header, pre .ruby .symbol, pre .xml .cdata {
color: #718c00;
}
.tomorrow-aqua, pre .css .hexcolor {
color: #3e999f;
}
.tomorrow-blue, pre .function, pre .python .decorator, pre .python .title, pre .ruby .function .title, pre .ruby .title .keyword, pre .perl .sub, pre .javascript .title, pre .coffeescript .title {
color: #4271ae;
}
.tomorrow-purple, pre .keyword, pre .javascript .function {
color: #8959a8;
}
/* media queries */
@media screen and (max-width: 960px) {
.nav-main {
position: static
}
.container {
padding-top: 0
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@ -0,0 +1 @@
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'><svg height="110px" style="enable-background:new 0 0 110 110;" version="1.0" viewBox="0 0 110 110" width="110px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="Artboard"/><g id="Multicolor"><circle cx="55" cy="55" r="55" style="fill:#00abff;"/><g><g><path d="M81.937,24.303C81.205,23.507,80.166,23,79,23H31c-2.209,0-4,1.791-4,4v56c0,2.209,1.791,4,4,4h48 c2.209,0,4-1.791,4-4V27C83,25.957,82.591,25.015,81.937,24.303z" style="fill:#F0F1F1;"/></g><g><path d="M31,29c0-1.104,0.895-2,2-2h12c1.105,0,2,0.896,2,2v30.239l4.436-4.436 C51.179,54.623,51,54.338,51,54V44c0-0.552,0.448-1,1-1h10c0.338,0,0.622,0.179,0.803,0.436l4.632-4.632 C67.179,38.623,67,38.338,67,38V28c0-0.552,0.448-1,1-1h10c0.338,0,0.622,0.179,0.803,0.436l3.133-3.133 C81.205,23.507,80.166,23,79,23H31c-2.209,0-4,1.791-4,4v52.239l4-4V29z M51,28c0-0.552,0.448-1,1-1h10c0.552,0,1,0.448,1,1v10 c0,0.552-0.448,1-1,1H52c-0.552,0-1-0.448-1-1V28z" style="fill:#FFFFFF;"/></g><g><path d="M45,27H33c-1.105,0-2,0.896-2,2v46.239V81c0,1.104,0.895,2,2,2h12c1.105,0,2-0.896,2-2V59.239V29 C47,27.896,46.105,27,45,27z" style="fill:#F4D0A1;"/></g><g><path d="M45,27H33c-1.105,0-2,0.896-2,2v46.239l16-16V29C47,27.896,46.105,27,45,27z" style="fill:#F8E1C2;"/></g><g><path d="M52,39h10c0.552,0,1-0.448,1-1V28c0-0.552-0.448-1-1-1H52c-0.552,0-1,0.448-1,1v10 C51,38.552,51.448,39,52,39z" style="fill:#F79392;"/></g><g><path d="M78.803,27.436C78.622,27.179,78.338,27,78,27H68c-0.552,0-1,0.448-1,1v10 c0,0.338,0.179,0.623,0.436,0.803C67.598,38.918,67.786,39,68,39h10c0.552,0,1-0.448,1-1V28 C79,27.786,78.918,27.599,78.803,27.436z" style="fill:#FACB1B;"/></g><g><path d="M78,27H68c-0.552,0-1,0.448-1,1v10c0,0.338,0.179,0.623,0.436,0.803l11.368-11.368 C78.622,27.179,78.338,27,78,27z" style="fill:#FBE158;"/></g><g><path d="M62.803,43.436C62.622,43.179,62.338,43,62,43H52c-0.552,0-1,0.448-1,1v10 c0,0.338,0.179,0.623,0.436,0.803C51.598,54.918,51.786,55,52,55h10c0.552,0,1-0.448,1-1V44 C63,43.786,62.918,43.599,62.803,43.436z" style="fill:#12B2A0;"/></g><g><path d="M62,43H52c-0.552,0-1,0.448-1,1v10c0,0.338,0.179,0.623,0.436,0.803l11.368-11.368 C62.622,43.179,62.338,43,62,43z" style="fill:#47C4B7;"/></g><g><path d="M39,43h-4v4l1.876,30.024C36.946,78.135,37.867,79,38.98,79H39h0.02 c1.113,0,2.034-0.865,2.104-1.976L43,47v-4H39z" style="fill:#84462D;"/></g><g><path d="M35,43v4l1.876,30.024C36.946,78.135,37.867,79,38.98,79H39V43H35z" style="fill:#9C6144;"/></g><g><path d="M79,54c0,0.552-0.448,1-1,1H68c-0.552,0-1-0.448-1-1V44c0-0.552,0.448-1,1-1h10 c0.552,0,1,0.448,1,1V54z" style="fill:#47C4B7;"/></g><g><path d="M63,70c0,0.552-0.448,1-1,1H52c-0.552,0-1-0.448-1-1V60c0-0.552,0.448-1,1-1h10 c0.552,0,1,0.448,1,1V70z" style="fill:#40C9E7;"/></g><g><path d="M79,70c0,0.552-0.448,1-1,1H68c-0.552,0-1-0.448-1-1V60c0-0.552,0.448-1,1-1h10 c0.552,0,1,0.448,1,1V70z" style="fill:#40C9E7;"/></g><g><path d="M79,82c0,0.552-0.448,1-1,1H52c-0.552,0-1-0.448-1-1v-6c0-0.552,0.448-1,1-1h26 c0.552,0,1,0.448,1,1V82z" style="fill:#F4D0A1;"/></g><g><path d="M39,30L39,30c0,0-5,5.687-5,9c0,1.851,0.713,3.175,1.811,4H39h3.189 C43.287,42.175,44,40.851,44,39C44,35.687,39.001,30.001,39,30z" style="fill:#3E3E3F;"/></g><g><path d="M34,39c0,1.851,0.713,3.175,1.811,4H39V30h0C39,30,34,35.687,34,39z" style="fill:#5B5C5F;"/></g><g><polygon points="39,43 35,43 35,47 39,47 43,47 43,43 " style="fill:#F3B607;"/></g><g><polygon points="35.811,43 35,43 35,47 39,47 39,43 " style="fill:#FACB1B;"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'><svg height="110px" style="enable-background:new 0 0 110 110;" version="1.0" viewBox="0 0 110 110" width="110px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="Artboard"/><g id="Multicolor"><circle cx="55" cy="55" r="55" style="fill:#00abff;"/><g><g><path d="M23,26.84c0-2.121,1.719-3.84,3.84-3.84H55l16,13.44v46.72c0,2.121-1.719,3.84-3.84,3.84H26.84 C24.719,87,23,85.281,23,83.16V26.84z" style="fill:#FFFFFF;"/><path d="M55,23v9.6c0,2.121,1.719,3.84,3.84,3.84H71L55,23z" style="fill:#F0F1F1;"/></g><path d="M52,70h10c0.551,0,1-0.448,1-1v-5c0-0.552-0.449-1-1-1H52c-0.551,0-1,0.448-1,1v5 C51,69.552,51.449,70,52,70z" style="fill:#E2E4E5;"/><path d="M62,72H52c-1.654,0-3-1.346-3-3v-5c0-1.654,1.346-3,3-3h10c1.654,0,3,1.346,3,3v5 C65,70.654,63.654,72,62,72z M52,63c-0.551,0-1,0.448-1,1v5c0,0.552,0.449,1,1,1h10c0.551,0,1-0.448,1-1v-5c0-0.552-0.449-1-1-1 H52z" style="fill:#B6BCBD;"/><path d="M30,70h10c0.551,0,1-0.448,1-1v-5c0-0.552-0.449-1-1-1H30c-0.551,0-1,0.448-1,1v5 C29,69.552,29.449,70,30,70z" style="fill:#E2E4E5;"/><path d="M40,72H30c-1.654,0-3-1.346-3-3v-5c0-1.654,1.346-3,3-3h10c1.654,0,3,1.346,3,3v5 C43,70.654,41.654,72,40,72z M30,63c-0.551,0-1,0.448-1,1v5c0,0.552,0.449,1,1,1h10c0.551,0,1-0.448,1-1v-5c0-0.552-0.449-1-1-1 H30z" style="fill:#B6BCBD;"/><path d="M41,50h10c0.551,0,1-0.448,1-1v-5c0-0.552-0.449-1-1-1H41c-0.551,0-1,0.448-1,1v5 C40,49.552,40.449,50,41,50z" style="fill:#9CE5F4;"/><g><polygon points="50.272,52 48.014,52 52.728,61 54.986,61 " style="fill:#CFD3D4;"/></g><g><polygon points="41.728,52 37.014,61 39.272,61 43.986,52 " style="fill:#CFD3D4;"/></g><path d="M51,52H41c-1.654,0-3-1.346-3-3v-5c0-1.654,1.346-3,3-3h10c1.654,0,3,1.346,3,3v5 C54,50.654,52.654,52,51,52z M41,43c-0.551,0-1,0.448-1,1v5c0,0.552,0.449,1,1,1h10c0.551,0,1-0.448,1-1v-5c0-0.552-0.449-1-1-1 H41z" style="fill:#40C9E7;"/><g><path d="M84.144,57.498L62.941,81.466l-5.877,1.21c-0.17-0.818-0.593-1.593-1.267-2.189 c-0.674-0.596-1.495-0.922-2.328-0.991l0.484-5.981l21.203-23.967L84.144,57.498z" style="fill:#F4D0A1;"/></g><g><path d="M84.115,57.473c0.016,0.014,0.017,0.038,0.003,0.054L63.397,80.95 c-0.033,0.038-0.086-0.002-0.062-0.047c0.651-1.2,0.414-2.728-0.653-3.672c-1.126-0.996-2.785-0.995-3.905-0.062 c-0.032,0.027-0.075-0.011-0.052-0.046c0.79-1.225,0.589-2.871-0.537-3.868c-1.079-0.955-2.648-0.993-3.762-0.173 c-0.036,0.027-0.077-0.015-0.047-0.049l20.752-23.458c0.014-0.016,0.038-0.017,0.054-0.003L84.115,57.473z" style="fill:#059BBF;"/></g><g><rect height="2" style="fill:#FACB1B;" transform="matrix(0.749 0.6626 -0.6626 0.749 55.1274 -39.9673)" width="12" x="74.313" y="51.774"/></g><g><path d="M84.996,47.571l-0.09-0.08c-2.457-2.174-6.211-1.944-8.385,0.513l-0.04,0.045L85.469,56 l0.04-0.045C87.683,53.498,87.453,49.744,84.996,47.571z" style="fill:#F79392;"/></g><g><path d="M84.119,57.527L63.371,80.979c-0.03,0.034-0.077-0.002-0.055-0.042 c0.674-1.205,0.444-2.753-0.634-3.707c-1.124-0.994-2.777-0.995-3.897-0.068c-0.019,0.015-0.041-0.008-0.025-0.026l20.865-23.586 c0.014-0.016,0.038-0.017,0.053-0.003l4.437,3.925C84.131,57.487,84.133,57.511,84.119,57.527z" style="fill:#0484AB;"/></g><g><path d="M57.064,82.675l-3.918,0.807l0.323-3.987c0.833,0.069,1.654,0.395,2.328,0.991 C56.471,81.082,56.894,81.857,57.064,82.675z" style="fill:#3E3E3F;"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,4 @@
{
"template": "index.jade",
"activeHome": true
}

View File

@ -0,0 +1,10 @@
{
"dependencies": {
"moment": "2.3.x",
"typogr": "0.5.x",
"underscore": "1.4.x",
"wintersmith": "2.3.1",
"wintersmith-sassy": "^1.0.0"
},
"private": true
}

View File

@ -0,0 +1,44 @@
module.exports = (env, callback) ->
### Paginator plugin. Defaults can be overridden in config.json
e.g. "paginator": {"perPage": 10} ###
defaults =
template: 'index.jade' # template that renders pages
articles: 'articles' # directory containing contents to paginate
first: 'index.html' # filename/url for first page
filename: 'page/%d/index.html' # filename for rest of pages
perPage: 2 # number of articles per page
groupSort: {}
# assign defaults any option not set in the config file
options = env.config.paginator or {}
for key, value of defaults
options[key] ?= defaults[key]
getArticles = (contents) ->
# helper that returns a list of articles found in *contents*
# note that each article is assumed to have its own directory in the articles directory
articles = contents[options.articles]._.directories.map (item) -> item.index
# skip articles that does not have a template associated
articles = articles.filter (item) -> item.template isnt 'none'
# sort article by date
articles.sort (a, b) -> b.metadata.sort - a.metadata.sort
groupedArticlesObj = articles.reduce (acc, curr) ->
groupName = curr.metadata.group
if not acc[groupName]
acc[groupName] =
groupName: groupName
items: []
acc[groupName].items.push curr
return acc
, {}
groupedArticles = (val for key, val of groupedArticlesObj)
groupedArticles.sort (a, b) -> (options.groupSort[b.groupName] || 0) - (options.groupSort[a.groupName] || 0)
return groupedArticles
# add the article helper to the environment so we can use it later
env.helpers.getGroupedArticles = getArticles
# tell the plugin manager we are done
callback()

21
ng2-admin/docs/templates/article.jade vendored Normal file
View File

@ -0,0 +1,21 @@
extends layout
block title
| ng2-admin documentation - #{page.title]
block content
section.content.wrap.documentationContent
div.nav-docs
each group in groupedArticles
div.nav-docs.section
h5=group.groupName
ul
each article in group.items
li
a(href=article.url)(class= locals.page === article ? 'active': '')= article.title
div.inner-content
h1=locals.page.title
div.subHeader
!= typogr(page.html).typogrify()

59
ng2-admin/docs/templates/index.jade vendored Normal file
View File

@ -0,0 +1,59 @@
extends layout
block title
| Admin HTML template based on Angular 2, Bootstrap 4 and Webpack
block content
div.hero
div.hero-content
div.wrap
div.text
strong ng2-#[span.white-text admin]
div.minitext Angular 2 admin panel front-end framework
div.buttons-unit
a.button(href=installationArticleUrl) Installation guidelines
a.button(href=firstArticleUrl) Documentation
div.admin-screenshots
div.admin-screenshot
div.browser-mockup
a.demo-link(href='http://akveo.com/ng2-admin/',target='_blank')
img(src=contents.images['sky-preview.png'].url)
span.demo-link-label Demo
div.index-block
div.wrap
h1.centered Why ng2-admin?
div.why-items
div.why-item
img(src=contents.images['why-structure.svg'].url)
h4 Awesome structure
p Component-based structure is the best choice for large Angular 2 applications.
div.why-item
img(src=contents.images['why-design.svg'].url)
h4 Neat design
p We have put a lot of effort and carefully selected each color and font for this template!
div.why-item
img(src=contents.images['why-practices.svg'].url)
h4 Ease of customization
p Check out #[a(href='/ng2-admin/articles/011-changing-color-scheme') our article], where we describe how you can create a different look in just 2 minutes!
div.index-block
div.wrap
h1.centered Is it free?
p Yes, ng2-admin is completely free and MIT licensed. That means you can do with it whatever you want.
div.index-block
div.wrap
h1.centered How can I support you guys?
p Here's what you can do:
ul
li Star #[a(href='https://github.com/akveo/ng2-admin',target='_blank') our GitHub repo]
li Create pull requests, submit bugs, suggest new features
li Follow #[a(href='https://twitter.com/akveo_inc',target='_blank') us on Twitter]
li Like #[a(href='https://www.facebook.com/akveo/',target='_blank') our page on Facebook]
div.index-block
div.wrap
h1.centered Can I hire you?
p Yes! We are available for hire. Visit #[a(href='http://akveo.com',target='_blank') our homepage]
|&nbsp;or simply leave us a note at #[a(href='mailto:contact@akveo.com') contact@akveo.com].
|&nbsp;We will be happy to work with you!

44
ng2-admin/docs/templates/layout.jade vendored Normal file
View File

@ -0,0 +1,44 @@
doctype html
block vars
- var bodyclass = null;
- var groupedArticles = env.helpers.getGroupedArticles(contents);
- var firstArticleUrl = groupedArticles[0].items[0].url
- var installationArticleUrl = groupedArticles[0].items[1].url
html(lang='en')
head
block head
meta(charset='utf-8')
meta(http-equiv='X-UA-Compatible', content='IE=edge,chrome=1')
meta(name='viewport', content='width=device-width')
meta(name='keywords', content='admin,dashboard,template,angular,bootstrap,blur,panel,html,css,javascript')
title
block title
= locals.name
link(rel='alternate', href=locals.url+'/feed.xml', type='application/rss+xml', title=locals.description)
link(rel='stylesheet', href='https://fonts.googleapis.com/css?family=Roboto:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900italic,900|Anonymous+Pro:400,700,400italic,700italic&subset=latin,greek,greek-ext,vietnamese,cyrillic-ext,latin-ext,cyrillic')
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/github-fork-ribbon-css/0.2.0/gh-fork-ribbon.min.css')
link(rel='stylesheet', href=contents.css['main.scss'].url)
link(rel='shortcut icon', href=contents.images['favicon.png'].url)
body(class=bodyclass)
div.container
div.nav-main
div.wrap
a.nav-home(href=contents['index'].url)
img.nav-logo(src=contents.images['logo.png'].url, width=24,height=24)
|&nbsp;#[span.blur-label ng2-]admin
ul.nav-site.nav-site-internal
li
a(class= locals.page.metadata.activeHome ? 'active': '')(href=contents['index'].url) Home
li
a(class= !locals.page.metadata.activeHome ? 'active': '')(href=firstArticleUrl) Docs
span.nav-docs-right
| Need some help? Let us know! #[a(href='mailto:contact@akveo.com') contact@akveo.com]
block content
h2 Welcome to blur admin!
footer.wrap
div.left Powered by Angular 2, Bootstrap 4, Webpack and many more...
div.right
| © 20152016 Akveo LLC<br />
| Documentation licensed under #[a(href='https://creativecommons.org/licenses/by/4.0/') CC BY 4.0].
a(href='https://github.com/akveo/ng2-admin', class='github-fork-ribbon', title="Star & Fork on GitHub")

179
ng2-admin/package.json Normal file
View File

@ -0,0 +1,179 @@
{
"name": "ng2-admin",
"version": "0.9.0",
"description": "Angular 2 and Bootstrap 4 Admin Template.",
"author": "akveo",
"homepage": "http://akveo.github.io/ng2-admin/",
"license": "MIT",
"dependencies": {
"@angular/common": "2.4.7",
"@angular/compiler": "2.4.7",
"@angular/core": "2.4.7",
"@angular/forms": "2.4.7",
"@angular/http": "2.4.7",
"@angular/platform-browser": "2.4.7",
"@angular/platform-browser-dynamic": "2.4.7",
"@angular/platform-server": "2.4.7",
"@angular/router": "3.4.7",
"@angularclass/conventions-loader": "1.0.13",
"@angularclass/hmr": "1.2.2",
"@angularclass/hmr-loader": "3.0.2",
"amcharts3": "github:amcharts/amcharts3",
"ammap3": "github:amcharts/ammap3",
"animate.css": "3.5.2",
"bootstrap": "4.0.0-alpha.4",
"chart.js": "1.1.1",
"chartist": "0.10.1",
"ckeditor": "4.6.0",
"core-js": "2.4.1",
"easy-pie-chart": "2.1.7",
"font-awesome": "4.7.0",
"fullcalendar": "2.9.1",
"google-maps": "3.2.1",
"http-server": "0.9.0",
"ie-shim": "0.1.0",
"ionicons": "2.0.1",
"is-electron-renderer": "2.0.1",
"jquery": "2.2.4",
"jquery-slimscroll": "1.3.8",
"leaflet": "0.7.7",
"leaflet-map": "0.2.1",
"lodash": "4.17.4",
"ng2-bootstrap": "1.3.3",
"ng2-ckeditor": "1.1.5",
"ng2-completer": "1.1.0",
"ng2-smart-table": "0.5.3-0",
"ng2-tree": "2.0.0-alpha.3",
"ngx-uploader": "2.2.0",
"normalize.css": "4.2.0",
"reflect-metadata": "0.1.9",
"rxjs": "5.0.2",
"tether": "1.4.0",
"zone.js": "0.7.7"
},
"devDependencies": {
"@angular/compiler-cli": "2.4.7",
"@types/electron": "1.4.32",
"@types/fullcalendar": "2.7.37",
"@types/hammerjs": "2.0.34",
"@types/jquery ": "2.0.40",
"@types/jquery.slimscroll": "1.3.30",
"@types/lodash": "ts2.0",
"@types/node": "6.0.63",
"@types/source-map": "0.5.0",
"@types/uglify-js": "2.6.28",
"@types/webpack": "2.2.5",
"add-asset-html-webpack-plugin": "1.0.2",
"angular2-template-loader": "0.6.0",
"assets-webpack-plugin": "3.5.1",
"awesome-typescript-loader": "3.0.4",
"bootstrap-loader": "2.0.0-beta.21",
"codelyzer": "2.0.0",
"copy-webpack-plugin": "4.0.1",
"css-loader": "0.26.1",
"electron": "1.6.0",
"es6-promise": "4.0.5",
"es6-shim": "0.35.3",
"es7-reflect-metadata": "1.6.0",
"exports-loader": "0.6.3",
"expose-loader": "0.7.3",
"extract-text-webpack-plugin": "2.0.0-rc.3",
"file-loader": "0.10.0",
"find-root": "1.0.0",
"font-awesome-sass-loader": "1.0.3",
"gh-pages": "0.12.0",
"html-webpack-plugin": "2.28.0",
"imports-loader": "0.7.0",
"json-loader": "0.5.4",
"ng-router-loader": "2.1.0",
"ngc-webpack": "1.2.0",
"node-sass": "4.5.0",
"npm-run-all": "4.0.1",
"optimize-js-plugin": "0.0.4",
"postcss-loader": "1.3.1",
"raw-loader": "0.5.1",
"resolve-url-loader": "1.6.1",
"rimraf": "2.5.4",
"sass-loader": "4.1.1",
"script-ext-html-webpack-plugin": "1.7.1",
"source-map-loader": "0.1.6",
"string-replace-loader": "1.0.5",
"style-loader": "0.13.1",
"to-string-loader": "1.1.5",
"ts-helpers": "1.1.2",
"ts-node": "2.1.0",
"tslint": "4.4.2",
"typedoc": "0.5.6",
"typescript": "2.0.10",
"url-loader": "0.5.7",
"webpack": "2.2.0",
"webpack-dev-middleware": "1.9.0",
"webpack-dev-server": "2.2.0",
"webpack-dll-bundles-plugin": "1.0.0-beta.5",
"webpack-merge": "2.6.1"
},
"scripts": {
"rimraf": "rimraf",
"tslint": "tslint",
"typedoc": "typedoc",
"webpack": "webpack --progress --profile --bail",
"webpack-dev-server": "webpack-dev-server",
"webdriver-manager": "webdriver-manager",
"clean": "npm cache clean && npm run rimraf -- node_modules doc coverage dist compiled dll",
"clean:dist": "npm run rimraf -- dist",
"clean:dll": "npm run rimraf -- dll",
"clean:electron": "npm run rimraf -- build",
"preclean:install": "npm run clean",
"clean:install": "npm set progress=false && npm install",
"preclean:start": "npm run clean",
"clean:start": "npm start",
"watch": "npm run watch:dev",
"watch:dev": "npm run build:dev -- --watch",
"watch:dev:hmr": "npm run watch:dev -- --hot",
"watch:prod": "npm run build:prod -- --watch",
"build": "npm run build:dev",
"prebuild:dev": "npm run clean:dist",
"build:dev": " npm run clean:dist && npm run webpack -- --config config/webpack.dev.js",
"prebuild:prod": "npm run clean:dist",
"build:prod": "npm run clean:dist && webpack --config config/webpack.prod.js --progress --profile",
"server": "npm run server:dev",
"server:dev": "webpack-dev-server --config config/webpack.dev.js --progress --profile --watch --content-base src/",
"server:dev:hmr": "npm run server:dev -- --inline --hot",
"server:prod": "http-server dist -c-1 --cors",
"server:test": "http-server dist-demo -c-1 --cors",
"server:prod:ci": "http-server dist -p 3000 -c-1 --cors",
"webdriver:update": "npm run webdriver-manager update",
"webdriver:start": "npm run webdriver-manager start",
"lint": "npm run tslint \"src/**/*.ts\" --force",
"ngc": "./node_modules/.bin/ngc-w -p tsconfig.webpack.json",
"pree2e": "npm run webdriver:update -- --standalone",
"pretest": "npm run lint",
"docs": "npm run typedoc -- --options typedoc.json --exclude '**/*.spec.ts' ./src/",
"gh-pages": "wintersmith build -C docs && gh-pages -d docs/build",
"start": "npm run server:dev",
"start:hmr": "npm run server:dev:hmr",
"version": "npm run build",
"postversion": "git push && git push --tags",
"build:electron": "npm run build:electron.full",
"prebuild:electron.full": "npm run clean:electron",
"build:electron.full": "npm run build:electron.renderer && npm run build:electron.main",
"postbuild:electron.full": "npm run electron:start",
"build:electron.renderer": "npm run webpack -- --config config/electron/webpack.renderer.prod.js",
"build:electron.main": "npm run webpack -- --config config/electron/webpack.electron.prod.js",
"electron:start": "electron build",
"build:aot:prod": "npm run clean:dist && npm run clean:aot && webpack --config config/webpack.prod.js --progress --profile --bail",
"build:aot": "npm run build:aot:prod",
"clean:aot": "npm run rimraf -- compiled",
"build:ci": "npm run build:prod && npm run build:aot"
},
"repository": {
"type": "git",
"url": "https://github.com/akveo/ng2-admin.git"
},
"bugs": {
"url": "https://github.com/akveo/ng2-admin/issues"
},
"engines": {
"node": ">= 5.4.1 < 7"
}
}

View File

@ -0,0 +1 @@
module.exports = {};

View File

@ -0,0 +1,55 @@
import { Component, ViewContainerRef } from '@angular/core';
import { GlobalState } from './global.state';
import { BaImageLoaderService, BaThemePreloader, BaThemeSpinner } from './theme/services';
import { BaThemeConfig } from './theme/theme.config';
import { layoutPaths } from './theme/theme.constants';
import 'style-loader!./app.scss';
import 'style-loader!./theme/initial.scss';
/*
* App Component
* Top Level Component
*/
@Component({
selector: 'app',
template: `
<main [ngClass]="{'menu-collapsed': isMenuCollapsed}" baThemeRun>
<div class="additional-bg"></div>
<router-outlet></router-outlet>
</main>
`
})
export class App {
isMenuCollapsed: boolean = false;
constructor(private _state: GlobalState,
private _imageLoader: BaImageLoaderService,
private _spinner: BaThemeSpinner,
private viewContainerRef: ViewContainerRef,
private themeConfig: BaThemeConfig) {
themeConfig.config();
this._loadImages();
this._state.subscribe('menu.isCollapsed', (isCollapsed) => {
this.isMenuCollapsed = isCollapsed;
});
}
public ngAfterViewInit(): void {
// hide spinner once all loaders are completed
BaThemePreloader.load().then((values) => {
this._spinner.hide();
});
}
private _loadImages(): void {
// register some loaders
BaThemePreloader.registerLoader(this._imageLoader.load(layoutPaths.images.root + 'sky-bg.jpg'));
}
}

View File

@ -0,0 +1,95 @@
import { NgModule, ApplicationRef } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';
import { removeNgStyles, createNewHosts, createInputTransfer } from '@angularclass/hmr';
/*
* Platform and Environment providers/directives/pipes
*/
import { ENV_PROVIDERS } from './environment';
import { routing } from './app.routing';
// App is our top level component
import { App } from './app.component';
import { AppState, InternalStateType } from './app.service';
import { GlobalState } from './global.state';
import { NgaModule } from './theme/nga.module';
import { PagesModule } from './pages/pages.module';
// Application wide providers
const APP_PROVIDERS = [
AppState,
GlobalState
];
export type StoreType = {
state: InternalStateType,
restoreInputValues: () => void,
disposeOldHosts: () => void
};
/**
* `AppModule` is the main entry point into Angular2's bootstraping process
*/
@NgModule({
bootstrap: [App],
declarations: [
App
],
imports: [ // import Angular's modules
BrowserModule,
HttpModule,
RouterModule,
FormsModule,
ReactiveFormsModule,
NgaModule.forRoot(),
PagesModule,
routing
],
providers: [ // expose our Services and Providers into Angular's dependency injection
ENV_PROVIDERS,
APP_PROVIDERS
]
})
export class AppModule {
constructor(public appRef: ApplicationRef, public appState: AppState) {
}
hmrOnInit(store: StoreType) {
if (!store || !store.state) return;
console.log('HMR store', JSON.stringify(store, null, 2));
// set state
this.appState._state = store.state;
// set input values
if ('restoreInputValues' in store) {
let restoreInputValues = store.restoreInputValues;
setTimeout(restoreInputValues);
}
this.appRef.tick();
delete store.state;
delete store.restoreInputValues;
}
hmrOnDestroy(store: StoreType) {
const cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement);
// save state
const state = this.appState._state;
store.state = state;
// recreate root elements
store.disposeOldHosts = createNewHosts(cmpLocation);
// save input values
store.restoreInputValues = createInputTransfer();
// remove styles
removeNgStyles();
}
hmrAfterDestroy(store: StoreType) {
// display new elements
store.disposeOldHosts();
delete store.disposeOldHosts;
}
}

View File

@ -0,0 +1,9 @@
import { Routes, RouterModule } from '@angular/router';
import { ModuleWithProviders } from '@angular/core';
export const routes: Routes = [
{ path: '', redirectTo: 'pages', pathMatch: 'full' },
{ path: '**', redirectTo: 'pages/dashboard' }
];
export const routing: ModuleWithProviders = RouterModule.forRoot(routes, { useHash: true });

View File

@ -0,0 +1,2 @@
@import "~normalize.css";
@import "theme/theme";

View File

@ -0,0 +1,41 @@
import { Injectable } from '@angular/core';
export type InternalStateType = {
[key: string]: any
};
@Injectable()
export class AppState {
_state: InternalStateType = {};
constructor() {
}
// already return a clone of the current state
get state() {
return this._state = this._clone(this._state);
}
// never allow mutation
set state(value) {
throw new Error('do not mutate the `.state` directly');
}
get(prop?: any) {
// use our state getter for the clone
const state = this.state;
return state.hasOwnProperty(prop) ? state[prop] : state;
}
set(prop: string, value: any) {
// internally mutate our state
return this._state[prop] = value;
}
private _clone(object: InternalStateType) {
// simple object clone
return JSON.parse(JSON.stringify(object));
}
}

View File

@ -0,0 +1,49 @@
// Angular 2
// rc2 workaround
import { enableDebugTools, disableDebugTools } from '@angular/platform-browser';
import { enableProdMode, ApplicationRef } from '@angular/core';
// Environment Providers
let PROVIDERS: any[] = [
// common env directives
];
// Angular debug tools in the dev console
// https://github.com/angular/angular/blob/86405345b781a9dc2438c0fbe3e9409245647019/TOOLS_JS.md
let _decorateModuleRef = function identity<T>(value: T): T { return value; };
if ('production' === ENV || 'renderer' === ENV) {
// Production
disableDebugTools();
enableProdMode();
PROVIDERS = [
...PROVIDERS,
// custom providers in production
];
} else {
_decorateModuleRef = (modRef: any) => {
const appRef = modRef.injector.get(ApplicationRef);
const cmpRef = appRef.components[0];
let _ng = (<any>window).ng;
enableDebugTools(cmpRef);
(<any>window).ng.probe = _ng.probe;
(<any>window).ng.coreTokens = _ng.coreTokens;
return modRef;
};
// Development
PROVIDERS = [
...PROVIDERS,
// custom providers in development
];
}
export const decorateModuleRef = _decorateModuleRef;
export const ENV_PROVIDERS = [
...PROVIDERS
];

View File

@ -0,0 +1,43 @@
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class GlobalState {
private _data = new Subject<Object>();
private _dataStream$ = this._data.asObservable();
private _subscriptions: Map<string, Array<Function>> = new Map<string, Array<Function>>();
constructor() {
this._dataStream$.subscribe((data) => this._onEvent(data));
}
notifyDataChanged(event, value) {
let current = this._data[event];
if (current !== value) {
this._data[event] = value;
this._data.next({
event: event,
data: this._data[event]
});
}
}
subscribe(event: string, callback: Function) {
let subscribers = this._subscriptions.get(event) || [];
subscribers.push(callback);
this._subscriptions.set(event, subscribers);
}
_onEvent(data: any) {
let subscribers = this._subscriptions.get(data['event']) || [];
subscribers.forEach((callback) => {
callback.call(null, data['data']);
});
}
}

View File

@ -0,0 +1 @@
export * from './app.module';

View File

@ -0,0 +1,15 @@
import {Component} from '@angular/core';
@Component({
selector: 'maps',
template: `<router-outlet></router-outlet>`
})
export class Charts {
constructor() {
}
ngOnInit() {
}
}

View File

@ -0,0 +1,27 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { NgaModule } from '../../theme/nga.module';
import { routing } from './charts.routing';
import { Charts } from './charts.component';
import { ChartistJs } from './components/chartistJs/chartistJs.component';
import { ChartistJsService } from './components/chartistJs/chartistJs.service';
@NgModule({
imports: [
CommonModule,
FormsModule,
NgaModule,
routing
],
declarations: [
Charts,
ChartistJs
],
providers: [
ChartistJsService
]
})
export class ChartsModule {}

View File

@ -0,0 +1,17 @@
import { Routes, RouterModule } from '@angular/router';
import { Charts } from './charts.component';
import { ChartistJs } from './components/chartistJs/chartistJs.component';
// noinspection TypeScriptValidateTypes
const routes: Routes = [
{
path: '',
component: Charts,
children: [
{ path: 'chartist-js', component: ChartistJs }
]
}
];
export const routing = RouterModule.forChild(routes);

View File

@ -0,0 +1,25 @@
import {Component} from '@angular/core';
import {ChartistJsService} from './chartistJs.service';
import 'style-loader!./chartistJs.scss';
@Component({
selector: 'chartist-js',
templateUrl: './chartistJs.html',
})
export class ChartistJs {
data:any;
constructor(private _chartistJsService:ChartistJsService) {
}
ngOnInit() {
this.data = this._chartistJsService.getAll();
}
getResponsive(padding, offset) {
return this._chartistJsService.getResponsive(padding, offset);
}
}

View File

@ -0,0 +1,86 @@
<section class="chartist">
<div class="row">
<div class="col-md-6 ">
<ba-card title="Lines" baCardClass="with-scroll">
<h5>Simple line chart</h5>
<ba-chartist-chart baChartistChartClass="ct-chart"
baChartistChartType="Line"
[baChartistChartData]="data['simpleLineData']"
[baChartistChartOptions]="data['simpleLineOptions']">
</ba-chartist-chart>
<h5>Line chart with area</h5>
<ba-chartist-chart baChartistChartClass="ct-chart"
baChartistChartType="Line"
[baChartistChartData]="data['areaLineData']"
[baChartistChartOptions]="data['areaLineOptions']">
</ba-chartist-chart>
<h5>Bi-polar line chart with area only</h5>
<ba-chartist-chart baChartistChartClass="ct-chart"
baChartistChartType="Line"
[baChartistChartData]="data['biLineData']"
[baChartistChartOptions]="data['biLineOptions']">
</ba-chartist-chart>
</ba-card>
</div>
<div class="col-md-6 ">
<ba-card title="Bars" baCardClass="with-scroll">
<h5>Simple bar chart</h5>
<ba-chartist-chart baChartistChartClass="ct-chart"
baChartistChartType="Bar"
[baChartistChartData]="data['simpleBarData']"
[baChartistChartOptions]="data['simpleBarOptions']">
</ba-chartist-chart>
<h5>Multi-line labels bar chart</h5>
<ba-chartist-chart baChartistChartClass="ct-chart"
baChartistChartType="Bar"
[baChartistChartData]="data['multiBarData']"
[baChartistChartOptions]="data['multiBarOptions']"
[baChartistChartResponsive]="data['multiBarResponsive']">
</ba-chartist-chart>
<h5>Stacked bar chart</h5>
<ba-chartist-chart baChartistChartClass="ct-chart stacked-bar"
baChartistChartType="Bar"
[baChartistChartData]="data['stackedBarData']"
[baChartistChartOptions]="data['stackedBarOptions']">
</ba-chartist-chart>
</ba-card>
</div>
</div>
<div class="row">
<div class="col-md-12">
<ba-card title="Pies & Donuts" baCardClass="with-scroll">
<div class="row">
<div class="col-md-12 col-lg-4"><h5>Simple Pie</h5>
<ba-chartist-chart baChartistChartClass="ct-chart stacked-bar"
baChartistChartType="Pie"
[baChartistChartData]="data['simplePieData']"
[baChartistChartOptions]="data['simplePieOptions']"
[baChartistChartResponsive]="getResponsive(20, 80)">
</ba-chartist-chart>
</div>
<div class="col-md-12 col-lg-4"><h5>Pie with labels</h5>
<ba-chartist-chart baChartistChartClass="ct-chart stacked-bar"
baChartistChartType="Pie"
[baChartistChartData]="data['labelsPieData']"
[baChartistChartOptions]="data['labelsPieOptions']">
</ba-chartist-chart>
</div>
<div class="col-md-12 col-lg-4"><h5>Donut</h5>
<ba-chartist-chart baChartistChartClass="ct-chart stacked-bar"
baChartistChartType="Pie"
[baChartistChartData]="data['simpleDonutData']"
[baChartistChartOptions]="data['simpleDonutOptions']"
[baChartistChartResponsive]="getResponsive(5, 40)">
</ba-chartist-chart>
</div>
</div>
</ba-card>
</div>
</div>
</section>

View File

@ -0,0 +1,71 @@
@import "../../../../theme/sass/conf/conf";
.ct-area {
fill-opacity: .5;
}
.ct-label{
color: $default-text;
opacity: 0.9;
fill: $default-text;
}
.ct-chart .ct-label{
font-size: 1em;
}
.ct-chart svg{
width: 100%;
display: block;
}
.ct-series-a {
.ct-bar, .ct-line, .ct-point, .ct-slice-donut, .ct-slice-pie {
stroke: $primary;
}
.ct-slice-pie, .ct-area{
fill: $primary;
}
}
.ct-series-b {
.ct-bar, .ct-line, .ct-point, .ct-slice-donut, .ct-slice-pie {
stroke: $success;
}
.ct-slice-pie, .ct-area{
fill: $success;
}
}
.ct-series-c {
.ct-bar, .ct-line, .ct-point, .ct-slice-donut, .ct-slice-pie {
stroke: $danger;
}
.ct-slice-pie, .ct-area{
fill: $danger;
}
}
.ct-series-d {
.ct-bar, .ct-line, .ct-point, .ct-slice-donut, .ct-slice-pie {
stroke: $warning;
}
.ct-slice-pie, .ct-area{
fill: $warning;
}
}
.ct-series-e {
.ct-bar, .ct-line, .ct-point, .ct-slice-donut, .ct-slice-pie {
stroke: $info;
}
.ct-slice-pie, .ct-area{
fill: $info;
}
}
.stacked-bar .ct-bar{
stroke-width: 30px;
}

View File

@ -0,0 +1,207 @@
import {Injectable} from '@angular/core';
import {BaThemeConfigProvider} from '../../../../theme';
@Injectable()
export class ChartistJsService {
private _data = {
simpleLineOptions: {
color: this._baConfig.get().colors.defaultText,
fullWidth: true,
height: '300px',
chartPadding: {
right: 40
}
},
simpleLineData: {
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
series: [
[20, 20, 12, 45, 50],
[10, 45, 30, 14, 12],
[34, 12, 12, 40, 50],
[10, 43, 25, 22, 16],
[3, 6, 30, 33, 43]
]
},
areaLineData: {
labels: [1, 2, 3, 4, 5, 6, 7, 8],
series: [
[5, 9, 7, 8, 5, 3, 5, 4]
]
},
areaLineOptions: {
fullWidth: true,
height: '300px',
low: 0,
showArea: true
},
biLineData: {
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
series: [
[1, 2, 3, 1, -2, 0, 1],
[-2, -1, -2, -1, -2.5, -1, -2],
[0, 0, 0, 1, 2, 2.5, 2],
[2.5, 2, 1, 0.5, 1, 0.5, -1]
]
},
biLineOptions: {
height: '300px',
high: 3,
low: -3,
showArea: true,
showLine: false,
showPoint: false,
fullWidth: true,
axisX: {
showGrid: false
}
},
simpleBarData: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
series: [
[15, 24, 43, 27, 5, 10, 23, 44, 68, 50, 26, 8],
[13, 22, 49, 22, 4, 6, 24, 46, 57, 48, 22, 4]
]
},
simpleBarOptions: {
fullWidth: true,
height: '300px'
},
multiBarData: {
labels: ['Quarter 1', 'Quarter 2', 'Quarter 3', 'Quarter 4'],
series: [
[5, 4, 3, 7],
[3, 2, 9, 5],
[1, 5, 8, 4],
[2, 3, 4, 6],
[4, 1, 2, 1]
]
},
multiBarOptions: {
fullWidth: true,
height: '300px',
stackBars: true,
axisX: {
labelInterpolationFnc: function (value) {
return value.split(/\s+/).map(function (word) {
return word[0];
}).join('');
}
},
axisY: {
offset: 20
}
},
multiBarResponsive: [
['screen and (min-width: 400px)', {
reverseData: true,
horizontalBars: true,
axisX: {
labelInterpolationFnc: (n) => n
},
axisY: {
offset: 60
}
}],
['screen and (min-width: 700px)', {
stackBars: false,
reverseData: false,
horizontalBars: false,
seriesBarDistance: 15
}]
],
stackedBarData: {
labels: ['Quarter 1', 'Quarter 2', 'Quarter 3', 'Quarter 4'],
series: [
[800000, 1200000, 1400000, 1300000],
[200000, 400000, 500000, 300000],
[100000, 200000, 400000, 600000]
]
},
stackedBarOptions: {
fullWidth: true,
height: '300px',
stackBars: true,
axisY: {
labelInterpolationFnc: function (value) {
return (value / 1000) + 'k';
}
}
},
simplePieData: {
series: [5, 3, 4]
},
simplePieOptions: {
fullWidth: true,
height: '300px',
weight: '300px',
labelInterpolationFnc: function (value) {
return Math.round(value / 12 * 100) + '%';
}
},
labelsPieData: {
labels: ['Bananas', 'Apples', 'Grapes'],
series: [20, 15, 40]
},
labelsPieOptions: {
fullWidth: true,
height: '300px',
weight: '300px',
labelDirection: 'explode',
labelInterpolationFnc: function (value) {
return value[0];
}
},
simpleDonutData: {
labels: ['Bananas', 'Apples', 'Grapes'],
series: [20, 15, 40]
},
simpleDonutOptions: {
fullWidth: true,
donut: true,
height: '300px',
weight: '300px',
labelDirection: 'explode',
labelInterpolationFnc: function (value) {
return value[0];
}
}
};
constructor(private _baConfig:BaThemeConfigProvider) {
}
public getAll() {
return this._data;
}
public getResponsive(padding, offset) {
return [
['screen and (min-width: 1550px)', {
chartPadding: padding,
labelOffset: offset,
labelDirection: 'explode',
labelInterpolationFnc: function (value) {
return value;
}
}],
['screen and (max-width: 1200px)', {
chartPadding: padding,
labelOffset: offset,
labelDirection: 'explode',
labelInterpolationFnc: function (value) {
return value;
}
}],
['screen and (max-width: 600px)', {
chartPadding: 0,
labelOffset: 0,
labelInterpolationFnc: function (value) {
return value[0];
}
}]
];
}
}

View File

@ -0,0 +1 @@
export * from './chartistJs.component';

View File

@ -0,0 +1 @@
export * from './charts.component';

View File

@ -0,0 +1,12 @@
import {Component} from '@angular/core';
@Component({
selector: 'components',
template: `<router-outlet></router-outlet>`
})
export class Components {
constructor() {
}
}

View File

@ -0,0 +1,24 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { NgaModule } from '../../theme/nga.module';
import { TreeModule } from 'ng2-tree';
import { routing } from './components.routing';
import { Components } from './components.component';
import { TreeView } from './components/treeView/treeView.component';
@NgModule({
imports: [
CommonModule,
FormsModule,
NgaModule,
TreeModule,
routing
],
declarations: [
Components,
TreeView,
]
})
export class ComponentsModule {}

View File

@ -0,0 +1,17 @@
import { Routes, RouterModule } from '@angular/router';
import { Components } from './components.component';
import { TreeView } from './components/treeView/treeView.component';
// noinspection TypeScriptValidateTypes
const routes: Routes = [
{
path: '',
component: Components,
children: [
{ path: 'treeview', component: TreeView }
]
}
];
export const routing = RouterModule.forChild(routes);

View File

@ -0,0 +1 @@
@import '../../theme/sass/treeView';

View File

@ -0,0 +1 @@
export * from './treeView.component';

View File

@ -0,0 +1,36 @@
import {Component} from '@angular/core';
import {TreeModel} from 'ng2-tree';
@Component({
selector: 'tree-view',
templateUrl: './treeView.html',
})
export class TreeView {
tree: TreeModel = {
value: 'Programming languages by programming paradigm',
children: [
{
value: 'Object-oriented programming',
children: [
{value: 'Java'},
{value: 'C++'},
{value: 'C#'},
]
},
{
value: 'Prototype-based programming',
children: [
{value: 'JavaScript'},
{value: 'CoffeeScript'},
{value: 'Lua'},
]
}
]
};
constructor() {
}
}

View File

@ -0,0 +1,5 @@
<div class="col-md-6">
<ba-card title="basic">
<tree id="tree-view" [tree]="tree"></tree>
</ba-card>
</div>

View File

@ -0,0 +1 @@
export * from './components.component';

View File

@ -0,0 +1,40 @@
import {Component} from '@angular/core';
import {CalendarService} from './calendar.service';
import 'style-loader!./calendar.scss';
@Component({
selector: 'calendar',
templateUrl: './calendar.html'
})
export class Calendar {
public calendarConfiguration:any;
private _calendar:Object;
constructor(private _calendarService:CalendarService) {
this.calendarConfiguration = this._calendarService.getData();
this.calendarConfiguration.select = (start, end) => this._onSelect(start, end);
}
public onCalendarReady(calendar):void {
this._calendar = calendar;
}
private _onSelect(start, end):void {
if (this._calendar != null) {
let title = prompt('Event Title:');
let eventData;
if (title) {
eventData = {
title: title,
start: start,
end: end
};
jQuery(this._calendar).fullCalendar('renderEvent', eventData, true);
}
jQuery(this._calendar).fullCalendar('unselect');
}
}
}

View File

@ -0,0 +1 @@
<ba-full-calendar [baFullCalendarConfiguration]="calendarConfiguration" baFullCalendarClass="blurCalendar" (onCalendarReady)="onCalendarReady($event)"></ba-full-calendar>

View File

@ -0,0 +1,765 @@
@import '../../../theme/sass/conf/conf';
div.blurCalendar{
font-size: 12px;
}
.fc {
direction: ltr;
text-align: left;
button {
box-sizing: border-box;
margin: 0;
height: 2.1em;
padding: 0 .6em;
font-size: 1em;
white-space: nowrap;
cursor: pointer;
&::-moz-focus-inner {
margin: 0;
padding: 0;
}
.fc-icon {
position: relative;
top: 0;
}
}
.fc-button-group {
& > * {
float: left;
margin: 0 0 0 -1px;
}
& > :first-child {
margin-left: 0;
}
}
hr {
height: 0;
margin: 0;
padding: 0 0 2px;
border-style: solid;
border-width: 1px 0;
}
table {
width: 100%;
table-layout: fixed;
border-collapse: collapse;
border-spacing: 0;
font-size: 1em;
}
th {
text-align: center;
}
th, td {
border: 1px solid rgba(255,255,255,0.3);
padding: 0;
vertical-align: top;
}
td.fc-today {
border-style: double;
}
.fc-row {
border: 0 solid;
}
.fc-toolbar {
& > * {
& > * {
float: left;
margin-left: .75em;
}
& > :first-child {
margin-left: 0;
}
}
}
.fc-axis {
vertical-align: middle;
padding: 0 4px;
white-space: nowrap;
}
}
.fc-rtl {
text-align: right;
}
.fc-unthemed {
th, td, hr, thead, tbody, .fc-row, .fc-popover {
border-color: rgba($border, 0.3);
}
.fc-popover {
background-color: $default;
border: 1px solid;
.fc-header {
background: #eee;
.fc-close {
color: #666666;
font-size: 25px;
margin-top: 4px;
}
}
}
hr {
background: #eee;
}
.fc-today {
background: rgba(255,255,255,0.15);
}
}
.fc-highlight {
background: rgba(255,255,255,0.25);
opacity: .3;
}
.fc-icon {
display: inline-block;
font-size: 2em;
font-family: "Courier New", Courier, monospace;
}
.fc-icon-left-single-arrow:after {
content: "\02039";
font-weight: $font-bold;
font-size: 100%;
}
.fc-icon-right-single-arrow:after {
content: "\0203A";
font-weight: $font-bold;
font-size: 100%;
}
.fc-icon-left-double-arrow:after {
content: "\000AB";
}
.fc-icon-right-double-arrow:after {
content: "\000BB";
}
.fc-icon-x:after {
content: "\000D7";
}
.fc-state-default {
border: 1px solid;
outline: none;
background: #f5f5f5 repeat-x;
border-color: #e6e6e6 #e6e6e6 #bfbfbf;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1);
color: #333333;
&.fc-corner-left {
border-top-left-radius: 0px;
border-bottom-left-radius: 0px;
}
&.fc-corner-right {
border-top-right-radius: 0px;
border-bottom-right-radius: 0px;
}
}
.fc-state-hover,
.fc-state-down,
.fc-state-active,
.fc-state-disabled {
color: #333333;
background-color: $disabled-bg;
}
.fc-state-hover {
color: #333333;
text-decoration: none;
background-position: 0 -15px;
transition: background-position 0.1s linear;
}
.fc-state-down,
.fc-state-active {
background: #cccccc none;
}
.fc-state-disabled {
cursor: default;
background-image: none;
opacity: 0.65;
box-shadow: none;
}
.fc-button-group {
display: inline-block;
}
.fc-popover {
position: absolute;
.fc-header {
padding: 2px 4px;
}
.fc-header .fc-title {
margin: 0 2px;
}
.fc-header .fc-close {
cursor: pointer;
}
}
.fc-ltr .fc-popover .fc-header .fc-title,
.fc-rtl .fc-popover .fc-header .fc-close {
float: left;
}
.fc-rtl .fc-popover .fc-header .fc-title,
.fc-ltr .fc-popover .fc-header .fc-close {
float: right;
}
.fc-popover > .ui-widget-header + .ui-widget-content {
border-top: 0;
}
.fc-clear {
clear: both;
}
.fc-bg,
.fc-highlight-skeleton,
.fc-helper-skeleton {
position: absolute;
top: 0;
left: 0;
right: 0;
}
.fc-bg {
bottom: 0;
}
.fc-bg table {
height: 100%;
}
.fc-row {
position: relative;
table {
border-left: 0 hidden transparent;
border-right: 0 hidden transparent;
border-bottom: 0 hidden transparent;
}
&:first-child table {
border-top: 0 hidden transparent;
}
.fc-bg {
z-index: 1;
}
.fc-highlight-skeleton {
z-index: 2;
bottom: 0;
table {
height: 100%;
}
td {
border-color: transparent;
}
}
.fc-content-skeleton {
position: relative;
z-index: 3;
padding-bottom: 2px;
}
.fc-helper-skeleton {
z-index: 4;
}
.fc-content-skeleton td,
.fc-helper-skeleton td {
background: none;
border-color: transparent;
border-bottom: 0;
}
.fc-content-skeleton tbody td,
.fc-helper-skeleton tbody td {
border-top: 0;
}
}
.fc-scroller {
//overflow-y: scroll;
//overflow-x: hidden;
& > * {
//position: relative;
//width: 100%;
//overflow: hidden;
//height: 100%;
}
}
.fc-event {
position: relative;
display: block;
font-size: .85em;
line-height: 1.3;
border: 1px solid $primary;
background-color: $primary;
font-weight: $font-normal;
}
.fc-event,
.fc-event:hover,
.ui-widget .fc-event {
color: $label-text;
text-decoration: none;
}
.fc-event[href],
.fc-event.fc-draggable {
cursor: pointer;
}
.fc-day-grid-event {
margin: 1px 2px 0;
padding: 0 1px;
}
.fc-ltr .fc-day-grid-event.fc-not-start,
.fc-rtl .fc-day-grid-event.fc-not-end {
margin-left: 0;
border-left-width: 0;
padding-left: 1px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.fc-ltr .fc-day-grid-event.fc-not-end,
.fc-rtl .fc-day-grid-event.fc-not-start {
margin-right: 0;
border-right-width: 0;
padding-right: 1px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.fc-day-grid-event > .fc-content {
white-space: nowrap;
overflow: hidden;
}
.fc-day-grid-event .fc-time {
font-weight: $font-bold;
}
.fc-day-grid-event .fc-resizer {
position: absolute;
top: 0;
bottom: 0;
width: 7px;
}
.fc-ltr .fc-day-grid-event .fc-resizer {
right: -3px;
cursor: e-resize;
}
.fc-rtl .fc-day-grid-event .fc-resizer {
left: -3px;
cursor: w-resize;
}
a.fc-more {
margin: 1px 3px;
font-size: .85em;
cursor: pointer;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
.fc-limited {
display: none;
}
.fc-day-grid .fc-row {
z-index: 1;
}
.fc-more-popover {
z-index: 2;
width: 220px;
.fc-event-container {
padding: 10px;
}
}
.fc-toolbar {
text-align: center;
margin-bottom: 1em;
.fc-left {
float: left;
}
.fc-right {
float: right;
}
.fc-center {
display: inline-block;
}
h2 {
margin: 0;
font-size: 24px;
width: 100%;
line-height: 26px;
}
button {
position: relative;
}
.fc-state-hover, .ui-state-hover {
z-index: 2;
}
.fc-state-down {
z-index: 3;
}
.fc-state-active,
.ui-state-active {
z-index: 4;
}
button:focus {
z-index: 5;
}
}
.fc-view-container *,
.fc-view-container *:before,
.fc-view-container *:after {
box-sizing: content-box;
}
.fc-view,
.fc-view > table {
position: relative;
z-index: 1;
}
.fc-basicWeek-view .fc-content-skeleton,
.fc-basicDay-view .fc-content-skeleton {
padding-top: 1px;
padding-bottom: 1em;
}
.fc-basic-view tbody .fc-row {
min-height: 4em;
max-height: 70px;
}
.fc-row.fc-rigid {
overflow: hidden;
}
.fc-row.fc-rigid .fc-content-skeleton {
position: absolute;
top: 0;
left: 0;
right: 0;
}
.fc-basic-view .fc-week-number,
.fc-basic-view .fc-day-number {
padding: 0 2px;
}
.fc-basic-view td.fc-week-number span,
.fc-basic-view td.fc-day-number {
padding-top: 2px;
padding-bottom: 2px;
}
.fc-basic-view .fc-week-number {
text-align: center;
}
.fc-basic-view .fc-week-number span {
display: inline-block;
min-width: 1.25em;
}
.fc-ltr .fc-basic-view .fc-day-number {
text-align: right;
}
.fc-rtl .fc-basic-view .fc-day-number {
text-align: left;
}
.fc-day-number.fc-other-month {
opacity: 0.3;
}
.fc-agenda-view .fc-day-grid {
position: relative;
z-index: 2;
}
.fc-agenda-view .fc-day-grid .fc-row {
min-height: 3em;
}
.fc-agenda-view .fc-day-grid .fc-row .fc-content-skeleton {
padding-top: 1px;
padding-bottom: 1em;
}
.fc-ltr .fc-axis {
text-align: right;
}
.fc-rtl .fc-axis {
text-align: left;
}
.ui-widget td.fc-axis {
font-weight: $font-normal;
}
.fc-time-grid-container,
.fc-time-grid {
position: relative;
z-index: 1;
}
.fc-time-grid {
min-height: 100%;
}
.fc-time-grid table {
border: 0 hidden transparent;
}
.fc-time-grid > .fc-bg {
z-index: 1;
}
.fc-time-grid .fc-slats,
.fc-time-grid > hr {
position: relative;
z-index: 2;
}
.fc-time-grid .fc-highlight-skeleton {
z-index: 3;
}
.fc-time-grid .fc-content-skeleton {
position: absolute;
z-index: 4;
top: 0;
left: 0;
right: 0;
}
.fc-time-grid > .fc-helper-skeleton {
z-index: 5;
}
.fc-slats {
td {
height: 1.5em;
border-bottom: 0;
}
.fc-minor td {
border-top-style: dotted;
}
.ui-widget-content {
background: none;
}
}
.fc-time-grid .fc-highlight-container {
position: relative;
}
.fc-time-grid .fc-highlight {
position: absolute;
left: 0;
right: 0;
}
.fc-time-grid .fc-event-container {
position: relative;
}
.fc-ltr .fc-time-grid .fc-event-container {
margin: 0 2.5% 0 2px;
}
.fc-rtl .fc-time-grid .fc-event-container {
margin: 0 2px 0 2.5%;
}
.fc-time-grid .fc-event {
position: absolute;
z-index: 1;
}
.fc-time-grid-event {
overflow: hidden;
&.fc-not-start {
border-top-width: 0;
padding-top: 1px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
&.fc-not-end {
border-bottom-width: 0;
padding-bottom: 1px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
& > .fc-content {
position: relative;
z-index: 2;
}
.fc-title {
padding: 0 1px;
}
.fc-time {
padding: 0 1px;
font-size: .85em;
white-space: nowrap;
}
.fc-bg {
z-index: 1;
background: $default;
opacity: .25;
filter: alpha(opacity=25);
}
&.fc-short {
.fc-content {
white-space: nowrap;
}
.fc-time {
display: inline-block;
vertical-align: top;
span {
display: none;
}
&:before {
content: attr(data-start);
}
&:after {
content: "\000A0-\000A0";
}
}
.fc-title {
display: inline-block;
vertical-align: top;
font-size: .85em;
padding: 0;
}
}
.fc-resizer {
position: absolute;
z-index: 3;
left: 0;
right: 0;
bottom: 0;
height: 8px;
overflow: hidden;
line-height: 8px;
font-size: 11px;
font-family: monospace;
text-align: center;
cursor: s-resize;
&:after {
content: "=";
}
}
}
.fc-day-grid-container.fc-scroller {
height: auto!important;
}
.calendar-panel.card .card-body{
padding: 0;
}
.fc-body > tr > .fc-widget-content{
border: none;
}
.fc-head{
color: $label-text;
background-color: $primary;
td, th{
border:none;
}
div.fc-widget-header{
padding: 5px 0;
}
}
.fc-today-button, .fc-month-button, .fc-agendaWeek-button, .fc-agendaDay-button {
display: none;
}
.blurCalendar{
margin-top: 15px;
}
.fc-prev-button, .fc-next-button{
position: absolute;
background: transparent;
box-shadow: none;
border: none;
color: $content-text;
}
.fc-next-button {
left: 30px;
}
.fc-prev-button {
}
.fc-day-number{
color: $content-text;
opacity: 0.9;
}

View File

@ -0,0 +1,49 @@
import {Injectable} from '@angular/core';
import {BaThemeConfigProvider} from '../../../theme';
@Injectable()
export class CalendarService {
constructor(private _baConfig:BaThemeConfigProvider) {
}
getData() {
let dashboardColors = this._baConfig.get().colors.dashboard;
return {
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultDate: '2016-03-08',
selectable: true,
selectHelper: true,
editable: true,
eventLimit: true,
events: [
{
title: 'All Day Event',
start: '2016-03-01',
color: dashboardColors.silverTree
},
{
title: 'Long Event',
start: '2016-03-07',
end: '2016-03-10',
color: dashboardColors.blueStone
},
{
title: 'Dinner',
start: '2016-03-14T20:00:00',
color: dashboardColors.surfieGreen
},
{
title: 'Birthday Party',
start: '2016-04-01T07:00:00',
color: dashboardColors.gossip
}
]
};
}
}

View File

@ -0,0 +1 @@
export * from './calendar.component';

View File

@ -0,0 +1,13 @@
import {Component} from '@angular/core';
@Component({
selector: 'dashboard',
styleUrls: ['./dashboard.scss'],
templateUrl: './dashboard.html'
})
export class Dashboard {
constructor() {
}
}

View File

@ -0,0 +1,52 @@
<div class="row">
<div class="col-xl-12 col-lg-12 col-md-12 col-sm-12 col-xs-12">
<pie-chart></pie-chart>
</div>
</div>
<div class="row">
<ba-card class="col-xlg-6 col-xl-6 col-lg-12 col-sm-12 col-xs-12"
title="Acquisition Channels" baCardClass="traffic-panel medium-card">
<traffic-chart></traffic-chart>
</ba-card>
<ba-card class="col-xlg-6 col-xl-6 col-lg-12 col-sm-12 col-xs-12"
title="Users by Country" baCardClass="medium-card">
<users-map></users-map>
</ba-card>
</div>
<div class="row">
<div class="col-xlg-9 col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
<div class="row">
<ba-card class="col-xlg-8 col-xl-12 col-lg-12 col-md-7 col-sm-12 col-xs-12"
title="Revenue" baCardClass="medium-card">
<line-chart></line-chart>
</ba-card>
<ba-card class="col-xlg-4 col-xl-12 col-lg-12 col-md-5 col-sm-12 col-xs-12"
baCardClass="popular-app medium-card">
<popular-app></popular-app>
</ba-card>
</div>
</div>
<div class="col-xlg-3 col-xl-6 col-lg-6 col-md-12 col-sm-12 col-xs-12">
<ba-card title="Feed"
baCardClass="large-card with-scroll feed-panel">
<feed></feed>
</ba-card>
</div>
</div>
<div class="row shift-up">
<ba-card class="col-xlg-3 col-lg-6 col-md-12 col-sm-12 col-xs-12" title="To Do List"
baCardClass="xmedium-card feed-comply-panel with-scroll todo-panel">
<todo></todo>
</ba-card>
<ba-card class="col-xlg-6 col-lg-6 col-md-12 col-sm-12 col-xs-12" title="Calendar"
baCardClass="xmedium-card feed-comply-panel with-scroll calendar-panel">
<calendar></calendar>
</ba-card>
</div>

View File

@ -0,0 +1,53 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { NgaModule } from '../../theme/nga.module';
import { Dashboard } from './dashboard.component';
import { routing } from './dashboard.routing';
import { PopularApp } from './popularApp';
import { PieChart } from './pieChart';
import { TrafficChart } from './trafficChart';
import { UsersMap } from './usersMap';
import { LineChart } from './lineChart';
import { Feed } from './feed';
import { Todo } from './todo';
import { Calendar } from './calendar';
import { CalendarService } from './calendar/calendar.service';
import { FeedService } from './feed/feed.service';
import { LineChartService } from './lineChart/lineChart.service';
import { PieChartService } from './pieChart/pieChart.service';
import { TodoService } from './todo/todo.service';
import { TrafficChartService } from './trafficChart/trafficChart.service';
import { UsersMapService } from './usersMap/usersMap.service';
@NgModule({
imports: [
CommonModule,
FormsModule,
NgaModule,
routing
],
declarations: [
PopularApp,
PieChart,
TrafficChart,
UsersMap,
LineChart,
Feed,
Todo,
Calendar,
Dashboard
],
providers: [
CalendarService,
FeedService,
LineChartService,
PieChartService,
TodoService,
TrafficChartService,
UsersMapService
]
})
export class DashboardModule {}

View File

@ -0,0 +1,17 @@
import { Routes, RouterModule } from '@angular/router';
import { Dashboard } from './dashboard.component';
import { ModuleWithProviders } from '@angular/core';
// noinspection TypeScriptValidateTypes
export const routes: Routes = [
{
path: '',
component: Dashboard,
children: [
//{ path: 'treeview', component: TreeViewComponent }
]
}
];
export const routing: ModuleWithProviders = RouterModule.forChild(routes);

View File

@ -0,0 +1,23 @@
@media screen and (min-width: 1620px) {
.row.shift-up {
> * {
margin-top: -573px;
}
}
}
@media screen and (max-width: 1620px) {
.card.feed-panel.large-card {
height: 824px;
}
}
.user-stats-card {
.card-title {
padding: 0 0 15px;
}
}
.blurCalendar {
height: 475px;
}

View File

@ -0,0 +1,29 @@
import {Component} from '@angular/core';
import {FeedService} from './feed.service';
import 'style-loader!./feed.scss';
@Component({
selector: 'feed',
templateUrl: './feed.html'
})
export class Feed {
public feed:Array<Object>;
constructor(private _feedService:FeedService) {
}
ngOnInit() {
this._loadFeed();
}
expandMessage (message){
message.expanded = !message.expanded;
}
private _loadFeed() {
this.feed = this._feedService.getData();
}
}

View File

@ -0,0 +1,32 @@
<div class="feed-messages-container">
<div class="feed-message" *ngFor="let message of feed" (click)="expandMessage(message)">
<div class="message-icon" *ngIf="message.type == 'text-message'">
<img class="photo-icon" src="{{ ( message.author | baProfilePicture ) }}">
</div>
<div class="message-icon" *ngIf="message.type != 'text-message'">
<img class="photo-icon" src="{{ ( message.author | baProfilePicture ) }}">
<span class="sub-photo-icon" [ngClass]="message.type"></span>
</div>
<div class="text-block text-message">
<div class="message-header">
<span class="author">{{ message.author }} {{ message.surname}}</span>
</div>
<div class="message-content line-clamp" [ngClass]="{'line-clamp-2' : !message.expanded}">
<span *ngIf="message.preview">{{ message.header }} </span>{{ message.text }}
</div>
<div class="preview" [ngClass]="{'hidden': !message.expanded}" *ngIf="message.preview">
<a href="{{ message.link }}" target="_blank">
<img src="{{ ( message.preview | baAppPicture )}}">
</a>
</div>
<div [ngClass]="{'hidden': !message.expanded}" class="message-time">
<div class="post-time">
{{ message.time }}
</div>
<div class="ago-time">
{{ message.ago }}
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,226 @@
@import '../../../theme/sass/conf/conf';
.feed-panel .card-body{
padding: 10px 0;
}
.feed-message {
$text-message-color: $content-text;
$video-message-color: $danger;
$image-message-color: $success;
$geo-message-color: $primary;
padding: 10px 0 ;
border-bottom: 1px solid rgba(0,0,0,0.12);
box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.12);
&:first-child {
padding-top: 0;
}
.hidden {
display: none!important;
}
.message-icon {
cursor: pointer;
width: 60px;
height: 60px;
float: left;
position: relative;
margin-left: 20px;
> img, .media-icon {
border-radius: 30px;
width: 100%;
height: 100%;
}
.sub-photo-icon {
display: inline-block;
padding: 4px;
&:after {
content: '';
display: inline-block;
width: 22px;
height: 22px;
background-size: contain;
}
&.video-message {
background: $video-message-color;
&:after {
@include bg-image('theme/icon/feed/feed-video.svg');
}
}
&.image-message {
background: $image-message-color;
&:after {
width: 21px;
height: 21px;
margin-top: 1px;
margin-left: 1px;
border-radius: 5px;
@include bg-image('theme/icon/feed/feed-image.svg');
}
}
&.geo-message {
background: $geo-message-color;
&:after {
width: 22px;
height: 22px;
@include bg-image('theme/icon/feed/feed-location.svg');
}
}
}
.sub-photo-icon {
position: absolute;
width: 30px;
height: 30px;
right: -2px;
bottom: -4px;
border-radius: 15px;
}
}
.text-block {
cursor: pointer;
position: relative;
border-radius: 5px;
margin: 0 0 0 80px;
padding: 5px 20px;
color: $text-message-color;
width: 280px;
height: 70px;
&.text-message {
font-size: 12px;
width: inherit;
max-width: calc(100% - 80px);
height: inherit;
min-height: 60px;
&:before {
display: block;
}
.message-content {
font-size: 12px;
line-height: 15px;
font-weight: $font-light;
}
}
&.small-message {
width: 155px;
height: 145px;
.preview {
bottom: 0;
top: initial;
height: 87px;
img {
width: 155px;
height: 87px;
border-radius: 0 0 5px 5px;
}
}
}
}
.message-header {
font-size: 12px;
padding-bottom: 5px;
.author {
font-size: 13px;
padding-right: 5px;
}
}
.message-content {
font-size: 18px;
line-height: 20px;
}
.preview {
transition: 0s linear all;
display: inline-block;
img {
padding-top: 10px;
width: 100%;
height: auto;
float: none!important;
}
}
.message-time {
width: 100%;
left: 0;
font-size: 11px;
padding-top: 10px;
color: $help-text;
margin-bottom: 5px;
.post-time {
float: left;
}
.ago-time {
float: right;
}
}
}
.line-clamp
{
display : block;
display : -webkit-box;
-webkit-box-orient : vertical;
position : relative;
line-height : 1.2;
overflow : hidden;
text-overflow : ellipsis;
padding : 0 !important;
}
@media screen and (-webkit-min-device-pixel-ratio:0) {
.line-clamp:after
{
content : '...';
text-align : right;
bottom : 0;
right : 0;
width : 25%;
display : block;
position : absolute;
height : calc(1em * 1.2);
}
}
@supports (-webkit-line-clamp: 1)
{
.line-clamp:after
{
display : none !important;
}
}
.line-clamp-1
{
-webkit-line-clamp : 1;
height : calc(1em * 1.2 * 1);
}
.line-clamp-2
{
-webkit-line-clamp : 2;
height : calc(1em * 1.2 * 2);
}
.line-clamp-3
{
-webkit-line-clamp : 3;
height : calc(1em * 1.2 * 3);
}
.line-clamp-4
{
-webkit-line-clamp : 4;
height : calc(1em * 1.2 * 4);
}
.line-clamp-5
{
-webkit-line-clamp : 5;
height : calc(1em * 1.2 * 5);
}

View File

@ -0,0 +1,121 @@
import {Injectable} from '@angular/core';
@Injectable()
export class FeedService {
private _data = [
{
type: 'text-message',
author: 'Kostya',
surname: 'Danovsky',
header: 'Posted new message',
text: 'Guys, check this out: \nA police officer found a perfect hiding place for watching for speeding motorists. One day, the officer was amazed when everyone was under the speed limit, so he investigated and found the problem. A 10 years old boy was standing on the side of the road with a huge hand painted sign which said "Radar Trap Ahead." A little more investigative work led the officer to the boy\'s accomplice: another boy about 100 yards beyond the radar trap with a sign reading "TIPS" and a bucket at his feet full of change.',
time: 'Today 11:55 pm',
ago: '25 minutes ago',
expanded: false,
}, {
type: 'video-message',
author: 'Andrey',
surname: 'Hrabouski',
header: 'Added new video',
text: '"Vader and Me"',
preview: 'app/feed/vader-and-me-preview.png',
link: 'https://www.youtube.com/watch?v=IfcpzBbbamk',
time: 'Today 9:30 pm',
ago: '3 hrs ago',
expanded: false,
}, {
type: 'image-message',
author: 'Vlad',
surname: 'Lugovsky',
header: 'Added new image',
text: '"My little kitten"',
preview: 'app/feed/my-little-kitten.png',
link: 'http://api.ning.com/files/DtcI2O2Ry7A7VhVxeiWfGU9WkHcMy4WSTWZ79oxJq*h0iXvVGndfD7CIYy-Ax-UAFCBCdqXI4GCBw3FOLKTTjQc*2cmpdOXJ/1082127884.jpeg',
time: 'Today 2:20 pm',
ago: '10 hrs ago',
expanded: false,
}, {
type: 'text-message',
author: 'Nasta',
surname: 'Linnie',
header: 'Posted new message',
text: 'Haha lol',
time: '11.11.2015',
ago: '2 days ago',
expanded: false,
}, {
type: 'geo-message',
author: 'Nick',
surname: 'Cat',
header: 'Posted location',
text: '"New York, USA"',
preview: 'app/feed/new-york-location.png',
link: 'https://www.google.by/maps/place/New+York,+NY,+USA/@40.7201111,-73.9893872,14z',
time: '11.11.2015',
ago: '2 days ago',
expanded: false,
}, {
type: 'text-message',
author: 'Vlad',
surname: 'Lugovsky',
header: 'Posted new message',
text: "First snake: I hope I'm not poisonous. Second snake: Why? First snake: Because I bit my lip!",
time: '12.11.2015',
ago: '3 days ago',
expanded: false,
}, {
type: 'text-message',
author: 'Andrey',
surname: 'Hrabouski',
header: 'Posted new message',
text: 'How do you smuggle an elephant across the border? Put a slice of bread on each side, and call him "lunch".',
time: '14.11.2015',
ago: '5 days ago',
expanded: false,
}, {
type: 'text-message',
author: 'Nasta',
surname: 'Linnie',
header: 'Posted new message',
text: 'When your hammer is C++, everything begins to look like a thumb.',
time: '14.11.2015',
ago: '5 days ago',
expanded: false,
}, {
type: 'text-message',
author: 'Alexander',
surname: 'Demeshko',
header: 'Posted new message',
text: '“I mean, they say you die twice. One time when you stop breathing and a second time, a bit later on, when somebody says your name for the last time." ©',
time: '15.11.2015',
ago: '6 days ago',
expanded: false,
}, {
type: 'image-message',
author: 'Nick',
surname: 'Cat',
header: 'Posted photo',
text: '"Protein Heroes"',
preview: 'app/feed/genom.png',
link: 'https://dribbble.com/shots/2504810-Protein-Heroes',
time: '16.11.2015',
ago: '7 days ago',
expanded: false,
},
{
type: 'text-message',
author: 'Kostya',
surname: 'Danovsky',
header: 'Posted new message',
text: 'Why did the CoffeeScript developer keep getting lost? Because he couldn\'t find his source without a map',
time: '18.11.2015',
ago: '9 days ago',
expanded: false,
}
];
getData() {
return this._data;
}
}

Some files were not shown because too many files have changed in this diff Show More