[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
This commit is contained in:
Bruno Boi
2023-03-29 09:33:35 +02:00
parent ba45832946
commit d2575b50eb
6 changed files with 25 additions and 1 deletions
@@ -13,6 +13,7 @@ const clock = markup(`<a class="fa fa-clock-o"></a>`);
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')],
@@ -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')],
@@ -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;
}
@@ -28,7 +28,7 @@
<small t-if="!env.isSmall and state.hasInputFocused" class="o_discard_msg text-muted float-end">
Esc to discard
</small>
<t t-if="props.exampleData and !env.isSmall">
<t t-if="canShowExamples and !env.isSmall">
<button type="button" class="btn btn-link o_kanban_examples p-0" t-on-click="showExamples">See examples</button>
</t>
</div>
@@ -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
@@ -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: [
{