[IMP] website: create generic kanban view

bzr revid: chm@openerp.com-20130821160632-tsl5v1l5cj10w92c
This commit is contained in:
Christophe Matthieu 2013-08-21 18:06:32 +02:00
parent 98f19d8890
commit b806728af1
5 changed files with 226 additions and 44 deletions

View File

@ -218,4 +218,8 @@ class Website(openerp.addons.web.controllers.main.Home):
return obj.website_published and "1" or "0"
@http.route(['/website/kanban/'], type='http', auth="public")
def kanban(self, **post):
return request.registry['website'].kanban_col(**post)
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -421,5 +421,125 @@
</template>
<template id="kanban">
<t t-set="step"><t t-esc="step or 0"/></t>
<t t-set="scope"><t t-esc="scope or 0"/></t>
<t t-set="orderby"><t t-esc="orderby or 'name'"/></t>
<t t-raw="snipped['kanban'](model, domain, column, content, step=step, scope=scope, orderby=orderby)"/>
</template>
<template id="kanban_contain">
<table class="table">
<thead>
<tr>
<t t-set="width" t-value="'%%s%%%%' % (100/len(objects))"/>
<t t-foreach="objects">
<th t-att-width="width">
<div t-field="column_id.name" class="text-center"/>
</th>
</t>
</tr>
</thead>
<tbody>
<tr>
<t t-foreach="objects">
<t t-set="pager">
<div t-if="1 != page_end" class="pagination pagination-centered">
<ul>
<li t-attf-class="prev #{'active' if page == 1 else '' }" >
<a t-att-href=" '%s,%s-%s' % (kanban_url, column_id.id, (page &gt; 1 and page-1 or 1)) ">Prev</a>
</li>
<t t-foreach="range(page_start, page_end+1)" t-as="p">
<li t-att-class=" 'active' if page == p else '' ">
<a t-att-href=" '%s,%s-%s' % (kanban_url, column_id.id, p)" t-esc="p"/>
</li>
</t>
<li t-attf-class="next #{'active' if page == page_end else '' }" >
<a t-att-href=" '%s,%s-%s' % (kanban_url, column_id.id, (page &lt; page_end and page+1 or page_end) )">Next</a>
</li>
</ul>
</div>
</t>
<td class="js_kanban_col"
t-att-data-content="content"
t-att-data-domain="domain"
t-att-data-page_count="page_count"
t-att-data-model="model"
t-att-data-step="step"
t-att-data-orderby="orderby">
<t t-raw="pager"/>
<div t-foreach="object_ids" t-as="object_id" class="thumbnail">
<t t-call="website_project.kanban_card"/>
</div>
<t t-raw="pager"/>
</td>
</t>
</tr>
</tbody>
</table>
<script>
$('.js_kanban_col').each(function () {
var $col = $(this);
var $pagination = $('.pagination', $col);
if(!$pagination.size()) {
return;
}
var page_count = $col.data('page_count');
var scope = $pagination.first().find("li").size()-2;
var kanban_url_col = $pagination.find("li a:first").attr("href").replace(/[0-9]+$/, '');
var data = {
'domain': $col.data('domain'),
'model': $col.data('model'),
'content': $col.data('content'),
'step': $col.data('step'),
'orderby': $col.data('orderby')
};
$pagination.on('click', 'a', function (ev) {
ev.preventDefault();
var $a = $(ev.target);
if($a.hasClass('active')) {
return;
}
var page = +$a.attr("href").split(",").pop().split('-')[1];
data['page'] = page;
$.post('/website/kanban/', data, function (col) {
$col.find("&gt; .thumbnail").remove();
$pagination.first().after('<div class="thumbnail">'+col+'</div>');
});
var page_start = page - parseInt(Math.floor((scope-1)/2));
if (page_start &lt; 1 ) page_start = 1;
var page_end = page_start + (scope-1);
if (page_end &gt; page_count ) page_end = page_count;
if (page_end - page_start &lt; scope) {
page_start = page_end - scope &gt; 0 ? page_end - scope : 1;
}
$pagination.find('li.prev a').attr("href", kanban_url_col+(page-1 > 0 ? page-1 : 1));
$pagination.find('li.next a').attr("href", kanban_url_col+(page+1));
for(var i=0; i &lt; scope; i++) {
$pagination.find('li:not(.prev):not(.next):eq('+i+') a').attr("href", kanban_url_col+(page_start+i)).html(page_start+i);
}
$pagination.find('li.active').removeClass('active');
$pagination.find('li:has(a[href="'+kanban_url_col+page+'"])').addClass('active');
});
});
</script>
</template>
</data>
</openerp>

View File

