[IMP] document_page_portal: black, isort, prettier

This commit is contained in:
Marcel Savegnago 2021-02-28 17:26:09 -03:00
parent eae641107f
commit b7f4fa7ebc
12 changed files with 245 additions and 151 deletions

View File

@ -3,26 +3,22 @@
{ {
'name': 'Document Page Portal', "name": "Document Page Portal",
'summary': """ "summary": """
This module enables document page portal""", This module enables document page portal""",
'version': '12.0.1.0.0', "version": "13.0.1.0.0",
'category': 'Knowledge Management', "category": "Knowledge Management",
'author': 'Escodoo, Odoo Community Association (OCA)', "author": "Escodoo, Odoo Community Association (OCA)",
'maintainers': ['marcelsavegnago'], "maintainers": ["marcelsavegnago"],
'images': ['static/description/banner.png'], "images": ["static/description/banner.png"],
'website': 'https://github.com/OCA/knowledge', "website": "https://github.com/OCA/knowledge",
'license': 'AGPL-3', "license": "AGPL-3",
'depends': [ "depends": ["base", "portal", "document_page"],
'base', "data": [
'portal', "views/assets.xml",
'document_page' "views/document_page.xml",
], "security/document_page_portal_security.xml",
'data': [ "security/ir.model.access.csv",
'views/assets.xml', "views/document_page_portal_templates.xml",
'views/document_page.xml',
'security/document_page_portal_security.xml',
'security/ir.model.access.csv',
'views/document_page_portal_templates.xml',
], ],
} }

View File

