[MRG]Merge with lp:openobject-addons

bzr revid: cod@tinyerp.com-20140318061058-af16oqhax7r2egm2
This commit is contained in:
Chirag Dodiya (OpenERP) 2014-03-18 11:40:58 +05:30
commit 02a6190f2f
50 changed files with 2913 additions and 1125 deletions

View File

@ -401,7 +401,7 @@
</div>
<div style="height: 50px;text-align: left;font-size : 14px;border-collapse: separate;margin-top:10px">
<strong style="margin-left:12px">Dear ${object.cn}</strong> ,<br/>
<p style="margin-left:12px">this it a reminder for the event below : </p>
<p style="margin-left:12px">That is a reminder for the event below : </p>
</div>
<div style="height: auto;margin-left:12px;margin-top:30px;">
<table>

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-03-13 06:16+0000\n"
"X-Launchpad-Export-Date: 2014-03-14 06:36+0000\n"
"X-Generator: Launchpad (build 16963)\n"
#. module: l10n_be_invoice_bba

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -25,7 +25,7 @@
<t t-set="additional_title">Partner Detail</t>
<div id="wrap">
<div class="oe_structure">
<section data-snippet-id="title">
<section>
<div class="container">
<div class="row">
<div class="col-md-12">
@ -73,7 +73,7 @@ response = request.website.render("website.template_partner_post", values)
<t t-set="additional_title">Partners</t>
<div id="wrap">
<div class="oe_structure">
<section data-snippet-id="title">
<section>
<div class="container">
<div class="row">
<div class="col-md-12">

View File

@ -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):

View File

@ -344,6 +344,12 @@
-moz-box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
}
.oe_overlay .oe_handle.readonly {
cursor: auto !important;
}
.oe_overlay .oe_handle.readonly:before, .oe_overlay .oe_handle.readonly.size {
display: none !important;
}
.oe_overlay .icon.btn {
display: inline-block;
}
@ -351,7 +357,7 @@
position: absolute;
left: 50% !important;
text-align: center;
top: -11px;
top: -20px;
z-index: 1002;
}
.oe_overlay .oe_overlay_options > .btn-group {
@ -618,8 +624,3 @@
height: 16px;
display: inline-block;
}
[data-snippet-id] {
min-height: 10px;
min-width: 10px;
}

View File

@ -252,6 +252,10 @@
background: rgba(30, 30, 30, .8)
color: #fff
+box-shadow(0 0 5px 3px rgba(255,255,255,.7))
&.readonly
cursor: auto !important
&:before, &.size
display: none !important
.icon.btn
display: inline-block
@ -260,7 +264,7 @@
position: absolute
left: 50% !important
text-align: center
top: -11px
top: -20px
z-index: 1002
> .btn-group
left: -50%
@ -485,10 +489,6 @@
height: 16px
display: inline-block
[data-snippet-id]
min-height: 10px
min-width: 10px

View File

