[FIX] web: Kanban: prevent drag&drop for readonly
If the kanban view is grouped by a readonly field, it should not be possible to drag&drop the record from one column to another as this will trigger a write on this readonly field. It should however be possible to resequence records so the option `containment` is used in the records. Closes #19390
This commit is contained in:
@@ -50,7 +50,7 @@ var KanbanColumn = Widget.extend({
|
||||
this.grouped_by_m2o = options.grouped_by_m2o;
|
||||
this.editable = options.editable;
|
||||
this.deletable = options.deletable;
|
||||
this.draggable = recordOptions.draggable;
|
||||
this.draggable = options.draggable;
|
||||
this.records_editable = options.records_editable;
|
||||
this.records_deletable = options.records_deletable;
|
||||
this.relation = options.relation;
|
||||
@@ -87,12 +87,13 @@ var KanbanColumn = Widget.extend({
|
||||
}
|
||||
this.$header.tooltip();
|
||||
|
||||
if (config.device.size_class > config.device.SIZES.XS && this.draggable !== false) {
|
||||
if (config.device.size_class > config.device.SIZES.XS) {
|
||||
// deactivate sortable in mobile mode. It does not work anyway,
|
||||
// and it breaks horizontal scrolling in kanban views. Someday, we
|
||||
// should find a way to use the touch events to make sortable work.
|
||||
this.$el.sortable({
|
||||
connectWith: '.o_kanban_group',
|
||||
containment: this.draggable ? '.o_kanban_view' : 'parent',
|
||||
revert: 0,
|
||||
delay: 0,
|
||||
items: '> .o_kanban_record:not(.o_updating)',
|
||||
|
||||
@@ -33,7 +33,6 @@ var KanbanRecord = Widget.extend({
|
||||
this.options = options;
|
||||
this.editable = options.editable;
|
||||
this.deletable = options.deletable;
|
||||
this.draggable = options.draggable;
|
||||
this.read_only_mode = options.read_only_mode;
|
||||
this.qweb = options.qweb;
|
||||
this.subWidgets = {};
|
||||
|
||||
@@ -316,7 +316,7 @@ var KanbanRenderer = BasicRenderer.extend({
|
||||
var groupByFieldInfo = state.fieldsInfo.kanban[state.groupedBy[0]];
|
||||
// Deactivate the drag'n'drop if the groupedBy field:
|
||||
// - is a date or datetime since we group by month or
|
||||
// - is readonly
|
||||
// - is readonly (on the field attrs or in the view)
|
||||
var draggable = true;
|
||||
if (groupByFieldAttrs) {
|
||||
if (groupByFieldAttrs.type === "date" || groupByFieldAttrs.type === "datetime") {
|
||||
@@ -325,6 +325,11 @@ var KanbanRenderer = BasicRenderer.extend({
|
||||
draggable = !(groupByFieldAttrs.readonly);
|
||||
}
|
||||
}
|
||||
if (groupByFieldInfo) {
|
||||
if (draggable && groupByFieldInfo.readonly !== undefined) {
|
||||
draggable = !(groupByFieldInfo.readonly);
|
||||
}
|
||||
}
|
||||
this.groupedByM2O = groupByFieldAttrs && (groupByFieldAttrs.type === 'many2one');
|
||||
var grouped_by_field = this.groupedByM2O && groupByFieldAttrs.relation;
|
||||
var groupByTooltip = groupByFieldInfo && groupByFieldInfo.options.group_by_tooltip;
|
||||
|
||||
@@ -581,6 +581,79 @@ QUnit.module('Views', {
|
||||
kanban.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('prevent drag and drop of record if grouped by readonly', function (assert) {
|
||||
assert.expect(12);
|
||||
|
||||
this.data.partner.fields.foo.readonly = true;
|
||||
var kanban = createView({
|
||||
View: KanbanView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<kanban>' +
|
||||
'<templates>' +
|
||||
'<t t-name="kanban-box"><div>' +
|
||||
'<field name="foo"/>' +
|
||||
'<field name="state" readonly="1"/>' +
|
||||
'</div></t>' +
|
||||
'</templates>' +
|
||||
'</kanban>',
|
||||
mockRPC: function (route, args) {
|
||||
if (route === '/web/dataset/resequence') {
|
||||
return $.when();
|
||||
}
|
||||
if (args.model === 'partner' && args.method === 'write') {
|
||||
throw new Error('should not be draggable');
|
||||
}
|
||||
return this._super(route, args);
|
||||
},
|
||||
});
|
||||
// simulate an update coming from the searchview, with another groupby given
|
||||
kanban.update({groupBy: ['state']});
|
||||
assert.strictEqual(kanban.$('.o_kanban_group:nth-child(1) .o_kanban_record').length, 1,
|
||||
"column should contain 1 record(s)");
|
||||
assert.strictEqual(kanban.$('.o_kanban_group:nth-child(2) .o_kanban_record').length, 1,
|
||||
"column should contain 1 record(s)");
|
||||
// drag&drop a record in another column
|
||||
var $record = kanban.$('.o_kanban_group:nth-child(1) .o_kanban_record:first');
|
||||
var $group = kanban.$('.o_kanban_group:nth-child(2)');
|
||||
testUtils.dragAndDrop($record, $group);
|
||||
// should not be draggable
|
||||
assert.strictEqual(kanban.$('.o_kanban_group:nth-child(1) .o_kanban_record').length, 1,
|
||||
"column should now contain 1 record(s)");
|
||||
assert.strictEqual(kanban.$('.o_kanban_group:nth-child(2) .o_kanban_record').length, 1,
|
||||
"column should contain 1 record(s)");
|
||||
|
||||
// simulate an update coming from the searchview, with another groupby given
|
||||
kanban.update({groupBy: ['foo']});
|
||||
assert.strictEqual(kanban.$('.o_kanban_group:nth-child(1) .o_kanban_record').length, 1,
|
||||
"column should contain 1 record(s)");
|
||||
assert.strictEqual(kanban.$('.o_kanban_group:nth-child(2) .o_kanban_record').length, 2,
|
||||
"column should contain 2 record(s)");
|
||||
// drag&drop a record in another column
|
||||
$record = kanban.$('.o_kanban_group:nth-child(1) .o_kanban_record:first');
|
||||
$group = kanban.$('.o_kanban_group:nth-child(2)');
|
||||
testUtils.dragAndDrop($record, $group);
|
||||
// should not be draggable
|
||||
assert.strictEqual(kanban.$('.o_kanban_group:nth-child(1) .o_kanban_record').length, 1,
|
||||
"column should now contain 1 record(s)");
|
||||
assert.strictEqual(kanban.$('.o_kanban_group:nth-child(2) .o_kanban_record').length, 2,
|
||||
"column should contain 2 record(s)");
|
||||
|
||||
// drag&drop a record in the same column
|
||||
var $record1 = kanban.$('.o_kanban_group:nth-child(2) .o_kanban_record:eq(0)');
|
||||
var $record2 = kanban.$('.o_kanban_group:nth-child(2) .o_kanban_record:eq(1)');
|
||||
assert.strictEqual($record1.text(), "blipDEF", "first record should be DEF");
|
||||
assert.strictEqual($record2.text(), "blipGHI", "second record should be GHI");
|
||||
testUtils.dragAndDrop($record2, $record1, {position: 'top'});
|
||||
// should still be able to resequence
|
||||
assert.strictEqual(kanban.$('.o_kanban_group:nth-child(2) .o_kanban_record:eq(0)').text(), "blipGHI",
|
||||
"records should have been resequenced");
|
||||
assert.strictEqual(kanban.$('.o_kanban_group:nth-child(2) .o_kanban_record:eq(1)').text(), "blipDEF",
|
||||
"records should have been resequenced");
|
||||
|
||||
kanban.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('kanban view with default_group_by', function (assert) {
|
||||
assert.expect(7);
|
||||
this.data.partner.records.product_id = 1;
|
||||
|
||||
Reference in New Issue
Block a user