@ -5,114 +5,146 @@
from odoo import http from odoo import http
from odoo.exceptions import AccessError, MissingError from odoo.exceptions import AccessError, MissingError
from odoo.http import request from odoo.http import request
from odoo.tools.translate import _
from odoo.addons.portal.controllers.portal import pager as portal_pager, CustomerPortal
from odoo.osv.expression import OR from odoo.osv.expression import OR
from odoo.tools.translate import _
from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager
class CustomerPortal(CustomerPortal): class CustomerPortal(CustomerPortal):
def _prepare_portal_layout_values(self): def _prepare_portal_layout_values(self):
values = super(CustomerPortal, self)._prepare_portal_layout_values() values = super(CustomerPortal, self)._prepare_portal_layout_values()
values['document_page_count'] = request.env[ values["document_page_count"] = request.env["document.page"].search_count(
'document.page'].search_count([('type', '=', 'content')]) [("type", "=", "content")]
)
return values return values
def _document_page_get_page_view_values(self, document_page, def _document_page_get_page_view_values(
access_token, **kwargs): self, document_page, access_token, **kwargs
):
values = { values = {
'page_name': 'document_page', "page_name": "document_page",
'document_page': document_page, "document_page": document_page,
} }
return self._get_page_view_values( return self._get_page_view_values(
document_page, access_token, values, document_page,
'my_document_pages_history', False, **kwargs) access_token,
values,
"my_document_pages_history",
False,
**kwargs
)
@http.route( @http.route(
['/my/knowledge/documents/', '/my/knowledge/documents/page/<int:page>'], ["/my/knowledge/documents/", "/my/knowledge/documents/page/<int:page>"],
type='http', auth="user", website=True) type="http",
def portal_my_knowledge_document_pages(self, page=1, date_begin=None, auth="user",
date_end=None, sortby=None, website=True,
search=None, search_in='content', **kw): )
def portal_my_knowledge_document_pages(
self,
page=1,
date_begin=None,
date_end=None,
sortby=None,
search=None,
search_in="content",
**kw
):
values = self._prepare_portal_layout_values() values = self._prepare_portal_layout_values()
domain = [('type', '=', 'content')] domain = [("type", "=", "content")]
searchbar_sortings = { searchbar_sortings = {
'date': {'label': _('Newest'), 'order': 'create_date desc'}, "date": {"label": _("Newest"), "order": "create_date desc"},
'name': {'label': _('Name'), 'order': 'name'}, "name": {"label": _("Name"), "order": "name"},
'parent': {'label': _('Category'), 'order': 'parent_id'}, "parent": {"label": _("Category"), "order": "parent_id"},
} }
searchbar_inputs = { searchbar_inputs = {
'content': {'input': 'content', 'label': _( "content": {
'Search <span class="nolabel"> (in Content)</span>')}, "input": "content",
'all': {'input': 'all', 'label': _('Search in All')}, "label": _('Search <span class="nolabel"> (in Content)</span>'),
},
"all": {"input": "all", "label": _("Search in All")},
} }
# default sort by value # default sort by value
if not sortby: if not sortby:
sortby = 'date' sortby = "date"
order = searchbar_sortings[sortby]['order'] order = searchbar_sortings[sortby]["order"]
# archive groups - Default Group By 'create_date' # archive groups - Default Group By 'create_date'
archive_groups = self._get_archive_groups('document.page', domain) archive_groups = self._get_archive_groups("document.page", domain)
if date_begin and date_end: if date_begin and date_end:
domain += [ domain += [
('create_date', '>', date_begin), ("create_date", ">", date_begin),
('create_date', '<=', date_end), ("create_date", "<=", date_end),
] ]
# search # search
if search and search_in: if search and search_in:
search_domain = [] search_domain = []
if search_in in ('content', 'all'): if search_in in ("content", "all"):
search_domain = OR([search_domain, [ search_domain = OR(
'|', ('name', 'ilike', search), ('content', 'ilike', search)]]) [
search_domain,
["|", ("name", "ilike", search), ("content", "ilike", search)],
]
)
domain += search_domain domain += search_domain
# pager # pager
document_pages_count = request.env['document.page'].search_count(domain) document_pages_count = request.env["document.page"].search_count(domain)
pager = portal_pager( pager = portal_pager(
url="/my/knowledge/documents", url="/my/knowledge/documents",
url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby}, url_args={"date_begin": date_begin, "date_end": date_end, "sortby": sortby},
total=document_pages_count, total=document_pages_count,
page=page, page=page,
step=self._items_per_page step=self._items_per_page,
) )
document_pages = request.env['document.page'].search( document_pages = request.env["document.page"].search(
domain, order=order, limit=self._items_per_page, offset=pager['offset']) domain, order=order, limit=self._items_per_page, offset=pager["offset"]
request.session['my_document_pages_history'] = document_pages.ids[:100] )
request.session["my_document_pages_history"] = document_pages.ids[:100]
values.update({ values.update(
'date': date_begin, {
'document_pages': document_pages, "date": date_begin,
'page_name': 'document_page', "document_pages": document_pages,
'default_url': '/my/knowledge/s', "page_name": "document_page",
'pager': pager, "default_url": "/my/knowledge/s",
'archive_groups': archive_groups, "pager": pager,
'searchbar_sortings': searchbar_sortings, "archive_groups": archive_groups,
'searchbar_inputs': searchbar_inputs, "searchbar_sortings": searchbar_sortings,
'sortby': sortby, "searchbar_inputs": searchbar_inputs,
'search_in': search_in, "sortby": sortby,
'search': search, "search_in": search_in,
}) "search": search,
}
)
return request.render( return request.render(
"document_page_portal.portal_my_knowledge_document_pages", values) "document_page_portal.portal_my_knowledge_document_pages", values
)
@http.route([ @http.route(
"/knowledge/document/<int:document_page_id>", [
"/knowledge/document/<int:document_page_id>/<token>", "/knowledge/document/<int:document_page_id>",
'/my/knowledge/document/<int:document_page_id>' "/knowledge/document/<int:document_page_id>/<token>",
], type='http', auth="public", website=True) "/my/knowledge/document/<int:document_page_id>",
def document_pages_followup(self, document_page_id=None, ],
access_token=None, **kw): type="http",
auth="public",
website=True,
)
def document_pages_followup(self, document_page_id=None, access_token=None, **kw):
try: try:
document_page_sudo = self._document_check_access( document_page_sudo = self._document_check_access(
'document.page', document_page_id, access_token) "document.page", document_page_id, access_token
)
except (AccessError, MissingError): except (AccessError, MissingError):
return request.redirect('/my') return request.redirect("/my")
values = self._document_page_get_page_view_values( values = self._document_page_get_page_view_values(
document_page_sudo, access_token, **kw) document_page_sudo, access_token, **kw
return request.render( )
"document_page_portal.document_pages_followup", values) return request.render("document_page_portal.document_pages_followup", values)

View File