@ -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,9 +120,10 @@ header a.navbar-brand img {
}
/* ----- BOOTSTRAP FIX ----- */
.container .container {
.container .container, .readable .container {
padding-left: 0;
padding-right: 0;
width: auto;
}
/* ----- BOOTSTRAP HACK FOR HEADER NAV BAR ----- */
@ -216,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 {
@ -280,12 +284,16 @@ ul.nav-stacked > li > a {
background-size: 100%;
}
[data-snippet-id], .colmd, .hr, .blockquote {
section, .carousel, .parallax, .row, .hr, .blockquote {
min-height: 30px;
}
.carousel, .parallax, .blockquote {
overflow: hidden;
}
@media (max-width: 400px) {
[data-snippet-id]:not([data-snippet-id="carousel"]) {
section, .parallax, .row, .hr, .blockquote {
height: auto !important;
}
}
@ -380,10 +388,10 @@ ul.nav-stacked > li > a {
}
/* Parallax Theme */
div.carousel[data-snippet-id="slider"] .carousel-indicators li {
div.carousel .carousel-indicators li {
border: 1px solid grey;
}
div.carousel[data-snippet-id="slider"] .carousel-indicators .active {
div.carousel .carousel-indicators .active {
background-color: grey;
}

View File

@ -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,17 +84,16 @@ header
/* ----- EDITOR ----- */
.css_non_editable_mode_hidden
display: none
/* ----- BOOTSTRAP FIX ----- */
.container
.container, .readable
.container
padding-left: 0
padding-right: 0
width: auto
/* ----- BOOTSTRAP HACK FOR HEADER NAV BAR ----- */
@ -179,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
@ -230,11 +234,13 @@ ul.nav-stacked > li > a
.oe_img_bg
background-size: 100%
[data-snippet-id],.colmd,.hr,.blockquote
section, .carousel, .parallax, .row, .hr, .blockquote
min-height: 30px
.carousel, .parallax, .blockquote
overflow: hidden
@media (max-width: 400px)
[data-snippet-id]:not([data-snippet-id="carousel"])
section, .parallax, .row, .hr, .blockquote
height: auto !important
.carousel-inner
@ -312,7 +318,7 @@ ul.nav-stacked > li > a
/* Parallax Theme */
div.carousel[data-snippet-id="slider"]
div.carousel
.carousel-indicators
li
border: 1px solid grey

View File

@ -106,6 +106,7 @@
},
canUndo: false,
editorFocus: true,
context: 'a',
});
//noinspection JSValidateTypes
editor.addCommand('image', {
@ -115,6 +116,7 @@
},
canUndo: false,
editorFocus: true,
context: 'img',
});
editor.ui.addButton('Link', {
@ -205,8 +207,9 @@
icon: '/website/static/src/img/bglink.png',
modes: { wysiwyg: true },
editorFocus: true,
context: 'a',
panel: {
css: '/website/static/lib/bootstrap/css/bootstrap.css',
css: '/web/static/lib/bootstrap/css/bootstrap.css',
attributes: { 'role': 'listbox', 'aria-label': label },
},
@ -346,14 +349,40 @@
requires: 'widget',
init: function (editor) {
var specials = {
// Can't find the correct ACL rule to only allow img tags
image: { content: '*' },
html: { text: '*' },
monetary: {
text: {
selector: 'span.oe_currency_value',
allowedContent: { }
}
}
};
_(specials).each(function (editable, type) {
editor.widgets.add(type, {
draggable: false,
editables: editable,
upcast: function (el) {
return el.attributes['data-oe-type'] === type;
}
});
});
editor.widgets.add('oeref', {
editables: { text: '*' },
draggable: false,
editables: {
text: {
selector: '*',
allowedContent: { }
},
},
upcast: function (el) {
var matches = el.attributes['data-oe-type'] && el.attributes['data-oe-type'] !== 'monetary';
if (!matches) { return false; }
var type = el.attributes['data-oe-type'];
if (!type || (type in specials)) {
return false;
}
if (el.attributes['data-oe-original']) {
while (el.children.length) {
el.children[0].remove();
@ -363,16 +392,9 @@
));
}
return true;
},
});
editor.widgets.add('monetary', {
editables: { text: 'span.oe_currency_value' },
draggable: false,
upcast: function (el) {
return el.attributes['data-oe-type'] === 'monetary';
}
});
editor.widgets.add('icons', {
draggable: false,

View File

@ -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,103 +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) {
/**
* A bootstrapped version of prompt() albeit asynchronous
@ -231,11 +124,13 @@
dialog.on('click', '.btn-primary', function () {
def.resolve(field.val(), field, dialog);
dialog.remove();
$('.modal-backdrop').remove();
});
});
dialog.on('hidden.bs.modal', function () {
def.reject();
dialog.remove();
$('.modal-backdrop').remove();
});
if (field.is('input[type="text"], select')) {
field.keypress(function (e) {
@ -248,6 +143,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);
@ -263,11 +168,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");

View File

@ -5,20 +5,26 @@
if (!website.snippet) website.snippet = {};
website.snippet.readyAnimation = [];
website.snippet.start_animation = function () {
website.snippet.start_animation = function (editable_mode, $target) {
for (var k in website.snippet.animationRegistry) {
var Animation = website.snippet.animationRegistry[k];
var selector = "[data-snippet-id='"+k+"']";
var selector = "";
if (Animation.prototype.selector) {
selector += ", " + Animation.prototype.selector;
if (selector != "") selector += ", "
selector += Animation.prototype.selector;
}
if ($target) {
if ($target.is(selector)) selector = $target;
else continue;
}
$(selector).each(function() {
var $snipped_id = $(this);
if ( !$snipped_id.parents("#oe_snippets").length &&
!$snipped_id.parent("body").length &&
!$snipped_id.data("snippet-view")) {
website.snippet.readyAnimation.push($snipped_id);
$snipped_id.data("snippet-view", new Animation($snipped_id));
$snipped_id.data("snippet-view", new Animation($snipped_id, editable_mode));
}
});
}
@ -32,7 +38,9 @@
}
});
};
$(document).ready(website.snippet.start_animation);
$(document).ready(function () {
website.snippet.start_animation();
});
website.snippet.animationRegistry = {};
@ -41,9 +49,9 @@
$: function () {
return this.$el.find.apply(this.$el, arguments);
},
init: function (dom) {
init: function (dom, editable_mode) {
this.$el = this.$target = $(dom);
this.start();
this.start(editable_mode);
},
/*
* start
@ -71,7 +79,7 @@
});
website.snippet.animationRegistry.parallax = website.snippet.Animation.extend({
parallax: ".parallax",
selector: ".parallax",
start: function () {
var self = this;
setTimeout(function () {self.set_values();});
@ -108,7 +116,7 @@
img.onload = function () {
var offset = 0;
var padding = parseInt($(document.body).css("padding-top"));
if (speed < 1) {
if (speed > 1) {
var inner_offset = - self.$target.outerHeight() + this.height / this.width * document.body.clientWidth;
var outer_offset = self.$target.offset().top - (document.body.clientHeight - self.$target.outerHeight()) - padding;
offset = - outer_offset * speed + inner_offset;
@ -123,4 +131,21 @@
}
});
website.snippet.animationRegistry.share = website.snippet.Animation.extend({
selector: ".oe_share",
start: function () {
var url = encodeURIComponent(window.location.href);
var title = encodeURIComponent($("title").text());
this.$target.find("a").each(function () {
var $a = $(this);
$a.attr("href", $(this).attr("href").replace("{url}", url).replace("{title}", title));
if ($a.attr("target") && $a.attr("target").match(/_blank/i)) {
$a.click(function () {
window.open(this.href,'','menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=550,width=600');
return false;
});
}
});
},
});
})();

File diff suppressed because it is too large Load Diff

View File

@ -35,11 +35,11 @@
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 },
},
{
snippet: 'carousel',
snippet: '#snippet_structure .oe_snippet:first',
placement: 'bottom',
title: _t("Drag & Drop a Banner"),
content: _t("Drag the Banner block and drop it in your page."),
@ -47,14 +47,14 @@
},
{
waitFor: '.oe_overlay_options .oe_options:visible',
element: '#wrap [data-snippet-id=carousel]:first .carousel-caption > div',
element: '#wrap .carousel:first .carousel-caption > div',
placement: 'top',
title: _t("Customize banner's text"),
content: _t("Click in the text and start editing it."),
popover: { next: _t("Continue") },
},
{
element: '.oe_overlay_options .oe_options',
element: '.oe_overlay_options .oe_options:visible',
placement: 'left',
title: _t("Customize the banner"),
content: _t("Customize any block through this menu. Try to change the background of the banner."),
@ -69,14 +69,7 @@
popover: { fixed: true },
},
{
element: 'a[href="#snippet_feature"]',
placement: 'bottom',
title: _t("Feature blocks list"),
content: _t("Click on 'Features' to see the feature blocks list."),
popover: { fixed: true },
},
{
snippet: 'features',
snippet: '#snippet_structure .oe_snippet:eq(6)',
placement: 'bottom',
title: _t("Drag & Drop This Block"),
content: _t("Drag the <em>'Features'</em> block and drop it below the banner."),
@ -92,8 +85,8 @@
},
{
waitFor: 'button[data-action=edit]:visible',
title: _("Good Job!"),
content: _("Well done, you created your homepage."),
title: _t("Good Job!"),
content: _t("Well done, you created your homepage."),
popover: { next: _t("Continue") },
},
{
@ -108,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") },

View File

@ -3,9 +3,22 @@
var website = openerp.website;
// don't need template to use bootstrap Tour in automatic mode
if (typeof QWeb2 !== "undefined")
website.add_template_file('/website/static/src/xml/website.tour.xml');
// don't need to use bootstrap Tour to launch an automatic tour
function bootstrap_tour_stub () {
if (typeof Tour === "undefined") {
window.Tour = function Tour() {};
Tour.prototype.addSteps = function () {};
Tour.prototype.end = function () {};
Tour.prototype.goto = function () {};
}
}
if (website.EditorBar)
website.EditorBar.include({
tours: [],
@ -175,6 +188,9 @@ website.Tour = openerp.Class.extend({
},
registerTour: function () {
if (this.automatic) {
bootstrap_tour_stub();
}
this.tour = new Tour({
name: this.id,
storage: this.tourStorage,
@ -205,7 +221,7 @@ website.Tour = openerp.Class.extend({
if (!step.element) step.orphan = true;
if (step.snippet) {
step.element = '#oe_snippets div.oe_snippet[data-snippet-id="'+step.snippet+'"] .oe_snippet_thumbnail';
step.element = '#oe_snippets '+step.snippet+' .oe_snippet_thumbnail';
}
}
@ -377,7 +393,7 @@ website.Tour = openerp.Class.extend({
if (step.snippet) {
var selector = '#oe_snippets div.oe_snippet[data-snippet-id="'+step.snippet+'"] .oe_snippet_thumbnail';
var selector = '#oe_snippets '+step.snippet+' .oe_snippet_thumbnail';
self.autoDragAndDropSnippet(selector);
} else if (step.element.match(/#oe_snippets .* \.oe_snippet_thumbnail/)) {

View File

@ -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: 'carousel',
},
{
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);
}());

View File

@ -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");
})();

View File

@ -97,7 +97,7 @@
target="fileframe"
class="col-sm-8">
<div class="text-center">
<input type="file" name="upload" style="position: absolute; opacity: 0; width: 1px; height: 1px;"/>
<input type="file" name="upload" accept="image/*" style="position: absolute; opacity: 0; width: 1px; height: 1px;"/>
<button type="button" class="btn btn-primary btn-lg filepicker">
Upload an image from your computer
</button>

View File

@ -22,7 +22,7 @@
<t t-name="website.snippet_overlay">
<div class="oe_overlay">
<div class="oe_overlay_options">
<div class="oe_overlay_options" contentEditable="false">
<div class="btn-group">
<a href="#" class="btn btn-default btn-sm oe_snippet_parent" title="Select Container Block"><i class="fa fa-upload"></i></a>
<div class="dropdown oe_options hidden btn-group">
@ -34,6 +34,13 @@
<a href="#" class="btn btn-default btn-sm oe_snippet_remove" title="Remove Block">&amp;nbsp;<i class="fa fa-trash-o"></i>&amp;nbsp; </a>
</div>
</div>
<div class='oe_handles'>
<div class='oe_handle n readonly'><div></div></div>
<div class='oe_handle e readonly'><div></div></div>
<div class='oe_handle w readonly'><div></div></div>
<div class='oe_handle size readonly'><div class="oe_handle_button size">Resize</div></div>
<div class='oe_handle s readonly'><div></div></div>
</div>
</div>
</t>
@ -45,13 +52,6 @@
<div t-name="website.snippets.resize" data-snippet-id='resize'>
<!-- custom data for the widget -->
<div class='oe_handles'>
<div class='oe_handle n'><div></div></div>
<div class='oe_handle e'><div></div></div>
<div class='oe_handle w'><div></div></div>
<div class='oe_handle size'><div class="oe_handle_button size">Resize</div></div>
<div class='oe_handle s'><div></div></div>
</div>
<div class='oe_snippet_thumbnail'>Margin resize</div>
</div>

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -13,14 +13,7 @@
<div id="snippet_structure" class="tab-pane fade in active">
<div data-snippet-id="carousel" data-selector-children=".oe_structure, [data-oe-type=html]">
<li class="oe_snippet_options divider"></li>
<li class="oe_snippet_options">
<a href="#" class="button js_add">Add Slide</a>
</li>
<li class="oe_snippet_options">
<a href="#" class="button js_remove">Remove Slide</a>
</li>
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_banner.png"/>
<span class="oe_snippet_thumbnail_title">Banner</span>
@ -51,7 +44,7 @@
</div>
</div>
<div data-snippet-id="text-image" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_text_image.png"/>
<span class="oe_snippet_thumbnail_title">Text-Image</span>
@ -79,7 +72,7 @@
</div>
<div data-snippet-id="image-text" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_image_text.png"/>
<span class="oe_snippet_thumbnail_title">Image-Text</span>
@ -107,7 +100,7 @@
</div>
<div data-snippet-id="jumbotron" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_jumbotron.png"/>
<span class="oe_snippet_thumbnail_title">Big Message</span>
@ -128,7 +121,7 @@
</div>
<div data-snippet-id="text-block" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_text_block.png"/>
<span class="oe_snippet_thumbnail_title">Text Block</span>
@ -166,7 +159,7 @@
</div>
<div data-snippet-id="title" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_title.png"/>
<span class="oe_snippet_thumbnail_title">Title</span>
@ -183,7 +176,7 @@
</section>
</div>
<div data-snippet-id="features" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_features.png"/>
<span class="oe_snippet_thumbnail_title">Features</span>
@ -214,7 +207,7 @@
</section>
</div>
<div data-snippet-id="big-picture" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_big_picture.png"/>
<span class="oe_snippet_thumbnail_title">Big Picture</span>
@ -246,7 +239,7 @@
</section>
</div>
<div data-snippet-id="three-columns" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_three_columns.png"/>
<span class="oe_snippet_thumbnail_title">Three Columns</span>
@ -291,7 +284,7 @@
<div id="snippet_content" class="tab-pane fade">
<div data-snippet-id="well" data-selector-siblings="p, h1, h2, h3, blockquote" data-selector-children=".content">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_well.png"/>
<span class="oe_snippet_thumbnail_title">Well</span>
@ -303,7 +296,7 @@
</div>
<div data-snippet-id="quote" data-selector-siblings="p, h1, h2, h3, blockquote" data-selector-children=".content">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_quote.png"/>
<span class="oe_snippet_thumbnail_title">Quote</span>
@ -318,7 +311,7 @@
</div>
<div data-snippet-id="panel" data-selector-siblings="p, h1, h2, h3, blockquote" data-selector-children=".content">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_panel.png"/>
<span class="oe_snippet_thumbnail_title">Panel</span>
@ -335,7 +328,7 @@
</div>
<div data-snippet-id="hr" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_separator.png"/>
<span class="oe_snippet_thumbnail_title">Separator</span>
@ -343,11 +336,29 @@
<hr class="oe_snippet_body"/>
</div>
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_button.png"/>
<span class="oe_snippet_thumbnail_title">Share</span>
</div>
<div class="oe_snippet_body oe_share">
<h3>
Share
<a target="_Blank" class="oe_share_facebook" href="https://www.facebook.com/sharer/sharer.php?u={url}"><i class="fa fa-facebook-square"></i></a>
<a target="_Blank" class="oe_share_twitter" href="https://twitter.com/intent/tweet?text={title}&amp;url={url}"><i class="fa fa-twitter"></i></a>
<a target="_Blank" class="oe_share_linkedin" href="http://www.linkedin.com/shareArticle?mini=true&amp;url={url}&amp;title={title}&amp;"><i class="fa fa-linkedin"></i></a>
<a target="_Blank" class="oe_share_google" href="https://plus.google.com/share?url={url}"><i class="fa fa-google-plus-square"></i></a>
<a href="mailto:?body={url}&amp;subject={title}"><i class="fa fa-envelope-o"></i></a>
</h3>
</div>
</div>
</div>
<div id="snippet_feature" class="tab-pane fade">
<div data-snippet-id="portfolio" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_portfolio.png"/>
<span class="oe_snippet_thumbnail_title">Portfolio</span>
@ -380,7 +391,7 @@
</div>
<div data-snippet-id="image-gallery" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_image_gallery.png"/>
<span class="oe_snippet_thumbnail_title">Image Gallery</span>
@ -422,7 +433,7 @@
</div>
<div data-snippet-id="pricing" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_comparison.png"/>
<span class="oe_snippet_thumbnail_title">Comparisons</span>
@ -528,7 +539,7 @@
</div>
<div data-snippet-id="cta" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_button.png"/>
<span class="oe_snippet_thumbnail_title">Button</span>
@ -545,7 +556,7 @@
</div>
<div data-snippet-id="faq" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_faq.png"/>
<span class="oe_snippet_thumbnail_title">FAQ</span>
@ -592,7 +603,7 @@
</div>
<div data-snippet-id="references" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_references.png"/>
<span class="oe_snippet_thumbnail_title">References</span>
@ -609,7 +620,7 @@
</h3>
</div>
<div class="col-md-4 col-md-offset-1 mt16 mb32">
<blockquote data-snippet-id="quote">
<blockquote>
<p>
Write a quote here from one of your customers. Quotes are a
great way to build confidence in your products or services.
@ -618,7 +629,7 @@
</blockquote>
</div>
<div class="col-md-4 col-md-offset-2 mt16 mb32">
<blockquote data-snippet-id="quote">
<blockquote>
<p>
OpenERP provides essential platform for our project management.
Things are better organized and more visible with it.
@ -646,14 +657,7 @@
</section>
</div>
<div data-snippet-id="slider" data-selector-children=".oe_structure, [data-oe-type=html]">
<li class="oe_snippet_options divider"></li>
<li class="oe_snippet_options">
<a href="#" class="button js_add">Add Slide</a>
</li>
<li class="oe_snippet_options">
<a href="#" class="button js_remove">Remove Slide</a>
</li>
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_quotes_slider.png"/>
<span class="oe_snippet_thumbnail_title">Quotes Slider</span>
@ -706,7 +710,7 @@
</div>
</div>
<div data-snippet-id="features-list" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_features.png"/>
<span class="oe_snippet_thumbnail_title">Feature Grid</span>
@ -766,22 +770,11 @@
<div id="snippet_effect" class="tab-pane fade">
<div data-snippet-id="parallax" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_parallax.png"/>
<span class="oe_snippet_thumbnail_title">Parallax</span>
</div>
<li class="oe_snippet_options dropdown-submenu">
<a tabindex="-1" href="#">Scroll Speed</a>
<ul class="dropdown-menu" name="parallax-scroll">
<li data-value="0"><a>Static</a></li>
<li data-value="0.3"><a>Very Slow</a></li>
<li data-value="0.6"><a>Slow</a></li>
<li data-value="1"><a>Fixed</a></li>
<li data-value="1.4"><a>Fast</a></li>
<li data-value="1.7"><a>Very Fast</a></li>
</ul>
</li>
<section class="oe_snippet_body parallax"
style="background-image: url('/website/static/src/img/banner/mountains.jpg')"
data-scroll-background-ratio="0.3">
@ -789,16 +782,16 @@
</section>
</div>
<div data-snippet-id="parallax_quote" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_quotes_slider.png"/>
<span class="oe_snippet_thumbnail_title">Parallax Slider</span>
</div>
<section class="oe_snippet_body parallax" data-snippet-id="parallax"
<section class="oe_snippet_body parallax"
style="background-image: url('/website/static/src/img/parallax/quote.png')"
data-scroll-background-ratio="0.3">
<div><div><div class="oe_structure">
<div id="myQuoteCarousel" class="carousel quotecarousel slide mb0" data-snippet-id="slider">
<div id="myQuoteCarousel" class="carousel quotecarousel slide mb0">
<!-- Indicators -->
<ol class="carousel-indicators mb0">
<li data-target="#myQuoteCarousel" data-slide-to="0" class="active"></li>
@ -850,109 +843,148 @@
</div>
<!-- use to declare snippet for snippet editor -->
<div id="snippet_hidden" class="hidden">
<div id="snippet_options" class="hidden">
<div data-snippet-id='colmd' data-selector-vertical-children='.row'>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_column.png"/>
<span class="oe_snippet_thumbnail_title">Add Column</span>
</div>
<div class="oe_snippet_body col-md-4">
<img class="img img-rounded img-responsive" src="/website/static/src/img/china_thumb.jpg"/>
<h4 class="mt16">Feature</h4>
<p>
Delete the above image or replace it with a picture
that illustrates your message. Click on the picture to
change it's <em>rounded corner</em> style.
</p>
</div>
</div>
</div>
<div id="snippet_styles" class="hidden">
<div data-snippet-style-id='text-style' data-selector="section">
<li class="dropdown-submenu">
<a tabindex="-1" href="#">Style</a>
<ul class="dropdown-menu">
<li data-class="readable"><a>Narrow</a></li>
</ul>
</li>
</div>
<div data-snippet-style-id='carousel-style' data-selector="div[data-snippet-id='carousel']">
<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>
</ul>
</li>
</div>
<div data-snippet-style-id='background' data-selector="section, section[data-snippet-id='parallax'], div[data-snippet-id='carousel'], div[data-snippet-id='slider']">
<li class="dropdown-submenu" data-required="true">
<a tabindex="-1" href="#">Background</a>
<ul class="dropdown-menu">
<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>
</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>
</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>
</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>
</ul>
</li>
<li data-class=""><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>
</ul>
</li>
</div>
<t t-call="website.snippet_options"/>
</div>
</div>
</div>
</template>
<template id="snippet_options">
<div data-snippet-option-id='blog-style'
data-selector="section:not(.carousel):not(.parallax)">
<li class="dropdown-submenu">
<a tabindex="-1" href="#">Style</a>
<ul class="dropdown-menu">
<li data-value="readable"><a>Narrow</a></li>
</ul>
</li>
</div>
<div data-snippet-option-id='background'
data-selector="section, .carousel, .parallax">
<li class="dropdown-submenu" data-required="true">
<a tabindex="-1" href="#">Background</a>
<ul class="dropdown-menu">
<li class="dropdown-submenu">
<a tabindex="-2" href="#">Uniform Color</a>
<ul class="dropdown-menu">
<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-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-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-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-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-value="oe_img_bg"><a><b>Choose an image...</b></a></li>
</ul>
</li>
</div>
<div data-snippet-option-id='carousel-style'
data-selector="div[data-snippet-id='carousel']">
<li class="dropdown-submenu" data-required="true">
<a tabindex="-1" href="#">Layout</a>
<ul class="dropdown-menu">
<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>
<div data-snippet-option-id='carousel'
data-selector=".carousel">
<li class="divider"></li>
<li>
<a href="#" class="button js_add">Add Slide</a>
</li>
<li>
<a href="#" class="button js_remove">Remove Slide</a>
</li>
</div>
<div data-snippet-option-id='margin-y'
data-selector="section, .row > [class*='col-md-'], .carousel, .parallax, hr">
</div>
<div data-snippet-option-id='resize'
data-selector="section, .carousel, .parallax"
data-selector-children=".oe_structure, [data-oe-type=html]">
<li>
<a href="#" class="button js_size_auto">Size Automatic</a>
</li>
</div>
<div data-snippet-option-id='margin-x'
data-selector=".row > [class*='col-md-']"
data-selector-vertical-children='.row'>
</div>
<div data-snippet-option-id='content'
data-selector="blockquote, .well, .panel, .oe_share"
data-selector-siblings="p, h1, h2, h3, blockquote, .well, .panel, .oe_share"
data-selector-children=".content">
</div>
<div data-snippet-option-id='parallax'
data-selector=".parallax">
<li class="dropdown-submenu">
<a tabindex="-1" href="#">Scroll Speed</a>
<ul class="dropdown-menu" name="parallax-scroll">
<li data-value="0"><a>Static</a></li>
<li data-value="0.3"><a>Very Slow</a></li>
<li data-value="0.6"><a>Slow</a></li>
<li data-value="1"><a>Fixed</a></li>
<li data-value="1.4"><a>Fast</a></li>
<li data-value="1.7"><a>Very Fast</a></li>
</ul>
</li>
</div>
</template>
</data>
</openerp>
</openerp>

View File

@ -364,7 +364,7 @@
</li>
<t t-raw="0"/>
<li t-if="publish_edit">
<a t-att-href="'/web#return_label=Website&amp;model=%s&amp;id=%s' % (object._name, object.id)"
<a t-attf-href="/web#return_label=Website&amp;view_type=form&amp;model=#{object._name}&amp;id=#{object.id}&amp;action=#{action}"
title='Edit in backend'>Edit</a>
</li>
</ul>

View File

@ -65,7 +65,7 @@
popover: { fixed: true },
},
{
snippet: 'image-text',
snippet: '#snippet_structure .oe_snippet:eq(2)',
placement: 'bottom',
title: _t("Drag & Drop a Block"),
content: _t("Drag this block and drop it in your page."),
@ -79,7 +79,7 @@
popover: { fixed: true },
},
{
snippet: 'text-block',
snippet: '#snippet_structure .oe_snippet:eq(4)',
placement: 'bottom',
title: _t("Drag & Drop a block"),
content: _t("Drag this block and drop it below the image block."),

View File

@ -155,7 +155,19 @@
<template id="blog_post_complete" name="Blog Post">
<t t-call="website_blog.index">
<div class="container" id="title">
<t t-call="website.publish_management">
<t t-set="object" t-value="blog_post"/>
<t t-set="publish_edit" t-value="True"/>
<t t-set="action" t-value="'website_blog.action_blog_post'"/>
<li>
<form class="duplicate hidden" action="/blogpost/duplicate">
<input name="blog_post_id" t-att-value="blog_post.id"/>
</form>
<a href="#" class="duplicate" onclick="$(this).prev('form').submit()">Duplicate</a>
</li>
</t>
<div id="title">
<h1 class="text-center" t-field="blog_post.name"/>
<p class="post-meta text-muted text-center" name="blog_post_data">
<span class="fa fa-calendar oe_date"> <span t-field="blog_post.create_date"/> &amp;nbsp;</span>
@ -167,18 +179,6 @@
</span>
</p>
</div>
<div class="container">
<t t-call="website.publish_management">
<t t-set="object" t-value="blog_post"/>
<t t-set="publish_edit" t-value="True"/>
<li>
<form class="duplicate hidden" action="/blogpost/duplicate">
<input name="blog_post_id" t-att-value="blog_post.id"/>
</form>
<a href="#" class="duplicate" onclick="$(this).prev('form').submit()">Duplicate</a>
</li>
</t>
</div>
<div t-field="blog_post.content"/>

View File

@ -187,7 +187,7 @@ class website_event(http.Controller):
}
return request.website.render("website_event.event_description_full", values)
@http.route('/event/add_event/', type='http', auth="user", multilang=True, methods=['POST'], website=True)
@http.route('/event/add_event', type='http', auth="user", multilang=True, methods=['POST'], website=True)
def add_event(self, event_name="New Event", **kwargs):
return self._add_event(event_name, request.context, **kwargs)

View File

@ -65,7 +65,7 @@
popover: { fixed: true },
},
{
snippet: 'image-text',
snippet: '#snippet_structure .oe_snippet:eq(2)',
placement: 'bottom',
title: _t("Drag & Drop a block"),
content: _t("Drag the 'Image-Text' block and drop it in your page."),
@ -80,7 +80,7 @@
popover: { fixed: true },
},
{
snippet: 'text-block',
snippet: '#snippet_structure .oe_snippet:eq(4)',
placement: 'bottom',
title: _t("Drag & Drop a block"),
content: _t("Drag the 'Text Block' in your event page."),

View File

@ -189,6 +189,11 @@
</ol>
</div>
<div class="col-sm-5" groups="event.group_event_manager">
<t t-call="website.publish_management">
<t t-set="object" t-value="event"/>
<t t-set="publish_edit" t-value="True"/>
<t t-set="action" t-value="'event.action_event_view'"/>
</t>
</div>
</div>
</div>

View File

@ -32,14 +32,9 @@
'views/website_mail.xml',
'views/website_email_designer.xml',
'views/email_template_view.xml',
'data/mail_groups.xml',
'security/website_mail.xml',
],
'css': [
'static/src/css/website_mail.css',
],
'js': [
'static/src/js/website_mail.js',
],
'qweb': [
'static/src/xml/website_mail.xml'
],

View File

@ -56,3 +56,13 @@ class WebsiteMail(http.Controller):
follower_ids = [p.id for p in obj.message_follower_ids]
return partner_ids[0] in follower_ids and 1 or 0
@http.route(['/website_mail/is_follower/'], type='json', auth="public", website=True)
def call(self, model, id, **post):
email = request.registry['res.users'].browse(request.cr, request.uid, request.uid, request.context).partner_id.email
value = request.registry.get(model).read(request.cr, request.uid, [id], ['message_is_follower'], request.context)
return {
'email': email,
'is_follower': value and value[0]['message_is_follower'] or False
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record model="mail.group" id="group_all_employees">
<field name="name">Newsletter</field>
<field name="public">public</field>
<field name="description">Public Newsletter.</field>
</record>
</data>
</openerp>

View File

@ -1,4 +1,5 @@
.js_follow[data-follow='on'] .js_follow_btn ,
.js_follow[data-follow='on'] .js_follow_email,
.js_follow[data-follow='off'] .js_unfollow_btn {
display: none;
}

View File

@ -0,0 +1,40 @@
(function () {
'use strict';
var website = openerp.website;
var _t = openerp._t;
website.snippet.options.subscribe = website.snippet.Option.extend({
on_prompt: function () {
var self = this;
return website.prompt({
id: "editor_new_subscribe_button",
window_title: _t("Add a Subscribe Button"),
select: _t("Mailing List"),
init: function (field) {
return website.session.model('mail.group')
.call('name_search', ['', [['public','=','public']]], { context: website.get_context() });
},
}).then(function (mail_group_id) {
self.$target.attr("data-id", mail_group_id);
});
},
drop_and_build_snippet: function() {
var self = this;
this._super();
this.on_prompt().fail(function () {
self.editor.on_remove();
});
},
start : function () {
var self = this;
this.$el.find(".js_mailing_list").on("click", _.bind(this.on_prompt, this));
this._super();
},
clean_for_save: function () {
this.$target.addClass("hidden");
},
});
})();

View File

@ -1,30 +1,56 @@
$(document).ready(function () {
(function () {
'use strict';
$(document).on('click', '.js_follow_btn, .js_unfollow_btn', function (ev) {
ev.preventDefault();
var website = openerp.website;
var self = this;
var $data = $(this).parents("div.js_follow");
var $email = $data.find(".js_follow_email");
website.snippet.animationRegistry.follow = website.snippet.Animation.extend({
selector: ".js_follow",
start: function (editable_mode) {
var self = this;
if ($email.length && !$email.val().match(/.+@.+/)) {
return false;
}
// set value and display button
openerp.jsonRpc('/website_mail/is_follower/', 'call', {
model: this.$target.data('object'),
id: +this.$target.data('id'),
}).always(function (data) {
self.$target.find('input.js_follow_email')
.val(data.email ? data.email : "")
.attr("disabled", data.email.length ? "disabled" : false);
self.$target.attr("data-follow", data.is_follower ? 'on' : 'off');
self.$target.removeClass("hidden");
});
var message_is_follower = $data.attr("data-follow") || "off";
$data.attr("data-follow", message_is_follower == 'off' ? 'on' : 'off');
openerp.jsonRpc('/website_mail/follow', 'call', {
'id': $data.data('id'),
'object': $data.data('object'),
'message_is_follower': message_is_follower,
'email': $email.length ? $email.val() : false,
}).then(function (result) {
if (result) {
$data.find(" > *").toggleClass("hidden");
// not if editable mode to allow designer to edit alert field
if (!editable_mode) {
$('.js_follow > .alert').addClass("hidden");
$('.js_follow > .input-group-btn.hidden').removeClass("hidden");
this.$target.find('.js_follow_btn, .js_unfollow_btn').on('click', function (event) {
event.preventDefault();
self.on_click();
});
}
$data.attr("data-follow", result ? 'on' : 'off');
});
});
},
on_click: function () {
var self = this;
var $email = this.$target.find(".js_follow_email:visible");
});
if ($email.length && !$email.val().match(/.+@.+/)) {
this.$target.addClass('has-error');
return false;
}
this.$target.removeClass('has-error');
openerp.jsonRpc('/website_mail/follow', 'call', {
'id': +this.$target.data('id'),
'object': this.$target.data('object'),
'message_is_follower': this.$target.attr("data-follow") || "off",
'email': $email.length ? $email.val() : false,
}).then(function (follow) {
if (follow) {
self.$target.find(" > *").toggleClass("hidden");
}
self.$target.attr("data-follow", follow ? 'on' : 'off');
});
},
});
})();

View File

@ -13,7 +13,7 @@
<div id="snippet_email_structure" class="tab-pane fade in active">
<div data-snippet-id="text-image" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_text_block.png"/>
<span class="oe_snippet_thumbnail_title">Text Block</span>
@ -63,7 +63,7 @@
</div>
<div data-snippet-id="text-image" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_text_image.png"/>
<span class="oe_snippet_thumbnail_title">Text-Image</span>
@ -104,7 +104,7 @@
</div>
<div data-snippet-id="image-text" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_image_text.png"/>
<span class="oe_snippet_thumbnail_title">Image-Text</span>
@ -145,7 +145,7 @@
</div>
<div data-snippet-id="three-columns" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website_mail/static/src/img/blocks/block_two_columns.png"/>
<span class="oe_snippet_thumbnail_title">Two Columns</span>
@ -185,7 +185,7 @@
</div>
<div data-snippet-id="three-columns" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website_mail/static/src/img/blocks/block_three_columns.png"/>
<span class="oe_snippet_thumbnail_title">Three Columns</span>
@ -236,7 +236,7 @@
</div>
<div data-snippet-id="hr" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_separator.png"/>
<span class="oe_snippet_thumbnail_title">Separator</span>
@ -262,7 +262,7 @@
<div id="snippet_email_feature" class="tab-pane fade">
<div data-snippet-id="big-picture" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_big_picture.png"/>
<span class="oe_snippet_thumbnail_title">Big Picture</span>
@ -298,7 +298,7 @@
</div>
<div data-snippet-id="pricing" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_comparison.png"/>
<span class="oe_snippet_thumbnail_title">Comparisons</span>
@ -389,7 +389,7 @@
</div>
<div data-snippet-id="text-image" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_jumbotron.png"/>
<span class="oe_snippet_thumbnail_title">Big Message</span>
@ -413,7 +413,7 @@
</div>
<div data-snippet-id="cta" data-selector-children=".oe_structure, [data-oe-type=html]">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_button.png"/>
<span class="oe_snippet_thumbnail_title">Button</span>
@ -478,18 +478,59 @@
</table>
</div>
</div>
</div>
<div id="snippet_styles" class="hidden">
<div id="snippet_options" class="hidden">
<t t-call="website.snippet_options"/>
</div>
</div>
</div>
</template>
<template id="subscribe" inherit_id="website.snippets" name="Snippet Subscribe">
<xpath expr="//div[@id='snippet_content']" position="inside">
<div>
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_button.png"/>
<span class="oe_snippet_thumbnail_title">Subscribe Button</span>
</div>
<div class="oe_snippet_body input-group js_follow"
data-id="0"
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">thanks for your subscription!</div>
</div>
</div>
</xpath>
<xpath expr="//div[@id='snippet_options']" position="inside">
<div data-snippet-option-id='subscribe'
data-selector=".js_follow"
data-selector-siblings="p, h1, h2, h3, blockquote, .well, .panel"
>
<li>
<a href="#" class="button js_mailing_list">Change mailing list</a>
</li>
</div>
</xpath>
</template>
</data>
</openerp>

View File

@ -9,7 +9,6 @@
<input
type="email" name="email"
class="js_follow_email form-control"
t-att-value="email or ''"
placeholder="your email..."
groups="base.group_public"/>
<span class="input-group-btn">
@ -22,6 +21,7 @@
<template id="head" inherit_id="website.layout" name="Mail customization">
<xpath expr="//head" position="inside">
<script type="text/javascript" src="/website_mail/static/src/js/website_mail.editor.js" groups="base.group_website_publisher"></script>
<script type="text/javascript" src="/website_mail/static/src/js/website_mail.js"></script>
<link rel='stylesheet' href='/website_mail/static/src/css/website_mail.css'/>
</xpath>

View File

@ -0,0 +1 @@
import controllers

View File

@ -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,
}

View File

@ -0,0 +1,3 @@
import main
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -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)

View File

@ -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&amp;field=image_small&amp;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&amp;field=author_avatar&amp;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&amp;id='+str(message.id)+'&amp;method=download_attachment&amp;attachment_id='+str(attachment.id)" target="_blank">
<t t-if="attachment.file_type == 'webimage'">
<img t-att-src="'/web/binary/image?model=ir.attachment&amp;field=datas&amp;id=' + str(attachment.id) + '&amp;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&amp;field=author_avatar&amp;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>

View File

@ -321,7 +321,7 @@ class Ecommerce(http.Controller):
context=dict(context, mail_create_nosubcribe=True))
return werkzeug.utils.redirect(request.httprequest.referrer + "#comments")
@http.route(['/shop/add_product/'], type='http', auth="user", methods=['POST'], website=True, multilang=True)
@http.route(['/shop/add_product'], type='http', auth="user", methods=['POST'], website=True, multilang=True)
def add_product(self, name=None, category=0, **post):
if not name:
name = _("New Product")

View File

@ -109,7 +109,7 @@
popover: { fixed: true },
},
{
snippet: 'big-picture',
snippet: '#snippet_structure .oe_snippet:eq(7)',
placement: 'bottom',
title: _t("Drag & Drop a block"),
content: _t("Drag the 'Big Picture' block and drop it in your page."),

View File

@ -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")
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")

View File

@ -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>
@ -293,6 +293,7 @@
<t t-call="website.publish_management">
<t t-set="object" t-value="product"/>
<t t-set="publish_edit" t-value="True"/>
<t t-set="action" t-value="'product.product_template_action'"/>
</t>
</div>
</div>