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"}')