├── .gitignore ├── docs └── demo │ ├── fonts │ ├── roboto.woff │ ├── DroidSans.ttf │ ├── roboto.woff2 │ ├── FontAwesome.otf │ ├── DroidSans-Bold.ttf │ ├── celeste_regular.eot │ ├── celeste_regular.ttf │ ├── celeste_regular.woff │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ ├── amplitude-bold-webfont.eot │ ├── amplitude-bold-webfont.ttf │ ├── fontawesome-webfont.woff2 │ ├── amplitude-bold-webfont.woff │ ├── amplitude-light-webfont.eot │ ├── amplitude-light-webfont.ttf │ ├── amplitude-light-webfont.woff │ ├── amplitude-medium-webfont.eot │ ├── amplitude-medium-webfont.ttf │ ├── amplitude-medium-webfont.woff │ ├── amplitude-regular-webfont.eot │ ├── amplitude-regular-webfont.ttf │ ├── amplitude-regular-webfont.woff │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 │ ├── css │ ├── images │ │ ├── ui-icons_222222_256x240.png │ │ └── css-images-ui-icons_222222_256x240.png │ ├── reset.css │ ├── style.css │ └── jquery-ui.min.css │ ├── js │ ├── widgets │ │ ├── misc.js │ │ ├── weather.js │ │ ├── controls.js │ │ ├── date.js │ │ ├── form.js │ │ ├── user.js │ │ ├── info.js │ │ └── widget-root.js │ └── index.js │ ├── package.json │ ├── webpack.config.js │ └── index.html ├── jif-landing-page ├── img │ ├── bg.jpg │ ├── holi.png │ ├── jlogo.png │ ├── callout.jpg │ └── cakeshop.png ├── font-awesome │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ ├── less │ │ ├── fixed-width.less │ │ ├── bordered-pulled.less │ │ ├── larger.less │ │ ├── list.less │ │ ├── font-awesome.less │ │ ├── core.less │ │ ├── stacked.less │ │ ├── rotated-flipped.less │ │ ├── path.less │ │ ├── animated.less │ │ └── mixins.less │ └── scss │ │ ├── _fixed-width.scss │ │ ├── _bordered-pulled.scss │ │ ├── _larger.scss │ │ ├── _list.scss │ │ ├── font-awesome.scss │ │ ├── _core.scss │ │ ├── _stacked.scss │ │ ├── _rotated-flipped.scss │ │ ├── _path.scss │ │ ├── _animated.scss │ │ └── _mixins.scss ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── LICENSE ├── README.md ├── css │ ├── prism.css │ └── stylesheet.css ├── index.html └── js │ └── prism.js ├── samples ├── cakeshop │ ├── fonts │ │ ├── roboto.woff │ │ ├── roboto.woff2 │ │ ├── DroidSans.ttf │ │ ├── jpmm-icons.eot │ │ ├── jpmm-icons.ttf │ │ ├── FontAwesome.otf │ │ ├── jpmm-icons.woff │ │ ├── DroidSans-Bold.ttf │ │ ├── celeste_regular.eot │ │ ├── celeste_regular.ttf │ │ ├── celeste_regular.woff │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ ├── amplitude-bold-webfont.eot │ │ ├── amplitude-bold-webfont.ttf │ │ ├── amplitude-bold-webfont.woff │ │ ├── amplitude-light-webfont.eot │ │ ├── amplitude-light-webfont.ttf │ │ ├── fontawesome-webfont.woff2 │ │ ├── amplitude-light-webfont.woff │ │ ├── amplitude-medium-webfont.eot │ │ ├── amplitude-medium-webfont.ttf │ │ ├── amplitude-medium-webfont.woff │ │ ├── amplitude-regular-webfont.eot │ │ ├── amplitude-regular-webfont.ttf │ │ ├── amplitude-regular-webfont.woff │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ ├── css │ │ ├── reset.css │ │ ├── index.html │ │ ├── style.css │ │ └── jquery-ui.min.css │ ├── js │ │ ├── widgets │ │ │ ├── misc.js │ │ │ ├── weather.js │ │ │ ├── controls.js │ │ │ ├── date.js │ │ │ ├── form.js │ │ │ ├── user.js │ │ │ ├── info.js │ │ │ └── widget-root.js │ │ └── index.js │ ├── package.json │ ├── webpack.config.js │ └── index.html └── widget-template.js ├── storage-available.js ├── LICENSE ├── package.json ├── dashboard-util.js ├── dashboard-template.js ├── widget-root.js ├── dashboard.css ├── README.md └── dashboard-core.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | -------------------------------------------------------------------------------- /docs/demo/fonts/roboto.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/roboto.woff -------------------------------------------------------------------------------- /jif-landing-page/img/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/jif-landing-page/img/bg.jpg -------------------------------------------------------------------------------- /docs/demo/fonts/DroidSans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/DroidSans.ttf -------------------------------------------------------------------------------- /docs/demo/fonts/roboto.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/roboto.woff2 -------------------------------------------------------------------------------- /jif-landing-page/img/holi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/jif-landing-page/img/holi.png -------------------------------------------------------------------------------- /jif-landing-page/img/jlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/jif-landing-page/img/jlogo.png -------------------------------------------------------------------------------- /docs/demo/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /jif-landing-page/img/callout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/jif-landing-page/img/callout.jpg -------------------------------------------------------------------------------- /docs/demo/fonts/DroidSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/DroidSans-Bold.ttf -------------------------------------------------------------------------------- /docs/demo/fonts/celeste_regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/celeste_regular.eot -------------------------------------------------------------------------------- /docs/demo/fonts/celeste_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/celeste_regular.ttf -------------------------------------------------------------------------------- /jif-landing-page/img/cakeshop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/jif-landing-page/img/cakeshop.png -------------------------------------------------------------------------------- /samples/cakeshop/fonts/roboto.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/roboto.woff -------------------------------------------------------------------------------- /samples/cakeshop/fonts/roboto.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/roboto.woff2 -------------------------------------------------------------------------------- /docs/demo/fonts/celeste_regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/celeste_regular.woff -------------------------------------------------------------------------------- /samples/cakeshop/fonts/DroidSans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/DroidSans.ttf -------------------------------------------------------------------------------- /samples/cakeshop/fonts/jpmm-icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/jpmm-icons.eot -------------------------------------------------------------------------------- /samples/cakeshop/fonts/jpmm-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/jpmm-icons.ttf -------------------------------------------------------------------------------- /docs/demo/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/demo/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/demo/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /samples/cakeshop/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /samples/cakeshop/fonts/jpmm-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/jpmm-icons.woff -------------------------------------------------------------------------------- /docs/demo/fonts/amplitude-bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/amplitude-bold-webfont.eot -------------------------------------------------------------------------------- /docs/demo/fonts/amplitude-bold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/amplitude-bold-webfont.ttf -------------------------------------------------------------------------------- /docs/demo/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /samples/cakeshop/fonts/DroidSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/DroidSans-Bold.ttf -------------------------------------------------------------------------------- /samples/cakeshop/fonts/celeste_regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/celeste_regular.eot -------------------------------------------------------------------------------- /samples/cakeshop/fonts/celeste_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/celeste_regular.ttf -------------------------------------------------------------------------------- /docs/demo/fonts/amplitude-bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/amplitude-bold-webfont.woff -------------------------------------------------------------------------------- /docs/demo/fonts/amplitude-light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/amplitude-light-webfont.eot -------------------------------------------------------------------------------- /docs/demo/fonts/amplitude-light-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/amplitude-light-webfont.ttf -------------------------------------------------------------------------------- /docs/demo/fonts/amplitude-light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/amplitude-light-webfont.woff -------------------------------------------------------------------------------- /docs/demo/fonts/amplitude-medium-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/amplitude-medium-webfont.eot -------------------------------------------------------------------------------- /docs/demo/fonts/amplitude-medium-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/amplitude-medium-webfont.ttf -------------------------------------------------------------------------------- /docs/demo/fonts/amplitude-medium-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/amplitude-medium-webfont.woff -------------------------------------------------------------------------------- /docs/demo/fonts/amplitude-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/amplitude-regular-webfont.eot -------------------------------------------------------------------------------- /docs/demo/fonts/amplitude-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/amplitude-regular-webfont.ttf -------------------------------------------------------------------------------- /samples/cakeshop/fonts/celeste_regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/celeste_regular.woff -------------------------------------------------------------------------------- /docs/demo/fonts/amplitude-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/amplitude-regular-webfont.woff -------------------------------------------------------------------------------- /samples/cakeshop/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /samples/cakeshop/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /samples/cakeshop/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /docs/demo/css/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/css/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /docs/demo/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /docs/demo/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /docs/demo/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /docs/demo/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /samples/cakeshop/fonts/amplitude-bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/amplitude-bold-webfont.eot -------------------------------------------------------------------------------- /samples/cakeshop/fonts/amplitude-bold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/amplitude-bold-webfont.ttf -------------------------------------------------------------------------------- /samples/cakeshop/fonts/amplitude-bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/amplitude-bold-webfont.woff -------------------------------------------------------------------------------- /samples/cakeshop/fonts/amplitude-light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/amplitude-light-webfont.eot -------------------------------------------------------------------------------- /samples/cakeshop/fonts/amplitude-light-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/amplitude-light-webfont.ttf -------------------------------------------------------------------------------- /samples/cakeshop/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/jif-landing-page/font-awesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /samples/cakeshop/fonts/amplitude-light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/amplitude-light-webfont.woff -------------------------------------------------------------------------------- /samples/cakeshop/fonts/amplitude-medium-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/amplitude-medium-webfont.eot -------------------------------------------------------------------------------- /samples/cakeshop/fonts/amplitude-medium-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/amplitude-medium-webfont.ttf -------------------------------------------------------------------------------- /samples/cakeshop/fonts/amplitude-medium-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/amplitude-medium-webfont.woff -------------------------------------------------------------------------------- /samples/cakeshop/fonts/amplitude-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/amplitude-regular-webfont.eot -------------------------------------------------------------------------------- /samples/cakeshop/fonts/amplitude-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/amplitude-regular-webfont.ttf -------------------------------------------------------------------------------- /jif-landing-page/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/jif-landing-page/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /jif-landing-page/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/jif-landing-page/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /samples/cakeshop/fonts/amplitude-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/amplitude-regular-webfont.woff -------------------------------------------------------------------------------- /samples/cakeshop/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /samples/cakeshop/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /jif-landing-page/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/jif-landing-page/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /jif-landing-page/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/jif-landing-page/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /samples/cakeshop/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /samples/cakeshop/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/samples/cakeshop/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /docs/demo/css/images/css-images-ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/docs/demo/css/images/css-images-ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/jif-landing-page/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/jif-landing-page/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/jif-landing-page/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpmorganchase/jif-dashboard/HEAD/jif-landing-page/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/less/fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /storage-available.js: -------------------------------------------------------------------------------- 1 | // from mdn, lightly edited. 2 | 3 | export default (function storageAvailable() { 4 | try { 5 | var storage = window.localStorage; 6 | var x = '__storage_test__'; 7 | storage.setItem(x, x); 8 | storage.removeItem(x); 9 | return true; 10 | } 11 | catch(e) { 12 | return false; 13 | } 14 | }()); 15 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/less/bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em @fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .pull-right { float: right; } 11 | .pull-left { float: left; } 12 | 13 | .@{fa-css-prefix} { 14 | &.pull-left { margin-right: .3em; } 15 | &.pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/scss/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em $fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .pull-right { float: right; } 11 | .pull-left { float: left; } 12 | 13 | .#{$fa-css-prefix} { 14 | &.pull-left { margin-right: .3em; } 15 | &.pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/less/larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .@{fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .@{fa-css-prefix}-2x { font-size: 2em; } 11 | .@{fa-css-prefix}-3x { font-size: 3em; } 12 | .@{fa-css-prefix}-4x { font-size: 4em; } 13 | .@{fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .#{$fa-css-prefix}-2x { font-size: 2em; } 11 | .#{$fa-css-prefix}-3x { font-size: 3em; } 12 | .#{$fa-css-prefix}-4x { font-size: 4em; } 13 | .#{$fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/less/list.less: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: @fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .@{fa-css-prefix}-li { 11 | position: absolute; 12 | left: -@fa-li-width; 13 | width: @fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.@{fa-css-prefix}-lg { 17 | left: (-@fa-li-width + (4em / 14)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "animated"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Licensed under the Apache License, Version 2.0 (the "License"); 3 | you may not use this software except in compliance with the License. 4 | You may obtain a copy of the License at 5 | 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | See the License for the specific language governing permissions and 12 | limitations under the License. 13 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables.less"; 7 | @import "mixins.less"; 8 | @import "path.less"; 9 | @import "core.less"; 10 | @import "larger.less"; 11 | @import "fixed-width.less"; 12 | @import "list.less"; 13 | @import "bordered-pulled.less"; 14 | @import "animated.less"; 15 | @import "rotated-flipped.less"; 16 | @import "stacked.less"; 17 | @import "icons.less"; 18 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/less/core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal @fa-font-size-base/1 FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | transform: translate(0, 0); // ensures no half-pixel rendering in firefox 12 | 13 | } 14 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/less/stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 21 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal #{$fa-font-size-base}/1 FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | transform: translate(0, 0); // ensures no half-pixel rendering in firefox 12 | 13 | } 14 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/less/rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .@{fa-css-prefix}-rotate-90, 15 | :root .@{fa-css-prefix}-rotate-180, 16 | :root .@{fa-css-prefix}-rotate-270, 17 | :root .@{fa-css-prefix}-flip-horizontal, 18 | :root .@{fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /docs/demo/css/reset.css: -------------------------------------------------------------------------------- 1 | html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}table{border-collapse:collapse;border-spacing:0} 2 | -------------------------------------------------------------------------------- /samples/cakeshop/css/reset.css: -------------------------------------------------------------------------------- 1 | html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}table{border-collapse:collapse;border-spacing:0} 2 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .#{$fa-css-prefix}-rotate-90, 15 | :root .#{$fa-css-prefix}-rotate-180, 16 | :root .#{$fa-css-prefix}-rotate-270, 17 | :root .#{$fa-css-prefix}-flip-horizontal, 18 | :root .#{$fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jif-dashboard", 3 | "version": "1.3.6", 4 | "description": "", 5 | "main": "dashboard-core.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+ssh://git@github.com/jpmorganchase/jif-dashboard.git" 12 | }, 13 | "author": "JPMorgan Chase ", 14 | "contributors":[ 15 | "Jasmine Feng", 16 | "Ilya Uts", 17 | "Felix Shnir" 18 | ], 19 | "license": "Apache-2.0", 20 | "bugs": { 21 | "url": "https://github.com/jpmorganchase/jif-dashboard/issues" 22 | }, 23 | "homepage": "https://github.com/jpmorganchase/jif-dashboard#readme", 24 | "dependencies": { 25 | "draggabilly": "^2.1.1", 26 | "packery": "^2.1.1", 27 | "underscore": "^1.8.3" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /docs/demo/js/widgets/misc.js: -------------------------------------------------------------------------------- 1 | module.exports = function(id) { 2 | var extended = { 3 | name: 'misc', 4 | title: 'Misc', 5 | size: 'large', 6 | widgetId: id, 7 | 8 | template: _.template('its empty'), 9 | 10 | render: function() { 11 | Dashboard.render.widget(this.name, this.shell.tpl); 12 | this.fetch(); 13 | 14 | $('#widget-' + this.shell.id).css({ 15 | 'height': '240px', 16 | 'margin-bottom': '10px', 17 | 'overflow-x': 'hidden', 18 | 'width': '100%' 19 | }).html( this.template()); 20 | 21 | 22 | this.postRender(); 23 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 24 | } 25 | }; 26 | 27 | 28 | var widget = _.extend({}, widgetRoot, extended); 29 | 30 | // register presence with screen manager 31 | Dashboard.addWidget(widget); 32 | }; 33 | -------------------------------------------------------------------------------- /samples/cakeshop/js/widgets/misc.js: -------------------------------------------------------------------------------- 1 | module.exports = function(id) { 2 | var extended = { 3 | name: 'misc', 4 | title: 'Misc', 5 | size: 'large', 6 | widgetId: id, 7 | 8 | template: _.template('its empty'), 9 | 10 | render: function() { 11 | Dashboard.render.widget(this.name, this.shell.tpl); 12 | this.fetch(); 13 | 14 | $('#widget-' + this.shell.id).css({ 15 | 'height': '240px', 16 | 'margin-bottom': '10px', 17 | 'overflow-x': 'hidden', 18 | 'width': '100%' 19 | }).html( this.template()); 20 | 21 | 22 | this.postRender(); 23 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 24 | } 25 | }; 26 | 27 | 28 | var widget = _.extend({}, widgetRoot, extended); 29 | 30 | // register presence with screen manager 31 | Dashboard.addWidget(widget); 32 | }; 33 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/less/path.less: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}'); 7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'), 8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'), 9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'), 10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'), 11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg'); 12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/scss/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); 7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), 8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'), 9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), 10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), 11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); 12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/less/animated.less: -------------------------------------------------------------------------------- 1 | // Animated Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | .@{fa-css-prefix}-pulse { 10 | -webkit-animation: fa-spin 1s infinite steps(8); 11 | animation: fa-spin 1s infinite steps(8); 12 | } 13 | 14 | @-webkit-keyframes fa-spin { 15 | 0% { 16 | -webkit-transform: rotate(0deg); 17 | transform: rotate(0deg); 18 | } 19 | 100% { 20 | -webkit-transform: rotate(359deg); 21 | transform: rotate(359deg); 22 | } 23 | } 24 | 25 | @keyframes fa-spin { 26 | 0% { 27 | -webkit-transform: rotate(0deg); 28 | transform: rotate(0deg); 29 | } 30 | 100% { 31 | -webkit-transform: rotate(359deg); 32 | transform: rotate(359deg); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /docs/demo/js/widgets/weather.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(id) { 3 | var extended = { 4 | title: 'Weather', 5 | size: 'third', 6 | widgetId: id, 7 | 8 | hideLink: true, 9 | 10 | template: _.template(''), 11 | 12 | render: function() { 13 | Dashboard.render.widget(this.name, this.shell.tpl); 14 | 15 | this.fetch(); 16 | 17 | $('#widget-' + this.shell.id).css({ 18 | 'height': '240px', 19 | 'margin-bottom': '10px', 20 | 'overflow-x': 'hidden', 21 | 'width': '100%' 22 | }).html( this.template() ); 23 | 24 | this.postRender(); 25 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 26 | }, 27 | }; 28 | 29 | var widget = _.extend({}, widgetRoot, extended); 30 | 31 | // register presence with screen manager 32 | Dashboard.addWidget(widget); 33 | }; 34 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/scss/_animated.scss: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | .#{$fa-css-prefix}-pulse { 10 | -webkit-animation: fa-spin 1s infinite steps(8); 11 | animation: fa-spin 1s infinite steps(8); 12 | } 13 | 14 | @-webkit-keyframes fa-spin { 15 | 0% { 16 | -webkit-transform: rotate(0deg); 17 | transform: rotate(0deg); 18 | } 19 | 100% { 20 | -webkit-transform: rotate(359deg); 21 | transform: rotate(359deg); 22 | } 23 | } 24 | 25 | @keyframes fa-spin { 26 | 0% { 27 | -webkit-transform: rotate(0deg); 28 | transform: rotate(0deg); 29 | } 30 | 100% { 31 | -webkit-transform: rotate(359deg); 32 | transform: rotate(359deg); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /samples/cakeshop/js/widgets/weather.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(id) { 3 | var extended = { 4 | title: 'Weather', 5 | size: 'third', 6 | widgetId: id, 7 | 8 | hideLink: true, 9 | 10 | template: _.template(''), 11 | 12 | render: function() { 13 | Dashboard.render.widget(this.name, this.shell.tpl); 14 | 15 | this.fetch(); 16 | 17 | $('#widget-' + this.shell.id).css({ 18 | 'height': '240px', 19 | 'margin-bottom': '10px', 20 | 'overflow-x': 'hidden', 21 | 'width': '100%' 22 | }).html( this.template() ); 23 | 24 | this.postRender(); 25 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 26 | }, 27 | }; 28 | 29 | var widget = _.extend({}, widgetRoot, extended); 30 | 31 | // register presence with screen manager 32 | Dashboard.addWidget(widget); 33 | }; 34 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | .fa-icon() { 5 | display: inline-block; 6 | font: normal normal normal @fa-font-size-base/1 FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | transform: translate(0, 0); // ensures no half-pixel rendering in firefox 12 | 13 | } 14 | 15 | .fa-icon-rotate(@degrees, @rotation) { 16 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation); 17 | -webkit-transform: rotate(@degrees); 18 | -ms-transform: rotate(@degrees); 19 | transform: rotate(@degrees); 20 | } 21 | 22 | .fa-icon-flip(@horiz, @vert, @rotation) { 23 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation, mirror=1); 24 | -webkit-transform: scale(@horiz, @vert); 25 | -ms-transform: scale(@horiz, @vert); 26 | transform: scale(@horiz, @vert); 27 | } 28 | -------------------------------------------------------------------------------- /jif-landing-page/font-awesome/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon() { 5 | display: inline-block; 6 | font: normal normal normal #{$fa-font-size-base}/1 FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | transform: translate(0, 0); // ensures no half-pixel rendering in firefox 12 | 13 | } 14 | 15 | @mixin fa-icon-rotate($degrees, $rotation) { 16 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); 17 | -webkit-transform: rotate($degrees); 18 | -ms-transform: rotate($degrees); 19 | transform: rotate($degrees); 20 | } 21 | 22 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 23 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); 24 | -webkit-transform: scale($horiz, $vert); 25 | -ms-transform: scale($horiz, $vert); 26 | transform: scale($horiz, $vert); 27 | } 28 | -------------------------------------------------------------------------------- /docs/demo/js/widgets/controls.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(id) { 3 | var extended = { 4 | title: 'Control Panel', 5 | size: 'third', 6 | widgetId: id, 7 | 8 | hideLink: true, 9 | 10 | template: _.template('
'), 15 | 16 | render: function() { 17 | Dashboard.render.widget(this.name, this.shell.tpl); 18 | 19 | this.fetch(); 20 | 21 | $('#widget-' + this.shell.id).css({ 22 | 'height': '240px', 23 | 'margin-bottom': '10px', 24 | 'overflow-x': 'hidden', 25 | 'width': '100%' 26 | }).html( this.template() ); 27 | 28 | this.postRender(); 29 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 30 | } 31 | }; 32 | 33 | var widget = _.extend({}, widgetRoot, extended); 34 | 35 | // register presence with screen manager 36 | Dashboard.addWidget(widget); 37 | }; 38 | -------------------------------------------------------------------------------- /jif-landing-page/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2016 Blackrock Digital LLC. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. -------------------------------------------------------------------------------- /samples/cakeshop/js/widgets/controls.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(id) { 3 | var extended = { 4 | title: 'Control Panel', 5 | size: 'third', 6 | widgetId: id, 7 | 8 | hideLink: true, 9 | 10 | template: _.template('
'), 15 | 16 | render: function() { 17 | Dashboard.render.widget(this.name, this.shell.tpl); 18 | 19 | this.fetch(); 20 | 21 | $('#widget-' + this.shell.id).css({ 22 | 'height': '240px', 23 | 'margin-bottom': '10px', 24 | 'overflow-x': 'hidden', 25 | 'width': '100%' 26 | }).html( this.template() ); 27 | 28 | this.postRender(); 29 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 30 | } 31 | }; 32 | 33 | var widget = _.extend({}, widgetRoot, extended); 34 | 35 | // register presence with screen manager 36 | Dashboard.addWidget(widget); 37 | }; 38 | -------------------------------------------------------------------------------- /samples/cakeshop/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cakeshop-api", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "js/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "webpack", 9 | "start": "webpack-dev-server", 10 | "watch": "webpack --watch" 11 | }, 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "babel-core": "6.13.2", 16 | "babel-loader": "6.2.4", 17 | "babel-plugin-transform-promise-to-bluebird": "1.1.0", 18 | "babel-plugin-transform-runtime": "6.12.0", 19 | "babel-polyfill": "6.13.0", 20 | "babel-preset-es2015": "6.13.2", 21 | "babel-runtime": "6.11.6", 22 | "webpack": "1.13.1", 23 | "webpack-dev-server": "1.15.1" 24 | }, 25 | "dependencies": { 26 | "backbone": "1.3.3", 27 | "bluebird": "3.4.1", 28 | "bootstrap": "3.3.7", 29 | "d3": "4.2.1", 30 | "jif-dashboard": "^1.0.0", 31 | "draggabilly": "2.1.1", 32 | "jquery": "3.3.1", 33 | "jquery-slimscroll": "1.3.8", 34 | "jquery-ui-dist": "1.12.0", 35 | "moment": "2.19.3", 36 | "sockjs-client": "1.1.1", 37 | "underscore": "1.8.3" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /docs/demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cakeshop-demo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "js/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "webpack", 9 | "start": "webpack-dev-server", 10 | "watch": "webpack --watch" 11 | }, 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "babel-core": "^6.13.2", 16 | "babel-loader": "^6.2.4", 17 | "babel-plugin-transform-promise-to-bluebird": "^1.1.0", 18 | "babel-plugin-transform-runtime": "^6.12.0", 19 | "babel-polyfill": "^6.13.0", 20 | "babel-preset-es2015": "^6.13.2", 21 | "babel-runtime": "^6.11.6", 22 | "css-loader": "^0.26.0", 23 | "style-loader": "^0.13.1", 24 | "webpack": "^1.13.1", 25 | "webpack-dev-server": "^1.15.1" 26 | }, 27 | "dependencies": { 28 | "backbone": "^1.3.3", 29 | "bluebird": "^3.4.1", 30 | "bootstrap": "^3.3.7", 31 | "d3": "^4.2.1", 32 | "jif-dashboard": "^1.0.0", 33 | "draggabilly": "^2.1.1", 34 | "jquery": "^3.0.0", 35 | "jquery-slimscroll": "^1.3.8", 36 | "jquery-ui-dist": "^1.12.0", 37 | "moment": "^2.19.3", 38 | "sockjs-client": "^1.1.1", 39 | "underscore": "^1.8.3" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /docs/demo/js/widgets/date.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(id) { 3 | var extended = { 4 | title: 'Date', 5 | size: 'third', 6 | widgetId: id, 7 | 8 | hideLink: true, 9 | 10 | template: _.template('
<%=month%> / <%=day%>
<%=year%>
'), 11 | 12 | render: function() { 13 | Dashboard.render.widget(this.name, this.shell.tpl); 14 | 15 | this.fetch(); 16 | 17 | var today = new Date(); 18 | var dd = today.getDate(); 19 | var mm = today.getMonth()+1; //January is 0! 20 | var yyyy = today.getFullYear(); 21 | 22 | if(dd<10) { 23 | dd='0'+dd 24 | } 25 | 26 | if(mm<10) { 27 | mm='0'+mm 28 | } 29 | 30 | today = mm+'/'+dd+'/'+yyyy; 31 | 32 | $('#widget-' + this.shell.id).css({ 33 | 'height': '240px', 34 | 'margin-bottom': '10px', 35 | 'overflow-x': 'hidden', 36 | 'width': '100%' 37 | }).html( this.template({ 38 | date: today, 39 | month: mm, 40 | day: dd, 41 | year: yyyy 42 | }) ); 43 | 44 | this.postRender(); 45 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 46 | }, 47 | }; 48 | 49 | var widget = _.extend({}, widgetRoot, extended); 50 | 51 | // register presence with screen manager 52 | Dashboard.addWidget(widget); 53 | }; 54 | -------------------------------------------------------------------------------- /samples/cakeshop/js/widgets/date.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(id) { 3 | var extended = { 4 | title: 'Date', 5 | size: 'third', 6 | widgetId: id, 7 | 8 | hideLink: true, 9 | 10 | template: _.template('
<%=month%> / <%=day%>
<%=year%>
'), 11 | 12 | render: function() { 13 | Dashboard.render.widget(this.name, this.shell.tpl); 14 | 15 | this.fetch(); 16 | 17 | var today = new Date(); 18 | var dd = today.getDate(); 19 | var mm = today.getMonth()+1; //January is 0! 20 | var yyyy = today.getFullYear(); 21 | 22 | if(dd<10) { 23 | dd='0'+dd 24 | } 25 | 26 | if(mm<10) { 27 | mm='0'+mm 28 | } 29 | 30 | today = mm+'/'+dd+'/'+yyyy; 31 | 32 | $('#widget-' + this.shell.id).css({ 33 | 'height': '240px', 34 | 'margin-bottom': '10px', 35 | 'overflow-x': 'hidden', 36 | 'width': '100%' 37 | }).html( this.template({ 38 | date: today, 39 | month: mm, 40 | day: dd, 41 | year: yyyy 42 | }) ); 43 | 44 | this.postRender(); 45 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 46 | }, 47 | }; 48 | 49 | var widget = _.extend({}, widgetRoot, extended); 50 | 51 | // register presence with screen manager 52 | Dashboard.addWidget(widget); 53 | }; 54 | -------------------------------------------------------------------------------- /docs/demo/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | 4 | 5 | module.exports = { 6 | entry: ["webpack/hot/dev-server", "./js/index.js"], 7 | output: { 8 | path: path.join(__dirname, 'js'), 9 | filename: "index-gen.js", 10 | publicPath: '/js/' 11 | }, 12 | watchOptions: { 13 | aggregateTimeout: 300, 14 | poll: 1000 15 | }, 16 | devServer: { 17 | historyApiFallback: true, 18 | hot: true, 19 | inline: true, 20 | stats: 'errors-only', 21 | port: 8081 22 | }, 23 | plugins: [ 24 | new webpack.ProvidePlugin({ 25 | $: "jquery", 26 | jQuery: "jquery", 27 | "window.jQuery": "jquery", 28 | d3: "d3", 29 | Backbone: "backbone", 30 | _: "underscore", 31 | SockJS: "sockjs-client", 32 | moment: "moment", 33 | }), 34 | new webpack.HotModuleReplacementPlugin({ 35 | multiStep: true 36 | }) 37 | ], 38 | module: { 39 | loaders: [ 40 | { test: /\.css$/, loader: "style-loader!css-loader" }, 41 | { 42 | test: /\.js$/, 43 | include: [ 44 | path.resolve(__dirname, "js"), 45 | path.resolve(__dirname, "node_modules/jif-dashboard"), 46 | ], 47 | loader: 'babel', 48 | query: { 49 | presets: ['es2015'], 50 | plugins: [ 51 | 'transform-promise-to-bluebird', 52 | 'transform-runtime' 53 | ], 54 | } 55 | } 56 | ] 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /samples/cakeshop/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | 4 | 5 | module.exports = { 6 | entry: ["webpack/hot/dev-server", "./js/index.js"], 7 | output: { 8 | path: path.join(__dirname, 'js'), 9 | filename: "index-gen.js", 10 | publicPath: '/js/' 11 | }, 12 | watchOptions: { 13 | aggregateTimeout: 300, 14 | poll: 1000 15 | }, 16 | devServer: { 17 | historyApiFallback: true, 18 | hot: true, 19 | inline: true, 20 | stats: 'errors-only', 21 | port: 8081 22 | }, 23 | plugins: [ 24 | new webpack.ProvidePlugin({ 25 | $: "jquery", 26 | jQuery: "jquery", 27 | "window.jQuery": "jquery", 28 | d3: "d3", 29 | Backbone: "backbone", 30 | _: "underscore", 31 | SockJS: "sockjs-client", 32 | moment: "moment", 33 | }), 34 | new webpack.HotModuleReplacementPlugin({ 35 | multiStep: true 36 | }) 37 | ], 38 | module: { 39 | loaders: [ 40 | { 41 | test: /\.js$/, 42 | include: [ 43 | path.resolve(__dirname, "js"), 44 | path.resolve(__dirname, "node_modules/jif-dashboard"), 45 | ], 46 | loader: 'babel', 47 | query: { 48 | presets: ['es2015'], 49 | plugins: [ 50 | 'transform-promise-to-bluebird', 51 | 'transform-runtime' 52 | ], 53 | } 54 | } 55 | ] 56 | } 57 | }; 58 | -------------------------------------------------------------------------------- /docs/demo/js/widgets/form.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(id) { 3 | var extended = { 4 | name: 'form', 5 | title: 'Form', 6 | size: 'medium', 7 | widgetId: id, 8 | 9 | hideLink: true, 10 | 11 | template: _.template('
' + 12 | '
' + 13 | '' + 14 | '' + 15 | '
' + 16 | '
' + 17 | '' + 18 | '' + 19 | '
' + 20 | '
' + 21 | '' + 22 | '' + 23 | '
' + 24 | '
' + 25 | '' + 28 | '
' + 29 | '' + 30 | '
'), 31 | 32 | render: function() { 33 | Dashboard.render.widget(this.name, this.shell.tpl); 34 | this.fetch(); 35 | 36 | $('#widget-' + this.shell.id).css({ 37 | 'height': '240px', 38 | 'margin-bottom': '10px', 39 | 'overflow-x': 'hidden', 40 | 'width': '100%' 41 | }).html( this.template()); 42 | 43 | this.postRender(); 44 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 45 | } 46 | } 47 | 48 | var widget = _.extend({}, widgetRoot, extended); 49 | 50 | // register presence with screen manager 51 | Dashboard.addWidget(widget); 52 | 53 | } 54 | -------------------------------------------------------------------------------- /samples/cakeshop/js/widgets/form.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(id) { 3 | var extended = { 4 | name: 'form', 5 | title: 'Form', 6 | size: 'medium', 7 | widgetId: id, 8 | 9 | hideLink: true, 10 | 11 | template: _.template('
' + 12 | '
' + 13 | '' + 14 | '' + 15 | '
' + 16 | '
' + 17 | '' + 18 | '' + 19 | '
' + 20 | '
' + 21 | '' + 22 | '' + 23 | '
' + 24 | '
' + 25 | '' + 28 | '
' + 29 | '' + 30 | '
'), 31 | 32 | render: function() { 33 | Dashboard.render.widget(this.name, this.shell.tpl); 34 | this.fetch(); 35 | 36 | $('#widget-' + this.shell.id).css({ 37 | 'height': '240px', 38 | 'margin-bottom': '10px', 39 | 'overflow-x': 'hidden', 40 | 'width': '100%' 41 | }).html( this.template()); 42 | 43 | this.postRender(); 44 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 45 | } 46 | } 47 | 48 | var widget = _.extend({}, widgetRoot, extended); 49 | 50 | // register presence with screen manager 51 | Dashboard.addWidget(widget); 52 | 53 | } 54 | -------------------------------------------------------------------------------- /dashboard-util.js: -------------------------------------------------------------------------------- 1 | var Utils = { 2 | debug: function(message) { 3 | var _ref; 4 | return typeof window !== 'undefined' && window !== null ? (_ref = window.console) != null ? _ref.log(message) : void 0 : void 0; 5 | }, 6 | 7 | demoFuzz: function() { 8 | return window.demo ? Math.ceil(Math.random() * 10) : 0; 9 | }, 10 | 11 | emit: function(e, quiet) { 12 | if(!quiet) { 13 | this.debug('Emitting ' + e); 14 | } 15 | 16 | if (e) { 17 | $(document).trigger('WidgetInternalEvent', [ e ]); 18 | } 19 | }, 20 | 21 | on: function(callback) { 22 | $(document).on('WidgetInternalEvent', callback); 23 | }, 24 | 25 | copyToClipboard: function(e) { 26 | 27 | if (navigator.appName == 'Microsoft Internet Explorer' || !!(navigator.userAgent.match(/Trident/) || navigator.userAgent.match(/rv 11/)) ) { 28 | //internet explorer 29 | window.clipboardData.setData('Text', $('#_clipboard').val()); 30 | } else { 31 | var t = e.target, 32 | c = t.dataset.copytarget, 33 | inp = (c ? document.querySelector(c) : null); 34 | 35 | // is element selectable? 36 | if (inp && inp.select) { 37 | // select text 38 | inp.select(); 39 | 40 | try { 41 | // copy text 42 | document.execCommand('copy'); 43 | inp.blur(); 44 | } catch (err) { 45 | console.log('did not copy'); 46 | window.prompt("Copy to clipboard: Ctrl+C, Enter", $('#_clipboard').val()); 47 | } 48 | } 49 | } 50 | }, 51 | 52 | selectorEscape: function(id) { 53 | return id.replace( /(:|\.|\[|\]|,|=|@)/g, '\\$1' ); 54 | } 55 | } 56 | 57 | window.Dashboard.Utils = Utils; 58 | 59 | // Adding event for sleep / wake 60 | $(document).on('visibilitychange', function(e) { 61 | Dashboard.Utils.emit('tower-control|sleep|' + document.hidden); 62 | }); 63 | -------------------------------------------------------------------------------- /jif-landing-page/README.md: -------------------------------------------------------------------------------- 1 | # [Start Bootstrap](http://startbootstrap.com/) - [Stylish Portfolio](http://startbootstrap.com/template-overviews/stylish-portfolio/) 2 | 3 | [Stylish Portfolio](http://startbootstrap.com/template-overviews/stylish-portfolio/) is a responsive, one page portfolio theme for [Bootstrap](http://getbootstrap.com/) created by [Start Bootstrap](http://startbootstrap.com/). The theme features multiple content sections with an off canvas navigation menu. 4 | 5 | ## Getting Started 6 | 7 | To begin using this template, choose one of the following options to get started: 8 | * [Download the latest release on Start Bootstrap](http://startbootstrap.com/template-overviews/stylish-portfolio/) 9 | * Clone the repo: `git clone https://github.com/BlackrockDigital/startbootstrap-stylish-portfolio.git` 10 | * Fork the repo 11 | 12 | ## Bugs and Issues 13 | 14 | Have a bug or an issue with this template? [Open a new issue](https://github.com/BlackrockDigital/startbootstrap-stylish-portfolio/issues) here on GitHub or leave a comment on the [template overview page at Start Bootstrap](http://startbootstrap.com/template-overviews/stylish-portfolio/). 15 | 16 | ## Creator 17 | 18 | Start Bootstrap was created by and is maintained by **[David Miller](http://davidmiller.io/)**, Owner of [Blackrock Digital](http://blackrockdigital.io/). 19 | 20 | * https://twitter.com/davidmillerskt 21 | * https://github.com/davidtmiller 22 | 23 | Start Bootstrap is based on the [Bootstrap](http://getbootstrap.com/) framework created by [Mark Otto](https://twitter.com/mdo) and [Jacob Thorton](https://twitter.com/fat). 24 | 25 | ## Copyright and License 26 | 27 | Copyright 2013-2016 Blackrock Digital LLC. Code released under the [MIT](https://github.com/BlackrockDigital/startbootstrap-stylish-portfolio/blob/gh-pages/LICENSE) license. -------------------------------------------------------------------------------- /dashboard-template.js: -------------------------------------------------------------------------------- 1 | window.Dashboard.TEMPLATES = { 2 | _widget: function(opts) { 3 | return '
\n'+ 4 | '
\n'+ 5 | '
\n'+ 6 | '

