This commit adds some commands that can be used in the html editor. Editor Commands --------------- Some new editor commands have been added: - */article:* This command is available on every html field using the Odoo Editor. This command allows to add a direct link to the selected knowledge article. - */file:* This command is only available in the Knowledge App. This command allows to add a file (or an image) download button inside the body. The user can choose a file to add from its own file directory or an existing attachment already present in the database. - */template:* This command is only available in the Knowledge App. This command allows the user to create a block where them can write and lay out content destined to be reused by the readers of the article. The lasts will be able to copy and paste it to send it as message or use it as a description on other records. No /command can be added inside a template. Technical notes: /file and /template commands can be activated in other modules by adding knowledge_commands = True on the html field in the view where they should be activated. Task-2674460 Part-of: odoo/odoo#82315 Co-authored-by: Damien Abeloos <abd@odoo.com> Co-authored-by: Julien Banken <jbn@odoo.com> Co-authored-by: David Beguin <dbe@odoo.com> Co-authored-by: Fabio Barbero <faba@odoo.com> Co-authored-by: Thibault Delavallee <tde@odoo.com> Co-authored-by: Aurelien Warnong <awa@odoo.com>
342 lines
25 KiB
XML
342 lines
25 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<odoo>
|
|
<record id="knowledge_article_view_form" model="ir.ui.view">
|
|
<field name="name">knowledge.article.view.form</field>
|
|
<field name="model">knowledge.article</field>
|
|
<field name="type">form</field>
|
|
<field name="arch" type="xml">
|
|
<form class="h-100" js_class="knowledge_article_view_form">
|
|
<field name="active" invisible="1"/>
|
|
<field name="icon" invisible="1"/>
|
|
<field name="category" invisible="1"/>
|
|
<field name="is_locked" invisible="1" readonly="1"/>
|
|
<field name="is_user_favorite" invisible="1"/>
|
|
<field name="user_has_write_access" invisible="1"/>
|
|
<field name="user_permission" invisible="1"/>
|
|
<div class="d-sm-flex h-100 bg-white">
|
|
<aside class="o_knowledge_aside d-print-none flex-shrink-0 p-0">
|
|
<div class="d-flex flex-column h-100">
|
|
<!-- Search bar -->
|
|
<div id="knowledge_search_bar" class="d-flex align-items-center border bg-light rounded m-3 o_cursor_pointer" data-hotkey="f">
|
|
<div class="flex-grow-1 px-2 py-1">Search an article...</div>
|
|
<i class="oi oi-search pr-2" title="search"/>
|
|
</div>
|
|
<!-- File explorer -->
|
|
<div class="flex-grow-1 position-relative">
|
|
<div class="o_scroll_view px-3">
|
|
<div class="o_knowledge_tree">
|
|
<div class="p-5 text-center">
|
|
<i class="fa fa-circle-o-notch fa-2x fa-spin" title="loader" role="img"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
<div class="flex-grow-1 position-relative">
|
|
<div class="o_knowledge_article_form_resizer d-none d-sm-block" />
|
|
<div class="d-flex flex-column h-100">
|
|
<!-- Article header -->
|
|
<div class="o_knowledge_header d-sm-flex border-bottom justify-content-between d-print-none">
|
|
<div class="d-flex align-items-center">
|
|
<!-- Breadcrumbs -->
|
|
<ol class="breadcrumb align-items-center p-3" role="navigation">
|
|
<li class="breadcrumb-item d-flex align-items-center">
|
|
<div class="o_knowledge_icon pr-1" attrs="{'invisible': [('icon', '=', False)]}">
|
|
<div class="o_article_emoji_dropdown dropdown">
|
|
<a href="#" class="o_article_editable_emoji o_article_emoji dropdown-toggle o-no-caret"
|
|
type="button" data-toggle="dropdown" aria-expanded="true"
|
|
attrs="{'invisible': ['|', ('is_locked', '=', True), ('user_has_write_access', '=', False)]}"/>
|
|
<span class="o_article_editable_emoji o_article_emoji o-no-caret"
|
|
attrs="{'invisible': [('is_locked', '=', False), ('user_has_write_access', '=', True)]}"/>
|
|
<div class="o_article_emoji_dropdown_panel dropdown-menu rounded p-0" role="menu"
|
|
aria-labelledby="o_article_emoji" />
|
|
</div>
|
|
</div>
|
|
<field attrs="{'readonly': ['|', ('is_locked', '=', True), ('user_has_write_access', '=', False)]}"
|
|
class="o_breadcrumb_article_name o_input" name="name"/>
|
|
</li>
|
|
</ol>
|
|
<i class="fa fa-star o_toggle_favorite o_cursor_pointer"
|
|
title="Remove from favorites"
|
|
attrs="{'invisible': [('is_user_favorite', '=', False)]}"/>
|
|
<i class="fa fa-star-o o_toggle_favorite o_cursor_pointer"
|
|
title="Add to favorites"
|
|
attrs="{'invisible': [('is_user_favorite', '=', True)]}"/>
|
|
<div attrs="{'invisible': ['|', ('is_locked', '=', False), ('user_has_write_access', '=', False)]}">
|
|
<i class="fa fa-fw fa-lock" title="This article is locked"/>
|
|
</div>
|
|
</div>
|
|
<!-- Buttons -->
|
|
<div class="d-flex flex-shrink-0 align-items-center pr-2">
|
|
<a type="button" role="button" class="btn btn-secondary btn-create text-capitalize mr-1" data-hotkey="c">
|
|
<i class="fa fa-plus-circle"/> Create
|
|
</a>
|
|
<div class="btn-group" role="toolbar" aria-label="options">
|
|
<div class="o-dropdown dropdown o-dropdown--no-caret">
|
|
<a type="button" role="button" class="btn btn-secondary btn-share dropdown-toggle mr-1"
|
|
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-hotkey="s"
|
|
attrs="{'invisible': [('id', '=', False)]}">
|
|
<i class="fa fa-share-alt"/> Share
|
|
</a>
|
|
<a type="button" role="button" class="btn btn-secondary btn-chatter mr-1" data-hotkey="d">
|
|
<i class="rounded-circle text-center fa fa-comments" title="Open chatter"/>
|
|
</a>
|
|
<div class="o_knowledge_share_panel dropdown-menu" role="menu">
|
|
<div class="px-3 pb-2">
|
|
<button type="action" name="%(knowledge_invite_action_from_article)d"
|
|
class="btn btn-primary w-100"
|
|
attrs="{'invisible': [('user_has_write_access', '=', False)]}">
|
|
<i class="fa fa-plus"/> Invite
|
|
</button>
|
|
</div>
|
|
<div class="o_knowledge_permission_panel"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="btn-group" role="toolbar" aria-label="options">
|
|
<div class="o-dropdown dropdown o-dropdown--no-caret">
|
|
<a type="button" role="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown"
|
|
aria-haspopup="true" aria-expanded="false" data-hotkey="p">
|
|
<i class="fa fa-ellipsis-v"/>
|
|
</a>
|
|
<div class="o_knowledge_more_options_panel dropdown-menu" role="menu">
|
|
<div attrs="{'invisible': [('user_has_write_access', '=', False)]}">
|
|
<a class="dropdown-item btn-move" href="#" role="button">
|
|
<i class="fa fa-fw fa-angle-double-right"/> Move To
|
|
</a>
|
|
<button class="dropdown-item btn-lock" href="#" type="object" name="action_set_lock"
|
|
attrs="{'invisible': [('is_locked', '=', True)]}">
|
|
<i class="fa fa-fw fa-lock"/> Lock
|
|
</button>
|
|
<button class="dropdown-item btn-lock" href="#" type="object" name="action_set_unlock"
|
|
attrs="{'invisible': [('is_locked', '=', False)]}">
|
|
<i class="fa fa-fw fa-unlock"/> Unlock
|
|
</button>
|
|
<a class="dropdown-item btn-duplicate" href="#" role="button">
|
|
<i class="fa fa-fw fa-copy"/> Duplicate
|
|
</a>
|
|
<button class="dropdown-item" type="object" name="action_article_archive"
|
|
attrs="{'invisible': [('active', '=', False)]}">
|
|
<i class="fa fa-fw fa-archive"/> Archive
|
|
</button>
|
|
<button class="dropdown-item" type="object" name="action_unarchive"
|
|
attrs="{'invisible': [('active', '=', True)]}">
|
|
<i class="fa fa-fw fa-archive"/> Unarchive
|
|
</button>
|
|
<div class="dropdown-divider"/>
|
|
<div class="px-3">
|
|
<field name="full_width" widget="boolean_toggle" force_save="1"/>
|
|
<label for="full_width" class="m-0"/>
|
|
</div>
|
|
<div class="dropdown-divider"
|
|
attrs="{'invisible': [('last_edition_uid', '=', False), ('last_edition_date', '=', False)]}"/>
|
|
</div>
|
|
<div class="px-4 py-2 mx-1" attrs="{'invisible': [('last_edition_uid', '=', False)]}">
|
|
<h6 class="small font-weight-bold m-0">Last Edited by:</h6>
|
|
<div class="d-flex">
|
|
<field name="last_edition_uid" widget="many2one_avatar_user" readonly="1" class="text-truncate"/>
|
|
<span class="mx-1">-</span>
|
|
<field name="last_edition_date" widget="datetime" readonly="1" class="text-nowrap"/>
|
|
</div>
|
|
<h6 class="small font-weight-bold m-0">Created by:</h6>
|
|
<div class="d-flex">
|
|
<field name="create_uid" widget="many2one_avatar_user" readonly="1" class="text-truncate"/>
|
|
<span class="mx-1">-</span>
|
|
<field name="create_date" widget="datetime" readonly="1" class="text-nowrap"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="flex-grow-1 position-relative">
|
|
<div class="o_scroll_view">
|
|
<div class="row p-0 m-0" style="min-height: 100%">
|
|
<div class="d-flex col-12 col-lg position-relative p-0">
|
|
<div class="o_scroll_view_lg">
|
|
<!-- Article body -->
|
|
<div class="o_knowledge_body d-flex flex-column">
|
|
<!-- Article Cover -->
|
|
<field name="cover" widget="image" class="o_knowledge_cover_image"
|
|
attrs="{'invisible': [('cover', '=', False)], 'readonly': [('is_locked', '=', True)]}"/>
|
|
|
|
<!-- Full Width handling -->
|
|
<span class="o_knowledge_article_view_form_dynamic_width d-none"
|
|
attrs="{'invisible': [('full_width', '=', False)]}"/>
|
|
|
|
<!-- Icon and Cover buttons -->
|
|
<div class="o_knowledge_icon_cover_buttons text-primary bg-white d-print-none mt-2"
|
|
attrs="{'invisible': ['|', ('is_locked', '=', True), ('user_has_write_access', '=', False)]}">
|
|
<a type="button" role="button" attrs="{'invisible': [('icon', '!=', False)]}"
|
|
class="btn btn-secondary btn-outline-secondary mr-2 pl-1 o_knowledge_add_icon">
|
|
<i class="fa fa-fw fa-smile-o" style="font-size: 1.5em;" title="Add icon"/> Add icon
|
|
</a>
|
|
<a type="button" role="button" attrs="{'invisible': [('cover', '!=', False)]}"
|
|
class="btn btn-secondary btn-outline-secondary o_knowledge_add_cover">
|
|
<i class="fa fa-fw fa-picture-o" style="font-size: 1.5em;" title="Add cover"/> Add cover
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Article Icon -->
|
|
<span class="d-none" attrs="{'invisible': [('cover', '!=', False)]}" />
|
|
<div class="o_knowledge_icon o_large" attrs="{'invisible': [('icon', '=', False)]}">
|
|
<div class="o_article_emoji_dropdown dropdown">
|
|
<a href="#" class="o_article_emoji dropdown-toggle o-no-caret"
|
|
type="button" data-toggle="dropdown" aria-expanded="true"
|
|
attrs="{'invisible': ['|', ('is_locked', '=', True), ('user_has_write_access', '=', False)]}"/>
|
|
<p class="o_article_emoji o-no-caret"
|
|
attrs="{'invisible': [('is_locked', '=', False), ('user_has_write_access', '=', True)]}"/>
|
|
<div class="o_article_emoji_dropdown_panel dropdown-menu rounded p-0" role="menu"
|
|
aria-labelledby="o_article_emoji" />
|
|
</div>
|
|
</div>
|
|
<!-- Article body -->
|
|
<div class="o_knowledge_editor d-flex flex-grow-1">
|
|
<field name="body" widget="html" no_label="1" default_focus="1"
|
|
options="{'resizable': False, 'knowledge_commands': true}"
|
|
attrs="{'readonly': ['|', ('is_locked', '=', True), ('user_has_write_access', '=', False)]}"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Chatter -->
|
|
<div class="o_knowledge_chatter col-12 col-lg-4 position-relative d-none d-print-none p-0">
|
|
<div class="o_scroll_view_lg">
|
|
<div class="oe_chatter">
|
|
<field name="message_follower_ids" groups="base.group_user"/>
|
|
<field name="activity_ids"/>
|
|
<field name="message_ids"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="o_knowledge_article_form_resizer d-print-none d-none d-sm-block px-3 opacity-75 opacity-100-hover">
|
|
<span class="bg-300 pl-1"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="knowledge_article_view_tree" model="ir.ui.view">
|
|
<field name="name">knowledge.article.view.tree</field>
|
|
<field name="model">knowledge.article</field>
|
|
<field name="arch" type="xml">
|
|
<tree default_order="is_user_favorite desc, favorite_count desc">
|
|
<field name="display_name"/>
|
|
<field name="is_user_favorite" widget="boolean_favorite" nolabel="1"
|
|
force_save="1" options="{'allow_order': '1'}"/>
|
|
<field name="favorite_count" invisible="1"/>
|
|
<field name="root_article_id"/>
|
|
<field name="last_edition_uid" widget="many2one_avatar_user"/>
|
|
<field name="last_edition_date"/>
|
|
</tree>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="knowledge_article_view_kanban" model="ir.ui.view">
|
|
<field name="name">knowledge.article.view.kanban</field>
|
|
<field name="model">knowledge.article</field>
|
|
<field name="arch" type="xml">
|
|
<kanban class="o_knowledge_article_kanban_view">
|
|
<field name="icon" invisible="1"/>
|
|
<field name="is_locked" invisible="1"/>
|
|
<field name="is_user_favorite" invisible="1"/>
|
|
<field name="user_has_write_access" invisible="1"/>
|
|
<field name="article_url" invisible="1"/>
|
|
<templates>
|
|
<t t-name="kanban-box">
|
|
<div class="oe_kanban_global_click">
|
|
<div class="o_knowledge_kanban_card d-flex flex-column">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-grow-1 lead text-truncate">
|
|
<field name="display_name"/>
|
|
</div>
|
|
<!-- When the user does not have 'write' access on an article, the user will not be
|
|
allowed to write on the `knowledge.article` model. Therefore, we can not use the
|
|
`boolean_favorite` widget as the model can block the write call issued by the widget.
|
|
To let the user add an article to their favorites, we will instead call an
|
|
intermediate action that will do a sudo call on the `knowledge.article` model. -->
|
|
<a type="object" name="action_toggle_favorite" class="o_favorite o_field_widget"
|
|
attrs="{'invisible': [('is_user_favorite', '=', False)]}">
|
|
<i class="fa fa-star" title="Remove from favorites"/>
|
|
</a>
|
|
<a type="object" name="action_toggle_favorite" class="o_favorite o_field_widget"
|
|
attrs="{'invisible': [('is_user_favorite', '=', True)]}">
|
|
<i class="fa fa-star-o" title="Add to favorites"/>
|
|
</a>
|
|
<div attrs="{'invisible': ['|', ('is_locked', '=', False), ('user_has_write_access', '=', False)]}">
|
|
<i class="fa fa-fw fa-lock" title="locked"/>
|
|
</div>
|
|
</div>
|
|
<div class="flex-grow-1 text-muted">
|
|
<field name="category"/>
|
|
</div>
|
|
<div class="d-flex justify-content-end align-items-center">
|
|
<div class="flex-grow-1">
|
|
<field name="article_url" widget="CopyClipboardButton"
|
|
options="{'label': 'Copy Link'}"/>
|
|
</div>
|
|
<field name="activity_ids" widget="kanban_activity"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
</templates>
|
|
</kanban>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="knowledge_article_view_search" model="ir.ui.view">
|
|
<field name="name">knowledge.article.view.search</field>
|
|
<field name="model">knowledge.article</field>
|
|
<field name="arch" type="xml">
|
|
<search>
|
|
<field name="name"/>
|
|
<field name="root_article_id"/>
|
|
<field name="last_edition_uid"/>
|
|
|
|
<filter name="filter_active" string="Archived"
|
|
domain="[('active', '=', False)]"/>
|
|
<filter name="filter_favorites" string="My Favorites"
|
|
domain="[('is_user_favorite', '=', True)]"/>
|
|
<filter name="filter_own_privates" string="My Private Articles"
|
|
domain="[('category', '=', 'private'), ('user_has_write_access', '=', True)]"/>
|
|
<filter name="filter_shared_articles" string="My Shared Articles"
|
|
domain="[('category', '=', 'shared')]"/>
|
|
|
|
<group expand="0" string="Group By">
|
|
<filter string="Category" name="group_by_category" domain="[]" context="{'group_by': 'category'}"/>
|
|
</group>
|
|
</search>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="knowledge_article_action" model="ir.actions.act_window">
|
|
<field name="name">Articles</field>
|
|
<field name="res_model">knowledge.article</field>
|
|
<field name="view_mode">tree,kanban,form</field>
|
|
<field name="help" type="html">
|
|
<p class="o_view_nocontent_smiling_face">
|
|
Create an article
|
|
</p><p>
|
|
Be the first one to unleash the power of Knowledge !
|
|
</p>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="knowledge_article_action_form" model="ir.actions.act_window">
|
|
<field name="name">Articles</field>
|
|
<field name="res_model">knowledge.article</field>
|
|
<field name="view_mode">form</field>
|
|
<field name="view_id" ref="knowledge.knowledge_article_view_form"/>
|
|
</record>
|
|
|
|
</odoo>
|