From d2575b50eb785d63edd3321dda5832c844f1f184 Mon Sep 17 00:00:00 2001 From: Bruno Boi Date: Tue, 28 Mar 2023 07:58:41 +0000 Subject: [PATCH] [FIX] web,*: restrict kanban examples availability *: project,utm **Before this commit** With the following steps, it is possible to use kanban column quick creation with unexpected fields, i.e. creating projects instead of stages inside a project: - Project > New > Groupby 'Project' - Click on the "see examples" link in the column in creation - Apply any column examples - Instead of stages inside the project, new projects are created **After this commit** The kanban_examples registry elements should now clearly state which are the allowed groupby fields. The 'See examples' link will not be displayed if the groupby field is not allowed. **Usage** See the modified files in project and utm modules in this commit. Taskid: 3246042 Part-of: odoo/odoo#115909 --- .../static/src/js/project_task_kanban_examples.js | 1 + .../static/src/js/utm_campaign_kanban_examples.js | 1 + .../src/views/kanban/kanban_column_quick_create.js | 6 ++++++ .../src/views/kanban/kanban_column_quick_create.xml | 2 +- .../web/static/src/views/kanban/kanban_renderer.js | 13 +++++++++++++ addons/web/static/tests/views/kanban_view_tests.js | 3 +++ 6 files changed, 25 insertions(+), 1 deletion(-) 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 3a50e3ade53..e4aa0bfe269 100644 --- a/addons/project/static/src/js/project_task_kanban_examples.js +++ b/addons/project/static/src/js/project_task_kanban_examples.js @@ -13,6 +13,7 @@ const clock = markup(``); const exampleData = { ghostColumns: [_lt('New'), _lt('Assigned'), _lt('In Progress'), _lt('Done')], applyExamplesText: _lt("Use This For My Project"), + allowedGroupBys: ['stage_id'], examples:[{ name: _lt('Software Development'), columns: [_lt('Backlog'), _lt('Specifications'), _lt('Development'), _lt('Tests'), _lt('Delivered')], diff --git a/addons/utm/static/src/js/utm_campaign_kanban_examples.js b/addons/utm/static/src/js/utm_campaign_kanban_examples.js index f73bd25a2e5..e3fcc6bd832 100644 --- a/addons/utm/static/src/js/utm_campaign_kanban_examples.js +++ b/addons/utm/static/src/js/utm_campaign_kanban_examples.js @@ -6,6 +6,7 @@ import { registry } from "@web/core/registry"; const exampleData = { ghostColumns: [_lt('Ideas'), _lt('Design'), _lt('Review'), _lt('Send'), _lt('Done')], applyExamplesText: _lt("Use This For My Campaigns"), + allowedGroupBys: ['stage_id'], examples: [{ name: _lt('Creative Flow'), columns: [_lt('Ideas'), _lt('Design'), _lt('Review'), _lt('Send'), _lt('Done')], diff --git a/addons/web/static/src/views/kanban/kanban_column_quick_create.js b/addons/web/static/src/views/kanban/kanban_column_quick_create.js index 6e611567b9d..e32bbb7fcf7 100644 --- a/addons/web/static/src/views/kanban/kanban_column_quick_create.js +++ b/addons/web/static/src/views/kanban/kanban_column_quick_create.js @@ -45,6 +45,12 @@ export class KanbanColumnQuickCreate extends Component { useHotkey("escape", () => this.fold()); } + get canShowExamples() { + const { allowedGroupBys = [], examples = [] } = this.props.exampleData || {}; + const hasExamples = Boolean(examples.length); + return hasExamples && allowedGroupBys.includes(this.props.groupByField.name); + } + get relatedFieldName() { return this.props.groupByField.string; } diff --git a/addons/web/static/src/views/kanban/kanban_column_quick_create.xml b/addons/web/static/src/views/kanban/kanban_column_quick_create.xml index 26c631c5175..4b3b6d9dce8 100644 --- a/addons/web/static/src/views/kanban/kanban_column_quick_create.xml +++ b/addons/web/static/src/views/kanban/kanban_column_quick_create.xml @@ -28,7 +28,7 @@ Esc to discard - + diff --git a/addons/web/static/src/views/kanban/kanban_renderer.js b/addons/web/static/src/views/kanban/kanban_renderer.js index e4377c26bc9..71166c13d4f 100644 --- a/addons/web/static/src/views/kanban/kanban_renderer.js +++ b/addons/web/static/src/views/kanban/kanban_renderer.js @@ -50,6 +50,16 @@ export function canQuickCreate(list) { ); } +function validateColumnQuickCreateExamples(data) { + const { allowedGroupBys = [], examples = [] } = data; + if (!allowedGroupBys.length) { + throw new Error("The example data must contain an array of allowed groupbys"); + } + if (!examples.length) { + throw new Error("The example data must contain an array of examples"); + } +} + export class KanbanRenderer extends Component { static template = "web.KanbanRenderer"; static components = { @@ -88,6 +98,9 @@ export class KanbanRenderer extends Component { this.exampleData = registry .category("kanban_examples") .get(this.props.archInfo.examples, null); + if (this.exampleData) { + validateColumnQuickCreateExamples(this.exampleData); + } this.ghostColumns = this.generateGhostColumns(); // Sortable diff --git a/addons/web/static/tests/views/kanban_view_tests.js b/addons/web/static/tests/views/kanban_view_tests.js index 847c0386d94..e121af48a5d 100644 --- a/addons/web/static/tests/views/kanban_view_tests.js +++ b/addons/web/static/tests/views/kanban_view_tests.js @@ -6449,6 +6449,7 @@ QUnit.module("Views", (hooks) => { QUnit.test("quick create column and examples", async (assert) => { serviceRegistry.add("dialog", dialogService, { force: true }); registry.category("kanban_examples").add("test", { + allowedGroupBys: ["product_id"], examples: [ { name: "A first example", @@ -6555,6 +6556,7 @@ QUnit.module("Views", (hooks) => { serviceRegistry.add("dialog", dialogService, { force: true }); const applyExamplesText = "Use This For My Test"; registry.category("kanban_examples").add("test", { + allowedGroupBys: ["product_id"], applyExamplesText: applyExamplesText, examples: [ { @@ -6601,6 +6603,7 @@ QUnit.module("Views", (hooks) => { async (assert) => { serverData.models.partner.records = []; registry.category("kanban_examples").add("test", { + allowedGroupBys: ["product_id"], ghostColumns: ["Ghost 1", "Ghost 2", "Ghost 3", "Ghost 4"], examples: [ {