mirror of https://github.com/OCA/web.git
Merge pull request #95 from yelizariev/8.0-web_last_viewed_records
8.0 web_last_viewed_recordspull/102/head
commit
02d82a468f
|
@ -0,0 +1,46 @@
|
||||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||||
|
:alt: License
|
||||||
|
|
||||||
|
Last viewed records
|
||||||
|
===================
|
||||||
|
|
||||||
|
The module shows links to last viewed records and pages.
|
||||||
|
|
||||||
|
The module doesn't affect on server performance, because it uses
|
||||||
|
browser's localStorage to save history. But dissadvantage is that
|
||||||
|
history is not synced accross browsers.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
There are no any settings to configure. Just install module and continue to use odoo in a usual way. You will see links to last visited pages.
|
||||||
|
|
||||||
|
For further information, please visit:
|
||||||
|
|
||||||
|
* https://yelizariev.github.io/odoo/module/2015/02/18/last-viewed-records.html
|
||||||
|
|
||||||
|
Known issues / Roadmap
|
||||||
|
======================
|
||||||
|
|
||||||
|
* FIXME: doesn't work in a res.config view
|
||||||
|
|
||||||
|
Credits
|
||||||
|
=======
|
||||||
|
|
||||||
|
Contributors
|
||||||
|
------------
|
||||||
|
|
||||||
|
* Ivan Yelizariev <yelizariev@it-projects.info>
|
||||||
|
|
||||||
|
Maintainer
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. image:: http://odoo-community.org/logo.png
|
||||||
|
:alt: Odoo Community Association
|
||||||
|
:target: http://odoo-community.org
|
||||||
|
|
||||||
|
This module is maintained by the OCA.
|
||||||
|
|
||||||
|
OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.
|
||||||
|
|
||||||
|
To contribute to this module, please visit http://odoo-community.org.
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
'name': 'Last viewed records',
|
||||||
|
'version': '1.0.0',
|
||||||
|
'author': 'Ivan Yelizariev, Odoo Community Association (OCA)',
|
||||||
|
'category': 'Base',
|
||||||
|
'website': 'https://yelizariev.github.io',
|
||||||
|
'depends': ['web', 'mail'],
|
||||||
|
'data': [
|
||||||
|
'views.xml',
|
||||||
|
],
|
||||||
|
'qweb': [
|
||||||
|
"static/src/xml/main.xml",
|
||||||
|
],
|
||||||
|
'installable': True
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
.oe_last_viewed_item.selected{
|
||||||
|
font-weight:bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openerp .oe_last_viewed_item .oe_e {
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 300 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.openerp .oe_last_viewed_item .list:after, .openerp .oe_last_viewed_item .tree:after {
|
||||||
|
padding: 2px;
|
||||||
|
content: "i";
|
||||||
|
}
|
||||||
|
.openerp .oe_last_viewed_item .form:after {
|
||||||
|
content: "m";
|
||||||
|
}
|
||||||
|
.openerp .oe_last_viewed_item .graph:after {
|
||||||
|
font-family: "mnmliconsRegular" !important;
|
||||||
|
font-size: 21px;
|
||||||
|
font-weight: 300 !important;
|
||||||
|
content: "}";
|
||||||
|
top: -2px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.openerp .oe_last_viewed_item .gantt:after {
|
||||||
|
font-family: "mnmliconsRegular" !important;
|
||||||
|
font-size: 21px;
|
||||||
|
font-weight: 300 !important;
|
||||||
|
content: "y";
|
||||||
|
top: -2px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.openerp .oe_last_viewed_item .calendar:after {
|
||||||
|
content: "P";
|
||||||
|
}
|
||||||
|
.openerp .oe_last_viewed_item .kanban:after {
|
||||||
|
content: "k";
|
||||||
|
}
|
||||||
|
.openerp .oe_last_viewed_item .diagram:after {
|
||||||
|
content: "f";
|
||||||
|
}
|
||||||
|
.oe_last_viewed_icon.fa{
|
||||||
|
display: inline;
|
||||||
|
}
|
|
@ -0,0 +1,180 @@
|
||||||
|
openerp.web_last_viewed_records = function(instance){
|
||||||
|
var localStorage = {};
|
||||||
|
if (typeof window.localStorage !== "undefined"){
|
||||||
|
localStorage = window.localStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.web.ActionManager.include({
|
||||||
|
last_viewed_history_var: 'odoo_last_viewed',
|
||||||
|
last_viewed_history_size: 8,
|
||||||
|
init:function(){
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
|
this.last_viewed = [];
|
||||||
|
var last_viewed = this.load_last_viewed_history().last_viewed || [];
|
||||||
|
for (var i=last_viewed.length-1; i>=0; i--){
|
||||||
|
this.unshift_last_viewed(last_viewed[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
add_last_viewed: function(item){
|
||||||
|
if (_.any(this.last_viewed, function(x){
|
||||||
|
if (x['title'] != item['title'] ||
|
||||||
|
x['view_type'] != item['view_type'] ||
|
||||||
|
x['url']['model'] != item['url']['model'])
|
||||||
|
return false;
|
||||||
|
if (x['view_type'] == 'form' && x['id'] != item['id'])
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}))
|
||||||
|
return;
|
||||||
|
|
||||||
|
//save json data to localStorage
|
||||||
|
var data = this.load_last_viewed_history();
|
||||||
|
data.last_viewed = data.last_viewed || []
|
||||||
|
data.last_viewed.unshift(item);
|
||||||
|
data.last_viewed.splice(this.last_viewed_history_size);
|
||||||
|
this.save_last_viewed_history(data);
|
||||||
|
|
||||||
|
this.unshift_last_viewed(item);
|
||||||
|
},
|
||||||
|
unshift_last_viewed: function(item){
|
||||||
|
var self = this;
|
||||||
|
this.last_viewed.unshift(item);
|
||||||
|
this.last_viewed.splice(this.last_viewed_history_size);
|
||||||
|
},
|
||||||
|
load_last_viewed_history: function(){
|
||||||
|
var data = localStorage[this.last_viewed_history_var] || '{}';
|
||||||
|
return JSON.parse(data);
|
||||||
|
},
|
||||||
|
save_last_viewed_history: function(data){
|
||||||
|
localStorage[this.last_viewed_history_var] = JSON.stringify(data);
|
||||||
|
},
|
||||||
|
// icon map: http://fortawesome.github.io/Font-Awesome/icons/
|
||||||
|
_model2icon: {
|
||||||
|
'account.analytic.account':'fa-book',
|
||||||
|
'account.invoice':'fa-pencil-square-o',
|
||||||
|
'calendar.event':'fa-calendar',
|
||||||
|
'crm.lead':'fa-star',
|
||||||
|
'crm.phonecall':'fa-phone',
|
||||||
|
'hr.employee':'fa-male',
|
||||||
|
'hr.payslip':'fa-money',
|
||||||
|
'hr_timesheet_sheet.sheet': 'fa-clock-o',
|
||||||
|
'ir.attachment': 'fa-file-o',
|
||||||
|
'ir.module.module':'fa-plus-circle',
|
||||||
|
'product.product': 'fa-sitemap',
|
||||||
|
'project.issue':'fa-bug',
|
||||||
|
'project.project':'fa-folder',
|
||||||
|
'project.task':'fa-tasks',
|
||||||
|
'purchase.order':'fa-shopping-cart',
|
||||||
|
'purchase.order.line':'fa-shopping-cart',
|
||||||
|
'res.company': 'fa-building-o',
|
||||||
|
'res.groups': 'fa-users',
|
||||||
|
'res.partner':'fa-user',
|
||||||
|
'res.user': 'fa-user-plus',
|
||||||
|
'sale.order':'fa-strikethrough',
|
||||||
|
},
|
||||||
|
get_last_viewed_title: function(){
|
||||||
|
var titles = [];
|
||||||
|
for (var i = 0; i < this.last_viewed.length; i += 1) {
|
||||||
|
var item = this.last_viewed[i];
|
||||||
|
var label = item.title;
|
||||||
|
var selected = false;//item.action.id == this.inner_action.id && item.action.res_id == this.inner_action.res_id;
|
||||||
|
var view_type = item.view_type;
|
||||||
|
var url = $.param(item.url);
|
||||||
|
var model = item.url.model;
|
||||||
|
var title = model;
|
||||||
|
|
||||||
|
var icon = this._model2icon[model];
|
||||||
|
if (!icon && /\.settings/.test(model))
|
||||||
|
icon = 'c';
|
||||||
|
if (icon)
|
||||||
|
icon = _.str.sprintf('<span class="oe_last_viewed_icon fa %s"></span>', icon);
|
||||||
|
titles.push(_.str.sprintf('<a title="%s" href="#%s" class="oe_last_viewed_item %s">%s %s <span class="oe_e %s"/></a>',
|
||||||
|
title,
|
||||||
|
url,
|
||||||
|
selected && 'selected' || '',
|
||||||
|
icon || '',
|
||||||
|
label,
|
||||||
|
view_type != 'form' && view_type || ''
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return titles.join(' <span class="oe_fade">|</span> ');
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
instance.web.ViewManagerAction.include({
|
||||||
|
try_add_last_viewed: function(view_type){
|
||||||
|
var view = this.views[view_type];
|
||||||
|
var act = view.options.action;
|
||||||
|
if (!act.type)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (act.target == 'new')
|
||||||
|
//skip widgets and popup forms
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var url = {
|
||||||
|
'view_type': view_type,
|
||||||
|
'model': act.res_model,
|
||||||
|
'menu_id': act.menu_id,
|
||||||
|
'action': act.id
|
||||||
|
}
|
||||||
|
var title = act.display_name;
|
||||||
|
var dr = view.controller.datarecord;
|
||||||
|
if (dr){
|
||||||
|
title = dr.display_name || title;
|
||||||
|
if (view_type=='form'){
|
||||||
|
url['id'] = dr.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (view_type=='form' && !url['id'])
|
||||||
|
return false;
|
||||||
|
var last_viewed_item = {
|
||||||
|
'title': title,
|
||||||
|
'url': url,
|
||||||
|
'view_type': view_type,
|
||||||
|
}
|
||||||
|
this.ActionManager.add_last_viewed(last_viewed_item);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
do_create_view: function(view_type) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var res = this._super.apply(this, arguments);
|
||||||
|
|
||||||
|
var view = this.views[view_type];
|
||||||
|
|
||||||
|
var exec = function(){
|
||||||
|
if (self.active_view == view_type && self.try_add_last_viewed(view_type)){
|
||||||
|
self.update_last_viewed_title()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exec();
|
||||||
|
view.controller.on('change:title', this, function(){
|
||||||
|
exec()
|
||||||
|
})
|
||||||
|
|
||||||
|
return res;
|
||||||
|
|
||||||
|
},
|
||||||
|
update_last_viewed_title: function(){
|
||||||
|
this.$el.find('.oe_view_manager_last_viewed').html(this.get_action_manager().get_last_viewed_title());
|
||||||
|
},
|
||||||
|
set_title: function(){
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
if (this.action.target!='new')
|
||||||
|
this.update_last_viewed_title();
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
instance.mail.Wall.include({
|
||||||
|
start: function() {
|
||||||
|
this._super();
|
||||||
|
this.update_last_viewed_title();
|
||||||
|
},
|
||||||
|
update_last_viewed_title: function(){
|
||||||
|
this.$el.find('.oe_view_manager_last_viewed').html(this.ActionManager.get_last_viewed_title());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<templates>
|
||||||
|
<t t-name="web_last_viewed_records.header">
|
||||||
|
<tr class="oe_header_row">
|
||||||
|
<td t-att-colspan="colspan or '3'">
|
||||||
|
<div class="oe_view_manager_last_viewed"/>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</t>
|
||||||
|
<t t-extend="ViewManagerAction">
|
||||||
|
<t t-jquery="tr.oe_header_row_top" t-operation="after">
|
||||||
|
<t t-call="web_last_viewed_records.header"/>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
<t t-extend="mail.wall">
|
||||||
|
<t t-jquery="tr.oe_header_row_top" t-operation="after">
|
||||||
|
<t t-call="web_last_viewed_records.header">
|
||||||
|
<t t-set="colspan" t-value="2"/>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</t>
|
||||||
|
</templates>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<openerp>
|
||||||
|
<data>
|
||||||
|
<template id="assets_backend" name="custom bar assets" inherit_id="web.assets_backend">
|
||||||
|
<xpath expr="." position="inside">
|
||||||
|
<link rel="stylesheet" href="/web_last_viewed_records/static/src/css/main.css"/>
|
||||||
|
<script type="text/javascript" src="/web_last_viewed_records/static/src/js/main.js"></script>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
</data>
|
||||||
|
</openerp>
|
||||||
|
|
Loading…
Reference in New Issue