' + opts.title + '

\n'+ 7 | '
    \n'+ 8 | 9 | ( opts.customButtons ? opts.customButtons : '' ) + 10 | 11 | ( opts.hideLink === true ? '' : '
  • \n') + 12 | 13 | '
  • \n'+ 14 | ( opts.hideRefresh === true ? '' : '
  • \n') + 15 | 16 | '
  • \n'+ 17 | '
\n'+ 18 | '
\n'+ 19 | '
\n'+ 20 | '
\n'+ 21 | '
\n'+ 22 | '
'; 23 | }, 24 | 25 | widget: function(o) { 26 | var opts = _.extend({ 27 | id: Math.ceil(Math.random() * 100000000), 28 | 29 | largeColumn: 3, 30 | mediumColumn: 4, 31 | smallColumn: 12 32 | }, o); 33 | 34 | switch (opts.size) { 35 | case 'medium': 36 | opts.largeColumn = 6; 37 | opts.mediumColumn = 12; 38 | opts.smallColumn = 12; 39 | 40 | break; 41 | 42 | case 'large': 43 | opts.largeColumn = 12; 44 | opts.mediumColumn = 6; 45 | opts.smallColumn = 12; 46 | 47 | break; 48 | 49 | case 'third': 50 | opts.largeColumn = 4; 51 | opts.mediumColumn = 6; 52 | opts.smallColumn = 12; 53 | 54 | break; 55 | } 56 | 57 | return { 58 | id: opts.id, 59 | tpl: Dashboard.TEMPLATES._widget(opts) 60 | }; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /docs/demo/js/widgets/user.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(id) { 3 | var extended = { 4 | title: 'Users', 5 | size: 'small', 6 | widgetId: id, 7 | 8 | hideLink: true, 9 | 10 | template: _.template('
' + 11 | '' + 12 | '' + 13 | '' + 14 | '
Name <%= name %>
Role <%= role %>
ID <%=id%>
'), 15 | 16 | 17 | init: function(data) { 18 | Dashboard.Utils.emit('widget|init|' + this.name); 19 | 20 | if (data) { 21 | this.setData(data); 22 | } 23 | 24 | this.shell = Dashboard.TEMPLATES.widget({ 25 | name: this.name, 26 | title: this.title, 27 | size: this.size, 28 | hideLink: this.hideLink, 29 | hideRefresh: this.hideRefresh, 30 | customButtons: this.customButtons, 31 | details: true 32 | }); 33 | 34 | this.initialized = true; 35 | 36 | Dashboard.Utils.emit('widget|ready|' + this.name); 37 | 38 | this.ready(); 39 | 40 | Dashboard.Utils.emit('widget|render|' + this.name); 41 | 42 | this.subscribe(); 43 | }, 44 | 45 | render: function() { 46 | Dashboard.render.widget(this.name, this.shell.tpl); 47 | 48 | this.fetch(); 49 | 50 | $('#widget-' + this.shell.id).css({ 51 | 'height': '240px', 52 | 'margin-bottom': '10px', 53 | 'overflow-x': 'hidden', 54 | 'width': '100%' 55 | }).html( this.template({ 56 | name: this.data.name, 57 | role: this.data.role, 58 | id: this.data.id 59 | }) ); 60 | 61 | this.postRender(); 62 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 63 | }, 64 | }; 65 | 66 | var widget = _.extend({}, widgetRoot, extended); 67 | 68 | // register presence with screen manager 69 | Dashboard.addWidget(widget); 70 | }; 71 | -------------------------------------------------------------------------------- /samples/cakeshop/js/widgets/user.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(id) { 3 | var extended = { 4 | title: 'Users', 5 | size: 'small', 6 | widgetId: id, 7 | 8 | hideLink: true, 9 | 10 | template: _.template('
' + 11 | '' + 12 | '' + 13 | '' + 14 | '
Name <%= name %>
Role <%= role %>
ID <%=id%>
'), 15 | 16 | 17 | init: function(data) { 18 | Dashboard.Utils.emit('widget|init|' + this.name); 19 | 20 | if (data) { 21 | this.setData(data); 22 | } 23 | 24 | this.shell = Dashboard.TEMPLATES.widget({ 25 | name: this.name, 26 | title: this.title, 27 | size: this.size, 28 | hideLink: this.hideLink, 29 | hideRefresh: this.hideRefresh, 30 | customButtons: this.customButtons, 31 | details: true 32 | }); 33 | 34 | this.initialized = true; 35 | 36 | Dashboard.Utils.emit('widget|ready|' + this.name); 37 | 38 | this.ready(); 39 | 40 | Dashboard.Utils.emit('widget|render|' + this.name); 41 | 42 | this.subscribe(); 43 | }, 44 | 45 | render: function() { 46 | Dashboard.render.widget(this.name, this.shell.tpl); 47 | 48 | this.fetch(); 49 | 50 | $('#widget-' + this.shell.id).css({ 51 | 'height': '240px', 52 | 'margin-bottom': '10px', 53 | 'overflow-x': 'hidden', 54 | 'width': '100%' 55 | }).html( this.template({ 56 | name: this.data.name, 57 | role: this.data.role, 58 | id: this.data.id 59 | }) ); 60 | 61 | this.postRender(); 62 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 63 | }, 64 | }; 65 | 66 | var widget = _.extend({}, widgetRoot, extended); 67 | 68 | // register presence with screen manager 69 | Dashboard.addWidget(widget); 70 | }; 71 | -------------------------------------------------------------------------------- /docs/demo/js/widgets/info.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(id) { 3 | var extended = { 4 | name: 'info', 5 | title: 'Info', 6 | size: 'medium', 7 | widgetId: id, //needed for dashboard 8 | 9 | hideLink: true, 10 | 11 | template: _.template('
' + 12 | '' + 13 | '' + 14 | '' + 15 | '' + 16 | '
App Name <%= app %>
# of Users <%= numUser %>
URL <%= url %>
Description <%=desc%>
'), 17 | 18 | init: function(data) { 19 | Dashboard.Utils.emit('widget|init|' + this.name); 20 | 21 | if (data) { 22 | this.setData(data); 23 | } 24 | 25 | this.shell = Dashboard.TEMPLATES.widget({ 26 | name: this.name, 27 | title: this.title, 28 | size: this.size, 29 | hideLink: this.hideLink, 30 | hideRefresh: this.hideRefresh, 31 | customButtons: this.customButtons, 32 | details: true 33 | }); 34 | 35 | this.initialized = true; 36 | 37 | Dashboard.Utils.emit('widget|ready|' + this.name); 38 | 39 | this.ready(); 40 | 41 | Dashboard.Utils.emit('widget|render|' + this.name); 42 | 43 | this.subscribe(); 44 | }, 45 | 46 | 47 | render: function() { 48 | Dashboard.render.widget(this.name, this.shell.tpl); 49 | this.fetch(); 50 | 51 | $('#widget-' + this.shell.id).css({ 52 | 'height': '240px', 53 | 'margin-bottom': '10px', 54 | 'overflow-x': 'hidden', 55 | 'width': '100%' 56 | }).html( this.template({ 57 | app: this.data.appName, 58 | desc: this.data.description, 59 | numUser: this.data.numUser, 60 | url: this.data.url 61 | }) ); 62 | 63 | this.postRender(); 64 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 65 | }, 66 | }; 67 | 68 | 69 | var widget = _.extend({}, widgetRoot, extended); 70 | 71 | // register presence with screen manager 72 | Dashboard.addWidget(widget); 73 | }; 74 | -------------------------------------------------------------------------------- /samples/cakeshop/js/widgets/info.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(id) { 3 | var extended = { 4 | name: 'info', 5 | title: 'Info', 6 | size: 'medium', 7 | widgetId: id, //needed for dashboard 8 | 9 | hideLink: true, 10 | 11 | template: _.template('
' + 12 | '' + 13 | '' + 14 | '' + 15 | '' + 16 | '
App Name <%= app %>
# of Users <%= numUser %>
URL <%= url %>
Description <%=desc%>
'), 17 | 18 | init: function(data) { 19 | Dashboard.Utils.emit('widget|init|' + this.name); 20 | 21 | if (data) { 22 | this.setData(data); 23 | } 24 | 25 | this.shell = Dashboard.TEMPLATES.widget({ 26 | name: this.name, 27 | title: this.title, 28 | size: this.size, 29 | hideLink: this.hideLink, 30 | hideRefresh: this.hideRefresh, 31 | customButtons: this.customButtons, 32 | details: true 33 | }); 34 | 35 | this.initialized = true; 36 | 37 | Dashboard.Utils.emit('widget|ready|' + this.name); 38 | 39 | this.ready(); 40 | 41 | Dashboard.Utils.emit('widget|render|' + this.name); 42 | 43 | this.subscribe(); 44 | }, 45 | 46 | 47 | render: function() { 48 | Dashboard.render.widget(this.name, this.shell.tpl); 49 | this.fetch(); 50 | 51 | $('#widget-' + this.shell.id).css({ 52 | 'height': '240px', 53 | 'margin-bottom': '10px', 54 | 'overflow-x': 'hidden', 55 | 'width': '100%' 56 | }).html( this.template({ 57 | app: this.data.appName, 58 | desc: this.data.description, 59 | numUser: this.data.numUser, 60 | url: this.data.url 61 | }) ); 62 | 63 | this.postRender(); 64 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 65 | }, 66 | }; 67 | 68 | 69 | var widget = _.extend({}, widgetRoot, extended); 70 | 71 | // register presence with screen manager 72 | Dashboard.addWidget(widget); 73 | }; 74 | -------------------------------------------------------------------------------- /docs/demo/js/widgets/widget-root.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Widget template. 3 | * 4 | * Loading flow: 5 | * 1. Register in a section for displaying 6 | * 2. Widget is pulled down 7 | * 3. addWidget called on screenManager 8 | * 4. screenManager calls widget.init 9 | * 5. widget.setData is called by widget.init 10 | * 6. widget.initialized is toggled 11 | * 7. widget.ready is called by widget.init 12 | * 8. widget.render is called by widget.init 13 | * 9. widget.fetch is called by widget.render 14 | * 10. widget.postRender is called by widget.render 15 | * 11. widget.subscribe is called by widget.init 16 | */ 17 | 18 | window.widgetRoot = { 19 | hideLink: false, 20 | hideRefresh: false, 21 | 22 | initialized: false, 23 | 24 | ready: function() { 25 | this.render(); 26 | }, 27 | 28 | setData: function(data) { 29 | this.data = data; 30 | }, 31 | 32 | fetch: function() { 33 | this.postFetch(); 34 | }, 35 | 36 | postFetch: function() { }, 37 | 38 | subscribe: function() { }, 39 | 40 | init: function(data) { 41 | Dashboard.Utils.emit('widget|init|' + this.name); 42 | 43 | if (data) { 44 | this.setData(data); 45 | } 46 | 47 | this.shell = Dashboard.TEMPLATES.widget({ 48 | name: this.name, 49 | title: this.title, 50 | size: this.size, 51 | hideLink: this.hideLink, 52 | hideRefresh: this.hideRefresh, 53 | customButtons: this.customButtons 54 | }); 55 | 56 | this.initialized = true; 57 | 58 | Dashboard.Utils.emit('widget|ready|' + this.name); 59 | 60 | this.ready(); 61 | 62 | Dashboard.Utils.emit('widget|render|' + this.name); 63 | 64 | this.subscribe(); 65 | }, 66 | 67 | render: function() { 68 | Dashboard.render.widget(this.name, this.shell.tpl); 69 | 70 | this.fetch(); 71 | 72 | $('#widget-' + this.shell.id).css({ 73 | 'height': '240px', 74 | 'margin-bottom': '10px', 75 | 'overflow-x': 'hidden', 76 | 'width': '100%' 77 | }); 78 | 79 | this.postRender(); 80 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 81 | }, 82 | 83 | refresh: function() { 84 | 85 | }, 86 | 87 | postRender: function() { }, 88 | }; 89 | -------------------------------------------------------------------------------- /samples/cakeshop/js/widgets/widget-root.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Widget template. 3 | * 4 | * Loading flow: 5 | * 1. Register in a section for displaying 6 | * 2. Widget is pulled down 7 | * 3. addWidget called on screenManager 8 | * 4. screenManager calls widget.init 9 | * 5. widget.setData is called by widget.init 10 | * 6. widget.initialized is toggled 11 | * 7. widget.ready is called by widget.init 12 | * 8. widget.render is called by widget.init 13 | * 9. widget.fetch is called by widget.render 14 | * 10. widget.postRender is called by widget.render 15 | * 11. widget.subscribe is called by widget.init 16 | */ 17 | 18 | window.widgetRoot = { 19 | hideLink: false, 20 | hideRefresh: false, 21 | 22 | initialized: false, 23 | 24 | ready: function() { 25 | this.render(); 26 | }, 27 | 28 | setData: function(data) { 29 | this.data = data; 30 | }, 31 | 32 | fetch: function() { 33 | this.postFetch(); 34 | }, 35 | 36 | postFetch: function() { }, 37 | 38 | subscribe: function() { }, 39 | 40 | init: function(data) { 41 | Dashboard.Utils.emit('widget|init|' + this.name); 42 | 43 | if (data) { 44 | this.setData(data); 45 | } 46 | 47 | this.shell = Dashboard.TEMPLATES.widget({ 48 | name: this.name, 49 | title: this.title, 50 | size: this.size, 51 | hideLink: this.hideLink, 52 | hideRefresh: this.hideRefresh, 53 | customButtons: this.customButtons 54 | }); 55 | 56 | this.initialized = true; 57 | 58 | Dashboard.Utils.emit('widget|ready|' + this.name); 59 | 60 | this.ready(); 61 | 62 | Dashboard.Utils.emit('widget|render|' + this.name); 63 | 64 | this.subscribe(); 65 | }, 66 | 67 | render: function() { 68 | Dashboard.render.widget(this.name, this.shell.tpl); 69 | 70 | this.fetch(); 71 | 72 | $('#widget-' + this.shell.id).css({ 73 | 'height': '240px', 74 | 'margin-bottom': '10px', 75 | 'overflow-x': 'hidden', 76 | 'width': '100%' 77 | }); 78 | 79 | this.postRender(); 80 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 81 | }, 82 | 83 | refresh: function() { 84 | 85 | }, 86 | 87 | postRender: function() { }, 88 | }; 89 | -------------------------------------------------------------------------------- /samples/widget-template.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | widget = function() { 4 | var extended = { 5 | name: 'widget-id', 6 | title: 'Widget Name That Appears on it', 7 | size: 'small', // 'small', 'medium', 'large', 'third' 8 | 9 | url: 'api/block/test', 10 | topic: '/topic/block', 11 | 12 | hideLink: true, 13 | hideRefresh: true, 14 | 15 | initialized: false, 16 | 17 | template: _.template('
    '+ // internal template 18 | '
  • List item 1
  • '+ 19 | '
  • List item 2
  • '+ 20 | '
  • List item 2
  • '+ 21 | '
  • List item 2
  • '+ 22 | '
