[MERGE][IMP] web, utm: add kanban example stages for UTM campaigns

Inspired by what is done in the task kanban of the project module,
add examples of kanban stage setups for UTM campaigns, and allow users
to load them.

There have also been some minor changes to the campaigns view:

- The helper message when there are no UTM campaigns has been changed
  to a more descriptive message.
- All stages that existed by default (hardcoded in the data XML) have
  been removed except default New one. An user with a fresh database will
  have no stages in their kanban. The old hardcoded stages have been moved
  to the demo data instead, so they will still be added by default if the
  user installs demo data.
- The ghost columns that appear in the kanban when no stages exist have
  been renamed to match the old stages that were hardcoded.
- When the user opens the view to create a column, the 'See examples'
  link will appear below the 'Column title', just like in the project
  addon, and clicking it will open some examples specifically made for UTM
  campaigns. Clicking on the 'Use This For My Kanban' button will load the
  stages of the selected example.
- A min-height property has been given to the example modal view so that
  the view does not change size depending on the number of rows in the
  ghost columns.

Sub commits are present to allow tweaking the feature more that currently
feasible.

Task ID: 2047369
PR #48299

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
Odoo's Mergebot
2020-04-30 11:41:46 +02:00
committed by GitHub
11 changed files with 92 additions and 41 deletions
@@ -39,6 +39,7 @@ function escFormat() {
kanbanExamplesRegistry.add('project', {
ghostColumns: [_lt('New'), _lt('Assigned'), _lt('In Progress'), _lt('Done')],
applyExamplesText: _lt("Use This For My Project"),
examples:[{
name: _lt('Software Development'),
columns: [_lt('Backlog'), _lt('Specifications'), _lt('Development'), _lt('Tests'), _lt('Delivered')],
+2 -12
View File
@@ -1,22 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- UTM Stage -->
<!-- This one is kept in data instead of demo to avoid crashing if the user starts creating campaigns
before stages have been created, as they are mandatory -->
<record id="default_utm_stage" model="utm.stage">
<field name="name">New</field>
<field name="sequence">10</field>
</record>
<record id="campaign_stage_1" model="utm.stage">
<field name="name">Schedule</field>
<field name="sequence">10</field>
</record>
<record id="campaign_stage_2" model="utm.stage">
<field name="name">Design</field>
<field name="sequence">20</field>
</record>
<record id="campaign_stage_3" model="utm.stage">
<field name="name">Sent</field>
<field name="sequence">30</field>
</record>
<!-- UTM Source -->
<record model="utm.source" id="utm_source_search_engine">
+38 -24
View File
@@ -1,26 +1,40 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- UTM Campaigns -->
<record model="utm.campaign" id="utm_campaign_fall_drive">
<field name="name">Sale</field>
<field name="stage_id" ref="utm.default_utm_stage"/>
<field name="is_website" eval="True"/>
</record>
<record model="utm.campaign" id="utm_campaign_christmas_special">
<field name="name">Christmas Special</field>
<field name="stage_id" ref="utm.default_utm_stage"/>
<field name="is_website" eval="True"/>
</record>
<record model="utm.campaign" id="utm_campaign_email_campaign_services">
<field name="name">Email Campaign - Services</field>
<field name="stage_id" ref="utm.default_utm_stage"/>
<field name="is_website" eval="True"/>
</record>
<record model="utm.campaign" id="utm_campaign_email_campaign_products">
<field name="name">Email Campaign - Products</field>
<field name="stage_id" ref="utm.default_utm_stage"/>
<field name="is_website" eval="True"/>
</record>
</data>
<data>
<!-- UTM Stage -->
<record id="campaign_stage_1" model="utm.stage">
<field name="name">Schedule</field>
<field name="sequence">10</field>
</record>
<record id="campaign_stage_2" model="utm.stage">
<field name="name">Design</field>
<field name="sequence">20</field>
</record>
<record id="campaign_stage_3" model="utm.stage">
<field name="name">Sent</field>
<field name="sequence">30</field>
</record>
<!-- UTM Campaigns -->
<record model="utm.campaign" id="utm_campaign_fall_drive">
<field name="name">Sale</field>
<field name="stage_id" ref="utm.default_utm_stage" />
<field name="is_website" eval="True" />
</record>
<record model="utm.campaign" id="utm_campaign_christmas_special">
<field name="name">Christmas Special</field>
<field name="stage_id" ref="utm.default_utm_stage" />
<field name="is_website" eval="True" />
</record>
<record model="utm.campaign" id="utm_campaign_email_campaign_services">
<field name="name">Email Campaign - Services</field>
<field name="stage_id" ref="utm.default_utm_stage" />
<field name="is_website" eval="True" />
</record>
<record model="utm.campaign" id="utm_campaign_email_campaign_products">
<field name="name">Email Campaign - Products</field>
<field name="stage_id" ref="utm.default_utm_stage" />
<field name="is_website" eval="True" />
</record>
</data>
</odoo>
@@ -0,0 +1,34 @@
odoo.define('utm.campaing_kanban_examples', function (require) {
'use strict';
var core = require('web.core');
var kanbanExamplesRegistry = require('web.kanban_examples_registry');
var _lt = core._lt;
kanbanExamplesRegistry.add('utm_campaign', {
ghostColumns: [_lt('Ideas'), _lt('Design'), _lt('Review'), _lt('Send'), _lt('Done')],
applyExamplesText: _lt("Use This For My Campaigns"),
examples: [{
name: _lt('Creative Flow'),
columns: [_lt('Ideas'), _lt('Design'), _lt('Review'), _lt('Send'), _lt('Done')],
description: _lt("Collect ideas, design creative content and publish it once reviewed."),
}, {
name: _lt('Event-driven Flow'),
columns: [_lt('Later'), _lt('This Month'), _lt('This Week'), _lt('Running'), _lt('Sent')],
description: _lt("Track incoming events (e.g. : Christmas, Black Friday, ...) and publish timely content."),
}, {
name: _lt('Soft-Launch Flow'),
columns: [_lt('Pre-Launch'), _lt('Soft-Launch'), _lt('Deploy'), _lt('Report'), _lt('Done')],
description: _lt("Prepare your Campaign, test it with part of your audience and deploy it fully afterwards."),
}, {
name: _lt('Audience-driven Flow'),
columns: [_lt('New'), _lt('Gather Data'), _lt('List-Building'), _lt('Copywriting'), _lt('Sent')],
description: _lt("Gather data, build a recipient list and write content based on your Marketing target."),
}, {
name: _lt('Approval-based Flow'),
columns: [_lt('New'), _lt('To be Approved'), _lt('Approved'), _lt('Deployed')],
description: _lt("Prepare Campaigns and get them approved before making them go live."),
}],
});
});
+3
View File
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="assets_backend" name="utm assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/utm/static/src/js/utm_campaign_kanban_examples.js"></script>
</xpath>
<xpath expr="link[last()]" position="after">
<link rel="stylesheet" type="text/scss" href="/utm/static/src/scss/utm_views.scss"/>
</xpath>
+1 -1
View File
@@ -73,7 +73,7 @@
<field name="name">utm.campaign.view.kanban</field>
<field name="model">utm.campaign</field>
<field name="arch" type="xml">
<kanban default_group_by='stage_id' class="o_utm_kanban" on_create="quick_create" quick_create_view="utm.utm_campaign_view_form_quick_create">
<kanban default_group_by='stage_id' class="o_utm_kanban" on_create="quick_create" quick_create_view="utm.utm_campaign_view_form_quick_create" examples="utm_campaign">
<field name='color'/>
<field name='user_id'/>
<field name="stage_id"/>
+4 -1
View File
@@ -18,7 +18,10 @@
<field name="view_mode">kanban,tree,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Define a new UTM campaign
Create a campaign
</p>
<p>
Campaigns are used to centralize your marketing efforts and track their results.
</p>
</field>
</record>
@@ -32,6 +32,7 @@ var ColumnQuickCreate = Widget.extend({
*/
init: function (parent, options) {
this._super.apply(this, arguments);
this.applyExamplesText = options.applyExampleText || _t("Use This For My Kanban");
this.examples = options.examples;
this.folded = true;
this.isMobile = false;
@@ -186,12 +187,12 @@ var ColumnQuickCreate = Widget.extend({
})),
buttons: [{
classes: 'btn-primary float-right',
text: _t('Use This For My Project'),
text: this.applyExamplesText,
close: true,
click: function () {
const activeExample = self.examples[this.$('.nav-link.active').data("exampleIndex")];
activeExample.columns.forEach(column => {
self.trigger_up('quick_create_add_column', {value: column.toString()});
self.trigger_up('quick_create_add_column', { value: column.toString(), foldQuickCreate: true });
});
}
}, {
@@ -226,7 +226,10 @@ var KanbanController = BasicController.extend({
}).then(function () {
return self.update({}, {reload: false});
}).then(function () {
self.renderer.quickCreateToggleFold();
let quickCreateFolded = self.renderer.quickCreate.folded;
if (ev.data.foldQuickCreate ? !quickCreateFolded : quickCreateFolded) {
self.renderer.quickCreateToggleFold();
}
self.renderer.trigger_up("quick_create_column_created");
});
});
@@ -373,6 +373,7 @@ var KanbanRenderer = BasicRenderer.extend({
if (this.createColumnEnabled) {
this.quickCreate = new ColumnQuickCreate(this, {
applyExamplesText: this.examples && this.examples.applyExamplesText,
examples: this.examples && this.examples.examples,
});
this.defs.push(this.quickCreate.appendTo(fragment).then(function () {
@@ -33,6 +33,7 @@
// content
.o_kanban_examples_dialog_content {
flex: 1 1 100%;
min-height: 300px;
.o_kanban_examples_description {
padding: 16px 16px 0;