From 8c9473fd78f14dea1c55765da4f3e55f8962bcc6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Mattiello?= <mcm@odoo.com>
Date: Tue, 3 Sep 2019 09:30:49 +0000
Subject: [PATCH] [IMP] website_slides_{*}: improve backend UI, views and user
 actions

Purpose of this commit is to perform a back2basics on eLearning backend
views. It helps users in their daily use of eLearning and improve UI.

Containing

  * channel kanban view tweaking;
  * channel form view: some spacing and renaming improvements. Also set
    advanced field (new content email, share template) as group no one;

  * slide kanban view tweaking;
  * removed sections from kanban and list view for contents;
  * contents form view: various improvements, with notably

    * removed field website_url;
    * set publishded date is now readonly, tracked and in group_no_one as
      it is automatically set when publishing the lesson, and people should
      not update it manually;
    * removed the sum "Content" and replaced it by a stat button
    * reword quiz constraint error messages;

  * rating views improvements:
    * revamped the kanban view of rating that were a bit broken;
    * added a pivot view in Reporting/Reviews;
    * updated graph view in Reporting/Reviews;

This commit also provides some usability fixes

  * prevent sending email if new content is category;
  * email: Prevent displaying an image if there is no image;

LINKS

Task 2049640 (website slides back2basics and fiximp)
Task 2058595 (eLearning v13 testing)
---
 .../models/slide_channel.py                   |  3 +-
 .../views/slide_channel_views.xml             |  3 +-
 addons/website_slides/data/mail_data.xml      |  2 +
 addons/website_slides/models/slide_channel.py | 12 ++--
 .../website_slides/models/slide_question.py   |  6 +-
 addons/website_slides/models/slide_slide.py   | 18 ++++--
 .../static/src/js/slides_upload.js            |  4 +-
 .../static/src/scss/rating_rating_views.scss  |  4 ++
 .../static/src/scss/slide_channel_views.scss  |  7 --
 ...category_backend.scss => slide_views.scss} | 10 ++-
 addons/website_slides/views/assets.xml        |  3 +-
 .../views/rating_rating_views.xml             | 64 ++++++++++++++-----
 .../views/slide_channel_views.xml             | 46 +++++++------
 .../views/slide_slide_views.xml               | 44 +++++++------
 .../views/slide_channel_views.xml             |  4 +-
 15 files changed, 141 insertions(+), 89 deletions(-)
 delete mode 100644 addons/website_slides/static/src/scss/slide_channel_views.scss
 rename addons/website_slides/static/src/scss/{category_backend.scss => slide_views.scss} (54%)

diff --git a/addons/website_sale_slides/models/slide_channel.py b/addons/website_sale_slides/models/slide_channel.py
index 88920f58e556..685e0af9aa03 100644
--- a/addons/website_sale_slides/models/slide_channel.py
+++ b/addons/website_sale_slides/models/slide_channel.py
@@ -9,9 +9,10 @@ class Channel(models.Model):
 
     enroll = fields.Selection(selection_add=[('payment', 'On payment')])
     product_id = fields.Many2one('product.product', 'Product', index=True)
-    product_sale_revenues = fields.Float(
+    product_sale_revenues = fields.Monetary(
         string='Total revenues', compute='_compute_product_sale_revenues',
         groups="sales_team.group_sale_salesman")
+    currency_id = fields.Many2one(related='product_id.currency_id')
 
     _sql_constraints = [
         ('product_id_check', "CHECK( enroll!='payment' OR product_id IS NOT NULL )", "Product is required for on payment channels.")
diff --git a/addons/website_sale_slides/views/slide_channel_views.xml b/addons/website_sale_slides/views/slide_channel_views.xml
index 7df803c10d9a..4099acf0ffab 100644
--- a/addons/website_sale_slides/views/slide_channel_views.xml
+++ b/addons/website_sale_slides/views/slide_channel_views.xml
@@ -33,7 +33,8 @@
             <xpath expr="//div[@name='info_total_time']" position="after">
                 <div class="d-flex" attrs="{'invisible': [('enroll', '!=', 'payment')]}">
                     <span class="mr-auto"><label for="product_sale_revenues" class="mb0">Sales</label></span>
-                    <field name="product_sale_revenues"/>
+                    <field name="product_sale_revenues" widget="monetary" options="{'currency_field': 'currency_id'}"/>
+                    <field name="currency_id" attrs="{'invisible': True}"/>
                 </div>
             </xpath>
             <xpath expr="//a[@name='action_channel_invite']" position="attributes">
diff --git a/addons/website_slides/data/mail_data.xml b/addons/website_slides/data/mail_data.xml
index 55628822d441..88c8a45cd5af 100644
--- a/addons/website_slides/data/mail_data.xml
+++ b/addons/website_slides/data/mail_data.xml
@@ -11,11 +11,13 @@
                         Hello<br/><br/>
                         There is something new in the course <strong>${object.channel_id.name}</strong> you are following:<br/><br/>
                         <center><strong>${object.name}</strong></center>
+                        % if object.image_1024
                         <div style="margin: 16px 8px 16px 8px; text-align: center;">
                             <a href="${object.website_url}">
                                 <img alt="${object.name}" src="${ctx['base_url']}/web/image/slide.slide/${object.id}/image_1024" style="height:auto; width:150px; margin: 16px;"/>
                             </a>
                         </div>
+                        % endif
                         <div style="margin: 16px 8px 16px 8px; text-align: center;">
                             <a href="${object.website_url}"
                                 style="background-color: #875a7b; padding: 8px 16px 8px 16px; text-decoration: none; color: #fff; border-radius: 5px;">View content</a>
diff --git a/addons/website_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py
index ee846b3d0d1e..49289105cd32 100644
--- a/addons/website_slides/models/slide_channel.py
+++ b/addons/website_slides/models/slide_channel.py
@@ -106,7 +106,7 @@ class Channel(models.Model):
         ('latest', 'Latest Published'),
         ('most_voted', 'Most Voted'),
         ('most_viewed', 'Most Viewed')],
-        string="Featuring Policy", default='latest', required=True)
+        string="Featured Content", default='latest', required=True)
     access_token = fields.Char("Security Token", copy=False, default=_default_access_token)
     nbr_presentation = fields.Integer('Presentations', compute='_compute_slides_statistics', store=True)
     nbr_document = fields.Integer('Documents', compute='_compute_slides_statistics', store=True)
