Browse Source

[IMP] help_popup module

pull/417/head
David Beal 9 years ago
parent
commit
a6a99ffeac
  1. 22
      help_popup/README.rst
  2. 24
      help_popup/__openerp__.py
  3. 43
      help_popup/demo/help.xml
  4. 142
      help_popup/model.py
  5. 46
      help_popup/report/all.xml
  6. 40
      help_popup/report/help.xml
  7. 17
      help_popup/report/report.xml
  8. 26
      help_popup/static/src/js/popup_help.js
  9. 5
      help_popup/static/src/xml/popup_help.xml
  10. 96
      help_popup/views/action_view.xml

22
help_popup/README.rst

@ -5,25 +5,21 @@
Help Popup
===========
This module adds an html help popup on each model action.
Two help fields are added to actions: enduser_help (html widget)
and advanced_help.
Installation
============
It was tested on Odoo 8.0 branch.
This module adds an html help popup on each model action.
It brings to end users inline documentation.
Some parts of the documentation can be modified by anyone (with proper rights).
Configuration
=============
Go to the action of your choice to add some help content
or put data in some modules.
* Go to any view and click on the `?` near the title view.
* Edit the html field to add content
To display the button which open the popup, enduser_help or advanced_help field
should be set to any value.
* You can provide documentation with this module by appending data
in the field advanced_help (relative to action) or advanced_help_model
if your help must be associated to model instead of action
Usage

24
help_popup/__openerp__.py

@ -1,27 +1,10 @@
# coding: utf-8
##############################################################################
#
# Odoo, Open Source Management Solution
# Copyright (C) 2015-TODAY Akretion (<http://www.akretion.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
# © 2015 David BEAL @ Akretion <david.beal@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': 'Help Popup',
'version': '8.0.0.5.0',
'version': '8.0.2.0.0',
'author': 'Akretion, Odoo Community Association (OCA)',
'depends': [
'web',
@ -32,6 +15,7 @@
'views/action_view.xml',
'report/report.xml',
'report/help.xml',
'report/all.xml',
],
'demo': [
'demo/help.xml',

43
help_popup/demo/help.xml

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<data>
<record id="base.action_partner_form" model="ir.actions.act_window">
<field name="enduser_help"><![CDATA[
@ -20,14 +20,17 @@ I'm displayed in a Qweb html report
Don't hesitate to customized me with your own words and syntax
</p>
<p>You can write any html tag. Here is an image with img tag</p>
<img src="http://www.akretion.com/sites/50443990c3c67e1bf3000004/theme/images/logo.png"/>
]]></field>
</record>
</data>
<data noupdate="0">
<record id="base.action_partner_form" model="ir.actions.act_window">
<field name="advanced_help"><![CDATA[
<b>Hi developers,</b>
<b>Hi Odoo community,</b>
<br/>
<br/>
@ -35,18 +38,42 @@ Don't hesitate to customized me with your own words and syntax
I'm the field 'advanced_help' in the customer action also displayed in Qweb report.
</p>
<p>
<b>Akretion</b> wrote these words to explain my main purpose:
I wrote these words to explain the main purpose:
<blockquote>
Allows to developers to write documentation on their work.
Odoo community companies can insert their documenation here with data in their modules. <br><br>
Then, any end users can see this documentation in one click.
<br>
End users can also display and print documentation about an entire menu.
</blockquote>
</p>
<p>
</p>
<p>You can write any html tag. Here is an image with img tag</p>
<img src="http://www.akretion.com/sites/50443990c3c67e1bf3000004/theme/images/logo.png"/>
]]></field>
</record>
<record id="base.action_partner_category_form"
model="ir.actions.act_window">
<field name="enduser_help"><![CDATA[
Hi all,<br><br>
A supplier can have several specialities.
<br><br>
Use these multicategories to classify your partners
]]></field>
</record>
<record id="base.action_res_bank_form"
model="ir.actions.act_window">
<field name="enduser_help"><![CDATA[
Hi all,<br>
<br><br>
Who does not want to rob a bank?
<br><br>
;-)
]]></field>
</record>

142
help_popup/model.py

