[MERGE] from trunk
bzr revid: chm@openerp.com-20140318102102-ug0ny6q360i4o1e6
This commit is contained in:
commit
abe8e7208e
File diff suppressed because it is too large
Load Diff
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 6.0dev\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2013-08-13 04:04+0000\n"
|
||||
"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n"
|
||||
"PO-Revision-Date: 2014-03-15 06:42+0000\n"
|
||||
"Last-Translator: Victor Yu <vivianyw@163.com>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-04 06:19+0000\n"
|
||||
"X-Generator: Launchpad (build 16948)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-16 05:42+0000\n"
|
||||
"X-Generator: Launchpad (build 16963)\n"
|
||||
|
||||
#. module: project
|
||||
#: view:project.project:0
|
||||
|
@ -671,7 +671,7 @@ msgstr "新任务"
|
|||
#. module: project
|
||||
#: field:project.config.settings,module_project_issue_sheet:0
|
||||
msgid "Invoice working time on issues"
|
||||
msgstr ""
|
||||
msgstr "依据问题工作时间开票"
|
||||
|
||||
#. module: project
|
||||
#: view:project.project:0
|
||||
|
@ -828,7 +828,7 @@ msgstr "花费的时间"
|
|||
#: view:project.project:0
|
||||
#: view:project.task:0
|
||||
msgid "í"
|
||||
msgstr ""
|
||||
msgstr "í"
|
||||
|
||||
#. module: project
|
||||
#: field:account.analytic.account,company_uom_id:0
|
||||
|
@ -958,7 +958,7 @@ msgstr "本项目和相关项目的任务实际花费的小时数合计"
|
|||
msgid ""
|
||||
"Follow this project to automatically track the events associated to tasks "
|
||||
"and issues of this project."
|
||||
msgstr ""
|
||||
msgstr "关注此项目的同时,追踪此项目的任务和问题关联的事件。"
|
||||
|
||||
#. module: project
|
||||
#: view:project.task:0
|
||||
|
@ -1018,7 +1018,7 @@ msgstr "信息和通信历史记录"
|
|||
msgid ""
|
||||
"To invoice or setup invoicing and renewal options, go to the related "
|
||||
"contract:"
|
||||
msgstr ""
|
||||
msgstr "开票或设定发票更新选项,到相关的合同:"
|
||||
|
||||
#. module: project
|
||||
#: field:project.task.delegate,state:0
|
||||
|
|
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 6.0dev\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2013-11-19 10:53+0000\n"
|
||||
"Last-Translator: Guipo Hao <hrlpool@sohu.com>\n"
|
||||
"PO-Revision-Date: 2014-03-15 07:15+0000\n"
|
||||
"Last-Translator: Victor Yu <vivianyw@163.com>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-04 07:04+0000\n"
|
||||
"X-Generator: Launchpad (build 16948)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-16 05:42+0000\n"
|
||||
"X-Generator: Launchpad (build 16963)\n"
|
||||
|
||||
#. module: sale
|
||||
#: help:sale.order,message_summary:0
|
||||
|
@ -247,7 +247,7 @@ msgstr "计量单位 "
|
|||
#: code:addons/sale/wizard/sale_make_invoice_advance.py:101
|
||||
#, python-format
|
||||
msgid "Incorrect Data"
|
||||
msgstr ""
|
||||
msgstr "错误的数据"
|
||||
|
||||
#. module: sale
|
||||
#: code:addons/sale/wizard/sale_make_invoice_advance.py:102
|
||||
|
@ -1570,7 +1570,7 @@ msgstr "查找未开票明细"
|
|||
#. module: sale
|
||||
#: model:ir.model,name:sale.model_account_config_settings
|
||||
msgid "account.config.settings"
|
||||
msgstr ""
|
||||
msgstr "会计.配置.设定"
|
||||
|
||||
#. module: sale
|
||||
#: sql_constraint:sale.order:0
|
||||
|
@ -2080,7 +2080,7 @@ msgstr "产品销售单位"
|
|||
#. module: sale
|
||||
#: model:process.node,note:sale.process_node_quotation0
|
||||
msgid "Draft state of sales order"
|
||||
msgstr "销售订单草稿状态"
|
||||
msgstr "草稿状态的销售订单"
|
||||
|
||||
#. module: sale
|
||||
#: field:sale.order,origin:0
|
||||
|
@ -2286,7 +2286,9 @@ msgstr ""
|
|||
msgid ""
|
||||
"Before choosing a product,\n"
|
||||
" select a customer in the sales form."
|
||||
msgstr "在挑选产品前,在 销售表单选择一个客户"
|
||||
msgstr ""
|
||||
"在挑选产品前,\n"
|
||||
" 在销售表单中选择一个客户。"
|
||||
|
||||
#. module: sale
|
||||
#: view:sale.order:0
|
||||
|
|
|
@ -8,14 +8,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:06+0000\n"
|
||||
"PO-Revision-Date: 2012-12-09 05:00+0000\n"
|
||||
"Last-Translator: sum1201 <Unknown>\n"
|
||||
"PO-Revision-Date: 2014-03-16 16:41+0000\n"
|
||||
"Last-Translator: Victor Yu <vivianyw@163.com>\n"
|
||||
"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-04 07:34+0000\n"
|
||||
"X-Generator: Launchpad (build 16948)\n"
|
||||
"X-Launchpad-Export-Date: 2014-03-17 04:48+0000\n"
|
||||
"X-Generator: Launchpad (build 16963)\n"
|
||||
|
||||
#. module: share
|
||||
#: code:addons/share/wizard/share_wizard.py:842
|
||||
|
@ -76,6 +76,8 @@ msgid ""
|
|||
" %s\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"附件没弄好,你可以在OpenERP服务器上查看: %s\n"
|
||||
"\n"
|
||||
|
||||
#. module: share
|
||||
#: model:ir.module.category,name:share.module_category_share
|
||||
|
@ -147,7 +149,7 @@ msgstr "共享URL"
|
|||
#: code:addons/share/wizard/share_wizard.py:881
|
||||
#, python-format
|
||||
msgid "These are your credentials to access this protected area:\n"
|
||||
msgstr ""
|
||||
msgstr "这是你访问这个保护区域的凭证:\n"
|
||||
|
||||
#. module: share
|
||||
#: view:share.wizard:0
|
||||
|
@ -173,7 +175,7 @@ msgstr ""
|
|||
#, python-format
|
||||
msgid ""
|
||||
"Please indicate the emails of the persons to share with, one per line."
|
||||
msgstr ""
|
||||
msgstr "请标明分享的用户电子邮箱,每行一个。"
|
||||
|
||||
#. module: share
|
||||
#: help:share.wizard,domain:0
|
||||
|
@ -189,7 +191,7 @@ msgstr "下一个"
|
|||
#: code:addons/share/wizard/share_wizard.py:662
|
||||
#, python-format
|
||||
msgid "Action and Access Mode are required to create a shared access."
|
||||
msgstr ""
|
||||
msgstr "操作和访问模式都需要要创建一个共享入口。"
|
||||
|
||||
#. module: share
|
||||
#: code:addons/share/wizard/share_wizard.py:850
|
||||
|
@ -256,7 +258,7 @@ msgstr "非共享组"
|
|||
msgid ""
|
||||
"An email notification with instructions has been sent to the following "
|
||||
"people:"
|
||||
msgstr ""
|
||||
msgstr "带有操作说明的邮件通知已经发送到以下人了:"
|
||||
|
||||
#. module: share
|
||||
#: code:addons/share/wizard/share_wizard.py:77
|
||||
|
@ -273,6 +275,8 @@ msgid ""
|
|||
"Sales, HR, etc.)\n"
|
||||
"It is open source and can be found on http://www.openerp.com."
|
||||
msgstr ""
|
||||
"OpenERP是强大的、用户友好的商业应用套装(CRM,销售、人事、等)\n"
|
||||
"而且是开源的,可以在 http://www.openerp.com 找到并下载。"
|
||||
|
||||
#. module: share
|
||||
#: field:share.wizard,action_id:0
|
||||
|
@ -282,7 +286,7 @@ msgstr "共享操作"
|
|||
#. module: share
|
||||
#: help:share.wizard,record_name:0
|
||||
msgid "Name of the shared record, if sharing a precise record"
|
||||
msgstr ""
|
||||
msgstr "如果共享一个精确记录,记录下分享名"
|
||||
|
||||
#. module: share
|
||||
#: field:res.users,share:0
|
||||
|
@ -337,7 +341,7 @@ msgstr "创建新的"
|
|||
#. module: share
|
||||
#: help:share.wizard,name:0
|
||||
msgid "Title for the share (displayed to users as menu and shortcut name)"
|
||||
msgstr ""
|
||||
msgstr "共享标题(显示给用户的菜单和快捷方式的名称)"
|
||||
|
||||
#. module: share
|
||||
#: code:addons/share/wizard/share_wizard.py:636
|
||||
|
@ -348,7 +352,7 @@ msgstr "创建用户 %s (%s )间接共享过滤器,在用户组 %s"
|
|||
#. module: share
|
||||
#: help:share.wizard,share_root_url:0
|
||||
msgid "Main access page for users that are granted shared access"
|
||||
msgstr ""
|
||||
msgstr "用户主要访问的页面被授权共享访问"
|
||||
|
||||
#. module: share
|
||||
#: code:addons/share/wizard/share_wizard.py:206
|
||||
|
@ -356,7 +360,7 @@ msgstr ""
|
|||
msgid ""
|
||||
"You must configure your email address in the user preferences before using "
|
||||
"the Share button."
|
||||
msgstr ""
|
||||
msgstr "在使用分享按钮前,你必须在用户首选项处配置你的电子邮件。"
|
||||
|
||||
#. module: share
|
||||
#: model:res.groups,name:share.group_share_user
|
||||
|
@ -387,7 +391,7 @@ msgstr "数据库"
|
|||
#. module: share
|
||||
#: view:share.wizard:0
|
||||
msgid "Share with these People (one email per line)"
|
||||
msgstr ""
|
||||
msgstr "与这些人分享(每行一个电子邮件)"
|
||||
|
||||
#. module: share
|
||||
#: field:share.wizard,domain:0
|
||||
|
@ -409,7 +413,7 @@ msgstr "简述"
|
|||
#: help:share.wizard,embed_code:0
|
||||
msgid ""
|
||||
"Embed this code in your documents to provide a link to the shared document."
|
||||
msgstr ""
|
||||
msgstr "在你的文档中嵌入下列代码以提供到分享文档的连接。"
|
||||
|
||||
#. module: share
|
||||
#: code:addons/share/wizard/share_wizard.py:513
|
||||
|
@ -431,7 +435,7 @@ msgstr "共享你的单据"
|
|||
#. module: share
|
||||
#: view:share.wizard:0
|
||||
msgid "Or insert the following code where you want to embed your documents"
|
||||
msgstr ""
|
||||
msgstr "或者在你想要嵌入你的文档时,插入下列代码"
|
||||
|
||||
#. module: share
|
||||
#: code:addons/share/wizard/share_wizard.py:886
|
||||
|
@ -439,7 +443,7 @@ msgstr ""
|
|||
msgid ""
|
||||
"The documents have been automatically added to your current OpenERP "
|
||||
"documents.\n"
|
||||
msgstr ""
|
||||
msgstr "一份文档已经被自动增加到你现在的OpenERP文档中了。\n"
|
||||
|
||||
#. module: share
|
||||
#: model:ir.model,name:share.model_share_wizard_result_line
|
||||
|
|
|
@ -314,6 +314,23 @@ class Website(openerp.addons.web.controllers.main.Home):
|
|||
'/website/image/<model>/<id>/<field>'
|
||||
], auth="public", website=True)
|
||||
def website_image(self, model, id, field, max_width=maxint, max_height=maxint):
|
||||
""" Fetches the requested field and ensures it does not go above
|
||||
(max_width, max_height), resizing it if necessary.
|
||||
|
||||
Resizing is bypassed if the object provides a $field_big, which will
|
||||
be interpreted as a pre-resized version of the base field.
|
||||
|
||||
If the record is not found or does not have the requested field,
|
||||
returns a placeholder image via :meth:`~.placeholder`.
|
||||
|
||||
Sets and checks conditional response parameters:
|
||||
* :mailheader:`ETag` is always set (and checked)
|
||||
* :mailheader:`Last-Modified is set iif the record has a concurrency
|
||||
field (``__last_update``)
|
||||
|
||||
The requested field is assumed to be base64-encoded image data in
|
||||
all cases.
|
||||
"""
|
||||
Model = request.registry[model]
|
||||
|
||||
response = werkzeug.wrappers.Response()
|
||||
|
@ -322,15 +339,17 @@ class Website(openerp.addons.web.controllers.main.Home):
|
|||
|
||||
ids = Model.search(request.cr, request.uid,
|
||||
[('id', '=', id)], context=request.context) \
|
||||
or Model.search(request.cr, openerp.SUPERUSER_ID,
|
||||
[('id', '=', id), ('website_published', '=', True)], context=request.context)
|
||||
or Model.search(request.cr, openerp.SUPERUSER_ID,
|
||||
[('id', '=', id), ('website_published', '=', True)], context=request.context)
|
||||
|
||||
if not ids:
|
||||
return self.placeholder(response)
|
||||
|
||||
presized = '%s_big' % field
|
||||
concurrency = '__last_update'
|
||||
[record] = Model.read(request.cr, openerp.SUPERUSER_ID, [id],
|
||||
[concurrency, field], context=request.context)
|
||||
[concurrency, field, presized],
|
||||
context=request.context)
|
||||
|
||||
if concurrency in record:
|
||||
server_format = openerp.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT
|
||||
|
@ -354,25 +373,28 @@ class Website(openerp.addons.web.controllers.main.Home):
|
|||
if response.status_code == 304:
|
||||
return response
|
||||
|
||||
data = record[field].decode('base64')
|
||||
fit = int(max_width), int(max_height)
|
||||
data = (record.get(presized) or record[field]).decode('base64')
|
||||
|
||||
buf = cStringIO.StringIO(data)
|
||||
|
||||
image = Image.open(buf)
|
||||
image.load()
|
||||
image = Image.open(cStringIO.StringIO(data))
|
||||
response.mimetype = Image.MIME[image.format]
|
||||
|
||||
# record provides a pre-resized version of the base field, use that
|
||||
# directly
|
||||
if record.get(presized):
|
||||
response.set_data(data)
|
||||
return response
|
||||
|
||||
fit = int(max_width), int(max_height)
|
||||
w, h = image.size
|
||||
max_w, max_h = fit
|
||||
|
||||
if w < max_w and h < max_h:
|
||||
response.data = data
|
||||
response.set_data(data)
|
||||
else:
|
||||
image.thumbnail(fit, Image.ANTIALIAS)
|
||||
image.save(response.stream, image.format)
|
||||
# invalidate content-length computed by make_conditional as writing
|
||||
# to response.stream does not do it (as of werkzeug 0.9.3)
|
||||
# invalidate content-length computed by make_conditional as
|
||||
# writing to response.stream does not do it (as of werkzeug 0.9.3)
|
||||
del response.headers['Content-Length']
|
||||
|
||||
return response
|
||||
|
|
|
@ -89,7 +89,7 @@ def slug(value):
|
|||
else:
|
||||
# assume name_search result tuple
|
||||
id, name = value
|
||||
slugname = slugify(name)
|
||||
slugname = slugify(name or '')
|
||||
if not slugname:
|
||||
return str(id)
|
||||
return "%s-%d" % (slugname, id)
|
||||
|
@ -580,10 +580,26 @@ class ir_attachment(osv.osv):
|
|||
return hashlib.new('sha1', attachment_dict['datas']).hexdigest()
|
||||
return None
|
||||
|
||||
def _datas_big(self, cr, uid, ids, name, arg, context=None):
|
||||
result = dict.fromkeys(ids, False)
|
||||
if context and context.get('bin_size'):
|
||||
return result
|
||||
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
if not record.datas: continue
|
||||
try:
|
||||
result[record.id] = openerp.tools.image_resize_image_big(record.datas)
|
||||
except IOError: # apparently the error PIL.Image.open raises
|
||||
pass
|
||||
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
'datas_checksum': fields.function(_datas_checksum, size=40,
|
||||
string="Datas checksum", type='char', store=True, select=True),
|
||||
'website_url': fields.function(_website_url_get, string="Attachment URL", type='char')
|
||||
'website_url': fields.function(_website_url_get, string="Attachment URL", type='char'),
|
||||
'datas_big': fields.function (_datas_big, type='binary', store=True,
|
||||
string="Resized file content"),
|
||||
}
|
||||
|
||||
def create(self, cr, uid, values, context=None):
|
||||
|
|
|
@ -102,6 +102,10 @@ header a.navbar-brand img {
|
|||
max-height: 50px;
|
||||
}
|
||||
|
||||
#wrapwrap p:empty:after {
|
||||
content: "\2060";
|
||||
}
|
||||
|
||||
/* ----- Snippets Styles ----- */
|
||||
.readable {
|
||||
font-size: 120%;
|
||||
|
@ -116,7 +120,7 @@ header a.navbar-brand img {
|
|||
}
|
||||
|
||||
/* ----- BOOTSTRAP FIX ----- */
|
||||
.container .container {
|
||||
.container .container, .readable .container {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
width: auto;
|
||||
|
@ -217,7 +221,6 @@ footer {
|
|||
/* -- Hack for removing double scrollbar from mobile preview -- */
|
||||
div#mobile-preview.modal {
|
||||
overflow: hidden;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
ul.nav-stacked > li > a {
|
||||
|
@ -284,6 +287,7 @@ ul.nav-stacked > li > a {
|
|||
section, .carousel, .parallax, .row, .hr, .blockquote {
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
.carousel, .parallax, .blockquote {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,12 @@ header
|
|||
img
|
||||
max-height: 50px
|
||||
|
||||
// add {WORD JOINER} (equivalent to deprecated ZERO WIDTH NO-BREAK SPACE) at
|
||||
// the beginning of paragraphs so they don't "disappear" after saving when
|
||||
// used solely for spacing.
|
||||
#wrapwrap p:empty:after
|
||||
content: '\2060'
|
||||
|
||||
/* ----- Snippets Styles ----- */
|
||||
|
||||
.readable
|
||||
|
@ -78,14 +84,12 @@ header
|
|||
|
||||
/* ----- EDITOR ----- */
|
||||
|
||||
|
||||
.css_non_editable_mode_hidden
|
||||
display: none
|
||||
|
||||
|
||||
/* ----- BOOTSTRAP FIX ----- */
|
||||
|
||||
.container
|
||||
.container, .readable
|
||||
.container
|
||||
padding-left: 0
|
||||
padding-right: 0
|
||||
|
@ -180,7 +184,6 @@ footer
|
|||
/* -- Hack for removing double scrollbar from mobile preview -- */
|
||||
div#mobile-preview.modal
|
||||
overflow: hidden
|
||||
overflow-y: hidden
|
||||
|
||||
ul.nav-stacked > li > a
|
||||
padding: 2px 15px
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
"use strict";
|
||||
|
||||
var website = {};
|
||||
// The following line can be removed in 2017
|
||||
openerp.website = website;
|
||||
|
||||
/* ----------------------------------------------------
|
||||
Helpers
|
||||
---------------------------------------------------- */
|
||||
website.get_context = function (dict) {
|
||||
var html = document.documentElement;
|
||||
return _.extend({
|
||||
|
@ -34,26 +36,11 @@
|
|||
}
|
||||
return parsedSearch;
|
||||
};
|
||||
|
||||
website.parseHash = function () {
|
||||
return website.parseQS(window.location.hash.substring(1));
|
||||
};
|
||||
|
||||
/* ----- TEMPLATE LOADING ---- */
|
||||
var templates_def = $.Deferred().resolve();
|
||||
website.add_template_file = function(template) {
|
||||
templates_def = templates_def.then(function() {
|
||||
var def = $.Deferred();
|
||||
openerp.qweb.add_template(template, function(err) {
|
||||
if (err) {
|
||||
def.reject(err);
|
||||
} else {
|
||||
def.resolve();
|
||||
}
|
||||
});
|
||||
return def;
|
||||
});
|
||||
};
|
||||
website.add_template_file('/website/static/src/xml/website.xml');
|
||||
website.reload = function () {
|
||||
location.hash = "scrollTop=" + window.document.body.scrollTop;
|
||||
if (location.search.indexOf("enable_editor") > -1) {
|
||||
|
@ -63,102 +50,9 @@
|
|||
}
|
||||
};
|
||||
|
||||
var all_ready = null;
|
||||
var dom_ready = website.dom_ready = $.Deferred();
|
||||
$(document).ready(function () {
|
||||
website.is_editable = website.is_editable || $('html').data('editable');
|
||||
website.is_editable_button= website.is_editable_button || $('html').data('editable');
|
||||
dom_ready.resolve();
|
||||
// fix for ie
|
||||
if($.fn.placeholder) $('input, textarea').placeholder();
|
||||
});
|
||||
|
||||
website.init_kanban = function ($kanban) {
|
||||
$('.js_kanban_col', $kanban).each(function () {
|
||||
var $col = $(this);
|
||||
var $pagination = $('.pagination', $col);
|
||||
if(!$pagination.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var page_count = $col.data('page_count');
|
||||
var scope = $pagination.last().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'),
|
||||
'template': $col.data('template'),
|
||||
'step': $col.data('step'),
|
||||
'orderby': $col.data('orderby')
|
||||
};
|
||||
|
||||
$pagination.on('click', 'a', function (ev) {
|
||||
ev.preventDefault();
|
||||
var $a = $(ev.target);
|
||||
if($a.parent().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.last().before(col);
|
||||
});
|
||||
|
||||
var page_start = page - parseInt(Math.floor((scope-1)/2), 10);
|
||||
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 < page_end ? page+1 : page_end));
|
||||
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');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a deferred resolved when the templates are loaded
|
||||
* and the Widgets can be instanciated.
|
||||
*/
|
||||
website.ready = function() {
|
||||
if (!all_ready) {
|
||||
all_ready = dom_ready.then(function () {
|
||||
return templates_def;
|
||||
}).then(function () {
|
||||
if (website.is_editable) {
|
||||
website.id = $('html').data('website-id');
|
||||
website.session = new openerp.Session();
|
||||
var modules = ['website'];
|
||||
return openerp._t.database.load_translations(website.session, modules, website.get_context().lang);
|
||||
}
|
||||
}).promise();
|
||||
}
|
||||
return all_ready;
|
||||
};
|
||||
|
||||
website.error = function(data, url) {
|
||||
var $error = $(openerp.qweb.render('website.error_dialog', {
|
||||
'title': data.data ? data.data.arguments[0] : "",
|
||||
'message': data.data ? data.data.arguments[1] : data.statusText,
|
||||
'backend_url': url
|
||||
}));
|
||||
$error.appendTo("body");
|
||||
$error.modal('show');
|
||||
};
|
||||
/* ----------------------------------------------------
|
||||
Widgets
|
||||
---------------------------------------------------- */
|
||||
|
||||
website.prompt = function (options) {
|
||||
/**
|
||||
|
@ -250,6 +144,16 @@
|
|||
return def;
|
||||
};
|
||||
|
||||
website.error = function(data, url) {
|
||||
var $error = $(openerp.qweb.render('website.error_dialog', {
|
||||
'title': data.data ? data.data.arguments[0] : "",
|
||||
'message': data.data ? data.data.arguments[1] : data.statusText,
|
||||
'backend_url': url
|
||||
}));
|
||||
$error.appendTo("body");
|
||||
$error.modal('show');
|
||||
};
|
||||
|
||||
website.form = function (url, method, params) {
|
||||
var form = document.createElement('form');
|
||||
form.setAttribute('action', url);
|
||||
|
@ -265,11 +169,117 @@
|
|||
form.submit();
|
||||
};
|
||||
|
||||
dom_ready.then(function () {
|
||||
website.init_kanban = function ($kanban) {
|
||||
$('.js_kanban_col', $kanban).each(function () {
|
||||
var $col = $(this);
|
||||
var $pagination = $('.pagination', $col);
|
||||
if(!$pagination.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* ----- BOOTSTRAP STUFF ---- */
|
||||
// $('.js_tooltip').bstooltip();
|
||||
var page_count = $col.data('page_count');
|
||||
var scope = $pagination.last().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'),
|
||||
'template': $col.data('template'),
|
||||
'step': $col.data('step'),
|
||||
'orderby': $col.data('orderby')
|
||||
};
|
||||
|
||||
$pagination.on('click', 'a', function (ev) {
|
||||
ev.preventDefault();
|
||||
var $a = $(ev.target);
|
||||
if($a.parent().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.last().before(col);
|
||||
});
|
||||
|
||||
var page_start = page - parseInt(Math.floor((scope-1)/2), 10);
|
||||
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 < page_end ? page+1 : page_end));
|
||||
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');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------
|
||||
Async Ready and Template loading
|
||||
---------------------------------------------------- */
|
||||
var templates_def = $.Deferred().resolve();
|
||||
website.add_template_file = function(template) {
|
||||
templates_def = templates_def.then(function() {
|
||||
var def = $.Deferred();
|
||||
openerp.qweb.add_template(template, function(err) {
|
||||
if (err) {
|
||||
def.reject(err);
|
||||
} else {
|
||||
def.resolve();
|
||||
}
|
||||
});
|
||||
return def;
|
||||
});
|
||||
};
|
||||
website.add_template_file('/website/static/src/xml/website.xml');
|
||||
|
||||
website.dom_ready = $.Deferred();
|
||||
$(document).ready(function () {
|
||||
website.is_editable = website.is_editable || $('html').data('editable');
|
||||
website.is_editable_button= website.is_editable_button || $('html').data('editable');
|
||||
website.dom_ready.resolve();
|
||||
// fix for ie
|
||||
if($.fn.placeholder) $('input, textarea').placeholder();
|
||||
});
|
||||
|
||||
var all_ready = null;
|
||||
/**
|
||||
* Returns a deferred resolved when the templates are loaded
|
||||
* and the Widgets can be instanciated.
|
||||
*/
|
||||
website.ready = function() {
|
||||
if (!all_ready) {
|
||||
all_ready = website.dom_ready.then(function () {
|
||||
return templates_def;
|
||||
}).then(function () {
|
||||
if (website.is_editable) {
|
||||
website.id = $('html').data('website-id');
|
||||
website.session = new openerp.Session();
|
||||
var modules = ['website'];
|
||||
return openerp._t.database.load_translations(website.session, modules, website.get_context().lang);
|
||||
}
|
||||
}).promise();
|
||||
}
|
||||
return all_ready;
|
||||
};
|
||||
|
||||
website.inject_tour = function() {
|
||||
// if a tour is active inject tour js
|
||||
}
|
||||
|
||||
website.dom_ready.then(function () {
|
||||
/* ----- PUBLISHING STUFF ---- */
|
||||
$(document).on('click', '.js_publish_management .js_publish_btn', function () {
|
||||
var $data = $(this).parents(".js_publish_management:first");
|
||||
|
|
|
@ -419,7 +419,7 @@
|
|||
$target.data("overlay").remove();
|
||||
$target.removeData("overlay");
|
||||
}
|
||||
$target.find("[data-snippet-id]").each(function () {
|
||||
$target.find(website.snippet.globalSelector).each(function () {
|
||||
var $snippet = $(this);
|
||||
$snippet.removeData("snippet-editor");
|
||||
if ($snippet.data("overlay")) {
|
||||
|
@ -623,7 +623,7 @@
|
|||
this.required = this.$el.data("required");
|
||||
|
||||
this.set_active();
|
||||
this.$el.find('li[data-class] a').on('mouseover mouseout click', _.bind(this._mouse, this));
|
||||
this.$el.find('li[data-value] a').on('mouseover mouseout click', _.bind(this._mouse, this));
|
||||
this.$target.on('snippet-style-reset', _.bind(this.set_active, this));
|
||||
|
||||
this.start();
|
||||
|
@ -643,9 +643,9 @@
|
|||
var $prev, $next;
|
||||
if (event.type === 'mouseout') {
|
||||
$prev = $(event.currentTarget).parent();
|
||||
$next = this.$el.find("li[data-class].active");
|
||||
$next = this.$el.find("li[data-value].active");
|
||||
} else {
|
||||
$prev = this.$el.find("li[data-class].active");
|
||||
$prev = this.$el.find("li[data-value].active");
|
||||
$next = $(event.currentTarget).parent();
|
||||
}
|
||||
if (!$prev.length) {
|
||||
|
@ -676,6 +676,30 @@
|
|||
// start is call just after the init
|
||||
start: function () {
|
||||
},
|
||||
/* onFocus
|
||||
* This method is called when the user click inside the snippet in the dom
|
||||
*/
|
||||
onFocus : function () {
|
||||
},
|
||||
|
||||
/* onFocus
|
||||
* This method is called when the user click outside the snippet in the dom, after a focus
|
||||
*/
|
||||
onBlur : function () {
|
||||
},
|
||||
|
||||
/* on_clone
|
||||
* This method is called when the snippet is cloned ($clone is allready inserted)
|
||||
*/
|
||||
on_clone: function ($clone) {
|
||||
},
|
||||
|
||||
/* on_remove
|
||||
* This method is called when the snippet is removed (dom is removing after this call)
|
||||
*/
|
||||
on_remove: function () {
|
||||
},
|
||||
|
||||
/*
|
||||
* drop_and_build_snippet
|
||||
* This method is called just after that a thumbnail is drag and dropped into a drop zone
|
||||
|
@ -685,6 +709,7 @@
|
|||
},
|
||||
/* select
|
||||
* called when a user select an item
|
||||
* li must have data-value attribute
|
||||
* variables: np = {$next, $prev}
|
||||
* $next is false if they are no next item selected
|
||||
* $prev is false if they are no previous item selected
|
||||
|
@ -693,10 +718,10 @@
|
|||
var self = this;
|
||||
// add or remove html class
|
||||
if (np.$prev) {
|
||||
this.$target.removeClass(np.$prev.data('class' || ""));
|
||||
this.$target.removeClass(np.$prev.data('value' || ""));
|
||||
}
|
||||
if (np.$next) {
|
||||
this.$target.addClass(np.$next.data('class') || "");
|
||||
this.$target.addClass(np.$next.data('value') || "");
|
||||
}
|
||||
},
|
||||
/* preview
|
||||
|
@ -710,10 +735,10 @@
|
|||
|
||||
// add or remove html class
|
||||
if (np.$prev) {
|
||||
this.$target.removeClass(np.$prev.data('class') || "");
|
||||
this.$target.removeClass(np.$prev.data('value') || "");
|
||||
}
|
||||
if (np.$next) {
|
||||
this.$target.addClass(np.$next.data('class') || "");
|
||||
this.$target.addClass(np.$next.data('value') || "");
|
||||
}
|
||||
},
|
||||
/* set_active
|
||||
|
@ -723,14 +748,14 @@
|
|||
set_active: function () {
|
||||
var self = this;
|
||||
this.$el.find('li').removeClass("active");
|
||||
var $active = this.$el.find('li[data-class]')
|
||||
var $active = this.$el.find('li[data-value]')
|
||||
.filter(function () {
|
||||
var $li = $(this);
|
||||
return ($li.data('class') && self.$target.hasClass($li.data('class')));
|
||||
return ($li.data('value') && self.$target.hasClass($li.data('value')));
|
||||
})
|
||||
.first()
|
||||
.addClass("active");
|
||||
this.$el.find('li:has(li[data-class].active)').addClass("active");
|
||||
this.$el.find('li:has(li[data-value].active)').addClass("active");
|
||||
},
|
||||
/* clean_for_save
|
||||
* function called just before save vue
|
||||
|
@ -749,7 +774,7 @@
|
|||
start: function () {
|
||||
this._super();
|
||||
var src = this._get_bg();
|
||||
this.$el.find("li[data-class].active.oe_custom_bg").data("src", src);
|
||||
this.$el.find("li[data-value].active.oe_custom_bg").data("src", src);
|
||||
},
|
||||
select: function(event, np) {
|
||||
var self = this;
|
||||
|
@ -765,7 +790,7 @@
|
|||
});
|
||||
editor.on('cancel', self, function () {
|
||||
if (!np.$prev || np.$prev.data("src") === "") {
|
||||
self.$target.removeClass(np.$next.data("class"));
|
||||
self.$target.removeClass(np.$next.data("value"));
|
||||
self.$target.trigger("snippet-style-change", [self, np]);
|
||||
}
|
||||
});
|
||||
|
@ -775,7 +800,7 @@
|
|||
}
|
||||
} else {
|
||||
this._set_bg(false);
|
||||
this.$target.removeClass(np.$prev.data("class"));
|
||||
this.$target.removeClass(np.$prev.data("value"));
|
||||
}
|
||||
},
|
||||
preview: function (event, np) {
|
||||
|
@ -788,41 +813,54 @@
|
|||
var self = this;
|
||||
var bg = self.$target.css("background-image");
|
||||
this.$el.find('li').removeClass("active");
|
||||
var $active = this.$el.find('li[data-class]')
|
||||
var $active = this.$el.find('li[data-value]')
|
||||
.filter(function () {
|
||||
var $li = $(this);
|
||||
return ($li.data('src') && bg.indexOf($li.data('src')) >= 0) ||
|
||||
(!$li.data('src') && self.$target.hasClass($li.data('class')));
|
||||
(!$li.data('src') && self.$target.hasClass($li.data('value')));
|
||||
})
|
||||
.first();
|
||||
if (!$active.length) {
|
||||
$active = this.$target.css("background-image") !== 'none' ?
|
||||
this.$el.find('li[data-class].oe_custom_bg') :
|
||||
this.$el.find('li[data-class=""]');
|
||||
this.$el.find('li[data-value].oe_custom_bg') :
|
||||
this.$el.find('li[data-value=""]');
|
||||
}
|
||||
$active.addClass("active");
|
||||
this.$el.find('li:has(li[data-class].active)').addClass("active");
|
||||
this.$el.find('li:has(li[data-value].active)').addClass("active");
|
||||
}
|
||||
});
|
||||
|
||||
website.snippet.options.slider = website.snippet.Option.extend({
|
||||
unique_id: function () {
|
||||
var id = 0;
|
||||
$(".carousel").each(function () {
|
||||
var cid = 1 + parseInt($(this).attr("id").replace(/[^0123456789]/g, ''),10);
|
||||
if (id < cid) id = cid;
|
||||
});
|
||||
return "myCarousel" + id;
|
||||
},
|
||||
drop_and_build_snippet: function() {
|
||||
var id = $(".carousel").length;
|
||||
this.id = "myCarousel" + id;
|
||||
this.id = this.unique_id();
|
||||
this.$target.attr("id", this.id);
|
||||
this.$target.find(".carousel-control").attr("href", "#myCarousel" + id);
|
||||
this.$target.find("[data-target]").attr("data-target", "#myCarousel" + id);
|
||||
this.$target.find("[data-slide]").attr("href", "#" + this.id);
|
||||
this.$target.find("[data-slide-to]").attr("data-target", "#" + this.id);
|
||||
|
||||
this.rebind_event();
|
||||
},
|
||||
on_clone: function ($clone) {
|
||||
var id = this.unique_id();
|
||||
$clone.attr("id", id);
|
||||
$clone.find("[data-slide]").attr("href", "#" + id);
|
||||
$clone.find("[data-slide-to]").attr("data-target", "#" + id);
|
||||
},
|
||||
// rebind event to active carousel on edit mode
|
||||
rebind_event: function () {
|
||||
var self = this;
|
||||
this.$target.find('.carousel-indicators [data-target]').off('click').on('click', function () {
|
||||
this.$target.find('.carousel-indicators [data-slide-to]').off('click').on('click', function () {
|
||||
self.$target.carousel(+$(this).data('slide-to')); });
|
||||
|
||||
this.$target.attr('contentEditable', 'false');
|
||||
this.$target.find('.oe_structure, .content>.row').attr('contentEditable', 'true');
|
||||
this.$target.find('.oe_structure, .content>.row, [data-slide]').attr('contentEditable', 'true');
|
||||
},
|
||||
clean_for_save: function () {
|
||||
this._super();
|
||||
|
@ -905,7 +943,7 @@
|
|||
},
|
||||
load_style_options : function () {
|
||||
this._super();
|
||||
$(".snippet-style-size li[data-class='']").remove();
|
||||
$(".snippet-style-size li[data-value='']").remove();
|
||||
},
|
||||
start : function () {
|
||||
var self = this;
|
||||
|
@ -923,11 +961,11 @@
|
|||
$active.css("background-image", self.$target.css("background-image"));
|
||||
}
|
||||
if (np.$prev) {
|
||||
$active.removeClass(np.$prev.data("class"));
|
||||
$active.removeClass(np.$prev.data("value"));
|
||||
}
|
||||
if (np.$next) {
|
||||
$active.addClass(np.$next.data("class"));
|
||||
add_class(np.$next.data("class"));
|
||||
$active.addClass(np.$next.data("value"));
|
||||
add_class(np.$next.data("value"));
|
||||
}
|
||||
});
|
||||
this.$target.on('slid', function () { // slide.bs.carousel
|
||||
|
@ -949,11 +987,13 @@
|
|||
var bg = this.$target.data("snippet-option-ids").background;
|
||||
if (!bg) return $clone;
|
||||
|
||||
var $styles = bg.$el.find("li[data-class]:not(.oe_custom_bg)");
|
||||
var $styles = bg.$el.find("li[data-value]:not(.oe_custom_bg)");
|
||||
var styles_index = $styles.index($styles.filter(".active")[0]);
|
||||
$styles.removeClass("active");
|
||||
var $select = $($styles[styles_index >= $styles.length-1 ? 0 : styles_index+1]);
|
||||
$select.addClass("active");
|
||||
$clone.css("background-image", $select.data("src") ? "url('"+ $select.data("src") +"')" : "");
|
||||
$clone.addClass($select.data("class") || "");
|
||||
$clone.addClass($select.data("value") || "");
|
||||
|
||||
return $clone;
|
||||
},
|
||||
|
@ -1187,25 +1227,22 @@
|
|||
this._super();
|
||||
},
|
||||
hide_remove_button: function() {
|
||||
this.$overlay.find('.oe_snippet_remove').toggleClass("hidden",
|
||||
!this.$target.siblings().length && this.$target.parents("[data-snippet-id]:first").find("[data-snippet-id='colmd']").length > 1);
|
||||
this.$overlay.find('.oe_snippet_remove').toggleClass("hidden", !this.$target.siblings().length);
|
||||
},
|
||||
onFocus : function () {
|
||||
this._super();
|
||||
this.hide_remove_button();
|
||||
},
|
||||
on_clone: function () {
|
||||
var $clone = this.$target.clone(false);
|
||||
on_clone: function ($clone) {
|
||||
var _class = $clone.attr("class").replace(/\s*(col-lg-offset-|col-md-offset-)([0-9-]+)/g, '');
|
||||
$clone.attr("class", _class);
|
||||
this.$target.after($clone);
|
||||
this.hide_remove_button();
|
||||
return false;
|
||||
},
|
||||
on_remove: function () {
|
||||
if (!this.$target.siblings().length) {
|
||||
var $parent = this.$target.parents("[data-snippet-id]:first");
|
||||
if($parent.find("[data-snippet-id='colmd']").length > 1) {
|
||||
var $parent = this.$target.parents(".row:first");
|
||||
if($parent.find("[class*='col-md']").length > 1) {
|
||||
return false;
|
||||
} else {
|
||||
if (!$parent.data("snippet-editor")) {
|
||||
|
@ -1455,7 +1492,7 @@
|
|||
get_parent_block: function () {
|
||||
var self = this;
|
||||
var $button = this.$overlay.find('.oe_snippet_parent');
|
||||
var $parent = this.$target.parents("[data-snippet-id]:first");
|
||||
var $parent = this.$target.parents(website.snippet.globalSelector).first();
|
||||
if ($parent.length) {
|
||||
$button.removeClass("hidden");
|
||||
$button.off("click").on('click', function (event) {
|
||||
|
@ -1483,12 +1520,18 @@
|
|||
on_clone: function () {
|
||||
var $clone = this.$target.clone(false);
|
||||
this.$target.after($clone);
|
||||
for (var i in this.styles){
|
||||
this.styles[i].on_clone($clone);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
on_remove: function () {
|
||||
this.onBlur();
|
||||
var index = _.indexOf(this.BuildingBlock.snippets, this.$target.get(0));
|
||||
for (var i in this.styles){
|
||||
this.styles[i].on_remove();
|
||||
}
|
||||
delete this.BuildingBlock.snippets[index];
|
||||
this.$target.remove();
|
||||
this.$overlay.remove();
|
||||
|
@ -1511,12 +1554,18 @@
|
|||
*/
|
||||
onFocus : function () {
|
||||
this.$overlay.addClass('oe_active');
|
||||
for (var i in this.styles){
|
||||
this.styles[i].onFocus();
|
||||
}
|
||||
},
|
||||
|
||||
/* onFocus
|
||||
* This method is called when the user click outside the snippet in the dom, after a focus
|
||||
*/
|
||||
onBlur : function () {
|
||||
for (var i in this.styles){
|
||||
this.styles[i].onBlur();
|
||||
}
|
||||
this.$overlay.removeClass('oe_active');
|
||||
},
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
element: 'button[data-action=snippet]',
|
||||
placement: 'bottom',
|
||||
title: _t("Insert building blocks"),
|
||||
content: _t("To add content in a page, you can insert building blocks."),
|
||||
content: _t("Click here to insert blocks of centent in the page."),
|
||||
popover: { fixed: true },
|
||||
},
|
||||
{
|
||||
|
@ -101,13 +101,13 @@
|
|||
element: '.modal:has(#mobile-viewport) button[data-dismiss=modal]',
|
||||
placement: 'right',
|
||||
title: _t("Check Mobile Preview"),
|
||||
content: _t("Scroll in the mobile preview to test the rendering. Once it's ok, close this dialog."),
|
||||
content: _t("Scroll to check rendering and then close the mobile preview."),
|
||||
popover: { next: _t("Continue") },
|
||||
},
|
||||
{
|
||||
waitNot: '.modal',
|
||||
element: '#content-menu-button',
|
||||
placement: 'bottom',
|
||||
placement: 'left',
|
||||
title: _t("Add new pages and menus"),
|
||||
content: _t("The 'Content' menu allows you to add pages or add the top menu."),
|
||||
popover: { next: _t("Close Tutorial") },
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
var website = openerp.website;
|
||||
|
||||
website.Tour.LoginEdit = website.Tour.extend({
|
||||
id: 'login_edit',
|
||||
name: "Try to log as admin and check editor",
|
||||
path: '/',
|
||||
init: function () {
|
||||
var self = this;
|
||||
self.steps = [
|
||||
{
|
||||
title: "click login",
|
||||
element: '#top_menu a[href*="/web/login"]',
|
||||
},
|
||||
{
|
||||
title: "insert login",
|
||||
element: '.oe_login_form input[name="login"]',
|
||||
sampleText: "admin",
|
||||
},
|
||||
{
|
||||
title: "insert password",
|
||||
waitFor: '.oe_login_form input[name="login"][value!=""]',
|
||||
element: '.oe_login_form input[name="password"]',
|
||||
sampleText: "admin",
|
||||
},
|
||||
{
|
||||
title: "select 2 Standard tickets",
|
||||
waitFor: '.oe_login_form input[name="password"][value!=""]',
|
||||
element: '.oe_login_form button',
|
||||
},
|
||||
{
|
||||
title: "go back to website from backend",
|
||||
element: 'a[data-action-model="ir.actions.act_url"]:contains("Website")',
|
||||
},
|
||||
{
|
||||
title: 'try to edit',
|
||||
waitNot: '#wrap .carousel',
|
||||
element: 'button[data-action=edit]:visible',
|
||||
},
|
||||
{
|
||||
title: 'check edit mode',
|
||||
waitFor: 'button[data-action=save]:visible',
|
||||
},
|
||||
{
|
||||
title: 'check branding',
|
||||
waitFor: '#wrap[data-oe-model="ir.ui.view"]',
|
||||
},
|
||||
{
|
||||
title: 'check rte',
|
||||
waitFor: '#oe_rte_toolbar',
|
||||
},
|
||||
{
|
||||
title: 'check insert block button',
|
||||
element: '[data-action="snippet"]:visible',
|
||||
},
|
||||
{
|
||||
title: 'add snippets',
|
||||
snippet: '#snippet_structure .oe_snippet:first',
|
||||
},
|
||||
{
|
||||
title: 'try to save',
|
||||
waitFor: '.oe_overlay_options .oe_options:visible',
|
||||
element: 'button[data-action=save]:visible',
|
||||
},
|
||||
{
|
||||
title: 'check saved',
|
||||
waitFor: '#wrap div.carousel',
|
||||
element: 'button[data-action=edit]:visible',
|
||||
},
|
||||
{
|
||||
title: 'try to re-edit',
|
||||
waitFor: 'button[data-action=save]:visible',
|
||||
element: '#wrap .carousel',
|
||||
},
|
||||
{
|
||||
title: 'remove snippet',
|
||||
element: '.oe_snippet_remove',
|
||||
},
|
||||
{
|
||||
title: 'try to re-save',
|
||||
waitNot: '#wrap .carousel',
|
||||
element: 'button[data-action=save]:visible',
|
||||
},
|
||||
{
|
||||
title: "click admin",
|
||||
waitFor: 'button[data-action=edit]:visible',
|
||||
element: 'a:contains("Administrator")',
|
||||
},
|
||||
{
|
||||
title: "click logout",
|
||||
element: '#top_menu a[href*="/logout"]',
|
||||
},
|
||||
{
|
||||
title: "check logout",
|
||||
waitFor: '#top_menu a[href*="/web/login"]',
|
||||
},
|
||||
];
|
||||
return this._super();
|
||||
},
|
||||
});
|
||||
// for test without editor bar
|
||||
website.Tour.add(website.Tour.LoginEdit);
|
||||
|
||||
}());
|
|
@ -1,34 +0,0 @@
|
|||
(function () {
|
||||
|
||||
function LoadScript(src) {
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = function() {
|
||||
if(xmlHttp.readyState == 4) {
|
||||
if (xmlHttp.status == 200 || xmlHttp.status == 304) {
|
||||
new Function(xmlHttp.responseText)();
|
||||
} else {
|
||||
throw new Error("Can't load JavaScript.\nhref: " + window.location.href + "\nsrc: " + src);
|
||||
}
|
||||
}
|
||||
};
|
||||
xmlHttp.open("GET", src, false);
|
||||
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
xmlHttp.send(null);
|
||||
}
|
||||
|
||||
if (typeof jQuery === "undefined")
|
||||
LoadScript("/web/static/lib/jquery/jquery.js");
|
||||
if (typeof _ === "undefined")
|
||||
LoadScript("/web/static/lib/underscore/underscore.js");
|
||||
if (typeof openerp === "undefined") {
|
||||
LoadScript("/web/static/lib/qweb/qweb2.js");
|
||||
LoadScript("/web/static/src/js/openerpframework.js");
|
||||
}
|
||||
if (typeof openerp === "undefined" || !openerp.website || !openerp.website.add_template_file)
|
||||
LoadScript("/website/static/src/js/website.js");
|
||||
if (typeof Tour === "undefined")
|
||||
LoadScript("/website/static/lib/bootstrap-tour/bootstrap-tour.js");
|
||||
if (typeof openerp === "undefined" || !openerp.website.Tour)
|
||||
LoadScript("/website/static/src/js/website.tour.js");
|
||||
|
||||
})();
|
|
@ -135,7 +135,7 @@ class TestConvertBack(common.TransactionCase):
|
|||
rendered = self.registry('website.qweb').render_tag_field(
|
||||
e, {'field': field_value}, '', ir_qweb.QWebContext(self.cr, self.uid, {
|
||||
'record': record,
|
||||
}))
|
||||
}, context={'inherit_branding': True}))
|
||||
element = html.fromstring(
|
||||
rendered, parser=html.HTMLParser(encoding='utf-8'))
|
||||
|
||||
|
@ -216,7 +216,7 @@ class TestConvertBack(common.TransactionCase):
|
|||
rendered = self.registry('website.qweb').render_tag_field(
|
||||
e, {'field': field_value}, '', ir_qweb.QWebContext(self.cr, self.uid, {
|
||||
'record': record,
|
||||
}))
|
||||
}, context={'inherit_branding': True}))
|
||||
|
||||
element = html.fromstring(rendered, parser=html.HTMLParser(encoding='utf-8'))
|
||||
# emulate edition
|
||||
|
|
|
@ -121,6 +121,6 @@ class URL(object):
|
|||
|
||||
def load_tests(loader, base, _):
|
||||
base.addTest(CrawlSuite())
|
||||
base.addTest(CrawlSuite('admin', tools.config['admin_passwd']))
|
||||
base.addTest(CrawlSuite('admin', 'admin'))
|
||||
base.addTest(CrawlSuite('demo', 'demo'))
|
||||
return base
|
||||
|
|
|
@ -8,6 +8,6 @@ class TestUi(openerp.tests.HttpCase):
|
|||
self.phantom_js("/", "console.log('ok')", "openerp.website.editor", login='admin')
|
||||
|
||||
def test_04_admin_tour_banner(self):
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('banner')", "openerp.website.Tour", login='admin')
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('banner')", "openerp.website.Tour.tours.banner", login='admin')
|
||||
|
||||
# vim:et:
|
||||
|
|
|
@ -860,7 +860,7 @@
|
|||
<li class="dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Style</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-class="readable"><a>Narrow</a></li>
|
||||
<li data-value="readable"><a>Narrow</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</div>
|
||||
|
@ -873,51 +873,51 @@
|
|||
<li class="dropdown-submenu">
|
||||
<a tabindex="-2" href="#">Uniform Color</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-class='oe_dark'><a>Darken</a></li>
|
||||
<li data-class='oe_green'><a>Green</a></li>
|
||||
<li data-class='oe_red'><a>Red</a></li>
|
||||
<li data-class='oe_blue_light'><a>Turquoise</a></li>
|
||||
<li data-class='oe_blue'><a>Dark Blue</a></li>
|
||||
<li data-class='oe_orange'><a>Orange</a></li>
|
||||
<li data-class='oe_purple'><a>Purple</a></li>
|
||||
<li data-class='oe_black'><a>Black</a></li>
|
||||
<li data-value='oe_dark'><a>Darken</a></li>
|
||||
<li data-value='oe_green'><a>Green</a></li>
|
||||
<li data-value='oe_red'><a>Red</a></li>
|
||||
<li data-value='oe_blue_light'><a>Turquoise</a></li>
|
||||
<li data-value='oe_blue'><a>Dark Blue</a></li>
|
||||
<li data-value='oe_orange'><a>Orange</a></li>
|
||||
<li data-value='oe_purple'><a>Purple</a></li>
|
||||
<li data-value='oe_black'><a>Black</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown-submenu">
|
||||
<a tabindex="-2" href="#">People</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/parallax/parallax_bg.jpg"><a>Sunflower</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/business_guy.jpg"><a>Business Guy</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/parallax/parallax_bg.jpg"><a>Sunflower</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/business_guy.jpg"><a>Business Guy</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown-submenu">
|
||||
<a tabindex="-2" href="#">Landscape</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/flower_field.jpg"><a>Flowers Field</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/landscape.jpg"><a>Landscape</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/mountains.jpg"><a>Mountains</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/greenfields.jpg"><a>Greenfields</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/flower_field.jpg"><a>Flowers Field</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/landscape.jpg"><a>Landscape</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/mountains.jpg"><a>Mountains</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/greenfields.jpg"><a>Greenfields</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown-submenu">
|
||||
<a tabindex="-2" href="#">Various</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/aqua.jpg"><a>Aqua</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/baby_blue.jpg"><a>Baby Blue</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/black.jpg"><a>Black</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/color_splash.jpg"><a>Color Splash</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/mango.jpg"><a>Mango</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/orange_red.jpg"><a>Orange Red</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/flower.jpg"><a>Purple</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/velour.jpg"><a>Velour</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/wood.jpg"><a>Wood</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/banner/yellow_green.jpg"><a>Yellow Green</a></li>
|
||||
<li data-class="oe_img_bg" data-src="/website/static/src/img/parallax/quote.png"><a>Quote</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/aqua.jpg"><a>Aqua</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/baby_blue.jpg"><a>Baby Blue</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/black.jpg"><a>Black</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/color_splash.jpg"><a>Color Splash</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/mango.jpg"><a>Mango</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/orange_red.jpg"><a>Orange Red</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/flower.jpg"><a>Purple</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/velour.jpg"><a>Velour</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/wood.jpg"><a>Wood</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/banner/yellow_green.jpg"><a>Yellow Green</a></li>
|
||||
<li data-value="oe_img_bg" data-src="/website/static/src/img/parallax/quote.png"><a>Quote</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li data-class=""><a>None</a></li>
|
||||
<li data-value=""><a>None</a></li>
|
||||
<li><a style="background: none; padding: 5px; border-top: 1px solid #ddd;"></a></li>
|
||||
<li class="oe_custom_bg" data-class="oe_img_bg"><a><b>Choose an image...</b></a></li>
|
||||
<li class="oe_custom_bg" data-value="oe_img_bg"><a><b>Choose an image...</b></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</div>
|
||||
|
@ -927,9 +927,9 @@
|
|||
<li class="dropdown-submenu" data-required="true">
|
||||
<a tabindex="-1" href="#">Layout</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li data-class="text_only"><a>Text Only</a></li>
|
||||
<li data-class="image_text"><a>Image - Text</a></li>
|
||||
<li data-class="text_image"><a>Text - Image</a></li>
|
||||
<li data-value="text_only"><a>Text Only</a></li>
|
||||
<li data-value="image_text"><a>Image - Text</a></li>
|
||||
<li data-value="text_image"><a>Text - Image</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</div>
|
||||
|
|
|
@ -509,10 +509,10 @@
|
|||
class="js_follow_email form-control"
|
||||
placeholder="your email..."/>
|
||||
<span class="input-group-btn">
|
||||
<a href="#" class="btn btn-default js_unfollow_btn">Unsubscribe</a>
|
||||
<a href="#" class="btn btn-primary js_follow_btn">Subscribe</a>
|
||||
<a href="#" class="btn btn-default js_unfollow_btn">unsubscribe</a>
|
||||
<a href="#" class="btn btn-primary js_follow_btn">subscribe</a>
|
||||
</span>
|
||||
<div class="alert alert-success hidden">Thanks for your subscription!</div>
|
||||
<div class="alert alert-success hidden">thanks for your subscription!</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
import controllers
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
'name': 'Mailing List Archive',
|
||||
'category': 'Website',
|
||||
'summary': '',
|
||||
'version': '1.0',
|
||||
'description': """
|
||||
OpenERP Mail Group : Mailing List Archives
|
||||
==========================================
|
||||
|
||||
""",
|
||||
'author': 'OpenERP SA',
|
||||
'depends': ['website_mail'],
|
||||
'data': [
|
||||
'views/website_mail_group.xml'
|
||||
],
|
||||
'qweb': [],
|
||||
'installable': True,
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
import main
|
||||
|
||||
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -0,0 +1,91 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2013-Today OpenERP SA (<http://www.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
|
||||
# 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.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
|
||||
|
||||
class MailGroup(http.Controller):
|
||||
_thread_per_page = 10
|
||||
|
||||
@http.route([
|
||||
"/groups",
|
||||
], type='http', auth="public", website=True)
|
||||
def view(self, **post):
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
group_obj = request.registry.get('mail.group')
|
||||
group_ids = group_obj.search(cr, uid, [], context=context)
|
||||
values = {'groups': group_obj.browse(cr, uid, group_ids, context)}
|
||||
return request.website.render('website_mail_group.mail_groups', values)
|
||||
|
||||
@http.route(["/groups/subscription/"], type='json', auth="user")
|
||||
def subscription(self, group_id=0, action=False ,**post):
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
group_obj = request.registry.get('mail.group')
|
||||
if action:
|
||||
group_obj.message_subscribe_users(cr, uid, [group_id], context=context)
|
||||
else:
|
||||
group_obj.message_unsubscribe_users(cr, uid, [group_id], context=context)
|
||||
return []
|
||||
|
||||
@http.route([
|
||||
"/groups/<model('mail.group'):group>/<any(thread,list):mode>",
|
||||
"/groups/<model('mail.group'):group>/<any(thread,list):mode>/page/<int:page>"
|
||||
], type='http', auth="public", website=True)
|
||||
def thread(self, group, mode='thread', page=1, **post):
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
|
||||
thread_obj = request.registry.get('mail.message')
|
||||
domain = [('model','=','mail.group'), ('res_id','=',group.id)]
|
||||
if mode=='thread':
|
||||
domain.append(('parent_id','=',False))
|
||||
thread_count = thread_obj.search_count(cr, uid, domain, context=context)
|
||||
pager = request.website.pager(
|
||||
url='/groups/%s/%s' % (group.id, mode),
|
||||
total=thread_count,
|
||||
page=page,
|
||||
step=self._thread_per_page,
|
||||
)
|
||||
thread_ids = thread_obj.search(cr, uid, domain, limit=self._thread_per_page, offset=pager['offset'])
|
||||
|
||||
messages = thread_obj.browse(cr, uid, thread_ids, context)
|
||||
for m in messages:
|
||||
print m.subject
|
||||
values = {
|
||||
'messages': messages,
|
||||
'group': group,
|
||||
'pager': pager,
|
||||
'mode': mode
|
||||
}
|
||||
return request.website.render('website_mail_group.group_messages', values)
|
||||
|
||||
@http.route([
|
||||
"/groups/<model('mail.group'):group>/message/<model('mail.message'):message>",
|
||||
], type='http', auth="public", website=True)
|
||||
def get_thread(self, group, message, mode='thread', page=1, **post):
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
values = {
|
||||
'message': message,
|
||||
'group': group,
|
||||
'mode': mode,
|
||||
'page': page,
|
||||
}
|
||||
return request.website.render('website_mail_group.group_message', values)
|
|
@ -0,0 +1,182 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<template id="footer_mailing_list" inherit_id="website.layout" name="Footer Mailing List Link">
|
||||
<xpath expr="//footer//div[@name='info']/ul" position="inside">
|
||||
<li><a t-attf-href="/groups">Mailing List</a></li>
|
||||
</xpath>
|
||||
</template>
|
||||
<template id="mail_groups" name="Mailing Lists">
|
||||
<t t-call="website.layout">
|
||||
<div class="container">
|
||||
<h1>
|
||||
Our Mailing Lists
|
||||
</h1>
|
||||
<div class="row">
|
||||
<div class="col-sm-4" style="height: 140px" t-foreach="groups" t-as="group">
|
||||
<img t-att-src="'/website/image?model=mail.group&field=image_small&id='+str(group['id'])" class="pull-left"/>
|
||||
<div>
|
||||
<strong><a t-attf-href="/groups/#{ slug(group) }/thread" t-esc="group.name"/></strong>
|
||||
<div t-esc="group.description" class="text-muted"/>
|
||||
|
||||
<div class="input-group js_follow"
|
||||
t-att-data-id="group.id"
|
||||
data-object="mail.group"
|
||||
data-follow="off">
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
class="js_follow_email form-control"
|
||||
placeholder="your email..."/>
|
||||
<span class="input-group-btn">
|
||||
<a href="#" class="btn btn-default js_unfollow_btn">unsubscribe</a>
|
||||
<a href="#" class="btn btn-primary js_follow_btn">subscribe</a>
|
||||
</span>
|
||||
<div class="alert alert-success hidden">You have been subscribed!</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="group_messages" name="Message Threads">
|
||||
<t t-call="website.layout">
|
||||
<section class="container">
|
||||
<div class="row mt8">
|
||||
<div class="col-md-5">
|
||||
<ol class="breadcrumb mb8">
|
||||
<li><a href="/groups">Mailing Lists</a></li>
|
||||
<li class="active" t-esc="group.name"/>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<t t-call="website.pager"/>
|
||||
</div>
|
||||
</div>
|
||||
<h1 class="mt8 mb32">
|
||||
<span t-field="group.name"/>
|
||||
<small>List Archive</small>
|
||||
</h1>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<ul class="nav nav-pills nav-stacked" id="group_mode">
|
||||
<li t-attf-class="#{mode=='thread' and 'active' or ''}">
|
||||
<a t-attf-href="/groups/#{ slug(group) }/thread">By thread</a>
|
||||
</li>
|
||||
<li t-attf-class="#{mode=='list' and 'active' or ''}">
|
||||
<a t-attf-href="/groups/#{ slug(group) }/list">By date</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<t t-call="website_mail_group.messages_short"/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="group_message">
|
||||
<t t-call="website.layout">
|
||||
<div class="container">
|
||||
<div class="row mt8">
|
||||
<div class="col-md-5">
|
||||
<ol class="breadcrumb mb8">
|
||||
<li><a href="/groups">Mailing Lists</a></li>
|
||||
<li>
|
||||
<a t-attf-href="/groups/#{ slug(group) }/#{mode}/page/#{str(page)}">
|
||||
<span t-field="group.name"/>
|
||||
</a>
|
||||
</li>
|
||||
<li class="active" t-esc="message.subject or 'Message'"/>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 t-field="message.subject"/>
|
||||
<img class="img-rounded pull-left" t-att-src="'/website/image?model=mail.message&field=author_avatar&id='+str(message.id)" style="width : 30px"/>
|
||||
<h4 class="mt0 mb32">
|
||||
<span t-field="message.author_id.name"/>
|
||||
on <span t-field="message.date"/>
|
||||
</h4>
|
||||
<div t-raw="message.body"/>
|
||||
|
||||
<div class="row" t-if="message.attachment_ids">
|
||||
<h3 class="col-sm-12">Attachment(s):</h3>
|
||||
<div class="col-md-2 col-sm-3 text-center" t-foreach='message.attachment_ids' t-as='attachment'>
|
||||
<a t-att-href="'/mail/download_attachment?model=mail.message&id='+str(message.id)+'&method=download_attachment&attachment_id='+str(attachment.id)" target="_blank">
|
||||
<t t-if="attachment.file_type == 'webimage'">
|
||||
<img t-att-src="'/web/binary/image?model=ir.attachment&field=datas&id=' + str(attachment.id) + '&resize=100,80'"
|
||||
class='oe_attachment_embedded'></img>
|
||||
</t>
|
||||
<t t-if="attachment.file_type != 'webimage'">
|
||||
<img t-att-src="'/mail/static/src/img/mimetypes/' + attachment.file_type + '.png'"
|
||||
class='oe_attachment_webimage'></img>
|
||||
</t>
|
||||
<div class='oe_attachment_name'><t t-raw='attachment.name' /></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="message.child_ids">
|
||||
<h2 class="page-header">Follow ups</h2>
|
||||
<t t-set="messages" t-value="message.child_ids"/>
|
||||
<t t-call="website_mail_group.messages_short"/>
|
||||
</div>
|
||||
<div t-if="message.parent_id">
|
||||
<h2 class="page-header">Reference</h2>
|
||||
<t t-set="messages" t-value="[message.parent_id]"/>
|
||||
<t t-call="website_mail_group.messages_short"/>
|
||||
</div>
|
||||
|
||||
<div class="jumbotron mt64">
|
||||
<h1>Join the discussion</h1>
|
||||
<p>
|
||||
Join this mailing list to follow or participate to this discussion.<br/>
|
||||
<span t-field="group.name"/>: <i t-field="group.description"/>
|
||||
</p>
|
||||
|
||||
<div style="max-width: 400px">
|
||||
<div class="input-group js_follow"
|
||||
t-att-data-id="group.id"
|
||||
data-object="mail.group"
|
||||
data-follow="off">
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
class="js_follow_email form-control"
|
||||
placeholder="your email..."/>
|
||||
<span class="input-group-btn">
|
||||
<a href="#" class="btn btn-default js_unfollow_btn">unsubscribe</a>
|
||||
<a href="#" class="btn btn-primary js_follow_btn">subscribe</a>
|
||||
</span>
|
||||
<div class="alert alert-success hidden">You have been subscribed!</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="messages_short">
|
||||
<ul class="media-list">
|
||||
<li t-foreach="messages" t-as="thread" class="media">
|
||||
<a t-attf-href="/groups/#{group.id}/message/#{ slug(thread) }?mode=#{mode}" class="pull-left">
|
||||
<img class="img-rounded pull-right mt0" style="height: 40px"
|
||||
t-att-src="'/website/image?model=mail.message&field=author_avatar&id='+str(thread.id)"/>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<h4 class="media-heading">
|
||||
<a t-attf-href="/groups/#{ slug(group) }/message/#{ slug(thread) }" t-esc="thread.subject"/>
|
||||
<br/>
|
||||
<small>by <t t-esc="thread.author_id.name and thread.author_id.name or thread.email_from"/> on <t t-esc="thread.date"/></small>
|
||||
</h4>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -4,21 +4,20 @@ import unittest2
|
|||
|
||||
import openerp.tests
|
||||
|
||||
inject = [
|
||||
("openerp.website.Tour", os.path.join(os.path.dirname(__file__), '../../website/static/src/js/website.tour.js')),
|
||||
("openerp.website.Tour.ShopTest", os.path.join(os.path.dirname(__file__), "../static/src/js/website.tour.sale.js")),
|
||||
]
|
||||
|
||||
class TestUi(openerp.tests.HttpCase):
|
||||
def test_01_admin_shop_tour(self):
|
||||
return
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('shop')", "openerp.website.Tour.Shop", login="admin")
|
||||
|
||||
def test_02_admin_checkout(self):
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour", login="admin", inject=inject)
|
||||
return
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", login="admin")
|
||||
|
||||
def test_03_demo_checkout(self):
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", login="demo", inject=inject)
|
||||
return
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", login="demo")
|
||||
|
||||
@unittest2.expectedFailure
|
||||
def test_04_public_checkout(self):
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", inject=inject)
|
||||
return
|
||||
self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest")
|
||||
|
|
|
@ -200,8 +200,8 @@
|
|||
</table>
|
||||
<t t-if="not bins">
|
||||
<div class="text-center text-muted">
|
||||
<h3 class="css_editable_display">No product defined.</h3>
|
||||
<t groups="base.group_website_publisher">
|
||||
<h3>No product found.</h3>
|
||||
<t groups="base.group_website_publisher" t-ignore="true">
|
||||
<p groups="base.group_sale_manager">Use the <i>'Content'</i> top menu to create a new product.</p>
|
||||
</t>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue