diff --git a/bower.json b/bower.json index 83f60db1..ce37d932 100644 --- a/bower.json +++ b/bower.json @@ -35,7 +35,9 @@ "venturocket-angular-slider": "~0.3.2", "font-awesome-bower": "~4.1.0", "bootstrap": "~3.1.1", - "font-lato-2-subset": "*" + "font-lato-2-subset": "*", + "packery": "~1.2.2", + "draggabilly": "~1.1.0" }, "private": true, "resolutions": { diff --git a/res/app/components/stf/angular-draggabilly/angular-draggabilly-directive.js b/res/app/components/stf/angular-draggabilly/angular-draggabilly-directive.js new file mode 100644 index 00000000..5c74843f --- /dev/null +++ b/res/app/components/stf/angular-draggabilly/angular-draggabilly-directive.js @@ -0,0 +1,16 @@ +module.exports = function angularDraggabillyDirective(DraggabillyService) { + return { + restrict: 'AE', + link: function (scope, element, attrs) { + var parsedAttrs = $parse(attrs.angularDraggabilly)() + if (typeof parsedAttrs !== 'object') { + parsedAttrs = {} + } + + var options = angular.extend({ + }, parsedAttrs) + + var draggie = new DraggabillyService(element[0], options) + } + } +} diff --git a/res/app/components/stf/angular-draggabilly/angular-draggabilly-spec.js b/res/app/components/stf/angular-draggabilly/angular-draggabilly-spec.js new file mode 100644 index 00000000..67ae1910 --- /dev/null +++ b/res/app/components/stf/angular-draggabilly/angular-draggabilly-spec.js @@ -0,0 +1,23 @@ +describe('angularDraggabilly', function () { + + beforeEach(module('stf.angular-draggabilly')); + + var scope, compile; + + beforeEach(inject(function ($rootScope, $compile) { + scope = $rootScope.$new(); + compile = $compile; + })); + + it('should ...', function () { + + /* + To test your directive, you need to create some html that would use your directive, + send that through compile() then compare the results. + + var element = compile('
hi
')(scope); + expect(element.text()).toBe('hello, world'); + */ + + }); +}); \ No newline at end of file diff --git a/res/app/components/stf/angular-draggabilly/index.js b/res/app/components/stf/angular-draggabilly/index.js new file mode 100644 index 00000000..2d734194 --- /dev/null +++ b/res/app/components/stf/angular-draggabilly/index.js @@ -0,0 +1,9 @@ +var draggabilly = require('draggabilly') + +module.exports = angular.module('stf.angular-draggabilly', [ + +]) + .factory('DraggabillyService', function () { + return draggabilly + }) + .directive('angularDraggabilly', require('./angular-draggabilly-directive')) diff --git a/res/app/components/stf/angular-packery/angular-packery-directive.js b/res/app/components/stf/angular-packery/angular-packery-directive.js new file mode 100644 index 00000000..050c9a8b --- /dev/null +++ b/res/app/components/stf/angular-packery/angular-packery-directive.js @@ -0,0 +1,61 @@ +var _ = require('lodash') + +module.exports = function angularPackeryDirective(PackeryService, DraggabillyService, $timeout, $parse) { + return { + restrict: 'AE', + link: function (scope, element, attrs) { + var container = element[0] + var pckry + var parsedAttrs = $parse(attrs.angularPackery)() + if (typeof parsedAttrs !== 'object') { + parsedAttrs = {} + } + + var options = angular.extend({ + itemSelector: '.packery-item', + columnWidth: '.packery-item', + transitionDuration: '300ms' + }, parsedAttrs) + + $timeout(function () { + pckry = new PackeryService(container, options) + pckry.on('layoutComplete', onLayoutComplete) + pckry.layout() + pckry.bindResize() + bindDraggable() + }, 50) + + function bindDraggable() { + if (options.draggable) { + var draggableOptions = {} + if (options.draggableHandle) { + draggableOptions.handle = options.draggableHandle + } + var itemElems = pckry.getItemElements() + for (var i = 0, len = itemElems.length; i < len; ++i) { + var elem = itemElems[i] + var draggie = new DraggabillyService(elem, draggableOptions) + pckry.bindDraggabillyEvents(draggie) + } + } + } + + function onLayoutComplete() { + return true + } + + function onPanelsResized() { + pckry.layout() + } + + scope.$on('panelsResized', _.throttle(onPanelsResized, 300)) + + scope.$on('$destroy', function () { + if (pckry) { + pckry.unbindResize() + pckry.off('layoutComplete', onLayoutComplete) + } + }) + } + } +} diff --git a/res/app/components/stf/angular-packery/angular-packery-spec.js b/res/app/components/stf/angular-packery/angular-packery-spec.js new file mode 100644 index 00000000..4072f9e8 --- /dev/null +++ b/res/app/components/stf/angular-packery/angular-packery-spec.js @@ -0,0 +1,23 @@ +describe('angularPackery', function () { + + beforeEach(module('stf.angular-packery')); + + var scope, compile; + + beforeEach(inject(function ($rootScope, $compile) { + scope = $rootScope.$new(); + compile = $compile; + })); + + it('should ...', function () { + + /* + To test your directive, you need to create some html that would use your directive, + send that through compile() then compare the results. + + var element = compile('
hi
')(scope); + expect(element.text()).toBe('hello, world'); + */ + + }); +}); \ No newline at end of file diff --git a/res/app/components/stf/angular-packery/angular-packery.css b/res/app/components/stf/angular-packery/angular-packery.css new file mode 100644 index 00000000..7733a677 --- /dev/null +++ b/res/app/components/stf/angular-packery/angular-packery.css @@ -0,0 +1,36 @@ +/* + Screen Breakpoints: + + screen-xs: 480px + screen-sm: 768px + screen-md: 992px + screen-lg: 1200px + screen-xl: 1500px +*/ + +div[angular-packery] { + overflow-y: hidden; + overflow-x: hidden; +} + +.col-md-4-x.packery-item { + width: 33.33333333333333%; +} + +@media screen and (min-width: 1500px) { + .col-md-4-x.packery-item { + width: 25%; + } +} + +@media screen and (max-width: 1200px) { + .col-md-4-x.packery-item { + width: 50%; + } +} + +@media screen and (max-width: 768px) { + .col-md-4-x.packery-item { + width: 100%; + } +} diff --git a/res/app/components/stf/angular-packery/index.js b/res/app/components/stf/angular-packery/index.js new file mode 100644 index 00000000..6fcea4ab --- /dev/null +++ b/res/app/components/stf/angular-packery/index.js @@ -0,0 +1,14 @@ +require('./angular-packery.css') + +require('packery/js/rect.js') +require('packery/js/packer.js') +require('packery/js/item.js') +var packery = require('packery/js/packery.js') + +module.exports = angular.module('stf.angular-packery', [ + require('stf/angular-draggabilly').name +]) + .factory('PackeryService', function () { + return packery + }) + .directive('angularPackery', require('./angular-packery-directive')) diff --git a/res/app/control-panes/info/index.js b/res/app/control-panes/info/index.js index 29e0196b..eca4fd5b 100644 --- a/res/app/control-panes/info/index.js +++ b/res/app/control-panes/info/index.js @@ -1,7 +1,7 @@ require('./info.css') module.exports = angular.module('stf.info', [ - + require('stf/angular-packery').name ]) .run(["$templateCache", function ($templateCache) { $templateCache.put('control-panes/info/info.jade', diff --git a/res/app/control-panes/info/info.css b/res/app/control-panes/info/info.css index 9c6c704f..507a8ca6 100644 --- a/res/app/control-panes/info/info.css +++ b/res/app/control-panes/info/info.css @@ -8,8 +8,6 @@ border-top: 0; } - - .stf-info .table-infocard tbody > tr > td:first-child { text-align: right; margin-right: 20px; @@ -25,3 +23,5 @@ margin-bottom: 0; height: 15px; } + + diff --git a/res/app/control-panes/info/info.jade b/res/app/control-panes/info/info.jade index a36a399e..2fa8dde4 100644 --- a/res/app/control-panes/info/info.jade +++ b/res/app/control-panes/info/info.jade @@ -1,6 +1,7 @@ -.row.stf-info(ng-controller='InfoCtrl') +.row.stf-info(ng-controller='InfoCtrl', +angular-packery='{draggable: true, draggableHandle: ".heading i"}') - .col-md-4 + .col-md-4-x.packery-item .widget-container.fluid-height .heading i.fa.fa-location-arrow @@ -16,7 +17,7 @@ td(translate) Place td {{device.provider.name}} - .col-md-4 + .col-md-4-x.packery-item .widget-container.fluid-height .heading i.fa.fa-bolt @@ -45,7 +46,7 @@ td Voltage td {{device.battery.voltage}} v - .col-md-4 + .col-md-4-x.packery-item .widget-container.fluid-height .heading i.fa.fa-tablet @@ -81,7 +82,7 @@ td Y DPI td {{device.display.ydpi}} - .col-md-4 + .col-md-4-x.packery-item .widget-container.fluid-height .heading i.fa.fa-signal @@ -108,7 +109,7 @@ td Sub Type td {{device.network.subtype | networkSubType}} - .col-md-4 + .col-md-4-x.packery-item .widget-container.fluid-height .heading i.fa.fa-credit-card @@ -134,7 +135,7 @@ small {{device.phone.iccid}} - .col-md-4 + .col-md-4-x.packery-item .widget-container.fluid-height .heading i.fa.fa-phone @@ -158,7 +159,7 @@ td(translate) Released td {{device.releasedAt | date:longDate}} - .col-md-4 + .col-md-4-x.packery-item .widget-container.fluid-height .heading i.fa.fa-mobile diff --git a/res/app/device-list/device-list.jade b/res/app/device-list/device-list.jade index b28ea991..c1902b75 100644 --- a/res/app/device-list/device-list.jade +++ b/res/app/device-list/device-list.jade @@ -114,13 +114,13 @@ div.stf-device-list td(ng-show='showAll', data-title="'Phone ICCID'", sortable='"phone.iccid"', filter='{"phone.iccid": "text"}') span {{device.phone.iccid}} - td(ng-show='showAll', data-title="'Battery Health'", sortable='"battery.health"', filter='{"battery.health": "text"}') + td(ng-show='showAll', data-title="'Battery Health'", sortable='"battery.health"') span {{device.battery.health | batteryHealth}} - td(ng-show='showAll', data-title="'Battery Source'", sortable='"battery.source"', filter='{"battery.source": "text"}') + td(ng-show='showAll', data-title="'Battery Source'", sortable='"battery.source"') span {{device.battery.source | batterySource}} - td(ng-show='showAll', data-title="'Battery Status'", sortable='"battery.status"', filter='{"battery.status": "text"}') + td(ng-show='showAll', data-title="'Battery Status'", sortable='"battery.status"') span {{device.battery.status | batteryStatus}} - td(ng-show='showAll', data-title="'Battery Level'", sortable='"battery.level"', filter='{"battery.level": "text"}') + td(ng-show='showAll', data-title="'Battery Level'", sortable='"battery.level"') progressbar(value='device.battery.level', max='device.battery.scale', type='success') span {{ device.battery.level / device.battery.scale * 100 }}% td(ng-show='showAll', data-title="'Battery Temperature'", sortable='"battery.temp"', filter='{"battery.temp": "text"}')