@@ -130,11 +130,11 @@ class Channel(models.Model):
         help="Email template to send slide publication through email",
         default=lambda self: self.env['ir.model.data'].xmlid_to_res_id('website_slides.slide_template_published'))
     share_template_id = fields.Many2one(
-        'mail.template', string='Shared Template',
+        'mail.template', string='Share Template',
         help="Email template used when sharing a slide",
         default=lambda self: self.env['ir.model.data'].xmlid_to_res_id('website_slides.slide_template_shared'))
     enroll = fields.Selection([
-        ('public', 'Public'), ('invite', 'Invite')],
+        ('public', 'Public'), ('invite', 'On Invitation')],
         default='public', string='Enroll Policy', required=True,
         help='Condition to enroll: everyone, on invite, on payment (sale bridge).')
     enroll_msg = fields.Html(
@@ -142,7 +142,7 @@ class Channel(models.Model):
         default=False, translate=tools.html_translate, sanitize_attributes=False)
     enroll_group_ids = fields.Many2many('res.groups', string='Auto Enroll Groups', help="Members of those groups are automatically added as members of the channel.")
     visibility = fields.Selection([
-        ('public', 'Public'), ('members', 'Members')],
+        ('public', 'Public'), ('members', 'Members Only')],
         default='public', string='Visibility', required=True,
         help='Applied directly as ACLs. Allow to hide channels and their content for non members.')
     partner_ids = fields.Many2many(
@@ -154,7 +154,7 @@ class Channel(models.Model):
     channel_partner_ids = fields.One2many('slide.channel.partner', 'channel_id', string='Members Information', groups='website.group_website_publisher', depends=['partner_ids'])
     upload_group_ids = fields.Many2many(
         'res.groups', 'rel_upload_groups', 'channel_id', 'group_id', string='Upload Groups',
-        help="Who can publish: responsible, members of upload_group_ids if defined or website publisher group members.")
+        help="Group of users allowed to publish contents on a documentation course.")
     # not stored access fields, depending on each user
     completed = fields.Boolean('Done', compute='_compute_user_statistics', compute_sudo=False)
     completion = fields.Integer('Completion', compute='_compute_user_statistics', compute_sudo=False)
@@ -493,7 +493,7 @@ class Channel(models.Model):
     def action_view_slides(self):
         action = self.env.ref('website_slides.slide_slide_action').read()[0]
         action['context'] = {'default_channel_id': self.id}
-        action['domain'] = [('channel_id', "=", self.id)]
+        action['domain'] = [('channel_id', "=", self.id), ('is_category', '=', False)]
         return action
 
     def action_view_ratings(self):
diff --git a/addons/website_slides/models/slide_question.py b/addons/website_slides/models/slide_question.py
index 98c51585dda5..adc871c22e24 100644
--- a/addons/website_slides/models/slide_question.py
+++ b/addons/website_slides/models/slide_question.py
@@ -27,19 +27,19 @@ class SlideQuestion(models.Model):
                 if answer.is_correct:
                     good_answer_count += 1
                     if good_answer_count > 1:
-                        raise ValidationError(_('A question can only have one good answer'))
+                        raise ValidationError(_('Question "%s" can only have one good answer') % question.question)
 
     @api.constrains('answer_ids')
     def _check_correct_answer(self):
         for question in self:
             if not any([answer.is_correct for answer in question.answer_ids]):
