[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
This commit is contained in:
committed by
Aaron Bohy
parent
3c319b2b8b
commit
ad0bc9adf2
@@ -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',
|
||||
],
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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"}}'/>
|
||||
|
||||
@@ -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 > Development > 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 & 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"
|
||||
}]);
|
||||
|
||||
});
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user