summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorFabien Pinckaers <fp@openerp.com>2016-06-08 09:57:33 +0200
committerAaron Bohy <aab@odoo.com>2016-06-16 14:59:41 +0200
commitad0bc9adf2c739cc0dfdacda9a6eca9b5a59d9ef (patch)
tree698daa275197a5e1a9c3fcbb8029e91fc4377987 /addons
parent3c319b2b8b300321be2f296e1b47076e80654f1d (diff)
[ADD] project: onboarding tour
Also: - creation of a (archived by default) sample project with tasks, that the user can activate to discover the project app. - improvement of the simplified form view to create a new project
Diffstat (limited to 'addons')
-rw-r--r--addons/project/__openerp__.py2
-rw-r--r--addons/project/project.py34
-rw-r--r--addons/project/project_dashboard.xml24
-rw-r--r--addons/project/project_data.xml1
-rw-r--r--addons/project/project_mail_template_data.xml20
-rw-r--r--addons/project/project_view.xml19
-rw-r--r--addons/project/static/src/js/tour.js55
-rw-r--r--addons/project/tour_view.xml10
-rw-r--r--addons/project/views/project.xml1
9 files changed, 140 insertions, 26 deletions
diff --git a/addons/project/__openerp__.py b/addons/project/__openerp__.py
index 18edca8a60d..7550b6027ec 100644
--- a/addons/project/__openerp__.py
+++ b/addons/project/__openerp__.py
@@ -17,6 +17,7 @@
'resource',
'web_kanban',
'web_planner',
+ 'web_tour',
],
'description': """
Track multi-level projects, tasks, work done on tasks
@@ -44,6 +45,7 @@ Dashboard / Reports for Project Management will include:
'res_config_view.xml',
'views/project.xml',
'project_dashboard.xml',
+ 'tour_view.xml',
'web_planner_data.xml',
'project_mail_template_data.xml',
],
diff --git a/addons/project/project.py b/addons/project/project.py
index 674c41ad2de..5c46c6a4957 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -129,9 +129,11 @@ class project(osv.osv):
def _get_visibility_selection(self, cr, uid, context=None):
""" Overriden in portal_project to offer more options """
- return [('portal', _('Customer project')),
- ('employees', _('All employees')),
- ('followers', _('Private: followers only'))]
+ return [
+ ('employees', _('Visible by all employees')),
+ ('followers', _('On invitation only')),
+ ('portal', _('Shared with a customer'))
+ ]
def attachment_tree_view(self, cr, uid, ids, context):
task_ids = self.pool.get('project.task').search(cr, uid, [('project_id', 'in', ids)])
@@ -157,6 +159,27 @@ class project(osv.osv):
'context': "{'default_res_model': '%s','default_res_id': %d}" % (self._name, res_id)
}
+ def activate_sample_project(self, cr, uid, context=None):
+ """ Unarchives the sample project 'project.project_project_data' and
+ reloads the project dashboard """
+ # Unarchive sample project
+ data_obj = self.pool.get('ir.model.data')
+ proj_id = data_obj.xmlid_to_res_id(cr, uid, 'project.project_project_data')
+ if proj_id:
+ self.browse(cr, uid, proj_id, context=context).write({'active': True})
+
+ # Change the help message on the action (no more activate project)
+ act_id = data_obj.xmlid_to_res_id(cr, uid, 'project.open_view_project_all')
+ action = None
+ if act_id:
+ act_window_obj = self.pool.get('ir.actions.act_window')
+ act_window_obj.write(cr, SUPERUSER_ID, [act_id], {
+ "help": _('''<p class="oe_view_nocontent_create">Click to create a new project.</p>''')
+ }, context=context)
+ action = act_window_obj.read(cr, uid, [act_id])[0]
+ # Reload the dashboard
+ return action
+
def _get_favorite(self, cr, uid, ids, name, args, context=None):
return dict((project.id, uid in project.favorite_user_ids.ids) for project in self.browse(cr, uid, ids, context=context))
@@ -195,7 +218,7 @@ class project(osv.osv):
"with Tasks (or optionally Issues if the Issue Tracker module is installed)."),
'alias_model': fields.selection(_alias_models, "Alias Model", select=True, required=True,
help="The kind of document created when an email is received on this project's email alias"),
- 'privacy_visibility': fields.selection(_visibility_selection, 'Privacy / Visibility', required=True,
+ 'privacy_visibility': fields.selection(_visibility_selection, 'Privacy', required=True,
help="Holds visibility of the tasks or issues that belong to the current project:\n"
"- Portal : employees see everything;\n"
" if portal is activated, portal users see the tasks or issues followed by\n"
@@ -350,6 +373,9 @@ class project(osv.osv):
self.write(cr, SUPERUSER_ID, not_fav_project_ids, {'favorite_user_ids': [(4, uid)]}, context=context)
self.write(cr, SUPERUSER_ID, favorite_project_ids, {'favorite_user_ids': [(3, uid)]}, context=context)
+ @api.multi
+ def close_dialog(self):
+ return {'type': 'ir.actions.act_window_close'}
class task(osv.osv):
_name = "project.task"
diff --git a/addons/project/project_dashboard.xml b/addons/project/project_dashboard.xml
index 50b11d9223c..d6f7355d144 100644
--- a/addons/project/project_dashboard.xml
+++ b/addons/project/project_dashboard.xml
@@ -4,19 +4,27 @@
<field name="model">project.project</field>
<field name="arch" type="xml">
<form string="Project">
- <sheet string="Project">
- <div class="oe_title">
- <h1>
- <field name="name" placeholder="Project Name"/>
- </h1>
- </div>
- </sheet>
+ <sheet>
+ <group>
+ <field name="name" class="o_project_name oe_inline"
+ string="Project Name" placeholder="e.g. Office Party"/>
+ <label for="alias_name" string="Choose a Project Email" attrs="{'invisible': [('alias_domain', '=', False)]}"/>
+ <div name="alias_def" attrs="{'invisible': [('alias_domain', '=', False)]}">
+ <field name="alias_name" class="oe_inline"/>@<field name="alias_domain" class="oe_inline" readonly="1"/>
+ </div>
+ </group>
+ <footer>
+ <button string="Create" name="close_dialog" type="object" class="btn-primary"/>
+ <button string="Discard" class="btn-default" special="cancel"/>
+ </footer>
+
+ </sheet>
</form>
</field>
</record>
<record id="open_create_project" model="ir.actions.act_window">
- <field name="name">Create Project</field>
+ <field name="name">Create a Project</field>
<field name="res_model">project.project</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
diff --git a/addons/project/project_data.xml b/addons/project/project_data.xml
index a3639c73996..16b88df0a52 100644
--- a/addons/project/project_data.xml
+++ b/addons/project/project_data.xml
@@ -115,6 +115,7 @@
<field name="name">Start here to discover Odoo</field>
<field name="privacy_visibility">followers</field>
<field name="user_id" ref="base.user_root"/>
+ <field name="active" eval="False"/>
<field name="alias_model">project.task</field>
<field name="alias_name">discover</field>
<field name="alias_model_id" ref="model_project_task"/>
diff --git a/addons/project/project_mail_template_data.xml b/addons/project/project_mail_template_data.xml
index 229b33704ab..489643afa6a 100644
--- a/addons/project/project_mail_template_data.xml
+++ b/addons/project/project_mail_template_data.xml
@@ -11,7 +11,7 @@
<field name="auto_delete" eval="True"/>
<field name="scheduled_date">${(datetime.datetime.now() + relativedelta(days=3)).strftime('%Y-%m-%d %H:%M')}</field>
<field name="body_html" ><![CDATA[
- % set last_created_project = user.env['project.project'].search([], order="create_date desc")[0]
+ % set last_created_project = user.env['project.project'].search([('alias_id','<>',False)], order="create_date desc")[0]
<div style="margin: 10px auto;">
<table cellspacing="0" cellpadding="0" style="width:100%;">
@@ -35,14 +35,16 @@
<p dir="ltr" style="margin-top:0pt;margin-bottom:8pt;">
<span style="font-size:13px;font-weight:bold;">What’s next?</span></p>
<ul style="margin-top:0pt;margin-bottom:0pt;font-size:13px;list-style-type:disc;">
- <li dir="ltr">
- <p dir="ltr" style="margin-top:0pt;margin-bottom:0pt;">
- <span>Try creating a task by sending an email to </span>
- <a href="mailto:${last_created_project.alias_id.name_get()[0][1] if last_created_project.alias_id.alias_domain else user.company_id.email}">
- <span style="font-weight:bold; text-decoration:underline;">${last_created_project.alias_id.name_get()[0][1] if last_created_project.alias_id.alias_domain else user.company_id.email}</span>
- </a>
- </p>
- </li>
+ % if last_created_project:
+ <li dir="ltr">
+ <p dir="ltr" style="margin-top:0pt;margin-bottom:0pt;">
+ <span>Try creating a task by sending an email to </span>
+ <a href="mailto:${last_created_project.alias_id.name_get()[0][1] if last_created_project.alias_id.alias_domain else user.company_id.email}">
+ <span style="font-weight:bold; text-decoration:underline;">${last_created_project.alias_id.name_get()[0][1] if last_created_project.alias_id.alias_domain else user.company_id.email}</span>
+ </a>
+ </p>
+ </li>
+ % endif
<li dir="ltr">
<p dir="ltr" style="margin-top:0pt;margin-bottom:8pt;">
<span><a href="/web#view_type=list&model=res.users&action=base.action_res_users">
diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml
index 8864ab5694f..9fbfada2b12 100644
--- a/addons/project/project_view.xml
+++ b/addons/project/project_view.xml
@@ -53,6 +53,7 @@
<field name="res_model">project.task</field>
<field name="view_mode">kanban,tree,form,calendar,pivot,graph</field>
<field name="context">{
+ 'group_by': 'stage_id',
'search_default_project_id': [active_id],
'default_project_id': active_id,
}</field>
@@ -182,6 +183,14 @@
</field>
</record>
+ <record id="activate_sample_project" model="ir.actions.server">
+ <field name="name">Activate Sample Project</field>
+ <field name="model_id" ref="project.model_project_project"/>
+ <field name="code">
+ action = self.activate_sample_project(cr, uid, context=context)
+ </field>
+ </record>
+
<record id="open_view_project_all" model="ir.actions.act_window">
<field name="name">Projects</field>
<field name="res_model">project.project</field>
@@ -189,11 +198,11 @@
<field name="domain">[]</field>
<field name="view_mode">kanban,form</field>
<field name="search_view_id" ref="view_project_project_filter"/>
+ <field name="target">main</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
- Create a new project.
- </p><p>
- Organize your activities (plan tasks, track issues, invoice timesheets) for internal, personal or customer projects.
+ Click to create a new project.<br/>
+ <i>Or <a type="action" name="%(project.activate_sample_project)d">activate a sample project</a> to play with.</i>
</p>
</field>
</record>
@@ -221,7 +230,7 @@
<field name="model">project.task</field>
<field eval="2" name="priority"/>
<field name="arch" type="xml">
- <form string="Project">
+ <form string="Task" class="o_form_project_tasks">
<header>
<field name="stage_id" widget="statusbar" clickable="True"
options="{'fold_field': 'fold'}"/>
@@ -290,7 +299,7 @@
<field name="name">project.task.kanban</field>
<field name="model">project.task</field>
<field name="arch" type="xml">
- <kanban default_group_by="stage_id" class="o_kanban_small_column" on_create="quick_create">
+ <kanban class="o_kanban_small_column o_kanban_project_tasks" on_create="quick_create">
<field name="color"/>
<field name="priority"/>
<field name="stage_id" options='{"group_by_tooltip": {"description": "Stage Description", "legend_priority": "Use of stars"}}'/>
diff --git a/addons/project/static/src/js/tour.js b/addons/project/static/src/js/tour.js
new file mode 100644
index 00000000000..37cb7d19d66
--- /dev/null
+++ b/addons/project/static/src/js/tour.js
@@ -0,0 +1,55 @@
+odoo.define('project.tour', function(require) {
+"use strict";
+
+var core = require('web.core');
+var tour = require('web_tour.tour');
+
+var _t = core._t;
+
+tour.register('project_tour', {
+ 'skip_enabled': true,
+}, [{
+ trigger: '.o_app[data-menu-xmlid="base.menu_main_pm"], .oe_menu_toggler[data-menu-xmlid="base.menu_main_pm"]',
+ content: _t('Want a better way to <b>manage your projects</b>? <i>It starts here.</i>'),
+ position: 'bottom',
+}, {
+ trigger: '.o-kanban-button-new',
+ extra_trigger: '.o_project_kanban',
+ content: _t('Let\'s create your first project.'),
+ position: 'right',
+ width: 200,
+}, {
+ trigger: 'input.o_project_name',
+ content: _t('Choose a <b>project name</b>. (e.g. Website Launch, Product Development, Office Party)'),
+ position: 'right',
+}, {
+ trigger: '.o_project_kanban .o_kanban_record:first-child',
+ content: _t('Let\'s <b>go to your project</b> and start organizing tasks.'),
+ position: 'right',
+}, {
+ trigger: ".o_kanban_project_tasks .o_column_quick_create",
+ content: _t("Add columns to setup <b>tasks stages</b>.<br/><i>e.g. Specification &gt; Development &gt; Tests</i>"),
+ position: "right"
+}, {
+ trigger: ".o-kanban-button-new",
+ extra_trigger: '.o_kanban_project_tasks .o_kanban_group:nth-child(2)',
+ content: _t("Now that the project is setup, <b>create a few tasks</b>."),
+ position: "right"
+}, {
+ trigger: ".o_kanban_record:nth-child(3)",
+ extra_trigger: '.o_kanban_project_tasks',
+ content: _t("<b>Drag &amp; drop tasks</b> between columns as you work on them."),
+ position: "right"
+}, {
+ trigger: ".o_kanban_record .o_priority_star",
+ extra_trigger: '.o_kanban_project_tasks',
+ content: _t("<b>Star tasks</b> to mark your favorites, the team sprint backlog, priorities, etc."),
+ position: "bottom"
+}, {
+ trigger: ".breadcrumb li:not(.active):last",
+ extra_trigger: '.o_form_project_tasks',
+ content: _t("Use the breadcrumbs to <b>go back to tasks</b>."),
+ position: "bottom"
+}]);
+
+});
diff --git a/addons/project/tour_view.xml b/addons/project/tour_view.xml
new file mode 100644
index 00000000000..afd0c089d93
--- /dev/null
+++ b/addons/project/tour_view.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <!-- Make the xmlid of menus required by the Project tour available in webclient -->
+ <record id="base.menu_main_pm" model="ir.ui.menu">
+ <field name="load_xmlid" eval="True"/>
+ </record>
+ <record id="menu_projects" model="ir.ui.menu">
+ <field name="load_xmlid" eval="True"/>
+ </record>
+</odoo>
diff --git a/addons/project/views/project.xml b/addons/project/views/project.xml
index cdc20c6dc8d..099eabed05d 100644
--- a/addons/project/views/project.xml
+++ b/addons/project/views/project.xml
@@ -5,6 +5,7 @@
<xpath expr="." position="inside">
<link rel="stylesheet" href="/project/static/src/css/project.css"/>
<script type="text/javascript" src="/project/static/src/js/project.js"></script>
+ <script type="text/javascript" src="/project/static/src/js/tour.js"></script>
<link rel="stylesheet" href="/project/static/src/less/project_dashboard.less"/>
<script type="text/javascript" src="/project/static/src/js/web_planner_project.js"></script>