Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 25 additions & 30 deletions document_page/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,31 @@


{
'name': 'Document Page',
'version': '12.0.1.3.0',
'category': 'Knowledge Management',
'author': 'OpenERP SA, Odoo Community Association (OCA)',
'images': [
'images/category_list.png',
'images/create_category.png',
'images/page_list.png',
'images/create_page.png',
'images/customer_invoice.jpeg',
'images/page_history.png',
"name": "Documentation Page",
"version": "12.0.1.4.0",
"category": "Knowledge Management",
"author": "OpenERP SA, Odoo Community Association (OCA)",
"images": [
"images/category_list.png",
"images/create_category.png",
"images/page_list.png",
"images/create_page.png",
"images/customer_invoice.jpeg",
"images/page_history.png",
],
'website': 'https://github.com/OCA/knowledge',
'license': 'AGPL-3',
'depends': [
'mail',
'knowledge',
],
'data': [
'security/document_page_security.xml',
'security/ir.model.access.csv',
'wizard/document_page_create_menu.xml',
'wizard/document_page_show_diff.xml',
'views/document_page.xml',
'views/document_page_category.xml',
'views/document_page_history.xml',
'views/document_page_assets.xml',
'views/report_document_page.xml',
],
'demo': [
'demo/document_page.xml'
"website": "https://github.com/OCA/knowledge",
"license": "AGPL-3",
"depends": ["mail", "knowledge"],
"data": [
"security/document_page_security.xml",
"security/ir.model.access.csv",
"wizard/document_page_create_menu.xml",
"wizard/document_page_show_diff.xml",
"views/document_page.xml",
"views/document_page_category.xml",
"views/document_page_history.xml",
"views/document_page_assets.xml",
"views/report_document_page.xml",
],
"demo": ["demo/document_page.xml"],
}
169 changes: 99 additions & 70 deletions document_page/models/document_page.py
Original file line number Diff line number Diff line change
@@ -1,116 +1,143 @@
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import api, fields, models, _
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError


class DocumentPage(models.Model):
"""This class is use to manage Document."""

_name = "document.page"
_inherit = ['mail.thread', 'mail.activity.mixin']
_inherit = ["mail.thread", "mail.activity.mixin"]
_description = "Document Page"
_order = 'name'
_parent_name = "parent_id"
_parent_store = True
_rec_name = "complete_name"
_order = "type, sequence, complete_name"

name = fields.Char('Title', required=True)
name = fields.Char("Title", required=True)
type = fields.Selection(
[('content', 'Content'), ('category', 'Category')],
'Type',
[("content", "Content"), ("category", "Category")],
"Type",
help="Page type",
default="content"
default="content",
)
active = fields.Boolean(default=True)
parent_id = fields.Many2one(
'document.page',
'Category',
domain=[('type', '=', 'category')]
)
child_ids = fields.One2many(
'document.page',
'parent_id',
'Children'
"document.page", "Category", domain=[("type", "=", "category")]
)
child_ids = fields.One2many("document.page", "parent_id", "Children")
content = fields.Text(
"Content",
compute='_compute_content',
inverse='_inverse_content',
search='_search_content',
compute="_compute_content",
inverse="_inverse_content",
search="_search_content",
required=True,
copy=True,
)

# no-op computed field
draft_name = fields.Char(
string='Name',
help='Name for the changes made',
string="Name",
help="Name for the changes made",
compute=lambda x: x,
inverse=lambda x: x,
)

# no-op computed field
draft_summary = fields.Char(
string='Summary',
help='Describe the changes made',
string="Summary",
help="Describe the changes made",
compute=lambda x: x,
inverse=lambda x: x,
)

template = fields.Html(
"Template",
help="Template that will be used as a content template "
"for all new page of this category.",
"for all new page of this category.",
)
history_head = fields.Many2one(
'document.page.history',
'HEAD',
compute='_compute_history_head',
"document.page.history",
"HEAD",
compute="_compute_history_head",
store=True,
auto_join=True,
)
history_ids = fields.One2many(
'document.page.history',
'page_id',
'History',
order='create_date DESC',
readonly=True,
)
menu_id = fields.Many2one(
'ir.ui.menu',
"Menu",
"document.page.history",
"page_id",
"History",
order="create_date DESC",
readonly=True,
)
menu_id = fields.Many2one("ir.ui.menu", "Menu", readonly=True,)
content_date = fields.Datetime(
'Last Contribution Date',
related='history_head.create_date',
"Last Contribution Date",
related="history_head.create_date",
store=True,
index=True,
readonly=True,
)
content_uid = fields.Many2one(
'res.users',
'Last Contributor',
related='history_head.create_uid',
"res.users",
"Last Contributor",
related="history_head.create_uid",
store=True,
index=True,
readonly=True,
)
company_id = fields.Many2one(
'res.company',
'Company',
help='If set, page is accessible only from this company',
"res.company",
"Company",
help="If set, page is accessible only from this company",
index=True,
ondelete='cascade',
ondelete="cascade",
)
backend_url = fields.Char(
string='Backend URL',
help='Use it to link resources univocally',
compute='_compute_backend_url',
string="Backend URL",
help="Use it to link resources univocally",
compute="_compute_backend_url",
)

sequence = fields.Integer(
string="Sequence", default=10, help="Used to organise the category."
)

parent_path = fields.Char(index=True)
complete_name = fields.Char(
"Complete Name", compute="_compute_complete_name", store=True
)

@api.depends('menu_id', 'parent_id.menu_id')
image = fields.Binary("Image", attachment=True,)

color = fields.Integer(string="Color Index")

@api.multi
def write(self, vals):
child_ids = self
if vals.get("color", False) and len(vals) == 1:
child_ids = self.search(
[("type", "=", "category"),
("parent_id", "child_of", self.ids)]
)
res = super(DocumentPage, child_ids).write(vals)
return res

@api.depends("name", "parent_id.complete_name")
def _compute_complete_name(self):
for category in self:
if category.parent_id:
category.complete_name = "{} / {}".format(
category.parent_id.complete_name, category.name,
)
else:
category.complete_name = category.name

@api.depends("menu_id", "parent_id.menu_id")
def _compute_backend_url(self):
tmpl = '/web#id={}&model=document.page&view_type=form'
tmpl = "/web#id={}&model=document.page&view_type=form"
for rec in self:
url = tmpl.format(rec.id)
# retrieve action
Expand All @@ -120,13 +147,13 @@ def _compute_backend_url(self):
action = parent.menu_id.action
parent = parent.parent_id
if action:
url += '&action={}'.format(action.id)
url += "&action={}".format(action.id)
rec.backend_url = url

@api.constrains('parent_id')
@api.constrains("parent_id")
def _check_parent_id(self):
if not self._check_recursion():
raise ValidationError(_('You cannot create recursive categories.'))
raise ValidationError(_("You cannot create recursive categories."))

@api.multi
def _get_page_index(self, link=True):
Expand All @@ -135,43 +162,45 @@ def _get_page_index(self, link=True):
index = []
for subpage in self.child_ids:
index += ["<li>" + subpage._get_page_index() + "</li>"]
r = ''
r = ""
if link:
r = '<a href="{}">{}</a>'.format(self.backend_url, self.name)
if index:
r += "<ul>" + "".join(index) + "</ul>"
return r

@api.multi
@api.depends('history_head')
@api.depends("history_head")
def _compute_content(self):
for rec in self:
if rec.type == 'category':
if rec.type == "category":
rec.content = rec._get_page_index(link=False)
else:
if rec.history_head:
rec.content = rec.history_head.content
else:
# html widget's default, so it doesn't trigger ghost save
rec.content = '<p><br></p>'
rec.content = "<p><br></p>"

@api.multi
def _inverse_content(self):
for rec in self:
if rec.type == 'content' and \
rec.content != rec.history_head.content:
rec._create_history({
'name': rec.draft_name,
'summary': rec.draft_summary,
'content': rec.content,
})
if rec.type == "content" \
and rec.content != rec.history_head.content:
rec._create_history(
{
"name": rec.draft_name,
"summary": rec.draft_summary,
"content": rec.content,
}
)

@api.multi
def _search_content(self, operator, value):
return [('history_head.content', operator, value)]
return [("history_head.content", operator, value)]

@api.multi
@api.depends('history_ids')
@api.depends("history_ids")
def _compute_history_head(self):
for rec in self:
if rec.history_ids:
Expand All @@ -180,20 +209,20 @@ def _compute_history_head(self):
@api.multi
def _create_history(self, vals):
self.ensure_one()
history = self.env['document.page.history']
vals['page_id'] = self.id
history = self.env["document.page.history"]
vals["page_id"] = self.id
return history.create(vals)

@api.onchange("parent_id")
def _onchange_parent_id(self):
"""We Set it the right content to the new parent."""
if not self.content or self.content == '<p><br></p>':
if not self.content or self.content == "<p><br></p>":
if self.parent_id and self.parent_id.type == "category":
self.content = self.parent_id.template
self.content = self.parent_id.template

@api.multi
def unlink(self):
menus = self.mapped('menu_id')
menus = self.mapped("menu_id")
res = super().unlink()
menus.unlink()
return res
2 changes: 2 additions & 0 deletions document_page/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
* `Tecnativa <https://www.tecnativa.com>`_:

* Víctor Martínez

* Florent THOMAS <florent.thomas@mind-and-go.com>
28 changes: 28 additions & 0 deletions document_page/static/src/js/document_page_kanban.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
odoo.define("document_page.update_kanban", function(require) {
"use strict";

var KanbanRecord = require("web.KanbanRecord");

KanbanRecord.include({
// --------------------------------------------------------------------------
// Private
// --------------------------------------------------------------------------

/**
* @override
* @private
*/
_openRecord: function() {
if (
this.modelName === "document.page" &&
this.$(".o_document_page_kanban_boxes a").length
) {
this.$(".o_document_page_kanban_boxes a")
.first()
.click();
} else {
this._super.apply(this, arguments);
}
}
});
});
Loading