[IMP] website: create generic kanban view
bzr revid: chm@openerp.com-20130821160632-tsl5v1l5cj10w92c
This commit is contained in:
parent
98f19d8890
commit
b806728af1
|
@ -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:
|
||||
|
|
|
@ -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 > 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 < 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("> .thumbnail").remove();
|
||||
$pagination.first().after('<div class="thumbnail">'+col+'</div>');
|
||||
});
|
||||
|
||||
var page_start = page - parseInt(Math.floor((scope-1)/2));
|
||||
if (page_start < 1 ) page_start = 1;
|
||||
var page_end = page_start + (scope-1);
|
||||
if (page_end > page_count ) page_end = page_count;
|
||||
|
||||
if (page_end - page_start < scope) {
|
||||
page_start = page_end - scope > 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 < 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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue