diff options
| author | Rémy Baranx (bar) <bar@odoo.com> | 2020-02-26 13:03:10 +0000 |
|---|---|---|
| committer | Yannick Tivisse <yti@odoo.com> | 2020-03-19 14:33:02 +0000 |
| commit | 11cd84317d5f40a68d5286ce581ce9c141afcd85 (patch) | |
| tree | c437d34845304abcfeb5019dc635eb2f9e7fc4b8 | |
| parent | bd2e82b504e17f626e044cbfc2c1e6e39b506ad5 (diff) | |
[IMP] pad_project: collaborative pads in portal
When the 'collaborative pads' option is activated for a project,
and the visibility is set to 'portal users', it is possible to define
the access level to pads to edit task descriptions.
- If set to 'internal users', the behavior stays the same.
- If set to 'portal users', a portal user has access to a pad to edit
task descriptions on the portal.
When configured for portal users access, by default, the task description
is displayed with an 'edit' button on top of it.
On 'edit' button click, the page is re-rendered with an additional
url parmater 'edit=1' to switch to edit mode.
In edit mode, the task description is shown in a collaborative pad,
with a 'Save' button on top of it.
On 'save' button click, the page is re-rendered with the 'edit' url
parameter, to switch in classic mode (read-only).
TaskID: 2204379
[IMP] project: collaborative pads in portal
In order to be (easily) able to add buttons to the right of the description
title, the description title is put inside a d-flex div.
closes odoo/odoo#46591
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
| -rw-r--r-- | addons/pad_project/__manifest__.py | 4 | ||||
| -rw-r--r-- | addons/pad_project/models/project.py | 35 | ||||
| -rw-r--r-- | addons/pad_project/static/src/css/pad_project.css | 10 | ||||
| -rw-r--r-- | addons/pad_project/views/project_portal_assets.xml | 8 | ||||
| -rw-r--r-- | addons/pad_project/views/project_portal_templates.xml | 34 | ||||
| -rw-r--r-- | addons/pad_project/views/project_views.xml | 6 | ||||
| -rw-r--r-- | addons/project/views/project_portal_templates.xml | 4 |
7 files changed, 98 insertions, 3 deletions
diff --git a/addons/pad_project/__manifest__.py b/addons/pad_project/__manifest__.py index 846b98c68ba..142784a1c91 100644 --- a/addons/pad_project/__manifest__.py +++ b/addons/pad_project/__manifest__.py @@ -14,7 +14,9 @@ This module adds a PAD in all project form views. ], 'data': [ 'views/res_config_settings_views.xml', - 'views/project_views.xml' + 'views/project_views.xml', + 'views/project_portal_templates.xml', + 'views/project_portal_assets.xml' ], 'auto_install': True, } diff --git a/addons/pad_project/models/project.py b/addons/pad_project/models/project.py index 40cfbfdbf10..8c58209a200 100644 --- a/addons/pad_project/models/project.py +++ b/addons/pad_project/models/project.py @@ -11,6 +11,10 @@ class ProjectTask(models.Model): description_pad = fields.Char('Pad URL', pad_content_field='description', copy=False) use_pad = fields.Boolean(related="project_id.use_pads", string="Use collaborative pad", readonly=True) + pad_availability = fields.Selection( + related="project_id.pad_availability", + string="Availability of collaborative pads", + readonly=True) @api.model def create(self, vals): @@ -20,8 +24,37 @@ class ProjectTask(models.Model): self = self.with_context(pad_no_create=True) return super(ProjectTask, self).create(vals) + def _use_portal_pad(self): + """ + Indicates if the task configuration requires to provide + an access to a portal pad. + """ + self.ensure_one() + return self.use_pad and self.pad_availability == 'portal' + + def _get_pad_content(self): + """ + Gets the content of the pad used to edit the task description + and returns it. + """ + self.ensure_one() + return self.pad_get_content(self.description_pad) + class ProjectProject(models.Model): _inherit = "project.project" - use_pads = fields.Boolean("Use collaborative pads", default=True, help="Use collaborative pad for the tasks on this project.") + use_pads = fields.Boolean("Use collaborative pads", default=True, + help="Use collaborative pad for the tasks on this project.") + + pad_availability = fields.Selection([ + ('internal', 'Internal Users'), + ('portal', 'Portal Users') + ], compute='_compute_pad_availability', store=True, readonly=False, + string='Availability of collaborative pads', required=True, default='internal') + + @api.depends('use_pads', 'privacy_visibility') + def _compute_pad_availability(self): + for project in self: + if project.privacy_visibility != 'portal' or not project.use_pads: + project.pad_availability = 'internal' diff --git a/addons/pad_project/static/src/css/pad_project.css b/addons/pad_project/static/src/css/pad_project.css new file mode 100644 index 00000000000..90a8b3de2cb --- /dev/null +++ b/addons/pad_project/static/src/css/pad_project.css @@ -0,0 +1,10 @@ +.o_pad_project_container { + border: solid 1px #c4c4c4; + height:500px; + padding: 0.5rem; + -webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.1); + -moz-box-shadow: 0 5px 10px rgba(0,0,0,0.1); + -ms-box-shadow: 0 5px 10px rgba(0,0,0,0.1); + -o-box-shadow: 0 5px 10px rgba(0,0,0,0.1); + box-shadow: 0 5px 10px rgba(0,0,0,0.1); +} diff --git a/addons/pad_project/views/project_portal_assets.xml b/addons/pad_project/views/project_portal_assets.xml new file mode 100644 index 00000000000..ef773412517 --- /dev/null +++ b/addons/pad_project/views/project_portal_assets.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <template id="project_portal_assets_frontend" name="project portal assets" inherit_id="web.assets_frontend"> + <xpath expr="." position="inside"> + <link rel="stylesheet" href="/pad_project/static/src/css/pad_project.css"/> + </xpath> + </template> +</odoo> diff --git a/addons/pad_project/views/project_portal_templates.xml b/addons/pad_project/views/project_portal_templates.xml new file mode 100644 index 00000000000..6981aaf1430 --- /dev/null +++ b/addons/pad_project/views/project_portal_templates.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <template id="portal_my_task" inherit_id="project.portal_my_task" priority="40"> + + <!-- add a button to the right of the 'description' title according to the mode (edit/read) --> + <xpath expr="//div[@t-if='task.description']//div[hasclass('d-flex')]" position="inside"> + <t t-if="task._use_portal_pad()"> + <t t-if="request.params.get('edit')"> + <a role="button" class="btn btn-primary btn-sm ml-auto" t-attf-href="/my/task/#{task.id}">Save</a> + </t> + <t t-else=""> + <a role="button" class="btn btn-primary btn-sm ml-auto" t-attf-href="/my/task/#{task.id}?edit=1">Edit</a> + </t> + </t> + </xpath> + + <!-- show the description (read mode) or a pad (edit mode) --> + <xpath expr="//div[@t-field='task.description']" position="replace"> + <t t-if="task._use_portal_pad()"> + <t t-if="request.params.get('edit')"> + <div class="o_pad_project_container"> + <iframe width="100%" height="100%" frameborder="0" t-att-src="task.description_pad + '?showChat=false&userName=' + request.env.user.name"/> + </div> + </t> + <t t-else=""> + <div class="py-1 px-2 bg-100 small" t-raw="task._get_pad_content()"/> + </t> + </t> + <t t-else=""> + <t>$0</t> + </t> + </xpath> + </template> +</odoo> diff --git a/addons/pad_project/views/project_views.xml b/addons/pad_project/views/project_views.xml index 50320a42831..81278874bc9 100644 --- a/addons/pad_project/views/project_views.xml +++ b/addons/pad_project/views/project_views.xml @@ -30,6 +30,12 @@ <div class="text-muted"> Use collaborative rich text pads on tasks </div> + <div class="content-group" attrs="{'invisible': ['|', ('use_pads', '=', False), ('privacy_visibility', '!=', 'portal')]}"> + <div class="mt16 row"> + <label for="pad_availability" string="Available to:" class="col-3 col-lg-3 o_light_label"/> + <field name="pad_availability" widget="radio"/> + </div> + </div> </div> </div> </xpath> diff --git a/addons/project/views/project_portal_templates.xml b/addons/project/views/project_portal_templates.xml index 2f8a8b502d4..b865607e5b8 100644 --- a/addons/project/views/project_portal_templates.xml +++ b/addons/project/views/project_portal_templates.xml @@ -236,7 +236,9 @@ <div class="row" t-if="task.description or task.attachment_ids"> <div t-if="task.description" t-attf-class="col-12 col-lg-7 mb-4 mb-md-0 {{'col-lg-7' if task.attachment_ids else 'col-lg-12'}}"> <hr class="mb-1"/> - <strong class="d-block mb-2">Description</strong> + <div class="d-flex my-2"> + <strong>Description</strong> + </div> <div class="py-1 px-2 bg-100 small" t-field="task.description"/> </div> <div t-if="task.attachment_ids" t-attf-class="col-12 col-lg-5 o_project_portal_attachments {{'col-lg-5' if task.description else 'col-lg-12'}}"> |