@ -6,9 +6,10 @@ from odoo import fields, models
class DocumentPage(models.Model): class DocumentPage(models.Model):
_inherit = 'document.page' _inherit = "document.page"
is_public = fields.Boolean( is_public = fields.Boolean(
'Public Page', "Public Page",
help='If true it allows any user of the portal to have ' help="If true it allows any user of the portal to have "
'access to this document.') "access to this document.",
)

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8" ?>
<odoo> <odoo>
<data noupdate="1"> <data noupdate="1">
<record model="ir.rule" id="knowledge_user_document_page_rule"> <record model="ir.rule" id="knowledge_user_document_page_rule">
@ -16,7 +16,10 @@
('message_partner_ids', 'child_of', [user.partner_id.commercial_partner_id.id]) ('message_partner_ids', 'child_of', [user.partner_id.commercial_partner_id.id])
] ]
</field> </field>
<field name="groups" eval="[(4, ref('base.group_portal')),(4, ref('base.group_user'))]" /> <field
name="groups"
eval="[(4, ref('base.group_portal')),(4, ref('base.group_user'))]"
/>
</record> </record>
</data> </data>
</odoo> </odoo>

View File

@ -1,3 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
document_page_portal,document.page portal,document_page.model_document_page,base.group_portal,1,0,0,0 document_page_portal,document.page portal,document_page.model_document_page,base.group_portal,1,0,0,0
document_page_portal_user,document.page portal user,document_page.model_document_page,base.group_user,1,0,0,0 document_page_portal_user,document.page portal user,document_page.model_document_page,base.group_user,1,0,0,0

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 document_page_portal document.page portal document_page.model_document_page base.group_portal 1 0 0 0
3 document_page_portal_user document.page portal user document_page.model_document_page base.group_user 1 0 0 0

View File

@ -1,37 +1,45 @@
odoo.define('document_page_portal.tour', function (require) { odoo.define("document_page_portal.tour", function(require) {
'use strict'; "use strict";
var tour = require("web_tour.tour"); var tour = require("web_tour.tour");
tour.register('document_page_portal_tour', { tour.register(
test: true, "document_page_portal_tour",
url: '/my',
},
[
{ {
content: "Check document_page_portal is loaded", test: true,
trigger: 'a[href*="/my/knowledge/documents"]:contains("Knowledge Documents"):first', url: "/my",
}, },
{ [
content: "Check public document_page is loaded", {
trigger: 'a[href*="/knowledge/document/"]:contains("Test Public Page 1"):first', content: "Check document_page_portal is loaded",
}, trigger:
]); 'a[href*="/my/knowledge/documents"]:contains("Knowledge Documents"):first',
},
{
content: "Check public document_page is loaded",
trigger:
'a[href*="/knowledge/document/"]:contains("Test Public Page 1"):first',
},
]
);
tour.register('document_page_portal_search_tour', { tour.register(
test: true, "document_page_portal_search_tour",
url: '/my/knowledge/documents',
},
[
{ {
content: "Search", test: true,
trigger: "input[name='search']", url: "/my/knowledge/documents",
run: "text Test",
}, },
{ [
content: "Click Search.", {
extra_trigger: "#wrap:not(:has(input[name=search]:propValue('')))", content: "Search",
trigger: '.search-submit', trigger: "input[name='search']",
}, run: "text Test",
]); },
{
content: "Click Search.",
extra_trigger: "#wrap:not(:has(input[name=search]:propValue('')))",
trigger: ".search-submit",
},
]
);
}); });

View File

@ -4,15 +4,17 @@
import odoo.tests import odoo.tests
@odoo.tests.tagged('post_install', '-at_install') @odoo.tests.tagged("post_install", "-at_install")
class TestUi(odoo.tests.HttpCase): class TestUi(odoo.tests.HttpCase):
def test_01_document_page_portal_tour(self): def test_01_document_page_portal_tour(self):
# Create a public document # Create a public document
self.env['document.page'].create({ self.env["document.page"].create(
'name': 'Test Public Page 1', {
'content': 'Test content', "name": "Test Public Page 1",
'is_public': True, "content": "Test content",
}) "is_public": True,
}
)
self.phantom_js( self.phantom_js(
"/", "/",
@ -20,7 +22,7 @@ class TestUi(odoo.tests.HttpCase):
".run('document_page_portal_tour')", ".run('document_page_portal_tour')",
"odoo.__DEBUG__.services['web_tour.tour']" "odoo.__DEBUG__.services['web_tour.tour']"
".tours.document_page_portal_tour.ready", ".tours.document_page_portal_tour.ready",
login="portal" login="portal",
) )
self.phantom_js( self.phantom_js(
@ -29,5 +31,5 @@ class TestUi(odoo.tests.HttpCase):
".run('document_page_portal_search_tour')", ".run('document_page_portal_search_tour')",
"odoo.__DEBUG__.services['web_tour.tour']" "odoo.__DEBUG__.services['web_tour.tour']"
".tours.document_page_portal_search_tour.ready", ".tours.document_page_portal_search_tour.ready",
login="portal" login="portal",
) )

