diff --git a/addons/board/static/src/js/dashboard.js b/addons/board/static/src/js/dashboard.js
index 855dc03d..5fce73ae 100644
--- a/addons/board/static/src/js/dashboard.js
+++ b/addons/board/static/src/js/dashboard.js
@@ -131,6 +131,9 @@ FormRenderer.include({
'click .oe_dashboard_link_change_layout': '_onChangeLayout',
'click .oe_dashboard_column .oe_close': '_onCloseAction',
}),
+ custom_events: _.extend({}, FormRenderer.prototype.custom_events, {
+ switch_view: '_onSwitchView',
+ }),
/**
* @override
@@ -140,6 +143,7 @@ FormRenderer.include({
this.noContentHelp = params.noContentHelp;
this.actionsDescr = {};
this._boardSubcontrollers = []; // for board: controllers of subviews
+ this._boardFormViewIDs = {}; // for board: mapping subview controller to form view id
},
/**
* Call `on_attach_callback` for each subview
@@ -266,6 +270,11 @@ FormRenderer.include({
hasSelectors: false,
});
return view.getController(self).then(function (controller) {
+ self._boardFormViewIDs[controller.handle] = _.first(
+ _.find(action.views, function (descr) {
+ return descr[1] === 'form';
+ })
+ );
self._boardSubcontrollers.push(controller);
return controller.appendTo(params.$node);
});
@@ -384,6 +393,16 @@ FormRenderer.include({
$action.find('.oe_content').toggle();
this.trigger_up('save_dashboard');
},
+ /**
+ * Let FormController know which form view it should display based on the
+ * window action of the sub controller that is switching view
+ *
+ * @private
+ * @param {OdooEvent} event
+ */
+ _onSwitchView: function (event) {
+ event.data.formViewID = this._boardFormViewIDs[event.target.handle];
+ },
});
});
diff --git a/addons/board/static/tests/dashboard_tests.js b/addons/board/static/tests/dashboard_tests.js
index 5b9e05cc..b6910c7c 100644
--- a/addons/board/static/tests/dashboard_tests.js
+++ b/addons/board/static/tests/dashboard_tests.js
@@ -272,6 +272,51 @@ QUnit.test('can open a record', function (assert) {
form.destroy();
});
+QUnit.test('can open record using action form view', function (assert) {
+ assert.expect(1);
+
+ var form = createView({
+ View: FormView,
+ model: 'board',
+ data: this.data,
+ arch: '
\n"
for device in devices:
device_name = device[device.find('ID')+2:]
- device_id = device_name.split()[0]
- if not (device_id in BANNED_DEVICES):
- resp += "
"+device_name+"
\n"
- count += 1
+ if device_name: # to avoid last empty line
+ device_id = device_name.split()[0]
+ if not (device_id in BANNED_DEVICES):
+ resp += "
"+device_name+"
\n"
+ count += 1
if count == 0:
resp += "
No USB Device Found
"
@@ -124,7 +127,7 @@ class Proxy(http.Controller):
%s
- """ % subprocess.check_output('lsusb -v', shell=True)
+ """ % subprocess.check_output('lsusb -v', shell=True).decode('utf-8')
return request.make_response(resp,{
'Cache-Control': 'no-cache',
diff --git a/addons/hw_scale/controllers/main.py b/addons/hw_scale/controllers/main.py
index 6d1a4e7d..8fdb6c6e 100644
--- a/addons/hw_scale/controllers/main.py
+++ b/addons/hw_scale/controllers/main.py
@@ -28,7 +28,7 @@ except ImportError:
def _toledo8217StatusParse(status):
""" Parse a scale's status, returning a `(weight, weight_info)` pair. """
weight, weight_info = None, None
- stat = ord(status[status.index('?') + 1])
+ stat = status[status.index(b'?') + 1]
if stat == 0:
weight_info = 'ok'
else:
@@ -68,17 +68,17 @@ Toledo8217Protocol = ScaleProtocol(
parity=serial.PARITY_EVEN,
timeout=1,
writeTimeout=1,
- weightRegexp="\x02\\s*([0-9.]+)N?\\r",
- statusRegexp="\x02\\s*(\\?.)\\r",
+ weightRegexp=b"\x02\\s*([0-9.]+)N?\\r",
+ statusRegexp=b"\x02\\s*(\\?.)\\r",
statusParse=_toledo8217StatusParse,
commandDelay=0.2,
weightDelay=0.5,
newWeightDelay=0.2,
- commandTerminator='',
- weightCommand='W',
- zeroCommand='Z',
- tareCommand='T',
- clearCommand='C',
+ commandTerminator=b'',
+ weightCommand=b'W',
+ zeroCommand=b'Z',
+ tareCommand=b'T',
+ clearCommand=b'C',
emptyAnswerValid=False,
autoResetWeight=False,
)
@@ -98,15 +98,15 @@ ADAMEquipmentProtocol = ScaleProtocol(
weightRegexp=r"\s*([0-9.]+)kg", # LABEL format 3 + KG in the scale settings, but Label 1/2 should work
statusRegexp=None,
statusParse=None,
- commandTerminator="\r\n",
+ commandTerminator=b"\r\n",
commandDelay=0.2,
weightDelay=0.5,
newWeightDelay=5, # AZExtra beeps every time you ask for a weight that was previously returned!
# Adding an extra delay gives the operator a chance to remove the products
# before the scale starts beeping. Could not find a way to disable the beeps.
- weightCommand='P',
- zeroCommand='Z',
- tareCommand='T',
+ weightCommand=b'P',
+ zeroCommand=b'Z',
+ tareCommand=b'T',
clearCommand=None, # No clear command -> Tare again
emptyAnswerValid=True, # AZExtra does not answer unless a new non-zero weight has been detected
autoResetWeight=True, # AZExtra will not return 0 after removing products
@@ -165,8 +165,8 @@ class Scale(Thread):
if not char:
break
else:
- answer.append(char)
- return ''.join(answer)
+ answer.append(bytes(char))
+ return b''.join(answer)
def _parse_weight_answer(self, protocol, answer):
""" Parse a scale's answer to a weighing request, returning