├── .gitignore ├── GruntFile.js ├── README.md ├── bower.json ├── grunt ├── clean.js ├── concat.js ├── copy.js ├── cssmin.js ├── htmlmin.js ├── index.js ├── recess.js └── uglify.js ├── image.jpg ├── package.json └── src ├── css ├── animate.css ├── app.css ├── bootstrap.css ├── bootstrap.css.map ├── dialogs.min.css ├── font-awesome.min.css ├── font.css ├── less │ ├── app.arrow.less │ ├── app.butterbar.less │ ├── app.buttons.less │ ├── app.colors.less │ ├── app.components.less │ ├── app.item.less │ ├── app.layout.boxed.less │ ├── app.layout.less │ ├── app.less │ ├── app.mixins.less │ ├── app.nav.dock.less │ ├── app.nav.less │ ├── app.nav.offscreen.less │ ├── app.ng.less │ ├── app.plugin.less │ ├── app.reset.less │ ├── app.utilities.less │ ├── app.variables.less │ └── app.widgets.less └── simple-line-icons.css ├── fonts ├── FontAwesome.otf ├── Simple-Line-Icons.eot ├── Simple-Line-Icons.svg ├── Simple-Line-Icons.ttf ├── Simple-Line-Icons.woff ├── fontawesome-webfont.eot ├── fontawesome-webfont.svg ├── fontawesome-webfont.ttf ├── fontawesome-webfont.woff ├── fontawesome-webfont.woff2 ├── glyphicons-halflings-regular.eot ├── glyphicons-halflings-regular.svg ├── glyphicons-halflings-regular.ttf ├── glyphicons-halflings-regular.woff ├── glyphicons-halflings-regular.woff2 └── sourcesanspro │ ├── sourcesanspro-bold.woff │ ├── sourcesanspro-light.woff │ └── sourcesanspro.woff ├── img ├── a0.jpg ├── bg.jpg ├── favicon.png └── loading.gif ├── index.html ├── index.min.html ├── js ├── app.js ├── config.js ├── config.lazyload.js ├── config.module.js ├── config.router.js ├── constants.js ├── custom │ ├── framework │ │ ├── dashboard-service.js │ │ ├── dashboard.js │ │ ├── login.js │ │ └── reset-password.js │ ├── sys │ │ ├── menu │ │ │ ├── menu-form.js │ │ │ ├── menu-list.js │ │ │ └── menu-service.js │ │ ├── role │ │ │ ├── role-form.js │ │ │ ├── role-list.js │ │ │ └── role-service.js │ │ └── user │ │ │ ├── user-form.js │ │ │ ├── user-info.js │ │ │ ├── user-list.js │ │ │ └── user-service.js │ └── trip │ │ └── user │ │ ├── user-form.js │ │ ├── user-list.js │ │ └── user-service.js ├── directives │ ├── setnganimate.js │ ├── ui-butterbar.js │ ├── ui-focus.js │ ├── ui-fullscreen.js │ ├── ui-jq.js │ ├── ui-module.js │ ├── ui-nav.js │ ├── ui-ordercolumn.js │ ├── ui-scroll.js │ ├── ui-shift.js │ └── ui-toggleclass.js ├── filters │ ├── dict.js │ └── props-filter.js ├── main.js └── services │ ├── auth-service.js │ └── ui-load.js ├── tpl ├── 404.html ├── app.html ├── blocks │ ├── aside.html │ ├── header.html │ ├── nav.html │ ├── pagination.html │ └── settings.html └── custom │ ├── framework │ ├── dashboard.html │ ├── login.html │ └── reset-password.html │ ├── sys │ ├── menu │ │ ├── menu-form.html │ │ └── menu-list.html │ ├── role │ │ ├── role-form.html │ │ └── role-list.html │ └── user │ │ ├── user-form.html │ │ ├── user-info.html │ │ └── user-list.html │ └── trip │ └── user │ ├── user-form.html │ └── user-list.html └── vendor ├── angular ├── angular-animate │ ├── angular-animate.min.js │ └── angular-animate.min.js.map ├── angular-bootstrap │ └── ui-bootstrap-tpls.min.js ├── angular-cookies │ ├── angular-cookies.min.js │ └── angular-cookies.min.js.map ├── angular-dialog │ └── dialogs.min.js ├── angular-resource │ ├── angular-resource.min.js │ └── angular-resource.min.js.map ├── angular-sanitize │ ├── angular-sanitize.min.js │ └── angular-sanitize.min.js.map ├── angular-touch │ ├── angular-touch.min.js │ └── angular-touch.min.js.map ├── angular-ui-router │ └── angular-ui-router.min.js ├── angular-ui-utils │ └── ui-utils.min.js ├── angular.min.js ├── angular.min.js.map ├── ngstorage │ └── ngStorage.min.js └── oclazyload │ └── ocLazyLoad.min.js ├── jquery ├── bootstrap.js ├── charts │ ├── easypiechart │ │ └── jquery.easy-pie-chart.js │ ├── flot │ │ ├── jquery.flot.min.js │ │ ├── jquery.flot.orderBars.js │ │ ├── jquery.flot.pie.min.js │ │ ├── jquery.flot.resize.js │ │ ├── jquery.flot.spline.js │ │ └── jquery.flot.tooltip.min.js │ └── sparkline │ │ └── jquery.sparkline.min.js ├── jquery-ui.min.js └── jquery.min.js ├── libs └── screenfull.min.js └── modules ├── angular-file-upload ├── angular-file-upload.min.js ├── angular-file-upload.min.js.map └── ngThumb.js ├── angular-ivh-treeview ├── ivh-treeview-theme-basic.css ├── ivh-treeview.min.css └── ivh-treeview.min.js ├── angular-tree-dnd ├── ng-tree-dnd.min.css └── ng-tree-dnd.min.js ├── angular-ui-select ├── select.min.css ├── select.min.css.map ├── select.min.js └── select.min.js.map └── angularjs-toaster ├── toaster.css └── toaster.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### JetBrains template 3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 4 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 5 | 6 | ## File-based project format: 7 | *.iws 8 | 9 | ## Plugin-specific files: 10 | 11 | # IntelliJ 12 | .idea 13 | /out/ 14 | 15 | # mpeltonen/sbt-idea plugin 16 | .idea_modules/ 17 | 18 | # JIRA plugin 19 | atlassian-ide-plugin.xml 20 | 21 | # Crashlytics plugin (for Android Studio and IntelliJ) 22 | com_crashlytics_export_strings.xml 23 | crashlytics.properties 24 | crashlytics-build.properties 25 | fabric.properties 26 | ### OSX template 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Icon must end with two \r 32 | Icon 33 | 34 | # Thumbnails 35 | ._* 36 | 37 | # Files that might appear in the root of a volume 38 | .DocumentRevisions-V100 39 | .fseventsd 40 | .Spotlight-V100 41 | .TemporaryItems 42 | .Trashes 43 | .VolumeIcon.icns 44 | 45 | # Directories potentially created on remote AFP share 46 | .AppleDB 47 | .AppleDesktop 48 | Network Trash Folder 49 | Temporary Items 50 | .apdisk 51 | 52 | #Project 53 | /bower_components/ 54 | /node_modules/ 55 | /angular/ 56 | -------------------------------------------------------------------------------- /GruntFile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | var gtx = require('gruntfile-gtx').wrap(grunt); 3 | 4 | gtx.loadAuto(); 5 | 6 | var gruntConfig = require('./grunt'); 7 | gruntConfig.package = require('./package.json'); 8 | 9 | gtx.config(gruntConfig); 10 | 11 | // We need our bower components in order to develop 12 | gtx.alias('build:dev', ['recess:app', 'copy:dev']); 13 | gtx.alias('build:angular', ['clean:angular', 'copy:angular', 'clean:angulars', 'cssmin:min', 'concat:vendor', 'concat:app', 'uglify:angular']); 14 | 15 | gtx.finalise(); 16 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # springboot-dubbox-web 2 | 3 | https://github.com/zhangxd1989/springboot-dubbox 前端管理 4 | ![预览](https://github.com/zhangxd1989/springboot-dubbox-web/blob/master/image.jpg) 5 | 6 | - install node.js 7 | - go to the app root 8 | 9 | ``` 10 | >npm install -g grunt-cli 11 | >npm install -g bower 12 | >npm install 13 | >bower install 14 | >grunt build:dev 15 | >grunt build:angular 16 | >npm start 17 | ``` 18 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "springboot-dubbox-web", 3 | "private": true, 4 | "dependencies": { 5 | "font-awesome": "^4.6.3", 6 | "bootstrap": "3.3.7", 7 | "angular": "1.3.20", 8 | "angular-animate": "1.3.20", 9 | "angular-cookies": "1.3.20", 10 | "angular-resource": "1.3.20", 11 | "angular-touch": "1.3.20", 12 | "angular-sanitize": "1.3.20", 13 | "angular-ui-router": "^0.3.2", 14 | "ngstorage": "^0.3.11", 15 | "oclazyload": "^1.0.9", 16 | "angular-bootstrap": "0.14.3", 17 | "angular-ui-utils": "~0.1.1", 18 | "screenfull": "^3.0.2", 19 | "angularjs-toaster": "~0.4.8", 20 | "angular-tree-dnd": "^3.0.4", 21 | "angular-dialog-service": "5.2.11", 22 | "angular-file-upload": "^2.3.4", 23 | "angular-ui-select": "^0.19.5" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /grunt/clean.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | angular: ['angular/*'], 3 | angulars: [ 4 | 'angular/css/**', 5 | 'angular/js/*.js', 6 | 'angular/vendor/angular/', 7 | 'angular/js/directives', 8 | 'angular/js/services', 9 | 'angular/js/filters', 10 | 'angular/index.min.html' 11 | ] 12 | }; -------------------------------------------------------------------------------- /grunt/concat.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | vendor: { 3 | options :{ 4 | stripBanners: true 5 | }, 6 | src: [ 7 | 'src/vendor/jquery/jquery.min.js', 8 | 'src/vendor/jquery/jquery-ui.min.js', 9 | 'src/vendor/jquery/ladda/spin.min.js', 10 | 'src/vendor/jquery/ladda/ladda.min.js', 11 | 'src/vendor/angular/angular.min.js', 12 | 'src/vendor/angular/**/*.js' 13 | ], 14 | dest: 'angular/vendor/vendor.min.js' 15 | }, 16 | app: { 17 | options :{ 18 | stripBanners: true 19 | }, 20 | src: [ 21 | 'src/js/*.js', 22 | 'src/js/directives/*.js', 23 | 'src/js/filters/*.js', 24 | 'src/js/services/*.js' 25 | ], 26 | dest: 'angular/js/dist.js' 27 | } 28 | }; -------------------------------------------------------------------------------- /grunt/copy.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | dev: { 3 | nonull: true, 4 | files: [ 5 | // Include our bower JS dependencies 6 | 7 | // angular 8 | {src: "bower_components/angular/angular.min.js", dest: "src/vendor/angular/angular.min.js"}, 9 | {src: "bower_components/angular/angular.min.js.map", dest: "src/vendor/angular/angular.min.js.map"}, 10 | {src: "bower_components/angular-animate/angular-animate.min.js", dest: "src/vendor/angular/angular-animate/angular-animate.min.js"}, 11 | {src: "bower_components/angular-animate/angular-animate.min.js.map", dest: "src/vendor/angular/angular-animate/angular-animate.min.js.map"}, 12 | {src: "bower_components/angular-cookies/angular-cookies.min.js", dest: "src/vendor/angular/angular-cookies/angular-cookies.min.js"}, 13 | {src: "bower_components/angular-cookies/angular-cookies.min.js.map", dest: "src/vendor/angular/angular-cookies/angular-cookies.min.js.map"}, 14 | {src: "bower_components/angular-resource/angular-resource.min.js", dest: "src/vendor/angular/angular-resource/angular-resource.min.js"}, 15 | {src: "bower_components/angular-resource/angular-resource.min.js.map", dest: "src/vendor/angular/angular-resource/angular-resource.min.js.map"}, 16 | {src: "bower_components/angular-sanitize/angular-sanitize.min.js", dest: "src/vendor/angular/angular-sanitize/angular-sanitize.min.js"}, 17 | {src: "bower_components/angular-sanitize/angular-sanitize.min.js.map", dest: "src/vendor/angular/angular-sanitize/angular-sanitize.min.js.map"}, 18 | {src: "bower_components/angular-touch/angular-touch.min.js", dest: "src/vendor/angular/angular-touch/angular-touch.min.js"}, 19 | {src: "bower_components/angular-touch/angular-touch.min.js.map", dest: "src/vendor/angular/angular-touch/angular-touch.min.js.map"}, 20 | 21 | // angular-dialogs 22 | {src: "bower_components/angular-dialog-service/dist/dialogs.min.js", dest: "src/vendor/angular/angular-dialog/dialogs.min.js"}, 23 | {src: "bower_components/angular-dialog-service/dist/dialogs.min.css", dest: "src/css/dialogs.min.css"}, 24 | 25 | // bootstrap 26 | {src: "bower_components/bootstrap/dist/css/bootstrap.css", dest: "src/css/bootstrap.css"}, 27 | {src: "bower_components/bootstrap/dist/css/bootstrap.css.map", dest: "src/css/bootstrap.css.map"}, 28 | {src: "bower_components/bootstrap/dist/js/bootstrap.js", dest: "src/vendor/jquery/bootstrap.js"}, 29 | {src: "**", dest: "src/fonts", cwd: 'bower_components/bootstrap/fonts', expand : true}, 30 | 31 | // fontawesome 32 | {src: "bower_components/font-awesome/css/font-awesome.min.css", dest: "src/css/font-awesome.min.css"}, 33 | {src: "**", dest: "src/fonts", cwd: 'bower_components/font-awesome/fonts', expand : true}, 34 | 35 | // libs 36 | {src: "bower_components/screenfull/dist/screenfull.min.js", dest: "src/vendor/libs/screenfull.min.js"}, 37 | 38 | // core 39 | {src: "bower_components/angular-ui-router/release/angular-ui-router.min.js", dest: "src/vendor/angular/angular-ui-router/angular-ui-router.min.js"}, 40 | {src: "bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js", dest: "src/vendor/angular/angular-bootstrap/ui-bootstrap-tpls.min.js"}, 41 | {src: "bower_components/angular-ui-utils/ui-utils.min.js", dest: "src/vendor/angular/angular-ui-utils/ui-utils.min.js"}, 42 | {src: "bower_components/ngstorage/ngStorage.min.js", dest: "src/vendor/angular/ngstorage/ngStorage.min.js"}, 43 | {src: "bower_components/oclazyload/dist/ocLazyLoad.min.js", dest: "src/vendor/angular/oclazyload/ocLazyLoad.min.js"}, 44 | 45 | // modules for lazy load 46 | {src: "bower_components/angular-ui-select/dist/select.min.js", dest: "src/vendor/modules/angular-ui-select/select.min.js"}, 47 | {src: "bower_components/angular-ui-select/dist/select.min.js.map", dest: "src/vendor/modules/angular-ui-select/select.min.js.map"}, 48 | {src: "bower_components/angular-ui-select/dist/select.min.css", dest: "src/vendor/modules/angular-ui-select/select.min.css"}, 49 | {src: "bower_components/angular-ui-select/dist/select.min.css.map", dest: "src/vendor/modules/angular-ui-select/select.min.css.map"}, 50 | 51 | {src: "bower_components/angular-file-upload/dist/angular-file-upload.min.js", dest: "src/vendor/modules/angular-file-upload/angular-file-upload.min.js"}, 52 | {src: "bower_components/angular-file-upload/dist/angular-file-upload.min.js.map", dest: "src/vendor/modules/angular-file-upload/angular-file-upload.min.js.map"}, 53 | 54 | {src: "bower_components/angular-tree-dnd/dist/ng-tree-dnd.min.js", dest: "src/vendor/modules/angular-tree-dnd/ng-tree-dnd.min.js"}, 55 | {src: "bower_components/angular-tree-dnd/dist/ng-tree-dnd.min.css", dest: "src/vendor/modules/angular-tree-dnd/ng-tree-dnd.min.css"}, 56 | 57 | // toaster 58 | {src: "bower_components/angularjs-toaster/toaster.js", dest: "src/vendor/modules/angularjs-toaster/toaster.js"}, 59 | {src: "bower_components/angularjs-toaster/toaster.css", dest: "src/vendor/modules/angularjs-toaster/toaster.css"} 60 | ] 61 | }, 62 | angular: { 63 | files: [ 64 | {expand: true, dest: 'angular/', src:'**', cwd:'src/'}, 65 | {dest: 'angular/index.html', src:'src/index.min.html'} 66 | ] 67 | } 68 | }; -------------------------------------------------------------------------------- /grunt/cssmin.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | min: { 3 | files: { 4 | 'angular/css/app.min.css': [ 5 | 'src/css/ladda.min.css', 6 | 'src/css/bootstrap.css', 7 | 'src/css/*.css' 8 | ] 9 | } 10 | } 11 | }; -------------------------------------------------------------------------------- /grunt/htmlmin.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | min: { 3 | files: [{ 4 | expand: true, 5 | cwd: 'src/tpl/', 6 | src: ['*.html', '**/*.html'], 7 | dest: 'angular/tpl/', 8 | ext: '.html', 9 | extDot: 'first' 10 | }] 11 | } 12 | }; -------------------------------------------------------------------------------- /grunt/index.js: -------------------------------------------------------------------------------- 1 | var requireDirectory = require('require-directory'); 2 | module.exports = requireDirectory(module); -------------------------------------------------------------------------------- /grunt/recess.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | app: { 3 | files: { 4 | 'src/css/app.css': [ 5 | 'src/css/less/app.less' 6 | ] 7 | }, 8 | options: { 9 | compile: true 10 | } 11 | } 12 | }; -------------------------------------------------------------------------------- /grunt/uglify.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | angular: { 3 | src: [ 4 | 'angular/js/dist.js' 5 | ], 6 | dest: 'angular/js/app.min.js' 7 | } 8 | }; -------------------------------------------------------------------------------- /image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/image.jpg -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "springboot-dubbox-web", 3 | "version": "1.0.0", 4 | "description": "Administrator web application.", 5 | "private": true, 6 | "scripts": { 7 | "start": "node node_modules/http-server/bin/http-server -p 8091 -o -P http://127.0.0.1:8080/" 8 | }, 9 | "devDependencies": { 10 | "grunt": "^0.4.5", 11 | "grunt-bower-install-simple": "^1.2.3", 12 | "grunt-contrib-clean": "^1.0.0", 13 | "grunt-contrib-concat": "^1.0.1", 14 | "grunt-contrib-copy": "^1.0.0", 15 | "grunt-contrib-cssmin": "^1.0.2", 16 | "grunt-contrib-htmlmin": "^2.0.0", 17 | "grunt-contrib-uglify": "^2.0.0", 18 | "grunt-recess": "^1.0.1", 19 | "gruntfile-gtx": "^0.3.0", 20 | "http-server": "^0.9.0", 21 | "require-directory": "^2.1.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/css/dialogs.min.css: -------------------------------------------------------------------------------- 1 | .dialog-header-error{background-color:#d2322d}.dialog-header-wait{background-color:#428bca}.dialog-header-notify{background-color:#eee}.dialog-header-confirm{background-color:#333}.dialog-header-confirm h4,.dialog-header-confirm span,.dialog-header-error h4,.dialog-header-error span,.dialog-header-wait h4,.dialog-header-wait span{color:#fff} -------------------------------------------------------------------------------- /src/css/font.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Source Sans Pro'; 3 | font-style: normal; 4 | font-weight: 300; 5 | src: local('Source Sans Pro Light'), local('SourceSansPro-Light'), url('../fonts/sourcesanspro/sourcesanspro-light.woff') format('woff'); 6 | } 7 | @font-face { 8 | font-family: 'Source Sans Pro'; 9 | font-style: normal; 10 | font-weight: 400; 11 | src: local('Source Sans Pro'), local('SourceSansPro-Regular'), url('../fonts/sourcesanspro/sourcesanspro.woff') format('woff'); 12 | } 13 | @font-face { 14 | font-family: 'Source Sans Pro'; 15 | font-style: normal; 16 | font-weight: 700; 17 | src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url('../fonts/sourcesanspro/sourcesanspro-bold.woff') format('woff'); 18 | } -------------------------------------------------------------------------------- /src/css/less/app.arrow.less: -------------------------------------------------------------------------------- 1 | .arrow { 2 | border-width: @arrow-outer-width; 3 | z-index: 10; 4 | &, 5 | &:after { 6 | position: absolute; 7 | display: block; 8 | width: 0; 9 | height: 0; 10 | border-color: transparent; 11 | border-style: solid; 12 | } 13 | &:after{ 14 | border-width: @arrow-width; 15 | content: ""; 16 | } 17 | 18 | &.top { 19 | left: 50%; 20 | margin-left: -@arrow-outer-width; 21 | border-top-width: 0; 22 | border-bottom-color: @arrow-outer-color; 23 | top: -@arrow-outer-width; 24 | &:after { 25 | top: 1px; 26 | margin-left: -@arrow-width; 27 | border-top-width: 0; 28 | border-bottom-color: @arrow-color; 29 | } 30 | &.arrow-primary{ 31 | &:after{ 32 | border-bottom-color: @brand-primary; 33 | } 34 | } 35 | &.arrow-info{ 36 | &:after{ 37 | border-bottom-color: @brand-info; 38 | } 39 | } 40 | &.arrow-success{ 41 | &:after{ 42 | border-bottom-color: @brand-success; 43 | } 44 | } 45 | &.arrow-danger{ 46 | &:after{ 47 | border-bottom-color: @brand-danger; 48 | } 49 | } 50 | &.arrow-warning{ 51 | &:after{ 52 | border-bottom-color: @brand-warning; 53 | } 54 | } 55 | &.arrow-light{ 56 | &:after{ 57 | border-bottom-color: @brand-light; 58 | } 59 | } 60 | &.arrow-dark{ 61 | &:after{ 62 | border-bottom-color: @brand-dark; 63 | } 64 | } 65 | &.arrow-black{ 66 | &:after{ 67 | border-bottom-color: @brand-black; 68 | } 69 | } 70 | } 71 | 72 | &.right { 73 | top: 50%; 74 | right: -@arrow-outer-width; 75 | margin-top: -@arrow-outer-width; 76 | border-right-width: 0; 77 | border-left-color: @arrow-outer-color; 78 | &:after { 79 | right: 1px; 80 | bottom: -@arrow-width; 81 | border-right-width: 0; 82 | border-left-color: @arrow-color; 83 | } 84 | &.arrow-primary{ 85 | &:after{ 86 | border-left-color: @brand-primary; 87 | } 88 | } 89 | &.arrow-info{ 90 | &:after{ 91 | border-left-color: @brand-info; 92 | } 93 | } 94 | &.arrow-success{ 95 | &:after{ 96 | border-left-color: @brand-success; 97 | } 98 | } 99 | &.arrow-danger{ 100 | &:after{ 101 | border-left-color: @brand-danger; 102 | } 103 | } 104 | &.arrow-warning{ 105 | &:after{ 106 | border-left-color: @brand-warning; 107 | } 108 | } 109 | &.arrow-light{ 110 | &:after{ 111 | border-left-color: @brand-light; 112 | } 113 | } 114 | &.arrow-dark{ 115 | &:after{ 116 | border-left-color: @brand-dark; 117 | } 118 | } 119 | &.arrow-black{ 120 | &:after{ 121 | border-left-color: @brand-black; 122 | } 123 | } 124 | } 125 | 126 | &.bottom { 127 | left: 50%; 128 | bottom: -@arrow-outer-width; 129 | margin-left: -@arrow-outer-width; 130 | border-bottom-width: 0; 131 | border-top-color: @arrow-outer-color; 132 | &:after { 133 | bottom: 1px; 134 | margin-left: -@arrow-width; 135 | border-bottom-width: 0; 136 | border-top-color: @arrow-color; 137 | } 138 | &.arrow-primary{ 139 | &:after{ 140 | border-top-color: @brand-primary; 141 | } 142 | } 143 | &.arrow-info{ 144 | &:after{ 145 | border-top-color: @brand-info; 146 | } 147 | } 148 | &.arrow-success{ 149 | &:after{ 150 | border-top-color: @brand-success; 151 | } 152 | } 153 | &.arrow-danger{ 154 | &:after{ 155 | border-top-color: @brand-danger; 156 | } 157 | } 158 | &.arrow-warning{ 159 | &:after{ 160 | border-top-color: @brand-warning; 161 | } 162 | } 163 | &.arrow-light{ 164 | &:after{ 165 | border-top-color: @brand-light; 166 | } 167 | } 168 | &.arrow-dark{ 169 | &:after{ 170 | border-top-color: @brand-dark; 171 | } 172 | } 173 | &.arrow-black{ 174 | &:after{ 175 | border-top-color: @brand-black; 176 | } 177 | } 178 | } 179 | 180 | &.left { 181 | top: 50%; 182 | left: -@arrow-outer-width; 183 | margin-top: -@arrow-outer-width; 184 | border-left-width: 0; 185 | border-right-color: @arrow-outer-color; 186 | &:after { 187 | left: 1px; 188 | bottom: -@arrow-width; 189 | border-left-width: 0; 190 | border-right-color: @arrow-color; 191 | } 192 | &.arrow-primary{ 193 | &:after{ 194 | border-right-color: @brand-primary; 195 | } 196 | } 197 | &.arrow-info{ 198 | &:after{ 199 | border-right-color: @brand-info; 200 | } 201 | } 202 | &.arrow-success{ 203 | &:after{ 204 | border-right-color: @brand-success; 205 | } 206 | } 207 | &.arrow-danger{ 208 | &:after{ 209 | border-right-color: @brand-danger; 210 | } 211 | } 212 | &.arrow-warning{ 213 | &:after{ 214 | border-right-color: @brand-warning; 215 | } 216 | } 217 | &.arrow-light{ 218 | &:after{ 219 | border-right-color: @brand-light; 220 | } 221 | } 222 | &.arrow-dark{ 223 | &:after{ 224 | border-right-color: @brand-dark; 225 | } 226 | } 227 | &.arrow-black{ 228 | &:after{ 229 | border-right-color: @brand-black; 230 | } 231 | } 232 | } 233 | 234 | &.pull-left{ 235 | left: @arrow-outer-width + 10; 236 | } 237 | &.pull-right{ 238 | left: auto; 239 | right: @arrow-outer-width + 10; 240 | } 241 | &.pull-up{ 242 | top: @arrow-outer-width + 10; 243 | } 244 | &.pull-down{ 245 | top: auto; 246 | bottom: @arrow-outer-width + 10; 247 | } 248 | 249 | } -------------------------------------------------------------------------------- /src/css/less/app.butterbar.less: -------------------------------------------------------------------------------- 1 | .butterbar{ 2 | position: relative; 3 | margin-bottom: -@butterbar-height; 4 | height: @butterbar-height; 5 | .bar{ 6 | position: absolute; 7 | height: 0; 8 | width: 100%; 9 | text-indent: -9999px; 10 | background-color: @brand-info; 11 | &:before{ 12 | content: ""; 13 | height: @butterbar-height; 14 | position: absolute; 15 | left: 50%; 16 | right: 50%; 17 | background-color: inherit; 18 | } 19 | } 20 | } 21 | .butterbar.active{ 22 | -webkit-animation: changebar @butterbar-time*3 infinite @butterbar-time; 23 | -moz-animation: changebar @butterbar-time*3 infinite @butterbar-time; 24 | animation: changebar @butterbar-time*3 infinite @butterbar-time; 25 | .bar{ 26 | -webkit-animation: changebar @butterbar-time*3 infinite; 27 | -moz-animation: changebar @butterbar-time*3 infinite; 28 | animation: changebar @butterbar-time*3 infinite; 29 | &:before{ 30 | -webkit-animation: movingbar @butterbar-time infinite; 31 | -moz-animation: movingbar @butterbar-time infinite; 32 | animation: movingbar @butterbar-time infinite; 33 | } 34 | } 35 | } 36 | 37 | /* Moving bar */ 38 | @-webkit-keyframes movingbar{ 39 | 0% { left:50%; right:50% } 40 | 99.9% { left:0%; right:0% } 41 | 100% { left:50%; right:50%} 42 | } 43 | 44 | @-moz-keyframes movingbar{ 45 | 0% { left:50%; right:50% } 46 | 99.9% { left:0%; right:0% } 47 | 100% { left:50%; right:50%} 48 | } 49 | 50 | @keyframes movingbar{ 51 | 0% { left:50%; right:50% } 52 | 99.9% { left:0%; right:0% } 53 | 100% { left:50%; right:50%} 54 | } 55 | 56 | /* change bar */ 57 | @-webkit-keyframes changebar{ 58 | 0% { background-color: @brand-info } 59 | 33.3% { background-color: @brand-info } 60 | 33.33% { background-color: @brand-warning } 61 | 66.6% { background-color: @brand-warning } 62 | 66.66% { background-color: @brand-primary } 63 | 99.9% { background-color: @brand-primary } 64 | } 65 | 66 | @-moz-keyframes changebar{ 67 | 0% { background-color: @brand-info } 68 | 33.3% { background-color: @brand-info } 69 | 33.33% { background-color: @brand-warning } 70 | 66.6% { background-color: @brand-warning } 71 | 66.66% { background-color: @brand-primary } 72 | 99.9% { background-color: @brand-primary } 73 | } 74 | 75 | @keyframes changebar{ 76 | 0% { background-color: @brand-info } 77 | 33.3% { background-color: @brand-info } 78 | 33.33% { background-color: @brand-warning } 79 | 66.6% { background-color: @brand-warning } 80 | 66.66% { background-color: @brand-primary } 81 | 99.9% { background-color: @brand-primary } 82 | } -------------------------------------------------------------------------------- /src/css/less/app.buttons.less: -------------------------------------------------------------------------------- 1 | .btn{ 2 | font-weight: 500; 3 | border-radius: @btn-border-radius; 4 | outline: 0!important; 5 | } 6 | .btn-link{ 7 | color: @text-color; 8 | &.active{ 9 | webkit-box-shadow:none; 10 | box-shadow:none; 11 | } 12 | } 13 | 14 | .btn-default{ 15 | .button-variant(@text-color, @btn-default-bg, @btn-default-border); 16 | background-color: #fff; 17 | border-bottom-color: darken(@btn-default-border, 2%); 18 | .box-shadow(0 1px 1px rgba(90,90,90,0.1)); 19 | &.btn-bg{ 20 | border-color:rgba(0,0,0,0.1); 21 | background-clip: padding-box; 22 | } 23 | } 24 | 25 | .btn-primary{ 26 | .button-variant(#fff, @brand-primary, @brand-primary); 27 | } 28 | 29 | .btn-success{ 30 | .button-variant(#fff, @brand-success, @brand-success); 31 | } 32 | 33 | .btn-info{ 34 | .button-variant(#fff, @brand-info, @brand-info); 35 | } 36 | 37 | .btn-warning{ 38 | .button-variant(#fff, @brand-warning, @brand-warning); 39 | } 40 | 41 | .btn-danger{ 42 | .button-variant(#fff, @brand-danger, @brand-danger); 43 | } 44 | 45 | .btn-dark{ 46 | .button-variant(#fff, @brand-dark, @brand-dark); 47 | } 48 | 49 | .btn-black{ 50 | .button-variant(#fff, @brand-black, @brand-black); 51 | } 52 | 53 | .btn-icon{ 54 | padding: 0 !important; 55 | text-align: center; 56 | width:34px; 57 | height: 34px; 58 | i{ 59 | top: -1px; 60 | position: relative; 61 | line-height: 34px; 62 | } 63 | &.btn-sm{ 64 | width: 30px; 65 | height: 30px; 66 | i{ 67 | line-height: 30px; 68 | } 69 | } 70 | &.btn-lg{ 71 | width: 45px; 72 | height: 45px; 73 | i{ 74 | line-height: 45px; 75 | } 76 | } 77 | } 78 | 79 | .btn-rounded{ 80 | border-radius: 50px; 81 | padding-left: 15px; 82 | padding-right: 15px; 83 | &.btn-lg{ 84 | padding-left: 25px; 85 | padding-right: 25px; 86 | } 87 | } 88 | 89 | .btn{ 90 | > i{ 91 | &.pull-left, 92 | &.pull-right{ 93 | line-height: @line-height-base; 94 | } 95 | } 96 | } 97 | 98 | .btn-block { 99 | padding-left: 12px; 100 | padding-right: 12px; 101 | } 102 | 103 | .btn-group-vertical > .btn:first-child:not(:last-child){ 104 | border-top-right-radius: @border-radius-base; 105 | } 106 | 107 | .btn-group-vertical > .btn:last-child:not(:first-child){ 108 | border-bottom-left-radius: @border-radius-base; 109 | } 110 | 111 | .btn-addon { 112 | i{ 113 | margin: -7px -12px; 114 | margin-right: 12px; 115 | background-color: rgba(0, 0, 0, 0.1); 116 | width: 34px; 117 | height: 34px; 118 | line-height: 34px; 119 | text-align: center; 120 | float: left; 121 | position: relative; 122 | border-radius: @btn-border-radius 0 0 @btn-border-radius; 123 | &.pull-right{ 124 | margin-right: -12px; 125 | margin-left: 12px; 126 | border-radius: 0 @btn-border-radius @btn-border-radius 0; 127 | } 128 | } 129 | &.btn-sm{ 130 | i{ 131 | margin: -6px -10px; 132 | margin-right: 10px; 133 | width: 30px; 134 | height: 30px; 135 | line-height: 30px; 136 | &.pull-right{ 137 | margin-right: -10px; 138 | margin-left: 10px; 139 | } 140 | } 141 | } 142 | &.btn-lg{ 143 | i{ 144 | margin: -11px -16px; 145 | margin-right: 16px; 146 | width: 45px; 147 | height: 45px; 148 | line-height: 45px; 149 | &.pull-right{ 150 | margin-right: -16px; 151 | margin-left: 16px; 152 | } 153 | } 154 | } 155 | &.btn-default{ 156 | i{ 157 | background-color: transparent; 158 | border-right: 1px solid @border-color; 159 | } 160 | } 161 | } 162 | 163 | .btn-groups .btn{ 164 | margin-bottom: 5px; 165 | } -------------------------------------------------------------------------------- /src/css/less/app.colors.less: -------------------------------------------------------------------------------- 1 | .bg-gd{ 2 | #gradient > .vertical(rgba(40,50,60,0), rgba(40,50,60,0.075), 0, 100%); 3 | filter:none; 4 | } 5 | 6 | .bg-gd-dk{ 7 | #gradient > .vertical(rgba(40,50,60,0), rgba(40,50,60,0.5), 10%, 100%); 8 | filter:none; 9 | } 10 | 11 | .bg-light { 12 | .color-variant(@brand-light, 2%, 3%, 3%, 5%); 13 | color: @text-color; 14 | } 15 | 16 | .bg-dark { 17 | .color-variant(@brand-dark, 5%, 10%, 5%, 10%); 18 | .font-variant(@brand-dark); 19 | } 20 | 21 | .bg-black { 22 | .color-variant(@brand-black, 5%, 10%, 5%, 10%); 23 | .font-variant(@brand-black); 24 | } 25 | 26 | .bg-primary { 27 | .color-variant(@brand-primary, 5%, 10%, 5%, 10%); 28 | .font-variant(@brand-primary); 29 | } 30 | 31 | .bg-success { 32 | .color-variant(@brand-success, 5%, 10%, 5%, 10%); 33 | .font-variant(@brand-success); 34 | } 35 | 36 | .bg-info { 37 | .color-variant(@brand-info, 5%, 10%, 5%, 10%); 38 | .font-variant(@brand-info); 39 | } 40 | 41 | .bg-warning { 42 | .color-variant(@brand-warning, 5%, 10%, 5%, 10%); 43 | .font-variant(@brand-warning); 44 | } 45 | 46 | .bg-danger { 47 | .color-variant(@brand-danger, 5%, 10%, 5%, 10%); 48 | .font-variant(@brand-danger); 49 | } 50 | 51 | .bg-white { 52 | background-color: #fff; 53 | color: @text-color; 54 | a { 55 | color: @link-color; 56 | &:hover{ 57 | color: darken(@link-color, 10%); 58 | } 59 | } 60 | .text-muted{color: @text-muted !important;} 61 | .lt, 62 | .lter, 63 | .dk, 64 | .dker{ 65 | background-color: #fff; 66 | } 67 | } 68 | .bg-white-only{background-color:#fff;} 69 | .bg-white-opacity{ 70 | background-color: rgba(255, 255, 255, 0.5); 71 | } 72 | .bg-black-opacity{ 73 | background-color: rgba(32, 43, 54, 0.5); 74 | } 75 | 76 | a.bg-light{ 77 | &:hover{ 78 | color: @link-color; 79 | } 80 | } 81 | 82 | .text-wariant(@brand-primary, primary); 83 | .text-wariant(@brand-info, info); 84 | .text-wariant(@brand-success, success); 85 | .text-wariant(@brand-warning, warning); 86 | .text-wariant(@brand-danger, danger); 87 | .text-wariant(@brand-dark, dark); 88 | .text-wariant(@brand-black, black); 89 | 90 | .text-white { 91 | color: #fff; 92 | } 93 | .text-black { 94 | color: #000; 95 | } 96 | 97 | .text-muted { 98 | color: @text-muted; 99 | } -------------------------------------------------------------------------------- /src/css/less/app.components.less: -------------------------------------------------------------------------------- 1 | .i-switch { 2 | cursor: pointer; 3 | position: relative; 4 | display: inline-block; 5 | width: @switch-width; 6 | height: @switch-height; 7 | border-radius: 30px; 8 | background-color: @brand-success; 9 | margin: 0; 10 | input { 11 | position: absolute; 12 | .opacity(0); 13 | &:checked { 14 | + i { 15 | &:before { 16 | top: 50%; 17 | bottom: 50%; 18 | left: 50%; 19 | right: 5px; 20 | border-width: 0; 21 | border-radius: 5px; 22 | } 23 | &:after { 24 | margin-left: @switch-width - @switch-height + 1; 25 | } 26 | } 27 | } 28 | } 29 | i { 30 | &:before { 31 | content: ""; 32 | position: absolute; 33 | top: -1px; 34 | bottom: -1px; 35 | left: -1px; 36 | right: -1px; 37 | background-color: #fff; 38 | border: 1px solid #f0f0f0; 39 | border-radius: 30px; 40 | .transition(all 0.2s); 41 | } 42 | &:after { 43 | content: ""; 44 | position: absolute; 45 | background-color: #fff; 46 | width: @switch-height - 2; 47 | top: 1px; 48 | bottom: 1px; 49 | border-radius: 50%; 50 | .box-shadow(1px 1px 3px rgba(0, 0, 0, 0.25)); 51 | .transition(margin-left 0.3s); 52 | } 53 | } 54 | } 55 | 56 | .i-switch-md { 57 | width: @switch-md-width; 58 | height: @switch-md-height; 59 | input { 60 | &:checked { 61 | + i { 62 | &:after { 63 | margin-left: @switch-md-width - @switch-md-height + 1; 64 | } 65 | } 66 | } 67 | } 68 | i { 69 | &:after { 70 | width: @switch-md-height - 2; 71 | } 72 | } 73 | } 74 | 75 | .i-switch-lg { 76 | width: @switch-lg-width; 77 | height: @switch-lg-height; 78 | input { 79 | &:checked { 80 | + i { 81 | &:after { 82 | margin-left: @switch-lg-width - @switch-lg-height + 1; 83 | } 84 | } 85 | } 86 | } 87 | i { 88 | &:after { 89 | width: @switch-lg-height - 2; 90 | } 91 | } 92 | } 93 | 94 | .i-checks { 95 | padding-left: 20px; 96 | cursor: pointer; 97 | input { 98 | opacity: 0; 99 | position: absolute; 100 | margin-left: -20px; 101 | &:checked + i { 102 | border-color: @brand-info; 103 | &:before { 104 | left: 4px; 105 | top: 4px; 106 | width: 10px; 107 | height: 10px; 108 | background-color: @brand-info; 109 | } 110 | } 111 | &:checked + span .active { 112 | display: inherit; 113 | } 114 | &[type="radio"] + i { 115 | &, 116 | &:before { 117 | border-radius: 50%; 118 | } 119 | } 120 | &[type="checkbox"]:checked + i:before { 121 | 122 | } 123 | &[type="radio"]:checked + i:before { 124 | 125 | } 126 | &[disabled], 127 | fieldset[disabled] & { 128 | & + i { 129 | border-color: lighten(@input-border, 5%); 130 | &:before { 131 | background-color: lighten(@input-border, 5%); 132 | } 133 | } 134 | } 135 | } 136 | > i { 137 | width: 20px; 138 | height: 20px; 139 | line-height: 1; 140 | border: 1px solid @input-border; 141 | background-color: #fff; 142 | margin-left: -20px; 143 | margin-top: -2px; 144 | display: inline-block; 145 | vertical-align: middle; 146 | margin-right: 4px; 147 | position: relative; 148 | &:before { 149 | content: ""; 150 | position: absolute; 151 | left: 50%; 152 | top: 50%; 153 | width: 0px; 154 | height: 0px; 155 | background-color: transparent; 156 | .transition(all 0.2s); 157 | } 158 | } 159 | > span { 160 | margin-left: -20px; 161 | .active { 162 | display: none; 163 | } 164 | } 165 | } 166 | 167 | .i-checks-sm { 168 | input { 169 | &:checked + i { 170 | &:before { 171 | left: 3px; 172 | top: 3px; 173 | width: 8px; 174 | height: 8px; 175 | } 176 | } 177 | } 178 | > i { 179 | width: 16px; 180 | height: 16px; 181 | margin-left: -18px; 182 | margin-right: 6px; 183 | } 184 | } 185 | 186 | .i-checks-lg { 187 | input { 188 | &:checked + i { 189 | &:before { 190 | left: 8px; 191 | top: 8px; 192 | width: 12px; 193 | height: 12px; 194 | } 195 | } 196 | } 197 | > i { 198 | width: 30px; 199 | height: 30px; 200 | } 201 | } 202 | 203 | .hide-file { 204 | input[type="file"] { 205 | position: absolute; 206 | left: 0; 207 | top: 0; 208 | opacity: 0; 209 | } 210 | } 211 | 212 | // ui.bootstrap datepicker 213 | .datepicker { 214 | margin: 0 5px 215 | } 216 | 217 | .datepicker .btn-default { 218 | border-width: 0; 219 | box-shadow: none; 220 | } 221 | 222 | .datepicker .btn[disabled] { 223 | opacity: 0.4 224 | } 225 | 226 | .datepicker .btn-info .text-info { 227 | color: #fff !important; 228 | } -------------------------------------------------------------------------------- /src/css/less/app.item.less: -------------------------------------------------------------------------------- 1 | .item { 2 | position: relative; 3 | .top { 4 | position: absolute; 5 | top: 0; 6 | left: 0; 7 | } 8 | .bottom { 9 | position: absolute; 10 | bottom: 0; 11 | left: 0; 12 | } 13 | .center { 14 | position: absolute; 15 | top: 50%; 16 | } 17 | } 18 | 19 | .item-overlay { 20 | display: none; 21 | position: absolute; 22 | top: 0; 23 | right: 0; 24 | bottom: 0; 25 | left: 0; 26 | &.active, 27 | .item:hover & { 28 | display: block; 29 | } 30 | } 31 | 32 | .loading { 33 | position: fixed; 34 | width: 100%; 35 | height: 100%; 36 | background: rgba(255, 255, 255, 0.5); 37 | z-index: 999999; 38 | top: 0; 39 | left: 0; 40 | 41 | .load { 42 | width: 160px; 43 | height: 56px; 44 | position: absolute; 45 | top: 0; 46 | right: 0; 47 | bottom: 0; 48 | left: 0; 49 | margin: auto; 50 | line-height: 56px; 51 | color: #fff; 52 | padding-left: 60px; 53 | font-size: 15px; 54 | background: #000 url('../img/loading.gif') no-repeat 10px 50%; 55 | opacity: 0.7; 56 | z-index: 9999; 57 | -moz-border-radius: 20px; 58 | -webkit-border-radius: 20px; 59 | border-radius: 20px; 60 | filter: progid:DXImageTransform.Microsoft.Alpha(opacity=70); 61 | } 62 | } -------------------------------------------------------------------------------- /src/css/less/app.layout.boxed.less: -------------------------------------------------------------------------------- 1 | html{ 2 | background: url('../img/bg.jpg'); 3 | background-attachment: fixed; 4 | background-size: cover; 5 | } 6 | 7 | .app.container{ 8 | padding-left: 0; 9 | padding-right: 0; 10 | } 11 | 12 | @media (min-width: 768px) { 13 | .app.container{ 14 | width: 750px; 15 | .box-shadow(0 0 30px rgba(0,0,0,0.3)); 16 | .app-aside{ 17 | overflow-x: hidden; 18 | } 19 | 20 | &.app-aside-folded{ 21 | .app-aside{ 22 | overflow-x: visible; 23 | } 24 | } 25 | &.app-aside-fixed{ 26 | .aside-wrap{ 27 | left: inherit; 28 | } 29 | &.app-aside-folded{ 30 | .app-aside{ 31 | > ul.nav{ 32 | position: absolute; 33 | } 34 | } 35 | } 36 | } 37 | 38 | .app-header, 39 | .app-aside{ 40 | max-width: 750px; 41 | } 42 | .app-footer-fixed{ 43 | left: auto; 44 | right: auto; 45 | width: 100%; 46 | max-width: 750 - @app-aside-width; 47 | } 48 | &.app-aside-folded{ 49 | .app-footer-fixed{ 50 | max-width: 750 - @app-aside-folded-width; 51 | } 52 | } 53 | &.app-aside-dock{ 54 | .app-footer-fixed{ 55 | max-width: 750px; 56 | } 57 | } 58 | } 59 | } 60 | 61 | @media (min-width: 992px) { 62 | .app.container{ 63 | width: 970px; 64 | .app-header, 65 | .app-aside{ 66 | max-width: 970px; 67 | } 68 | .app-footer-fixed{ 69 | max-width: 970 - @app-aside-width; 70 | } 71 | &.app-aside-folded{ 72 | .app-footer-fixed{ 73 | max-width: 970 - @app-aside-folded-width; 74 | } 75 | } 76 | &.app-aside-dock{ 77 | .app-footer-fixed{ 78 | max-width: 970px; 79 | } 80 | } 81 | } 82 | } 83 | 84 | @media (min-width: 1200px) { 85 | .app.container{ 86 | width: 1170px; 87 | .app-header, 88 | .app-aside{ 89 | max-width: 1170px; 90 | } 91 | .app-footer-fixed{ 92 | max-width: 1170 - @app-aside-width; 93 | } 94 | &.app-aside-folded{ 95 | .app-footer-fixed{ 96 | max-width: 1170 - @app-aside-folded-width; 97 | } 98 | } 99 | &.app-aside-dock{ 100 | .app-footer-fixed{ 101 | max-width: 1170px; 102 | } 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /src/css/less/app.less: -------------------------------------------------------------------------------- 1 | // Core variables and mixins 2 | @import "app.variables.less"; 3 | @import "app.mixins.less"; 4 | 5 | @import "app.reset.less"; 6 | @import "app.layout.less"; 7 | @import "app.layout.boxed.less"; 8 | @import "app.nav.less"; 9 | @import "app.nav.offscreen.less"; 10 | @import "app.nav.dock.less"; 11 | 12 | @import "app.arrow.less"; 13 | @import "app.buttons.less"; 14 | @import "app.widgets.less"; 15 | 16 | @import "app.components.less"; 17 | @import "app.plugin.less"; 18 | @import "app.item.less"; 19 | @import "app.ng.less"; 20 | 21 | @import "app.colors.less"; 22 | @import "app.utilities.less"; 23 | 24 | @import "app.butterbar.less"; -------------------------------------------------------------------------------- /src/css/less/app.nav.dock.less: -------------------------------------------------------------------------------- 1 | @media (min-width: @app-aside-dock-media) { 2 | .app-aside-dock{ 3 | .app-content, 4 | .app-footer{ 5 | margin-left: 0; 6 | } 7 | .app-aside-footer ~ div{ 8 | padding-bottom: 0; 9 | } 10 | &.app-aside-fixed{ 11 | &.app-header-fixed{ 12 | padding-top: 115px; 13 | } 14 | .app-aside{ 15 | position: fixed; 16 | top: 50px; 17 | width: 100%; 18 | z-index: 1000; 19 | } 20 | } 21 | .app-aside, 22 | .aside-wrap, 23 | .navi-wrap{ 24 | float: none; 25 | width: 100% !important; 26 | position: relative; 27 | top: 0; 28 | overflow: visible !important; 29 | } 30 | 31 | .app-aside{ 32 | bottom: auto !important; 33 | &.b-r{ 34 | border-right-width: 0; 35 | border-bottom:1px solid @border-color; 36 | } 37 | &:before { 38 | display: none; 39 | } 40 | nav > .nav{ 41 | float: left; 42 | } 43 | .hidden-folded, 44 | .line, 45 | .navi-wrap > div{ 46 | display: none !important; 47 | } 48 | .navi > ul > li{ 49 | position: relative; 50 | float: left; 51 | display: inline-block; 52 | > a{ 53 | padding: 10px 15px 12px 15px; 54 | text-align: center; 55 | height: auto; 56 | > .badge, 57 | > .label{ 58 | position: absolute; 59 | top: 5px; 60 | right: 8px; 61 | padding: 1px 4px; 62 | } 63 | > i{ 64 | margin-left: auto; 65 | margin-right: auto; 66 | margin-bottom: -7px; 67 | margin-top: -10px; 68 | display: block; 69 | float: none; 70 | font-size: 14px; 71 | line-height: 40px; 72 | width: 40px; 73 | } 74 | > span.pull-right{ 75 | position: absolute; 76 | bottom: 2px; 77 | left: 50%; 78 | margin-left: -6px; 79 | display: block !important; 80 | line-height: 1; 81 | i { 82 | &.text{ 83 | .rotate(90deg); 84 | line-height: 14px; 85 | } 86 | line-height: 12px; 87 | width: 12px; 88 | font-size: 12px; 89 | } 90 | } 91 | > span{ 92 | font-weight: normal; 93 | display: block; 94 | } 95 | } 96 | .nav-sub{ 97 | height: auto !important; 98 | display: none; 99 | position: absolute; 100 | left: 0; 101 | top: auto !important; 102 | z-index: 1050; 103 | width: @app-aside-width; 104 | .box-shadow(0 2px 6px rgba(0,0,0,0.1)); 105 | } 106 | .nav-sub-header{ 107 | display: none !important; 108 | } 109 | } 110 | .navi li li a{ 111 | padding-left: 15px; 112 | } 113 | .navi li:hover, 114 | .navi li:focus, 115 | .navi li:active{ 116 | > .nav-sub{ 117 | display: block; 118 | opacity: 1; 119 | margin-left: 0; 120 | height: auto !important; 121 | overflow: auto; 122 | } 123 | } 124 | } 125 | } 126 | } -------------------------------------------------------------------------------- /src/css/less/app.nav.less: -------------------------------------------------------------------------------- 1 | .nav-sub{ 2 | opacity: 0; 3 | height: 0; 4 | overflow: hidden; 5 | margin-left: -20px; 6 | .transition(all .2s ease-in-out 0s); 7 | 8 | .active > &, 9 | .app-aside-folded li:hover > &, 10 | .app-aside-folded li:focus > &, 11 | .app-aside-folded li:active > &{ 12 | opacity: 1; 13 | margin-left: 0; 14 | height: auto !important; 15 | overflow: auto; 16 | } 17 | } 18 | 19 | .nav-sub-header { 20 | display: none !important; 21 | a{ 22 | padding: floor((@app-aside-folded-nav-height - @line-height-computed)/2) 20px; 23 | } 24 | } 25 | 26 | .navi { 27 | ul.nav { 28 | li { 29 | display: block; 30 | position: relative; 31 | li { 32 | a { 33 | padding-left: @app-aside-nav-height + 15px; 34 | } 35 | ul{ 36 | display:none; 37 | } 38 | &.active > ul{ 39 | display:block; 40 | } 41 | } 42 | a { 43 | font-weight: normal; 44 | text-transform: none; 45 | display: block; 46 | padding: floor((@app-aside-nav-height - @line-height-computed)/2) 20px; 47 | position: relative; 48 | .transition(background-color .2s ease-in-out 0s); 49 | .badge, 50 | .label { 51 | font-size: 11px; 52 | padding: 2px 5px; 53 | margin-top: 2px; 54 | } 55 | > i { 56 | margin: floor(-(@app-aside-nav-height - @line-height-computed)/2) -10px; 57 | line-height: @app-aside-nav-height; 58 | width: @app-aside-nav-height; 59 | float: left; 60 | margin-right: 5px; 61 | text-align: center; 62 | position: relative; 63 | top: 0; 64 | overflow: hidden; 65 | &:before { 66 | position: relative; 67 | z-index: 2; 68 | } 69 | } 70 | } 71 | } 72 | } 73 | } 74 | 75 | @media (min-width: 768px) { 76 | .app-aside-folded{ 77 | .nav-sub-header{ 78 | display: block !important; 79 | a{ 80 | padding: floor((@app-aside-folded-nav-height - @line-height-computed)/2) 20px !important; 81 | } 82 | } 83 | .navi{ 84 | > ul { 85 | > li { 86 | > a { 87 | position: relative; 88 | padding: 0; 89 | text-align: center; 90 | height: @app-aside-folded-nav-height; 91 | border: none; 92 | span { 93 | display: none; 94 | &.pull-right{ 95 | display: none !important; 96 | } 97 | } 98 | i{ 99 | width: auto; 100 | float: none; 101 | display: block; 102 | font-size: 16px; 103 | margin: 0; 104 | line-height: @app-aside-folded-nav-height; 105 | border: none !important; 106 | b{ 107 | left: 0 !important; 108 | } 109 | } 110 | .badge, 111 | .label{ 112 | position: absolute; 113 | right: 12px; 114 | top: 8px; 115 | z-index: 3; 116 | } 117 | } 118 | } 119 | > li > ul{ 120 | height: 0 !important; 121 | position: absolute; 122 | left: 100%; 123 | top: 0 !important; 124 | z-index: 1050; 125 | width: @app-aside-width; 126 | .box-shadow(0 2px 6px rgba(0,0,0,0.1)); 127 | } 128 | } 129 | li { 130 | li{ 131 | a{ 132 | padding-left: 20px !important; 133 | } 134 | } 135 | } 136 | } 137 | } 138 | 139 | .app-aside-folded.app-aside-fixed .app-aside{ 140 | > ul.nav { 141 | &:before{ 142 | content:""; 143 | width: @app-aside-folded-width; 144 | height: @app-aside-folded-nav-height; 145 | position: absolute; 146 | left: -@app-aside-folded-width; 147 | top: 0; 148 | } 149 | z-index: 1010; 150 | opacity: 1; 151 | height: auto; 152 | overflow: visible; 153 | overflow-y: auto; 154 | display: block; 155 | width: @app-aside-width + @app-aside-folded-width; 156 | left: @app-aside-folded-width + 20; 157 | position: fixed; 158 | -webkit-overflow-scrolling: touch; 159 | a{ 160 | padding-left: 20px !important; 161 | padding-right: 20px !important; 162 | } 163 | } 164 | } 165 | } -------------------------------------------------------------------------------- /src/css/less/app.nav.offscreen.less: -------------------------------------------------------------------------------- 1 | @media (max-width: 767px) { 2 | .app{ 3 | overflow-x: hidden; 4 | } 5 | .app-content{ 6 | .transition-transform(0.2s ease); 7 | } 8 | .off-screen{ 9 | position: absolute; 10 | top: 50px; 11 | bottom: 0; 12 | width: @off-screen-width; 13 | display: block !important; 14 | visibility: visible; 15 | overflow-x: hidden; 16 | overflow-y: auto; 17 | -webkit-overflow-scrolling: touch; 18 | z-index: 1010; 19 | + *{ 20 | background-color: @body-bg; 21 | .transition-transform(0.2s ease); 22 | .backface-visibility(hidden); 23 | .translate3d(@off-screen-width, 0px, 0px); 24 | overflow: hidden; 25 | position: absolute; 26 | width: 100%; 27 | top: 0; 28 | bottom: 0; 29 | left: 0; 30 | right: 0; 31 | z-index: 1015; 32 | padding-top: 50px; 33 | .off-screen-toggle { 34 | display:block !important; 35 | position: absolute; 36 | left: 0; 37 | right: 0; 38 | top: 0; 39 | bottom: 0; 40 | z-index: 1020; 41 | } 42 | } 43 | &.pull-right{ 44 | right: 0; 45 | + *{ 46 | .translate3d(-@off-screen-width, 0px, 0px); 47 | } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /src/css/less/app.ng.less: -------------------------------------------------------------------------------- 1 | .form-validation{ 2 | .form-control{ 3 | &.ng-dirty.ng-invalid{ 4 | border-color: @brand-danger; 5 | } 6 | &.ng-dirty.ng-valid{ 7 | &, 8 | &:focus{ 9 | border-color: @brand-success; 10 | } 11 | } 12 | } 13 | 14 | .i-checks{ 15 | .ng-invalid.ng-dirty + i{ 16 | border-color: @brand-danger; 17 | } 18 | } 19 | } 20 | 21 | .ng-animate .bg-auto:before{ 22 | display: none; 23 | } 24 | 25 | [ui-view].ng-leave { 26 | display: none; 27 | } 28 | 29 | [ui-view].ng-leave.smooth { 30 | display: block; 31 | } 32 | 33 | .smooth.ng-animate{ 34 | position: absolute; 35 | width: 100%; 36 | height: 100%; 37 | overflow: hidden; 38 | } 39 | 40 | // big animation 41 | .fade-in-right-big.ng-enter { 42 | -webkit-animation: fadeInRightBig 0.5s; 43 | animation: fadeInRightBig 0.5s; 44 | } 45 | .fade-in-right-big.ng-leave { 46 | -webkit-animation: fadeOutLeftBig 0.5s; 47 | animation: fadeOutLeftBig 0.5s; 48 | } 49 | 50 | .fade-in-left-big.ng-enter { 51 | -webkit-animation: fadeInLeftBig 0.5s; 52 | animation: fadeInLeftBig 0.5s; 53 | } 54 | .fade-in-left-big.ng-leave { 55 | -webkit-animation: fadeOutRightBig 0.5s; 56 | animation: fadeOutRightBig 0.5s; 57 | } 58 | 59 | .fade-in-up-big.ng-enter { 60 | -webkit-animation: fadeInUpBig 0.5s; 61 | animation: fadeInUpBig 0.5s; 62 | } 63 | .fade-in-up-big.ng-leave { 64 | -webkit-animation: fadeOutUpBig 0.5s; 65 | animation: fadeOutUpBig 0.5s; 66 | } 67 | 68 | .fade-in-down-big.ng-enter { 69 | -webkit-animation: fadeInDownBig 0.5s; 70 | animation: fadeInDownBig 0.5s; 71 | } 72 | .fade-in-down-big.ng-leave { 73 | -webkit-animation: fadeOutDownBig 0.5s; 74 | animation: fadeOutDownBig 0.5s; 75 | } 76 | 77 | // small 78 | .fade-in.ng-enter { 79 | -webkit-animation: fadeIn 0.5s; 80 | animation: fadeIn 0.5s; 81 | } 82 | .fade-in.ng-leave { 83 | -webkit-animation: fadeOut 0.5s; 84 | animation: fadeOut 0.5s; 85 | } 86 | 87 | .fade-in-right.ng-enter { 88 | -webkit-animation: fadeInRight 0.5s; 89 | animation: fadeInRight 0.5s; 90 | } 91 | .fade-in-right.ng-leave { 92 | -webkit-animation: fadeOutLeft 0.5s; 93 | animation: fadeOutLeft 0.5s; 94 | } 95 | 96 | .fade-in-left.ng-enter { 97 | -webkit-animation: fadeInLeft 0.5s; 98 | animation: fadeInLeft 0.5s; 99 | } 100 | .fade-in-left.ng-leave { 101 | -webkit-animation: fadeOutRight 0.5s; 102 | animation: fadeOutRight 0.5s; 103 | } 104 | 105 | .fade-in-up.ng-enter { 106 | -webkit-animation: fadeInUp 0.5s; 107 | animation: fadeInUp 0.5s; 108 | } 109 | .fade-in-up.ng-leave { 110 | -webkit-animation: fadeOutUp 0.5s; 111 | animation: fadeOutUp 0.5s; 112 | } 113 | 114 | .fade-in-down.ng-enter { 115 | -webkit-animation: fadeInDown 0.5s; 116 | animation: fadeInDown 0.5s; 117 | } 118 | .fade-in-down.ng-leave { 119 | -webkit-animation: fadeOutDown 0.5s; 120 | animation: fadeOutDown 0.5s; 121 | } -------------------------------------------------------------------------------- /src/css/less/app.plugin.less: -------------------------------------------------------------------------------- 1 | /*Charts*/ 2 | .jqstooltip { 3 | background-color: rgba(0, 0, 0, 0.8) !important; 4 | border: solid 1px #000 !important; 5 | -webkit-border-radius: 3px; 6 | -moz-border-radius: 3px; 7 | border-radius: 3px; 8 | padding: 5px 10px !important; 9 | .box-sizing(content-box); 10 | } 11 | 12 | // easypie 13 | .easyPieChart { 14 | position: relative; 15 | text-align: center; 16 | > div { 17 | position: relative; 18 | z-index: 1; 19 | .text { 20 | position: absolute; 21 | width: 100%; 22 | top: 60%; 23 | line-height: 1; 24 | } 25 | img { 26 | margin-top: -4px; 27 | } 28 | } 29 | canvas { 30 | position: absolute; 31 | top: 0; 32 | left: 0; 33 | z-index: 0 34 | } 35 | } 36 | 37 | // flot tip 38 | #flotTip { 39 | padding: 4px 10px; 40 | background-color: rgba(0, 0, 0, 0.8); 41 | border: solid 1px #000 !important; 42 | z-index: 100; 43 | font-size: 12px; 44 | color: #fff; 45 | -webkit-border-radius: 3px; 46 | -moz-border-radius: 3px; 47 | border-radius: 3px; 48 | } 49 | 50 | // flot lengend 51 | .legendColorBox { 52 | > div { 53 | border: none !important; 54 | margin: 5px; 55 | > div { 56 | border-radius: 10px; 57 | } 58 | } 59 | } 60 | 61 | // sortable 62 | .sortable-placeholder { 63 | list-style: none; 64 | border: 1px dashed #CCC; 65 | min-height: 50px; 66 | margin-bottom: 5px 67 | } 68 | 69 | .table { 70 | > thead { 71 | .sorting, 72 | .sorting_asc, 73 | .sorting_desc { 74 | cursor: pointer; 75 | white-space: normal; 76 | } 77 | 78 | .sorting:after, 79 | .sorting_asc:after, 80 | .sorting_desc:after { 81 | font-family: FontAwesome; 82 | color: #ccc; 83 | position: relative; 84 | font-weight: normal; 85 | float: right; 86 | } 87 | 88 | .sorting:after { 89 | content: "\f0dc"; 90 | } 91 | .sorting_asc:after { 92 | content: "\f0de"; 93 | } 94 | .sorting_desc:after { 95 | content: "\f0dd"; 96 | } 97 | } 98 | } 99 | 100 | .ibox { 101 | clear: both; 102 | margin-bottom: 25px; 103 | margin-top: 0; 104 | padding: 0; 105 | } 106 | 107 | .ibox.collapsed .ibox-content { 108 | display: none; 109 | } 110 | 111 | .ibox.collapsed .fa.fa-chevron-up:before { 112 | content: "\f078"; 113 | } 114 | 115 | .ibox.collapsed .fa.fa-chevron-down:before { 116 | content: "\f077"; 117 | } 118 | 119 | .ibox:after, .ibox:before { 120 | display: table; 121 | } 122 | 123 | .ibox-title { 124 | -moz-border-bottom-colors: none; 125 | -moz-border-left-colors: none; 126 | -moz-border-right-colors: none; 127 | -moz-border-top-colors: none; 128 | background-color: @ibox-title-bg; 129 | border-color: @border-color; 130 | border-image: none; 131 | border-style: solid solid none; 132 | border-width: 3px 0 0; 133 | color: inherit; 134 | margin-bottom: 0; 135 | padding: 14px 15px 7px; 136 | min-height: 48px; 137 | } 138 | 139 | .ibox-content { 140 | background-color: @ibox-content-bg; 141 | color: inherit; 142 | padding: 15px 20px 20px 20px; 143 | 144 | border-color: @border-color; 145 | border-image: none; 146 | border-style: solid solid none; 147 | border-width: 1px 0; 148 | } 149 | 150 | .ibox-footer { 151 | color: inherit; 152 | border-top: 1px solid @border-color; 153 | font-size: 90%; 154 | background: #ffffff; 155 | padding: 10px 15px; 156 | } 157 | -------------------------------------------------------------------------------- /src/css/less/app.variables.less: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | */ 4 | 5 | @brand-primary: #7266ba; 6 | @brand-info: #23b7e5; 7 | @brand-success: #27c24c; 8 | @brand-warning: #fad733; 9 | @brand-danger: #f05050; 10 | @brand-light: #edf1f2; 11 | @brand-dark: #3a3f51; 12 | @brand-black: #1c2b36; 13 | 14 | @body-bg: lighten(@brand-light, 1%); 15 | @text-color: #58666e; 16 | @text-muted: lighten(@text-color, 25%); 17 | 18 | @font-family-sans-serif: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; 19 | @font-family-serif: Georgia, "Times New Roman", Times, serif; 20 | @font-family-base: @font-family-sans-serif; 21 | 22 | @font-size-base: 14px; 23 | @font-size-lg: ceil(@font-size-base * 1.23); // ~20px 24 | @font-size-md: ceil(@font-size-base * 1.14); // ~16px 25 | @font-size-sm: ceil(@font-size-base * 0.92); // ~13px 26 | @font-size-xs: ceil(@font-size-base * 0.85); // ~12px 27 | 28 | @link-color: darken(@text-color, 15%); 29 | @link-hover-color: darken(@text-color, 30%); 30 | 31 | @border-radius-base: 2px; 32 | @border-color: darken(@brand-light, 5%); 33 | 34 | @line-height-base: 1.42857143; // 20/14 35 | @line-height-computed: floor(@font-size-base * @line-height-base); // ~20px 36 | @icon-css-prefix: i; 37 | 38 | // Buttons 39 | // ------------------------- 40 | 41 | @btn-default-color: @text-color; 42 | @btn-default-bg: lighten(@brand-light, 5%); 43 | @btn-default-border: @border-color; 44 | @btn-border-radius: @border-radius-base; 45 | 46 | @input-border: darken(@border-color, 5%); 47 | @input-border-focus: @brand-info; 48 | @input-border-radius: @border-radius-base; 49 | 50 | @panel-bg: #fff; 51 | @panel-border: @border-color; 52 | @panel-heading-border: lighten(@border-color, 5%); 53 | @panel-list-group-border: lighten(@border-color, 5%); 54 | @panel-border-radius: @border-radius-base; 55 | @panel-heading-bg: lighten(@brand-light, 3%); 56 | @panel-footer-bg: #fff; 57 | 58 | @nav-bg: lighten(@brand-light, 3%); 59 | @badge-bg: darken(@brand-light, 10%); 60 | 61 | @list-group-item-border: lighten(@border-color, 3%); 62 | @list-group-item-hover: lighten(@brand-light, 3%); 63 | @list-group-item-focus: darken(@brand-light, 3%); 64 | @list-group-select-color: #dbeef9; 65 | @list-group-active-color: @brand-info; 66 | 67 | @table-border-color: lighten(@border-color, 4%); 68 | @table-striped-color: lighten(@brand-light, 4.5%);; 69 | 70 | @arrow-width: 8px; 71 | @arrow-color: #fff; 72 | @arrow-outer-width: (@arrow-width + 1); 73 | @arrow-outer-color: rgba(0,0,0,.1); 74 | 75 | @switch-width: 35px; 76 | @switch-height: 20px; 77 | @switch-md-width: 40px; 78 | @switch-md-height: 24px; 79 | @switch-lg-width: 50px; 80 | @switch-lg-height: 30px; 81 | 82 | @app-aside-width: 200px; 83 | @app-aside-nav-height: 40px; 84 | @app-aside-folded-width: 60px; 85 | @app-aside-folded-nav-height: 50px; 86 | @app-aside-dock-media: 992px; 87 | 88 | @app-header-height: 50px; 89 | @app-header-md-height: 60px; 90 | 91 | @scroll-bar-width: 17px; 92 | @butterbar-height: 3px; 93 | @butterbar-time: 0.75s; 94 | 95 | @off-screen-width: 75%; 96 | 97 | @ibox-title-bg: lighten(@brand-light, 1%); 98 | @ibox-content-bg: lighten(@brand-light, 1%); 99 | -------------------------------------------------------------------------------- /src/css/less/app.widgets.less: -------------------------------------------------------------------------------- 1 | // icon list 2 | .list-icon i{font-size: 14px;width:40px;vertical-align:middle;margin:0;display: inline-block;text-align: center;.transition(font-size .2s);} 3 | .list-icon div{line-height: 40px;white-space: nowrap;} 4 | .list-icon div:hover i{font-size:26px;} 5 | 6 | // settings 7 | .settings{ 8 | z-index: 1050; 9 | position: fixed; 10 | top: 120px; 11 | right: -240px; 12 | width: 240px; 13 | .transition(right 0.2s); 14 | } 15 | .settings.active{ 16 | right: -1px; 17 | } 18 | 19 | .settings > .btn{ 20 | background: @panel-heading-bg !important; 21 | border-right-width: 0; 22 | border-color: @border-color !important; 23 | position: absolute; 24 | left: -42px; 25 | top: -1px; 26 | padding: 10px 15px; 27 | } 28 | 29 | .settings .i-checks span b{ 30 | width: 50%; 31 | height: 20px; 32 | display: inline-block; 33 | float: left; 34 | } 35 | .settings .i-checks span b.header{ 36 | height: 10px; 37 | } 38 | 39 | // streamline 40 | .streamline { 41 | position: relative; 42 | border-color: @border-color; 43 | .sl-item:after, 44 | &:after{ 45 | content: ''; 46 | position: absolute; 47 | background-color: #fff; 48 | border-color: inherit; 49 | border-width: 1px; 50 | border-style: solid; 51 | border-radius: 10px; 52 | width: 9px; 53 | height: 9px; 54 | margin-left: -5px; 55 | bottom: 0; 56 | left: 0; 57 | } 58 | } 59 | 60 | .sl-item{ 61 | border-color: @border-color; 62 | position: relative; 63 | padding-bottom: 1px; 64 | .clearfix(); 65 | &:after{ 66 | top: 6px; 67 | bottom: auto; 68 | } 69 | &.b-l{ 70 | margin-left: -1px; 71 | } 72 | } 73 | 74 | // timeline 75 | .timeline{ 76 | margin: 0; 77 | padding: 0; 78 | } 79 | .tl-item{ 80 | display: block; 81 | .clearfix(); 82 | } 83 | .visible-left{ 84 | display: none; 85 | } 86 | .tl-wrap{ 87 | display: block; 88 | margin-left: 6em; 89 | padding: 15px 0 15px 20px; 90 | border-style: solid; 91 | border-color: @border-color; 92 | border-width: 0 0 0 4px; 93 | .clearfix(); 94 | &:before{ 95 | position: relative; 96 | content: ""; 97 | float: left; 98 | top: 15px; 99 | margin-left: -27px; 100 | width: 10px; 101 | height: 10px; 102 | border-color: inherit; 103 | border-width: 3px; 104 | border-radius: 50%; 105 | border-style: solid; 106 | background: @brand-light; 107 | box-shadow: 0 0 0 4px @body-bg; 108 | } 109 | &:hover:before{ 110 | background: transparent; 111 | border-color: #fff; 112 | } 113 | } 114 | 115 | .tl-date{ 116 | position: relative; 117 | top: 10px; 118 | float: left; 119 | margin-left: -7.5em; 120 | display: block; 121 | width: 4.5em; 122 | text-align: right; 123 | } 124 | 125 | .tl-content{ 126 | display: inline-block; 127 | position: relative; 128 | padding-top: 10px; 129 | padding-bottom: 10px; 130 | &.block{ 131 | display: block; 132 | width: 100%; 133 | } 134 | &.panel{ 135 | margin-bottom: 0; 136 | } 137 | } 138 | 139 | .tl-header{ 140 | display: block; 141 | width: 12em; 142 | text-align: center; 143 | margin-left: 2px; 144 | } 145 | 146 | .timeline-center{ 147 | .tl-item{ 148 | margin-left: 50%; 149 | .tl-wrap{ 150 | margin-left: -2px; 151 | } 152 | } 153 | .tl-header{ 154 | width: auto; 155 | margin: 0; 156 | } 157 | .tl-left{ 158 | margin-left: 0; 159 | margin-right: 50%; 160 | .hidden-left{ 161 | display: none !important; 162 | } 163 | .visible-left{ 164 | display: inherit; 165 | } 166 | .tl-wrap{ 167 | float: right; 168 | margin-right: -2px; 169 | border-left-width: 0; 170 | border-right-width: 4px; 171 | padding-left: 0; 172 | padding-right: 20px; 173 | &:before{ 174 | float: right; 175 | margin-left: 0; 176 | margin-right: -27px; 177 | } 178 | } 179 | .tl-date{ 180 | float: right; 181 | margin-left: 0; 182 | margin-right: -8.5em; 183 | text-align: left; 184 | } 185 | } 186 | } -------------------------------------------------------------------------------- /src/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /src/fonts/Simple-Line-Icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/fonts/Simple-Line-Icons.eot -------------------------------------------------------------------------------- /src/fonts/Simple-Line-Icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/fonts/Simple-Line-Icons.ttf -------------------------------------------------------------------------------- /src/fonts/Simple-Line-Icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/fonts/Simple-Line-Icons.woff -------------------------------------------------------------------------------- /src/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /src/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /src/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /src/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /src/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /src/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /src/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /src/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /src/fonts/sourcesanspro/sourcesanspro-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/fonts/sourcesanspro/sourcesanspro-bold.woff -------------------------------------------------------------------------------- /src/fonts/sourcesanspro/sourcesanspro-light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/fonts/sourcesanspro/sourcesanspro-light.woff -------------------------------------------------------------------------------- /src/fonts/sourcesanspro/sourcesanspro.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/fonts/sourcesanspro/sourcesanspro.woff -------------------------------------------------------------------------------- /src/img/a0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/img/a0.jpg -------------------------------------------------------------------------------- /src/img/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/img/bg.jpg -------------------------------------------------------------------------------- /src/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/img/favicon.png -------------------------------------------------------------------------------- /src/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/springboot-dubbox-web/a72b62d70beaa6798f6bdc51c41842680f20e49b/src/img/loading.gif -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 后台管理平台 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/index.min.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 环球旅行管理平台 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 |
19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/js/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('app', [ 4 | 'ngAnimate', 5 | 'ngCookies', 6 | 'ngResource', 7 | 'ngSanitize', 8 | 'ngTouch', 9 | 'ngStorage', 10 | 'ui.router', 11 | 'ui.bootstrap', 12 | 'ui.utils', 13 | 'ui.load', 14 | 'ui.jq', 15 | 'oc.lazyLoad', 16 | 'dialogs.main' 17 | ]); -------------------------------------------------------------------------------- /src/js/config.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .config(appConfig) 6 | ; 7 | 8 | appConfig.$inject = ['$controllerProvider', '$compileProvider', '$filterProvider', '$provide']; 9 | function appConfig($controllerProvider, $compileProvider, $filterProvider, $provide) { 10 | 11 | var app = 12 | angular.module('app'); 13 | 14 | // lazy controller, directive and service 15 | app.controller = $controllerProvider.register; 16 | app.directive = $compileProvider.directive; 17 | app.filter = $filterProvider.register; 18 | app.factory = $provide.factory; 19 | app.service = $provide.service; 20 | app.constant = $provide.constant; 21 | app.value = $provide.value; 22 | } 23 | 24 | })(); -------------------------------------------------------------------------------- /src/js/config.lazyload.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | // lazyload config 4 | 5 | angular.module('app') 6 | 7 | .constant('JQ_CONFIG', { 8 | easyPieChart: ['vendor/jquery/charts/easypiechart/jquery.easy-pie-chart.js'], 9 | sparkline: ['vendor/jquery/charts/sparkline/jquery.sparkline.min.js'], 10 | plot: ['vendor/jquery/charts/flot/jquery.flot.min.js', 11 | 'vendor/jquery/charts/flot/jquery.flot.resize.js', 12 | 'vendor/jquery/charts/flot/jquery.flot.tooltip.min.js', 13 | 'vendor/jquery/charts/flot/jquery.flot.spline.js', 14 | 'vendor/jquery/charts/flot/jquery.flot.orderBars.js', 15 | 'vendor/jquery/charts/flot/jquery.flot.pie.min.js'] 16 | } 17 | ) 18 | // oclazyload config 19 | .config(lazyLoadConfig) 20 | ; 21 | 22 | lazyLoadConfig.$inject = ['$ocLazyLoadProvider']; 23 | function lazyLoadConfig($ocLazyLoadProvider) { 24 | // We configure ocLazyLoad to use the lib script.js as the async loader 25 | $ocLazyLoadProvider.config({ 26 | debug: false, 27 | events: true, 28 | modules: [ 29 | { 30 | name: 'ntt.TreeDnD', 31 | files: [ 32 | 'vendor/modules/angular-tree-dnd/ng-tree-dnd.min.js', 33 | 'vendor/modules/angular-tree-dnd/ng-tree-dnd.min.css' 34 | ] 35 | }, 36 | { 37 | name: 'ivh.treeview', 38 | files: [ 39 | 'vendor/modules/angular-ivh-treeview/ivh-treeview.min.js', 40 | 'vendor/modules/angular-ivh-treeview/ivh-treeview.min.css', 41 | 'vendor/modules/angular-ivh-treeview/ivh-treeview-theme-basic.css' 42 | ] 43 | }, 44 | { 45 | name: 'ui.select', 46 | files: [ 47 | 'vendor/modules/angular-ui-select/select.min.js', 48 | 'vendor/modules/angular-ui-select/select.min.css' 49 | ] 50 | }, 51 | { 52 | name: 'angularFileUpload', 53 | files: [ 54 | 'vendor/modules/angular-file-upload/angular-file-upload.min.js', 55 | 'vendor/modules/angular-file-upload/ngThumb.js' 56 | ] 57 | }, 58 | { 59 | name: 'toaster', 60 | files: [ 61 | 'vendor/modules/angularjs-toaster/toaster.js', 62 | 'vendor/modules/angularjs-toaster/toaster.css' 63 | ] 64 | } 65 | ] 66 | }); 67 | } 68 | })(); -------------------------------------------------------------------------------- /src/js/config.module.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .config(httpConfig) 6 | .config(dialogConfig) 7 | ; 8 | 9 | httpConfig.$inject = ['$httpProvider']; 10 | function httpConfig($httpProvider) { 11 | 12 | $httpProvider.interceptors.push(httpInterceptor); 13 | 14 | } 15 | 16 | httpInterceptor.$inject = ['$q', '$injector', '$localStorage', '$sessionStorage', 'APP_CONST']; 17 | function httpInterceptor($q, $injector, $localStorage, $sessionStorage, APP_CONST) { 18 | return { 19 | 'request': function (request) { 20 | 21 | var authToken = $sessionStorage[APP_CONST.STORAGE.AUTH_TOKEN] || $localStorage[APP_CONST.STORAGE.AUTH_TOKEN] || ''; 22 | if (authToken) { 23 | request.headers['Authorization'] = 'Bearer ' + authToken; 24 | } 25 | 26 | return request; 27 | }, 28 | 'response': function (response) { 29 | return response; 30 | }, 31 | 'responseError': function (rejection) { 32 | 33 | var state = $injector.get('$state'); 34 | var toaster = $injector.get('toaster'); 35 | switch (rejection.status) { 36 | case 400: { 37 | toaster.pop('error', '参数错误', rejection.data.message); 38 | break; 39 | } 40 | case 403: { 41 | toaster.pop('error', '访问未授权', rejection.data.message); 42 | break; 43 | } 44 | case 500: { 45 | toaster.pop('error', '服务端错误', rejection.data.message); 46 | break; 47 | } 48 | case 401: { 49 | state.go('access.login'); 50 | break; 51 | } 52 | case 404: { 53 | state.go('access.404'); 54 | break; 55 | } 56 | default : { 57 | 58 | break; 59 | } 60 | } 61 | 62 | return $q.reject(rejection); 63 | } 64 | }; 65 | } 66 | 67 | dialogConfig.$inject = ['$translateProvider']; 68 | function dialogConfig($translateProvider) { 69 | // This will set default modal buttons, header and message text 70 | $translateProvider.translations('en-US', { 71 | DIALOGS_ERROR: "错误", 72 | DIALOGS_ERROR_MSG: "未知错误。", 73 | DIALOGS_CLOSE: "关闭", 74 | DIALOGS_PLEASE_WAIT: "请等待", 75 | DIALOGS_PLEASE_WAIT_ELIPS: "请稍等...", 76 | DIALOGS_PLEASE_WAIT_MSG: "等待操作完成", 77 | DIALOGS_PERCENT_COMPLETE: "% 完成", 78 | DIALOGS_NOTIFICATION: "通知", 79 | DIALOGS_NOTIFICATION_MSG: "未知通知。", 80 | DIALOGS_CONFIRMATION: "确认", 81 | DIALOGS_CONFIRMATION_MSG: "操作需要确认", 82 | DIALOGS_OK: "OK", 83 | DIALOGS_YES: "是", 84 | DIALOGS_NO: "否" 85 | }); 86 | } 87 | 88 | })(); -------------------------------------------------------------------------------- /src/js/constants.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('app') 4 | .constant('APP_CONST', { 5 | PROPERTY: { 6 | API_URL: '' 7 | }, 8 | STORAGE: { 9 | USER: 'user', 10 | MENU: 'menu', 11 | AUTH_TOKEN: 'authToken' 12 | } 13 | }) 14 | .constant('DICT_CONST', { 15 | YES_NO: [{ 16 | key: true, 17 | value: '是' 18 | }, { 19 | key: false, 20 | value: '否' 21 | }], 22 | GENDER: [{ 23 | key: '0', 24 | value: '未知' 25 | }, { 26 | key: '1', 27 | value: '男' 28 | }, { 29 | key: '2', 30 | value: '女' 31 | }] 32 | }) 33 | ; -------------------------------------------------------------------------------- /src/js/custom/framework/dashboard-service.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .service('DashboardService', DashboardService); 6 | 7 | DashboardService.$inject = ['$http', '$q', 'APP_CONST']; 8 | function DashboardService($http, $q, APP_CONST) { 9 | 10 | this.get = function get() { 11 | var d = $q.defer(); 12 | 13 | $http.get(APP_CONST.PROPERTY.API_URL + '/dashboard') 14 | .success(function (data) { 15 | d.resolve(data); 16 | }) 17 | .error(function () { 18 | d.reject(); 19 | }); 20 | 21 | return d.promise; 22 | }; 23 | } 24 | })(); -------------------------------------------------------------------------------- /src/js/custom/framework/login.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .controller('LoginCtrl', LoginCtrl); 6 | 7 | LoginCtrl.$inject = ['$rootScope', '$scope', '$state', '$localStorage', '$sessionStorage', 'AuthService', 'SysUserService', 'SysMenuService', 'APP_CONST']; 8 | function LoginCtrl($rootScope, $scope, $state, $localStorage, $sessionStorage, authService, sysUserService, sysMenuService, APP_CONST) { 9 | $scope.user = {}; 10 | $scope.authError = null; 11 | $scope.usernameFocus = true; 12 | 13 | $scope.login = function () { 14 | $scope.authError = null; 15 | $rootScope.loading = true; 16 | 17 | authService.login($scope.user) 18 | .then(function (data) { 19 | if ($scope.rememberPwd) { 20 | $localStorage[APP_CONST.STORAGE.AUTH_TOKEN] = data.access_token; 21 | } 22 | $sessionStorage[APP_CONST.STORAGE.AUTH_TOKEN] = data.access_token; 23 | sysUserService.retrieve() 24 | .then(function (data) { 25 | $localStorage[APP_CONST.STORAGE.USER] = data; 26 | $rootScope.sysuser = data; 27 | $state.go('app.dashboard'); 28 | }); 29 | sysMenuService.nav() 30 | .then(function (data) { 31 | $localStorage[APP_CONST.STORAGE.MENU] = data; 32 | $rootScope.menu = data; 33 | }); 34 | }) 35 | .catch(function () { 36 | $scope.authError = '登录失败,请重试'; 37 | }) 38 | .finally(function () { 39 | $rootScope.loading = false; 40 | }); 41 | }; 42 | 43 | } 44 | })(); -------------------------------------------------------------------------------- /src/js/custom/framework/reset-password.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .controller('ResetPwdCtrl', ResetPwdCtrl); 6 | 7 | ResetPwdCtrl.$inject = ['$rootScope', '$scope', '$state', 'SysUserService']; 8 | function ResetPwdCtrl($rootScope, $scope, $state, sysUserService) { 9 | 10 | $scope.title = '重置密码'; 11 | $scope.user = {}; 12 | 13 | $scope.saveData = function () { 14 | $rootScope.loading = true; 15 | sysUserService.resetPwd($scope.user) 16 | .then(function () { 17 | $state.go('access.login'); 18 | }) 19 | .finally(function () { 20 | $rootScope.loading = false; 21 | }) 22 | ; 23 | } 24 | 25 | } 26 | })(); -------------------------------------------------------------------------------- /src/js/custom/sys/menu/menu-form.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .controller('SysMenuFormCtrl', SysMenuFormCtrl); 6 | 7 | SysMenuFormCtrl.$inject = ['$rootScope', '$scope', '$state', 'toaster', 'SysMenuService', 'DICT_CONST']; 8 | function SysMenuFormCtrl($rootScope, $scope, $state, toaster, sysMenuService, DICT_CONST) { 9 | 10 | var id = $state.params.id; 11 | var parentId = $state.params.parentId; 12 | 13 | $scope.yes_no = DICT_CONST.YES_NO; 14 | 15 | if (!!id) { //编辑 16 | $scope.title = '菜单详情'; 17 | $rootScope.loading = true; 18 | sysMenuService.getById(id) 19 | .then(function (data) { 20 | $scope.menu = data; 21 | }) 22 | .finally(function () { 23 | $rootScope.loading = false; 24 | }) 25 | ; 26 | } else if (!id && !parentId) { //新建 27 | $scope.title = '新建菜单'; 28 | $scope.menu = { 29 | id: '', 30 | parentId: '', 31 | icon: 'icon-star', 32 | sort: 0, 33 | show: true 34 | }; 35 | } else if (!id && !!parentId) { //添加子菜单 36 | $scope.title = '添加子菜单'; 37 | $scope.menu = { 38 | id: '', 39 | parentId: parentId, 40 | sort: 0, 41 | show: false 42 | }; 43 | } 44 | 45 | 46 | $scope.saveData = function () { 47 | $rootScope.loading = true; 48 | sysMenuService.saveData($scope.menu) 49 | .then(function (data) { 50 | $state.go('app.sys.menu.form', { 51 | id: data.id 52 | }); 53 | toaster.pop('success', '', '保存成功'); 54 | }) 55 | .finally(function () { 56 | $rootScope.loading = false; 57 | }) 58 | ; 59 | } 60 | 61 | } 62 | })(); -------------------------------------------------------------------------------- /src/js/custom/sys/menu/menu-list.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .controller('SysMenuListCtrl', SysMenuListCtrl); 6 | 7 | SysMenuListCtrl.$inject = ['$rootScope', '$scope', '$state', '$TreeDnDConvert', 'dialogs', 'SysMenuService']; 8 | function SysMenuListCtrl($rootScope, $scope, $state, $TreeDnDConvert, dialogs, sysMenuService) { 9 | 10 | $scope.title = '菜单管理'; 11 | 12 | var tree; 13 | $scope.tree_data = {}; 14 | $scope.my_tree = tree = {}; 15 | 16 | $scope.filter = {}; 17 | 18 | $scope.my_tree.update = function (node) { 19 | $state.go('app.sys.menu.form', { 20 | id: node.id, 21 | parentId: node.parentId 22 | }); 23 | }; 24 | 25 | $scope.my_tree.delete = function (node) { 26 | 27 | dialogs.confirm('确认', '要删除该菜单及所有子菜单项吗?', { 28 | size: 'md' 29 | }) 30 | .result.then(function () { 31 | sysMenuService.deleteById(node.id) 32 | .then(function () { 33 | $state.reload(); 34 | }) 35 | ; 36 | }); 37 | }; 38 | 39 | $scope.my_tree.addChild = function (node) { 40 | $state.go('app.sys.menu.form', { 41 | parentId: node.id, 42 | level: node.__level__ 43 | }); 44 | }; 45 | 46 | $scope.expanding_property = { 47 | field: 'name', 48 | displayName: '名称' 49 | }; 50 | $scope.col_defs = [ 51 | { 52 | field: 'href', 53 | displayName: '链接' 54 | }, { 55 | field: 'sort', 56 | displayName: '排序', 57 | titleClass: 'text-center', 58 | cellClass: 'text-center' 59 | }, { 60 | field: 'show', 61 | titleClass: 'text-center', 62 | cellClass: 'text-center', 63 | displayName: '可见', 64 | cellTemplate: '{{node.show | dict: "YES_NO" }}' 65 | }, { 66 | field: 'permission', 67 | displayName: '权限标识' 68 | }, { 69 | displayName: '操作', 70 | cellTemplate: '' 71 | + '' 72 | + '' 73 | }]; 74 | 75 | $rootScope.loading = true; 76 | sysMenuService.list() 77 | .then(function (data) { 78 | $scope.tree_data = $TreeDnDConvert.line2tree(data, 'id', 'parentId'); 79 | }) 80 | .finally(function () { 81 | $rootScope.loading = false; 82 | }) 83 | ; 84 | 85 | } 86 | })(); -------------------------------------------------------------------------------- /src/js/custom/sys/menu/menu-service.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .service('SysMenuService', SysMenuService); 6 | 7 | SysMenuService.$inject = ['$http', '$q', 'APP_CONST']; 8 | function SysMenuService($http, $q, APP_CONST) { 9 | 10 | this.nav = function tree() { 11 | var d = $q.defer(); 12 | 13 | $http.get(APP_CONST.PROPERTY.API_URL + '/sys/menu/nav') 14 | .success(function (data) { 15 | d.resolve(data); 16 | }) 17 | .error(function () { 18 | d.reject(); 19 | }); 20 | 21 | return d.promise; 22 | }; 23 | 24 | this.tree = function tree() { 25 | var d = $q.defer(); 26 | 27 | $http.get(APP_CONST.PROPERTY.API_URL + '/sys/menu/tree') 28 | .success(function (data) { 29 | d.resolve(data); 30 | }) 31 | .error(function () { 32 | d.reject(); 33 | }); 34 | 35 | return d.promise; 36 | }; 37 | 38 | this.list = function list() { 39 | var d = $q.defer(); 40 | 41 | $http.get(APP_CONST.PROPERTY.API_URL + '/sys/menu/list') 42 | .success(function (data) { 43 | d.resolve(data); 44 | }) 45 | .error(function () { 46 | d.reject(); 47 | }); 48 | 49 | return d.promise; 50 | }; 51 | 52 | this.deleteById = function deleteById(id) { 53 | var d = $q.defer(); 54 | 55 | $http.delete(APP_CONST.PROPERTY.API_URL + '/sys/menu/' + id) 56 | .success(function (data) { 57 | d.resolve(data); 58 | }) 59 | .error(function () { 60 | d.reject(); 61 | }); 62 | 63 | return d.promise; 64 | }; 65 | 66 | this.getById = function getById(id) { 67 | var d = $q.defer(); 68 | 69 | $http.get(APP_CONST.PROPERTY.API_URL + '/sys/menu/' + id) 70 | .success(function (data) { 71 | d.resolve(data); 72 | }) 73 | .error(function () { 74 | d.reject(); 75 | }); 76 | 77 | return d.promise; 78 | }; 79 | 80 | this.saveData = function saveData(data) { 81 | var d = $q.defer(); 82 | 83 | $http.post(APP_CONST.PROPERTY.API_URL + '/sys/menu', data) 84 | .success(function (data) { 85 | d.resolve(data); 86 | }) 87 | .error(function () { 88 | d.reject(); 89 | }); 90 | 91 | return d.promise; 92 | } 93 | 94 | } 95 | })(); -------------------------------------------------------------------------------- /src/js/custom/sys/role/role-form.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .controller('SysRoleFormCtrl', SysRoleFormCtrl); 6 | 7 | SysRoleFormCtrl.$inject = ['$rootScope', '$scope', '$state', '$filter', 'toaster', 'SysRoleService', 'SysMenuService', 'DICT_CONST']; 8 | function SysRoleFormCtrl($rootScope, $scope, $state, $filter, toaster, sysRoleService, sysMenuService, DICT_CONST) { 9 | 10 | var id = $state.params.id; 11 | 12 | $scope.treeOpts = { 13 | labelAttribute: 'name', 14 | expandToDepth: 2, 15 | twistieCollapsedTpl: '', 16 | twistieExpandedTpl: '', 17 | twistieLeafTpl: '' 18 | }; 19 | 20 | $scope.yes_no = DICT_CONST.YES_NO; 21 | 22 | if (!!id) { //编辑 23 | $scope.title = '角色详情'; 24 | } else { //新建 25 | $scope.title = '新建角色'; 26 | $scope.role = { 27 | enabled: true 28 | }; 29 | } 30 | 31 | $rootScope.loading = true; 32 | sysMenuService.tree() 33 | .then(function (data) { 34 | var sortOrder = function (nodes) { 35 | nodes = $filter('orderBy')(nodes, ['sort'], false); 36 | angular.forEach(nodes, function (node) { 37 | if (node.children && node.children.length > 0) { 38 | node.children = sortOrder(node.children); 39 | } 40 | }); 41 | return nodes; 42 | }; 43 | 44 | $scope.menus = sortOrder(data); 45 | 46 | if (!!id) { 47 | sysRoleService.getById(id) 48 | .then(function (data) { 49 | $scope.role = data; 50 | 51 | var roleMenus = []; 52 | angular.forEach(data.menus, function (roleMenu) { 53 | roleMenus.push(roleMenu.id); 54 | }); 55 | 56 | $scope.selectNode($scope.menus, roleMenus); 57 | }); 58 | } 59 | }) 60 | .finally(function () { 61 | $rootScope.loading = false; 62 | }) 63 | ; 64 | 65 | $scope.selectNode = function (menus, data) { 66 | angular.forEach(menus, function (menu) { 67 | menu.selected = $.inArray(menu.id, data) >= 0; 68 | if (menu.children && menu.children.length > 0) { 69 | $scope.selectNode(menu.children, data); 70 | } 71 | }); 72 | }; 73 | 74 | 75 | $scope.saveData = function () { 76 | $rootScope.loading = true; 77 | 78 | var selected = []; 79 | $scope.getSelected(selected, $scope.menus); 80 | 81 | $scope.role.menus = selected; 82 | 83 | sysRoleService.saveData($scope.role) 84 | .then(function (data) { 85 | $state.go('app.sys.role.form', { 86 | id: data.id 87 | }); 88 | toaster.pop('success', '', '保存成功'); 89 | }) 90 | .finally(function () { 91 | $rootScope.loading = false; 92 | }) 93 | ; 94 | }; 95 | 96 | $scope.getSelected = function (selected, menus) { 97 | angular.forEach(menus, function (menu) { 98 | if (menu.selected) selected.push({id: menu.id}); 99 | if (menu.children && menu.children.length > 0) { 100 | $scope.getSelected(selected, menu.children); 101 | } 102 | }); 103 | }; 104 | } 105 | })(); -------------------------------------------------------------------------------- /src/js/custom/sys/role/role-list.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .controller('SysRoleListCtrl', SysRoleListCtrl); 6 | 7 | SysRoleListCtrl.$inject = ['$rootScope', '$scope', '$state', 'dialogs', 'SysRoleService']; 8 | function SysRoleListCtrl($rootScope, $scope, $state, dialogs, sysRoleService) { 9 | 10 | $scope.title = '角色管理'; 11 | $scope.params = { 12 | pageNum: 1, 13 | pageSize: 20, 14 | orderBy: '' 15 | }; 16 | 17 | $scope.search = function () { 18 | $rootScope.loading = true; 19 | sysRoleService.list($scope.params) 20 | .then(function (data) { 21 | $scope.pageInfo = data; 22 | }) 23 | .finally(function () { 24 | $rootScope.loading = false; 25 | }) 26 | ; 27 | }; 28 | 29 | $scope.search(); 30 | 31 | $scope.pageChanged = function () { 32 | $scope.params.pageNum = $scope.pageInfo.pageNum; 33 | $scope.search(); 34 | }; 35 | 36 | $scope.delete = function (id) { 37 | 38 | dialogs.confirm('确认', '要删除该角色吗?', { 39 | size: 'md' 40 | }) 41 | .result.then(function () { 42 | sysRoleService.deleteById(id) 43 | .then(function () { 44 | $state.reload(); 45 | }) 46 | ; 47 | }); 48 | }; 49 | 50 | } 51 | })(); -------------------------------------------------------------------------------- /src/js/custom/sys/role/role-service.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .service('SysRoleService', SysRoleService); 6 | 7 | SysRoleService.$inject = ['$http', '$q', 'APP_CONST']; 8 | function SysRoleService($http, $q, APP_CONST) { 9 | 10 | this.list = function list(params) { 11 | var d = $q.defer(); 12 | 13 | $http.get(APP_CONST.PROPERTY.API_URL + '/sys/role/list', { 14 | params: params 15 | }) 16 | .success(function (data) { 17 | d.resolve(data); 18 | }) 19 | .error(function () { 20 | d.reject(); 21 | }); 22 | 23 | return d.promise; 24 | }; 25 | 26 | this.listAll = function list() { 27 | var d = $q.defer(); 28 | 29 | $http.get(APP_CONST.PROPERTY.API_URL + '/sys/role/all') 30 | .success(function (data) { 31 | d.resolve(data); 32 | }) 33 | .error(function () { 34 | d.reject(); 35 | }); 36 | 37 | return d.promise; 38 | }; 39 | 40 | this.deleteById = function deleteById(id) { 41 | var d = $q.defer(); 42 | 43 | $http.delete(APP_CONST.PROPERTY.API_URL + '/sys/role/' + id) 44 | .success(function (data) { 45 | d.resolve(data); 46 | }) 47 | .error(function () { 48 | d.reject(); 49 | }); 50 | 51 | return d.promise; 52 | }; 53 | 54 | this.getById = function getById(id) { 55 | var d = $q.defer(); 56 | 57 | $http.get(APP_CONST.PROPERTY.API_URL + '/sys/role/' + id) 58 | .success(function (data) { 59 | d.resolve(data); 60 | }) 61 | .error(function () { 62 | d.reject(); 63 | }); 64 | 65 | return d.promise; 66 | }; 67 | 68 | this.saveData = function saveData(data) { 69 | var d = $q.defer(); 70 | 71 | $http.post(APP_CONST.PROPERTY.API_URL + '/sys/role', data) 72 | .success(function (data) { 73 | d.resolve(data); 74 | }) 75 | .error(function () { 76 | d.reject(); 77 | }); 78 | 79 | return d.promise; 80 | }; 81 | 82 | } 83 | })(); -------------------------------------------------------------------------------- /src/js/custom/sys/user/user-form.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .controller('SysUserFormCtrl', SysUserFormCtrl); 6 | 7 | SysUserFormCtrl.$inject = ['$rootScope', '$scope', '$state', '$filter', 'toaster', 'SysUserService', 'SysRoleService', 'DICT_CONST']; 8 | function SysUserFormCtrl($rootScope, $scope, $state, $filter, toaster, sysUserService, sysRoleService, DICT_CONST) { 9 | 10 | var id = $state.params.id; 11 | 12 | $scope.yes_no = DICT_CONST.YES_NO; 13 | 14 | $rootScope.loading = true; 15 | if (!!id) { //编辑 16 | $scope.title = '用户详情'; 17 | } else { //新建 18 | $scope.title = '新建用户'; 19 | $scope.user = { 20 | enabled: true 21 | }; 22 | } 23 | 24 | sysRoleService.listAll() 25 | .then(function (data) { 26 | $scope.roles = data; 27 | if (!!id) { 28 | sysUserService.getById(id) 29 | .then(function (data) { 30 | $scope.user = data; 31 | var userRoles = []; 32 | angular.forEach(data.roles, function (userRole) { 33 | userRoles.push(userRole.id); 34 | }); 35 | angular.forEach($scope.roles, function (role) { 36 | role.checked = $.inArray(role.id, userRoles) >= 0; 37 | }); 38 | $scope.selectedRoles(); 39 | }) 40 | ; 41 | } 42 | }) 43 | .finally(function () { 44 | $rootScope.loading = false; 45 | }); 46 | 47 | $scope.selectedRoles = function () { 48 | $scope.selected = $filter('filter')($scope.roles, {checked: true}); 49 | }; 50 | 51 | $scope.saveData = function () { 52 | $rootScope.loading = true; 53 | 54 | var selected = []; 55 | angular.forEach($scope.selected, function (role) { 56 | selected.push({id: role.id}); 57 | }); 58 | $scope.user.roles = selected; 59 | 60 | sysUserService.saveData($scope.user) 61 | .then(function (data) { 62 | $state.go('app.sys.user.form', { 63 | id: data.id 64 | }); 65 | toaster.pop('success', '', '保存成功'); 66 | }) 67 | .finally(function () { 68 | $rootScope.loading = false; 69 | }) 70 | ; 71 | } 72 | 73 | } 74 | })(); -------------------------------------------------------------------------------- /src/js/custom/sys/user/user-info.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .controller('SysUserInfoCtrl', SysUserInfoCtrl); 6 | 7 | SysUserInfoCtrl.$inject = ['$rootScope', '$scope', 'toaster', 'SysUserService']; 8 | function SysUserInfoCtrl($rootScope, $scope, toaster, sysUserService) { 9 | 10 | $scope.title = '个人信息'; 11 | var id = $rootScope.sysuser.id; 12 | 13 | $rootScope.loading = true; 14 | sysUserService.getById(id) 15 | .then(function (data) { 16 | $scope.user = data; 17 | }) 18 | .finally(function () { 19 | $rootScope.loading = false; 20 | }) 21 | ; 22 | 23 | $scope.saveData = function () { 24 | $rootScope.loading = true; 25 | sysUserService.saveInfo($scope.user) 26 | .then(function () { 27 | toaster.pop('success', '', '保存成功'); 28 | }) 29 | .finally(function () { 30 | $rootScope.loading = false; 31 | }) 32 | ; 33 | } 34 | 35 | } 36 | })(); -------------------------------------------------------------------------------- /src/js/custom/sys/user/user-list.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .controller('SysUserListCtrl', SysUserListCtrl); 6 | 7 | SysUserListCtrl.$inject = ['$rootScope', '$scope', '$state', 'dialogs', 'SysUserService']; 8 | function SysUserListCtrl($rootScope, $scope, $state, dialogs, sysUserService) { 9 | 10 | $scope.title = '用户管理'; 11 | $scope.params = { 12 | pageNum: 1, 13 | pageSize: 20, 14 | orderBy: '' 15 | }; 16 | 17 | $scope.search = function () { 18 | $rootScope.loading = true; 19 | sysUserService.list($scope.params) 20 | .then(function (data) { 21 | $scope.pageInfo = data; 22 | }) 23 | .finally(function () { 24 | $rootScope.loading = false; 25 | }) 26 | ; 27 | }; 28 | 29 | $scope.search(); 30 | 31 | $scope.pageChanged = function () { 32 | $scope.params.pageNum = $scope.pageInfo.pageNum; 33 | $scope.search(); 34 | }; 35 | 36 | $scope.delete = function (id) { 37 | 38 | dialogs.confirm('确认', '要删除该用户吗?', { 39 | size: 'md' 40 | }) 41 | .result.then(function () { 42 | sysUserService.deleteById(id) 43 | .then(function () { 44 | $state.reload(); 45 | }) 46 | ; 47 | }); 48 | }; 49 | 50 | } 51 | })(); -------------------------------------------------------------------------------- /src/js/custom/sys/user/user-service.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .service('SysUserService', SysUserService); 6 | 7 | SysUserService.$inject = ['$http', '$q', 'APP_CONST']; 8 | function SysUserService($http, $q, APP_CONST) { 9 | 10 | this.retrieve = function retrieve() { 11 | var d = $q.defer(); 12 | 13 | $http.get(APP_CONST.PROPERTY.API_URL + '/sys/user/info') 14 | .success(function (data) { 15 | d.resolve(data); 16 | }) 17 | .error(function () { 18 | d.reject(); 19 | }); 20 | 21 | return d.promise; 22 | }; 23 | 24 | this.list = function list(params) { 25 | var d = $q.defer(); 26 | 27 | $http.get(APP_CONST.PROPERTY.API_URL + '/sys/user/list', { 28 | params: params 29 | }) 30 | .success(function (data) { 31 | d.resolve(data); 32 | }) 33 | .error(function () { 34 | d.reject(); 35 | }); 36 | 37 | return d.promise; 38 | }; 39 | 40 | this.deleteById = function deleteById(id) { 41 | var d = $q.defer(); 42 | 43 | $http.delete(APP_CONST.PROPERTY.API_URL + '/sys/user/' + id) 44 | .success(function (data) { 45 | d.resolve(data); 46 | }) 47 | .error(function () { 48 | d.reject(); 49 | }); 50 | 51 | return d.promise; 52 | }; 53 | 54 | this.getById = function getById(id) { 55 | var d = $q.defer(); 56 | 57 | $http.get(APP_CONST.PROPERTY.API_URL + '/sys/user/' + id) 58 | .success(function (data) { 59 | d.resolve(data); 60 | }) 61 | .error(function () { 62 | d.reject(); 63 | }); 64 | 65 | return d.promise; 66 | }; 67 | 68 | this.saveData = function saveData(data) { 69 | var d = $q.defer(); 70 | 71 | $http.post(APP_CONST.PROPERTY.API_URL + '/sys/user', data) 72 | .success(function (data) { 73 | d.resolve(data); 74 | }) 75 | .error(function () { 76 | d.reject(); 77 | }); 78 | 79 | return d.promise; 80 | }; 81 | 82 | this.saveInfo = function saveData(data) { 83 | var d = $q.defer(); 84 | 85 | $http.post(APP_CONST.PROPERTY.API_URL + '/sys/user/info', data) 86 | .success(function (data) { 87 | d.resolve(data); 88 | }) 89 | .error(function () { 90 | d.reject(); 91 | }); 92 | 93 | return d.promise; 94 | }; 95 | 96 | this.resetPwd = function saveData(data) { 97 | var d = $q.defer(); 98 | 99 | $http.put(APP_CONST.PROPERTY.API_URL + '/sys/user/password', data) 100 | .success(function (data) { 101 | d.resolve(data); 102 | }) 103 | .error(function () { 104 | d.reject(); 105 | }); 106 | 107 | return d.promise; 108 | }; 109 | 110 | } 111 | })(); -------------------------------------------------------------------------------- /src/js/custom/trip/user/user-form.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .controller('TripUserFormCtrl', TripUserFormCtrl); 6 | 7 | TripUserFormCtrl.$inject = ['$rootScope', '$scope', '$state', 'TripUserService']; 8 | function TripUserFormCtrl($rootScope, $scope, $state, tripUserService) { 9 | 10 | var id = $state.params.id; 11 | 12 | $scope.title = '用户详情'; 13 | $rootScope.loading = true; 14 | tripUserService.getById(id) 15 | .then(function (data) { 16 | $scope.data = data; 17 | }) 18 | .finally(function () { 19 | $rootScope.loading = false; 20 | }) 21 | ; 22 | 23 | } 24 | })(); -------------------------------------------------------------------------------- /src/js/custom/trip/user/user-list.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .controller('TripUserListCtrl', TripUserListCtrl); 6 | 7 | TripUserListCtrl.$inject = ['$rootScope', '$scope', 'TripUserService', 'DICT_CONST']; 8 | function TripUserListCtrl($rootScope, $scope, tripUserService, DICT_CONST) { 9 | 10 | $scope.title = '用户信息'; 11 | $scope.gender = DICT_CONST.GENDER; 12 | $scope.yes_no = DICT_CONST.YES_NO; 13 | $scope.params = { 14 | pageNum: 1, 15 | pageSize: 20, 16 | orderBy: '' 17 | }; 18 | 19 | $scope.search = function () { 20 | $rootScope.loading = true; 21 | tripUserService.list($scope.params) 22 | .then(function (data) { 23 | $scope.pageInfo = data; 24 | }) 25 | .finally(function () { 26 | $rootScope.loading = false; 27 | }) 28 | ; 29 | }; 30 | 31 | $scope.search(); 32 | 33 | $scope.pageChanged = function () { 34 | $scope.params.pageNum = $scope.pageInfo.pageNum; 35 | $scope.search(); 36 | }; 37 | } 38 | })(); -------------------------------------------------------------------------------- /src/js/custom/trip/user/user-service.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .service('TripUserService', TripUserService); 6 | 7 | TripUserService.$inject = ['$http', '$q', 'APP_CONST']; 8 | function TripUserService($http, $q, APP_CONST) { 9 | 10 | this.list = function list(params) { 11 | var d = $q.defer(); 12 | 13 | $http.get(APP_CONST.PROPERTY.API_URL + '/trip/user/list', { 14 | params: params 15 | }) 16 | .success(function (data) { 17 | d.resolve(data); 18 | }) 19 | .error(function () { 20 | d.reject(); 21 | }); 22 | 23 | return d.promise; 24 | }; 25 | 26 | this.getById = function getById(id) { 27 | var d = $q.defer(); 28 | 29 | $http.get(APP_CONST.PROPERTY.API_URL + '/trip/user/' + id) 30 | .success(function (data) { 31 | d.resolve(data); 32 | }) 33 | .error(function () { 34 | d.reject(); 35 | }); 36 | 37 | return d.promise; 38 | }; 39 | 40 | } 41 | })(); -------------------------------------------------------------------------------- /src/js/directives/setnganimate.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .directive('setNgAnimate', setNgAnimate); 6 | 7 | setNgAnimate.$inject = ['$animate']; 8 | function setNgAnimate($animate) { 9 | return { 10 | link: function ($scope, $element, $attrs) { 11 | $scope.$watch(function () { 12 | return $scope.$eval($attrs.setNgAnimate, $scope); 13 | }, function (valnew) { 14 | $animate.enabled(!!valnew, $element); 15 | }); 16 | } 17 | }; 18 | } 19 | })(); -------------------------------------------------------------------------------- /src/js/directives/ui-butterbar.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .directive('uiButterbar', uiButterbar); 6 | 7 | uiButterbar.$inject = ['$anchorScroll']; 8 | function uiButterbar($anchorScroll) { 9 | return { 10 | restrict: 'AC', 11 | template: '', 12 | link: function (scope, el) { 13 | el.addClass('butterbar hide'); 14 | scope.$on('$stateChangeStart', function () { 15 | $anchorScroll(); 16 | el.removeClass('hide').addClass('active'); 17 | }); 18 | scope.$on('$stateChangeSuccess', function (event) { 19 | event.targetScope.$watch('$viewContentLoaded', function () { 20 | el.addClass('hide').removeClass('active'); 21 | }) 22 | }); 23 | } 24 | }; 25 | } 26 | 27 | })(); -------------------------------------------------------------------------------- /src/js/directives/ui-focus.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .directive('uiFocus', uiFocus); 6 | 7 | uiFocus.$inject = ['$timeout', '$parse']; 8 | function uiFocus($timeout, $parse) { 9 | return { 10 | link: function (scope, element, attr) { 11 | var model = $parse(attr.uiFocus); 12 | scope.$watch(model, function (value) { 13 | if (value === true) { 14 | $timeout(function () { 15 | element[0].focus(); 16 | }); 17 | } 18 | }); 19 | element.bind('blur', function () { 20 | scope.$apply(model.assign(scope, false)); 21 | }); 22 | } 23 | }; 24 | } 25 | })(); -------------------------------------------------------------------------------- /src/js/directives/ui-fullscreen.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .directive('uiFullscreen', uiFullscreen); 6 | 7 | uiFullscreen.$inject = ['uiLoad', '$document']; 8 | function uiFullscreen(uiLoad, $document) { 9 | return { 10 | restrict: 'AC', 11 | template: '', 12 | link: function (scope, el, attr) { 13 | el.addClass('hide'); 14 | uiLoad.load('vendor/libs/screenfull.min.js').then(function () { 15 | // disable on ie11 16 | if (screenfull.enabled && !navigator.userAgent.match(/Trident.*rv:11\./)) { 17 | el.removeClass('hide'); 18 | } 19 | el.on('click', function () { 20 | var target; 21 | attr.target && ( target = $(attr.target)[0] ); 22 | screenfull.toggle(target); 23 | }); 24 | $document.on(screenfull.raw.fullscreenchange, function () { 25 | if (screenfull.isFullscreen) { 26 | el.addClass('active'); 27 | } else { 28 | el.removeClass('active'); 29 | } 30 | }); 31 | }); 32 | } 33 | }; 34 | } 35 | })(); -------------------------------------------------------------------------------- /src/js/directives/ui-jq.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('ui.jq', ['ui.load']).value('uiJqConfig', {}) 5 | .directive('uiJq', uiJqInjectingFunction); 6 | 7 | uiJqInjectingFunction.$inject = ['uiJqConfig', 'JQ_CONFIG', 'uiLoad', '$timeout']; 8 | function uiJqInjectingFunction(uiJqConfig, JQ_CONFIG, uiLoad, $timeout) { 9 | 10 | return { 11 | restrict: 'A', 12 | compile: function uiJqCompilingFunction(tElm, tAttrs) { 13 | 14 | if (!angular.isFunction(tElm[tAttrs.uiJq]) && !JQ_CONFIG[tAttrs.uiJq]) { 15 | throw new Error('ui-jq: The "' + tAttrs.uiJq + '" function does not exist'); 16 | } 17 | var options = uiJqConfig && uiJqConfig[tAttrs.uiJq]; 18 | 19 | return function uiJqLinkingFunction(scope, elm, attrs) { 20 | 21 | function getOptions() { 22 | var linkOptions = []; 23 | 24 | // If ui-options are passed, merge (or override) them onto global defaults and pass to the jQuery method 25 | if (attrs.uiOptions) { 26 | linkOptions = scope.$eval('[' + attrs.uiOptions + ']'); 27 | if (angular.isObject(options) && angular.isObject(linkOptions[0])) { 28 | linkOptions[0] = angular.extend({}, options, linkOptions[0]); 29 | } 30 | } else if (options) { 31 | linkOptions = [options]; 32 | } 33 | return linkOptions; 34 | } 35 | 36 | // If change compatibility is enabled, the form input's "change" event will trigger an "input" event 37 | if (attrs.ngModel && elm.is('select,input,textarea')) { 38 | elm.bind('change', function () { 39 | elm.trigger('input'); 40 | }); 41 | } 42 | 43 | // Call jQuery method and pass relevant options 44 | function callPlugin() { 45 | $timeout(function () { 46 | elm[attrs.uiJq].apply(elm, getOptions()); 47 | }, 0, false); 48 | } 49 | 50 | function refresh() { 51 | // If ui-refresh is used, re-fire the the method upon every change 52 | if (attrs.uiRefresh) { 53 | scope.$watch(attrs.uiRefresh, function () { 54 | callPlugin(); 55 | }); 56 | } 57 | } 58 | 59 | if (JQ_CONFIG[attrs.uiJq]) { 60 | uiLoad.load(JQ_CONFIG[attrs.uiJq]).then(function () { 61 | callPlugin(); 62 | refresh(); 63 | }).catch(function () { 64 | 65 | }); 66 | } else { 67 | callPlugin(); 68 | refresh(); 69 | } 70 | }; 71 | } 72 | }; 73 | } 74 | })(); -------------------------------------------------------------------------------- /src/js/directives/ui-module.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .directive('uiModule', uiModule); 6 | 7 | uiModule.$inject = ['MODULE_CONFIG', 'uiLoad', '$compile']; 8 | function uiModule(MODULE_CONFIG, uiLoad, $compile) { 9 | return { 10 | restrict: 'A', 11 | compile: function (el) { 12 | var contents = el.contents().clone(); 13 | return function (scope, el, attrs) { 14 | el.contents().remove(); 15 | uiLoad.load(MODULE_CONFIG[attrs.uiModule]) 16 | .then(function () { 17 | $compile(contents)(scope, function (clonedElement) { 18 | el.append(clonedElement); 19 | }); 20 | }); 21 | } 22 | } 23 | }; 24 | } 25 | })(); -------------------------------------------------------------------------------- /src/js/directives/ui-nav.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular.module('app') 5 | .directive('uiNav', uiNav); 6 | 7 | function uiNav() { 8 | return { 9 | restrict: 'AC', 10 | link: function (scope, el) { 11 | var _window = $(window), 12 | _mb = 768, 13 | wrap = $('.app-aside'), 14 | next, 15 | backdrop = '.dropdown-backdrop'; 16 | // unfolded 17 | el.on('click', 'a', function (e) { 18 | next && next.trigger('mouseleave.nav'); 19 | var _this = $(this); 20 | _this.parent().siblings(".active").toggleClass('active'); 21 | _this.next().is('ul') && _this.parent().toggleClass('active') && e.preventDefault(); 22 | // mobile 23 | _this.next().is('ul') || ( ( _window.width() < _mb ) && $('.app-aside').removeClass('show off-screen') ); 24 | }); 25 | 26 | // folded & fixed 27 | el.on('mouseenter', 'a', function (e) { 28 | next && next.trigger('mouseleave.nav'); 29 | $('> .nav', wrap).remove(); 30 | if (!$('.app-aside-fixed.app-aside-folded').length || ( _window.width() < _mb ) || $('.app-aside-dock').length) return; 31 | var _this = $(e.target) 32 | , top 33 | , w_h = $(window).height() 34 | , offset = 50 35 | , min = 150; 36 | 37 | !_this.is('a') && (_this = _this.closest('a')); 38 | if (_this.next().is('ul')) { 39 | next = _this.next(); 40 | } else { 41 | return; 42 | } 43 | 44 | _this.parent().addClass('active'); 45 | top = _this.parent().position().top + offset; 46 | next.css('top', top); 47 | if (top + next.height() > w_h) { 48 | next.css('bottom', 0); 49 | } 50 | if (top + min > w_h) { 51 | next.css('bottom', w_h - top - offset).css('top', 'auto'); 52 | } 53 | next.appendTo(wrap); 54 | 55 | next.on('mouseleave.nav', function (e) { 56 | $(backdrop).remove(); 57 | next.appendTo(_this.parent()); 58 | next.off('mouseleave.nav').css('top', 'auto').css('bottom', 'auto'); 59 | _this.parent().removeClass('active'); 60 | }); 61 | 62 | $('.smart').length && $(' -------------------------------------------------------------------------------- /src/tpl/custom/trip/user/user-list.html: -------------------------------------------------------------------------------- 1 | 2 | 11 |
12 |
13 |
14 |
15 |
16 |
17 | 21 |
22 |
23 |
24 | 32 | 33 | 37 | 38 |
39 |
40 |
41 |
42 | 50 | 51 | 55 | 56 |
57 |
58 |
59 | 60 |
61 | 62 |
63 |
64 |
65 | 66 |
67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 91 | 92 | 93 |
手机号昵称性别年龄注册时间可用操作
{{item.mobile}}{{item.nickname}}{{item.gender | dict : 'GENDER'}}{{item.age}}{{item.createDate | date : 'yyyy-MM-dd H:mm:ss'}}{{item.enabled | dict : 'YES_NO'}} 88 | 90 |
94 |
95 | 96 | 97 | 98 |
99 |
-------------------------------------------------------------------------------- /src/vendor/angular/angular-cookies/angular-cookies.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.3.20 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(p,g,n){'use strict';g.module("ngCookies",["ng"]).factory("$cookies",["$rootScope","$browser",function(e,b){var c={},f={},h,k=!1,l=g.copy,m=g.isUndefined;b.addPollFn(function(){var a=b.cookies();h!=a&&(h=a,l(a,f),l(a,c),k&&e.$apply())})();k=!0;e.$watch(function(){var a,d,e;for(a in f)m(c[a])&&(b.cookies(a,n),delete f[a]);for(a in c)d=c[a],g.isString(d)||(d=""+d,c[a]=d),d!==f[a]&&(b.cookies(a,d),f[a]=d,e=!0);if(e)for(a in d=b.cookies(),c)c[a]!==d[a]&&(m(d[a])?(delete c[a],delete f[a]):c[a]= 7 | f[a]=d[a])});return c}]).factory("$cookieStore",["$cookies",function(e){return{get:function(b){return(b=e[b])?g.fromJson(b):b},put:function(b,c){e[b]=g.toJson(c)},remove:function(b){delete e[b]}}}])})(window,window.angular); 8 | //# sourceMappingURL=angular-cookies.min.js.map 9 | -------------------------------------------------------------------------------- /src/vendor/angular/angular-cookies/angular-cookies.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"angular-cookies.min.js", 4 | "lineCount":7, 5 | "mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAA6B,CAmBtCD,CAAAE,OAAA,CAAe,WAAf,CAA4B,CAAC,IAAD,CAA5B,CAAAC,QAAA,CA0BW,UA1BX,CA0BuB,CAAC,YAAD,CAAe,UAAf,CAA2B,QAAQ,CAACC,CAAD,CAAaC,CAAb,CAAuB,CAAA,IACvEC,EAAU,EAD6D,CAEvEC,EAAc,EAFyD,CAGvEC,CAHuE,CAIvEC,EAAU,CAAA,CAJ6D,CAKvEC,EAAOV,CAAAU,KALgE,CAMvEC,EAAcX,CAAAW,YAGlBN,EAAAO,UAAA,CAAmB,QAAQ,EAAG,CAC5B,IAAIC,EAAiBR,CAAAC,QAAA,EACjBE,EAAJ,EAA0BK,CAA1B,GACEL,CAGA,CAHqBK,CAGrB,CAFAH,CAAA,CAAKG,CAAL,CAAqBN,CAArB,CAEA,CADAG,CAAA,CAAKG,CAAL,CAAqBP,CAArB,CACA,CAAIG,CAAJ,EAAaL,CAAAU,OAAA,EAJf,CAF4B,CAA9B,CAAA,EAUAL,EAAA,CAAU,CAAA,CAKVL,EAAAW,OAAA,CASAC,QAAa,EAAG,CAAA,IACVC,CADU,CAEVC,CAFU,CAIVC,CAGJ,KAAKF,CAAL,GAAaV,EAAb,CACMI,CAAA,CAAYL,CAAA,CAAQW,CAAR,CAAZ,CAAJ,GACEZ,CAAAC,QAAA,CAAiBW,CAAjB,CAAuBhB,CAAvB,CACA,CAAA,OAAOM,CAAA,CAAYU,CAAZ,CAFT,CAOF,KAAKA,CAAL,GAAaX,EAAb,CACEY,CAKA,CALQZ,CAAA,CAAQW,CAAR,CAKR,CAJKjB,CAAAoB,SAAA,CAAiBF,CAAjB,CAIL,GAHEA,CACA,CADQ,EACR,CADaA,CACb,CAAAZ,CAAA,CAAQW,CAAR,CAAA,CAAgBC,CAElB,EAAIA,CAAJ,GAAcX,CAAA,CAAYU,CAAZ,CAAd,GACEZ,CAAAC,QAAA,CAAiBW,CAAjB,CAAuBC,CAAvB,CAEA,CADAX,CAAA,CAAYU,CAAZ,CACA,CADoBC,CACpB,CAAAC,CAAA,CAAU,CAAA,CAHZ,CAQF,IAAIA,CAAJ,CAGE,IAAKF,CAAL,GAFAI,EAEaf,CAFID,CAAAC,QAAA,EAEJA,CAAAA,CAAb,CACMA,CAAA,CAAQW,CAAR,CAAJ,GAAsBI,CAAA,CAAeJ,CAAf,CAAtB,GAEMN,CAAA,CAAYU,CAAA,CAAeJ,CAAf,CAAZ,CAAJ,EACE,OAAOX,CAAA,CAAQW,CAAR,CACP,CAAA,OAAOV,CAAA,CAAYU,CAAZ,CAFT,EAIEX,CAAA,CAAQW,CAAR,CAJF;AAIkBV,CAAA,CAAYU,CAAZ,CAJlB,CAIsCI,CAAA,CAAeJ,CAAf,CANxC,CAjCU,CAThB,CAEA,OAAOX,EA1BoE,CAA1D,CA1BvB,CAAAH,QAAA,CAqIW,cArIX,CAqI2B,CAAC,UAAD,CAAa,QAAQ,CAACmB,CAAD,CAAW,CAErD,MAAO,CAWLC,IAAKA,QAAQ,CAACC,CAAD,CAAM,CAEjB,MAAO,CADHN,CACG,CADKI,CAAA,CAASE,CAAT,CACL,EAAQxB,CAAAyB,SAAA,CAAiBP,CAAjB,CAAR,CAAkCA,CAFxB,CAXd,CA0BLQ,IAAKA,QAAQ,CAACF,CAAD,CAAMN,CAAN,CAAa,CACxBI,CAAA,CAASE,CAAT,CAAA,CAAgBxB,CAAA2B,OAAA,CAAeT,CAAf,CADQ,CA1BrB,CAuCLU,OAAQA,QAAQ,CAACJ,CAAD,CAAM,CACpB,OAAOF,CAAA,CAASE,CAAT,CADa,CAvCjB,CAF8C,CAAhC,CArI3B,CAnBsC,CAArC,CAAD,CAyMGzB,MAzMH,CAyMWA,MAAAC,QAzMX;", 6 | "sources":["angular-cookies.js"], 7 | "names":["window","angular","undefined","module","factory","$rootScope","$browser","cookies","lastCookies","lastBrowserCookies","runEval","copy","isUndefined","addPollFn","currentCookies","$apply","$watch","push","name","value","updated","isString","browserCookies","$cookies","get","key","fromJson","put","toJson","remove"] 8 | } 9 | -------------------------------------------------------------------------------- /src/vendor/angular/angular-resource/angular-resource.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.3.20 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(I,d,B){'use strict';function D(f,q){q=q||{};d.forEach(q,function(d,h){delete q[h]});for(var h in f)!f.hasOwnProperty(h)||"$"===h.charAt(0)&&"$"===h.charAt(1)||(q[h]=f[h]);return q}var w=d.$$minErr("$resource"),C=/^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;d.module("ngResource",["ng"]).provider("$resource",function(){var f=this;this.defaults={stripTrailingSlashes:!0,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}}}; 7 | this.$get=["$http","$q",function(q,h){function t(d,g){this.template=d;this.defaults=s({},f.defaults,g);this.urlParams={}}function v(x,g,l,m){function c(b,k){var c={};k=s({},g,k);r(k,function(a,k){u(a)&&(a=a());var d;if(a&&a.charAt&&"@"==a.charAt(0)){d=b;var e=a.substr(1);if(null==e||""===e||"hasOwnProperty"===e||!C.test("."+e))throw w("badmember",e);for(var e=e.split("."),n=0,g=e.length;n=c;d--)e.end&&e.end(f[d]);f.length=c}}"string"!==typeof a&&(a=null===a||"undefined"===typeof a?"":""+a);var b,k,f=[],m=a,l;for(f.last=function(){return f[f.length-1]};a;){l="";k=!0;if(f.last()&&w[f.last()])a=a.replace(new RegExp("([\\W\\w]*)<\\s*\\/\\s*"+f.last()+"[^>]*>","i"),function(a,b){b=b.replace(H,"$1").replace(I,"$1");e.chars&&e.chars(q(b));return""}),c("",f.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e",b)===b&&(e.comment&& 8 | e.comment(a.substring(4,b)),a=a.substring(b+3),k=!1);else if(x.test(a)){if(b=a.match(x))a=a.replace(b[0],""),k=!1}else if(J.test(a)){if(b=a.match(y))a=a.substring(b[0].length),b[0].replace(y,c),k=!1}else K.test(a)&&((b=a.match(z))?(b[4]&&(a=a.substring(b[0].length),b[0].replace(z,d)),k=!1):(l+="<",a=a.substring(1)));k&&(b=a.indexOf("<"),l+=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),e.chars&&e.chars(q(l)))}if(a==m)throw L("badparse",a);m=a}c()}function q(a){if(!a)return"";A.innerHTML=a.replace(//g,">")}function r(a,e){var d=!1,c=h.bind(a,a.push);return{start:function(a,k,f){a=h.lowercase(a);!d&&w[a]&&(d=a);d||!0!==C[a]||(c("<"),c(a),h.forEach(k,function(d,f){var k=h.lowercase(f),g="img"===a&&"src"===k||"background"=== 10 | k;!0!==O[k]||!0===D[k]&&!e(d,g)||(c(" "),c(f),c('="'),c(B(d)),c('"'))}),c(f?"/>":">"))},end:function(a){a=h.lowercase(a);d||!0!==C[a]||(c(""));a==d&&(d=!1)},chars:function(a){d||c(B(a))}}}var L=h.$$minErr("$sanitize"),z=/^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,y=/^<\/\s*([\w:-]+)[^>]*>/,G=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,K=/^]*?)>/i, 11 | I=/"\u201d\u2019]/i,d=/^mailto:/i;return function(c,b){function k(a){a&&g.push(E(a))}function f(a,c){g.push("');k(c);g.push("")}if(!c)return c;for(var m,l=c,g=[],n,p;m=l.match(e);)n=m[0],m[2]||m[4]||(n=(m[3]?"http://":"mailto:")+n),p=m.index,k(l.substr(0,p)),f(n,m[0].replace(d,"")),l=l.substring(p+m[0].length);k(l);return a(g.join(""))}}])})(window,window.angular); 16 | //# sourceMappingURL=angular-sanitize.min.js.map 17 | -------------------------------------------------------------------------------- /src/vendor/angular/angular-touch/angular-touch.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.3.20 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(y,s,z){'use strict';function t(f,k,p){n.directive(f,["$parse","$swipe",function(d,e){return function(l,m,g){function h(a){if(!b)return!1;var c=Math.abs(a.y-b.y);a=(a.x-b.x)*k;return q&&75>c&&0c/a}var c=d(g[f]),b,q,a=["touch"];s.isDefined(g.ngSwipeDisableMouse)||a.push("mouse");e.bind(m,{start:function(a,c){b=a;q=!0},cancel:function(a){q=!1},end:function(a,b){h(a)&&l.$apply(function(){m.triggerHandler(p);c(l,{$event:b})})}},a)}}])}var n=s.module("ngTouch",[]);n.factory("$swipe", 7 | [function(){function f(d){d=d.originalEvent||d;var e=d.touches&&d.touches.length?d.touches:[d];d=d.changedTouches&&d.changedTouches[0]||e[0];return{x:d.clientX,y:d.clientY}}function k(d,e){var l=[];s.forEach(d,function(d){(d=p[d][e])&&l.push(d)});return l.join(" ")}var p={mouse:{start:"mousedown",move:"mousemove",end:"mouseup"},touch:{start:"touchstart",move:"touchmove",end:"touchend",cancel:"touchcancel"}};return{bind:function(d,e,l){var m,g,h,c,b=!1;l=l||["mouse","touch"];d.on(k(l,"start"),function(a){h= 8 | f(a);b=!0;g=m=0;c=h;e.start&&e.start(h,a)});var q=k(l,"cancel");if(q)d.on(q,function(a){b=!1;e.cancel&&e.cancel(a)});d.on(k(l,"move"),function(a){if(b&&h){var d=f(a);m+=Math.abs(d.x-c.x);g+=Math.abs(d.y-c.y);c=d;10>m&&10>g||(g>m?(b=!1,e.cancel&&e.cancel(a)):(a.preventDefault(),e.move&&e.move(d,a)))}});d.on(k(l,"end"),function(a){b&&(b=!1,e.end&&e.end(f(a),a))})}}}]);n.config(["$provide",function(f){f.decorator("ngClickDirective",["$delegate",function(k){k.shift();return k}])}]);n.directive("ngClick", 9 | ["$parse","$timeout","$rootElement",function(f,k,p){function d(c,b,d){for(var a=0;aMath.abs(c[a]-b)&&25>Math.abs(e-g))return c.splice(a,a+2),!0}return!1}function e(c){if(!(2500e&&1>b||h&&h[0]===e&&h[1]===b)){h&&(h=null);var a=c.target;"label"===s.lowercase(a.nodeName||a[0]&&a[0].nodeName)&&(h=[e,b]);d(g,e,b)||(c.stopPropagation(),c.preventDefault(),c.target&& 10 | c.target.blur&&c.target.blur())}}}function l(c){c=c.touches&&c.touches.length?c.touches:[c];var b=c[0].clientX,d=c[0].clientY;g.push(b,d);k(function(){for(var a=0;ak&&12>x&&(g||(p[0].addEventListener("click",e,!0),p[0].addEventListener("touchstart",l,!0),g=[]),m=Date.now(), 12 | d(g,f,u),r&&r.blur(),s.isDefined(h.disabled)&&!1!==h.disabled||b.triggerHandler("click",[c]));a()});b.onclick=function(a){};b.on("click",function(a,b){c.$apply(function(){k(c,{$event:b||a})})});b.on("mousedown",function(a){b.addClass("ng-click-active")});b.on("mousemove mouseup",function(a){b.removeClass("ng-click-active")})}}]);t("ngSwipeLeft",-1,"swipeleft");t("ngSwipeRight",1,"swiperight")})(window,window.angular); 13 | //# sourceMappingURL=angular-touch.min.js.map 14 | -------------------------------------------------------------------------------- /src/vendor/angular/ngstorage/ngStorage.min.js: -------------------------------------------------------------------------------- 1 | /*! ngstorage 0.3.10 | Copyright (c) 2016 Gias Kay Lee | MIT License */!function(a,b){"use strict";"function"==typeof define&&define.amd?define(["angular"],b):a.hasOwnProperty("angular")?b(a.angular):"object"==typeof exports&&(module.exports=b(require("angular")))}(this,function(a){"use strict";function b(a,b){var c;try{c=a[b]}catch(d){c=!1}if(c){var e="__"+Math.round(1e7*Math.random());try{a[b].setItem(e,e),a[b].removeItem(e,e)}catch(d){c=!1}}return c}function c(c){var d=b(window,c);return function(){var e="ngStorage-";this.setKeyPrefix=function(a){if("string"!=typeof a)throw new TypeError("[ngStorage] - "+c+"Provider.setKeyPrefix() expects a String.");e=a};var f=a.toJson,g=a.fromJson;this.setSerializer=function(a){if("function"!=typeof a)throw new TypeError("[ngStorage] - "+c+"Provider.setSerializer expects a function.");f=a},this.setDeserializer=function(a){if("function"!=typeof a)throw new TypeError("[ngStorage] - "+c+"Provider.setDeserializer expects a function.");g=a},this.supported=function(){return!!d},this.get=function(a){return d&&g(d.getItem(e+a))},this.set=function(a,b){return d&&d.setItem(e+a,f(b))},this.remove=function(a){d&&d.removeItem(e+a)},this.$get=["$rootScope","$window","$log","$timeout","$document",function(d,h,i,j,k){var l,m,n=e.length,o=b(h,c),p=o||(i.warn("This browser does not support Web Storage!"),{setItem:a.noop,getItem:a.noop,removeItem:a.noop}),q={$default:function(b){for(var c in b)a.isDefined(q[c])||(q[c]=a.copy(b[c]));return q.$sync(),q},$reset:function(a){for(var b in q)"$"===b[0]||delete q[b]&&p.removeItem(e+b);return q.$default(a)},$sync:function(){for(var a,b=0,c=p.length;c>b;b++)(a=p.key(b))&&e===a.slice(0,n)&&(q[a.slice(n)]=g(p.getItem(a)))},$apply:function(){var b;if(m=null,!a.equals(q,l)){b=a.copy(l),a.forEach(q,function(c,d){a.isDefined(c)&&"$"!==d[0]&&(p.setItem(e+d,f(c)),delete b[d])});for(var c in b)p.removeItem(e+c);l=a.copy(q)}},$supported:function(){return!!o}};return q.$sync(),l=a.copy(q),d.$watch(function(){m||(m=j(q.$apply,100,!1))}),h.addEventListener&&h.addEventListener("storage",function(b){if(b.key){var c=k[0];c.hasFocus&&c.hasFocus()||e!==b.key.slice(0,n)||(b.newValue?q[b.key.slice(n)]=g(b.newValue):delete q[b.key.slice(n)],l=a.copy(q),d.$apply())}}),h.addEventListener&&h.addEventListener("beforeunload",function(){q.$apply()}),q}]}}return a=a&&a.module?a:window.angular,a.module("ngStorage",[]).provider("$localStorage",c("localStorage")).provider("$sessionStorage",c("sessionStorage"))}); -------------------------------------------------------------------------------- /src/vendor/jquery/charts/flot/jquery.flot.resize.js: -------------------------------------------------------------------------------- 1 | /* 2 | Flot plugin for automatically redrawing plots when the placeholder 3 | size changes, e.g. on window resizes. 4 | 5 | It works by listening for changes on the placeholder div (through the 6 | jQuery resize event plugin) - if the size changes, it will redraw the 7 | plot. 8 | 9 | There are no options. If you need to disable the plugin for some 10 | plots, you can just fix the size of their placeholders. 11 | */ 12 | 13 | 14 | /* Inline dependency: 15 | * jQuery resize event - v1.1 - 3/14/2010 16 | * http://benalman.com/projects/jquery-resize-plugin/ 17 | * 18 | * Copyright (c) 2010 "Cowboy" Ben Alman 19 | * Dual licensed under the MIT and GPL licenses. 20 | * http://benalman.com/about/license/ 21 | */ 22 | (function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);if(r===undefined){n.apply(this,arguments);return;}r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this); 23 | 24 | 25 | (function ($) { 26 | var options = { }; // no options 27 | 28 | function init(plot) { 29 | function onResize() { 30 | var placeholder = plot.getPlaceholder(); 31 | 32 | // somebody might have hidden us and we can't plot 33 | // when we don't have the dimensions 34 | if (placeholder.width() == 0 || placeholder.height() == 0) 35 | return; 36 | 37 | plot.resize(); 38 | plot.setupGrid(); 39 | plot.draw(); 40 | } 41 | 42 | function bindEvents(plot, eventHolder) { 43 | plot.getPlaceholder().resize(onResize); 44 | } 45 | 46 | function shutdown(plot, eventHolder) { 47 | plot.getPlaceholder().unbind("resize", onResize); 48 | } 49 | 50 | plot.hooks.bindEvents.push(bindEvents); 51 | plot.hooks.shutdown.push(shutdown); 52 | } 53 | 54 | $.plot.plugins.push({ 55 | init: init, 56 | options: options, 57 | name: 'resize', 58 | version: '1.0' 59 | }); 60 | })(jQuery); 61 | -------------------------------------------------------------------------------- /src/vendor/jquery/charts/flot/jquery.flot.tooltip.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jquery.flot.tooltip 3 | * 4 | * description: easy-to-use tooltips for Flot charts 5 | * version: 0.7.1 6 | * author: Krzysztof Urbas @krzysu [myviews.pl] 7 | * website: https://github.com/krzysu/flot.tooltip 8 | * 9 | * build on 2014-06-22 10 | * released under MIT License, 2012 11 | */ 12 | Array.prototype.indexOf||(Array.prototype.indexOf=function(t,i){if(void 0===this||null===this)throw new TypeError('"this" is null or not defined');var e=this.length>>>0;for(i=+i||0,1/0===Math.abs(i)&&(i=0),0>i&&(i+=e,0>i&&(i=0));e>i;i++)if(this[i]===t)return i;return-1}),function(t){var i={tooltip:!1,tooltipOpts:{content:"%s | X: %x | Y: %y",xDateFormat:null,yDateFormat:null,monthNames:null,dayNames:null,shifts:{x:10,y:20},defaultTheme:!0,onHover:function(){}}},e=function(t){this.tipPosition={x:0,y:0},this.init(t)};e.prototype.init=function(i){function e(t){var i={};i.x=t.pageX,i.y=t.pageY,o.updateTooltipPosition(i)}function s(t,i,e){var s=o.getDomElement();if(e){var a;a=o.stringFormat(o.tooltipOptions.content,e),s.html(a),o.updateTooltipPosition({x:i.pageX,y:i.pageY}),s.css({left:o.tipPosition.x+o.tooltipOptions.shifts.x,top:o.tipPosition.y+o.tooltipOptions.shifts.y}).show(),"function"==typeof o.tooltipOptions.onHover&&o.tooltipOptions.onHover(e,s)}else s.hide().html("")}var o=this,a=t.plot.plugins.length;if(this.plotPlugins=[],a)for(var n=0;a>n;n++)this.plotPlugins.push(t.plot.plugins[n].name);i.hooks.bindEvents.push(function(i,a){o.plotOptions=i.getOptions(),o.plotOptions.tooltip!==!1&&void 0!==o.plotOptions.tooltip&&(o.tooltipOptions=o.plotOptions.tooltipOpts,o.getDomElement(),t(i.getPlaceholder()).bind("plothover",s),t(a).bind("mousemove",e))}),i.hooks.shutdown.push(function(i,o){t(i.getPlaceholder()).unbind("plothover",s),t(o).unbind("mousemove",e)})},e.prototype.getDomElement=function(){var i=t("#flotTip");return 0===i.length&&(i=t("
").attr("id","flotTip"),i.appendTo("body").hide().css({position:"absolute"}),this.tooltipOptions.defaultTheme&&i.css({background:"#fff","z-index":"1040",padding:"0.4em 0.6em","border-radius":"0.5em","font-size":"0.8em",border:"1px solid #111",display:"none","white-space":"nowrap"})),i},e.prototype.updateTooltipPosition=function(i){var e=t("#flotTip"),s=e.outerWidth()+this.tooltipOptions.shifts.x,o=e.outerHeight()+this.tooltipOptions.shifts.y;i.x-t(window).scrollLeft()>t(window).innerWidth()-s&&(i.x-=s),i.y-t(window).scrollTop()>t(window).innerHeight()-o&&(i.y-=o),this.tipPosition.x=i.x,this.tipPosition.y=i.y},e.prototype.stringFormat=function(t,i){var e,s,o,a=/%p\.{0,1}(\d{0,})/,n=/%s/,r=/%lx/,p=/%ly/,l=/%x\.{0,1}(\d{0,})/,d=/%y\.{0,1}(\d{0,})/,x="%x",h="%y",u="%ct";if(i.series.threshold!==void 0?(e=i.datapoint[0],s=i.datapoint[1],o=i.datapoint[2]):i.series.lines!==void 0&&i.series.lines.steps?(e=i.series.datapoints.points[2*i.dataIndex],s=i.series.datapoints.points[2*i.dataIndex+1],o=""):(e=i.series.data[i.dataIndex][0],s=i.series.data[i.dataIndex][1],o=i.series.data[i.dataIndex][2]),null===i.series.label&&i.series.originSeries&&(i.series.label=i.series.originSeries.label),"function"==typeof t&&(t=t(i.series.label,e,s,i)),i.series.percent!==void 0&&(t=this.adjustValPrecision(a,t,i.series.percent)),t=i.series.label!==void 0?t.replace(n,i.series.label):t.replace(n,""),t=this.hasAxisLabel("xaxis",i)?t.replace(r,i.series.xaxis.options.axisLabel):t.replace(r,""),t=this.hasAxisLabel("yaxis",i)?t.replace(p,i.series.yaxis.options.axisLabel):t.replace(p,""),this.isTimeMode("xaxis",i)&&this.isXDateFormat(i)&&(t=t.replace(l,this.timestampToDate(e,this.tooltipOptions.xDateFormat,i.series.xaxis.options))),this.isTimeMode("yaxis",i)&&this.isYDateFormat(i)&&(t=t.replace(d,this.timestampToDate(s,this.tooltipOptions.yDateFormat,i.series.yaxis.options))),"number"==typeof e&&(t=this.adjustValPrecision(l,t,e)),"number"==typeof s&&(t=this.adjustValPrecision(d,t,s)),i.series.xaxis.ticks!==void 0){var c;c=this.hasRotatedXAxisTicks(i)?"rotatedTicks":"ticks";var m=i.dataIndex+i.seriesIndex;if(i.series.xaxis[c].length>m&&!this.isTimeMode("xaxis",i)){var f=this.isCategoriesMode("xaxis",i)?i.series.xaxis[c][m].label:i.series.xaxis[c][m].v;f===e&&(t=t.replace(l,i.series.xaxis[c][m].label))}}if(i.series.yaxis.ticks!==void 0)for(var y in i.series.yaxis.ticks)if(i.series.yaxis.ticks.hasOwnProperty(y)){var v=this.isCategoriesMode("yaxis",i)?i.series.yaxis.ticks[y].label:i.series.yaxis.ticks[y].v;v===s&&(t=t.replace(d,i.series.yaxis.ticks[y].label))}return i.series.xaxis.tickFormatter!==void 0&&(t=t.replace(x,i.series.xaxis.tickFormatter(e,i.series.xaxis).replace(/\$/g,"$$"))),i.series.yaxis.tickFormatter!==void 0&&(t=t.replace(h,i.series.yaxis.tickFormatter(s,i.series.yaxis).replace(/\$/g,"$$"))),o&&(t=t.replace(u,o)),t},e.prototype.isTimeMode=function(t,i){return i.series[t].options.mode!==void 0&&"time"===i.series[t].options.mode},e.prototype.isXDateFormat=function(){return this.tooltipOptions.xDateFormat!==void 0&&null!==this.tooltipOptions.xDateFormat},e.prototype.isYDateFormat=function(){return this.tooltipOptions.yDateFormat!==void 0&&null!==this.tooltipOptions.yDateFormat},e.prototype.isCategoriesMode=function(t,i){return i.series[t].options.mode!==void 0&&"categories"===i.series[t].options.mode},e.prototype.timestampToDate=function(i,e,s){var o=t.plot.dateGenerator(i,s);return t.plot.formatDate(o,e,this.tooltipOptions.monthNames,this.tooltipOptions.dayNames)},e.prototype.adjustValPrecision=function(t,i,e){var s,o=i.match(t);return null!==o&&""!==RegExp.$1&&(s=RegExp.$1,e=e.toFixed(s),i=i.replace(t,e)),i},e.prototype.hasAxisLabel=function(t,i){return-1!==this.plotPlugins.indexOf("axisLabels")&&i.series[t].options.axisLabel!==void 0&&i.series[t].options.axisLabel.length>0},e.prototype.hasRotatedXAxisTicks=function(i){return 1===t.grep(t.plot.plugins,function(t){return"tickRotor"===t.name}).length&&i.series.xaxis.rotatedTicks!==void 0};var s=function(t){new e(t)};t.plot.plugins.push({init:s,options:i,name:"tooltip",version:"0.6.7"})}(jQuery); -------------------------------------------------------------------------------- /src/vendor/libs/screenfull.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * screenfull 3 | * v3.0.0 - 2015-11-24 4 | * (c) Sindre Sorhus; MIT License 5 | */ 6 | !function(){"use strict";var a="undefined"!=typeof module&&module.exports,b="undefined"!=typeof Element&&"ALLOW_KEYBOARD_INPUT"in Element,c=function(){for(var a,b,c=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],d=0,e=c.length,f={};e>d;d++)if(a=c[d],a&&a[1]in document){for(d=0,b=a.length;b>d;d++)f[c[0][d]]=a[d];return f}return!1}(),d={request:function(a){var d=c.requestFullscreen;a=a||document.documentElement,/5\.1[\.\d]* Safari/.test(navigator.userAgent)?a[d]():a[d](b&&Element.ALLOW_KEYBOARD_INPUT)},exit:function(){document[c.exitFullscreen]()},toggle:function(a){this.isFullscreen?this.exit():this.request(a)},raw:c};return c?(Object.defineProperties(d,{isFullscreen:{get:function(){return Boolean(document[c.fullscreenElement])}},element:{enumerable:!0,get:function(){return document[c.fullscreenElement]}},enabled:{enumerable:!0,get:function(){return Boolean(document[c.fullscreenEnabled])}}}),void(a?module.exports=d:window.screenfull=d)):void(a?module.exports=!1:window.screenfull=!1)}(); -------------------------------------------------------------------------------- /src/vendor/modules/angular-file-upload/ngThumb.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | 4 | angular.module('app') 5 | .directive('ngThumb', ['$window', function ($window) { 6 | var helper = { 7 | support: !!($window.FileReader && $window.CanvasRenderingContext2D), 8 | isFile: function (item) { 9 | return angular.isObject(item) && item instanceof $window.File; 10 | }, 11 | isImage: function (file) { 12 | var type = '|' + file.type.slice(file.type.lastIndexOf('/') + 1) + '|'; 13 | return '|jpg|png|jpeg|bmp|gif|'.indexOf(type) !== -1; 14 | } 15 | }; 16 | 17 | return { 18 | restrict: 'A', 19 | template: '', 20 | link: function (scope, element, attributes) { 21 | if (!helper.support) return; 22 | 23 | var params = scope.$eval(attributes.ngThumb); 24 | 25 | if (!helper.isFile(params.file)) return; 26 | if (!helper.isImage(params.file)) return; 27 | 28 | var canvas = element.find('canvas'); 29 | var reader = new FileReader(); 30 | 31 | reader.onload = onLoadFile; 32 | reader.readAsDataURL(params.file); 33 | 34 | function onLoadFile(event) { 35 | var img = new Image(); 36 | img.onload = onLoadImage; 37 | img.src = event.target.result; 38 | } 39 | 40 | function onLoadImage() { 41 | var width = params.width || this.width / this.height * params.height; 42 | var height = params.height || this.height / this.width * params.width; 43 | canvas.attr({width: width, height: height}); 44 | canvas[0].getContext('2d').drawImage(this, 0, 0, width, height); 45 | } 46 | } 47 | }; 48 | }]); -------------------------------------------------------------------------------- /src/vendor/modules/angular-ivh-treeview/ivh-treeview-theme-basic.css: -------------------------------------------------------------------------------- 1 | ul.ivh-treeview { 2 | list-style-type: none; 3 | padding-left: 0; 4 | } 5 | ul.ivh-treeview ul.ivh-treeview { 6 | padding-left: 15px; 7 | } 8 | ul.ivh-treeview .ivh-treeview-toggle { 9 | cursor: pointer; 10 | } 11 | ul.ivh-treeview .ivh-treeview-node-leaf .ivh-treeview-toggle { 12 | cursor: auto; 13 | } 14 | -------------------------------------------------------------------------------- /src/vendor/modules/angular-ivh-treeview/ivh-treeview.min.css: -------------------------------------------------------------------------------- 1 | ul.ivh-treeview .ivh-treeview-twistie-collapsed,ul.ivh-treeview .ivh-treeview-twistie-leaf,ul.ivh-treeview li.ivh-treeview-node-collapsed ul.ivh-treeview{display:none}ul.ivh-treeview .ivh-treeview-node-collapsed .ivh-treeview-twistie-collapsed{display:inline}ul.ivh-treeview .ivh-treeview-node-collapsed .ivh-treeview-twistie-expanded{display:none}ul.ivh-treeview li.ivh-treeview-node-leaf .ivh-treeview-twistie-leaf{display:inline}ul.ivh-treeview li.ivh-treeview-node-leaf .ivh-treeview-twistie-collapsed,ul.ivh-treeview li.ivh-treeview-node-leaf .ivh-treeview-twistie-expanded{display:none} -------------------------------------------------------------------------------- /src/vendor/modules/angular-tree-dnd/ng-tree-dnd.min.css: -------------------------------------------------------------------------------- 1 | .tree-dnd-animate-enter,.tree-dnd-node.ng-enter{transition:0 linear all;position:relative;display:block;opacity:0;max-height:0}.tree-dnd-animate-enter,.tree-dnd-animate-leave,.tree-dnd-node.ng-enter,.tree-dnd-node.ng-leave{-webkit-transition:0 linear all;-moz-transition:0 linear all;-ms-transition:0 linear all;-o-transition:0 linear all}.tree-dnd-animate-enter.tree-dnd-animate-enter-active,.tree-dnd-node.ng-enter-active{opacity:1;max-height:30px}.tree-dnd-animate-leave,.tree-dnd-node.ng-leave{transition:0 linear all;position:relative;display:block;height:30px;max-height:30px;opacity:1}.tree-dnd-animate-leave.tree-dnd-animate-leave-active,.tree-dnd-node.ng-leave-active{height:0;max-height:0;opacity:0}.tree-dnd-node>td{position:relative}.tree-dnd .tree-icon,.tree-label{cursor:pointer}.tree-dnd>tbody>tr>td,.tree-dnd>tfoot>tr>td,.tree-dnd>thead>tr>td{vertical-align:middle!important}.tree-dnd-empty{border:2px dashed #72da67!important;min-height:100px;background-color:#e5e5e5}.tree-dnd-handle,.tree-dnd-node,.tree-dnd-placeholder{min-height:20px;line-height:20px}.indented{position:relative}.tree-dnd-hidden{display:none}.tree-dnd-placeholder{position:relative;margin:0;padding:0}.tree-dnd-handle{cursor:pointer;text-decoration:none;font-weight:700;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.tree-dnd-drag{position:absolute;pointer-events:none;z-index:999;opacity:.7;background-color:#cdffdc;border:2px dashed #385736}.tree-dnd-status{position:absolute;background-color:#fff;border:1px solid #92e5d3;padding:1px 4px;opacity:.85}.tree-dnd-nodes{margin:0;padding:0;list-style:none}.tree-dnd-nodes .tree-dnd-node{border-radius:0!important}.tree-dnd-nodes .tree-dnd-nodes{padding-left:20px} --------------------------------------------------------------------------------