@ -1,35 +1,127 @@
# coding: utf-8
##############################################################################
#
# Odoo, Open Source Management Solution
# Copyright (C) 2015-TODAY Akretion (<http://www.akretion.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import models, fields
# © 2015 David BEAL @ Akretion <david.beal@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import _, api, models, fields
class IrActionsActwindow(models.Model):
_inherit = 'ir.actions.act_window'
class ErpHelp(models.AbstractModel):
_name = 'erp.help'
enduser_help = fields.Html(
string="End User Help",
help="Use this field to add custom content for documentation purpose\n"
"mainly by power users ")
advanced_help = fields.Text(
string="Advanced Help",
string="Advanced Help", groups='base.group_no_one',
help="Use this field to add custom content for documentation purpose\n"
"mainly by developers")
"mainly by developers or consultants")
class IrModel(models.Model):
_inherit = ['ir.model', 'erp.help']
_name = 'ir.model'
class IrActionsActwindow(models.Model):
_inherit = ['ir.actions.act_window', 'erp.help']
_name = 'ir.actions.act_window'
_rpt_menu = False
enduser_help_model = fields.Html(
string='Enduser Help from Model', store="True",
compute='_compute_model_help', inverse='_inverse_model_help',
help="")
advanced_help_model = fields.Text(
string='Advanced Help from model', store="True",
compute='_compute_model_help', inverse='_inverse_model_help',
help="")
action_help = fields.Boolean(string="Display Action Help")
help_has_content = fields.Boolean(
string="Content in help", compute='_compute_contains_help',
help="One of the help has content")
@api.one
@api.depends('enduser_help', 'advanced_help',
'enduser_help_model', 'advanced_help_model')
def _compute_contains_help(self):
if (self.enduser_help or self.enduser_help_model or
self.advanced_help or self.advanced_help_model):
self.help_has_content = True
else:
self.help_has_content = False
@api.multi
def _compute_model_help(self):
for rec in self:
model = rec.env['ir.model'].search([('model', '=', rec.res_model)])
rec.enduser_help_model = model.enduser_help
rec.advanced_help_model = model.advanced_help
def _inverse_model_help(self):
for rec in self:
model = rec.env['ir.model'].search([('model', '=', rec.res_model)])
model.enduser_help = rec.enduser_help_model
model.advanced_help = rec.advanced_help_model
@api.multi
def open_help_popup(self):
""" Open in a new tab instead of in popup"""
self.ensure_one()
return {
'name': _('Open help for this action'),
'type': 'ir.actions.act_url',
'url': 'report/html/help_popup.tpl_help/%s' % self.id,
'target': 'new',
}
@api.model
def get_help_actions(self):
""" called by the template"""
self._rpt_menu = self.get_main_menu()
menu_names = self.get_menu_names(self._rpt_menu)
actions = self.search([
('id', 'in', menu_names.keys()),
'|', '|', '|',
('enduser_help', '!=', False),
('enduser_help_model', '!=', False),
('advanced_help', '!=', False),
('advanced_help_model', '!=', False),
])
return actions
@api.model
def get_main_menu(self):
self._rpt_menu = False
ir_vals = self.env['ir.values'].search([
('key2', '=', 'tree_but_open'),
('key', '=', 'action'),
('res_id', '>', 0),
('value', '=', 'ir.actions.act_window,%s' % self.id),
])
if ir_vals:
# we only keep the first menu beacause we have no info on menu_id
self._rpt_menu = self.env['ir.ui.menu'].browse(ir_vals[0].res_id)
while self._rpt_menu.parent_id:
self._rpt_menu = self._rpt_menu.parent_id
return self._rpt_menu
@api.model
def get_menu_names(self, main_menu):
""" @return dict {action_id: 'menu name'} """
menus = self.env['ir.ui.menu'].search(
[('id', 'child_of', main_menu.id)])
ir_vals = self.env['ir.values'].search([
('key2', '=', 'tree_but_open'),
('key', '=', 'action'),
('res_id', 'in', menus.ids),
('value', 'like', 'ir.actions.act_window,%'),
])
map_menu = {x.id: x.name for x in menus}
return {int(x.value[22:]): map_menu[x.res_id] for x in ir_vals}
def _anchorize(self, string):
""" called by template """
for char in ["'", '"', ' ']:
string = string.replace(char, '-')
return string