'), 23 | 24 | ready: function() { 25 | this.render(); 26 | }, 27 | 28 | setData: function(data) { 29 | this.data = data; 30 | }, 31 | 32 | fetch: function() { 33 | this.postFetch(); 34 | }, 35 | 36 | postFetch: function() { }, 37 | 38 | subscribe: function() { }, 39 | 40 | init: function(data) { 41 | Dashboard.Utils.emit('widget|init|' + this.name); 42 | 43 | if (data) { 44 | this.setData(data); 45 | } 46 | 47 | this.shell = Dashboard.TEMPLATES.widget({ 48 | name: this.name, 49 | title: this.title, 50 | size: this.size, 51 | hideLink: this.hideLink, 52 | hideRefresh: this.hideRefresh, 53 | customButtons: this.customButtons 54 | }); 55 | 56 | this.initialized = true; 57 | 58 | Dashboard.Utils.emit('widget|ready|' + this.name); 59 | 60 | this.ready(); 61 | 62 | Dashboard.Utils.emit('widget|render|' + this.name); 63 | 64 | this.subscribe(); 65 | }, 66 | 67 | render: function() { 68 | Dashboard.render.widget(this.name, this.shell.tpl); 69 | 70 | this.fetch(); 71 | 72 | $('#widget-' + this.shell.id).css({ 73 | 'height': '240px', 74 | 'margin-bottom': '10px', 75 | 'overflow-x': 'hidden', 76 | 'width': '100%' 77 | }); 78 | 79 | this.postRender(); 80 | $(document).trigger("WidgetInternalEvent", ["widget|rendered|" + this.name]); 81 | }, 82 | 83 | postRender: function() { // executed when placing on screen 84 | $('#widget-' + this.shell.id).html(this.template({})); 85 | $('#widget-' + this.shell.id + ' button').click(this._handler); 86 | }, 87 | 88 | }; 89 | 90 | 91 | var widget = _.extend({}, widgetRoot, extended); 92 | 93 | // register presence with screen manager 94 | Dashboard.addWidget(widget); 95 | }; 96 | -------------------------------------------------------------------------------- /jif-landing-page/css/prism.css: -------------------------------------------------------------------------------- 1 | /* http://prismjs.com/download.html?themes=prism-okaidia&languages=markup+css+clike+javascript */ 2 | /** 3 | * okaidia theme for JavaScript, CSS and HTML 4 | * Loosely based on Monokai textmate theme by http://www.monokai.nl/ 5 | * @author ocodia 6 | */ 7 | 8 | code[class*="language-"], 9 | pre[class*="language-"] { 10 | color: #f8f8f2; 11 | background: none; 12 | text-shadow: 0 1px rgba(0, 0, 0, 0.3); 13 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 14 | text-align: left; 15 | white-space: pre; 16 | word-spacing: normal; 17 | word-break: normal; 18 | word-wrap: normal; 19 | line-height: 1.5; 20 | 21 | -moz-tab-size: 4; 22 | -o-tab-size: 4; 23 | tab-size: 4; 24 | 25 | -webkit-hyphens: none; 26 | -moz-hyphens: none; 27 | -ms-hyphens: none; 28 | hyphens: none; 29 | } 30 | 31 | /* Code blocks */ 32 | pre[class*="language-"] { 33 | padding: 1em; 34 | margin: .5em 0; 35 | overflow: auto; 36 | border-radius: 0.3em; 37 | } 38 | 39 | :not(pre) > code[class*="language-"], 40 | pre[class*="language-"] { 41 | background: #272822; 42 | } 43 | 44 | /* Inline code */ 45 | :not(pre) > code[class*="language-"] { 46 | padding: .1em; 47 | border-radius: .3em; 48 | white-space: normal; 49 | } 50 | 51 | .token.comment, 52 | .token.prolog, 53 | .token.doctype, 54 | .token.cdata { 55 | color: slategray; 56 | } 57 | 58 | .token.punctuation { 59 | color: #f8f8f2; 60 | } 61 | 62 | .namespace { 63 | opacity: .7; 64 | } 65 | 66 | .token.property, 67 | .token.tag, 68 | .token.constant, 69 | .token.symbol, 70 | .token.deleted { 71 | color: #f92672; 72 | } 73 | 74 | .token.boolean, 75 | .token.number { 76 | color: #ae81ff; 77 | } 78 | 79 | .token.selector, 80 | .token.attr-name, 81 | .token.string, 82 | .token.char, 83 | .token.builtin, 84 | .token.inserted { 85 | color: #a6e22e; 86 | } 87 | 88 | .token.operator, 89 | .token.entity, 90 | .token.url, 91 | .language-css .token.string, 92 | .style .token.string, 93 | .token.variable { 94 | color: #f8f8f2; 95 | } 96 | 97 | .token.atrule, 98 | .token.attr-value, 99 | .token.function { 100 | color: #e6db74; 101 | } 102 | 103 | .token.keyword { 104 | color: #66d9ef; 105 | } 106 | 107 | .token.regex, 108 | .token.important { 109 | color: #fd971f; 110 | } 111 | 112 | .token.important, 113 | .token.bold { 114 | font-weight: bold; 115 | } 116 | .token.italic { 117 | font-style: italic; 118 | } 119 | 120 | .token.entity { 121 | cursor: help; 122 | } 123 | 124 | -------------------------------------------------------------------------------- /widget-root.js: -------------------------------------------------------------------------------- 1 | /* 2 | Loading Flow 3 | ------------ 4 | 1. Add widget to a section for displaying 5 | 2. Widget is registered 6 | 3. addWidget in dashboard-core is called from the widget 7 | 4. Dashboard calls widget.init 8 | 5. widget.setData is called by widget.init 9 | 6. widget.ready is called by widget.init 10 | 7. widget.render is called by widget.init 11 | 8. widget.fetch is called by widget.render 12 | 9. widget.postRender is called by widget.render 13 | 10. widget.subscribe is called by widget.init 14 | */ 15 | 16 | window.widgetRoot = { 17 | hideLink: false, 18 | hideRefresh: false, 19 | refreshOnStart: false, 20 | 21 | initialized: false, 22 | 23 | ready: function() { 24 | this.render(); 25 | }, 26 | 27 | setData: function(data) { 28 | this.data = data; 29 | }, 30 | 31 | fetch: function() { 32 | this.postFetch(); 33 | }, 34 | 35 | postFetch: function() { }, 36 | 37 | subscribe: function() { }, 38 | 39 | init: function(data) { 40 | Dashboard.Utils.emit('widget|init|' + this.name); 41 | 42 | if (data) { 43 | this.setData(data); 44 | } 45 | 46 | this.shell = Dashboard.TEMPLATES.widget({ 47 | name: this.name, 48 | title: this.title, 49 | size: this.size, 50 | hideLink: this.hideLink, 51 | hideRefresh: this.hideRefresh, 52 | customButtons: this.customButtons 53 | }); 54 | 55 | this.initialized = true; 56 | 57 | Dashboard.Utils.emit('widget|ready|' + this.name); 58 | 59 | this.ready(); 60 | 61 | Dashboard.Utils.emit('widget|render|' + this.name); 62 | 63 | this.subscribe(); 64 | 65 | // Tag the widget with appropriate service 66 | if(data.service) { 67 | $('#widget-shell-' + this.shell.id).data('service', data.service); 68 | } else { 69 | $('#widget-shell-' + this.shell.id).data('service', '_common'); 70 | } 71 | }, 72 | 73 | render: function() { 74 | Dashboard.render.widget(this.name, this.shell.tpl); 75 | 76 | this.fetch(); 77 | 78 | $('#widget-' + this.shell.id).css({ 79 | 'height': '240px', 80 | 'margin-bottom': '10px', 81 | 'overflow-x': 'hidden', 82 | 'width': '100%' 83 | }); 84 | 85 | this.postRender(); 86 | $(document).trigger('WidgetInternalEvent', ['widget|rendered|' + this.name]); 87 | }, 88 | 89 | _$: function(id) { 90 | if (id !== undefined) { 91 | return $('#widget-' + this.shell.id).find(id); 92 | } else { 93 | return $('#widget-' + this.shell.id); 94 | } 95 | }, 96 | 97 | postRender: function() { }, 98 | 99 | refresh: _.debounce(function() { 100 | this.fetch(); 101 | }, 100), 102 | }; 103 | -------------------------------------------------------------------------------- /docs/demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sample // Dashboard 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 | 40 |
41 |
42 | 43 | 61 | 62 |
63 |
64 |
65 |
66 |
67 | Console 68 |
69 | 70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /samples/cakeshop/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sample // Dashboard 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 | 40 |
41 |
42 | 43 | 61 | 62 |
63 |
64 |
65 |
66 |
67 | Console 68 |
69 | 70 |
71 |
72 |
73 | 74 |
75 |
76 |
77 |
78 | 79 | 80 |

