summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichaël Mattiello <mcm@odoo.com>2019-09-03 09:30:49 +0000
committerThibault Delavallée <tde@odoo.com>2019-09-03 15:02:21 +0000
commit8c9473fd78f14dea1c55765da4f3e55f8962bcc6 (patch)
treedf648c1f8016ed1df17e4005855657e111fa9fd5
parentc4eba6f5b150a0e881b7fb9b935ef1a0c3154bbf (diff)
[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)
-rw-r--r--addons/website_sale_slides/models/slide_channel.py3
-rw-r--r--addons/website_sale_slides/views/slide_channel_views.xml3
-rw-r--r--addons/website_slides/data/mail_data.xml2
-rw-r--r--addons/website_slides/models/slide_channel.py12
-rw-r--r--addons/website_slides/models/slide_question.py6
-rw-r--r--addons/website_slides/models/slide_slide.py18
-rw-r--r--addons/website_slides/static/src/js/slides_upload.js4
-rw-r--r--addons/website_slides/static/src/scss/rating_rating_views.scss4
-rw-r--r--addons/website_slides/static/src/scss/slide_channel_views.scss7
-rw-r--r--addons/website_slides/static/src/scss/slide_views.scss (renamed from addons/website_slides/static/src/scss/category_backend.scss)10
-rw-r--r--addons/website_slides/views/assets.xml3
-rw-r--r--addons/website_slides/views/rating_rating_views.xml64
-rw-r--r--addons/website_slides/views/slide_channel_views.xml46
-rw-r--r--addons/website_slides/views/slide_slide_views.xml44
-rw-r--r--addons/website_slides_survey/views/slide_channel_views.xml4
15 files changed, 141 insertions, 89 deletions
diff --git a/addons/website_sale_slides/models/slide_channel.py b/addons/website_sale_slides/models/slide_channel.py
index 88920f58e55..685e0af9aa0 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 7df803c10d9..4099acf0ffa 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 55628822d44..88c8a45cd5a 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 ee846b3d0d1..49289105cd3 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 98c51585dda..adc871c22e2 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 2a17ade329d..9fda9095129 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 0377abedeb1..37c6245d191 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 49886be92f5..e86a1811c10 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 3bd8203c4eb..00000000000
--- 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
index 99b017738ca..1110a3f9442 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 ed7df5ceb55..b310391042a 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 5446fc76779..4f95b6c7c19 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 7690d6bc469..3a037150c3f 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 46001792f8a..a7130a21567 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 5a783677320..1ff9e02a556 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"/>