46
help_popup/report/all.xml

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<template id="all_help">
<t t-call="report.html_container">
<t t-call="report.internal_layout">
<t t-foreach="docs" t-as="o">
<div class="page">
<t t-set="actions" t-value="o.get_help_actions()"/>
<h2 class="text-center" t-if="o._rpt_menu" t-raw="o._rpt_menu.name"/>
<ul>
<t t-foreach="actions" t-as="act">
<li>
<a t-attf-href="#-{{ o._anchorize(act.name) }}" t-raw='act.name'/>
</li>
</t>
</ul>
<t t-foreach="actions" t-as="act">
<h2 t-attf-id="-{{ o._anchorize(act.name) }}" t-raw='act.name'/>
<div class="bg-warning" t-if="act.enduser_help" t-raw="act.enduser_help"/>
<div class="bg-warning" t-if="act.enduser_help_model" t-raw="act.enduser_help_model"/>
<hr width="70%"/>
<div t-if="act.advanced_help" t-raw="act.advanced_help"/>
<div t-if="act.advanced_help_model" t-raw="act.advanced_help_model"/>
</t>
<hr width="70%"/>
</div>
<!--end foreach-->
</t>
</t>
</t>
</template>
</data>
</openerp>

40
help_popup/report/help.xml

@ -13,18 +13,34 @@
<div class="page">
<div t-raw="o.enduser_help"/>
<hr width="70%"/>
<h3 t-if="o.advanced_help">Help from developer</h3>
<div t-raw="o.advanced_help"/>
<hr width="70%"/>
<h3 t-if="o.help">Help from Odoo</h3>
<div t-raw="o.help"/>
<div class="pull-right bg-sucess">
<t t-set="action_id" t-value="o.env.ref('help_popup.action_help_popup_form').id" />
<a t-attf-href="/report/html/help_popup.all_help/{{ o.id }}" class="btn btn-success btn-xs" title="Click to see documentation for the whole menu">
<span t-raw="o.get_main_menu().name"/> help</a>
<a t-attf-href="/web#id={{ o.id }}&amp;view_type=form&amp;model=ir.actions.act_window&amp;action={{ action_id }}" class="btn btn-danger btn-xs" title="Edit this documentation">Edit</a>
<br/>
</div>
<br/>
<div class="bg-warning" t-if="o.enduser_help_model or o.enduser_help">
<div class="oe_text_center label label-info">Internal</div>
<div t-if="o.enduser_help_model" t-raw="o.enduser_help_model"/>
<div t-if="o.enduser_help" t-raw="o.enduser_help"/>
<hr width="70%"/>
</div>
<div t-if="o.advanced_help_model or o.advanced_help">
<div class="oe_text_center label label-info" title="Odoo Community Association (OCA) maintains several modules with high quality level">Odoo Community</div>
<div t-if="o.advanced_help_model" t-raw="o.advanced_help_model"/>
<div t-if="o.advanced_help" t-raw="o.advanced_help"/>
<hr width="70%"/>
</div>
<div t-if="o.help">
<div class="oe_text_center label label-info" title="Help from Odoo editor">Odoo</div>
<div t-if="o.help" t-raw="o.help"/>
<hr width="70%"/>
</div>
<div>Use Ctrl + P to print this document</div>
</div>
<!--end foreach-->

17
help_popup/report/report.xml

@ -3,11 +3,18 @@
<openerp>
<data>
<report id="report_help_popup"
model="ir.actions.act_window"
string="Contextual Help"
name="help_popup.tpl_help"
report_type="qweb-html"/>
<report id="report_help_popup"
model="ir.actions.act_window"
string="Contextual Help"
name="help_popup.tpl_help"
report_type="qweb-html"/>
<report id="report_all_help"
model="ir.actions.act_window"
string="All Contextual Help"
name="help_popup.all_help"
report_type="qweb-html"/>
</data>
</openerp>

26
help_popup/static/src/js/popup_help.js