@ -9,6 +9,7 @@ from openerp.addons.web.http import request
import urllib
import math
import traceback
from openerp.tools.safe_eval import safe_eval
import logging
logger = logging.getLogger(__name__)
@ -63,6 +64,9 @@ class website(osv.osv):
'host_url': request.httprequest.host_url,
'res_company': request.registry['res.company'].browse(request.cr, openerp.SUPERUSER_ID, 1),
'json': simplejson,
'snipped': {
'kanban': self.kanban
}
}
if additional_values:
values.update(additional_values)
@ -75,10 +79,10 @@ class website(osv.osv):
}
try:
return view.render(request.cr, request.uid, template, values, context=context)
except (osv.except_osv, orm.except_orm), err:
logger.error(err)
values['error'] = err[1]
return self.render('website.401', values)
# except (osv.except_osv, orm.except_orm), err:
# logger.error(err)
# values['error'] = err[1]
# return self.render('website.401', values)
# except ValueError:
# logger.error("Website Rendering Error.\n\n%s" % (traceback.format_exc()))
# return self.render('website.404', values)
@ -146,6 +150,77 @@ class website(osv.osv):
if xids[view['id']]
]
def kanban(self, model, domain, column, content, step=None, scope=None, orderby=None):
step = step and int(step) or 10
scope = scope and int(scope) or 5
orderby = orderby or "name"
get_args = dict(request.httprequest.args or {})
model_obj = request.registry[model]
relation = model_obj._columns.get(column)._obj
relation_obj = request.registry[relation]
get_args.setdefault('kanban', "")
kanban = get_args.pop('kanban')
kanban_url = "?%s&kanban=" % urllib.urlencode(get_args)
pages = {}
for col in kanban.split(","):
if col:
col = col.split("-")
pages[int(col[0])] = int(col[1])
objects = []
for group in model_obj.read_group(request.cr, request.uid, domain, ["id", column], groupby=column):
obj = {}
# browse column
relation_id = group[column][0]
obj['column_id'] = relation_obj.browse(request.cr, request.uid, relation_id)
obj['kanban_url'] = kanban_url
for k, v in pages.items():
if k != relation_id:
obj['kanban_url'] += "%s-%s" % (k, v)
# pager
number = model_obj.search(request.cr, request.uid, group['__domain'], count=True)
obj['page'] = pages.get(relation_id) or 1
obj['page_count'] = int(math.ceil(float(number) / step))
offset = (obj['page']-1) * step
obj['page_start'] = max(obj['page'] - int(math.floor((scope-1)/2)), 1)
obj['page_end'] = min(obj['page_start'] + (scope-1), obj['page_count'])
# view data
obj['domain'] = group['__domain']
obj['model'] = model
obj['step'] = step
obj['orderby'] = orderby
# browse objects
object_ids = model_obj.search(request.cr, request.uid, group['__domain'], limit=step, offset=offset, order=orderby)
obj['object_ids'] = model_obj.browse(request.cr, request.uid, object_ids)
objects.append(obj)
values = self.get_rendering_context({
'objects': objects,
'range': range,
'content': content,
})
return self.render("website.kanban_contain", values)
def kanban_col(self, model, domain, page, content, step, orderby):
html = ""
model_obj = request.registry[model]
domain = safe_eval(domain)
step = int(step)
offset = (int(page)-1) * step
object_ids = model_obj.search(request.cr, request.uid, domain, limit=step, offset=offset, order=orderby)
object_ids = model_obj.browse(request.cr, request.uid, object_ids)
for object_id in object_ids:
html += self.render(content, self.get_rendering_context({'object_id': object_id}))
return html
class res_partner(osv.osv):
_inherit = "res.partner"

View File

@ -24,20 +24,10 @@ class website_project(http.Controller):
def blog(self, project_id=None, **post):
website = request.registry['website']
project_obj = request.registry['project.project']
task_obj = request.registry['project.task']
stage_obj = request.registry['project.task.type']
project = project_obj.browse(request.cr, request.uid, project_id)
domain = [('id', 'in', [task.id for task in project.tasks])]
stages = task_obj.read_group(request.cr, request.uid, domain, ["id", "stage_id"], groupby="stage_id")
for stage in stages:
stage['stage_id'] = stage_obj.browse(request.cr, request.uid, stage['stage_id'][0])
task_ids = task_obj.search(request.cr, request.uid, stage['__domain'])
stage['task_ids'] = task_obj.browse(request.cr, request.uid, task_ids)
values = website.get_rendering_context({
'project_id': project,
'stages': stages,
})
return website.render("website_project.index", values)

View File

@ -13,41 +13,34 @@
<!-- Page -->
<template id="kanban_card" name="Project">
<a t-attf-href="/task/#{ object_id.id }/"><span t-field="object_id.name"/></a>
<div>
Assigned to <span t-field="object_id.user_id"/>
</div>
<div>
<span t-foreach="object_id.categ_ids" t-as="categ_id" class="label">
<t t-esc="categ_id.name"/>
</span>
</div>
<small>
<i class="icon-time"></i> <span t-field="object_id.date_start"/><br/>
<t t-if="object_id.date_end">Ending Date: <span t-field="object_id.date_end"/></t>
</small>
</template>
<template id="index" name="Project">
<t t-call="website.layout">
<t t-set="title">Project</t>
<div class="container">
<h4 t-field="project_id.name"/>
<table class="table">
<thead>
<tr>
<th t-foreach="stages">
<span t-field="stage_id.name"/>
</th>
</tr>
</thead>
<tbody>
<tr>
<td t-foreach="stages" t-as="stage">
<div t-foreach="stage['task_ids']" t-as="task" class="thumbnail">
<a t-attf-href="/task/#{ task.id }/"><span t-field="task.name"/></a>
<div>
Assigned to <span t-field="task.user_id"/>
</div>
<div>
<span t-foreach="task.categ_ids" t-as="categ" class="label">
<t t-esc="categ.name"/>
</span>
</div>
<small>
<i class="icon-time"></i> <span t-field="task.date_start"/><br/>
<t t-if="task.date_end">Ending Date: <span t-field="task.date_end"/></t>
</small>
</div>
</td>
</tr>
</tbody>
</table>
<t t-call="website.kanban">
<t t-set="model">project.task</t>
<t t-set="domain" t-value="[('project_id', '=', project_id.id)]"/>
<t t-set="column">stage_id</t>
<t t-set="content">website_project.kanban_card</t>
</t>
</div>
</t>
</template>