[FW][MERGE][FIX] website_{,sale_}slides: fix join/buy links and resource access
This commit fixes * One link that was not updated to use the post_link class * The join course link for "payment" courses after completing the quiz once logged in. * The link to resources that became accessible for non-authorized users for "payment" courses See underlying commits for details. Task-2818136 Part of Task-2663320 closes odoo/odoo#92104 Forward-port-of: odoo/odoo#92055 Forward-port-of: odoo/odoo#88454 Signed-off-by: Warnon Aurélien (awa) <awa@odoo.com> Signed-off-by: Florian Charlier (flch) <flch@odoo.com>
This commit is contained in:
@@ -6,8 +6,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server saas~15.3\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-04-19 13:58+0000\n"
|
||||
"PO-Revision-Date: 2022-04-19 13:58+0000\n"
|
||||
"POT-Creation-Date: 2022-05-20 12:45+0000\n"
|
||||
"PO-Revision-Date: 2022-05-20 12:45+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -272,5 +272,5 @@ msgstr ""
|
||||
|
||||
#. module: website_sale_slides
|
||||
#: model_terms:ir.ui.view,arch_db:website_sale_slides.course_buy_course_link
|
||||
msgid "to download resources"
|
||||
msgid "to access resources"
|
||||
msgstr ""
|
||||
|
||||
@@ -29,9 +29,10 @@ CourseJoinWidget.include({
|
||||
ev.preventDefault();
|
||||
|
||||
if (this.channel.channelEnroll === 'payment' && !this.publicUser) {
|
||||
const self = this;
|
||||
this.beforeJoin().then(function () {
|
||||
wUtils.sendRequest('/shop/cart/update', {
|
||||
product_id: this.productId,
|
||||
product_id: self.productId,
|
||||
express: 1,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</template>
|
||||
|
||||
<template name="Buy Course To Download Resource" id="slide_aside_training_category_buy_course" inherit_id="website_slides.slide_aside_training_category">
|
||||
<xpath expr="//div[hasclass('o_wslides_js_course_join')]" position="inside">
|
||||
<xpath expr="//div[hasclass('o_wslides_js_course_join') and hasclass('o_wslides_no_access')]" position="inside">
|
||||
<li t-elif="aside_slide.channel_id.enroll == 'payment'" class="text-decoration-none small">
|
||||
<i class="fa fa-download mr-1"/>
|
||||
<t t-call="website_sale_slides.course_buy_course_link">
|
||||
@@ -25,7 +25,7 @@
|
||||
</template>
|
||||
|
||||
<template name="Buy Course To Download Resource Slide Detail" id="slide_content_detailed_buy_course" inherit_id="website_slides.slide_content_detailed">
|
||||
<xpath expr="//div[hasclass('o_wslides_js_course_join')]" position="inside">
|
||||
<xpath expr="//div[hasclass('o_wslides_js_course_join') and hasclass('o_wslides_no_access')]" position="inside">
|
||||
<span t-elif="slide.channel_id.enroll == 'payment'" class="text-muted mr-auto border-left pl-3">
|
||||
<t t-call="website_sale_slides.course_buy_course_link"/>
|
||||
</span>
|
||||
@@ -59,7 +59,7 @@
|
||||
</template>
|
||||
|
||||
<template name="Buy Course To Download Resource Fullscreen" id="slide_fullscreen_sidebar_category_buy_course" inherit_id="website_slides.slide_fullscreen_sidebar_category">
|
||||
<xpath expr="//div[hasclass('o_wslides_js_course_join')]" position="inside">
|
||||
<xpath expr="//div[hasclass('o_wslides_js_course_join') and hasclass('o_wslides_no_access')]" position="inside">
|
||||
<li t-elif="slide.channel_id.enroll == 'payment'" class="o_wslides_fs_slide_link mb-1">
|
||||
<i class="fa fa-download mr-1"/>
|
||||
<t t-call="website_sale_slides.course_buy_course_link"/>
|
||||
@@ -79,10 +79,8 @@
|
||||
|
||||
<!-- TOOLS -->
|
||||
<template name="Buy Course Link" id="course_buy_course_link">
|
||||
<a t-att-href="'/shop/cart/update?product_id=%s' % slide.channel_id.product_id.id">
|
||||
Buy Course
|
||||
</a>
|
||||
to download resources
|
||||
<a class="post_link" t-att-href="'/shop/cart/update?product_id=%s' % slide.channel_id.product_id.id">
|
||||
Buy Course</a> to access resources
|
||||
</template>
|
||||
|
||||
<template name="Buy Course Button" id="course_buy_course_button">
|
||||
|
||||
@@ -6,8 +6,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server saas~15.3\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-04-19 13:57+0000\n"
|
||||
"PO-Revision-Date: 2022-04-19 13:57+0000\n"
|
||||
"POT-Creation-Date: 2022-05-20 12:38+0000\n"
|
||||
"PO-Revision-Date: 2022-05-20 12:38+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -628,6 +628,14 @@ msgstr ""
|
||||
msgid "<span class=\"text-500 mx-2\">•</span>"
|
||||
msgstr ""
|
||||
|
||||
#. module: website_slides
|
||||
#: model_terms:ir.ui.view,arch_db:website_slides.slide_content_detailed
|
||||
msgid ""
|
||||
"<span class=\"text-muted font-weight-bold mr-3\">\n"
|
||||
" Additional Resources\n"
|
||||
" </span>"
|
||||
msgstr ""
|
||||
|
||||
#. module: website_slides
|
||||
#: model_terms:ir.ui.view,arch_db:website_slides.slide_content_detailed
|
||||
msgid "<span class=\"text-muted font-weight-bold mr-3\">External sources</span>"
|
||||
@@ -5650,7 +5658,7 @@ msgstr ""
|
||||
|
||||
#. module: website_slides
|
||||
#: model_terms:ir.ui.view,arch_db:website_slides.join_course_link
|
||||
msgid "to download resources"
|
||||
msgid "to access resources"
|
||||
msgstr ""
|
||||
|
||||
#. module: website_slides
|
||||
|
||||
@@ -300,6 +300,13 @@ class Slide(models.Model):
|
||||
for slide in self:
|
||||
slide.questions_count = len(slide.question_ids)
|
||||
|
||||
def _has_additional_resources(self, resource_type=None):
|
||||
"""Sudo required for public user to know if the course has additional
|
||||
resources that they will be able to access once a member."""
|
||||
self.ensure_one()
|
||||
domain = [('resource_type', '=', resource_type)] if resource_type else []
|
||||
return bool(self.sudo().slide_resource_ids.filtered_domain(domain))
|
||||
|
||||
@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:
|
||||
|
||||
@@ -21,7 +21,9 @@ access_slide_channel_partners_all,slide.channel.users.all,model_slide_channel_pa
|
||||
access_slide_channel_partners_system,slide.channel.users.system,model_slide_channel_partner,website_slides.group_website_slides_officer,1,1,1,1
|
||||
access_slide_embed_all,slide.embed.all,model_slide_embed,,1,0,0,0
|
||||
access_slide_embed_user,slide.embed.user,model_slide_embed,base.group_user,1,1,1,1
|
||||
access_slide_slide_resource_all,slide.slide.resource.all,model_slide_slide_resource,,1,0,0,0
|
||||
access_slide_slide_resource_all,slide.slide.resource.all,model_slide_slide_resource,,0,0,0,0
|
||||
access_slide_slide_resource_public,slide.slide.resource.public,model_slide_slide_resource,base.group_public,0,0,0,0
|
||||
access_slide_slide_resource_portal,slide.slide.resource.portal,model_slide_slide_resource,base.group_portal,1,0,0,0
|
||||
access_slide_slide_resource_internal,slide.slide.resource.internal,model_slide_slide_resource,base.group_user,1,0,0,0
|
||||
access_slide_slide_resource_publisher,slide.slide.resource.publisher,model_slide_slide_resource,website_slides.group_website_slides_officer,1,1,1,1
|
||||
access_slide_channel_invite,access.slide.channel.invite,model_slide_channel_invite,base.group_user,1,1,1,0
|
||||
|
||||
|
@@ -189,7 +189,7 @@
|
||||
|
||||
<!--SLIDE RESOURCE-->
|
||||
<record id="rule_slide_slide_resource_downloadable" model="ir.rule">
|
||||
<field name="name">Resource: restricted to channel members and channel responsible</field>
|
||||
<field name="name">Resource: read restricted to channel members and channel responsible</field>
|
||||
<field name="model_id" ref="model_slide_slide_resource"/>
|
||||
<field name="domain_force">[('slide_id.channel_id.partner_ids', '=', user.partner_id.id)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_portal')), (4, ref('base.group_user'))]"/>
|
||||
@@ -199,6 +199,28 @@
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="rule_slide_slide_resource_officer_read" model="ir.rule">
|
||||
<field name="name">Resource: officer: read all</field>
|
||||
<field name="model_id" ref="model_slide_slide_resource"/>
|
||||
<field name="domain_force">[(1, '=', 1)]</field>
|
||||
<field name="groups" eval="[(4, ref('group_website_slides_officer'))]"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="False"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="rule_slide_slide_resource_officer_crud" model="ir.rule">
|
||||
<field name="name">Resource: officer: crud own only</field>
|
||||
<field name="model_id" ref="model_slide_slide_resource"/>
|
||||
<field name="domain_force">[('slide_id.channel_id.user_id', '=', user.id)]</field>
|
||||
<field name="groups" eval="[(4, ref('group_website_slides_officer'))]"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_unlink" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="rule_slide_slide_resource_downloadable_manager" model="ir.rule">
|
||||
<field name="name">Resource: manager: crud all</field>
|
||||
<field name="model_id" ref="model_slide_slide_resource"/>
|
||||
|
||||
@@ -33,8 +33,8 @@ var CourseJoinWidget = publicWidget.Widget.extend({
|
||||
this.channel = options.channel;
|
||||
this.isMember = options.isMember;
|
||||
this.publicUser = options.publicUser;
|
||||
this.joinMessage = options.joinMessage || _t('Join Course'),
|
||||
this.beforeJoin = options.beforeJoin || Promise.resolve();
|
||||
this.joinMessage = options.joinMessage || _t('Join Course');
|
||||
this.beforeJoin = options.beforeJoin || function () {return Promise.resolve();};
|
||||
this.afterJoin = options.afterJoin || function () {document.location.reload();};
|
||||
},
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
import base64
|
||||
|
||||
from odoo.addons.mail.tests.common import mail_new_test_user
|
||||
from odoo.addons.website_slides.tests import common
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.tests import tagged
|
||||
@@ -297,3 +299,69 @@ class TestAccessFeatures(common.SlidesCase):
|
||||
channel_superuser.invalidate_cache(['can_upload', 'can_publish'])
|
||||
self.assertTrue(channel_superuser.can_upload)
|
||||
self.assertTrue(channel_superuser.can_publish)
|
||||
|
||||
@mute_logger('odoo.models.unlink', 'odoo.addons.base.models.ir_rule', 'odoo.addons.base.models.ir_model')
|
||||
def test_resource_access(self):
|
||||
resource_values = {
|
||||
'name': 'Image',
|
||||
'slide_id': self.slide_3.id,
|
||||
'resource_type': 'file',
|
||||
'data': base64.b64encode(b'Some content')
|
||||
}
|
||||
resource1, resource2 = self.env['slide.slide.resource'].with_user(self.user_officer).create(
|
||||
[resource_values for _ in range(2)])
|
||||
resource3 = self.env['slide.slide.resource'].with_user(self.user_officer).create([
|
||||
{'name': 'Link',
|
||||
'slide_id': self.slide_3.id,
|
||||
'resource_type': 'url',
|
||||
'link': 'https://www.odoo.com'}
|
||||
])
|
||||
# No public access to resources
|
||||
with self.assertRaises(AccessError):
|
||||
resource1.with_user(self.user_public).read(['name'])
|
||||
resource3.with_user(self.user_public).read(['name'])
|
||||
|
||||
with self.assertRaises(AccessError):
|
||||
resource1.with_user(self.user_public).write({'name': 'other name'})
|
||||
resource3.with_user(self.user_public).write({'name': 'other name'})
|
||||
|
||||
# public access to knowing if there are resources, also by type
|
||||
self.assertTrue(self.slide_3.with_user(self.user_public)._has_additional_resources())
|
||||
self.assertTrue(self.slide_3.with_user(self.user_public)._has_additional_resources('file'))
|
||||
self.assertTrue(self.slide_3.with_user(self.user_public)._has_additional_resources('url'))
|
||||
|
||||
# No random portal access
|
||||
with self.assertRaises(AccessError):
|
||||
resource1.with_user(self.user_portal).read(['name'])
|
||||
|
||||
# Members can only read
|
||||
self.env['slide.channel.partner'].create({
|
||||
'channel_id': self.channel.id,
|
||||
'partner_id': self.user_portal.partner_id.id,
|
||||
})
|
||||
resource1.with_user(self.user_portal).read(['name'])
|
||||
with self.assertRaises(AccessError):
|
||||
resource1.with_user(self.user_portal).write({'name': 'other name'})
|
||||
|
||||
# Other officers can only read
|
||||
user_officer_other = mail_new_test_user(
|
||||
self.env, name='Ornella Officer', login='user_officer_2', email='officer2@example.com',
|
||||
groups='base.group_user,website_slides.group_website_slides_officer'
|
||||
)
|
||||
resource1.with_user(user_officer_other).read(['name'])
|
||||
with self.assertRaises(AccessError):
|
||||
resource1.with_user(user_officer_other).write({'name': 'Another name'})
|
||||
|
||||
with self.assertRaises(AccessError):
|
||||
self.env['slide.slide.resource'].with_user(user_officer_other).create(resource_values)
|
||||
with self.assertRaises(AccessError):
|
||||
resource1.with_user(user_officer_other).unlink()
|
||||
|
||||
# Responsible officer can do anything on their own channels
|
||||
resource1.with_user(self.user_officer).write({'name': 'other name'})
|
||||
resource1.with_user(self.user_officer).unlink()
|
||||
|
||||
# Managers can do anything on all channels
|
||||
resource2.with_user(self.user_manager).write({'name': 'Another name'})
|
||||
resource2.with_user(self.user_manager).unlink()
|
||||
self.env['slide.slide.resource'].with_user(self.user_manager).create(resource_values)
|
||||
|
||||
@@ -145,10 +145,11 @@
|
||||
</t>
|
||||
</a>
|
||||
<ul class="collapse show p-0 m-0 list-unstyled" t-att-id="('collapse-%s') % (category.id if category else 0)" >
|
||||
<t t-set="is_member" t-value="slide.channel_id.is_member"/>
|
||||
<t t-set="can_access_channel" t-value="is_member or slide.channel_id.can_publish"/>
|
||||
<t t-foreach="category_slide_ids" t-as="aside_slide">
|
||||
<t t-set="slide_completed" t-value="channel_progress[aside_slide.id].get('completed')"/>
|
||||
<t t-set="is_member" t-value="slide.channel_id.is_member"/>
|
||||
<t t-set="can_access" t-value="aside_slide.is_preview or is_member or slide.channel_id.can_publish"/>
|
||||
<t t-set="can_access" t-value="aside_slide.is_preview or can_access_channel"/>
|
||||
<li class="p-0 pb-1">
|
||||
<div t-att-class="'o_wslides_lesson_aside_list_link d-flex align-items-center 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"
|
||||
@@ -172,27 +173,25 @@
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<ul t-if="aside_slide.slide_resource_ids or aside_slide.question_ids" class="list-group px-2 mb-1 list-unstyled">
|
||||
<t t-foreach="aside_slide.slide_resource_ids" t-as="resource" t-if="resource.resource_type == 'url'">
|
||||
<li class="pl-4">
|
||||
<a t-if="can_access" t-att-href="resource.link" target="new" class="text-decoration-none small">
|
||||
<i class="fa fa-link mr-1"/><span t-field="resource.name"/>
|
||||
</a>
|
||||
<span t-else="" class="text-decoration-none text-muted small">
|
||||
<i class="fa fa-link mr-1"/><span t-field="resource.name"/>
|
||||
</span>
|
||||
</li>
|
||||
</t>
|
||||
<t t-set="resource_file_ids" t-value="aside_slide.slide_resource_ids.filtered(lambda res: res.resource_type == 'file')"/>
|
||||
<div class="o_wslides_js_course_join pl-4" t-if="resource_file_ids">
|
||||
<t t-if="is_member or aside_slide.channel_id.can_publish">
|
||||
<li t-foreach="resource_file_ids" t-as="resource">
|
||||
<ul t-if="aside_slide._has_additional_resources() or aside_slide.question_ids" class="list-group px-2 mb-1 list-unstyled">
|
||||
<t t-if="can_access_channel">
|
||||
<t t-foreach="aside_slide.slide_resource_ids" t-as="resource" t-if="resource.resource_type == 'url'">
|
||||
<li class="pl-4">
|
||||
<a t-if="can_access" t-att-href="resource.link" target="new" class="text-decoration-none small">
|
||||
<i class="fa fa-link mr-1"/><span t-field="resource.name"/>
|
||||
</a>
|
||||
</li>
|
||||
</t>
|
||||
<div class="o_wslides_js_course_join pl-4" t-if="aside_slide._has_additional_resources()">
|
||||
<li t-foreach="aside_slide.slide_resource_ids" t-as="resource" t-if="resource.resource_type == 'file'">
|
||||
<a t-attf-href="/web/content/slide.slide.resource/#{resource.id}/data?download=true" class="text-decoration-none small">
|
||||
<i class="fa fa-download mr-1"/><span t-field="resource.name"/>
|
||||
</a>
|
||||
</li>
|
||||
</t>
|
||||
<li t-elif="aside_slide.channel_id.enroll == 'public'" class="text-decoration-none small">
|
||||
</div>
|
||||
</t>
|
||||
<div t-else="" class="o_wslides_js_course_join o_wslides_no_access">
|
||||
<li t-if="aside_slide.channel_id.enroll == 'public'" class="text-decoration-none small">
|
||||
<i class="fa fa-download mr-1"/>
|
||||
<t t-call="website_slides.join_course_link"/>
|
||||
</li>
|
||||
@@ -430,31 +429,43 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3 mb-3">
|
||||
<t t-set="links" t-value="slide.slide_resource_ids.filtered(lambda res: res.resource_type == 'url')"/>
|
||||
<t t-set="files" t-value="slide.slide_resource_ids.filtered(lambda res: res.resource_type == 'file' and res.data)"/>
|
||||
<div class="col-12 col-md d-flex align-items-start mb-4 mb-md-0" t-if="links">
|
||||
<span class="text-muted font-weight-bold mr-3">External sources</span>
|
||||
<div class="text-muted mr-auto border-left pl-3">
|
||||
<t t-foreach="links" t-as="link">
|
||||
<a t-att-href="link.link" t-esc="link.name"/><br />
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<group>
|
||||
<div class="col-12 col-md d-flex align-items-start mb-4 mb-md-0 o_wslides_js_course_join" t-if="files">
|
||||
<span t-if="slide.channel_id.is_member or slide.channel_id.can_publish or slide.is_preview or slide.channel_id.enroll in ['private', 'payment']" class="text-muted font-weight-bold mr-3">
|
||||
<t t-if="slide._has_additional_resources()">
|
||||
<t t-set="can_access_channel" t-value="slide.channel_id.is_member or slide.channel_id.can_publish"/>
|
||||
<t t-if="can_access_channel">
|
||||
<t t-set="links" t-value="slide.slide_resource_ids.filtered(lambda res: res.resource_type == 'url')"/>
|
||||
<div class="col-12 col-md d-flex align-items-start mb-4 mb-md-0" t-if="links">
|
||||
<span class="text-muted font-weight-bold mr-3">External sources</span>
|
||||
<div class="text-muted mr-auto border-left pl-3">
|
||||
<t t-foreach="links" t-as="link">
|
||||
<a t-att-href="link.link" t-esc="link.name"/><br />
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<group>
|
||||
<t t-set="files" t-value="slide.slide_resource_ids.filtered(lambda res: res.resource_type == 'file' and res.data)"/>
|
||||
<div class="col-12 col-md d-flex align-items-start mb-4 mb-md-0 o_wslides_js_course_join" t-if="files">
|
||||
<span class="text-muted font-weight-bold mr-3">
|
||||
Additional Resources
|
||||
</span>
|
||||
<div class="text-muted mr-auto border-left pl-3">
|
||||
<t t-foreach="slide.slide_resource_ids" t-as="resource" t-if="resource.resource_type == 'file' and resource.data">
|
||||
<a t-attf-href="/web/content/slide.slide.resource/#{resource.id}/data?download=true" t-esc="resource.name"/><br />
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span t-if="slide.is_preview or slide.channel_id.enroll in ['private', 'payment']" class="text-muted font-weight-bold mr-3">
|
||||
Additional Resources
|
||||
</span>
|
||||
<div t-if="slide.channel_id.is_member or slide.channel_id.can_publish" class="text-muted mr-auto border-left pl-3">
|
||||
<t t-foreach="files" t-as="resource">
|
||||
<a t-attf-href="/web/content/slide.slide.resource/#{resource.id}/data?download=true" t-esc="resource.name"/><br />
|
||||
</t>
|
||||
<div class="o_wslides_js_course_join o_wslides_no_access">
|
||||
<div t-if="slide.channel_id.enroll == 'public'" class="text-muted mr-auto border-left pl-3">
|
||||
<t t-call="website_slides.join_course_link"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-elif="slide.channel_id.enroll == 'public'" class="text-muted mr-auto border-left pl-3">
|
||||
<t t-call="website_slides.join_course_link"/>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -101,10 +101,11 @@
|
||||
<b t-field="category.name"/>
|
||||
</a>
|
||||
<ul class="o_wslides_fs_sidebar_section_slides collapse show position-relative px-0 pb-1 my-0 mx-n3" t-att-id="('collapse-%s') % (category.id if category else 0)">
|
||||
<t t-set="is_member" t-value="current_slide.channel_id.is_member"/>
|
||||
<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="is_member" t-value="current_slide.channel_id.is_member"/>
|
||||
<t t-set="can_access" t-value="slide.is_preview or is_member or current_slide.channel_id.can_publish"/>
|
||||
<t t-set="can_access" t-value="can_access_channel or slide.is_preview"/>
|
||||
<li t-attf-class="o_wslides_fs_sidebar_list_item d-flex align-items-center py-1 #{'active' if slide.id == current_slide.id else ''}"
|
||||
t-att-data-id="slide.id"
|
||||
t-att-data-can-access="can_access"
|
||||
@@ -137,26 +138,25 @@
|
||||
<div class="o_wslides_fs_slide_name text-600" t-esc="slide.name"/>
|
||||
</div>
|
||||
</span>
|
||||
<ul class="list-unstyled w-100 pt-2 small" t-if="slide.slide_resource_ids or (slide.question_ids and not slide.slide_category =='quiz')" >
|
||||
<t t-set="links" t-value="slide.slide_resource_ids.filtered(lambda res: res.resource_type == 'url')"/>
|
||||
<li t-if="links" t-foreach="links" t-as="link" class="pl-0 mb-1">
|
||||
<a t-if="can_access" class="o_wslides_fs_slide_link" t-att-href="link.link" target="_blank">
|
||||
<i class="fa fa-link mr-2"/><span t-esc="link.name"/>
|
||||
</a>
|
||||
<span t-else="" class="o_wslides_fs_slide_link text-600">
|
||||
<i class="fa fa-link mr-2"/><span t-esc="link.name"/>
|
||||
</span>
|
||||
</li>
|
||||
<t t-set="resources" t-value="slide.slide_resource_ids.filtered(lambda res: res.resource_type == 'file')"/>
|
||||
<div class="o_wslides_js_course_join pl-0" t-if="resources">
|
||||
<t t-if="is_member or slide.channel_id.can_publish">
|
||||
<ul class="list-unstyled w-100 pt-2 small" t-if="slide._has_additional_resources() or (slide.question_ids and not slide.slide_category =='quiz')" >
|
||||
<t t-if="can_access_channel">
|
||||
<t t-set="links" t-value="slide.slide_resource_ids.filtered(lambda res: res.resource_type == 'url')"/>
|
||||
<li t-foreach="links" t-as="link" class="pl-0 mb-1">
|
||||
<a t-if="can_access" class="o_wslides_fs_slide_link" t-att-href="link.link" target="_blank">
|
||||
<i class="fa fa-link mr-2"/><span t-esc="link.name"/>
|
||||
</a>
|
||||
</li>
|
||||
<div class="o_wslides_js_course_join pl-0" t-if="slide._has_additional_resources('file')">
|
||||
<t t-set="resources" t-value="slide.slide_resource_ids.filtered(lambda res: res.resource_type == 'file')"/>
|
||||
<li t-foreach="resources" t-as="resource" class="mb-1">
|
||||
<a class="o_wslides_fs_slide_link" t-attf-href="/web/content/slide.slide.resource/#{resource.id}/data?download=true">
|
||||
<i class="fa fa-download mr-2"/><span t-esc="resource.name"/>
|
||||
</a>
|
||||
</li>
|
||||
</t>
|
||||
<li t-elif="slide.channel_id.enroll == 'public'" class="o_wslides_fs_slide_link mb-1">
|
||||
</div>
|
||||
</t>
|
||||
<div t-else="" class="o_wslides_js_course_join o_wslides_no_access pl-0">
|
||||
<li t-if="slide.channel_id.enroll == 'public'" class="o_wslides_fs_slide_link mb-1">
|
||||
<i class="fa fa-download mr-1"/>
|
||||
<t t-call="website_slides.join_course_link"/>
|
||||
</li>
|
||||
|
||||
@@ -92,8 +92,7 @@
|
||||
<template id="join_course_link" name="Join Course Link">
|
||||
<a class="o_wslides_js_course_join_link" href="#" t-att-data-channel-enroll="slide.channel_id.enroll"
|
||||
t-att-data-channel-id="slide.channel_id.id">
|
||||
Join Course
|
||||
</a> to download resources
|
||||
Join Course</a> to access resources
|
||||
</template>
|
||||
|
||||
<!-- Python equivalent of the JS template "website.slides.sidebar.done.button" -->
|
||||
|
||||
Reference in New Issue
Block a user