1
0
Fork 0
mirror of https://github.com/openstf/stf synced 2025-10-05 10:39:25 +02:00

Allow to update device notes column from STF UI. https://github.com/openstf/stf/issues/124

This commit is contained in:
Vishal Banthia 2015-10-23 01:36:41 +09:00
parent 26421fd322
commit 466890777d
9 changed files with 135 additions and 7 deletions

View file

@ -32,7 +32,8 @@
"eventEmitter": "~4.3.0", "eventEmitter": "~4.3.0",
"angular-ladda": "~0.3.1", "angular-ladda": "~0.3.1",
"d3": "~3.5.6", "d3": "~3.5.6",
"spin.js": "~2.3.2" "spin.js": "~2.3.2",
"angular-xeditable": "~0.1.9"
}, },
"private": true, "private": true,
"devDependencies": { "devDependencies": {

View file

@ -258,6 +258,12 @@ dbapi.setDeviceRotation = function(serial, rotation) {
})) }))
} }
dbapi.setDeviceNote = function(serial, note) {
return db.run(r.table('devices').get(serial).update({
notes: note
}))
}
dbapi.setDeviceReverseForwards = function(serial, forwards) { dbapi.setDeviceReverseForwards = function(serial, forwards) {
return db.run(r.table('devices').get(serial).update({ return db.run(r.table('devices').get(serial).update({
reverseForwards: forwards reverseForwards: forwards

View file

@ -305,6 +305,28 @@ module.exports = function(options) {
new Promise(function(resolve) { new Promise(function(resolve) {
socket.on('disconnect', resolve) socket.on('disconnect', resolve)
// Global messages for all clients using socket.io
//
// Device note
.on('device.note', function(data) {
return dbapi.setDeviceNote(data.serial, data.note)
.then(function() {
return dbapi.loadDevice(data.serial)
})
.then(function(device) {
if(device) {
io.emit('device.change', {
important: true
, data: {
serial: device.serial
, notes: device.notes
}
})
}
})
})
// Client specific messages
//
// Settings // Settings
.on('user.settings.update', function(data) { .on('user.settings.update', function(data) {
dbapi.updateUserSettings(user.email, data) dbapi.updateUserSettings(user.email, data)

View file

@ -210,5 +210,12 @@ module.exports = function DeviceServiceFactory($http, socket, EnhanceDeviceServi
}) })
} }
deviceService.updateNote = function (serial, note) {
socket.emit('device.note', {
serial: serial,
note: note
})
}
return deviceService return deviceService
} }

View file

@ -18,7 +18,7 @@ var filterOps = {
} }
} }
module.exports = function DeviceColumnService($filter, gettext) { module.exports = function DeviceColumnService($filter, $compile, gettext) {
// Definitions for all possible values. // Definitions for all possible values.
return { return {
state: DeviceStatusCell({ state: DeviceStatusCell({
@ -252,8 +252,14 @@ module.exports = function DeviceColumnService($filter, gettext) {
return device.provider ? device.provider.name : '' return device.provider ? device.provider.name : ''
} }
}) })
, notes: TextCell({ , notes: XEditableCell({
title: gettext('Notes') title: gettext('Notes')
, compile: $compile
, scopeRequired: true
, attrs: {
model: 'device.notes'
, onbeforesave: 'updateNote(device.serial, $data)'
}
, value: function(device) { , value: function(device) {
return device.notes || '' return device.notes || ''
} }
@ -613,3 +619,38 @@ function DeviceStatusCell(options) {
} }
}) })
} }
function XEditableCell(options) {
return _.defaults(options, {
title: options.title
, defaultOrder: 'asc'
, build: function (scope) {
var td = document.createElement('td')
, a = document.createElement('a')
// Ref: http://vitalets.github.io/angular-xeditable/#text-simple
a.setAttribute('href', '#')
a.setAttribute('editable-text', options.attrs.model)
a.setAttribute('onbeforesave', options.attrs.onbeforesave)
a.appendChild(document.createTextNode(options.attrs.model))
td.appendChild(a)
// compile with new scope
options.compile(td)(scope)
return td
}
, update: function(td, item) {
var a = td.firstChild
, t = a.firstChild
t.nodeValue = options.value(item) || 'click to add'
return td
}
, compare: function(a, b) {
return compareIgnoreCase(options.value(a), options.value(b))
}
, filter: function(item, filter) {
return filterIgnoreCase(options.value(item), filter.query)
}
})
}

View file

@ -2,10 +2,12 @@ var patchArray = require('./../util/patch-array')
module.exports = function DeviceListDetailsDirective( module.exports = function DeviceListDetailsDirective(
$filter $filter
, $compile
, $rootScope
, gettext , gettext
, DeviceColumnService , DeviceColumnService
, GroupService , GroupService
, $rootScope , DeviceService
, LightboxImageService , LightboxImageService
, StandaloneService , StandaloneService
) { ) {
@ -277,6 +279,20 @@ module.exports = function DeviceListDetailsDirective(
} }
})() })()
// check if new column needs a new scope or not
// and build accordingly
function buildColumn(col, device) {
var td
if (col.scopeRequired) {
var childScope = scope.$new()
childScope.device = device
td = col.build(childScope)
} else {
td = col.build()
}
return td
}
// Creates a completely new row for the device. Means that this is // Creates a completely new row for the device. Means that this is
// the first time we see the device. // the first time we see the device.
function createRow(device) { function createRow(device) {
@ -291,8 +307,10 @@ module.exports = function DeviceListDetailsDirective(
} }
for (var i = 0, l = activeColumns.length; i < l; ++i) { for (var i = 0, l = activeColumns.length; i < l; ++i) {
td = scope.columnDefinitions[activeColumns[i]].build() var col = scope.columnDefinitions[activeColumns[i]]
scope.columnDefinitions[activeColumns[i]].update(td, device)
td = buildColumn(col, device)
col.update(td, device)
tr.appendChild(td) tr.appendChild(td)
} }
@ -301,6 +319,10 @@ module.exports = function DeviceListDetailsDirective(
return tr return tr
} }
scope.updateNote = function(serial, note) {
DeviceService.updateNote(serial, note)
}
// Patches all rows. // Patches all rows.
function patchAll(patch) { function patchAll(patch) {
for (var i = 0, l = rows.length; i < l; ++i) { for (var i = 0, l = rows.length; i < l; ++i) {
@ -317,7 +339,7 @@ module.exports = function DeviceListDetailsDirective(
switch (op[0]) { switch (op[0]) {
case 'insert': case 'insert':
var col = scope.columnDefinitions[op[2]] var col = scope.columnDefinitions[op[2]]
tr.insertBefore(col.update(col.build(), device), tr.cells[op[1]]) tr.insertBefore(col.update(buildColumn(col, device), device), tr.cells[op[1]])
break break
case 'remove': case 'remove':
tr.deleteCell(op[1]) tr.deleteCell(op[1])

View file

@ -1,6 +1,7 @@
require('./device-list.css') require('./device-list.css')
module.exports = angular.module('device-list', [ module.exports = angular.module('device-list', [
require('angular-xeditable').name,
require('stf/device').name, require('stf/device').name,
require('stf/user/group').name, require('stf/user/group').name,
require('stf/control').name, require('stf/control').name,
@ -21,4 +22,8 @@ module.exports = angular.module('device-list', [
controller: 'DeviceListCtrl' controller: 'DeviceListCtrl'
}) })
}]) }])
.run(function(editableOptions) {
// bootstrap3 theme for xeditables
editableOptions.theme = 'bs3'
})
.controller('DeviceListCtrl', require('./device-list-controller')) .controller('DeviceListCtrl', require('./device-list-controller'))

View file

@ -0,0 +1,7 @@
require('angular-xeditable/dist/js/xeditable.js')
require('angular-xeditable/dist/css/xeditable.css')
require('./style.css')
module.exports = {
name: 'xeditable'
}

View file

@ -0,0 +1,17 @@
a.editable-click {
text-decoration: none;
color: #167FFC;
border-bottom: none;
}
a.editable-click:hover {
color: #808080;
}
a.editable-empty {
color: transparent;
}
a.editable-empty:focus {
color: #808080;
}