-                raise ValidationError(_("A question must at least have one good answer"))
+                raise ValidationError(_('Question "%s" must at least have one good answer') % question.question)
 
     @api.constrains('answer_ids')
     def _check_at_least_2_answers(self):
         for question in self:
             if len(question.answer_ids) < 2:
-                raise ValidationError(_("A question must at least have two possible answers"))
+                raise ValidationError(_('Question "%s" has no valid answer, please set one') % question.question)
 
     @api.depends('slide_id')
     def _compute_statistics(self):
diff --git a/addons/website_slides/models/slide_slide.py b/addons/website_slides/models/slide_slide.py
index 2a17ade329d4..9fda90951297 100644
--- a/addons/website_slides/models/slide_slide.py
+++ b/addons/website_slides/models/slide_slide.py
@@ -59,7 +59,7 @@ class SlideLink(models.Model):
 
     slide_id = fields.Many2one('slide.slide', required=True, ondelete='cascade')
     name = fields.Char('Title', required=True)
-    link = fields.Char('External Link', required=True)
+    link = fields.Char('Link', required=True)
 
 
 class EmbeddedSlide(models.Model):
@@ -123,11 +123,11 @@ class Slide(models.Model):
     description = fields.Text('Description', translate=True)
     channel_id = fields.Many2one('slide.channel', string="Channel", required=True)
     tag_ids = fields.Many2many('slide.tag', 'rel_slide_tag', 'slide_id', 'tag_id', string='Tags')
-    is_preview = fields.Boolean('Is Preview', default=False, help="The course is accessible by anyone : the users don't need to join the channel to access the content of the course.")
-    completion_time = fields.Float('Completion Time', digits=(10, 4), help="The estimated completion time for this slide")
+    is_preview = fields.Boolean('Allow Preview', default=False, help="The course is accessible by anyone : the users don't need to join the channel to access the content of the course.")
+    completion_time = fields.Float('Duration', digits=(10, 4), help="The estimated completion time for this slide")
     # Categories
     is_category = fields.Boolean('Is a category', default=False)
-    category_id = fields.Many2one('slide.slide', string="Category", compute="_compute_category_id", store=True)
+    category_id = fields.Many2one('slide.slide', string="Section", compute="_compute_category_id", store=True)
     slide_ids = fields.One2many('slide.slide', "category_id", string="Slides")
     # subscribers
     partner_ids = fields.Many2many('res.partner', 'slide_slide_partner', 'slide_id', 'partner_id',
@@ -138,6 +138,7 @@ class Slide(models.Model):
         help="Subscriber information for the current logged in user")
     # Quiz related fields
     question_ids = fields.One2many("slide.question", "slide_id", string="Questions")
+    questions_count = fields.Integer(string="Numbers of Questions", compute='_compute_questions_count')
     quiz_first_attempt_reward = fields.Integer("First attempt reward", default=10)
     quiz_second_attempt_reward = fields.Integer("Second attempt reward", default=7)
     quiz_third_attempt_reward = fields.Integer("Third attempt reward", default=5,)
@@ -161,7 +162,7 @@ class Slide(models.Model):
     html_content = fields.Html("HTML Content", help="Custom HTML content for slides of type 'Web Page'.", translate=True)
     # website
     website_id = fields.Many2one(related='channel_id.website_id', readonly=True)
-    date_published = fields.Datetime('Publish Date')
+    date_published = fields.Datetime('Publish Date', readonly=True, tracking=True)
     likes = fields.Integer('Likes', compute='_compute_user_info', store=True, compute_sudo=False)
     dislikes = fields.Integer('Dislikes', compute='_compute_user_info', store=True, compute_sudo=False)
     user_vote = fields.Integer('User vote', compute='_compute_user_info', compute_sudo=False)
@@ -214,6 +215,11 @@ class Slide(models.Model):
                 elif slide.category_id != current_category:
                     slide.category_id = current_category.id
 
+    @api.depends('question_ids')
+    def _compute_questions_count(self):
+        for slide in self:
+            slide.questions_count = len(slide.question_ids)
+
     @api.depends('website_message_ids.res_id', 'website_message_ids.model', 'website_message_ids.message_type')
     def _compute_comments_count(self):
         for slide in self:
@@ -393,7 +399,7 @@ class Slide(models.Model):
 
         slide = super(Slide, self).create(values)
 
-        if slide.is_published:
+        if slide.is_published and not slide.is_category:
             slide._post_publication()
         return slide
 
