[REF] website_slides: improve elearning backend usability and onboarding

PURPOSE

Improve elearning backend usability and onboarding

SPECIFICATIONS

Improve layout of email send when invite. Do like a SO, add the join button
in the notification email and not in the composer itself. It required to
create a new notification layout specific to that invite wizard.

Improve channel form view: remove statistics as they are already displayed
in various places, add a stat button for content/visits, better display of
karma (split gain from karma-based access rules).

Automatically publish channel's product to avoid de-synchronization of publish
flags.

Remove unused channel_url field on wizard.

LINKS

Task ID-2241513
PR #55698
This commit is contained in:
Patrick Hoste
2020-08-11 10:31:23 +00:00
committed by Thibault Delavallée
parent b39f4b6307
commit 4f2a4b175f
8 changed files with 102 additions and 54 deletions
@@ -7,7 +7,8 @@
<field name="arch" type="xml">
<xpath expr="//field[@name='enroll']" position="after">
<field name="product_id"
attrs="{'invisible': [('enroll', '!=', 'payment')], 'required': [('enroll', '=', 'payment')]}" />
attrs="{'invisible': [('enroll', '!=', 'payment')], 'required': [('enroll', '=', 'payment')]}"
context="{'default_type': 'service', 'default_invoice_policy': 'order', 'default_purchase_ok': False, 'default_sale_ok': True, 'default_website_published': True}"/>
</xpath>
<xpath expr="//button[@name='action_redirect_to_members']" position="after">
<button name="action_view_sales"
+1 -1
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
{
'name': 'eLearning',
'version': '2.1',
'version': '2.2',
'sequence': 145,
'summary': 'Manage and publish an eLearning platform',
'website': 'https://www.odoo.com/page/slides',
+73 -12
View File
@@ -80,24 +80,85 @@
<field name="body_html" type="html">
<div style="margin: 0px; padding: 0px; font-size: 13px;">
<p style="margin: 0px; padding: 0px; font-size: 13px;">
Dear ${object.partner_id.name or 'participant'}<br/><br/>
Hello<br/><br/>
You have been invited to join a new course: ${object.channel_id.name}.
<div style="margin: 16px 0px 16px 0px;">
<a href="${(object.channel_id.website_url) | safe}"
style="background-color: #875A7B; padding: 8px 16px 8px 16px; text-decoration: none; color: #fff; border-radius: 5px; font-size:13px;">
Click here to start the course.
</a>
</div>
Enjoy this exclusive content !
% if user.signature
<br />
${user.signature | safe}
% endif
</p>
</div>
</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="auto_delete" eval="True"/>
</record>
<!-- QWeb templates -->
<!-- Note: mail_notification_channel_invite: record should be a slide.channel.partner record -->
<template id="mail_notification_channel_invite">
<table border="0" cellpadding="0" cellspacing="0" style="padding-top: 16px; background-color: #F1F1F1; font-family:Verdana, Arial,sans-serif; color: #454748; width: 100%; border-collapse:separate;"><tr><td align="center">
<table border="0" cellpadding="0" cellspacing="0" width="590" style="padding: 24px; background-color: white; color: #454748; border-collapse:separate;">
<tbody>
<!-- HEADER -->
<tr>
<td align="center" style="min-width: 590px;">
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: white; padding: 0; border-collapse:separate;">
<tr><td valign="middle">
<span style="font-size: 10px;">Your <t t-esc="model_description or 'document'"/></span><br/>
<span style="font-size: 20px; font-weight: bold;">
<t t-esc="message.record_name and message.record_name.replace('/','-') or ''"/>
</span>
</td><td valign="middle" align="right">
<img t-att-src="'/logo.png?company=%s' % (company.id or 0)" style="padding: 0px; margin: 0px; height: 48px;" t-att-alt="'%s' % company.name"/>
</td></tr>
<tr><td colspan="2" style="text-align:center;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin:4px 0px 32px 0px;"/>
</td></tr>
</table>
</td>
</tr>
<!-- CONTENT -->
<tr>
<td style="min-width: 590px;">
<t t-raw="message.body"/>
<div style="margin: 32px 0px 32px 0px; text-align: center;">
<a t-att-href="record.channel_id.website_url"
style="background-color: #875A7B; padding: 8px 16px 8px 16px; text-decoration: none; color: #fff; border-radius: 5px; font-size:13px;">
Click here to start the course
</a>
</div>
<div style="margin: 0px; padding: 0px; font-size:13px;">
Enjoy this exclusive content !
</div>
<div>&amp;nbsp;</div>
<div t-if="signature" style="font-size: 13px;">
<div t-raw="signature"/>
</div>
</td>
</tr>
<!-- FOOTER -->
<tr>
<td align="center" style="min-width: 590px; padding: 0 8px 0 8px; font-size:11px;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 4px 0px;"/>
<b t-esc="company.name"/><br/>
<div style="color: #999999;">
<t t-esc="company.phone"/>
<t t-if="company.email"> |
<a t-att-href="'mailto:%s' % company.email" style="text-decoration:none; color: #999999;"><t t-esc="company.email"/></a>
</t>
<t t-if="company.website"> |
<a t-att-href="'%s' % company.website" style="text-decoration:none; color: #999999;">
<t t-esc="company.website"/>
</a>
</t>
</div>
</td>
</tr>
</tbody>
</table>
</td></tr>
<!-- POWERED BY -->
<tr><td align="center" style="min-width: 590px;">
Powered by <a target="_blank" href="https://www.odoo.com?utm_source=db&amp;utm_medium=email" style="color: #875A7B;">Odoo</a>
</td></tr>
</table>
</template>
</data>
</odoo>
@@ -8,7 +8,7 @@ from dateutil.relativedelta import relativedelta
from odoo import api, fields, models, tools, _
from odoo.addons.http_routing.models.ir_http import slug
from odoo.exceptions import UserError, AccessError
from odoo.exceptions import AccessError
from odoo.osv import expression
@@ -476,7 +476,7 @@ class Channel(models.Model):
default_channel_id=self.id,
default_use_template=bool(template),
default_template_id=template and template.id or False,
notif_layout='mail.mail_notification_light',
notif_layout='website_slides.mail_notification_channel_invite',
)
return {
'type': 'ir.actions.act_window',
@@ -18,8 +18,8 @@
class="oe_stat_button"
groups="website_slides.group_website_slides_officer">
<div class="o_field_widget o_stat_info">
<span class="o_stat_value"><field name="total_slides" nolabel="1"/></span>
<span name="total_slides_label" class="o_stat_text">Contents</span>
<span class="o_stat_value"><field name="total_views" nolabel="1"/> Visits</span>
<span class="o_stat_value"><field name="total_slides" nolabel="1"/> Contents</span>
</div>
</button>
<button name="action_redirect_to_done_members"
@@ -45,7 +45,10 @@
class="oe_stat_button"
groups="website_slides.group_website_slides_officer"
attrs="{'invisible': [('allow_comment', '=', False)]}">
<field name="rating_count" string="Reviews" widget="statinfo"/>
<div class="o_field_widget o_stat_info">
<span class="o_stat_value"><field name="rating_avg_stars" nolabel="1"/>/5</span>
<span name="rating_count_label" class="o_stat_text"><field name="rating_count" nolabel="1"/> Reviews</span>
</div>
</button>
<field name="is_published" widget="website_redirect_button"/>
</div>
@@ -53,7 +56,7 @@
<field name="image_1920" widget="image" class="oe_avatar" options="{'preview_image': 'image_128'}"/>
<div class="oe_title">
<label for="name" class="oe_edit_only" string="Course Title"/>
<h1><field name="name" default_focus="1" placeholder="Course Title"/></h1>
<h1><field name="name" default_focus="1" placeholder="Computer Science for kids"/></h1>
</div>
<div>
<field name="active" invisible="1"/>
@@ -61,7 +64,7 @@
</div>
<notebook colspan="4">
<page name="content" string="Content">
<field name="slide_ids" colspan="4" nolabel="1" widget="slide_category_one2many" mode="tree,kanban" context="{'default_channel_id': active_id, 'form_view_ref' : 'website_slides.view_slide_slide_form_wo_channel_id'}">
<field name="slide_ids" string="Content" colspan="4" nolabel="1" widget="slide_category_one2many" mode="tree,kanban" context="{'default_channel_id': active_id, 'form_view_ref' : 'website_slides.view_slide_slide_form_wo_channel_id'}">
<tree decoration-bf="is_category" editable="bottom">
<field name="sequence" widget="handle"/>
<field name="name"/>
@@ -80,8 +83,7 @@
</page>
<page name="description" string="Description">
<group>
<field name="description" colspan="4" />
<field name="description_short" colspan="4" />
<field name="description" colspan="4" placeholder="Common tasks for a computer scientist is asking the right questions and answering questions. In this course, you'll study those topics with activities about mathematics, science and logic."/>
</group>
</page>
<page name="options" string="Options">
@@ -118,33 +120,16 @@
<field name="enroll_msg" colspan="4" nolabel="1"/>
</div>
</page>
<page string="Karma Rules" name="karma_rules">
<page string="Karma" name="karma_rules">
<group>
<field name="karma_gen_channel_rank" string="Rank Course"/>
<field name="karma_gen_channel_finish" string="Finish Course"/>
<field name="karma_review" attrs="{'invisible': [('allow_comment', '!=', True)]}"/>
<field name="karma_slide_comment" attrs="{'invisible': [('allow_comment', '!=', True)]}"/>
<field name="karma_slide_vote" attrs="{'invisible': [('allow_comment', '!=', True)]}"/>
</group>
</page>
<page name="statistics" string="Statistics">
<group>
<group name="statistics_nbr" class="col-4">
<field name="nbr_presentation"/>
<field name="nbr_document"/>
<field name="nbr_video"/>
<field name="nbr_infographic"/>
<field name="nbr_quiz" string="Quizzes"/>
<field name="nbr_webpage"/>
<group string="Rewards">
<field name="karma_gen_channel_rank" string="Review Course"/>
<field name="karma_gen_channel_finish" string="Finish Course"/>
</group>
<group name="view_stats">
<field name="total_views" string="Visits"/>
<field string="Rating" name="rating_avg" widget="field_float_rating"/>
<label for="total_time" string="Watch Time"/>
<div>
<field name="total_time" widget="float_time" />
<span class="ml-2">Hours</span>
</div>
<group string="Access Rights" attrs="{'invisible': [('allow_comment', '!=', True)]}">
<field name="karma_review" attrs="{'invisible': [('allow_comment', '!=', True)]}"/>
<field name="karma_slide_comment" attrs="{'invisible': [('allow_comment', '!=', True)]}"/>
<field name="karma_slide_vote" attrs="{'invisible': [('allow_comment', '!=', True)]}"/>
</group>
</group>
</page>
@@ -185,6 +170,7 @@
<tree string="Courses" create="false" default_order="total_views desc" sample="1">
<field name="name"/>
<field name="total_views"/>
<field name="total_time" widget="float_time" />
<field name="members_count"/>
<field name="total_votes"/>
<field name="rating_avg_stars"/>
@@ -28,7 +28,6 @@ class SlideChannelInvite(models.TransientModel):
partner_ids = fields.Many2many('res.partner', string='Recipients')
# slide channel
channel_id = fields.Many2one('slide.channel', string='Slide channel', required=True)
channel_url = fields.Char(related="channel_id.website_url", readonly=True)
@api.depends('template_id')
def _compute_template_values(self):
@@ -107,10 +106,13 @@ class SlideChannelInvite(models.TransientModel):
except ValueError:
_logger.warning('QWeb template %s not found when sending slide channel mails. Sending without layouting.' % (notif_layout))
else:
# could be great to use _notify_prepare_template_context someday
template_ctx = {
'message': self.env['mail.message'].sudo().new(dict(body=mail_values['body_html'], record_name=self.channel_id.name)),
'model_description': self.env['ir.model']._get('website_slides.slide_channel').display_name,
'model_description': self.env['ir.model']._get('slide.channel').display_name,
'record': slide_channel_partner,
'company': self.env.company,
'signature': self.channel_id.user_id.signature,
}
body = template._render(template_ctx, engine='ir.qweb', minimal_qcontext=True)
mail_values['body_html'] = self.env['mail.render.mixin']._replace_local_links(body)
@@ -22,7 +22,7 @@
<field name="attachment_ids" widget="many2many_binary"/>
</group>
<group>
<field name="template_id" label="Use template"/>
<field name="template_id" label="Use template" context="{'default_model': 'slide.channel.partner'}"/>
</group>
</group>
</group>
@@ -6,12 +6,10 @@
<field name="inherit_id" ref="website_slides.view_slide_channel_form"/>
<field name="arch" type="xml">
<xpath expr="//span[@name='members_done_count_label']" position="replace">
<field name="nbr_certification" invisible="1"/>
<span class="o_stat_text" attrs="{'invisible': [('nbr_certification', '>', 0)]}">Finished</span>
<span class="o_stat_text" attrs="{'invisible': [('nbr_certification', '=', 0)]}">Certified</span>
</xpath>
<xpath expr="//field[@name='nbr_webpage']" position="after">
<field name="nbr_certification" string="Certifications"/>
</xpath>
<xpath expr="//field[@name='slide_type']" position="after">
<field name="survey_id"/>
</xpath>