View File

@ -1,11 +1,18 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2020 - TODAY, Marcel Savegnago - Escodoo <!-- Copyright 2020 - TODAY, Marcel Savegnago - Escodoo
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo> <odoo>
<template id="assets_frontend" inherit_id="web.assets_frontend" name="Portal Assets" priority="15"> <template
id="assets_frontend"
inherit_id="web.assets_frontend"
name="Portal Assets"
priority="15"
>
<xpath expr="//script[last()]" position="after"> <xpath expr="//script[last()]" position="after">
<script type="text/javascript" src="/document_page_portal/static/src/js/document_page_portal_tour.js"></script> <script
type="text/javascript"
src="/document_page_portal/static/src/js/document_page_portal_tour.js"
/>
</xpath> </xpath>
</template> </template>

View File

@ -1,16 +1,15 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2020 - TODAY, Marcel Savegnago - Escodoo <!-- Copyright 2020 - TODAY, Marcel Savegnago - Escodoo
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo> <odoo>
<record model="ir.ui.view" id="document_page_form_view"> <record model="ir.ui.view" id="document_page_form_view">
<field name="name">document.page.form (in document_page_portal)</field> <field name="name">document.page.form (in document_page_portal)</field>
<field name="model">document.page</field> <field name="model">document.page</field>
<field name="inherit_id" ref="document_page.view_wiki_form"/> <field name="inherit_id" ref="document_page.view_wiki_form" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="parent_id" position="after"> <field name="parent_id" position="after">
<field name="is_public" groups="document_page.group_document_manager"/> <field name="is_public" groups="document_page.group_document_manager" />
</field> </field>
</field> </field>
</record> </record>

View File