@ -6,24 +6,40 @@ openerp.help_popup = function(instance, local) {
do_create_view: function(view_type) {
var self = this;
var res = self._super(view_type);
var params = 'height=650, width=900, location=no, ';
params += 'resizable=yes, menubar=yes, scrollbars=yes';
self.$el.find('span.update_help').each(function () {
var $elem = $(this);
if ($elem.data('click-init')) {
return true;
}
$elem.data('click-init', true);
console.log('me ' + self)
if (self.action.id == undefined || self.action.help_has_content == true) {
self.$el.find('span.update_help').hide()
}
$elem.on('click', function(e) {
path = self.action.id;
my_window = window.open('/web#id='+ path +'&view_type=form&model=ir.actions.act_window&action=help_popup.action_help_popup_form', 'Help', params);
// allows to back to the window if opened previoulsy
setTimeout('my_window.focus()', 1);
});
return true;
});
self.$el.find('span.view_help').each(function () {
var $elem = $(this);
if ($elem.data('click-init')) {
return true;
}
$elem.data('click-init', true);
if (self.action.id == undefined || (self.action.advanced_help == '' && self.action.enduser_help == '')) {
if (self.action.id == undefined || self.action.help_has_content == false) {
self.$el.find('span.view_help').hide()
}
$elem.on('click', function(e) {
var params = 'height=650, width=800, location=no, ';
params += 'resizable=yes, menubar=yes';
path = self.action.id;
my_window = window.open('/report/html/help_popup.tpl_help/' + path, 'Help', params);
// allows to back to the window if opened previoulsy
setTimeout('my_window.focus()', 1);
});
return true;
});

5
help_popup/static/src/xml/popup_help.xml

@ -2,7 +2,10 @@
<templates>
<t t-name="ViewManagerAction" t-extend="ViewManagerAction">
<t t-jquery="h2.oe_view_title" t-operation="before">
<span> &amp;nbsp; </span><span class="oe_button oe_highlight view_help">?</span>
<span> &amp;nbsp; </span>
<span class="btn btn-primary btn-sm view_help"
title="Display help content">?</span>
<span class="btn btn-link btn-xs update_help" title="Define help content">?</span>
</t>
</t>
</templates>

96
help_popup/views/action_view.xml

@ -1,18 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<data>
<record id="view_window_action_form" model="ir.ui.view">
<field name="model">ir.actions.act_window</field>
<field name="inherit_id"
ref="base.view_window_action_form"/>
<field name="arch" type="xml">
<field name="help" position="after">
<field name="enduser_help"/>
<field name="advanced_help"/>
<record id="view_window_action_form" model="ir.ui.view">
<field name="model">ir.actions.act_window</field>
<field name="inherit_id"
ref="base.view_window_action_form"/>
<field name="arch" type="xml">
<field name="help" position="after">
<field name="enduser_help"/>
<field name="advanced_help"/>
</field>
</field>
</field>
</record>
</record>
</data>
<record id="view_window_action_help_form" model="ir.ui.view">
<field name="model">ir.actions.act_window</field>
<field name="arch" type="xml">
<form>
<sheet>
<group name="main" col="4">
<field name="name" attrs="{'readonly': True}"/>
<field name="res_model" attrs="{'readonly': True}"/>
<field name="action_help"/>
<button name="open_help_popup" type="object" string="Help"
class="oe_highlight"/><span/>
<!-- <field name="help_has_content"/> -->
<separator string="End users help" colspan="4"/>
<field name="enduser_help_model" colspan="4" nolabel="1"/>
<div attrs="{'invisible': [('action_help', '=', False)]}"
class="alert alert-warning"
colspan="4">Help field below is only used by action (i.e. action for 'customer' is different than action for 'supplier' but share the same model)</div>
<field name="enduser_help" colspan="4" nolabel="1"
attrs="{'invisible': [('action_help', '=', False)]}"/>
<separator string="Odoo community help" colspan="4"/>
<field name="advanced_help_model" attrs="{'readonly': True}"
colspan="4" nolabel="1"/>
<field name="advanced_help" attrs="{'readonly': True}"
colspan="4" nolabel="1"/>
<span colspan="4"></span>
<separator string="Standard Odoo help" colspan="4"/>
<field name="help" nolabel="1" attrs="{'readonly': True}" colspan="4"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_window_action_help_tree" model="ir.ui.view">
<field name="model">ir.actions.act_window</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="res_model"/>
<field name="enduser_help"/>
<field name="advanced_help"/>
<field name="help"/>
</tree>
</field>
</record>
<record id="action_help_popup_form" model="ir.actions.act_window">
<field name="name">Help on Action</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">ir.actions.act_window</field>
<field name="view_mode">form</field>
<field name="target">current</field>
<!-- <field name="context">{'search_default_customer':1, 'restrict_kind': ['individu', 'incorpo'], 'default_kind':'incorpo'}</field> -->
</record>
<record model="ir.actions.act_window.view" id="act_help_popup_formr_view_form">
<field name="act_window_id" ref="action_help_popup_form"/>
<field name="view_mode">form</field>
<field name="sequence" eval="10"/>
<field name="view_id" ref="view_window_action_help_form"/>
</record>
<record model="ir.actions.act_window.view" id="act_help_popup_formr_view_tree">
<field name="act_window_id" ref="action_help_popup_form"/>
<field name="view_mode">tree</field>
<field name="sequence" eval="5"/>
<field name="view_id" ref="view_window_action_help_tree"/>
</record>
<menuitem id="action_with_help" sequence="100"
action="action_help_popup_form" name="Help"
parent="base.menu_config"/>
</data>
</openerp>
Loading…
Cancel
Save