From 5c651a09e12b4657bfe64e37e353c0a86f40a0ce Mon Sep 17 00:00:00 2001 From: Hiral Bhavsar Date: Wed, 21 Feb 2018 18:50:38 +0530 Subject: [PATCH] [IMP] web: Kanban: allow to archive/restore column records This feature has been removed in rev. odoo/odoo@e533085 but this commit reintroduces it. It was considered as "too dangerous" for new users. Instead of removing the feature, a confirmation request has been added to warn the user about his potentially harmful action. The same warning has also been added in List view when archiving records. Task 60393 Co-authored-by: Mohammed Shekha --- .../src/js/views/kanban/kanban_column.js | 24 ++++++++ .../src/js/views/kanban/kanban_controller.js | 22 ++++++++ .../src/js/views/list/list_controller.js | 8 ++- addons/web/static/src/xml/kanban.xml | 4 ++ addons/web/static/tests/views/kanban_tests.js | 55 ++++++++++++++++++- addons/web/static/tests/views/list_tests.js | 8 ++- 6 files changed, 117 insertions(+), 4 deletions(-) diff --git a/addons/web/static/src/js/views/kanban/kanban_column.js b/addons/web/static/src/js/views/kanban/kanban_column.js index e66601816c215..5dfcbce01c811 100644 --- a/addons/web/static/src/js/views/kanban/kanban_column.js +++ b/addons/web/static/src/js/views/kanban/kanban_column.js @@ -27,6 +27,8 @@ var KanbanColumn = Widget.extend({ 'click .o_kanban_quick_add': '_onAddQuickCreate', 'click .o_kanban_load_more': '_onLoadMore', 'click .o_kanban_toggle_fold': '_onToggleFold', + 'click .o_column_archive_records': '_onArchiveRecords', + 'click .o_column_unarchive_records': '_onUnarchiveRecords' }, /** * @override @@ -355,6 +357,28 @@ var KanbanColumn = Widget.extend({ ev.data.callback(record.$el, record.state.data); }); }, + /** + * @private + * @param {MouseEvent} event + */ + _onArchiveRecords: function (event) { + event.preventDefault(); + Dialog.confirm(this, _t("Are you sure that you want to archive all the records from this column?"), { + confirm_callback: this.trigger_up.bind(this, 'kanban_column_records_toggle_active', { + archive: true, + }), + }); + }, + /** + * @private + * @param {MouseEvent} event + */ + _onUnarchiveRecords: function (event) { + event.preventDefault(); + this.trigger_up('kanban_column_records_toggle_active', { + archive: false, + }); + } }); return KanbanColumn; diff --git a/addons/web/static/src/js/views/kanban/kanban_controller.js b/addons/web/static/src/js/views/kanban/kanban_controller.js index 986fff3a53e9f..86f1cb72589bf 100644 --- a/addons/web/static/src/js/views/kanban/kanban_controller.js +++ b/addons/web/static/src/js/views/kanban/kanban_controller.js @@ -30,6 +30,7 @@ var KanbanController = BasicController.extend({ kanban_load_more: '_onLoadMore', kanban_load_records: '_onLoadColumnRecords', column_toggle_fold: '_onToggleColumn', + kanban_column_records_toggle_active: '_onToggleActiveRecords', }), /** * @override @@ -443,6 +444,27 @@ var KanbanController = BasicController.extend({ ev.data.force_save = true; this._applyChanges(ev.target.db_id, changes, ev); }, + /** + * Allow the user to archive/restore all the records of a column. + * + * @private + * @param {OdooEvent} event + */ + _onToggleActiveRecords: function (event) { + var self = this; + var active = !event.data.archive; + var column = event.target; + var recordIds = _.pluck(column.records, 'db_id'); + if (recordIds.length) { + this.model + .toggleActive(recordIds, active, column.db_id) + .then(function (dbID) { + var data = self.model.get(dbID); + self.renderer.updateColumn(dbID, data); + self._updateEnv(); + }); + } + }, }); return KanbanController; diff --git a/addons/web/static/src/js/views/list/list_controller.js b/addons/web/static/src/js/views/list/list_controller.js index b42da9665ade5..ae1a8f7305b6e 100644 --- a/addons/web/static/src/js/views/list/list_controller.js +++ b/addons/web/static/src/js/views/list/list_controller.js @@ -10,6 +10,7 @@ odoo.define('web.ListController', function (require) { var core = require('web.core'); var BasicController = require('web.BasicController'); var DataExport = require('web.DataExport'); +var Dialog = require('web.Dialog'); var pyeval = require('web.pyeval'); var Sidebar = require('web.Sidebar'); @@ -136,6 +137,7 @@ var ListController = BasicController.extend({ * @param {jQuery Node} $node */ renderSidebar: function ($node) { + var self = this; if (this.hasSidebar) { var other = [{ label: _t("Export"), @@ -144,7 +146,11 @@ var ListController = BasicController.extend({ if (this.archiveEnabled) { other.push({ label: _t("Archive"), - callback: this._onToggleArchiveState.bind(this, true) + callback: function () { + Dialog.confirm(self, _t("Are you sure that you want to archive all the selected records?"), { + confirm_callback: self._onToggleArchiveState.bind(self, true), + }); + } }); other.push({ label: _t("Unarchive"), diff --git a/addons/web/static/src/xml/kanban.xml b/addons/web/static/src/xml/kanban.xml index 23af895b8ea29..9c3fac6574a5f 100644 --- a/addons/web/static/src/xml/kanban.xml +++ b/addons/web/static/src/xml/kanban.xml @@ -22,6 +22,10 @@
  • Edit Stage
  • Delete
  • + +
  • Archive All
  • +
  • Restore All
  • +
    diff --git a/addons/web/static/tests/views/kanban_tests.js b/addons/web/static/tests/views/kanban_tests.js index c5e5f606f6155..04003c568a33b 100644 --- a/addons/web/static/tests/views/kanban_tests.js +++ b/addons/web/static/tests/views/kanban_tests.js @@ -97,7 +97,7 @@ QUnit.module('Views', { }); QUnit.test('basic grouped rendering', function (assert) { - assert.expect(11); + assert.expect(13); var kanban = createView({ View: KanbanView, @@ -135,6 +135,8 @@ QUnit.module('Views', { "should not be able to edit the column"); assert.ok(!kanban.$('.o_kanban_header:first .o_kanban_config .o_column_delete').length, "should not be able to delete the column"); + assert.ok(!kanban.$('.o_kanban_header:first .o_kanban_config .o_column_archive_records').length, "should not be able to archive all the records"); + assert.ok(!kanban.$('.o_kanban_header:first .o_kanban_config .o_column_unarchive_records').length, "should not be able to restore all the records"); // the next line makes sure that reload works properly. It looks useless, // but it actually test that a grouped local record can be reloaded without @@ -145,6 +147,51 @@ QUnit.module('Views', { kanban.destroy(); }); + QUnit.test('basic grouped rendering with active field', function (assert) { + assert.expect(9); + + // add active field on partner model and make all records active + this.data.partner.fields.active = {string: 'Active', type: 'char', default: true}; + + var envIDs = [1, 2, 3, 4]; // the ids that should be in the environment during this test + var kanban = createView({ + View: KanbanView, + model: 'partner', + data: this.data, + arch: '' + + '' + + '' + + '' + + '
    ' + + '
    ', + groupBy: ['bar'], + intercepts: { + env_updated: function (event) { + assert.deepEqual(event.data.env.ids, envIDs, + "should notify the environment with the correct ids"); + }, + }, + }); + + // check archive/restore all actions in kanban header's config dropdown + assert.ok(kanban.$('.o_kanban_header:first .o_kanban_config .o_column_archive_records').length, "should be able to archive all the records"); + assert.ok(kanban.$('.o_kanban_header:first .o_kanban_config .o_column_unarchive_records').length, "should be able to restore all the records"); + + // archive the records of the first column + assert.strictEqual(kanban.$('.o_kanban_group:last .o_kanban_record').length, 3, + "last column should contain 3 records"); + envIDs = [4]; + kanban.$('.o_kanban_group:last .o_column_archive_records').click(); // Click on 'Archive All' + assert.ok($('.modal').length, 'a confirm modal should be displayed'); + $('.modal .modal-footer .btn-default').click(); // Click on 'Cancel' + assert.strictEqual(kanban.$('.o_kanban_group:last .o_kanban_record').length, 3, "still last column should contain 3 records"); + kanban.$('.o_kanban_group:last .o_column_archive_records').click(); + assert.ok($('.modal').length, 'a confirm modal should be displayed'); + $('.modal .modal-footer .btn-primary').click(); // Click on 'Ok' + assert.strictEqual(kanban.$('.o_kanban_group:last .o_kanban_record').length, 0, "last column should not contain any records"); + kanban.destroy(); + }); + QUnit.test('pager should be hidden in grouped mode', function (assert) { assert.expect(1); @@ -1684,7 +1731,7 @@ QUnit.module('Views', { }); QUnit.test('delete a column in grouped on m2o', function (assert) { - assert.expect(29); + assert.expect(33); testUtils.patch(KanbanRenderer, { _renderGrouped: function () { @@ -1741,6 +1788,8 @@ QUnit.module('Views', { "should be able to edit the column"); assert.ok(kanban.$('.o_kanban_group:first .o_column_delete').length, "should be able to delete the column"); + assert.ok(!kanban.$('.o_kanban_group:first .o_column_archive_records').length, "should not be able to archive all the records"); + assert.ok(!kanban.$('.o_kanban_group:first .o_column_unarchive_records').length, "should not be able to restore all the records"); // delete second column (first cancel the confirm request, then confirm) kanban.$('.o_kanban_group:last .o_column_delete').click(); // click on delete @@ -1763,6 +1812,8 @@ QUnit.module('Views', { 'Undefined column could not be deleted'); assert.ok(!kanban.$('.o_kanban_group:first .o_column_edit').length, 'Undefined column could not be edited'); + assert.ok(!kanban.$('.o_kanban_group:first .o_column_archive_records').length, "Records of undefined column could not be archived"); + assert.ok(!kanban.$('.o_kanban_group:first .o_column_unarchive_records').length, "Records of undefined column could not be restored"); assert.verifySteps(['read_group', 'unlink', 'read_group']); assert.strictEqual(kanban.renderer.widgets.length, 2, "the old widgets should have been correctly deleted"); diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js index fd2f77f068d51..c948528dcc60c 100644 --- a/addons/web/static/tests/views/list_tests.js +++ b/addons/web/static/tests/views/list_tests.js @@ -843,7 +843,7 @@ QUnit.module('Views', { }); QUnit.test('archiving one record', function (assert) { - assert.expect(9); + assert.expect(12); // add active field on foo model and make all records active this.data.foo.fields.active = {string: 'Active', type: 'boolean', default: true}; @@ -872,7 +872,13 @@ QUnit.module('Views', { assert.verifySteps(['/web/dataset/search_read']); list.sidebar.$('a:contains(Archive)').click(); + assert.strictEqual($('.modal').length, 1, 'a confirm modal should be displayed'); + $('.modal .modal-footer .btn-default').click(); // Click on 'Cancel' + assert.strictEqual(list.$('tbody td.o_list_record_selector').length, 4, "still should have 4 records"); + list.sidebar.$('a:contains(Archive)').click(); + assert.strictEqual($('.modal').length, 1, 'a confirm modal should be displayed'); + $('.modal .modal-footer .btn-primary').click(); // Click on 'Ok' assert.strictEqual(list.$('tbody td.o_list_record_selector').length, 3, "should have 3 records"); assert.verifySteps(['/web/dataset/search_read', '/web/dataset/call_kw/foo/write', '/web/dataset/search_read']); list.destroy();