81 | 82 | 83 |

84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /dashboard.css: -------------------------------------------------------------------------------- 1 | /*@import url('https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css'); 2 | @import url('https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css'); 3 | @import url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css');*/ 4 | @import url('https://fonts.googleapis.com/css?family=Roboto+Condensed'); 5 | 6 | .panel { 7 | box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); 8 | border-radius: 0 !important; 9 | position: relative; 10 | /*-webkit-transition: all .2s linear;*/ 11 | } 12 | 13 | .panel-close { 14 | -webkit-transform: scale3d(0, 0, 0); 15 | transform: scale3d(0, 0, 0); 16 | } 17 | 18 | .panel-body { 19 | position: relative; 20 | height: 250px; 21 | } 22 | 23 | .panel-heading { 24 | background: white !important; 25 | border-radius: 0; 26 | padding: 15px; 27 | border-bottom: 0 !important; 28 | } 29 | 30 | .panel-heading .panel-title { 31 | font-family: 'Roboto Condensed', "Helvetica Neue", Helvetica, Arial, sans-serif; 32 | text-transform: uppercase; 33 | font-weight: 600; 34 | font-size: 13px; 35 | color: #515d6e; 36 | 37 | width: 85%; 38 | text-overflow: ellipsis; 39 | white-space: nowrap; 40 | overflow: hidden; 41 | } 42 | 43 | .overlay { 44 | position: absolute; 45 | top: 0; 46 | left: 0; 47 | right: 0; 48 | bottom: 0; 49 | z-index: 1001; 50 | background: rgba(255, 255, 255, 0.75); 51 | text-align: center; 52 | } 53 | 54 | .overlay:before { 55 | content: ""; 56 | height: 100%; 57 | vertical-align: middle; 58 | width: 1px; 59 | display: inline-block; 60 | margin-left: -5px; 61 | } 62 | 63 | .overlay .overlay-content { 64 | display: inline-block; 65 | vertical-align: middle; 66 | } 67 | 68 | .overlay i { 69 | display: block; 70 | position: inline-block; 71 | vertical-align: middle; 72 | color: black; 73 | } 74 | 75 | .panel-action { 76 | list-style: none; 77 | display: inline-block; 78 | float: right; 79 | font-size: 13px; 80 | margin-top: -15px; 81 | } 82 | 83 | .panel-action li { 84 | display: inline-block; 85 | color: #515d6e; 86 | margin: 0 5px; 87 | cursor: pointer; 88 | } 89 | 90 | .is-dragging, .is-positioning-post-drag { 91 | z-index: 200; /* keep dragged item on top */ 92 | } 93 | 94 | .packery-drop-placeholder { 95 | z-index: 0; 96 | outline: 3px dashed #CCC; 97 | outline-offset: -15px; 98 | transition: transform 0.2s; 99 | } 100 | 101 | .ui-draggable-dragging { 102 | z-index: 2; 103 | } 104 | 105 | 106 | .ui-resizable-handle { 107 | right: 12px; 108 | z-index: 90; 109 | bottom: 17px; 110 | opacity: 0.1; 111 | } 112 | 113 | .ui-resizable-handle:hover { 114 | opacity: 1; 115 | } 116 | 117 | .widget-collapse { 118 | height: 45px !important; 119 | margin-bottom: 18px; 120 | } 121 | 122 | .back-panel-collapse { 123 | height: 45px !important; 124 | margin-bottom: 18px; 125 | box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26) !important; 126 | overflow: hidden; 127 | } 128 | -------------------------------------------------------------------------------- /docs/demo/js/index.js: -------------------------------------------------------------------------------- 1 | import 'bootstrap'; 2 | import 'd3'; 3 | import 'jquery-ui'; 4 | import moment from 'moment'; 5 | 6 | 7 | import 'jif-dashboard/dashboard.css'; 8 | 9 | import 'jif-dashboard/dashboard-core'; 10 | import 'jif-dashboard/dashboard-util'; 11 | import 'jif-dashboard/dashboard-template'; 12 | 13 | // import this first because it sets a global all the rest of the widgets need 14 | import './widgets/widget-root'; 15 | 16 | 17 | window.Tower = { 18 | ready: false, 19 | current: null, 20 | status: {}, 21 | 22 | // Tower Control becomes ready only after the first status is received from the server 23 | isReady: function() { 24 | Tower.ready = true; 25 | 26 | // let everyone listening in know 27 | Dashboard.Utils.emit('tower-control|ready|true'); 28 | 29 | return true; 30 | }, 31 | 32 | 33 | init: function() { 34 | //set options for the Dashboard 35 | Dashboard.setOptions({ 36 | 'appName': 'sample-dashboard' 37 | }); 38 | 39 | //initialize the Dashboard, set up widget container 40 | Dashboard.init() 41 | 42 | Dashboard.preregisterWidgets({ 43 | 'info': require('./widgets/info'), 44 | 'form': require('./widgets/form'), 45 | 'misc': require('./widgets/misc'), 46 | 'date': require('./widgets/date'), 47 | 'controls': require('./widgets/controls'), 48 | 'weather': require('./widgets/weather') 49 | }); 50 | 51 | //open first section - console 52 | Tower.section['console'](); 53 | }, 54 | 55 | //define the sections 56 | section: { 57 | 'console': function() { 58 | // data that the widgets will use 59 | var data = { 60 | 'numUser': 4, 61 | 'appName': 'sample app', 62 | 'url': 'hello.com', 63 | 'description': 'this is a description of the app.' 64 | } 65 | 66 | // the array of widgets that belong to the section, 67 | // these were preregistered in init() because they are unique 68 | var widgets = [ 69 | { widgetId: 'date' }, 70 | { widgetId: 'controls' }, 71 | { widgetId: 'weather' }, 72 | { widgetId: 'info' , data: data}, //data can be passed in 73 | { widgetId: 'form' }, 74 | { widgetId: 'misc' }, 75 | ]; 76 | 77 | // opens the section and pass in the widgets that it needs 78 | Dashboard.showSection('console', widgets); 79 | }, 80 | 81 | // a section using same widget template for multiple widgets 82 | 'users': function() { 83 | // define the data 84 | var userlist = { 85 | 'user1': { 86 | 'name' : 'Admin', 87 | 'role' : 'admin', 88 | 'id' : 123 89 | }, 90 | 'user2': { 91 | 'name' : 'Developer', 92 | 'role' : 'developer', 93 | 'id' : 456 94 | }, 95 | 'user3': { 96 | 'name' : 'Data Scientist', 97 | 'role' : 'data scientist', 98 | 'id' : 789 99 | }, 100 | 'user4': { 101 | 'name' : 'QA', 102 | 'role' : 'qa', 103 | 'id' : 101 104 | } 105 | } 106 | 107 | var widgets = []; 108 | // iterate over the data, creating a new widget for each item 109 | _.each(userlist, function(user, key) { 110 | var widget = {}; 111 | widget[key + '-user'] = require('./widgets/user.js'); 112 | Dashboard.preregisterWidgets(widget); 113 | 114 | widgets = widgets.concat([{ 115 | widgetId: key + '-user', 116 | data: user 117 | }]) 118 | }) 119 | 120 | Dashboard.showSection('users', widgets); 121 | } 122 | } 123 | }; 124 | 125 | 126 | 127 | $(function() { 128 | $(window).on('scroll', function(e) { 129 | if ($(window).scrollTop() > 50) { 130 | $('body').addClass('sticky'); 131 | } else { 132 | $('body').removeClass('sticky'); 133 | } 134 | }); 135 | 136 | // Resetting dashboard 137 | $('#reset').on('click', function() { 138 | Dashboard.reset(); 139 | }) 140 | 141 | // Navigation menu handler 142 | $('.tower-sidebar li').click(function(e) { 143 | var id = $(this).attr('id'); 144 | 145 | e.preventDefault(); 146 | 147 | Tower.current = id; 148 | 149 | $('.tower-sidebar li').removeClass('active'); 150 | $(this).addClass('active'); 151 | 152 | Tower.section[Tower.current](); 153 | 154 | $('.tower-page-title').html( $('', { html: $(this).find('.tower-sidebar-item').html() }) ); 155 | }); 156 | 157 | // ---------- INIT ----------- 158 | Tower.init(); 159 | 160 | // Setting 'Console' as first section 161 | $('.tower-sidebar li').first().click(); 162 | }); 163 | -------------------------------------------------------------------------------- /samples/cakeshop/js/index.js: -------------------------------------------------------------------------------- 1 | import 'bootstrap'; 2 | import 'd3'; 3 | import 'jquery-ui'; 4 | import moment from 'moment'; 5 | 6 | import 'dashboard-framework/dashboard-core'; 7 | import 'dashboard-framework/dashboard-util'; 8 | import 'dashboard-framework/dashboard-template'; 9 | 10 | // import this first because it sets a global all the rest of the widgets need 11 | import './widgets/widget-root'; 12 | 13 | window.Tower = { 14 | ready: false, 15 | current: null, 16 | status: {}, 17 | 18 | // Tower Control becomes ready only after the first status is received from the server 19 | isReady: function() { 20 | Tower.ready = true; 21 | 22 | // let everyone listening in know 23 | Dashboard.Utils.emit('tower-control|ready|true'); 24 | 25 | return true; 26 | }, 27 | 28 | 29 | init: function() { 30 | //set options for the Dashboard 31 | Dashboard.setOptions({ 32 | 'appName': 'sample-dashboard' 33 | }); 34 | 35 | //initialize the Dashboard, set up widget container 36 | Dashboard.init() 37 | 38 | Dashboard.preregisterWidgets({ 39 | 'info' : require('./widgets/info'), 40 | 'form' : require('./widgets/form'), 41 | 'misc' : require('./widgets/misc'), 42 | 'date' : require('./widgets/date'), 43 | 'controls' : require('./widgets/controls'), 44 | 'weather' : require('./widgets/weather') 45 | }); 46 | 47 | //open first section - console 48 | Tower.section['console'](); 49 | }, 50 | 51 | //define the sections 52 | section: { 53 | 'console': function() { 54 | // data that the widgets will use 55 | var data = { 56 | 'numUser': 4, 57 | 'appName': 'sample app', 58 | 'url': 'hello.com', 59 | 'description': 'this is a description of the app.' 60 | } 61 | 62 | // the array of widgets that belong to the section, 63 | // these were preregistered in init() because they are unique 64 | var widgets = [ 65 | { widgetId: 'date' }, 66 | { widgetId: 'controls' }, 67 | { widgetId: 'weather' }, 68 | { widgetId: 'info' , data: data}, //data can be passed in 69 | { widgetId: 'form' }, 70 | { widgetId: 'misc' }, 71 | ]; 72 | 73 | // opens the section and pass in the widgets that it needs 74 | Dashboard.showSection('console', widgets); 75 | }, 76 | 77 | // a section using same widget template for multiple widgets 78 | 'users': function() { 79 | 80 | // define the data 81 | var userlist = { 82 | 'user1': { 83 | 'name' : 'Admin', 84 | 'role' : 'admin', 85 | 'id' : 123 86 | }, 87 | 'user2': { 88 | 'name' : 'Developer', 89 | 'role' : 'developer', 90 | 'id' : 456 91 | }, 92 | 'user3': { 93 | 'name' : 'Data Scientist', 94 | 'role' : 'data scientist', 95 | 'id' : 789 96 | }, 97 | 'user4': { 98 | 'name' : 'QA', 99 | 'role' : 'qa', 100 | 'id' : 101 101 | } 102 | } 103 | 104 | var widgets = []; 105 | //iterate over the data, creating a new widget for each item 106 | _.each(userlist, function(user, key) { 107 | var widget = {}; 108 | widget[key + '-user'] = require('./widgets/user.js'); 109 | Dashboard.preregisterWidgets(widget); 110 | 111 | widgets = widgets.concat([{ 112 | widgetId: key + '-user', 113 | data: user 114 | }]) 115 | }) 116 | 117 | Dashboard.showSection('users', widgets); 118 | } 119 | }, 120 | 121 | 122 | debug: function(message) { 123 | var _ref; 124 | return typeof window !== 'undefined' && window !== null ? (_ref = window.console) !== null ? _ref.log(message) : void 0 : void 0; 125 | } 126 | }; 127 | 128 | 129 | 130 | $(function() { 131 | $(window).on('scroll', function(e) { 132 | if ($(window).scrollTop() > 50) { 133 | $('body').addClass('sticky'); 134 | } else { 135 | $('body').removeClass('sticky'); 136 | } 137 | }); 138 | 139 | // logo handler 140 | $("a.tower-logo").click(function(e) { 141 | e.preventDefault(); 142 | $("#console").click(); 143 | }); 144 | 145 | // Menu (burger) handler 146 | $('.tower-toggle-btn').on('click', function() { 147 | $('.tower-logo-container').toggleClass('tower-nav-min'); 148 | $('.tower-sidebar').toggleClass('tower-nav-min'); 149 | $('.tower-body-wrapper').toggleClass('tower-nav-min'); 150 | }); 151 | 152 | $('#reset').on('click', function() { 153 | Dashboard.reset(); 154 | }) 155 | 156 | // Navigation menu handler 157 | $('.tower-sidebar li').click(function(e) { 158 | var id = $(this).attr('id'); 159 | 160 | e.preventDefault(); 161 | 162 | Tower.current = id; 163 | 164 | $('.tower-sidebar li').removeClass('active'); 165 | $(this).addClass('active'); 166 | 167 | Tower.section[Tower.current](); 168 | 169 | $('.tower-page-title').html( $('', { html: $(this).find('.tower-sidebar-item').html() }) ); 170 | 171 | }); 172 | 173 | // ---------- INIT ----------- 174 | Tower.init(); 175 | 176 | // Setting 'Console' as first section 177 | $('.tower-sidebar li').first().click(); 178 | }); 179 | -------------------------------------------------------------------------------- /samples/cakeshop/css/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Cakeshop // Dashboard 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 |
23 | 41 |
42 |
43 | 44 | 98 | 99 | 100 | 101 |
102 |
103 |
104 |
105 |
106 | Console 107 |
108 | 109 |
110 |
111 |
112 | 113 | Node Status 114 | 115 | Refreshing 116 | 117 |
118 |
119 | 120 |
121 |
122 | 123 | Peers 124 | 125 | - 126 | 127 |
128 |
129 | 130 |
131 |
132 | 133 | Blocks 134 | 135 | - 136 | 137 |
138 |
139 | 140 |
141 |
142 | 143 | Queued Transactions 144 | 145 | - 146 | 147 |
148 |
149 | 150 |
151 | 152 |
153 |
154 |
155 | 156 |
157 |
158 |
159 |
160 | 161 | 162 |

163 | 164 | 165 |

166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /jif-landing-page/css/stylesheet.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Start Bootstrap - Stylish Portfolio (http://startbootstrap.com/) 3 | * Copyright 2013-2016 Start Bootstrap 4 | * Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap/blob/gh-pages/LICENSE) 5 | */ 6 | 7 | /* Global Styles */ 8 | 9 | html, 10 | body { 11 | width: 100%; 12 | height: 100%; 13 | } 14 | 15 | body { 16 | font-family: "Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif; 17 | } 18 | 19 | p { 20 | font-size: 20px; 21 | } 22 | 23 | hr { 24 | width: 100px; 25 | } 26 | 27 | .text-vertical-center { 28 | display: table-cell; 29 | text-align: center; 30 | vertical-align: middle; 31 | } 32 | 33 | .text-vertical-center h1 { 34 | margin: 0; 35 | padding: 0; 36 | font-size: 9.5em; 37 | font-weight: 600; 38 | } 39 | 40 | .text-center h1 { 41 | margin: 0; 42 | padding: 0; 43 | font-size: 4.5em; 44 | font-weight: 600; 45 | } 46 | 47 | .docs-container h2 { 48 | margin: 0; 49 | padding: 0; 50 | font-size: 3.5em; 51 | font-weight: 500; 52 | margin-bottom: 15px; 53 | } 54 | 55 | .info-section { 56 | display: table; 57 | width: 100%; 58 | height: 400px; 59 | color: #fff; 60 | /*background: url(../img/callout.jpg) no-repeat center center scroll;*/ 61 | -webkit-background-size: cover; 62 | -moz-background-size: cover; 63 | background-size: cover; 64 | -o-background-size: cover; 65 | padding-top: 25px; 66 | padding-bottom: 25px; 67 | } 68 | 69 | .info-section h1 { 70 | margin: 0; 71 | padding: 0; 72 | font-size: 4.5em; 73 | font-weight: 600; 74 | } 75 | 76 | /* Custom Button Styles */ 77 | 78 | .btn-dark { 79 | border-radius: 0; 80 | color: #fff; 81 | background-color: rgba(0,0,0,0.4); 82 | } 83 | 84 | .btn-dark:hover, 85 | .btn-dark:focus, 86 | .btn-dark:active { 87 | color: #fff; 88 | background-color: rgba(0,0,0,0.7); 89 | } 90 | 91 | .btn-light { 92 | border-radius: 0; 93 | color: #333; 94 | background-color: rgb(255,255,255); 95 | } 96 | 97 | .btn-light:hover, 98 | .btn-light:focus, 99 | .btn-light:active { 100 | color: #333; 101 | background-color: rgba(255,255,255,0.8); 102 | } 103 | 104 | /* Custom Horizontal Rule */ 105 | 106 | hr.small { 107 | max-width: 100px; 108 | } 109 | 110 | .toggle { 111 | margin: 5px 5px 0 0; 112 | } 113 | 114 | /* Header */ 115 | 116 | .header { 117 | display: table; 118 | position: relative; 119 | width: 100%; 120 | height: 100%; 121 | /*background: url(../img/bg.jpg) no-repeat center center scroll;*/ 122 | background-color: #1b435b; 123 | color: white; 124 | -webkit-background-size: cover; 125 | -moz-background-size: cover; 126 | background-size: cover; 127 | -o-background-size: cover; 128 | } 129 | 130 | /* About */ 131 | 132 | .about { 133 | padding: 50px 0; 134 | } 135 | 136 | /* Services */ 137 | 138 | .services { 139 | padding: 50px 0; 140 | } 141 | 142 | .service-item { 143 | margin-bottom: 30px; 144 | } 145 | 146 | /* Callout */ 147 | 148 | #quickstart { 149 | display: table; 150 | width: 100%; 151 | height: 400px; 152 | color: #fff; 153 | background-color: #7d6969; 154 | /*background: url(../img/callout.jpg) no-repeat center center scroll;*/ 155 | -webkit-background-size: cover; 156 | -moz-background-size: cover; 157 | background-size: cover; 158 | -o-background-size: cover; 159 | padding-top: 25px; 160 | padding-bottom: 25px; 161 | } 162 | 163 | /* Portfolio */ 164 | 165 | #portfolio { 166 | background-color: #c6ccc7; 167 | } 168 | 169 | .portfolio { 170 | padding: 50px 0; 171 | } 172 | 173 | .portfolio-item { 174 | margin-bottom: 30px; 175 | } 176 | 177 | .img-portfolio { 178 | margin: 0 auto; 179 | } 180 | 181 | .img-portfolio:hover { 182 | opacity: 0.8; 183 | } 184 | 185 | /* Call to Action */ 186 | 187 | .call-to-action { 188 | padding: 50px 0; 189 | } 190 | 191 | .call-to-action .btn { 192 | margin: 10px; 193 | } 194 | 195 | /* Footer */ 196 | 197 | footer { 198 | padding: 100px 0; 199 | } 200 | 201 | #to-top { 202 | display: none; 203 | position: fixed; 204 | bottom: 5px; 205 | right: 5px; 206 | border-radius: 25px; 207 | } 208 | 209 | /* Code blocks */ 210 | pre { 211 | width: 100%; 212 | } 213 | 214 | code[class*="language-"], pre[class*="language-"] { 215 | tab-size: 1; 216 | } 217 | 218 | .center-code { 219 | margin: 0px 28%; 220 | } 221 | 222 | #getting-started { 223 | display: table; 224 | width: 100%; 225 | height: 400px; 226 | color: #fff; 227 | background: url(../img/callout.jpg) no-repeat center center scroll; 228 | -webkit-background-size: cover; 229 | -moz-background-size: cover; 230 | background-size: cover; 231 | -o-background-size: cover; 232 | padding-top: 25px; 233 | padding-bottom: 25px; 234 | } 235 | 236 | .docs-container { 237 | padding-left: 15%; 238 | padding-right: 15%; 239 | } 240 | 241 | .docs-container .center-code { 242 | margin: 0px 18%; 243 | } 244 | 245 | #docs-label { 246 | display: table; 247 | width: 100%; 248 | height: 200px; 249 | color: black; 250 | background-color: #fff; 251 | } 252 | 253 | .navbar-default { 254 | opacity: .5; 255 | transition: opacity .3s ease; 256 | } 257 | 258 | .navbar-default:hover { 259 | opacity: .8; 260 | transition: opacity .3s ease; 261 | } 262 | 263 | .navbar-inverse { 264 | background-color: #321b0f; 265 | } 266 | 267 | p code { 268 | background-color: rgba(249, 242, 244, 0.64); 269 | } 270 | #html-docs { 271 | background-color: #9898ce 272 | } 273 | 274 | #widget { 275 | background-color: #b7475b; 276 | } 277 | 278 | #section-docs { 279 | background-color: #8c9e87; 280 | } 281 | 282 | #options { 283 | background-color: #e8aeae; 284 | } 285 | 286 | #utils { 287 | background-color: #479889; 288 | } 289 | 290 | #links a { 291 | color: white; 292 | } 293 | 294 | .logo { 295 | height: 50px; 296 | } 297 | -------------------------------------------------------------------------------- /jif-landing-page/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | JIF Dashboard 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 | 34 | 35 | 60 | 61 | 62 |
63 |
64 |

JIF Dashboard

65 |

JPMorgan Interface Framework

66 |
67 | Learn more 68 |
69 |
70 | 71 | 72 |
73 |
74 |
75 |
76 |

JIF is a dashboard framework to quickly build widget-based dashboards.

77 |
78 |

It supports sections built out of widgets using a packery grid.

79 |
80 |
81 | 82 |
83 | 84 |
85 | 86 | 87 |
88 |
89 |

Quickstart

90 |

It's easy to get started with JIF through npm.

91 |
92 |

Add dashboard-framework to your project's package.json file:

93 |
 94 | 				
 95 | 					"dependencies": {
 96 | 						...
 97 | 						"jif-dashboard": "^1.0.0",
 98 | 						...
 99 | 					}
100 | 				
101 | 			

102 | 103 |

Then import or require the JIF Dashboard files. For example, in index.js,

104 |
105 | 				
106 | 					import 'jif-dashboard/dashboard-core'
107 | 					import 'jif-dashboard/dashboard-util'
108 | 					import 'jif-dashboard/dashboard-template'
109 | 				
110 | 			

111 |
112 |
113 | 114 | 115 |
116 |
117 |
118 |
119 |

Built with JIF Dashboard

120 |
121 |
122 |
123 |
124 | 125 |
126 |
127 |
128 |
129 | 130 |
131 |
132 |
133 |
134 | 135 |
136 | 137 |
138 | 139 |
140 | 141 | 142 | 143 | 181 | 182 | 183 |
184 |
185 |
186 |
187 |

JIF Dashboard 188 |

189 |

Emerging Technologies

190 |
191 |
    192 |
  • 193 | 194 |
  • 195 |
196 |
197 |

Copyright © JPMorgan Chase 2016

198 |
199 |
200 |
201 | 202 |
203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 259 | 260 | 261 | -------------------------------------------------------------------------------- /jif-landing-page/js/prism.js: -------------------------------------------------------------------------------- 1 | /* http://prismjs.com/download.html?themes=prism-okaidia&languages=markup+css+clike+javascript */ 2 | var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-(\w+)\b/i,t=0,n=_self.Prism={util:{encode:function(e){return e instanceof a?new a(e.type,n.util.encode(e.content),e.alias):"Array"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(v instanceof a)){u.lastIndex=0;var b=u.exec(v),k=1;if(!b&&h&&m!=r.length-1){if(u.lastIndex=y,b=u.exec(e),!b)break;for(var w=b.index+(c?b[1].length:0),_=b.index+b[0].length,A=m,P=y,x=r.length;x>A&&_>P;++A)P+=r[A].length,w>=P&&(++m,y=P);if(r[m]instanceof a||r[A-1].greedy)continue;k=A-m,v=e.slice(y,P),b.index-=y}if(b){c&&(f=b[1].length);var w=b.index+f,b=b[0].slice(f),_=w+b.length,O=v.slice(0,w),S=v.slice(_),j=[m,k];O&&j.push(O);var N=new a(l,g?n.tokenize(b,g):b,d,b,h);j.push(N),S&&j.push(S),Array.prototype.splice.apply(r,j)}}}}}return r},hooks:{all:{},add:function(e,t){var a=n.hooks.all;a[e]=a[e]||[],a[e].push(t)},run:function(e,t){var a=n.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(t)}}},a=n.Token=function(e,t,n,a,r){this.type=e,this.content=t,this.alias=n,this.length=0|(a||"").length,this.greedy=!!r};if(a.stringify=function(e,t,r){if("string"==typeof e)return e;if("Array"===n.util.type(e))return e.map(function(n){return a.stringify(n,t,e)}).join("");var i={type:e.type,content:a.stringify(e.content,t,r),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===n.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}n.hooks.run("wrap",i);var o="";for(var s in i.attributes)o+=(o?" ":"")+s+'="'+(i.attributes[s]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'"'+(o?" "+o:"")+">"+i.content+""},!_self.document)return _self.addEventListener?(_self.addEventListener("message",function(e){var t=JSON.parse(e.data),a=t.language,r=t.code,i=t.immediateClose;_self.postMessage(n.highlight(r,n.languages[a],a)),i&&_self.close()},!1),_self.Prism):_self.Prism;var r=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return r&&(n.filename=r.src,document.addEventListener&&!r.hasAttribute("data-manual")&&("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(n.highlightAll):window.setTimeout(n.highlightAll,16):document.addEventListener("DOMContentLoaded",n.highlightAll))),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); 3 | Prism.languages.markup={comment://,prolog:/<\?[\w\W]+?\?>/,doctype://i,cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/[=>"']/}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Prism.languages.xml=Prism.languages.markup,Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup; 4 | Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*?(?=\s*\{)/,string:{pattern:/("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.util.clone(Prism.languages.css),Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/()[\w\W]*?(?=<\/style>)/i,lookbehind:!0,inside:Prism.languages.css,alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag)); 5 | Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:{pattern:/(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/}; 6 | Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,"function":/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*\*?|\/|~|\^|%|\.{3}/}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\\\|\\?[^\\])*?`/,greedy:!0,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/()[\w\W]*?(?=<\/script>)/i,lookbehind:!0,inside:Prism.languages.javascript,alias:"language-javascript"}}),Prism.languages.js=Prism.languages.javascript; 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JIF Dashboard 2 | A dashboard framework to quickly build widget-based dashboards with. 3 | 4 | Supports sections built out of widgets using a packery grid. Check out the `Samples` folder for a starting template. 5 | 6 | ## Demo 7 | [See live demo here](https://jpmorganchase.github.io/jif-dashboard/demo/) 8 | 9 | ## Quickstart 10 | Using npm and webpack 11 | 12 | ### npm 13 | Add jif-dashboard and dependencies to the `package.json` file: 14 | 15 | ```JSON 16 | "dependencies": { 17 | "jquery": "^3.0.0", 18 | "jquery-ui-dist": "^1.12.1", 19 | "jif-dashboard": "^1.0.0", 20 | } 21 | ``` 22 | 23 | ### Webpack 24 | Import the files into CSS and JS files: 25 | 26 | For example, in `index.js` 27 | ```javascript 28 | // must have css loader 29 | import 'jif-dashboard/dashboard.css' 30 | 31 | import 'jif-dashboard/dashboard-core' 32 | import 'jif-dashboard/dashboard-util' 33 | import 'jif-dashboard/dashboard-template' 34 | ``` 35 | 36 | If you would like to use a loader such as babel, include jif-dashboard in `webpack.config.js`. Add appropriate dependencies in `package.json`. 37 | 38 | module:{ 39 | loaders:[ 40 | { 41 | ... 42 | include: [ 43 | path.resolve(__dirname, "node_modules/jif-dashboard") 44 | ], 45 | loader: 'babel', 46 | ... 47 | } 48 | ] 49 | } 50 | 51 | JIF has several front styling dependencies: 52 | 53 | ```HTML 54 | 55 | 56 | 57 | ``` 58 | 59 | ## How to Use 60 | 61 | ### General Flow 62 | 63 | #### Initialize the grid 64 | Set [Options](#options) and initialize the Dashboard grid with a call to `Dashboard.init()`. This creates the grid that makes up the core of the Dashboard. 65 | 66 | #### Add a widget 67 | Create a widget and pre-register any widgets you want with `Dashboard.preregisterWidgets()`. Further details on widget creation and registration are provided in the [Widgets](#widgets) section. 68 | 69 | #### Create a section 70 | Make a new section and add widgets to it. A more detailed overview is in [Sections](#sections). 71 | 72 | ### Widgets 73 | Widgets hold the content of the dashboard. They have various sizes and have the option of being draggable and resizable. They also have various controls: links, refresh, close, and minimize. 74 | 75 | #### `widget-root.js` 76 | It is highly recommended that your widgets extend `widget-root.js`. As seen in the sample app, it is very helpful in helping widgets load smoothly. It provides a structure to your widgets, and any of its methods can be overridden. Place it in the same directory as your widgets. 77 | 78 | #### Creating a Widget 79 | Make a new directory called `widgets` to hold your widgets. The path should be `js/widgets/`. If you need to use a different path, override the Dashboard.registerWidget function. 80 | 81 | Create a widget using `widget-template.js` in `/samples` for reference. The widget filename should be the same as `widgetId`. For example, a widget with an id of widget1 should be in a file named `widget1.js`. There is also another reference id `name`. If this value is not set in widgets, then it will be set to `widgetId`. This represents the internals of the widget - such as tables, charts, input fields, or anything else that represents your data. 82 | 83 | The outer shell of widgets is created by `dashboard-template.js` and accessed through the `init()` function in each widget. Options are passed with `Dashboard.TEMPLATES.widget()`, such as name, title, and size. The `widget-shell-id`, a randomly generated id number for internal widget handling. The template can be overridden with a custom template by creating a new file and setting `Dashboard.TEMPLATES = require('custom-template.js');`. 84 | 85 | You may explicitly register the widgets or leave it to be dynamically loaded by [section](#sections). 86 | 87 | **To register the widget yourself**: 88 | 89 | ```javascript 90 | // a file such as index.js 91 | 92 | Dashboard.preregisterWidgets({ 93 | 'widget1' : require('./widgets/widget1'), 94 | 'widget2' : require('./widgets/widget2'), 95 | 'widget3' : require('./widgets/widget3'), 96 | // etc 97 | }); 98 | ``` 99 | 100 | #### Widget Options 101 | 102 | **title**: (string) The title to be displayed for the widget. 103 | 104 | **size**: (string) In order of increasing size - 'small', 'third', 'medium', or 'large'. The default is small. 105 | 106 | **customButtons**: (string html) Use this to add custom html buttons to the header of the widget. The default is an empty string. 107 | 108 | **hideLink**: (boolean) Whether or not a link icon will show up on the header of the widget. Clicking the link icon will copy a link to the widget to the clipboard. The default is false. 109 | 110 | **hideRefresh**: (boolean) Whether a refresh icon will show up on the widget header. Clicking the icon will cause the widget to refresh by fetching. The default is false. 111 | 112 | **refreshOnStart**: (boolean) Whether the widget will refresh after it is loaded. This option is helpful if resize and storage are on and you have something in the widget body whose size depends on the widget, as it will ensure that everything is sized correctly. 113 | 114 | **name**: (string) This is used internally and must be unique. 115 | 116 | **widgetId**: (string) If you do not set a name, then you must have a widgetId. This can be set or passed through when registering widgets. 117 | 118 | ```javascript 119 | // widget1.js 120 | 121 | module.exports = function(id) { 122 | var extended = { 123 | widgetId: id, // id is passed from registering widget 124 | name: 'mywidget', 125 | title: 'My Widget', 126 | size: 'medium', 127 | hideLink: true, 128 | hidRefresh: false, 129 | customButtons: '
  • ', 130 | // ... 131 | } 132 | var widget = _.extend({}, widgetRoot, extended); 133 | 134 | // register presence with screen manager 135 | Dashboard.addWidget(widget); 136 | }; 137 | ``` 138 | 139 | #### Loading flow 140 | This is a walkthrough of how the widget is loaded. The earlier steps may vary depending on how you registered your widgets: 141 | 142 | 1. Add widget to a section for displaying 143 | 2. Widget is registered 144 | 3. `addWidget` in dashboard-core is called from the widget 145 | 4. Dashboard calls `widget.init` 146 | 5. `widget.setData` is called by `widget.init` 147 | 6. `widget.ready` is called by `widget.init` 148 | 7. `widget.render` is called by `widget.init` 149 | 8. `widget.fetch` is called by `widget.render` 150 | 9. `widget.postRender` is called by `widget.render` 151 | 10. `widget.subscribe` is called by `widget.init` 152 | 153 | ### Sections 154 | Dashboards may have many sections. Sections are used to group widgets and as a reference to store widget sizes and sort orders. 155 | 156 | Widgets are added to sections to be displayed. This will also register any widgets that you have not explicitly registered yourself: 157 | 158 | ```javascript 159 | 'sectionName': function() { 160 | var widgets = [ 161 | { widgetId: 'widget1' }, 162 | { widgetId: 'widget2' }, 163 | { widgetId: 'widget3' } 164 | ]; 165 | 166 | Dashboard.showSection('sectionName', widgets); 167 | }, 168 | ``` 169 | 170 | ### Options 171 | There are a few options you can use with the framework. Required settings are `appName` and `widgetContainer`. 172 | 173 | The defaults are: 174 | 175 | ```javascript 176 | settings: { 177 | appName: 'cakeshop', 178 | widgetContainer: '#grounds', 179 | resize: true, 180 | drag: true, 181 | storage: true, 182 | minWidth: 200, 183 | minHeight: 250 184 | } 185 | ``` 186 | 187 | Set the options with `Dashboard.setOptions()` and pass in the settings you wish to change. 188 | 189 | **appName**: (string) The name of your application 190 | 191 | **widgetContainer**: (string) The id for the container that will hold your widgets. 192 | 193 | **resize**: (boolean) Whether widgets are resizable 194 | 195 | **drag**: (boolean) Whether widgets are draggable 196 | 197 | **storage**: (boolean) Whether dragged locations and resizes are saved to be loaded on refresh/start. This is saved based on the dashboard `section`. 198 | 199 | **minWidth**: (int) The minimum width of a widget. This is only relevant if resizing is on. 200 | 201 | **minHeight**: (int) The minimum height a widget can be resized to. 202 | 203 | ##### The Widget Sizer 204 | As an alternative to minWidth and minHeight, you may specify an element as the widget sizer by adding a class `.widget-sizer` to it. Jif-Dashboard will use the minimum width or height if it is specified in the options, then the widget sizer dimensions, and resort to the default only if nothing is present. 205 | 206 | ### External Functions 207 | Jif Dashboard provides some external functions that may be helpful. 208 | 209 | #####`reset(singleSection)` 210 | If resize, drag, and storage are enabled, reset will cause the widgets to be reset to their original layout. Passing in the boolean `singleSection` is optional. If **true**, it will only reset the current section, and if **false**, every section will be reset. 211 | 212 | #####`removeWidget(shellId)` 213 | This will remove the widget from the grid completely. Requires the widget's shell id, which can be accessed from the widget with `this.shell.id`. 214 | 215 | #####`clear()` 216 | This clears the grid of displayed widgets, but does not remove them from the grid. 217 | 218 | #####`hide(shellId)` 219 | This will hide one widget, but will not remove it from the grid. Requires the widget's shell id, which can be accessed from the widget with `this.shell.id`. 220 | 221 | #####`show(opts)` 222 | This will show the widget if it was hidden. `opts` is an object: `{widgetId: 123456}`, where `widgetId` is the widget's shell id, which can be accessed from the widget with `this.shell.id`. 223 | 224 | ### Utils 225 | A few utils methods are provided in `dashboard-util.js`. 226 | 227 | **emit**: Prints a maintenance message to the console, and triggers a `WidgetInternalEvent` the type of which can be passed into the emit call. This is helpful for triggering other events on the dashboard. 228 | -------------------------------------------------------------------------------- /docs/demo/css/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | background: #f0f0f0; 7 | line-height: normal; 8 | font-size: 16px; 9 | overflow-Y: scroll; 10 | font-family: 'Roboto Condensed', "Helvetica Neue", Helvetica, Arial, sans-serif; 11 | -webkit-font-smoothing: antialiased !important; 12 | } 13 | 14 | a, a:hover, a:visited, a:link, a:active { 15 | text-decoration: none; 16 | } 17 | 18 | a:active { 19 | color: #fff !important; 20 | } 21 | 22 | ::-moz-selection { 23 | background: #5af; 24 | color: #fff; 25 | text-shadow: none; 26 | } 27 | 28 | ::selection { 29 | background: #5af; 30 | color: #fff; 31 | text-shadow: none; 32 | } 33 | 34 | 35 | .settings { 36 | right: 25px; 37 | position: absolute; 38 | bottom: 26px; 39 | font-size: 20px; 40 | } 41 | 42 | .settings:hover { 43 | cursor: pointer; 44 | } 45 | 46 | .settings hr { 47 | margin-top: 8px; 48 | margin-bottom: 8px; 49 | } 50 | 51 | .settings h4 { 52 | margin-top: 4px; 53 | margin-bottom: 4px; 54 | text-align: center; 55 | } 56 | 57 | .settings li { 58 | margin: 12px; 59 | } 60 | 61 | .settings > .dropdown-toggle { 62 | margin-right: 8px; 63 | } 64 | 65 | .dropdown-menu { 66 | border-radius: 0px; 67 | margin-top: 8px; 68 | } 69 | 70 | .dropdown-arrow { 71 | height: 5px; 72 | background-color: #333; 73 | margin-top: -5px; 74 | margin-bottom: 8px; 75 | } 76 | 77 | .arrow-up { 78 | width: 0px; 79 | height: 0px; 80 | border-left: 8px solid transparent; 81 | border-right: 8px solid transparent; 82 | border-bottom: 8px solid #333; 83 | position: absolute; 84 | right: 8px; 85 | top: -8px; 86 | } 87 | 88 | 89 | .tower-page-title { 90 | margin-bottom: 20px; 91 | } 92 | 93 | .tower-page-title span { 94 | font-size: 30px; 95 | font-weight: 500; 96 | display: block; 97 | } 98 | 99 | .tower-navigation { 100 | position: fixed; 101 | left: 0; 102 | right: 0; 103 | top: 0; 104 | box-shadow: 0 0px 9px 4px rgba(0, 0, 0, 0.1), 0 -5px 2px 2px 105 | rgba(0, 0, 0, 0.1); 106 | background: white; 107 | z-index: 10000; 108 | text-align: center; 109 | } 110 | 111 | .tower-navigation ul { 112 | margin-bottom: 0; 113 | } 114 | 115 | .tower-logo-hidden { 116 | line-height: 75px; 117 | font-weight: 900; 118 | text-transform: uppercase; 119 | font-size: 22px; 120 | text-decoration: none; 121 | color: #222533; 122 | opacity: 0; 123 | visibility: hidden; 124 | position: absolute; 125 | left: 50%; 126 | -webkit-transition: all .2s ease-in-out; 127 | transition: all .2s ease-in-out; 128 | } 129 | 130 | .links { 131 | margin-right: 10px; 132 | position: relative; 133 | } 134 | 135 | .links>li { 136 | list-style: none; 137 | position: relative; 138 | margin: 10px; 139 | display: inline-block; 140 | } 141 | 142 | .lg-text { 143 | font-size: 13px; 144 | font-weight: 600; 145 | color: #333; 146 | } 147 | 148 | .sm-text { 149 | font-size: 11px; 150 | color: #c6c6c6; 151 | } 152 | 153 | .md-text { 154 | font-size: 12px; 155 | color: #c6c6c6; 156 | } 157 | 158 | .tower-logo-container { 159 | /*width: 225px;*/ 160 | text-align: center; 161 | height: 50px; 162 | float: left; 163 | -webkit-transition: all .2s ease-in-out; 164 | transition: all .2s ease-in-out; 165 | } 166 | 167 | .tower-toggle-btn, .tower-logo { 168 | text-decoration: none; 169 | position: relative; 170 | height: 50px; 171 | line-height: 50px; 172 | padding: 0 15px; 173 | font-size: 22px; 174 | font-weight: 900; 175 | text-transform: uppercase; 176 | text-decoration: none; 177 | color: #222533; 178 | display: inline-block; 179 | } 180 | 181 | .tower-logo i { 182 | padding-top: 2px; 183 | vertical-align: middle; 184 | margin-right: 10px; 185 | } 186 | 187 | .tower-toggle-btn:hover { 188 | background: #f9f9f9; 189 | } 190 | 191 | .sm-menu { 192 | min-width: 150px !important; 193 | } 194 | 195 | .sm-menu>li { 196 | padding: 10px; 197 | text-align: left; 198 | } 199 | 200 | .sm-menu>li i { 201 | margin: 0 10px 0 0; 202 | } 203 | 204 | .sm-menu>li>a { 205 | padding: 10px; 206 | } 207 | 208 | .hide { 209 | display: none; 210 | } 211 | 212 | .tower-sidebar { 213 | z-index: 9999; 214 | position: fixed; 215 | font-weight: 600; 216 | background: white !important; 217 | width: 225px; 218 | height: 100vh; 219 | top: 50px; 220 | left: 0; 221 | bottom: 0; 222 | box-shadow: 0 0 4px rgba(0, 0, 0, 0.14), 2px 4px 8px rgba(0, 0, 0, 0.28); 223 | -webkit-transition: all .2s ease-in-out; 224 | transition: all .2s ease-in-out; 225 | } 226 | 227 | .tower-sidebar li { 228 | text-align: left; 229 | height: 45px; 230 | font-size: 14px; 231 | font-weight: 500; 232 | letter-spacing: .025em; 233 | line-height: 1.5; 234 | } 235 | 236 | .tower-sidebar li a { 237 | text-decoration: none; 238 | display: block; 239 | color: #515d6e; 240 | } 241 | 242 | .tower-sidebar li a i { 243 | position: relative; 244 | width: 45px; 245 | line-height: 45px; 246 | text-align: center; 247 | } 248 | 249 | .tower-sidebar li a i:before { 250 | z-index: 10; 251 | position: relative; 252 | } 253 | 254 | .tower-sidebar li a>span { 255 | display: inline-block; 256 | visibility: visible; 257 | opacity: 1; 258 | padding-left: 10px; 259 | -webkit-transition: all .2s ease-in-out .2s; 260 | -webkit-transform: translate3d(0, 0, 0); 261 | transform: translate3d(0, 0, 0); 262 | text-transform: uppercase; 263 | font-size: 15px; 264 | } 265 | 266 | .tower-sidebar li:hover, .tower-sidebar li.active { 267 | background: #f2f2f2; 268 | } 269 | 270 | .tower-sidebar li:hover .icon-bg, .tower-sidebar li.active .icon-bg { 271 | -webkit-transform: translate3d(0, 0, 0); 272 | transform: translate3d(0, 0, 0); 273 | } 274 | 275 | .tower-sidebar li:hover a>i, .tower-sidebar li.active a>i { 276 | color: white; 277 | } 278 | 279 | .icon-bg { 280 | position: absolute; 281 | left: 0; 282 | top: 0; 283 | bottom: 0; 284 | z-index: 1; 285 | width: 100%; 286 | -webkit-transform: translate3d(-43px, 0, 0); 287 | transform: translate3d(-43px, 0, 0); 288 | -webkit-transition: all .2s ease-in-out; 289 | transition: all .2s ease-in-out; 290 | } 291 | 292 | .tower-txt-primary { 293 | color: #1C7EBB; 294 | } 295 | 296 | .tower-sidebar li:nth-child(5n+1) .icon-bg { 297 | background: #23AE89; 298 | } 299 | 300 | .tower-sidebar li:nth-child(5n+2) .icon-bg { 301 | background: #E94B3B; 302 | } 303 | 304 | .tower-sidebar li:nth-child(5n+3) .icon-bg { 305 | background: #1C7EBB; 306 | } 307 | 308 | .tower-sidebar li:nth-child(5n+4) .icon-bg { 309 | background: #F98E33; 310 | } 311 | 312 | .tower-sidebar li:nth-child(5n+5) .icon-bg { 313 | background: #6A55C2; 314 | } 315 | 316 | .tower-bg-primary { 317 | background: #1C7EBB; 318 | } 319 | 320 | .tower-txt-success { 321 | color: #23AE89; 322 | } 323 | 324 | .tower-bg-success { 325 | background: #23AE89; 326 | } 327 | 328 | .tower-txt-danger { 329 | color: #E94B3B; 330 | } 331 | 332 | .tower-bg-danger { 333 | background: #E94B3B; 334 | } 335 | 336 | .tower-txt-warning { 337 | color: #F98E33; 338 | } 339 | 340 | .tower-bg-warning { 341 | background: #F98E33; 342 | } 343 | 344 | .tower-txt-violet { 345 | color: #6A55C2; 346 | } 347 | 348 | .tower-bg-violet { 349 | background: #6A55C2; 350 | } 351 | 352 | .tower-bg-crimson { 353 | background: crimson; 354 | } 355 | 356 | .tower-bg-teal { 357 | background: #1fb5ad; 358 | } 359 | 360 | .tower-bg-orange { 361 | background: #ff503f; 362 | } 363 | 364 | .tower-bg-purple { 365 | background: #4c2673; 366 | } 367 | 368 | .tower-bg-twitter { 369 | background: #55acee; 370 | } 371 | 372 | .tower-logo-container.tower-nav-min { 373 | -webkit-transform: translate3d(-180px, 0, 0); 374 | transform: translate3d(-180px, 0, 0); 375 | } 376 | 377 | .tower-logo-container.tower-nav-min .tower-logo { 378 | opacity: 0; 379 | } 380 | 381 | .tower-logo-container.tower-nav-min+.tower-logo-hidden { 382 | opacity: 1; 383 | visibility: visible; 384 | } 385 | 386 | .tower-sidebar.tower-nav-min { 387 | width: 45px !important; 388 | } 389 | 390 | .tower-sidebar.tower-nav-min .tower-sidebar-item { 391 | opacity: 0; 392 | visibility: hidden; 393 | -webkit-transition: all .1s linear; 394 | -webkit-transform: translate3d(-200px, 0, 0); 395 | transform: translate3d(-200px, 0, 0); 396 | } 397 | 398 | .tower-sidebar.tower-nav-min .icon-bg { 399 | -webkit-transform: translate3d(0, 0, 0); 400 | transform: translate3d(0, 0, 0); 401 | } 402 | 403 | .tower-sidebar.tower-nav-min i { 404 | border: 0px; 405 | color: white; 406 | -webkit-transition: all .2s linear; 407 | transition: all .2s linear; 408 | } 409 | 410 | .tower-sidebar.tower-nav-min li:hover .icon-bg { 411 | -webkit-transform: scale(1.2, 1); 412 | -ms-transform: scale(1.2, 1); 413 | transform: scale(1.2, 1); 414 | } 415 | 416 | .tower-body-wrapper { 417 | position: absolute; 418 | left: 230px; 419 | top: 75px; 420 | width: auto; 421 | right: 0; 422 | -webkit-transition: all .2s ease-in-out; 423 | transition: all .2s ease-in-out; 424 | } 425 | 426 | .tower-body-wrapper.tower-nav-min { 427 | left: 50px; 428 | } 429 | 430 | @media screen and (max-width: 450px) { 431 | .tower-nugget i { 432 | opacity: .3; 433 | } 434 | } 435 | 436 | @media screen and (min-width: 850px) { 437 | .tower-logo-container { 438 | height: 75px; 439 | } 440 | .tower-logo-container .tower-logo { 441 | line-height: 75px; 442 | } 443 | .tower-logo-container .tower-toggle-btn { 444 | line-height: 75px; 445 | height: auto; 446 | } 447 | .tower-sidebar { 448 | top: 75px; 449 | } 450 | .tower-body-wrapper { 451 | top: 100px; 452 | } 453 | } 454 | 455 | @media screen and (max-width: 850px) { 456 | .tower-navigation { 457 | height: 100px; 458 | } 459 | .tower-logo-container.tower-nav-min { 460 | -webkit-transform: translate3d(0, 0, 0); 461 | transform: translate3d(0, 0, 0); 462 | background: transparent; 463 | } 464 | .tower-logo-container.tower-nav-min .tower-logo { 465 | opacity: 1; 466 | } 467 | .tower-logo-container.tower-nav-min+.tower-logo-hidden { 468 | display: none; 469 | } 470 | .tower-logo-container { 471 | display: block; 472 | float: none; 473 | width: 100%; 474 | border-bottom: 1px solid #F2F2F2; 475 | } 476 | .tower-sidebar { 477 | top: 100px; 478 | } 479 | .tower-sidebar.tower-nav-min { 480 | -webkit-transform: translate3d(-200px, 0, 0); 481 | transform: translate3d(-200px, 0, 0); 482 | } 483 | .tower-body-wrapper { 484 | top: 125px; 485 | position: relative; 486 | } 487 | .tower-body-wrapper.tower-nav-min { 488 | left: 0px; 489 | } 490 | } 491 | 492 | 493 | 494 | /* sample widget styling */ 495 | 496 | .slow-spin { 497 | -webkit-animation: fa-spin 20s infinite linear; 498 | animation: fa-spin 20s infinite linear; 499 | } 500 | 501 | .user-info { 502 | display: inline-block; 503 | margin-left: 4%; 504 | } 505 | 506 | .user-info li { 507 | padding-bottom: 10%; 508 | } 509 | 510 | .slow-spin { 511 | -webkit-animation: fa-spin 20s infinite linear; 512 | animation: fa-spin 20s infinite linear; 513 | } 514 | 515 | .date-container { 516 | padding-top: 8%; 517 | text-align: center; 518 | font-weight: bolder; 519 | font-size: 60px; 520 | color: #6ea9dc; 521 | } 522 | 523 | .weather-container { 524 | font-size: 200px; 525 | color: #e4d165; 526 | text-align: center; 527 | } 528 | 529 | .controls-container .btn{ 530 | width: 100%; 531 | margin-bottom: 5px; 532 | margin-top: 5px; 533 | } 534 | 535 | .controls-container i { 536 | padding-right: 5px; 537 | } 538 | -------------------------------------------------------------------------------- /samples/cakeshop/css/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Roboto Condensed'; 3 | font-style: normal; 4 | font-weight: 400; 5 | src: local('Roboto Condensed'), 6 | local('RobotoCondensed-Regular'), 7 | url(../fonts/roboto.woff2) format('woff2'), 8 | url(../fonts/roboto.woff) format('woff'); 9 | } 10 | 11 | * { 12 | box-sizing: border-box; 13 | } 14 | 15 | body { 16 | background: #f0f0f0; 17 | line-height: normal; 18 | font-size: 16px; 19 | overflow-Y: scroll; 20 | font-family: 'Roboto Condensed', "Helvetica Neue", Helvetica, Arial, sans-serif; 21 | -webkit-font-smoothing: antialiased !important; 22 | } 23 | 24 | a, a:hover, a:visited, a:link, a:active { 25 | text-decoration: none; 26 | } 27 | 28 | a:active { 29 | color: #fff !important; 30 | } 31 | 32 | .sm-img { 33 | height: 30px !important; 34 | width: 30px !important; 35 | } 36 | 37 | ::-moz-selection { 38 | background: #5af; 39 | color: #fff; 40 | text-shadow: none; 41 | } 42 | 43 | ::selection { 44 | background: #5af; 45 | color: #fff; 46 | text-shadow: none; 47 | } 48 | 49 | .settings { 50 | right: 25px; 51 | position: absolute; 52 | bottom: 26px; 53 | font-size: 20px; 54 | } 55 | 56 | .settings:hover { 57 | cursor: pointer; 58 | } 59 | 60 | .settings hr { 61 | margin-top: 8px; 62 | margin-bottom: 8px; 63 | } 64 | 65 | .settings h4 { 66 | margin-top: 4px; 67 | margin-bottom: 4px; 68 | text-align: center; 69 | } 70 | 71 | .settings li { 72 | margin: 12px; 73 | } 74 | 75 | .settings > .dropdown-toggle { 76 | margin-right: 8px; 77 | } 78 | 79 | .dropdown-menu { 80 | border-radius: 0px; 81 | margin-top: 8px; 82 | } 83 | 84 | .dropdown-arrow { 85 | height: 5px; 86 | background-color: #333; 87 | margin-top: -5px; 88 | margin-bottom: 8px; 89 | } 90 | 91 | .arrow-up { 92 | width: 0px; 93 | height: 0px; 94 | border-left: 8px solid transparent; 95 | border-right: 8px solid transparent; 96 | border-bottom: 8px solid #333; 97 | position: absolute; 98 | right: 8px; 99 | top: -8px; 100 | } 101 | 102 | .tower-page-title { 103 | margin-bottom: 20px; 104 | } 105 | 106 | .tower-page-title span { 107 | font-size: 30px; 108 | font-weight: 500; 109 | display: block; 110 | } 111 | 112 | .tower-navigation { 113 | position: fixed; 114 | left: 0; 115 | right: 0; 116 | top: 0; 117 | box-shadow: 0 0px 9px 4px rgba(0, 0, 0, 0.1), 0 -5px 2px 2px 118 | rgba(0, 0, 0, 0.1); 119 | background: white; 120 | z-index: 10000; 121 | text-align: center; 122 | } 123 | 124 | .tower-navigation ul { 125 | margin-bottom: 0; 126 | } 127 | 128 | .tower-logo-hidden { 129 | line-height: 75px; 130 | font-weight: 900; 131 | text-transform: uppercase; 132 | font-size: 22px; 133 | text-decoration: none; 134 | color: #222533; 135 | opacity: 0; 136 | visibility: hidden; 137 | position: absolute; 138 | left: 50%; 139 | -webkit-transition: all .2s ease-in-out; 140 | transition: all .2s ease-in-out; 141 | } 142 | 143 | .links { 144 | margin-right: 10px; 145 | position: relative; 146 | } 147 | 148 | .links>li { 149 | list-style: none; 150 | position: relative; 151 | margin: 10px; 152 | display: inline-block; 153 | } 154 | 155 | .lg-text { 156 | font-size: 13px; 157 | font-weight: 600; 158 | color: #333; 159 | } 160 | 161 | .sm-text { 162 | font-size: 11px; 163 | color: #c6c6c6; 164 | } 165 | 166 | .md-text { 167 | font-size: 12px; 168 | color: #c6c6c6; 169 | } 170 | 171 | .tower-logo-container { 172 | /*width: 225px;*/ 173 | text-align: center; 174 | height: 50px; 175 | float: left; 176 | -webkit-transition: all .2s ease-in-out; 177 | transition: all .2s ease-in-out; 178 | } 179 | 180 | .tower-toggle-btn, .tower-logo { 181 | text-decoration: none; 182 | position: relative; 183 | height: 50px; 184 | line-height: 50px; 185 | padding: 0 15px; 186 | font-size: 22px; 187 | font-weight: 900; 188 | text-transform: uppercase; 189 | text-decoration: none; 190 | color: #222533; 191 | display: inline-block; 192 | } 193 | 194 | .tower-logo i { 195 | padding-top: 2px; 196 | vertical-align: middle; 197 | margin-right: 10px; 198 | } 199 | 200 | .tower-toggle-btn:hover { 201 | background: #f9f9f9; 202 | } 203 | 204 | .sm-menu { 205 | min-width: 150px !important; 206 | } 207 | 208 | .sm-menu>li { 209 | padding: 10px; 210 | text-align: left; 211 | } 212 | 213 | .sm-menu>li i { 214 | margin: 0 10px 0 0; 215 | } 216 | 217 | .sm-menu>li>a { 218 | padding: 10px; 219 | } 220 | 221 | .hide { 222 | display: none; 223 | } 224 | 225 | .tower-sidebar { 226 | z-index: 9999; 227 | position: fixed; 228 | font-weight: 600; 229 | background: white !important; 230 | width: 225px; 231 | height: 100vh; 232 | top: 50px; 233 | left: 0; 234 | bottom: 0; 235 | box-shadow: 0 0 4px rgba(0, 0, 0, 0.14), 2px 4px 8px rgba(0, 0, 0, 0.28); 236 | -webkit-transition: all .2s ease-in-out; 237 | transition: all .2s ease-in-out; 238 | } 239 | 240 | .tower-sidebar li { 241 | text-align: left; 242 | height: 45px; 243 | font-size: 14px; 244 | font-weight: 500; 245 | letter-spacing: .025em; 246 | line-height: 1.5; 247 | } 248 | 249 | .tower-sidebar li a { 250 | text-decoration: none; 251 | display: block; 252 | color: #515d6e; 253 | } 254 | 255 | .tower-sidebar li a i { 256 | position: relative; 257 | width: 45px; 258 | line-height: 45px; 259 | text-align: center; 260 | } 261 | 262 | .tower-sidebar li a i:before { 263 | z-index: 10; 264 | position: relative; 265 | } 266 | 267 | .tower-sidebar li a>span { 268 | display: inline-block; 269 | visibility: visible; 270 | opacity: 1; 271 | padding-left: 10px; 272 | -webkit-transition: all .2s ease-in-out .2s; 273 | -webkit-transform: translate3d(0, 0, 0); 274 | transform: translate3d(0, 0, 0); 275 | text-transform: uppercase; 276 | font-size: 15px; 277 | } 278 | 279 | .tower-sidebar li:hover, .tower-sidebar li.active { 280 | background: #f2f2f2; 281 | } 282 | 283 | .tower-sidebar li:hover .icon-bg, .tower-sidebar li.active .icon-bg { 284 | -webkit-transform: translate3d(0, 0, 0); 285 | transform: translate3d(0, 0, 0); 286 | } 287 | 288 | .tower-sidebar li:hover a>i, .tower-sidebar li.active a>i { 289 | color: white; 290 | } 291 | 292 | .icon-bg { 293 | position: absolute; 294 | left: 0; 295 | top: 0; 296 | bottom: 0; 297 | z-index: 1; 298 | width: 100%; 299 | -webkit-transform: translate3d(-43px, 0, 0); 300 | transform: translate3d(-43px, 0, 0); 301 | -webkit-transition: all .2s ease-in-out; 302 | transition: all .2s ease-in-out; 303 | } 304 | 305 | .tower-txt-primary { 306 | color: #1C7EBB; 307 | } 308 | 309 | .tower-sidebar li:nth-child(5n+1) .icon-bg { 310 | background: #23AE89; 311 | } 312 | 313 | .tower-sidebar li:nth-child(5n+2) .icon-bg { 314 | background: #E94B3B; 315 | } 316 | 317 | .tower-sidebar li:nth-child(5n+3) .icon-bg { 318 | background: #1C7EBB; 319 | } 320 | 321 | .tower-sidebar li:nth-child(5n+4) .icon-bg { 322 | background: #F98E33; 323 | } 324 | 325 | .tower-sidebar li:nth-child(5n+5) .icon-bg { 326 | background: #6A55C2; 327 | } 328 | 329 | .tower-bg-primary { 330 | background: #1C7EBB; 331 | } 332 | 333 | .tower-txt-success { 334 | color: #23AE89; 335 | } 336 | 337 | .tower-bg-success { 338 | background: #23AE89; 339 | } 340 | 341 | .tower-txt-danger { 342 | color: #E94B3B; 343 | } 344 | 345 | .tower-bg-danger { 346 | background: #E94B3B; 347 | } 348 | 349 | .tower-txt-warning { 350 | color: #F98E33; 351 | } 352 | 353 | .tower-bg-warning { 354 | background: #F98E33; 355 | } 356 | 357 | .tower-txt-violet { 358 | color: #6A55C2; 359 | } 360 | 361 | .tower-bg-violet { 362 | background: #6A55C2; 363 | } 364 | 365 | .tower-bg-crimson { 366 | background: crimson; 367 | } 368 | 369 | .tower-bg-teal { 370 | background: #1fb5ad; 371 | } 372 | 373 | .tower-bg-orange { 374 | background: #ff503f; 375 | } 376 | 377 | .tower-bg-purple { 378 | background: #4c2673; 379 | } 380 | 381 | .tower-bg-twitter { 382 | background: #55acee; 383 | } 384 | 385 | .tower-logo-container.tower-nav-min { 386 | -webkit-transform: translate3d(-180px, 0, 0); 387 | transform: translate3d(-180px, 0, 0); 388 | } 389 | 390 | .tower-logo-container.tower-nav-min .tower-logo { 391 | opacity: 0; 392 | } 393 | 394 | .tower-logo-container.tower-nav-min+.tower-logo-hidden { 395 | opacity: 1; 396 | visibility: visible; 397 | } 398 | 399 | .tower-sidebar.tower-nav-min { 400 | width: 45px !important; 401 | } 402 | 403 | .tower-sidebar.tower-nav-min .tower-sidebar-item { 404 | opacity: 0; 405 | visibility: hidden; 406 | -webkit-transition: all .1s linear; 407 | -webkit-transform: translate3d(-200px, 0, 0); 408 | transform: translate3d(-200px, 0, 0); 409 | } 410 | 411 | .tower-sidebar.tower-nav-min .icon-bg { 412 | -webkit-transform: translate3d(0, 0, 0); 413 | transform: translate3d(0, 0, 0); 414 | } 415 | 416 | .tower-sidebar.tower-nav-min i { 417 | border: 0px; 418 | color: white; 419 | -webkit-transition: all .2s linear; 420 | transition: all .2s linear; 421 | } 422 | 423 | .tower-sidebar.tower-nav-min li:hover .icon-bg { 424 | -webkit-transform: scale(1.2, 1); 425 | -ms-transform: scale(1.2, 1); 426 | transform: scale(1.2, 1); 427 | } 428 | 429 | .tower-body-wrapper { 430 | position: absolute; 431 | left: 230px; 432 | top: 75px; 433 | width: auto; 434 | right: 0; 435 | -webkit-transition: all .2s ease-in-out; 436 | transition: all .2s ease-in-out; 437 | } 438 | 439 | .tower-body-wrapper.tower-nav-min { 440 | left: 50px; 441 | } 442 | 443 | .widget-collapse { 444 | height: 45px !important; 445 | margin-bottom: 18px; 446 | } 447 | 448 | .back-panel-collapse { 449 | height: 45px !important; 450 | margin-bottom: 18px; 451 | box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26) !important; 452 | overflow: hidden; 453 | } 454 | 455 | @media screen and (max-width: 450px) { 456 | .tower-nugget i { 457 | opacity: .3; 458 | } 459 | } 460 | 461 | @media screen and (min-width: 850px) { 462 | .tower-logo-container { 463 | height: 75px; 464 | } 465 | .tower-logo-container .tower-logo { 466 | line-height: 75px; 467 | } 468 | .tower-logo-container .tower-toggle-btn { 469 | line-height: 75px; 470 | height: auto; 471 | } 472 | .tower-sidebar { 473 | top: 75px; 474 | } 475 | .tower-body-wrapper { 476 | top: 100px; 477 | } 478 | } 479 | 480 | @media screen and (max-width: 850px) { 481 | .tower-navigation { 482 | height: 100px; 483 | } 484 | .tower-logo-container.tower-nav-min { 485 | -webkit-transform: translate3d(0, 0, 0); 486 | transform: translate3d(0, 0, 0); 487 | background: transparent; 488 | } 489 | .tower-logo-container.tower-nav-min .tower-logo { 490 | opacity: 1; 491 | } 492 | .tower-logo-container.tower-nav-min+.tower-logo-hidden { 493 | display: none; 494 | } 495 | .tower-logo-container { 496 | display: block; 497 | float: none; 498 | width: 100%; 499 | border-bottom: 1px solid #F2F2F2; 500 | } 501 | .tower-sidebar { 502 | top: 100px; 503 | } 504 | .tower-sidebar.tower-nav-min { 505 | -webkit-transform: translate3d(-200px, 0, 0); 506 | transform: translate3d(-200px, 0, 0); 507 | } 508 | .tower-body-wrapper { 509 | top: 125px; 510 | position: relative; 511 | } 512 | .tower-body-wrapper.tower-nav-min { 513 | left: 0px; 514 | } 515 | } 516 | 517 | .panel { 518 | box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); 519 | border-radius: 0 !important; 520 | position: relative; 521 | -webkit-transition: all .2s linear; 522 | } 523 | 524 | .panel-close { 525 | -webkit-transform: scale3d(0, 0, 0); 526 | transform: scale3d(0, 0, 0); 527 | } 528 | 529 | .panel-body { 530 | position: relative; 531 | height: 250px; 532 | } 533 | 534 | .panel-heading { 535 | background: white !important; 536 | border-radius: 0; 537 | padding: 15px; 538 | border-bottom: 0 !important; 539 | } 540 | 541 | .panel-heading .panel-title { 542 | text-transform: uppercase; 543 | font-weight: 600; 544 | font-size: 13px; 545 | color: #515d6e; 546 | 547 | width: 85%; 548 | text-overflow: ellipsis; 549 | white-space: nowrap; 550 | overflow: hidden; 551 | } 552 | 553 | .overlay { 554 | position: absolute; 555 | top: 0; 556 | left: 0; 557 | right: 0; 558 | bottom: 0; 559 | z-index: 1001; 560 | background: rgba(255, 255, 255, 0.75); 561 | text-align: center; 562 | } 563 | 564 | .overlay:before { 565 | content: ""; 566 | height: 100%; 567 | vertical-align: middle; 568 | width: 1px; 569 | display: inline-block; 570 | margin-left: -5px; 571 | } 572 | 573 | .overlay .overlay-content { 574 | display: inline-block; 575 | vertical-align: middle; 576 | } 577 | 578 | .overlay i { 579 | display: block; 580 | position: inline-block; 581 | vertical-align: middle; 582 | color: black; 583 | } 584 | 585 | .panel-action { 586 | list-style: none; 587 | display: inline-block; 588 | float: right; 589 | font-size: 13px; 590 | margin-top: -15px; 591 | } 592 | 593 | .panel-action li { 594 | display: inline-block; 595 | color: #515d6e; 596 | margin: 0 5px; 597 | cursor: pointer; 598 | } 599 | 600 | .tower-nugget { 601 | margin-bottom: 16px; 602 | box-shadow: 1px 1px 2px 0 #CCCCCC; 603 | padding: 20px; 604 | box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); 605 | background: white !important; 606 | } 607 | 608 | .tower-nugget i { 609 | display: block; 610 | background-clip: padding-box; 611 | margin-right: 15px; 612 | height: 60px; 613 | width: 60px; 614 | border-radius: 100%; 615 | line-height: 60px; 616 | text-align: center; 617 | font-size: 4.4em; 618 | position: absolute; 619 | } 620 | 621 | .tower-nugget .value, .tower-nugget .heading { 622 | display: block; 623 | position: relative; 624 | color: #515d6e; 625 | text-align: right; 626 | z-index: 10; 627 | } 628 | 629 | .tower-nugget .heading { 630 | font-size: 1.2em; 631 | font-weight: 300; 632 | text-transform: uppercase; 633 | } 634 | 635 | .tower-nugget .value { 636 | font-size: 2.1em; 637 | font-weight: 600; 638 | margin-top: 5px; 639 | } 640 | 641 | .icon-shadow { 642 | box-shadow: 0 0px 3px 1px rgba(0, 0, 0, 0.26); 643 | } 644 | 645 | .fa-spin { 646 | -webkit-animation: fa-spin .5s infinite linear; 647 | animation: fa-spin .5s infinite linear; 648 | } 649 | 650 | .brand-icon { 651 | font-size: 22px; 652 | height: 50px; 653 | display: inline-block; 654 | float: left; 655 | width: 50px; 656 | background-color: crimson; 657 | text-align: center; 658 | line-height: 50px; 659 | color: white; 660 | font-weight: 700; 661 | -webkit-transition: all .2s linear; 662 | transition: all .2s linear; 663 | margin-left: -230px; 664 | display: none; 665 | } 666 | 667 | .default { 668 | transition: opacity .5s ease-in-out; 669 | } 670 | 671 | .widget-node-control button { 672 | width: 100%; 673 | margin: 2px; 674 | } 675 | 676 | pre { 677 | background-color: inherit; 678 | border: 0px; 679 | padding: 0px; 680 | } 681 | 682 | .is-dragging, .is-positioning-post-drag { 683 | z-index: 200; /* keep dragged item on top */ 684 | } 685 | 686 | .packery-drop-placeholder { 687 | z-index: 0; 688 | outline: 3px dashed #CCC; 689 | outline-offset: -15px; 690 | transition: transform 0.2s; 691 | } 692 | 693 | .ui-draggable-dragging { 694 | z-index: 2; 695 | } 696 | 697 | .ui-resizable-handle { 698 | right: 12px; 699 | z-index: 90; 700 | bottom: 17px; 701 | opacity: 0.1; 702 | } 703 | 704 | .ui-resizable-handle:hover { 705 | opacity: 1; 706 | } 707 | 708 | .version-info { 709 | text-align: center; 710 | font-size: smaller; 711 | } 712 | 713 | .user-pics { 714 | width: 55%; 715 | } 716 | 717 | .user-info { 718 | display: inline-block; 719 | margin-left: 4%; 720 | } 721 | 722 | .user-info li { 723 | padding-bottom: 10%; 724 | } 725 | 726 | .slow-spin { 727 | -webkit-animation: fa-spin 20s infinite linear; 728 | animation: fa-spin 20s infinite linear; 729 | } 730 | 731 | .date-container { 732 | padding-top: 8%; 733 | text-align: center; 734 | font-weight: bolder; 735 | font-size: 60px; 736 | color: #6ea9dc; 737 | } 738 | 739 | .weather-container { 740 | font-size: 200px; 741 | color: #e4d165; 742 | text-align: center; 743 | } 744 | 745 | .controls-container .btn{ 746 | width: 100%; 747 | margin-bottom: 5px; 748 | margin-top: 5px; 749 | } 750 | 751 | .controls-container i { 752 | padding-right: 5px; 753 | } 754 | -------------------------------------------------------------------------------- /docs/demo/css/jquery-ui.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.11.4 - 2016-03-11 2 | * http://jqueryui.com 3 | * Includes: core.css, draggable.css, resizable.css, theme.css 4 | * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px 5 | * Copyright jQuery Foundation and other contributors; Licensed MIT */ 6 | 7 | .ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #aaa;background:#fff;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#ccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;color:#222;font-weight:bold}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #999;background:#dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#212121;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;color:#cd0a0a}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-state-default .ui-icon{background-image:url("images/ui-icons_888888_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url("images/ui-icons_454545_256x240.png")}.ui-state-active .ui-icon{background-image:url("images/ui-icons_454545_256x240.png")}.ui-state-highlight .ui-icon{background-image:url("images/ui-icons_2e83ff_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cd0a0a_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px} -------------------------------------------------------------------------------- /samples/cakeshop/css/jquery-ui.min.css: -------------------------------------------------------------------------------- 1 | /*! jQuery UI - v1.11.4 - 2016-03-11 2 | * http://jqueryui.com 3 | * Includes: core.css, draggable.css, resizable.css, theme.css 4 | * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px 5 | * Copyright jQuery Foundation and other contributors; Licensed MIT */ 6 | 7 | .ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #aaa;background:#fff;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#ccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;color:#222;font-weight:bold}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #999;background:#dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#212121;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;color:#cd0a0a}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-state-default .ui-icon{background-image:url("images/ui-icons_888888_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url("images/ui-icons_454545_256x240.png")}.ui-state-active .ui-icon{background-image:url("images/ui-icons_454545_256x240.png")}.ui-state-highlight .ui-icon{background-image:url("images/ui-icons_2e83ff_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cd0a0a_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px} -------------------------------------------------------------------------------- /dashboard-core.js: -------------------------------------------------------------------------------- 1 | import Packery from 'packery'; 2 | import Draggabilly from 'draggabilly'; 3 | 4 | import 'jquery'; 5 | import 'jquery-ui-dist/jquery-ui.js'; 6 | 7 | import storageAvailable from './storage-available'; 8 | 9 | window.Dashboard = { 10 | // option defaults 11 | settings: { 12 | appName: 'cakeshop', 13 | widgetContainer: '#grounds', 14 | resize: true, 15 | drag: true, 16 | storage: true, 17 | minWidth: 200, 18 | minHeight: 250 19 | }, 20 | 21 | // section to widget mapping 22 | sectionMap: {}, 23 | 24 | // widget id to widget mapping 25 | idMap: {}, 26 | 27 | // widgets that have been queued for load 28 | queued: [], 29 | 30 | // widgets that have been loaded 31 | loaded: {}, 32 | 33 | // init data for widgets 34 | initData: {}, 35 | 36 | // widget id to widget module 37 | widgetDefns: {}, 38 | 39 | setOptions(options) { 40 | if (options.minWidth) { 41 | this.setMinWidth = true; 42 | } 43 | if (options.minHeight) { 44 | this.setMinHeight = true; 45 | } 46 | $.extend(this.settings, options); 47 | }, 48 | 49 | preregisterWidgets(defns) { 50 | Object.assign(this.widgetDefns, defns); 51 | }, 52 | 53 | registerWidget(widgetId) { 54 | var widget = {}; 55 | try{ 56 | widget[widgetId] = require('../../js/widgets/' + widgetId); 57 | } catch (e) { 58 | console.log('path does not exist') 59 | } 60 | 61 | Object.assign(this.widgetDefns, widget); 62 | }, 63 | 64 | // debounced refreshing of the packery layout 65 | refresh: _.debounce(function() { 66 | Dashboard.grid.layout(); 67 | }, 0), 68 | 69 | // DOM anchor for the widget field and packery grid 70 | init: function() { 71 | Dashboard.widgetContainer = $(this.settings.widgetContainer); 72 | //TODO: look into widget sizer vs options for column/row values 73 | Dashboard.grid = new Packery(Dashboard.widgetContainer[0], { 74 | columnWidth: '.widget-sizer', 75 | //rowHeight: '.widget-sizer', 76 | percentPosition: true, 77 | itemSelector: '.widget-shell', 78 | gutter: 0, 79 | }); 80 | 81 | Dashboard.grid.on( 'dragItemPositioned', () => { 82 | const itemElems = Dashboard.grid.getItemElements(), 83 | order = itemElems.map(elem => { 84 | var elemId = $(elem).attr('id').split('-'); 85 | return this.idMap[elemId[elemId.length - 1]].name; 86 | }); 87 | 88 | if (this.settings.drag && this.settings.storage && storageAvailable) { 89 | Dashboard.Utils.emit('options|drag-saved'); 90 | const sortKey = `${Dashboard.settings.appName}:${Dashboard.section}:sort-order`; 91 | window.localStorage[sortKey] = JSON.stringify(order); 92 | } else { 93 | Dashboard.Utils.emit('options|drag-unsaved'); 94 | } 95 | }); 96 | }, 97 | 98 | // Optional module to enforce placement order 99 | render: { 100 | unstub: function(id) { 101 | $('#stub-' + Dashboard.Utils.selectorEscape(id)).remove(); 102 | }, 103 | 104 | stub: function(id) { 105 | var el = $('
    ', { 106 | id: 'stub-' + id, 107 | style: 'display: none;' 108 | }); 109 | 110 | Dashboard.widgetContainer.append(el); 111 | }, 112 | 113 | widget: function(id, el) { 114 | $('#stub-' + Dashboard.Utils.selectorEscape(id)).replaceWith(el); 115 | Dashboard.render.unstub(id); 116 | } 117 | }, 118 | 119 | addWidget: function(widget) { 120 | 121 | if (!widget.name) { 122 | widget.name = widget.widgetId; 123 | } 124 | 125 | // shared injects 126 | widget.init(this.initData[widget.name]); 127 | 128 | // set section widget belongs to 129 | _.each(this.sectionMap, function(val, section) { 130 | _.each(val, function(v) { 131 | if (widget.name == v) { 132 | widget.section = section; 133 | } 134 | }); 135 | }); 136 | 137 | 138 | // to overwrite when the widget starts if we don't want it to render 139 | // right away. 140 | // widget.ready = function() { widget.render(); }; 141 | 142 | this.loaded[widget.name] = widget; 143 | this.idMap[widget.shell.id] = widget; 144 | 145 | this.queued = _.without(this.queued, widget.name); 146 | delete this.initData[widget.name]; 147 | 148 | const shell = document.getElementById('widget-shell-' + widget.shell.id); 149 | 150 | if (this.settings.resize && this.settings.storage && storageAvailable) { 151 | const sizeKey = `${Dashboard.settings.appName}:${Dashboard.section}:sizes`; 152 | 153 | var size = { 154 | 'height': $('#widget-shell-' + widget.shell.id).height(), 155 | 'width': $('#widget-shell-' + widget.shell.id).width(), 156 | 'panelHeight': $('#widget-shell-' + widget.shell.id + ' > .panel').height(), 157 | 'panelWidth': $('#widget-shell-' + widget.shell.id + ' > .panel').width(), 158 | 'contentWidth': $('#widget-' + widget.shell.id).width(), 159 | 'contentHeight': $('#widget-' + widget.shell.id).height(), 160 | }; 161 | 162 | //check if sizes have been saved 163 | if (window.localStorage[sizeKey] != null) { 164 | var sizes = JSON.parse(window.localStorage[sizeKey]); 165 | 166 | //check if size for specific widget is saved 167 | if (sizes[this.idMap[widget.shell.id].name] != undefined) { 168 | Dashboard.Utils.emit('options|load-size|' + widget.name); 169 | 170 | size = sizes[this.idMap[widget.shell.id].name]; 171 | 172 | $('#widget-shell-' + widget.shell.id).width(size['width']).height(size['height']); 173 | $('#widget-shell-' + widget.shell.id + ' > .panel').height(size['panelHeight']).width(size['panelWidth']); 174 | $('#widget-' + widget.shell.id).height(size['contentHeight']).width(size['contentWidth']); 175 | 176 | if(widget.refreshOnStart) { 177 | widget.fetch(); 178 | } 179 | 180 | } else { 181 | sizes[this.idMap[widget.shell.id].name] = size; 182 | window.localStorage.setItem(sizeKey, JSON.stringify(sizes)); 183 | } 184 | } else { 185 | var sizes = {}; 186 | sizes[this.idMap[widget.shell.id].name] = size; 187 | window.localStorage.setItem(sizeKey, JSON.stringify(sizes)); 188 | } 189 | } 190 | 191 | // packery registration, and draggable init 192 | this.grid.appended(shell); 193 | 194 | if (this.settings.drag) { 195 | const draggie = new Draggabilly(shell, { handle: '.panel-heading' }); 196 | this.grid.bindDraggabillyEvents(draggie); 197 | } 198 | 199 | if (this.settings.resize) { 200 | var minHeight, 201 | minWidth; 202 | 203 | if (this.setMinWidth) { 204 | // explicitly set width value 205 | minWidth = this.settings.minWidth; 206 | } else if ($('.widget-sizer').length) { 207 | // no explicitly set width, use sizer 208 | minWidth = $('.widget-sizer').width(); 209 | } else { 210 | // not set, no sizer -> use default 211 | minWidth = this.settings.minWidth; 212 | } 213 | // same for height as for width 214 | if (this.setMinHeight) { 215 | minHeight = this.settings.minHeight; 216 | } else if ($('.widget-sizer').length) { 217 | minHeight = $('.widget-sizer').height(); 218 | } else { 219 | minHeight = this.settings.minHeight; 220 | } 221 | 222 | $('#widget-shell-' + widget.shell.id).resizable({ 223 | minHeight: minHeight, 224 | minWidth: minWidth, 225 | alsoResize: '#widget-shell-' + widget.shell.id + ' > .panel', 226 | grid: [ 5, 5 ], 227 | start: function(event, ui) { 228 | $('#widget-shell-' + widget.shell.id).css('box-sizing', 'content-box'); 229 | }, 230 | resize: function(event, ui) { 231 | /*$('#widget-' + widget.shell.id).css({ 232 | height: ui.size.height - 100, 233 | width: ui.size.width - 35 234 | }); 235 | 236 | $('#widget-shell-' + widget.shell.id).height($('#widget-shell-' + widget.shell.id + ' > .panel').height() + 20); 237 | $('#widget-shell-' + widget.shell.id).width($('#widget-shell-' + widget.shell.id + ' > .panel').width()); 238 | */ 239 | 240 | $('#widget-' + widget.shell.id).css({ 241 | height: ui.size.height - 68, 242 | width: ui.size.width - 5 243 | }); 244 | 245 | $('#widget-shell-' + widget.shell.id).height($('#widget-shell-' + widget.shell.id + ' > .panel').height() + 20); 246 | $('#widget-shell-' + widget.shell.id).width($('#widget-shell-' + widget.shell.id + ' > .panel').width()); 247 | 248 | /* 249 | $('#widget-shell-' + widget.shell.id).height(ui.size.height); 250 | $('#widget-shell-' + widget.shell.id).width(ui.size.width); 251 | 252 | $('#widget-' + widget.shell.id).css({ 253 | // 68 == header 45px + margin-bottom 20px + 3px jitter space 254 | height: ui.size.height - 68, 255 | width: ui.size.width 256 | }); */ 257 | widget.refresh(); 258 | Dashboard.refresh(); 259 | }, 260 | stop: function( event, ui) { 261 | const sizeKey = `${Dashboard.settings.appName}:${Dashboard.section}:sizes`; 262 | 263 | if (Dashboard.settings.storage && storageAvailable && window.localStorage[sizeKey] != null) { 264 | Dashboard.Utils.emit('options|saved-resize|' + widget.name); 265 | 266 | var sizes = JSON.parse(window.localStorage[sizeKey]), 267 | size = { 268 | 'height': $('#widget-shell-' + widget.shell.id).height(), 269 | 'width': $('#widget-shell-' + widget.shell.id).width(), 270 | 'panelHeight': $('#widget-shell-' + widget.shell.id + ' > .panel').height(), 271 | 'panelWidth': $('#widget-shell-' + widget.shell.id + ' > .panel').width(), 272 | 'contentHeight': $('#widget-' + widget.shell.id).height(), 273 | 'contentWidth': $('#widget-' + widget.shell.id).width(), 274 | }; 275 | 276 | sizes[window.Dashboard.idMap[widget.shell.id].name] = size; 277 | window.localStorage.setItem(sizeKey, JSON.stringify(sizes)); 278 | } else { 279 | Dashboard.Utils.emit('options|unsaved-resize|' + widget.name); 280 | } 281 | } 282 | }); 283 | } 284 | 285 | this.refresh(); 286 | }, 287 | 288 | reset: function(singleSection) { 289 | Dashboard.Utils.emit('dashboard|reset'); 290 | 291 | window.location.hash = 'section=' + Dashboard.section; 292 | 293 | var sizeKey = '', 294 | sortKey = ''; 295 | 296 | if(singleSection) { 297 | sizeKey = `${Dashboard.settings.appName}:${Dashboard.section}:sizes`; 298 | sortKey = `${Dashboard.settings.appName}:${Dashboard.section}:sort-order`; 299 | 300 | if (window.localStorage.getItem(sizeKey) != null) { 301 | window.localStorage.removeItem(sizeKey); 302 | } 303 | 304 | if (window.localStorage.getItem(sortKey) != null) { 305 | window.localStorage.removeItem(sortKey); 306 | } 307 | } else { 308 | //reset all sections 309 | _.each(Object.keys(this.sectionMap), function(section) { 310 | sizeKey = `${Dashboard.settings.appName}:${section}:sizes`; 311 | sortKey = `${Dashboard.settings.appName}:${section}:sort-order`; 312 | 313 | if (window.localStorage.getItem(sizeKey) != null) { 314 | window.localStorage.removeItem(sizeKey); 315 | } 316 | 317 | if (window.localStorage.getItem(sortKey) != null) { 318 | window.localStorage.removeItem(sortKey); 319 | } 320 | }) 321 | } 322 | 323 | location.reload(); 324 | }, 325 | 326 | showSection: function(section, widgets) { 327 | Dashboard.Utils.emit('section|' + section); 328 | 329 | // reset screen, load widgets 330 | Dashboard.clear(); 331 | Dashboard.section = section; 332 | 333 | const sortedWidgets = widgets.slice(); 334 | 335 | if (this.settings.drag && this.settings.storage && storageAvailable) { 336 | const sortKey = `${Dashboard.settings.appName}:${Dashboard.section}:sort-order`; 337 | 338 | if (window.localStorage[sortKey] != null) { 339 | const sortOrder = JSON.parse(window.localStorage[sortKey]); 340 | sortedWidgets.sort(({widgetId: id1}, {widgetId: id2}) => { 341 | const ix1 = sortOrder.indexOf(id1), 342 | ix2 = sortOrder.indexOf(id2); 343 | 344 | if (ix1 === ix2) { 345 | return 0; 346 | 347 | // one of the two not found -- sort that one after; 348 | } else if (ix1 === -1 || ix2 === -1) { 349 | return ix1 < ix2 ? 1 : -1; 350 | 351 | // otherwise sort the one that appears first in the sort order first 352 | } else { 353 | return ix1 < ix2 ? -1 : 1; 354 | } 355 | }); 356 | } 357 | 358 | window.localStorage[sortKey] = JSON.stringify( 359 | sortedWidgets.map(({widgetId}) => widgetId) 360 | ); 361 | } 362 | 363 | // show registered section widgets 364 | sortedWidgets.forEach(obj => { 365 | Dashboard.show(Object.assign({}, obj, {section })); 366 | }); 367 | 368 | 369 | // show un-registered section widgets 370 | _.each( 371 | _.filter(Dashboard.loaded, function(widget) { return widget.section === section }), 372 | function(val) { 373 | Dashboard.show({ widgetId: val.name, section: section }); 374 | }); 375 | }, 376 | 377 | show: function(opts) { 378 | const { widgetId } = opts; 379 | 380 | if (!(widgetId in this.widgetDefns)) { 381 | this.registerWidget(widgetId) 382 | } 383 | 384 | if (!opts.section) { 385 | opts.section = ''; 386 | } 387 | 388 | if (this.loaded[widgetId]) { 389 | var $shell = $('#widget-shell-' + this.loaded[widgetId].shell.id); 390 | // been loaded, execute? 391 | if ($shell.css('display') === 'none') { 392 | // Remove .panel-close 393 | $shell.children().removeClass('panel-close'); 394 | 395 | $shell.css({ 396 | 'display': 'block' 397 | }); 398 | } 399 | 400 | if ( (opts.data) && this.loaded[widgetId].setData ) { 401 | this.loaded[widgetId].setData(opts.data); 402 | 403 | if (opts.refetch) { 404 | this.loaded[widgetId].fetch(); 405 | } 406 | } 407 | 408 | this.refresh(); 409 | } else { 410 | if (opts.data) { 411 | this.initData[widgetId] = opts.data; 412 | } 413 | 414 | // if queued to load, exit here 415 | if ( this.queued.indexOf(widgetId) >= 0) { 416 | return; 417 | } 418 | 419 | // mark as being queued 420 | this.queued.push(widgetId); 421 | 422 | if (!Dashboard.sectionMap[opts.section]) { 423 | Dashboard.sectionMap[opts.section] = []; 424 | } 425 | 426 | Dashboard.sectionMap[opts.section].push(widgetId); 427 | 428 | // drop placement stub 429 | Dashboard.render.stub(widgetId); 430 | this.widgetDefns[widgetId](widgetId); 431 | } 432 | }, 433 | 434 | hide: function(widget) { 435 | if ($('#widget-shell-' + widget.shell.id).css('display') !== 'none') { 436 | $('#widget-shell-' + widget.shell.id).css({ 437 | 'display': 'none' 438 | }); 439 | } 440 | }, 441 | 442 | // clear the grounds of any displayed widgets 443 | // TODO: using show/hide CSS. Could be easier in the long run to 444 | // remove from DOM 445 | clear: function(currentSection) { 446 | var _this = this; 447 | 448 | _.each(this.loaded, function(val, key) { 449 | if (currentSection != val.section) { 450 | _this.hide(val); 451 | } 452 | }); 453 | }, 454 | 455 | widgetControls: function() { 456 | $(document).on('click', function(e) { 457 | var el = $(e.target); 458 | 459 | if ( el.parent().parent().hasClass('panel-action') ) { 460 | 461 | // Widget collapse / expand handler 462 | if ( el.hasClass('fa-chevron-down') ) { 463 | Dashboard.Utils.emit('widget-controls|collapse'); 464 | 465 | var $ele = el.parents('.panel-heading'); 466 | var $panel = $ele.parent(); 467 | var $widget = $ele.parent().parent(); 468 | 469 | $widget.toggleClass('widget-collapse'); 470 | $widget.children('.ui-resizable-handle').toggle(); 471 | $panel.toggleClass('back-panel-collapse'); 472 | 473 | Dashboard.grid.layout(); 474 | 475 | // Widget close handler 476 | } else if ( el.hasClass('fa-close') ) { 477 | Dashboard.Utils.emit('widget-controls|close'); 478 | 479 | var $ele = el.parents('.panel'); 480 | $ele.addClass('panel-close'); 481 | 482 | setTimeout(function() { 483 | $ele.parent().css({ 'display': 'none'}); 484 | }, 210); 485 | 486 | // Widget refresh handler 487 | } else if ( el.hasClass('fa-rotate-right') ) { 488 | Dashboard.Utils.emit('widget-controls|refresh'); 489 | 490 | var wid = el.parents('.panel').parent().attr('id').replace('widget-shell-', ''), 491 | $ele = el.parents('.panel-heading').siblings('.panel-body'), 492 | postFetchFunc = function() { 493 | $ele.find('.overlay').remove(); 494 | $ele.css('overflow-y', 'auto'); 495 | }; 496 | 497 | $ele 498 | .append('
    ') 499 | .scrollTop(0) 500 | .css('overflow-y', 'hidden'); 501 | 502 | 503 | Dashboard.idMap[wid].postFetch = postFetchFunc; 504 | (Dashboard.idMap[wid].fetch && Dashboard.idMap[wid].fetch()); 505 | 506 | setTimeout(postFetchFunc, 2000); 507 | } else if ( el.hasClass('fa-link') ) { 508 | Dashboard.Utils.emit('widget-controls|link'); 509 | 510 | var wid = el.parents('.panel').parent().attr('id').replace('widget-shell-', ''), 511 | params = { 512 | section: Dashboard.idMap[wid].section, 513 | widgetId: Dashboard.idMap[wid].name 514 | }, 515 | link = document.location.protocol + '//' + document.location.host + document.location.pathname + '#'; 516 | 517 | if (Dashboard.idMap[wid].data) { 518 | params.data = JSON.stringify(Dashboard.idMap[wid].data); 519 | } 520 | 521 | link += $.param(params); 522 | 523 | //note: event handler is assigned by user 524 | $('#_clipboard').val(link); 525 | $('#_clipboard_button').click(); 526 | 527 | } 528 | } 529 | }); 530 | }, 531 | 532 | removeWidget: function(widgetId) { 533 | 534 | // Make sure the widgetId exists 535 | if(!(this.loaded[widgetId])) { 536 | return; 537 | } 538 | 539 | var shellId = this.loaded[widgetId].shell.id; 540 | const shell = document.getElementById('widget-shell-' + shellId); 541 | 542 | this.grid.remove(shell); 543 | Dashboard.refresh(); 544 | } 545 | } 546 | 547 | // INIT 548 | $(function() { 549 | Dashboard.widgetControls(); 550 | 551 | Dashboard.Utils.emit('options|resize|' + Dashboard.settings.resize); 552 | Dashboard.Utils.emit('options|drag|' + Dashboard.settings.drag); 553 | Dashboard.Utils.emit('options|storage|' + Dashboard.settings.storage); 554 | 555 | // misc hallo 556 | try { 557 | console.log( 558 | ' _______ __________________ \n'+ 559 | ' \\ \\\\______ \\______ \\ \n'+ 560 | ' / | \\| ___/| | \\ \n'+ 561 | '/ | \\ | | ` \\ \n'+ 562 | '\\____|__ /____| /_______ / \n'+ 563 | ' \\/ \\/ \n' + 564 | 'This app is a product of NPD. \n'+ 565 | 'Interested? Ping R556615. Bye! '); 566 | } catch(e) {} 567 | }); 568 | 569 | export default Dashboard; 570 | --------------------------------------------------------------------------------