@ -1,11 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8" ?>
<odoo> <odoo>
<data noupdate="0"> <data noupdate="0">
<template id="portal_my_home_menu_Knowledge" name="Portal layout : Knowledge document_pages menu entries" inherit_id="portal.portal_breadcrumbs" priority="50"> <template
id="portal_my_home_menu_Knowledge"
name="Portal layout : Knowledge document_pages menu entries"
inherit_id="portal.portal_breadcrumbs"
priority="50"
>
<xpath expr="//ol[hasclass('o_portal_submenu')]" position="inside"> <xpath expr="//ol[hasclass('o_portal_submenu')]" position="inside">
<li t-if="page_name == 'document_page' or document_page" t-attf-class="breadcrumb-item #{'active ' if not document_page else ''}"> <li
<a t-if="document_page" t-attf-href="/my/knowledge/documents?{{ keep_query() }}">Knowledge Documents</a> t-if="page_name == 'document_page' or document_page"
t-attf-class="breadcrumb-item #{'active ' if not document_page else ''}"
>
<a
t-if="document_page"
t-attf-href="/my/knowledge/documents?{{ keep_query() }}"
>Knowledge Documents</a>
<t t-else="">Knowledge Documents</t> <t t-else="">Knowledge Documents</t>
</li> </li>
<li t-if="document_page" class="breadcrumb-item active"> <li t-if="document_page" class="breadcrumb-item active">
@ -14,7 +25,12 @@
</xpath> </xpath>
</template> </template>
<template id="portal_my_home_Knowledge_document_page" name="Portal My Home : Knowledge Documents" inherit_id="portal.portal_my_home" priority="50"> <template
id="portal_my_home_Knowledge_document_page"
name="Portal My Home : Knowledge Documents"
inherit_id="portal.portal_my_home"
priority="50"
>
<xpath expr="//div[hasclass('o_portal_docs')]" position="inside"> <xpath expr="//div[hasclass('o_portal_docs')]" position="inside">
<t t-if="document_page_count" t-call="portal.portal_docs_entry"> <t t-if="document_page_count" t-call="portal.portal_docs_entry">
<t t-set="title">Knowledge Documents</t> <t t-set="title">Knowledge Documents</t>
@ -39,18 +55,25 @@
<tr> <tr>
<th class="text-right">Ref</th> <th class="text-right">Ref</th>
<th class="w-100">Name</th> <th class="w-100">Name</th>
<th/> <th />
<th class="text-center">Category</th> <th class="text-center">Category</th>
</tr> </tr>
</thead> </thead>
<t t-foreach="document_pages" t-as="document_page"> <t t-foreach="document_pages" t-as="document_page">
<tr> <tr>
<td class="text-right"><a t-attf-href="/knowledge/document/#{document_page.id}"><small>#</small><t t-esc="document_page.id"/></a></td> <td class="text-right"><a
t-attf-href="/knowledge/document/#{document_page.id}"
><small>#</small><t t-esc="document_page.id" /></a></td>
<td> <td>
<a t-attf-href="/knowledge/document/#{document_page.id}"><span t-field="document_page.name" /></a> <a
t-attf-href="/knowledge/document/#{document_page.id}"
><span t-field="document_page.name" /></a>
</td> </td>
<td/> <td />
<td class="text-center"><span class="badge badge-pill badge-info" t-field="document_page.parent_id.name" /></td> <td class="text-center"><span
class="badge badge-pill badge-info"
t-field="document_page.parent_id.name"
/></td>
</tr> </tr>
</t> </t>
</t> </t>
@ -61,9 +84,15 @@
<t t-call="portal.portal_layout"> <t t-call="portal.portal_layout">
<t t-set="wrapwrap_classes" t-value="'o_portal_bg_dark'" /> <t t-set="wrapwrap_classes" t-value="'o_portal_bg_dark'" />
<t t-set="o_portal_fullwidth_alert" groups="knowledge.group_document_user"> <t
t-set="o_portal_fullwidth_alert"
groups="knowledge.group_document_user"
>
<t t-call="portal.portal_back_in_edit_mode"> <t t-call="portal.portal_back_in_edit_mode">
<t t-set="backend_url" t-value="'/web#return_label=Website&amp;model=document.page&amp;id=%s&amp;view_type=form' % (document_page.id)" /> <t
t-set="backend_url"
t-value="'/web#return_label=Website&amp;model=document.page&amp;id=%s&amp;view_type=form' % (document_page.id)"
/>
</t> </t>
</t> </t>
@ -72,22 +101,32 @@
<div class="row no-gutters"> <div class="row no-gutters">
<div class="col-md"> <div class="col-md">
<h5 class="mb-1 mb-md-0"> <h5 class="mb-1 mb-md-0">
<span t-field="document_page.name"/> <span t-field="document_page.name" />
<small class="text-muted"> (#<span t-field="document_page.id"/>)</small> <small class="text-muted"> (#<span
t-field="document_page.id"
/>)</small>
</h5> </h5>
</div> </div>
<div class="col-md text-md-right"> <div class="col-md text-md-right">
<small class="text-right">Category:</small> <small class="text-right">Category:</small>
<span t-field="document_page.parent_id.name" class=" badge badge-pill badge-info" title="Current Category of this document" /> <span
t-field="document_page.parent_id.name"
class=" badge badge-pill badge-info"
title="Current Category of this document"
/>
</div> </div>
</div> </div>
</t> </t>
<t t-set="card_body"> <t t-set="card_body">
<div class="row mb-4"> <div class="row mb-4">
<h1 class="col-lg-12"> <h1 class="col-lg-12">
<span t-field="document_page.name"/> <span t-field="document_page.name" />
</h1> </h1>
<div t-if="document_page.content" class="col-lg-12" t-raw="document_page.content" /> <div
t-if="document_page.content"
class="col-lg-12"
t-raw="document_page.content"
/>
<div t-else="" class="col-lg-10"> <div t-else="" class="col-lg-10">
<em class="text-muted"><small>No content</small></em> <em class="text-muted"><small>No content</small></em>
</div> </div>

View File

@ -0,0 +1 @@
../../../../document_page_portal

View File

@ -0,0 +1,6 @@
import setuptools
setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)