[IMP] merge of modules board and web_dashboard
bzr revid: chs@openerp.com-20120809153027-3sl125kda0jtdrcg
This commit is contained in:
parent
6c12d5b308
commit
591680f99c
|
@ -3,6 +3,7 @@
|
|||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2010-2012 OpenERP s.a. (<http://openerp.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
|
||||
|
@ -20,6 +21,6 @@
|
|||
##############################################################################
|
||||
|
||||
import board
|
||||
import wizard
|
||||
import controllers
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2010-2012 OpenERP s.a. (<http://openerp.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
|
||||
|
@ -35,15 +36,19 @@ The user can also publish notes.
|
|||
'depends': ['base'],
|
||||
'update_xml': [
|
||||
'security/ir.model.access.csv',
|
||||
'wizard/board_menu_create_view.xml',
|
||||
'board_view.xml',
|
||||
'board_data_admin.xml',
|
||||
'board_data_home.xml',
|
||||
'board_mydashboard_view.xml'
|
||||
],
|
||||
'demo_xml': [
|
||||
'board_demo.xml'
|
||||
"js": [
|
||||
'static/src/js/dashboard.js',
|
||||
],
|
||||
"css": [
|
||||
'static/src/css/dashboard.css',
|
||||
],
|
||||
'qweb': [
|
||||
"static/src/xml/*.xml",
|
||||
],
|
||||
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'certificate': '0076912305725',
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2010-2012 OpenERP s.a. (<http://openerp.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
|
||||
|
@ -19,75 +20,58 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
from operator import itemgetter
|
||||
from textwrap import dedent
|
||||
from osv import fields, osv
|
||||
import time
|
||||
import tools
|
||||
|
||||
class board_board(osv.osv):
|
||||
"""
|
||||
Board
|
||||
"""
|
||||
_name = 'board.board'
|
||||
_description = "Board"
|
||||
_auto = False
|
||||
_columns = {}
|
||||
|
||||
def create_view(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
Create view
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of Board's IDs
|
||||
@return: arch of xml view.
|
||||
"""
|
||||
arch = """<?xml version="1.0"?>
|
||||
<form string="My Board" version="7.0">
|
||||
<board style="1-1">
|
||||
<column/>
|
||||
<column/>
|
||||
</board>
|
||||
</form>"""
|
||||
return arch
|
||||
@tools.cache()
|
||||
def list(self, cr, uid, context=None):
|
||||
Actions = self.pool.get('ir.actions.act_window')
|
||||
Menus = self.pool.get('ir.ui.menu')
|
||||
IrValues = self.pool.get('ir.values')
|
||||
|
||||
act_ids = Actions.search(cr, uid, [('res_model', '=', self._name)], context=context)
|
||||
refs = ['%s,%s' % (Actions._name, act_id) for act_id in act_ids]
|
||||
|
||||
# cannot search "action" field on menu (non stored function field without search_fnct)
|
||||
irv_ids = IrValues.search(cr, uid, [
|
||||
('model', '=', 'ir.ui.menu'),
|
||||
('key', '=', 'action'),
|
||||
('key2', '=', 'tree_but_open'),
|
||||
('value', 'in', refs),
|
||||
], context=context)
|
||||
menu_ids = map(itemgetter('res_id'), IrValues.read(cr, uid, irv_ids, ['res_id'], context=context))
|
||||
menu_names = Menus.name_get(cr, uid, menu_ids, context=context)
|
||||
return [dict(id=m[0], name=m[1]) for m in menu_names]
|
||||
|
||||
def _clear_list_cache(self):
|
||||
self.list.clear_cache(self)
|
||||
|
||||
def create(self, cr, user, vals, context=None):
|
||||
"""
|
||||
create new record.
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param vals: dictionary of values for every field.
|
||||
dictionary must use this form: {‘name_of_the_field’: value, ...}
|
||||
@return: id of new created record of board.board.
|
||||
"""
|
||||
return 0
|
||||
|
||||
|
||||
if not 'name' in vals:
|
||||
return False
|
||||
id = super(board_board, self).create(cr, user, vals, context=context)
|
||||
view_id = self.pool.get('ir.ui.view').create(cr, user, {
|
||||
'name': vals['name'],
|
||||
'model': 'board.board',
|
||||
'priority': 16,
|
||||
'type': 'form',
|
||||
'arch': self.create_view(cr, user, id, context=context),
|
||||
})
|
||||
|
||||
super(board_board, self).write(cr, user, [id], {'view_id': view_id}, context)
|
||||
return id
|
||||
|
||||
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None,\
|
||||
toolbar=False, submenu=False):
|
||||
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
|
||||
"""
|
||||
Overrides orm field_view_get.
|
||||
@return: Dictionary of Fields, arch and toolbar.
|
||||
"""
|
||||
|
||||
res = {}
|
||||
res = super(board_board, self).fields_view_get(cr, user, view_id, view_type,\
|
||||
context, toolbar=toolbar, submenu=submenu)
|
||||
res = super(board_board, self).fields_view_get(cr, user, view_id, view_type,
|
||||
context, toolbar=toolbar, submenu=submenu)
|
||||
|
||||
vids = self.pool.get('ir.ui.view.custom').search(cr, user,\
|
||||
[('user_id', '=', user), ('ref_id' ,'=', view_id)])
|
||||
CustView = self.pool.get('ir.ui.view.custom')
|
||||
vids = CustView.search(cr, user, [('user_id', '=', user), ('ref_id', '=', view_id)], context=context)
|
||||
if vids:
|
||||
view_id = vids[0]
|
||||
arch = self.pool.get('ir.ui.view.custom').browse(cr, user, view_id, context=context)
|
||||
arch = CustView.browse(cr, user, view_id, context=context)
|
||||
res['custom_view_id'] = view_id
|
||||
res['arch'] = arch.arch
|
||||
res['arch'] = self._arch_preprocessing(cr, user, res['arch'], context=context)
|
||||
|
@ -98,10 +82,10 @@ class board_board(osv.osv):
|
|||
from lxml import etree
|
||||
def remove_unauthorized_children(node):
|
||||
for child in node.iterchildren():
|
||||
if child.tag=='action' and child.get('invisible'):
|
||||
if child.tag == 'action' and child.get('invisible'):
|
||||
node.remove(child)
|
||||
else:
|
||||
child=remove_unauthorized_children(child)
|
||||
child = remove_unauthorized_children(child)
|
||||
return node
|
||||
|
||||
def encode(s):
|
||||
|
@ -110,16 +94,84 @@ class board_board(osv.osv):
|
|||
return s
|
||||
|
||||
archnode = etree.fromstring(encode(arch))
|
||||
return etree.tostring(remove_unauthorized_children(archnode),pretty_print=True)
|
||||
return etree.tostring(remove_unauthorized_children(archnode), pretty_print=True)
|
||||
|
||||
|
||||
class board_create(osv.osv_memory):
|
||||
|
||||
def board_create(self, cr, uid, ids, context=None):
|
||||
assert len(ids) == 1
|
||||
this = self.browse(cr, uid, ids[0], context=context)
|
||||
|
||||
view_arch = dedent("""<?xml version="1.0"?>
|
||||
<form string="%s" version="7.0">
|
||||
<board style="2-1">
|
||||
<column/>
|
||||
<column/>
|
||||
</board>
|
||||
</form>
|
||||
""".strip() % (this.name,))
|
||||
|
||||
view_id = self.pool.get('ir.ui.view').create(cr, uid, {
|
||||
'name': this.name,
|
||||
'model': 'board.board',
|
||||
'priority': 16,
|
||||
'type': 'form',
|
||||
'arch': view_arch,
|
||||
}, context=context)
|
||||
|
||||
action_id = self.pool.get('ir.actions.act_window').create(cr, uid, {
|
||||
'name': this.name,
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'board.board',
|
||||
'usage': 'menu',
|
||||
'view_id': view_id,
|
||||
'help': dedent('''<div class="oe_empty_custom_dashboard">
|
||||
<p>
|
||||
<b>This dashboard is empty.</b>
|
||||
</p><p>
|
||||
To add the first report into this dashboard, go to any
|
||||
menu, switch to list or graph view, and click <i>'Add to
|
||||
Dashboard'</i> in the extended search options.
|
||||
</p><p>
|
||||
You can filter and group data before inserting into the
|
||||
dashboard using the search options.
|
||||
</p>
|
||||
</div>
|
||||
''')
|
||||
}, context=context)
|
||||
|
||||
menu_id = self.pool.get('ir.ui.menu').create(cr, uid, {
|
||||
'name': this.name,
|
||||
'parent_id': this.menu_parent_id.id,
|
||||
'action': 'ir.actions.act_window,%s' % (action_id,)
|
||||
}, context=context)
|
||||
|
||||
self.pool.get('board.board')._clear_list_cache()
|
||||
|
||||
return {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'reload',
|
||||
'params': {
|
||||
'menu_id': menu_id
|
||||
},
|
||||
}
|
||||
|
||||
def _default_menu_parent_id(self, cr, uid, context=None):
|
||||
_, menu_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'menu_reporting_dashboard')
|
||||
return menu_id
|
||||
|
||||
_name = "board.create"
|
||||
_description = "Board Creation"
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Dashboard', size=64, required=True),
|
||||
'view_id': fields.many2one('ir.ui.view', 'Board View'),
|
||||
'name': fields.char('Board Name', size=64, required=True),
|
||||
'menu_parent_id': fields.many2one('ir.ui.menu', 'Parent Menu', required=True),
|
||||
}
|
||||
|
||||
# the following lines added to let the button on dashboard work.
|
||||
_defaults = {
|
||||
'name':lambda *args: 'Dashboard'
|
||||
'menu_parent_id': _default_menu_parent_id,
|
||||
}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -1,41 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- neat client actions that can be used in dashboards to display res_widgets -->
|
||||
<record id="action_application_tiles" model="ir.actions.client">
|
||||
<field name="name">Applications Tiles</field>
|
||||
<field name="tag">board.home.applications</field>
|
||||
</record>
|
||||
<record id="action_res_widgets_tweets" model="ir.actions.client">
|
||||
<field name="name">Tweets Widget</field>
|
||||
<field name="tag">board.home.widgets</field>
|
||||
<field name="params" eval="{'widget_id': ref('base.openerp_favorites_twitter_widget')}"/>
|
||||
</record>
|
||||
<record id="action_res_widgets_events" model="ir.actions.client">
|
||||
<field name="name">Events Widget</field>
|
||||
<field name="tag">board.home.widgets</field>
|
||||
<field name="params" eval="{'widget_id': ref('base.events_widget')}"/>
|
||||
</record>
|
||||
<record id="action_res_widgets_facebook" model="ir.actions.client">
|
||||
<field name="name">Facebook Widget</field>
|
||||
<field name="tag">board.home.widgets</field>
|
||||
<field name="params" eval="{'widget_id': ref('base.facebook_widget')}"/>
|
||||
</record>
|
||||
<record id="action_res_widgets_note" model="ir.actions.client">
|
||||
<field name="name">Note Widget</field>
|
||||
<field name="tag">board.home.widgets</field>
|
||||
<field name="params" eval="{'widget_id': ref('base.note_widget')}"/>
|
||||
</record>
|
||||
<record id="action_res_widgets_map" model="ir.actions.client">
|
||||
<field name="name">Google Maps Widget</field>
|
||||
<field name="tag">board.home.widgets</field>
|
||||
<field name="params" eval="{'widget_id': ref('base.google_maps_widget')}"/>
|
||||
</record>
|
||||
<record id="action_res_widgets_currency_converter" model="ir.actions.client">
|
||||
<field name="name">Currency Converter Widget</field>
|
||||
<field name="tag">board.home.widgets</field>
|
||||
<field name="params" eval="{'widget_id': ref('base.currency_converter_widget')}"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
</data>
|
||||
</openerp>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<!--My Dashboard-->
|
||||
<record model="ir.ui.view" id="board_my_dash_view">
|
||||
<field name="name">My Dashboard</field>
|
||||
|
|
|
@ -1,64 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- Board Search View -->
|
||||
<record id="view_board_search" model="ir.ui.view">
|
||||
<field name="name">board.board.search</field>
|
||||
<field name="model">board.board</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Dashboard">
|
||||
<field name="name" string="Dashboard"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Board Tree View -->
|
||||
<record id="view_board_tree" model="ir.ui.view">
|
||||
<field name="name">board.board.tree</field>
|
||||
<field name="model">board.board</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Dashboard">
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Board Form View -->
|
||||
<record id="view_board_form" model="ir.ui.view">
|
||||
<field name="name">board.board.form</field>
|
||||
<field name="model">board.board</field>
|
||||
<record id="view_board_create" model="ir.ui.view">
|
||||
<field name="name">board.create.form</field>
|
||||
<field name="model">board.create</field>
|
||||
<field name="type">form</field>
|
||||
<field eval="1" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Dashboard" version="7.0">
|
||||
<header>
|
||||
<button name="%(action_board_menu_create)d" string="Create Menu" type="action" class="oe_highlight"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="view_id" invisible="1"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
<form string="Create New Dashboard" version="7.0">
|
||||
<group colspan="4">
|
||||
<field name="name"/>
|
||||
<field name="menu_parent_id"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button string="Create" name="board_create" type="object" class="oe_highlight"/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Action for DashBoard Definition form -->
|
||||
<record id="action_view_board_list_form" model="ir.actions.act_window">
|
||||
<field name="name">Dashboard Definition</field>
|
||||
<field name="res_model">board.board</field>
|
||||
<record id="action_board_create" model="ir.actions.act_window">
|
||||
<field name="name">Create Board</field>
|
||||
<field name="res_model">board.create</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="view_board_search"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_board_create"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_view_board_list_form"
|
||||
id="menu_view_board_form" parent="base.menu_reporting_config"
|
||||
<menuitem action="action_board_create"
|
||||
id="menu_board_create" parent="base.menu_reporting_config"
|
||||
groups="base.group_no_one"
|
||||
sequence="2"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from xml.etree import ElementTree
|
||||
|
||||
try:
|
||||
import openerp.addons.web.common.http as openerpweb
|
||||
from openerp.addons.web.common import nonliterals
|
||||
from openerp.addons.web.controllers.main import load_actions_from_ir_values
|
||||
except ImportError:
|
||||
import web.common.http as openerpweb # noqa
|
||||
from web.common import nonliterals # noqa
|
||||
from web.controllers.main import load_actions_from_ir_values # noqa
|
||||
|
||||
class Board(openerpweb.Controller):
|
||||
_cp_path = '/board'
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def add_to_dashboard(self, req, menu_id, action_id, context_to_save, domain, view_mode, name=''):
|
||||
# FIXME move this method to board.board model
|
||||
to_eval = nonliterals.CompoundContext(context_to_save)
|
||||
to_eval.session = req.session
|
||||
ctx = dict((k, v) for k, v in to_eval.evaluate().iteritems()
|
||||
if not k.startswith('search_default_'))
|
||||
ctx['dashboard_merge_domains_contexts'] = False # TODO: replace this 6.1 workaround by attribute on <action/>
|
||||
domain = nonliterals.CompoundDomain(domain)
|
||||
domain.session = req.session
|
||||
domain = domain.evaluate()
|
||||
|
||||
dashboard_action = load_actions_from_ir_values(req, 'action', 'tree_but_open', [('ir.ui.menu', menu_id)], False)
|
||||
|
||||
if dashboard_action:
|
||||
action = dashboard_action[0][2]
|
||||
if action['res_model'] == 'board.board' and action['views'][0][1] == 'form':
|
||||
# Maybe should check the content instead of model board.board ?
|
||||
view_id = action['views'][0][0]
|
||||
board = req.session.model(action['res_model']).fields_view_get(view_id, 'form')
|
||||
if board and 'arch' in board:
|
||||
xml = ElementTree.fromstring(board['arch'])
|
||||
column = xml.find('./board/column')
|
||||
if column is not None:
|
||||
new_action = ElementTree.Element('action', {
|
||||
'name': str(action_id),
|
||||
'string': name,
|
||||
'view_mode': view_mode,
|
||||
'context': str(ctx),
|
||||
'domain': str(domain)
|
||||
})
|
||||
column.insert(0, new_action)
|
||||
arch = ElementTree.tostring(xml, 'utf-8')
|
||||
return req.session.model('ir.ui.view.custom').create({
|
||||
'user_id': req.session._uid,
|
||||
'ref_id': view_id,
|
||||
'arch': arch
|
||||
}, req.session.eval_context(req.context))
|
||||
|
||||
return False
|
|
@ -1,3 +1,2 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_board_board all,board.board,model_board_board,,1,0,0,0
|
||||
access_board_board system,board.board system,model_board_board,base.group_system,1,1,1,1
|
||||
|
|
|
|
@ -0,0 +1,309 @@
|
|||
.openerp table.oe_dashboard {
|
||||
width: 100%;
|
||||
}
|
||||
.openerp .oe_dashboard_links {
|
||||
text-align: right;
|
||||
margin: 0 4px 6px 0;
|
||||
}
|
||||
.openerp .oe_dashboard_action {
|
||||
margin: 0 0.5em 0.5em 0;
|
||||
padding: 0px;
|
||||
background-color: white;
|
||||
border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
}
|
||||
|
||||
.openerp .oe_dashboard_action .oe_dashboard_action_header {
|
||||
font-size: 85%;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
text-indent: 10px;
|
||||
vertical-align: middle;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
background: white url("/web/static/src/img/box-a-header-a.gif") 0% 0% repeat-x;
|
||||
}
|
||||
|
||||
.openerp h2.oe_dashboard_action_header {
|
||||
margin: 0;
|
||||
padding:4px 4px;
|
||||
-moz-border-radius-topleft: 3px;
|
||||
-webkit-border-top-left-radius: 3px;
|
||||
border-top-left-radius: 3px;
|
||||
-moz-border-radius-topright: 3px;
|
||||
-webkit-border-top-right-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
.openerp h2.oe_dashboard_action_header_empty {
|
||||
padding-top: 0;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.openerp .oe_dashboard_button_create {
|
||||
margin-left: 4px;
|
||||
padding: 0 4px 0 4px;
|
||||
height: 16px !important;
|
||||
}
|
||||
|
||||
.openerp a.oe_dashboard_action_rename {
|
||||
float: left;
|
||||
padding-right: 4px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.openerp .oe_dashboard_action_input {
|
||||
height: 16px;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.openerp .oe_dashboard_action .oe_dashboard_action_header:hover {
|
||||
cursor: move;
|
||||
}
|
||||
.openerp .oe_dashboard_action .ui-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
.openerp .oe_dashboard_action .ui-icon:hover {
|
||||
background-color: #ccc;
|
||||
border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
}
|
||||
|
||||
.openerp .oe_dashboard_action .oe_dashboard_action_header .ui-icon {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.openerp .oe_dashboard .ui-sortable-placeholder {
|
||||
border: 1px dotted black;
|
||||
visibility: visible !important;
|
||||
height: 50px !important;
|
||||
}
|
||||
|
||||
.openerp .oe_dashboard .ui-sortable-placeholder * {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/* Base overwriting */
|
||||
.openerp .oe_dashboard .oe_list_content, .openerp .oe_dashboard .ui-widget-header {
|
||||
border-right:none !important;
|
||||
padding:0 3px;
|
||||
}
|
||||
|
||||
/* Layouts */
|
||||
.openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_0 {
|
||||
width: 100%;
|
||||
}
|
||||
.openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_1,
|
||||
.openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_2 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.openerp .oe_dashboard_layout_1-1 .oe_dashboard_column {
|
||||
width: 50%;
|
||||
}
|
||||
.openerp .oe_dashboard_layout_1-1 .oe_dashboard_column.index_2 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.openerp .oe_dashboard_layout_1-1-1 .oe_dashboard_column {
|
||||
width: 33%;
|
||||
}
|
||||
|
||||
.openerp .oe_dashboard_layout_2-1 .oe_dashboard_column.index_0 {
|
||||
width: 70%;
|
||||
}
|
||||
.openerp .oe_dashboard_layout_2-1 .oe_dashboard_column.index_1 {
|
||||
width: 30%;
|
||||
}
|
||||
.openerp .oe_dashboard_layout_2-1 .oe_dashboard_column.index_2 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.openerp .oe_dashboard_layout_1-2 .oe_dashboard_column.index_0 {
|
||||
width: 30%;
|
||||
}
|
||||
.openerp .oe_dashboard_layout_1-2 .oe_dashboard_column.index_1 {
|
||||
width: 70%;
|
||||
}
|
||||
.openerp .oe_dashboard_layout_1-2 .oe_dashboard_column.index_2 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.openerp .oe_dashboard_layout_selector {
|
||||
overflow: auto;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.openerp .oe_dashboard_layout_selector ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.openerp .oe_dashboard_layout_selector ul li {
|
||||
position: relative;
|
||||
float: left;
|
||||
height: 51px;
|
||||
list-style-type: none;
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
width: 82px;
|
||||
cursor: pointer;
|
||||
border: 1px solid white;
|
||||
}
|
||||
.openerp .oe_dashboard_layout_selector ul li:hover {
|
||||
border: 1px solid #090;
|
||||
}
|
||||
.openerp .oe_dashboard_layout_selector ul li img.oe_dashboard_selected_layout {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.openerp .oe_dashboard_home_tile {
|
||||
text-align: center;
|
||||
margin: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
-webkit-box-shadow: 3px 3px 5px 3px #DADDDD;
|
||||
-moz-box-shadow: 3px 3px 5px 3px #DADDDD;
|
||||
box-shadow: 3px 3px 5px 3px #DADDDD;
|
||||
}
|
||||
.openerp .oe_dashboard_home_tile span {
|
||||
display: block;
|
||||
padding: 0 0 15px;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
color: #555;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.openerp .oe_dashboard_home_tile_icon {
|
||||
height: 100px;
|
||||
}
|
||||
.openerp .oe_dashboard_home_tile_icon img {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.openerp .oe_dashboard_home_tile_icon img.hover {
|
||||
display: none;
|
||||
}
|
||||
.openerp .oe_dashboard_home_tile:hover {
|
||||
background-color: #fafafa;
|
||||
-webkit-box-shadow: 3px 3px 5px 3px #979797;
|
||||
-moz-box-shadow: 3px 3px 5px 3px #979797;
|
||||
box-shadow: 3px 3px 5px 3px #979797;
|
||||
}
|
||||
.openerp .oe_dashboard_home_tile:hover img {
|
||||
display: none;
|
||||
}
|
||||
.openerp .oe_dashboard_home_tile:hover img.hover {
|
||||
display: block;
|
||||
}
|
||||
.openerp .oe_dashboard_home_tile:hover span {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.openerp .oe_dashboard_action .view-manager-main-content {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.openerp .oe_app_tiles h1, .openerp .oe_app_tiles h3 {
|
||||
margin: 16px 24px;
|
||||
}
|
||||
|
||||
.openerp .oe_app_tiles {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.openerp .oe_app_tiles li {
|
||||
float: left;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.openerp .oe_app_tiles li img {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
.openerp .oe_app_tiles li img.hover {
|
||||
display: none;
|
||||
}
|
||||
.openerp .oe_app_tiles li:hover img {
|
||||
display: none;
|
||||
}
|
||||
.openerp .oe_app_tiles li:hover img.hover {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.openerp .oe_app_tiles li a {
|
||||
display: block;
|
||||
height: 120px;
|
||||
width: 194px;
|
||||
color: #4C4C4C;
|
||||
border: 1px solid #f4f2f2;
|
||||
margin: 6px;
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
background: white;
|
||||
-moz-border-radius: 6px;
|
||||
-webkit-border-radius: 6px;
|
||||
-ms-border-radius: 6px;
|
||||
border-radius: 6px;
|
||||
-moz-box-shadow: 0 1px 2px #bbb;
|
||||
-webkit-box-shadow: 0 1px 2px #bbb;
|
||||
-o-box-shadow: 0 1px 2px #bbb;
|
||||
box-shadow: 0 1px 2px #bbb;
|
||||
}
|
||||
/* changing icon for the change layout button */
|
||||
|
||||
.openerp .oe_dashboard_link_change_layout, .openerp .oe_dashboard_link_reset {
|
||||
padding-top: 1px;
|
||||
height: 22px;
|
||||
}
|
||||
.openerp .oe_dashboard_link_change_layout > *, .openerp .oe_dashboard_link_reset > *{
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.openerp .oe_welcome_message {
|
||||
display:none;
|
||||
}
|
||||
.openerp .oe_initial_welcome_message {
|
||||
width:30%;
|
||||
text-align:center;
|
||||
margin:10px 35% 0 35%;
|
||||
padding: 5px 10px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
background: #eeeded;
|
||||
box-shadow: 0 1px 0 #fff;
|
||||
-moz-box-shadow: 0 1px 0 #fff;
|
||||
-webkit-box-shadow: 0 1px 0 #fff;
|
||||
color: #8c8c8c;
|
||||
font-size: 90%;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
text-shadow: #fff 0 1px 0;
|
||||
}
|
||||
|
||||
.openerp .oe_initial_welcome_message ul{
|
||||
padding:10px 0 0 0;
|
||||
margin:0;
|
||||
list-style-type: none;
|
||||
padding: 7px 0 5px 5px;
|
||||
background-position: 0 50%;
|
||||
background-repeat: no-repeat;
|
||||
cursor: pointer;
|
||||
}
|
||||
.openerp .oe_initial_welcome_message ul a, .openerp .initial_welcome_message ul a:hover, .openerp .initial_welcome_message ul a:active, .openerp .initial_welcome_message ul a:focus {
|
||||
color:#222;
|
||||
text-decoration:none;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 306 B |
Binary file not shown.
After Width: | Height: | Size: 313 B |
Binary file not shown.
After Width: | Height: | Size: 313 B |
Binary file not shown.
After Width: | Height: | Size: 292 B |
Binary file not shown.
After Width: | Height: | Size: 304 B |
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
|
@ -0,0 +1,378 @@
|
|||
openerp.board = function(instance) {
|
||||
var QWeb = instance.web.qweb,
|
||||
_t = instance.web._t;
|
||||
|
||||
if (!instance.board) {
|
||||
/** @namespace */
|
||||
instance.board = {};
|
||||
}
|
||||
|
||||
instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
||||
init: function(view, node) {
|
||||
this._super(view, node);
|
||||
this.form_template = 'DashBoard';
|
||||
this.actions_attrs = {};
|
||||
this.action_managers = [];
|
||||
},
|
||||
start: function() {
|
||||
var self = this;
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.$element.find('.oe_dashboard_column').sortable({
|
||||
connectWith: '.oe_dashboard_column',
|
||||
handle: '.oe_dashboard_action_header',
|
||||
scroll: false
|
||||
}).disableSelection().bind('sortstop', self.do_save_dashboard);
|
||||
|
||||
// Events
|
||||
this.$element.find('.oe_dashboard_link_reset').click(this.on_reset);
|
||||
this.$element.find('.oe_dashboard_link_change_layout').click(this.on_change_layout);
|
||||
|
||||
this.$element.delegate('.oe_dashboard_column .oe_dashboard_fold', 'click', this.on_fold_action);
|
||||
this.$element.delegate('.oe_dashboard_column .ui-icon-closethick', 'click', this.on_close_action);
|
||||
|
||||
// Init actions
|
||||
_.each(this.node.children, function(column, column_index) {
|
||||
_.each(column.children, function(action, action_index) {
|
||||
delete(action.attrs.width);
|
||||
delete(action.attrs.height);
|
||||
delete(action.attrs.colspan);
|
||||
var action_id = _.str.toNumber(action.attrs.name);
|
||||
if (!_.isNaN(action_id)) {
|
||||
self.rpc('/web/action/load', {action_id: action_id}, function(result) {
|
||||
self.on_load_action(result, column_index + '_' + action_index, action.attrs);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
on_reset: function() {
|
||||
this.rpc('/web/view/undo_custom', {
|
||||
view_id: this.view.fields_view.view_id,
|
||||
reset: true
|
||||
}, this.do_reload);
|
||||
},
|
||||
on_change_layout: function() {
|
||||
var self = this;
|
||||
var qdict = {
|
||||
current_layout : this.$element.find('.oe_dashboard').attr('data-layout')
|
||||
};
|
||||
var $dialog = instance.web.dialog($('<div>'), {
|
||||
modal: true,
|
||||
title: _t("Edit Layout"),
|
||||
width: 'auto',
|
||||
height: 'auto'
|
||||
}).html(QWeb.render('DashBoard.layouts', qdict));
|
||||
$dialog.find('li').click(function() {
|
||||
var layout = $(this).attr('data-layout');
|
||||
$dialog.dialog('destroy');
|
||||
self.do_change_layout(layout);
|
||||
});
|
||||
},
|
||||
do_change_layout: function(new_layout) {
|
||||
var $dashboard = this.$element.find('.oe_dashboard');
|
||||
var current_layout = $dashboard.attr('data-layout');
|
||||
if (current_layout != new_layout) {
|
||||
var clayout = current_layout.split('-').length,
|
||||
nlayout = new_layout.split('-').length,
|
||||
column_diff = clayout - nlayout;
|
||||
if (column_diff > 0) {
|
||||
var $last_column = $();
|
||||
$dashboard.find('.oe_dashboard_column').each(function(k, v) {
|
||||
if (k >= nlayout) {
|
||||
$(v).find('.oe_dashboard_action').appendTo($last_column);
|
||||
} else {
|
||||
$last_column = $(v);
|
||||
}
|
||||
});
|
||||
}
|
||||
$dashboard.toggleClass('oe_dashboard_layout_' + current_layout + ' oe_dashboard_layout_' + new_layout);
|
||||
$dashboard.attr('data-layout', new_layout);
|
||||
this.do_save_dashboard();
|
||||
}
|
||||
},
|
||||
on_fold_action: function(e) {
|
||||
var $e = $(e.currentTarget),
|
||||
$action = $e.parents('.oe_dashboard_action:first'),
|
||||
id = parseInt($action.attr('data-id'), 10);
|
||||
if ($e.is('.ui-icon-minusthick')) {
|
||||
$action.data('action_attrs').fold = '1';
|
||||
} else {
|
||||
delete($action.data('action_attrs').fold);
|
||||
}
|
||||
$e.toggleClass('ui-icon-minusthick ui-icon-plusthick');
|
||||
$action.find('.oe_dashboard_action_content').toggle();
|
||||
this.do_save_dashboard();
|
||||
},
|
||||
on_close_action: function(e) {
|
||||
if (confirm(_t("Are you sure you want to remove this item ?"))) {
|
||||
$(e.currentTarget).parents('.oe_dashboard_action:first').remove();
|
||||
this.do_save_dashboard();
|
||||
}
|
||||
},
|
||||
do_save_dashboard: function() {
|
||||
var self = this;
|
||||
var board = {
|
||||
form_title : this.view.fields_view.arch.attrs.string,
|
||||
style : this.$element.find('.oe_dashboard').attr('data-layout'),
|
||||
columns : []
|
||||
};
|
||||
this.$element.find('.oe_dashboard_column').each(function() {
|
||||
var actions = [];
|
||||
$(this).find('.oe_dashboard_action').each(function() {
|
||||
var action_id = $(this).attr('data-id'),
|
||||
new_attrs = _.clone($(this).data('action_attrs'));
|
||||
if (new_attrs.domain) {
|
||||
new_attrs.domain = new_attrs.domain_string;
|
||||
delete(new_attrs.domain_string);
|
||||
}
|
||||
if (new_attrs.context) {
|
||||
new_attrs.context = new_attrs.context_string;
|
||||
delete(new_attrs.context_string);
|
||||
}
|
||||
actions.push(new_attrs);
|
||||
});
|
||||
board.columns.push(actions);
|
||||
});
|
||||
var arch = QWeb.render('DashBoard.xml', board);
|
||||
this.rpc('/web/view/add_custom', {
|
||||
view_id: this.view.fields_view.view_id,
|
||||
arch: arch
|
||||
}, function() {
|
||||
self.$element.find('.oe_dashboard_link_reset').show();
|
||||
});
|
||||
},
|
||||
on_load_action: function(result, index, action_attrs) {
|
||||
var self = this,
|
||||
action = result.result,
|
||||
view_mode = action_attrs.view_mode;
|
||||
|
||||
if (action_attrs.context && action_attrs.context['dashboard_merge_domains_contexts'] === false) {
|
||||
// TODO: replace this 6.1 workaround by attribute on <action/>
|
||||
action.context = action_attrs.context || {};
|
||||
action.domain = action_attrs.domain || [];
|
||||
} else {
|
||||
if (action_attrs.context) {
|
||||
action.context = _.extend((action.context || {}), action_attrs.context);
|
||||
}
|
||||
if (action_attrs.domain) {
|
||||
action.domain = action.domain || [];
|
||||
action.domain.unshift.apply(action.domain, action_attrs.domain);
|
||||
}
|
||||
}
|
||||
|
||||
var action_orig = _.extend({ flags : {} }, action);
|
||||
|
||||
if (view_mode && view_mode != action.view_mode) {
|
||||
action.views = _.map(view_mode.split(','), function(mode) {
|
||||
mode = mode === 'tree' ? 'list' : mode;
|
||||
return _(action.views).find(function(view) { return view[1] == mode; })
|
||||
|| [false, mode];
|
||||
});
|
||||
}
|
||||
|
||||
action.flags = {
|
||||
search_view : false,
|
||||
sidebar : false,
|
||||
views_switcher : false,
|
||||
action_buttons : false,
|
||||
pager: false,
|
||||
low_profile: true,
|
||||
display_title: false,
|
||||
list: {
|
||||
selectable: false
|
||||
}
|
||||
};
|
||||
var am = new instance.web.ActionManager(this),
|
||||
// FIXME: ideally the dashboard view shall be refactored like kanban.
|
||||
$action = $('#' + this.view.element_id + '_action_' + index);
|
||||
$action.parent().data('action_attrs', action_attrs);
|
||||
this.action_managers.push(am);
|
||||
am.appendTo($action);
|
||||
am.do_action(action);
|
||||
am.do_action = function (action) {
|
||||
self.do_action(action);
|
||||
};
|
||||
if (action_attrs.creatable && action_attrs.creatable !== 'false') {
|
||||
var action_id = parseInt(action_attrs.creatable, 10);
|
||||
$action.parent().find('button.oe_dashboard_button_create').click(function() {
|
||||
if (isNaN(action_id)) {
|
||||
action_orig.flags.default_view = 'form';
|
||||
self.do_action(action_orig);
|
||||
} else {
|
||||
self.rpc('/web/action/load', {
|
||||
action_id: action_id
|
||||
}, function(result) {
|
||||
result.result.flags = result.result.flags || {};
|
||||
result.result.flags.default_view = 'form';
|
||||
self.do_action(result.result);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (am.inner_widget) {
|
||||
am.inner_widget.on_mode_switch.add(function(mode) {
|
||||
var new_views = [];
|
||||
_.each(action_orig.views, function(view) {
|
||||
new_views[view[1] === mode ? 'unshift' : 'push'](view);
|
||||
});
|
||||
if (!new_views.length || new_views[0][1] !== mode) {
|
||||
new_views.unshift([false, mode]);
|
||||
}
|
||||
action_orig.views = new_views;
|
||||
action_orig.res_id = am.inner_widget.dataset.ids[am.inner_widget.dataset.index];
|
||||
self.do_action(action_orig);
|
||||
});
|
||||
}
|
||||
},
|
||||
renderElement: function() {
|
||||
this._super();
|
||||
|
||||
var check = _.detect(this.node.children, function(column, column_index) {
|
||||
return _.detect(column.children,function(element){
|
||||
return element.tag === "action"? element: false;
|
||||
});
|
||||
});
|
||||
if (!check) {
|
||||
return this.no_result();
|
||||
}
|
||||
// We should start with three columns available
|
||||
for (var i = this.node.children.length; i < 3; i++) {
|
||||
this.node.children.push({
|
||||
tag: 'column',
|
||||
attrs: {},
|
||||
children: []
|
||||
});
|
||||
}
|
||||
var rendered = QWeb.render(this.form_template, this);
|
||||
this.$element.html(rendered);
|
||||
},
|
||||
no_result: function() {
|
||||
if (this.view.options.action.help) {
|
||||
this.$element.append(
|
||||
$('<div class="oe_view_nocontent">')
|
||||
.append($('<div>').html(this.view.options.action.help || " "))
|
||||
);
|
||||
}
|
||||
},
|
||||
do_reload: function() {
|
||||
var view_manager = this.view.getParent(),
|
||||
action_manager = view_manager.getParent();
|
||||
this.view.destroy();
|
||||
action_manager.do_action(view_manager.action);
|
||||
}
|
||||
});
|
||||
instance.web.form.DashBoardLegacy = instance.web.form.DashBoard.extend({
|
||||
renderElement: function() {
|
||||
if (this.node.tag == 'hpaned') {
|
||||
this.node.attrs.style = '2-1';
|
||||
} else if (this.node.tag == 'vpaned') {
|
||||
this.node.attrs.style = '1';
|
||||
}
|
||||
this.node.tag = 'board';
|
||||
_.each(this.node.children, function(child) {
|
||||
if (child.tag.indexOf('child') == 0) {
|
||||
child.tag = 'column';
|
||||
var actions = [], first_child = child.children[0];
|
||||
if (first_child && first_child.tag == 'vpaned') {
|
||||
_.each(first_child.children, function(subchild) {
|
||||
actions.push.apply(actions, subchild.children);
|
||||
});
|
||||
child.children = actions;
|
||||
}
|
||||
}
|
||||
});
|
||||
this._super(this);
|
||||
}
|
||||
});
|
||||
|
||||
instance.web.form.tags.add('hpaned', 'instance.web.form.DashBoardLegacy');
|
||||
instance.web.form.tags.add('vpaned', 'instance.web.form.DashBoardLegacy');
|
||||
instance.web.form.tags.add('board', 'instance.web.form.DashBoard');
|
||||
|
||||
|
||||
instance.board.AddToDashboard = instance.web.search.Input.extend({
|
||||
template: 'SearchView.addtodashboard',
|
||||
_in_drawer: true,
|
||||
start: function () {
|
||||
var self = this;
|
||||
this.$element
|
||||
.on('click', 'h4', this.proxy('show_option'))
|
||||
.on('submit', 'form', function (e) {
|
||||
e.preventDefault();
|
||||
self.add_dashboard();
|
||||
});
|
||||
return this.load_data().then(this.proxy("render_data"));
|
||||
},
|
||||
load_data:function(){
|
||||
var board = new instance.web.Model('board.board');
|
||||
return board.call('list');
|
||||
},
|
||||
_x:function() {
|
||||
if (!instance.webclient) { return $.Deferred().reject(); }
|
||||
var dashboard_menu = instance.webclient.menu.data.data.children;
|
||||
return new instance.web.Model('ir.model.data')
|
||||
.query(['res_id'])
|
||||
.filter([['name','=','menu_reporting_dashboard']])
|
||||
.first().pipe(function (result) {
|
||||
var menu = _(dashboard_menu).chain()
|
||||
.pluck('children')
|
||||
.flatten(true)
|
||||
.find(function (child) { return child.id === result.res_id; })
|
||||
.value();
|
||||
return menu ? menu.children : [];
|
||||
});
|
||||
},
|
||||
render_data: function(dashboard_choices){
|
||||
var selection = instance.web.qweb.render(
|
||||
"SearchView.addtodashboard.selection", {
|
||||
selections: dashboard_choices});
|
||||
this.$("input").before(selection)
|
||||
},
|
||||
add_dashboard: function(){
|
||||
var self = this;
|
||||
var getParent = this.getParent();
|
||||
var view_parent = this.getParent().getParent();
|
||||
if (! view_parent.action || ! this.$element.find("select").val()) {
|
||||
this.do_warn("Can't find dashboard action");
|
||||
return;
|
||||
}
|
||||
var data = getParent.build_search_data();
|
||||
var context = new instance.web.CompoundContext(getParent.dataset.get_context() || []);
|
||||
var domain = new instance.web.CompoundDomain(getParent.dataset.get_domain() || []);
|
||||
_.each(data.contexts, context.add, context);
|
||||
_.each(data.domains, domain.add, domain);
|
||||
this.rpc('/board/add_to_dashboard', {
|
||||
menu_id: this.$element.find("select").val(),
|
||||
action_id: view_parent.action.id,
|
||||
context_to_save: context,
|
||||
domain: domain,
|
||||
view_mode: view_parent.active_view,
|
||||
name: this.$element.find("input").val()
|
||||
}, function(r) {
|
||||
if (r === false) {
|
||||
self.do_warn("Could not add filter to dashboard");
|
||||
} else {
|
||||
self.$element.toggleClass('oe_opened');
|
||||
self.do_notify("Filter added to dashboard", '');
|
||||
}
|
||||
});
|
||||
},
|
||||
show_option:function(){
|
||||
this.$element.toggleClass('oe_opened');
|
||||
if (! this.$element.hasClass('oe_opened'))
|
||||
return;
|
||||
this.$("input").val(this.getParent().fields_view.name || "" );
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
instance.web.SearchView.include({
|
||||
add_common_inputs: function() {
|
||||
this._super();
|
||||
(new instance.board.AddToDashboard(this));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
};
|
|
@ -0,0 +1,80 @@
|
|||
<template>
|
||||
<t t-name="DashBoard">
|
||||
<div class="oe_dashboard_links">
|
||||
<button type="button" class="button oe_dashboard_link_reset" title="Reset Layout.." t-att-style="view.fields_view.custom_view_id ? null : 'display: none'">
|
||||
<img src="/board/static/src/img/layout_2-1.png" width="16" height="16"/>
|
||||
<span> Reset </span>
|
||||
</button>
|
||||
<button type="button" class="button oe_dashboard_link_change_layout" title="Change Layout..">
|
||||
<img src="/board/static/src/img/layout_1-1-1.png" width="16" height="16"/>
|
||||
<span> Change Layout </span>
|
||||
</button>
|
||||
</div>
|
||||
<table t-att-data-layout="node.attrs.style" t-attf-class="oe_dashboard oe_dashboard_layout_#{node.attrs.style}" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr>
|
||||
<td t-foreach="node.children" t-as="column" t-if="column.tag == 'column'"
|
||||
t-att-id="view.element_id + '_column_' + column_index" t-attf-class="oe_dashboard_column index_#{column_index}">
|
||||
|
||||
<t t-foreach="column.children" t-as="action" t-if="action.tag == 'action'" t-call="DashBoard.action"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</t>
|
||||
<t t-name="DashBoard.action">
|
||||
<div t-att-data-id="action.attrs.name" class="oe_dashboard_action">
|
||||
<h2 t-attf-class="oe_dashboard_action_header #{action.attrs.string ? '' : 'oe_dashboard_action_header_empty'}">
|
||||
<t t-esc="action.attrs.string"/>
|
||||
<t t-if="!action.attrs.string">&nbsp;</t>
|
||||
<button t-if="action.attrs.creatable and action.attrs.creatable !== 'false'" class="oe_button oe_dashboard_button_create">Create</button>
|
||||
<span class='ui-icon ui-icon-closethick'></span>
|
||||
<span class='ui-icon ui-icon-minusthick oe_dashboard_fold' t-if="!action.attrs.fold"></span>
|
||||
<span class='ui-icon ui-icon-plusthick oe_dashboard_fold' t-if="action.attrs.fold"></span>
|
||||
</h2>
|
||||
<div t-attf-id="#{view.element_id}_action_#{column_index}_#{action_index}" class="oe_dashboard_action_content" t-att-style="action.attrs.fold ? 'display: none' : null"></div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="DashBoard.layouts">
|
||||
<div class="oe_dashboard_layout_selector">
|
||||
<p>
|
||||
<strong>Choose dashboard layout</strong>
|
||||
</p>
|
||||
<ul>
|
||||
<li t-foreach="'1 1-1 1-1-1 1-2 2-1'.split(' ')" t-as="layout" t-att-data-layout="layout">
|
||||
<img t-attf-src="/board/static/src/img/layout_#{layout}.png"/>
|
||||
<img t-if="layout == current_layout"
|
||||
src="/web/static/src/img/icons/gtk-apply.png" width="16" height="16" class="oe_dashboard_selected_layout"/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="DashBoard.xml">
|
||||
<form t-att-string="form_title" version="7.0">
|
||||
<board t-att-style="style">
|
||||
<column t-foreach="columns" t-as="column">
|
||||
<action t-foreach="column" t-as="action" t-att="action"/>
|
||||
</column>
|
||||
</board>
|
||||
</form>
|
||||
</t>
|
||||
<div t-name="HomeWidget" class="oe_dashboard_home_widget"/>
|
||||
<t t-name="HomeWidget.content">
|
||||
<h3><t t-esc="widget.title"/></h3>
|
||||
<iframe width="100%" frameborder="0" t-att-src="url"/>
|
||||
</t>
|
||||
|
||||
<div t-name="SearchView.addtodashboard" class="oe_searchview_dashboard">
|
||||
<h4>Add to Dashboard</h4>
|
||||
<form>
|
||||
<p><input placeholder="Title of new dashboard item"/></p>
|
||||
<button class="oe_apply" type="submit">Add</button>
|
||||
</form>
|
||||
</div>
|
||||
<t t-name="SearchView.addtodashboard.selection">
|
||||
<select>
|
||||
<option t-foreach="selections" t-as="element"
|
||||
t-att-value="element.id ">
|
||||
<t t-esc="element.name"/></option>
|
||||
</select>
|
||||
</t>
|
||||
|
||||
</template>
|
|
@ -1,25 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import board_menu_create
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# 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 osv import fields, osv
|
||||
from tools.translate import _
|
||||
|
||||
class board_menu_create(osv.osv_memory):
|
||||
"""
|
||||
Create Menu
|
||||
"""
|
||||
def view_init(self, cr, uid, fields, context=None):
|
||||
"""
|
||||
This function checks for precondition before wizard executes
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param fields: List of fields for default value
|
||||
@param context: A standard dictionary for contextual values
|
||||
|
||||
check dashboard view on menu name field.
|
||||
@return: False
|
||||
"""
|
||||
data = context and context.get('active_id', False) or False
|
||||
if data:
|
||||
return False
|
||||
|
||||
|
||||
def board_menu_create(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
Create Menu.
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of Board Menu Create's IDs
|
||||
@return: Dictionary {}.
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
context_id = context and context.get('active_id', False) or False
|
||||
if context_id:
|
||||
board = self.pool.get('board.board').browse(cr, uid, context_id, context=context)
|
||||
action_id = self.pool.get('ir.actions.act_window').create(cr, uid, {
|
||||
'name': board.name,
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'board.board',
|
||||
'view_id': board.view_id.id,
|
||||
'help': _('''<div class="oe_empty_custom_dashboard">
|
||||
<p>
|
||||
<b>This dashboard is empty.</b>
|
||||
</p><p>
|
||||
To add the first report into this dashboard, go to any
|
||||
menu, switch to list or graph view, and click <i>'Add to
|
||||
Dashboard'</i> in the extended search options.
|
||||
</p><p>
|
||||
You can filter and group data before inserting into the
|
||||
dashboard using the search options.
|
||||
</p>
|
||||
</div>
|
||||
''')
|
||||
})
|
||||
obj_menu = self.pool.get('ir.ui.menu')
|
||||
#start Loop
|
||||
for data in self.browse(cr, uid, ids, context=context):
|
||||
obj_menu.create(cr, uid, {
|
||||
'name': data.menu_name,
|
||||
'parent_id': data.menu_parent_id.id,
|
||||
'action': 'ir.actions.act_window,' + str(action_id)
|
||||
}, context=context)
|
||||
#End Loop
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
_name = "board.menu.create"
|
||||
_description = "Menu Create"
|
||||
|
||||
_columns = {
|
||||
'menu_name': fields.char('Menu Name', size=64, required=True),
|
||||
'menu_parent_id': fields.many2one('ir.ui.menu', 'Parent Menu', required=True),
|
||||
}
|
||||
|
||||
board_menu_create()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!--Board menu create wizard -->
|
||||
|
||||
<record id="view_board_menu_create" model="ir.ui.view">
|
||||
<field name="name">board.menu.create.form</field>
|
||||
<field name="model">board.menu.create</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Create Menu For Dashboard" version="7.0">
|
||||
<group colspan="4" string="Menu Information">
|
||||
<field name="menu_name"/>
|
||||
<field name="menu_parent_id"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button string="Create Menu" name="board_menu_create" type="object" class="oe_highlight"/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Action for Board Menu create wizard. -->
|
||||
|
||||
<record id="action_board_menu_create" model="ir.actions.act_window">
|
||||
<field name="name">Create Board Menu</field>
|
||||
<field name="res_model">board.menu.create</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_board_menu_create"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
Loading…
Reference in New Issue