From 756aa60ecfc14d16975d3c5d74f9952bfea8d4db Mon Sep 17 00:00:00 2001 From: Jinal Patel Date: Wed, 6 Feb 2019 11:32:01 +0000 Subject: [PATCH] [IMP] web, project: improve examples background on kanban quick create column MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit makes the use of the kanban more intuitive by changing the view's example background columns labels. kanbanExamplesRegistry will have object as a value instead of array, ghostColumns and examples will be the key where ghostColumns defines column titles for example background on column quick create and examples will be array of examples which will be displayed on click of See Examples link in quick create column If ghoseColumns are not defined then dynamically ghost columns will be generated with titles like Column 1, Column2... task- 1937198 closes odoo/odoo#30911 Signed-off-by: Jérome Maes (jem) Co-authored-by: Mohammed Shekha --- .../src/js/project_task_kanban_examples.js | 113 +++++++++--------- .../src/js/views/kanban/kanban_renderer.js | 20 +++- addons/web/static/src/xml/kanban.xml | 4 +- addons/web/static/tests/views/kanban_tests.js | 90 ++++++++++++-- doc/reference/views.rst | 3 + 5 files changed, 162 insertions(+), 68 deletions(-) diff --git a/addons/project/static/src/js/project_task_kanban_examples.js b/addons/project/static/src/js/project_task_kanban_examples.js index fb65b30445d..390be680d84 100644 --- a/addons/project/static/src/js/project_task_kanban_examples.js +++ b/addons/project/static/src/js/project_task_kanban_examples.js @@ -24,60 +24,63 @@ function escFormat() { return _.str.sprintf.apply(_.str, arguments); } -kanbanExamplesRegistry.add('project', [{ - name: _t('Software Development'), - columns: [_t('Backlog'), _t('Specifications'), _t('Development'), _t('Tests'), _t('Delivered')], - description: escFormat(_t('Prioritize Tasks by using the %s icon.'+ - '%s Use the %s button to signalize to your colleagues that a task is ready for the next stage.'+ - '%s Use the %s to signalize a problem or a need for discussion on a task.'), star, '
', greenBullet, '
', redBullet), - bullets: [greenBullet, redBullet, star], -}, { - name: _t('Agile'), - columns: [_t('Backlog'), _t('Analysis'), _t('Development'), _t('Testing'), _t('Done')], - description: escFormat(_t('Waiting for the next stage: use %s and %s bullets.'), greenBullet, redBullet), - bullets: [greenBullet, redBullet], -}, { - name: _t('Digital Marketing'), - columns: [_t('Ideas'), _t('Researching'), _t('Writing'), _t('Editing'), _t('Done')], - description: escFormat(_t('Everyone can propose ideas, and the Editor marks the best ones ' + - 'as %s. Attach all documents or links to the task directly, to have all information about ' + - 'a research centralized.'), greenBullet), - bullets: [greenBullet, redBullet], -}, { - name: _t('Customer Feedback'), - columns: [_t('New'), _t('In development'), _t('Done'), _t('Refused')], - description: escFormat(_t('Customers propose feedbacks by email; Odoo creates tasks ' + - 'automatically, and you can communicate on the task directly. Your managers decide which ' + - 'feedback is accepted %s and which feedback is moved to the "Refused" column.'), greenBullet), - bullets: [greenBullet, redBullet], -}, { - name: _t('Getting Things Done (GTD)'), - columns: [_t('Inbox'), _t('Today'), _t('This Week'), _t('This Month'), _t('Long Term')], - description: _t('Fill your Inbox easily with the email gateway. Periodically review your ' + - 'Inbox and schedule tasks by moving them to others columns. Every day, you review the ' + - '"This Week" column to move important tasks "Today". Every Monday, you review the "This ' + - 'Month" column.'), -}, { - name: _t('Consulting'), - columns: [_t('New Projects'), _t('Resources Allocation'), _t('In Progress'), _t('Done')], - description: escFormat(_t('Manage the lifecycle of your project using the kanban view. Add newly acquired project, assign them and use the %s and %s to define if the project is ready for the next step.'), greenBullet, redBullet), - bullets: [greenBullet, redBullet], -}, { - name: _t('Research Project'), - columns: [_t('Brainstorm'), _t('Research'), _t('Draft'), _t('Final Document')], - description: escFormat(_t('Handle your idea gahtering within Tasks of your new Project and discuss them in the chatter of the tasks. Use the %s and %s to signalize what is the current status of your Idea'), greenBullet, redBullet), - bullets: [greenBullet, redBullet], -}, { - name: _t('Website Redesign'), - columns: [_t('Page Ideas'), _t('Copywriting'), _t('Design'), _t('Live')], - description: escFormat(_t('Handle your idea gahtering within Tasks of your new Project and discuss them in the chatter of the tasks. Use the %s and %s to signalize what is the current status of your Idea'), greenBullet, redBullet), -}, { - name: _t('T-shirt Printing'), - columns: [_t('New Orders'), _t('Logo Design'), _t('To Print'), _t('Done')], - description: escFormat(_t('Communicate with customers on the task using the email gateway. ' + - 'Attach logo designs to the task, so that information flow from designers to the workers ' + - 'who print the t-shirt. Organize priorities amongst orders %s using the icon.'), star), - bullets: [star], -}]); +kanbanExamplesRegistry.add('project', { + ghostColumns: [_t('New'), _t('Assigned'), _t('In Progress'), _t('Done')], + examples:[{ + name: _t('Software Development'), + columns: [_t('Backlog'), _t('Specifications'), _t('Development'), _t('Tests'), _t('Delivered')], + description: escFormat(_t('Prioritize Tasks by using the %s icon.'+ + '%s Use the %s button to signalize to your colleagues that a task is ready for the next stage.'+ + '%s Use the %s to signalize a problem or a need for discussion on a task.'), star, '
', greenBullet, '
', redBullet), + bullets: [greenBullet, redBullet, star], + }, { + name: _t('Agile'), + columns: [_t('Backlog'), _t('Analysis'), _t('Development'), _t('Testing'), _t('Done')], + description: escFormat(_t('Waiting for the next stage: use %s and %s bullets.'), greenBullet, redBullet), + bullets: [greenBullet, redBullet], + }, { + name: _t('Digital Marketing'), + columns: [_t('Ideas'), _t('Researching'), _t('Writing'), _t('Editing'), _t('Done')], + description: escFormat(_t('Everyone can propose ideas, and the Editor marks the best ones ' + + 'as %s. Attach all documents or links to the task directly, to have all information about ' + + 'a research centralized.'), greenBullet), + bullets: [greenBullet, redBullet], + }, { + name: _t('Customer Feedback'), + columns: [_t('New'), _t('In development'), _t('Done'), _t('Refused')], + description: escFormat(_t('Customers propose feedbacks by email; Odoo creates tasks ' + + 'automatically, and you can communicate on the task directly. Your managers decide which ' + + 'feedback is accepted %s and which feedback is moved to the "Refused" column.'), greenBullet), + bullets: [greenBullet, redBullet], + }, { + name: _t('Getting Things Done (GTD)'), + columns: [_t('Inbox'), _t('Today'), _t('This Week'), _t('This Month'), _t('Long Term')], + description: _t('Fill your Inbox easily with the email gateway. Periodically review your ' + + 'Inbox and schedule tasks by moving them to others columns. Every day, you review the ' + + '"This Week" column to move important tasks "Today". Every Monday, you review the "This ' + + 'Month" column.'), + }, { + name: _t('Consulting'), + columns: [_t('New Projects'), _t('Resources Allocation'), _t('In Progress'), _t('Done')], + description: escFormat(_t('Manage the lifecycle of your project using the kanban view. Add newly acquired project, assign them and use the %s and %s to define if the project is ready for the next step.'), greenBullet, redBullet), + bullets: [greenBullet, redBullet], + }, { + name: _t('Research Project'), + columns: [_t('Brainstorm'), _t('Research'), _t('Draft'), _t('Final Document')], + description: escFormat(_t('Handle your idea gahtering within Tasks of your new Project and discuss them in the chatter of the tasks. Use the %s and %s to signalize what is the current status of your Idea'), greenBullet, redBullet), + bullets: [greenBullet, redBullet], + }, { + name: _t('Website Redesign'), + columns: [_t('Page Ideas'), _t('Copywriting'), _t('Design'), _t('Live')], + description: escFormat(_t('Handle your idea gahtering within Tasks of your new Project and discuss them in the chatter of the tasks. Use the %s and %s to signalize what is the current status of your Idea'), greenBullet, redBullet), + }, { + name: _t('T-shirt Printing'), + columns: [_t('New Orders'), _t('Logo Design'), _t('To Print'), _t('Done')], + description: escFormat(_t('Communicate with customers on the task using the email gateway. ' + + 'Attach logo designs to the task, so that information flow from designers to the workers ' + + 'who print the t-shirt. Organize priorities amongst orders %s using the icon.'), star), + bullets: [star], + }], +}); }); diff --git a/addons/web/static/src/js/views/kanban/kanban_renderer.js b/addons/web/static/src/js/views/kanban/kanban_renderer.js index bd6c00a6802..5be98e4de52 100644 --- a/addons/web/static/src/js/views/kanban/kanban_renderer.js +++ b/addons/web/static/src/js/views/kanban/kanban_renderer.js @@ -13,6 +13,7 @@ var utils = require('web.utils'); var viewUtils = require('web.viewUtils'); var qweb = core.qweb; +var _t = core._t; function findInNode(node, predicate) { if (predicate(node)) { @@ -281,6 +282,20 @@ var KanbanRenderer = BasicRenderer.extend({ previousCard.focus(); } }, + /** + * Returns the default columns for the kanban view example background. + * You can override this method to easily customize the column names. + * + * @private + */ + _getGhostColumns: function () { + if (this.examples && this.examples.ghostColumns) { + return this.examples.ghostColumns; + } + return _.map(_.range(1, 5), function (num) { + return _.str.sprintf(_t("Column %s"), num); + }); + }, /** * Render the Example Ghost Kanban card on the background * @@ -288,7 +303,7 @@ var KanbanRenderer = BasicRenderer.extend({ * @param {DocumentFragment} fragment */ _renderExampleBackground: function (fragment) { - var $background = $(qweb.render('KanbanView.ExamplesBackground')); + var $background = $(qweb.render('KanbanView.ExamplesBackground', {ghostColumns: this._getGhostColumns()})); $background.appendTo(fragment); }, /** @@ -358,10 +373,9 @@ var KanbanRenderer = BasicRenderer.extend({ }, }); - // Enable column quickcreate if (this.createColumnEnabled) { this.quickCreate = new ColumnQuickCreate(this, { - examples: this.examples, + examples: this.examples && this.examples.examples, }); this.defs.push(this.quickCreate.appendTo(fragment).then(function () { // Open it directly if there is no column yet diff --git a/addons/web/static/src/xml/kanban.xml b/addons/web/static/src/xml/kanban.xml index 3a01370443f..424408f9340 100644 --- a/addons/web/static/src/xml/kanban.xml +++ b/addons/web/static/src/xml/kanban.xml @@ -191,9 +191,9 @@
- +
-
Column
+
diff --git a/addons/web/static/tests/views/kanban_tests.js b/addons/web/static/tests/views/kanban_tests.js index 5e2c4e0a8f6..7284caeae21 100644 --- a/addons/web/static/tests/views/kanban_tests.js +++ b/addons/web/static/tests/views/kanban_tests.js @@ -3355,14 +3355,16 @@ QUnit.module('Views', { QUnit.test('quick create column and examples', async function (assert) { assert.expect(12); - kanbanExamplesRegistry.add('test', [{ - name: "A first example", - columns: ["Column 1", "Column 2", "Column 3"], - description: "Some description", - }, { - name: "A second example", - columns: ["Col 1", "Col 2"], - }]); + kanbanExamplesRegistry.add('test', { + examples:[{ + name: "A first example", + columns: ["Column 1", "Column 2", "Column 3"], + description: "Some description", + }, { + name: "A second example", + columns: ["Col 1", "Col 2"], + }], + }); var kanban = await createView({ View: KanbanView, @@ -3417,6 +3419,78 @@ QUnit.module('Views', { kanban.destroy(); }); + QUnit.test('quick create column and examples background with ghostColumns titles', async function (assert) { + assert.expect(4); + + this.data.partner.records = []; + + kanbanExamplesRegistry.add('test', { + ghostColumns: ["Ghost 1", "Ghost 2", "Ghost 3", "Ghost 4"], + examples:[{ + name: "A first example", + columns: ["Column 1", "Column 2", "Column 3"], + description: "Some description", + }, { + name: "A second example", + columns: ["Col 1", "Col 2"], + }], + }); + + var kanban = await createView({ + View: KanbanView, + model: 'partner', + data: this.data, + arch: '' + + '' + + '' + + '
' + + '
' + + '
', + groupBy: ['product_id'], + }); + + assert.containsOnce(kanban, '.o_kanban_example_background', + "should have ExamplesBackground when no data"); + assert.strictEqual(kanban.$('.o_kanban_examples_group h6').text(), 'Ghost 1Ghost 2Ghost 3Ghost 4', + "ghost title should be correct"); + assert.containsOnce(kanban, '.o_column_quick_create', + "should have a ColumnQuickCreate widget"); + assert.containsOnce(kanban, '.o_column_quick_create .o_kanban_examples:visible', + "should not have a link to see examples as there is no examples registered"); + + kanban.destroy(); + }); + + QUnit.test('quick create column and examples background without ghostColumns titles', async function (assert) { + assert.expect(4); + + this.data.partner.records = []; + + var kanban = await createView({ + View: KanbanView, + model: 'partner', + data: this.data, + arch: '' + + '' + + '' + + '
' + + '
' + + '
', + groupBy: ['product_id'], + }); + + assert.containsOnce(kanban, '.o_kanban_example_background', + "should have ExamplesBackground when no data"); + assert.strictEqual(kanban.$('.o_kanban_examples_group h6').text(), 'Column 1Column 2Column 3Column 4', + "ghost title should be correct"); + assert.containsOnce(kanban, '.o_column_quick_create', + "should have a ColumnQuickCreate widget"); + assert.containsNone(kanban, '.o_column_quick_create .o_kanban_examples:visible', + "should not have a link to see examples as there is no examples registered"); + + kanban.destroy(); + }); + QUnit.test('if view was not grouped at start, it can be grouped and ungrouped', async function (assert) { assert.expect(3); diff --git a/doc/reference/views.rst b/doc/reference/views.rst index 12c0615d9b7..999839da2d0 100644 --- a/doc/reference/views.rst +++ b/doc/reference/views.rst @@ -1023,6 +1023,8 @@ attributes: the list view) ``class`` adds HTML classes to the root HTML element of the Kanban view +``examples`` + if set to a key in the `KanbanExamplesRegistry`_, examples on column setups will be available in the grouped kanban view. `Here `_ is an example of how to define those setups. ``group_create`` whether the "Add a new column" bar is visible or not. Default: true. ``group_delete`` @@ -2095,3 +2097,4 @@ The main additions of qweb-as-view to the basic qweb-as-template are: .. _kanban board: http://en.wikipedia.org/wiki/Kanban_board .. _pivot table: http://en.wikipedia.org/wiki/Pivot_table .. _XPath: http://en.wikipedia.org/wiki/XPath +.. _KanbanExamplesRegistry: https://github.com/odoo/odoo/blob/99821fdcf89aa66ac9561a972c6823135ebf65c0/addons/web/static/src/js/views/kanban/kanban_examples_registry.js