diff --git a/addons/website_slides/static/src/js/slides_upload.js b/addons/website_slides/static/src/js/slides_upload.js
index 0377abedeb15..37c6245d1910 100644
--- a/addons/website_slides/static/src/js/slides_upload.js
+++ b/addons/website_slides/static/src/js/slides_upload.js
@@ -74,13 +74,13 @@ var SlideUploadDialog = Dialog.extend({
         this.$('.alert-warning').remove();
     },
     /**
-     * Category and tags management from select2
+     * Section and tags management from select2
      *
      * @private
      */
     _bindSelect2Dropdown: function () {
         var self = this;
-        this.$('#category_id').select2(this._select2Wrapper(_t('Category'), false,
+        this.$('#category_id').select2(this._select2Wrapper(_t('Section'), false,
             function () {
                 return self._rpc({
                     route: '/slides/category/search_read',
diff --git a/addons/website_slides/static/src/scss/rating_rating_views.scss b/addons/website_slides/static/src/scss/rating_rating_views.scss
index 49886be92f55..e86a1811c10b 100644
--- a/addons/website_slides/static/src/scss/rating_rating_views.scss
+++ b/addons/website_slides/static/src/scss/rating_rating_views.scss
@@ -7,5 +7,9 @@ $o-kanban-large-record-width: 350px;
 
     .o_slide_rating_kanban_left {
     	min-width: 80px;
+
+    	.o_slide_rating_value {
+    	    font-size: 4rem;
+    	}
     }
 }
diff --git a/addons/website_slides/static/src/scss/slide_channel_views.scss b/addons/website_slides/static/src/scss/slide_channel_views.scss
deleted file mode 100644
index 3bd8203c4eb0..000000000000
--- a/addons/website_slides/static/src/scss/slide_channel_views.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-$o-kanban-large-record-width: 400px;
-
-.o_kanban_view.o_slide_channel_kanban {
-    .o_kanban_record {
-    	width: $o-kanban-large-record-width
-    }
-}
diff --git a/addons/website_slides/static/src/scss/category_backend.scss b/addons/website_slides/static/src/scss/slide_views.scss
similarity index 54%
rename from addons/website_slides/static/src/scss/category_backend.scss
rename to addons/website_slides/static/src/scss/slide_views.scss
index 99b017738cae..1110a3f94424 100644
--- a/addons/website_slides/static/src/scss/category_backend.scss
+++ b/addons/website_slides/static/src/scss/slide_views.scss
@@ -1,6 +1,14 @@
+$o-kanban-large-record-width: 400px;
+
+.o_kanban_view.o_slide_kanban {
+    .o_kanban_record {
+    	width: $o-kanban-large-record-width
+    }
+}
+
 table.o_section_list_view tr.o_data_row.o_is_section {
     font-weight: bold;
     background-color: #DDD;
     border-top: 1px solid #BBB;
     border-bottom: 1px solid #BBB;
-}
\ No newline at end of file
+}
diff --git a/addons/website_slides/views/assets.xml b/addons/website_slides/views/assets.xml
index ed7df5ceb550..b310391042a4 100644
--- a/addons/website_slides/views/assets.xml
+++ b/addons/website_slides/views/assets.xml
@@ -4,8 +4,7 @@
         <template id="assets_backend" inherit_id="web.assets_backend" name="Slides Backend Assets">
             <xpath expr="." position="inside">
                 <link rel="stylesheet" type="text/scss" href="/website_slides/static/src/scss/rating_rating_views.scss"/>
-                <link rel="stylesheet" type="text/scss" href="/website_slides/static/src/scss/slide_channel_views.scss"/>
-                <link rel="stylesheet" type="text/scss" href="/website_slides/static/src/scss/category_backend.scss" t-ignore="true"/>
+                <link rel="stylesheet" type="text/scss" href="/website_slides/static/src/scss/slide_views.scss"/>
                 <script type="text/javascript" src="/website_slides/static/src/js/slide_category_one2many.js"/>
                 <script type="text/javascript" src="/website_slides/static/src/js/rating_field_backend.js"/>
             </xpath>
diff --git a/addons/website_slides/views/rating_rating_views.xml b/addons/website_slides/views/rating_rating_views.xml
index 5446fc767795..4f95b6c7c19d 100644
--- a/addons/website_slides/views/rating_rating_views.xml
+++ b/addons/website_slides/views/rating_rating_views.xml
@@ -18,14 +18,15 @@
                         <t t-set="empty_star" t-value="5 - (val_integer + Math.ceil(val_decimal))"/>
                         <div class="oe_kanban_card oe_kanban_global_click">
                             <div class="d-flex flex-row">
-                                <div class="o_slide_rating_kanban_left">
+                                <div class="o_slide_rating_kanban_left mr-3">
+                                    <h1 class="o_slide_rating_value text-center text-primary" t-esc="val_stars"/>
                                     <t t-foreach="_.range(0, val_integer)" t-as="num">
-                                        <i class="fa fa-star" role="img" aria-label="One star" title="One star"></i>
+                                        <i class="fa fa-star" role="img"></i>
                                     </t>
                                     <t t-if="val_decimal">
-                                        <i class="fa fa-star-half-o" role="img" aria-label="Half a star" title="Half a star"></i>
+                                        <i class="fa fa-star-half-o" role="img"></i>
                                     </t>
-                                    <t t-foreach="_.range(0, empty_star)" t-as="num" role="img" t-attf-aria-label="#{empty_star} on 5" t-attf-title="#{empty_star} on 5">
+                                    <t t-foreach="_.range(0, empty_star)" t-as="num" role="img">
                                         <i class="fa fa-star text-black-25"></i>
                                     </t>
                                 </div>
@@ -36,14 +37,14 @@
                                         </div>
                                     </div>
                                     <div class="o_kanban_card_content mt0 d-flex flex-column">
-                                        <span>for
+                                        <span>
+                                            <i class="fa fa-folder mr-2"></i>
                                             <a type="object" name="action_open_rated_object" t-att-title="record.res_name.raw_value">
                                                 <field name="res_name" />
                                             </a>
                                         </span>
-                                        <span><i class="fa fa-clock-o mr-2"/>on <field name="create_date" /></span>
+                                        <span><i class="fa fa-clock-o mr-2"/> <field name="create_date" /></span>
                                         <div class="d-flex mt-2">
-                                            <i t-if="record.feedback.raw_value" class="fa fa-comment mr-2" t-att-title="record.feedback.raw_value"  t-att-aria-label="record.feedback.raw_value" role="img"/>
                                             <span t-esc="record.feedback.raw_value"/>
                                         </div>
                                     </div>
@@ -74,19 +75,32 @@
     </record>
 
     <record id="rating_rating_view_graph_slide_channel" model="ir.ui.view">
-       <field name="name">rating.rating.graph</field>
-       <field name="model">rating.rating</field>
-       <field name="priority">20</field>
-       <field name="arch" type="xml">
-            <graph string="Rating Average" type="bar" stacked="False">
+        <field name="name">rating.rating.view.graph.slides</field>
+        <field name="model">rating.rating</field>
+        <field name="priority">20</field>
+        <field name="arch" type="xml">
+            <graph string="Rating Average" type="bar">
                 <field name="res_name" type="row"/>
-                <field name="rating" type="col"/>
+                <field name="rating" type="measure"/>
             </graph>
         </field>
     </record>
 
+    <record id="rating_rating_view_pivot_slide_channel" model="ir.ui.view">
+        <field name="name">rating.rating.view.pivot.slides</field>
+        <field name="model">rating.rating</field>
+        <field name="priority">20</field>
+        <field name="arch" type="xml">
+            <pivot>
+                <field name="res_name" type="row"/>
+                <field name="rating_text" type="col"/>
+                <field name="rating" type="measure"/>
+            </pivot>
+        </field>
+    </record>
+
     <record id="rating_rating_action_slide_channel" model="ir.actions.act_window">
-        <field name="name">Courses Rating</field>
+        <field name="name">Rating</field>
         <field name="res_model">rating.rating</field>
         <field name="view_mode">kanban,tree,graph,pivot,form</field>
         <field name="domain">[('consumed', '=', True), ('res_model', '=', 'slide.channel')]</field>
@@ -101,17 +115,33 @@
     </record>
 
     <record id="rating_rating_action_slide_channel_report" model="ir.actions.act_window">
-        <field name="name">Courses Rating</field>
+        <field name="name">Rating</field>
         <field name="res_model">rating.rating</field>
-        <field name="view_mode">graph,tree</field>
         <field name="domain">[('consumed', '=', True), ('res_model', '=', 'slide.channel')]</field>
         <field name="context">{}</field>
         <field name="search_view_id" ref="rating_rating_view_search_slide_channel"/>
-        <field name="view_id" ref="rating_rating_view_graph_slide_channel"/>
         <field name="help" type="html">
             <p class="o_view_nocontent_empty_folder">
                 There is no rating for these courses at the moment
             </p>
         </field>
     </record>
+    <record id="rating_rating_action_slide_channel_report_view_graph" model="ir.actions.act_window.view">
+        <field name="act_window_id" ref="rating_rating_action_slide_channel_report"/>
+        <field name="sequence">1</field>
+        <field name="view_mode">graph</field>
+        <field name="view_id" ref="rating_rating_view_graph_slide_channel"/>
+    </record>
+    <record id="rating_rating_action_slide_channel_report_view_pivot" model="ir.actions.act_window.view">
+        <field name="act_window_id" ref="rating_rating_action_slide_channel_report"/>
+        <field name="sequence">2</field>
+        <field name="view_mode">pivot</field>
+        <field name="view_id" ref="rating_rating_view_pivot_slide_channel"/>
+    </record>
+    <record id="rating_rating_action_slide_channel_report_view_tree" model="ir.actions.act_window.view">
+        <field name="act_window_id" ref="rating_rating_action_slide_channel_report"/>
+        <field name="sequence">3</field>
+        <field name="view_mode">tree</field>
+        <field name="view_id" eval="False"/>
+    </record>
 </odoo>
diff --git a/addons/website_slides/views/slide_channel_views.xml b/addons/website_slides/views/slide_channel_views.xml
index 7690d6bc469a..3a037150c3f4 100644
--- a/addons/website_slides/views/slide_channel_views.xml
+++ b/addons/website_slides/views/slide_channel_views.xml
@@ -3,7 +3,7 @@
     <data>
         <!-- SLIDE.CHANNEL VIEWS -->
         <record model="ir.ui.view" id="view_slide_channel_form">
-            <field name="name">slide.channel.form</field>
+            <field name="name">slide.channel.view.form</field>
             <field name="model">slide.channel</field>
             <field name="arch" type="xml">
                 <form string="Channels">
@@ -12,6 +12,16 @@
                     </header>
                     <sheet>
                         <div class="oe_button_box" name="button_box">
+                            <button name="action_view_slides"
+                                type="object"
+                                icon="fa-files-o"
+                                class="oe_stat_button"
+                                groups="website.group_website_publisher">
+                                <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>
+                                </div>
+                            </button>
                             <button name="action_redirect_to_done_members"
                                 type="object"
                                 icon="fa-trophy"
@@ -19,7 +29,7 @@
                                 groups="website.group_website_publisher">
                                 <div class="o_field_widget o_stat_info">
                                     <span class="o_stat_value"><field name="members_done_count" nolabel="1"/></span>
-                                    <span name="stat_label" class="o_stat_text">Finished</span>
+                                    <span name="members_done_count_label" class="o_stat_text">Finished</span>
                                 </div>
                             </button>
                             <button name="action_redirect_to_members"
@@ -45,12 +55,11 @@
                             <label for="name" class="oe_edit_only" string="Course Title"/>
                             <h1><field name="name" default_focus="1" placeholder="Course Title"/></h1>
                         </div>
-                        <group>
-                            <group>
-                                <field name="active" invisible="1"/>
-                                <field name="tag_ids" widget="many2many_tags" placeholder="Tags"/>
-                            </group>
-                        </group>
+                        <div>
+                            <field name="active" invisible="1"/>
+                            <label for="tag_ids"/>
+                            <field name="tag_ids" widget="many2many_tags" placeholder="Tags"/>
+                        </div>
                         <notebook colspan="4">
                             <page name="content" string="Content">
                                 <field name="slide_ids" colspan="4" nolabel="1" widget="slide_category_one2many" context="{'default_channel_id': active_id}">
@@ -61,7 +70,6 @@
                                         <field name="completion_time" attrs="{'invisible': [('slide_type', '=', 'category')]}"/>
                                         <field name="total_views" attrs="{'invisible': [('slide_type', '=', 'category')]}"/>
                                         <field name="is_category" invisible="1"/>
-
                                         <control>
                                             <create name="add_slide_section" string="Add Section" context="{'default_is_category': True}"/>
                                             <create name="add_slide_lesson" string="Add Content"/>
@@ -81,15 +89,15 @@
                                     </group>
                                     <group name="access_rights" string="Access Rights">
                                         <field name="enroll" widget="radio" options="{'horizontal': true}"/>
-                                        <field name="upload_group_ids" string="New Content" widget="many2many_tags"/>
+                                        <field name="upload_group_ids" widget="many2many_tags" groups="base.group_no_one"/>
                                         <field name="enroll_group_ids" widget="many2many_tags" groups="base.group_no_one"/>
                                     </group>
                                 </group>
                                 <group>
                                     <group name="communication" string="Communication">
                                         <field string="Allow Rating" name="allow_comment"/>
-                                        <field name="publish_template_id" domain="[('model','=','slide.slide')]"/>
-                                        <field name="share_template_id" domain="[('model','=','slide.slide')]"/>
+                                        <field name="publish_template_id" domain="[('model','=','slide.slide')]" groups="base.group_no_one"/>
+                                        <field name="share_template_id" domain="[('model','=','slide.slide')]" groups="base.group_no_one"/>
                                     </group>
                                     <group name="display" string="Display">
                                         <field name="visibility" widget="radio"/>
@@ -119,8 +127,6 @@
                                         <field name="nbr_infographic"/>
                                         <field name="nbr_quiz" string="Quizzes"/>
                                         <field name="nbr_webpage"/>
-                                        <separator/>
-                                        <field name="total_slides"/>
                                     </group>
                                     <group name="view_stats">
                                         <field name="total_views" string="Visits"/>
@@ -202,7 +208,7 @@
             <field name="name">slide.channel.view.kanban</field>
             <field name="model">slide.channel</field>
             <field name="arch" type="xml">
-                <kanban string="eLearning Overview" class="o_emphasize_colors o_kanban_dashboard o_slide_channel_kanban breadcrumb_item active" edit="false">
+                <kanban string="eLearning Overview" class="o_emphasize_colors o_kanban_dashboard o_slide_kanban breadcrumb_item active" edit="false">
                     <field name="color"/>
                     <field name="website_published"/>
                     <templates>
@@ -241,23 +247,21 @@
                                     </div>
                                 </div>
                                 <div class="container o_kanban_card_content mt0">
-                                    <div class="row">
+                                    <div class="row mb16">
                                         <div class="col-6 o_kanban_primary_left">
                                             <button class="btn btn-primary" name="open_website_url" type="object">View course</button>
                                         </div>
                                         <div class="col-6 o_kanban_primary_right">
                                             <div class="d-flex">
-                                                <span class="mr-auto"><label for="rating_avg" class="mb0">Rating</label></span>
-                                                <a name="action_view_ratings" type="object">
-                                                    <field name="rating_count"/><span class="ml-2">reviews</span> (<field name="rating_avg_stars"/>/5)
-                                                </a>
+                                                <a name="action_view_ratings" type="object" class="mr-auto"><field name="rating_count"/> reviews</a>
+                                                <span><field name="rating_avg_stars"/> / 5</span>
                                             </div>
                                             <div class="d-flex">
                                                 <span class="mr-auto"><label for="total_views" class="mb0">Views</label></span>
                                                 <field name="total_views"/>
                                             </div>
                                             <div class="d-flex" name="info_total_time">
-                                                <span class="mr-auto"><label for="total_time" class="mb0">Completion Time</label></span>
+                                                <span class="mr-auto"><label for="total_time" class="mb0">Duration</label></span>
                                                 <field name="total_time" widget="float_time"/>
                                             </div>
                                         </div>
diff --git a/addons/website_slides/views/slide_slide_views.xml b/addons/website_slides/views/slide_slide_views.xml
index 46001792f8ae..a7130a21567e 100644
--- a/addons/website_slides/views/slide_slide_views.xml
+++ b/addons/website_slides/views/slide_slide_views.xml
@@ -50,10 +50,10 @@
                         />
                         <div class="oe_title">
                             <div>
-                                <label for="name" string="Name"/>
+                                <label for="name" string="Content Title" class="oe_edit_only"/>
                             </div>
                             <h1>
-                                <field name="name" default_focus="1" placeholder="Title"/>
+                                <field name="name" default_focus="1" placeholder="e.g. How to grow your business with Odoo?"/>
                                 <field name="is_category" invisible="1"/>
                             </h1>
                             <field name="tag_ids" attrs="{'invisible': [('is_category', '=', True)]}" widget="many2many_tags" placeholder="Tags..."/>
@@ -63,6 +63,7 @@
                                 <group>
                                     <group name="lesson_details">
                                         <field name="active" invisible="1"/>
+                                        <field name="channel_id"/>
                                         <field name="slide_type"/>
                                         <field name="url" attrs="{
                                             'required': [('slide_type', 'in', ('video'))],
@@ -74,28 +75,26 @@
                                     </group>
                                     <group name="related_details">
                                         <field name="user_id"/>
-                                        <field name="channel_id"/>
                                         <field name="website_id" groups="website.group_multi_website"/>
-                                        <field name="website_url"/>
                                         <field name="is_preview"/>
-                                        <label for="completion_time" string="Completion Time"/>
+                                        <label for="completion_time"/>
                                         <div>
                                             <field name="completion_time" widget="float_time" class="oe_inline"/>
                                             <span> hours</span>
                                         </div>
-                                        <field name="date_published" string="Published Date"/>
+                                        <field name="date_published" string="Published Date" attrs="{'invisible': [('date_published', '=', False)]}" groups="base.group_no_one"/>
                                     </group>
                                 </group>
                             </page>
                             <page name="description" string="Description">
-                                <field name="description"/>
+                                <field name="description" placeholder="e.g. In this video, we'll give you the keys on how Odoo can help you to grow your business. At the end, we'll propose you a quiz to test your knowledge."/>
                             </page>
                             <page string="External Links" name="external_links" >
                                 <group>
                                     <field name="link_ids" widget="one2many" nolabel="1">
                                         <tree editable="top">
                                             <field name="name"/>
-                                            <field name="link" widget="url"/>
+                                            <field name="link" widget="url" placeholder="e.g. https://www.odoo.com"/>
                                         </tree>
                                     </field>
                                 </group>
@@ -123,15 +122,15 @@
                             <page name="statistics" string="Statistics">
                                 <group>
                                     <group name="view_statistics" string="Views">
-                                        <field string="Member views" name="slide_views"/>
-                                        <field string="Public views" name="public_views" readonly="1"/>
-                                        <field string="Total views" name="total_views"/>
+                                        <field string="Member" name="slide_views"/>
+                                        <field string="Public" name="public_views" readonly="1"/>
+                                        <field string="Total" name="total_views"/>
                                         <hr attrs="{'invisible': [('channel_allow_comment', '!=', True), ('channel_type', '=', 'training')]}"/>
                                         <field name="channel_type" invisible="1" readonly="1"/>
                                         <field name="channel_allow_comment" invisible="1" readonly="1"/>
                                         <field name="likes" attrs="{'invisible': [('channel_type', '=', 'training')]}"/>
                                         <field name="dislikes" attrs="{'invisible': [('channel_type', '=', 'training')]}"/>
-                                        <field name="comments_count" attrs="{'invisible': [('channel_allow_comment', '!=', True)]}"/>
+                                        <field name="comments_count" string="Comments" attrs="{'invisible': [('channel_allow_comment', '!=', True)]}"/>
                                     </group>
                                 </group>
                             </page>
@@ -149,10 +148,11 @@
             <field name="name">slide.slide.view.kanban</field>
             <field name="model">slide.slide</field>
             <field name="arch" type="xml">
-                <kanban edit="false">
+                <kanban edit="false" class="o_slide_kanban">
                     <field name="id"/>
                     <field name="channel_id"/>
                     <field name="slide_type"/>
+                    <field name="user_id"/>
                     <templates>
                         <t t-name="kanban-box">
                             <div class="oe_kanban_global_click o_kanban_record_has_image_fill">
@@ -171,21 +171,23 @@
                                 </div>
                                 <div class="oe_kanban_details d-flex flex-column">
                                     <strong class="o_kanban_record_title oe_partner_heading"><field name="display_name"/></strong>
-                                    <div class="o_kanban_tags_section">
+                                    <div class="text-mutex"><field name="channel_id"/></div>
+                                    <div class="o_kanban_tags_section mb-2">
                                         <span class="oe_kanban_list_many2many">
                                             <field name="tag_ids" widget="many2many_tags"/>
                                         </span>
                                     </div>
-                                    <span class="text-primary"><field name="channel_id"/></span>
-                                    <span class="text-primary"><field name="user_id"/></span>
-                                    <div class=" mt-auto d-flex justify-content-between">
-                                        <span class="badge badge-pill">
+                                    <div class="o_kanban_record_bottom mt-auto d-flex justify-content-between align-items-end">
+                                        <span>
                                             <i class="fa fa-clock-o mr-2" aria-label="Duration" role="img" title="Duration"/><field name="completion_time" widget="float_time"/>
                                         </span>
-                                        <span class="badge badge-pill">
+                                        <span>
+                                            <i class="fa fa-question mr-2" aria-label="Number of Questions" role="img" title="Number of Questions"/><field name="questions_count"/>
+                                        </span>
+                                        <span>
                                             <i class="fa fa-eye mr-2" aria-label="Views" role="img" title="Views"/><field name="total_views"/>
                                         </span>
-                                        <span class="badge badge-pill">
+                                        <span>
                                             <t t-if="record.slide_type.raw_value == 'infographic'">
                                                 <i class="fa fa-file-image-o mr-2" aria-label="Infographic" role="img" title="Infographic"/>
                                             </t>
@@ -201,6 +203,7 @@
                                             <t t-else=""><i class="fa fa-file-pdf-o mr-2" aria-label="Document" role="img" title="Document"/></t>
                                             <field name="slide_type"/>
                                         </span>
+                                        <img t-att-src="kanban_image('res.users', 'image_64', record.user_id.raw_value)" t-att-title="record.user_id.value" t-att-alt="record.user_id.value" width="24" height="24" class="oe_kanban_avatar"/>
                                     </div>
                                 </div>
                             </div>
@@ -265,6 +268,7 @@
             <field name="res_model">slide.slide</field>
             <field name="view_mode">kanban,tree,form</field>
             <field name="context"></field>
+            <field name="domain">[('is_category', '=', False)]</field>
             <field name="help" type="html">
                 <p class="o_view_nocontent_smiling_face">
                     Add a new lesson
diff --git a/addons/website_slides_survey/views/slide_channel_views.xml b/addons/website_slides_survey/views/slide_channel_views.xml
index 5a7836773200..1ff9e02a5563 100644
--- a/addons/website_slides_survey/views/slide_channel_views.xml
+++ b/addons/website_slides_survey/views/slide_channel_views.xml
@@ -5,12 +5,12 @@
         <field name="model">slide.channel</field>
         <field name="inherit_id" ref="website_slides.view_slide_channel_form"/>
         <field name="arch" type="xml">
-            <xpath expr="//span[@name='stat_label']" position="replace">
+            <xpath expr="//span[@name='members_done_count_label']" position="replace">
                 <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 string="Certifications" name="nbr_certification"/>
+                <field  name="nbr_certification" string="Certifications"/>
             </xpath>
             <xpath expr="//field[@name='slide_type']" position="after">
                 <field name="survey_id"/>
-- 
GitLab