[IMP] website_slides{_survey}: add slide icon class field
Add a slide icon class field to prevent computing the fa-class icon from the slide type in the template everytime we need it. Also, using a template wasn't suitable anymore as we may need the icon outside of its own <i> tag (see slide_sidebar_done_button). Task-3378180 closes odoo/odoo#125859 Related: odoo/upgrade#4802 Signed-off-by: Warnon Aurélien (awa) <awa@odoo.com>
This commit is contained in:
@@ -183,6 +183,7 @@ class Slide(models.Model):
|
||||
image_google_url = fields.Char('Image Link', related='url', readonly=False,
|
||||
help="Link of the image (we currently only support Google Drive as source)")
|
||||
# content - documents
|
||||
slide_icon_class = fields.Char('Slide Icon fa-class', compute='_compute_slide_icon_class')
|
||||
slide_type = fields.Selection([
|
||||
('image', 'Image'),
|
||||
('article', 'Article'),
|
||||
@@ -401,6 +402,23 @@ class Slide(models.Model):
|
||||
filtered_slides = category.slide_ids.filtered(lambda slide: slide.is_published)
|
||||
category.completion_time = sum(filtered_slides.mapped("completion_time"))
|
||||
|
||||
@api.depends('slide_type')
|
||||
def _compute_slide_icon_class(self):
|
||||
icon_per_slide_type = {
|
||||
'image': 'fa-file-picture-o',
|
||||
'article': 'fa-file-text-o',
|
||||
'quiz': 'fa-question-circle-o',
|
||||
'pdf': 'fa-file-pdf-o',
|
||||
'sheet': 'fa-file-excel-o',
|
||||
'doc': 'fa-file-word-o',
|
||||
'slides': 'fa-file-powerpoint-o',
|
||||
'youtube_video': 'fa-youtube-play',
|
||||
'google_drive_video': 'fa-play-circle-o',
|
||||
'vimeo_video': 'fa-vimeo',
|
||||
}
|
||||
for slide in self:
|
||||
slide.slide_icon_class = icon_per_slide_type.get(slide.slide_type, 'fa-file-o')
|
||||
|
||||
@api.depends('slide_category', 'source_type', 'video_source_type')
|
||||
def _compute_slide_type(self):
|
||||
""" For 'local content' or specific slide categories, the slide type is directly derived
|
||||
|
||||
@@ -63,7 +63,7 @@ export const SlideCoursePage = publicWidget.Widget.extend({
|
||||
|
||||
const newButton = QWeb.render('website.slides.sidebar.done.button', {
|
||||
slideId: slide.id,
|
||||
slideIcon: $button.data('slideIcon') ?? 'fa-file-o',
|
||||
uncompletedIcon: $button.data('uncompletedIcon') ?? 'fa-circle-thin',
|
||||
slideCompleted: completed,
|
||||
canSelfMarkUncompleted: slide.canSelfMarkUncompleted,
|
||||
canSelfMarkCompleted: slide.canSelfMarkCompleted,
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
<t t-name="website.slides.sidebar.done.button">
|
||||
<div class="o_wslides_sidebar_done_button"
|
||||
t-att-data-id="slideId"
|
||||
t-att-data-slide-icon="slideIcon"
|
||||
t-att-data-uncompleted-icon="uncompletedIcon"
|
||||
t-att-data-completed="slideCompleted"
|
||||
t-att-data-can-self-mark-completed="canSelfMarkCompleted"
|
||||
t-att-data-can-self-mark-uncompleted="canSelfMarkUncompleted"
|
||||
t-att-data-is-member="isMember"> <!-- The template is only used for members -->
|
||||
<button class="o_wslides_button_complete btn btn-sm" t-if="slideCompleted and canSelfMarkUncompleted or !slideCompleted and canSelfMarkCompleted">
|
||||
<i t-if="slideCompleted" class="o_wslides_slide_completed fa fa-check-circle fa-fw text-success fa-lg" t-att-data-slide-id="slideId" title="Mark as not done"/>
|
||||
<i t-else="" t-attf-class="fa #{slideIcon or 'fa-circle-thin'} fa-fw fa-lg" t-att-data-slide-id="slideId" title="Mark as done"/>
|
||||
<i t-else="" t-attf-class="fa #{uncompletedIcon or 'fa-circle-thin'} fa-fw fa-lg" t-att-data-slide-id="slideId" title="Mark as done"/>
|
||||
</button>
|
||||
<button class="o_wslides_button_complete btn btn-sm" t-else="" disabled="1">
|
||||
<i t-if="slideCompleted" class="o_wslides_slide_completed fa fa-check fa-fw text-success fa-lg" t-att-data-slide-id="slideId" title="Can not be marked as not done"/>
|
||||
<i t-else="" t-attf-class="fa #{slideIcon or 'fa-circle-thin'} fa-fw fa-lg" t-att-data-slide-id="slideId" title="Can not be marked as done"/>
|
||||
<i t-else="" t-attf-class="fa #{uncompletedIcon or 'fa-circle-thin'} fa-fw fa-lg" t-att-data-slide-id="slideId" title="Can not be marked as done"/>
|
||||
</button>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -595,9 +595,7 @@
|
||||
<div t-if="channel.can_publish" class=" o_wslides_slides_list_drag m-2 o_not_editable">
|
||||
<i class="fa fa-sort"></i>
|
||||
</div>
|
||||
<t t-call="website_slides.slide_icon">
|
||||
<t t-set="icon_class" t-value="'py-2 mx-2'"/>
|
||||
</t>
|
||||
<i t-attf-class="fa #{slide.slide_icon_class} py-2 mx-2"/>
|
||||
<div class="text-truncate me-auto">
|
||||
<a t-if="not invite_preview and (slide.is_preview or channel.is_member or channel.can_publish)" class="o_wslides_js_slides_list_slide_link" t-attf-href="/slides/slide/#{slug(slide)}">
|
||||
<span t-field="slide.name"/>
|
||||
@@ -631,6 +629,7 @@
|
||||
<t t-call="website_slides.slide_sidebar_done_button">
|
||||
<t t-set="is_member" t-value="channel.is_member"/>
|
||||
<t t-set="slide_completed" t-value="channel_progress[slide.id].get('completed')"/>
|
||||
<t t-set="use_slide_icon" t-value="False"/>
|
||||
</t>
|
||||
<span t-if="channel.can_publish" class="d-none d-md-flex">
|
||||
<a t-if="slide.slide_category == 'article'" class="mx-2 o_text_link text-primary o_not_editable" target="_blank" t-attf-href="/slides/slide/#{slug(slide)}?enable_editor=1"><span class="fa fa-pencil"/></a>
|
||||
@@ -892,19 +891,4 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="slide_icon">
|
||||
<t t-set="icon_class" t-value="icon_class if icon_class else 'me-2 text-muted'"/>
|
||||
<i t-if="slide.slide_type == 'pdf'" t-att-class="'fa fa-file-pdf-o %s' % icon_class"></i>
|
||||
<i t-if="slide.slide_type == 'sheet'" t-att-class="'fa fa-file-excel-o %s' % icon_class"></i>
|
||||
<i t-if="slide.slide_type == 'doc'" t-att-class="'fa fa-file-word-o %s' % icon_class"></i>
|
||||
<i t-if="slide.slide_type == 'slides'" t-att-class="'fa fa-file-powerpoint-o %s' % icon_class"></i>
|
||||
<i t-if="slide.slide_type == 'image'" t-att-class="'fa fa-file-picture-o %s' % icon_class"></i>
|
||||
<i t-if="slide.slide_type == 'youtube_video'" t-att-class="'fa fa-youtube-play %s' % icon_class"></i>
|
||||
<i t-if="slide.slide_type == 'google_drive_video'" t-att-class="'fa fa-play-circle-o %s' % icon_class"></i>
|
||||
<i t-if="slide.slide_type == 'vimeo_video'" t-att-class="'fa fa-vimeo %s' % icon_class"></i>
|
||||
<i t-if="slide.slide_type == 'article'" t-att-class="'fa fa-file-text-o %s' % icon_class"></i>
|
||||
<i t-if="slide.slide_type == 'quiz'" t-att-class="'fa fa-question-circle-o %s' % icon_class"></i>
|
||||
<i t-if="not slide.slide_type" t-att-class="'fa fa-file-o %s' % icon_class"></i>
|
||||
</template>
|
||||
|
||||
</data></odoo>
|
||||
|
||||
@@ -157,20 +157,10 @@
|
||||
<div t-att-class="'o_wslides_lesson_aside_list_link d-flex p-1 %s%s' % (('bg-100 active' if aside_slide == slide else ''), 'text-muted' if not can_access else '')"
|
||||
t-att-data-id="slide.id"
|
||||
t-att-data-completed="slide_completed">
|
||||
<t t-set="slide_icon" t-if="aside_slide.slide_type == 'pdf'" t-value="'fa-file-pdf-o'"/>
|
||||
<t t-set="slide_icon" t-elif="aside_slide.slide_type == 'sheet'" t-value="'fa-file-excel-o'"/>
|
||||
<t t-set="slide_icon" t-elif="aside_slide.slide_type == 'doc'" t-value="'fa-file-word-o'"/>
|
||||
<t t-set="slide_icon" t-elif="aside_slide.slide_type == 'slides'" t-value="'fa-file-powerpoint-o'"/>
|
||||
<t t-set="slide_icon" t-elif="aside_slide.slide_type == 'image'" t-value="'fa-file-picture-o'"/>
|
||||
<t t-set="slide_icon" t-elif="aside_slide.slide_type == 'youtube_video'" t-value="'fa-youtube-play'"/>
|
||||
<t t-set="slide_icon" t-elif="aside_slide.slide_type == 'google_drive_video'" t-value="'fa-play-circle-o'"/>
|
||||
<t t-set="slide_icon" t-elif="aside_slide.slide_type == 'vimeo_video'" t-value="'fa-vimeo'"/>
|
||||
<t t-set="slide_icon" t-elif="aside_slide.slide_type == 'article'" t-value="'fa-file-text-o'"/>
|
||||
<t t-set="slide_icon" t-elif="aside_slide.slide_type == 'quiz'" t-value="'fa-question-circle-o'"/>
|
||||
<t t-set="slide_icon" t-else="" t-value="'fa-file-o'"/>
|
||||
<t t-call="website_slides.slide_sidebar_done_button">
|
||||
<t t-set="slide" t-value="aside_slide"/>
|
||||
<t t-set="slide_completed" t-value="channel_progress[aside_slide.id].get('completed')"/>
|
||||
<t t-set="use_slide_icon" t-value="True"/>
|
||||
</t>
|
||||
<a t-att-href="'/slides/slide/%s' % (slug(aside_slide)) if can_access else '#'"
|
||||
t-attf-class="d-flex text-decoration-none mw-100 overflow-hidden #{'text-muted' if not can_access else ''}">
|
||||
@@ -233,9 +223,7 @@
|
||||
<div class="col-12 col-md order-2 order-md-1 d-flex">
|
||||
<div class="d-flex align-items-start">
|
||||
<h1 class="h4 my-0 d-flex flex_row">
|
||||
<t t-call="website_slides.slide_icon">
|
||||
<t t-set="icon_class" t-valuef="me-2"/>
|
||||
</t>
|
||||
<i t-attf-class="fa #{slide.slide_icon_class} me-2"/>
|
||||
<span t-field="slide.name"/>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
@@ -114,20 +114,10 @@
|
||||
<t t-set="can_access_channel" t-value="is_member or current_slide.channel_id.can_publish"/>
|
||||
<t t-foreach="slides" t-as="slide">
|
||||
<t t-set="slide_completed" t-value="channel_progress[slide.id].get('completed')"/>
|
||||
<t t-set="use_slide_icon" t-value="True"/>
|
||||
<t t-set="can_access" t-value="can_access_channel or slide.is_preview"/>
|
||||
<t t-set="is_member" t-value="current_slide.channel_id.is_member"/>
|
||||
<t t-set="is_member_or_invited" t-value="is_member or current_slide.channel_id.is_member_invited"/>
|
||||
<t t-set="slide_icon" t-if="slide.slide_type == 'pdf'" t-value="'fa-file-pdf-o'"/>
|
||||
<t t-set="slide_icon" t-elif="slide.slide_type == 'sheet'" t-value="'fa-file-excel-o'"/>
|
||||
<t t-set="slide_icon" t-elif="slide.slide_type == 'doc'" t-value="'fa-file-word-o'"/>
|
||||
<t t-set="slide_icon" t-elif="slide.slide_type == 'slides'" t-value="'fa-file-powerpoint-o'"/>
|
||||
<t t-set="slide_icon" t-elif="slide.slide_type == 'image'" t-value="'fa-file-picture-o'"/>
|
||||
<t t-set="slide_icon" t-elif="slide.slide_type == 'youtube_video'" t-value="'fa-youtube-play'"/>
|
||||
<t t-set="slide_icon" t-elif="slide.slide_type == 'google_drive_video'" t-value="'fa-play-circle-o'"/>
|
||||
<t t-set="slide_icon" t-elif="slide.slide_type == 'vimeo_video'" t-value="'fa-vimeo'"/>
|
||||
<t t-set="slide_icon" t-elif="slide.slide_type == 'article'" t-value="'fa-file-text-o'"/>
|
||||
<t t-set="slide_icon" t-elif="slide.slide_type == 'quiz'" t-value="'fa-question-circle-o'"/>
|
||||
<t t-set="slide_icon" t-else="" t-value="'fa-file-o'"/>
|
||||
<li t-attf-class="o_wslides_fs_sidebar_list_item d-flex py-1 #{'active' if slide.id == current_slide.id else ''}"
|
||||
t-att-data-id="slide.id"
|
||||
t-att-data-can-access="can_access"
|
||||
@@ -149,17 +139,15 @@
|
||||
<div class="ms-2 o_wslides_sidebar_content">
|
||||
<a t-if="can_access" class="d-block" href="#">
|
||||
<div class="d-flex">
|
||||
<t t-set="icon_class" t-value="'me-2'"/>
|
||||
<t t-if="is_member" t-call="website_slides.slide_sidebar_done_button"/>
|
||||
<t t-else="" t-call="website_slides.slide_icon"/>
|
||||
<i t-else="" t-attf-class="fa #{slide.slide_icon_class} me-2"/>
|
||||
<div class="o_wslides_fs_slide_name" t-esc="slide.name"/>
|
||||
</div>
|
||||
</a>
|
||||
<span t-else="" class="d-block" href="#">
|
||||
<div class="d-flex">
|
||||
<t t-set="icon_class" t-value="'me-2 text-600'"/>
|
||||
<t t-if="is_member" t-call="website_slides.slide_sidebar_done_button"/>
|
||||
<t t-else="" t-call="website_slides.slide_icon"/>
|
||||
<i t-else="" t-attf-class="fa #{slide.slide_icon_class} me-2 text-600"/>
|
||||
<div class="o_wslides_fs_slide_name text-600" t-esc="slide.name"/>
|
||||
</div>
|
||||
</span>
|
||||
|
||||
@@ -139,21 +139,22 @@
|
||||
|
||||
<!-- Python equivalent of the JS template "website.slides.sidebar.done.button" -->
|
||||
<template id="slide_sidebar_done_button" name="Sidebar Done Button">
|
||||
<t t-set="uncompleted_icon" t-value="use_slide_icon and slide.slide_icon_class or 'fa-circle-thin'"/>
|
||||
<div t-if="is_member"
|
||||
class="o_wslides_sidebar_done_button align-self-start"
|
||||
t-att-data-id="slide.id"
|
||||
t-att-data-slide-icon="slide_icon"
|
||||
t-att-data-uncompleted-icon="uncompleted_icon"
|
||||
t-att-data-completed="slide_completed"
|
||||
t-att-data-can-self-mark-completed="slide.can_self_mark_completed"
|
||||
t-att-data-can-self-mark-uncompleted="slide.can_self_mark_uncompleted"
|
||||
t-att-data-is-member="is_member">
|
||||
<button class="o_wslides_button_complete btn btn-sm" t-if="slide_completed and slide.can_self_mark_uncompleted or not slide_completed and slide.can_self_mark_completed">
|
||||
<i t-if="slide_completed" class="o_wslides_slide_completed fa fa-check-circle fa-fw text-success fa-lg" t-att-data-slide-id="slide.id" title="Mark as not done"/>
|
||||
<i t-else="" t-attf-class="fa #{slide_icon or 'fa-circle-thin'} fa-fw fa-lg" t-att-data-slide-id="slide.id" title="Mark as done"/>
|
||||
<i t-else="" t-attf-class="fa #{uncompleted_icon} fa-fw fa-lg" t-att-data-slide-id="slide.id" title="Mark as done"/>
|
||||
</button>
|
||||
<button class="o_wslides_button_complete o_wslides_button_uncompleted btn btn-sm" t-else="" disabled="1">
|
||||
<i t-if="slide_completed" class="o_wslides_slide_completed fa fa-check fa-fw text-success fa-lg" t-att-data-slide-id="slide.id" title="Can not be marked as not done"/>
|
||||
<i t-else="" t-attf-class="fa #{slide_icon or 'fa-circle-thin'} fa-fw fa-lg" t-att-data-slide-id="slide.id" title="Can not be marked as done"/>
|
||||
<i t-else="" t-attf-class="fa #{uncompleted_icon} fa-fw fa-lg" t-att-data-slide-id="slide.id" title="Can not be marked as done"/>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -65,6 +65,12 @@ class Slide(models.Model):
|
||||
if slide.slide_category == 'certification' or not slide.is_preview:
|
||||
slide.is_preview = False
|
||||
|
||||
@api.depends('slide_type')
|
||||
def _compute_slide_icon_class(self):
|
||||
certification = self.filtered(lambda slide: slide.slide_type == 'certification')
|
||||
certification.slide_icon_class = 'fa-trophy'
|
||||
super(Slide, self - certification)._compute_slide_icon_class()
|
||||
|
||||
@api.depends('slide_category', 'source_type')
|
||||
def _compute_slide_type(self):
|
||||
super(Slide, self)._compute_slide_type()
|
||||
|
||||
@@ -18,12 +18,6 @@
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="slide_icon_inherit_survey" inherit_id="website_slides.slide_icon">
|
||||
<xpath expr="//i[last()]" position="after">
|
||||
<i t-if="slide.slide_type == 'certification'" t-att-class="'fa fa-trophy %s' % icon_class"></i>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="course_slides_list_slide_inherit_survey" inherit_id="website_slides.course_slides_list_slide">
|
||||
<xpath expr="//a[hasclass('o_wslides_js_slides_list_slide_link')]" position="attributes">
|
||||
<attribute name="t-attf-href">#{'/slides_survey/slide/get_certification_url?slide_id=%s' %(slide.id) if slide.slide_category == 'certification' and slide.channel_id.total_slides == 1 else '/slides/slide/%s' %(slug(slide))}</attribute>
|
||||
|
||||
Reference in New Issue
Block a user