summaryrefslogtreecommitdiff
path: root/addons/website_slides/views
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/website_slides/views
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/website_slides/views')
-rw-r--r--addons/website_slides/views/assets.xml75
-rw-r--r--addons/website_slides/views/rating_rating_views.xml147
-rw-r--r--addons/website_slides/views/res_config_settings_views.xml95
-rw-r--r--addons/website_slides/views/res_partner_views.xml31
-rw-r--r--addons/website_slides/views/slide_channel_partner_views.xml44
-rw-r--r--addons/website_slides/views/slide_channel_tag_views.xml109
-rw-r--r--addons/website_slides/views/slide_channel_views.xml317
-rw-r--r--addons/website_slides/views/slide_question_views.xml81
-rw-r--r--addons/website_slides/views/slide_slide_views.xml331
-rw-r--r--addons/website_slides/views/website_slides_menu_views.xml81
-rw-r--r--addons/website_slides/views/website_slides_templates_course.xml848
-rw-r--r--addons/website_slides/views/website_slides_templates_homepage.xml508
-rw-r--r--addons/website_slides/views/website_slides_templates_lesson.xml563
-rw-r--r--addons/website_slides/views/website_slides_templates_lesson_embed.xml164
-rw-r--r--addons/website_slides/views/website_slides_templates_lesson_fullscreen.xml170
-rw-r--r--addons/website_slides/views/website_slides_templates_profile.xml69
-rw-r--r--addons/website_slides/views/website_slides_templates_utils.xml84
17 files changed, 3717 insertions, 0 deletions
diff --git a/addons/website_slides/views/assets.xml b/addons/website_slides/views/assets.xml
new file mode 100644
index 00000000..f614708b
--- /dev/null
+++ b/addons/website_slides/views/assets.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" ?>
+<odoo>
+ <data>
+ <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_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"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/activity.js"/>
+ </xpath>
+ </template>
+
+ <template id="assets_frontend" inherit_id="website.assets_frontend" name="Slides Frontend Assets">
+ <xpath expr="//link[last()]" position="after">
+ <link rel="stylesheet" type="text/scss" href="/website_slides/static/src/scss/website_slides.scss" t-ignore="true"/>
+ <link rel="stylesheet" type="text/scss" href="/website_slides/static/src/scss/website_slides_profile.scss"/>
+ <link rel="stylesheet" type="text/scss" href="/website_slides/static/src/scss/slides_slide_fullscreen.scss" t-ignore="true"/>
+ </xpath>
+ <xpath expr="//script[last()]" position="after">
+ <script type="text/javascript" src="/website_slides/static/src/js/slides.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_share.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_upload.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_category_add.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_slide_archive.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_slide_toggle_is_preview.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_slide_like.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_course_slides_list.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_course_fullscreen_player.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_course_join.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_course_enroll_email.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_course_quiz.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_course_quiz_question_form.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_course_quiz_finish.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_course_tag_add.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_course_unsubscribe.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/js/tours/slides_tour.js"/>
+ </xpath>
+ </template>
+
+ <template id="assets_tests" inherit_id="web.assets_tests" name="Slides Tests Assets">
+ <xpath expr="." position="inside">
+ <script type="text/javascript" src="/website_slides/static/src/tests/tours/slides_tour_tools.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/tests/tours/slides_course_member.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/tests/tours/slides_course_member_yt.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/tests/tours/slides_course_publisher.js"/>
+ <script type="text/javascript" src="/website_slides/static/src/tests/tours/slides_full_screen_web_editor.js"/>
+ </xpath>
+ </template>
+
+ <template id="assets_editor_inherit_website_slides" inherit_id="website.assets_editor" name="website_slides Assets Editor">
+ <xpath expr="." position="inside">
+ <script type="text/javascript" src="/website_slides/static/src/js/website_slides.editor.js"/>
+ </xpath>
+ </template>
+
+ <!-- Bundle (minimal) for embedded slide iframe -->
+ <template id="website_slides.slide_embed_assets" name="Website slides embed assets">
+ <t t-call="web._assets_helpers"/>
+ <t t-call="web._assets_bootstrap"/>
+ <link rel="stylesheet" type="text/scss" href="/website_slides/static/src/scss/website_slides.scss" t-ignore="true"/>
+
+ <t t-call="web.pdf_js_lib"></t>
+ <script type="text/javascript" src="/website_slides/static/lib/pdfslidesviewer/PDFSlidesViewer.js"></script>
+ <script type="text/javascript" src="/website_slides/static/src/js/slides_embed.js"></script>
+ </template>
+
+ <template id="website_slides_tests" name="eLearning tests" inherit_id="web.qunit_suite_tests">
+ <xpath expr="//script[last()]" position="after">
+ <script type="text/javascript" src="/website_slides/static/src/components/activity/activity_tests.js"/>
+ </xpath>
+ </template>
+
+ </data>
+</odoo>
diff --git a/addons/website_slides/views/rating_rating_views.xml b/addons/website_slides/views/rating_rating_views.xml
new file mode 100644
index 00000000..0b003bea
--- /dev/null
+++ b/addons/website_slides/views/rating_rating_views.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <record id="rating_rating_view_kanban_slide_channel" model="ir.ui.view">
+ <field name="name">rating.rating.view.kanban.slides</field>
+ <field name="model">rating.rating</field>
+ <field name="priority">20</field>
+ <field name="arch" type="xml">
+ <kanban create="false" class="o_slide_rating_kanban">
+ <field name="rating"/>
+ <field name="res_name"/>
+ <field name="feedback"/>
+ <field name="partner_id"/>
+ <templates>
+ <t t-name="kanban-box">
+ <t t-set="val_stars" t-value="record.rating.raw_value"/>
+ <t t-set="val_integer" t-value="Math.floor(val_stars)"/>
+ <t t-set="val_decimal" t-value="val_stars - val_integer"/>
+ <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 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" aria-label="A star" role="img"></i>
+ </t>
+ <t t-if="val_decimal">
+ <i class="fa fa-star-half-o" aria-label="Half a star" role="img"></i>
+ </t>
+ <t t-foreach="_.range(0, empty_star)" t-as="num" role="img">
+ <i class="fa fa-star text-black-25" aria-label="A star"></i>
+ </t>
+ </div>
+ <div>
+ <div class="o_kanban_card_header">
+ <div class="o_kanban_card_header_title">
+ <span class="font-weight-bold"><field name="partner_id"/></span>
+ </div>
+ </div>
+ <div class="o_kanban_card_content mt0 d-flex flex-column">
+ <span>
+ <i class="fa fa-folder mr-2" aria-label="Open folder"></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" aria-label="Create date"/> <field name="create_date" /></span>
+ <div class="d-flex mt-2">
+ <span t-esc="record.feedback.raw_value"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </t>
+ </templates>
+ </kanban>
+ </field>
+ </record>
+
+ <record id="rating_rating_view_search_slide_channel" model="ir.ui.view">
+ <field name="name">rating.rating.view.search.slides</field>
+ <field name="model">rating.rating</field>
+ <field name="priority">20</field>
+ <field name="inherit_id" ref="rating.rating_rating_view_search"/>
+ <field name="mode">primary</field>
+ <field name="arch" type="xml">
+ <xpath expr="//filter[@name='resource']" position="after">
+ <filter string="Course" name="groupby_course" context="{'group_by': 'res_name'}"/>
+ </xpath>
+ <xpath expr="/search" position="inside">
+ <filter string="Creation Date" name="rating_last_30_days" date="create_date" default_period="last_30_days"/>
+ <separator/>
+ </xpath>
+ </field>
+ </record>
+
+ <record id="rating_rating_view_graph_slide_channel" model="ir.ui.view">
+ <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" sample="1">
+ <field name="res_name" type="row"/>
+ <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 sample="1">
+ <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">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>
+ <field name="context">{}</field>
+ <field name="search_view_id" ref="rating_rating_view_search_slide_channel"/>
+ <field name="view_id" ref="rating_rating_view_kanban_slide_channel"/>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_empty_folder">
+ There are no ratings for these courses at the moment
+ </p>
+ </field>
+ </record>
+
+ <record id="rating_rating_action_slide_channel_report" model="ir.actions.act_window">
+ <field name="name">Rating</field>
+ <field name="res_model">rating.rating</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="help" type="html">
+ <p class="o_view_nocontent_empty_folder">
+ There are no ratings 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/res_config_settings_views.xml b/addons/website_slides/views/res_config_settings_views.xml
new file mode 100644
index 00000000..4f9c919d
--- /dev/null
+++ b/addons/website_slides/views/res_config_settings_views.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <record id="res_config_settings_view_form" model="ir.ui.view">
+ <field name="name">res.config.settings.view.form.inherit.website.slides</field>
+ <field name="model">res.config.settings</field>
+ <field name="inherit_id" ref="website.res_config_settings_view_form"/>
+ <field name="arch" type="xml">
+ <xpath expr="//div[@id='google_maps_setting']" position="after">
+ <div class="col-12 col-lg-6 o_setting_box" id="slides_install_setting">
+ <div class="o_setting_right_pane">
+ <span class="o_form_label">Slides</span>
+ <span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
+ <div class="text-muted">
+ Google Drive API Key
+ </div>
+ <div class="content-group">
+ <div class="row mt16">
+ <label for="website_slide_google_app_key" class="col-lg-3 o_light_label" string="API Key"/>
+ <field name="website_slide_google_app_key" class="oe_inline"/>
+ </div>
+ <div class="oe_link">
+ <a href="https://console.developers.google.com/flows/enableapi?apiid=drive,youtube"><span class="fa fa-arrow-right"/>
+ Create a Google Project and Get a Key
+ </a>
+ </div>
+ </div>
+ </div>
+ </div>
+ </xpath>
+ <xpath expr="//div[hasclass('settings')]" position="inside">
+ <div class="app_settings_block" data-string="eLearning" string="eLearning" data-key="website_slides">
+ <h2>eLearning</h2>
+ <div class="row mt16 o_settings_container" id="elearning_selection_settings">
+ <div class="col-12 col-lg-6 o_setting_box" id="elearning_install_forum">
+ <div class="o_setting_left_pane">
+ <field name="module_website_slides_forum"/>
+ </div>
+ <div class="o_setting_right_pane">
+ <label for="module_website_slides_forum"/>
+ <div class="text-muted">
+ Create a community and let the members help each others
+ </div>
+ </div>
+ </div>
+ <div class="col-12 col-lg-6"></div>
+ <div class="col-12 col-lg-6 o_setting_box" id="website_slides_install_mass_mailing_slides">
+ <div class="o_setting_left_pane">
+ <field name="module_mass_mailing_slides"/>
+ </div>
+ <div class="o_setting_right_pane">
+ <label for="module_mass_mailing_slides"/>
+ <div class="text-muted">
+ Contact all the members of a course via mass mailing
+ </div>
+ </div>
+ </div>
+ <div class="col-12 col-lg-6"></div>
+ <div class="col-12 col-lg-6 o_setting_box" id="elearning_install_certif">
+ <div class="o_setting_left_pane">
+ <field name="module_website_slides_survey"/>
+ </div>
+ <div class="o_setting_right_pane">
+ <label for="module_website_slides_survey"/>
+ <div class="text-muted">
+ Evaluate your students and certify them
+ </div>
+ </div>
+ </div>
+ <div class="col-12 col-lg-6"></div>
+ <div class="col-12 col-lg-6 o_setting_box" id="elearning_install_sell">
+ <div class="o_setting_left_pane">
+ <field name="module_website_sale_slides"/>
+ </div>
+ <div class="o_setting_right_pane">
+ <label for="module_website_sale_slides"/>
+ <div class="text-muted">
+ Generate revenues thanks to your courses
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </xpath>
+ </field>
+ </record>
+
+ <record id="website_slides_action_settings" model="ir.actions.act_window">
+ <field name="name">Settings</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">res.config.settings</field>
+ <field name="view_mode">form</field>
+ <field name="target">inline</field>
+ <field name="context">{'module': 'website_slides', 'bin_size': False}</field>
+ </record>
+</odoo>
diff --git a/addons/website_slides/views/res_partner_views.xml b/addons/website_slides/views/res_partner_views.xml
new file mode 100644
index 00000000..cbdac1cf
--- /dev/null
+++ b/addons/website_slides/views/res_partner_views.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo><data>
+
+ <record id="res_partner_view_form" model="ir.ui.view">
+ <field name="name">res.partner.view.form.inherit.slides</field>
+ <field name="model">res.partner</field>
+ <field name="inherit_id" ref="base.view_partner_form"/>
+ <field name="groups_id" eval="[(4, ref('website_slides.group_website_slides_officer'))]"/>
+ <field name="arch" type="xml">
+ <xpath expr="//div[@name='button_box']" position="inside">
+ <button class="oe_stat_button" type="object"
+ icon="fa-graduation-cap" name="action_view_courses"
+ attrs="{'invisible': ['|', ('slide_channel_count', '=', 0), ('is_company', '=', True)]}">
+ <div class="o_field_widget o_stat_info">
+ <span class="o_stat_value"><field name="slide_channel_count"/></span>
+ <span class="o_stat_text">Courses</span>
+ </div>
+ </button>
+ <button class="oe_stat_button" type="object"
+ icon="fa-graduation-cap" name="action_view_courses"
+ attrs="{'invisible': ['|', ('slide_channel_company_count', '=', 0), ('is_company', '=', False)]}">
+ <div class="o_field_widget o_stat_info">
+ <span class="o_stat_value"><field name="slide_channel_company_count" /></span>
+ <span class="o_stat_text">Courses</span>
+ </div>
+ </button>
+ </xpath>
+ </field>
+ </record>
+
+</data></odoo>
diff --git a/addons/website_slides/views/slide_channel_partner_views.xml b/addons/website_slides/views/slide_channel_partner_views.xml
new file mode 100644
index 00000000..20227f7c
--- /dev/null
+++ b/addons/website_slides/views/slide_channel_partner_views.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data>
+ <record id="slide_channel_partner_view_search" model="ir.ui.view">
+ <field name="name">slide.channel.partner.search</field>
+ <field name="model">slide.channel.partner</field>
+ <field name="arch" type="xml">
+ <search string="Channel Member">
+ <field name="partner_id"/>
+ <field name="partner_email"/>
+ <field name="channel_id"/>
+ </search>
+ </field>
+ </record>
+
+ <record id="slide_channel_partner_action" model="ir.actions.act_window">
+ <field name="name">Attendees</field>
+ <field name="res_model">slide.channel.partner</field>
+ <field name="view_mode">tree</field>
+ <field name="search_view_id" ref="website_slides.slide_channel_partner_view_search"/>
+ </record>
+
+ <record id="slide_channel_partner_view_tree" model="ir.ui.view">
+ <field name="name">slide.channel.partner.tree</field>
+ <field name="model">slide.channel.partner</field>
+ <field name="arch" type="xml">
+ <tree string="Attendees" editable="top">
+ <field name="create_date"/>
+ <field name="partner_id" string="Contact"/>
+ <field name="partner_email"/>
+ <field name="channel_id" string="Channel" invisible="context.get('default_channel_id',False)" />
+ <field name="completion" string="Progress" widget="progressbar" />
+ <button name="unlink" title="Remove" icon="fa-times" type="object"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="slide_channel_partner_action" model="ir.actions.act_window">
+ <field name="name">Attendees</field>
+ <field name="res_model">slide.channel.partner</field>
+ <field name="view_mode">tree,form</field>
+ </record>
+ </data>
+</odoo>
diff --git a/addons/website_slides/views/slide_channel_tag_views.xml b/addons/website_slides/views/slide_channel_tag_views.xml
new file mode 100644
index 00000000..b4c4e9ab
--- /dev/null
+++ b/addons/website_slides/views/slide_channel_tag_views.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo><data>
+ <!-- SLIDE.CHANNEL.TAG -->
+ <record id="slide_channel_tag_view_search" model="ir.ui.view">
+ <field name="name">slide.channel.tag.view.search</field>
+ <field name="model">slide.channel.tag</field>
+ <field name="arch" type="xml">
+ <search string="Course Tags">
+ <field name="name"/>
+ <field name="group_id"/>
+ </search>
+ </field>
+ </record>
+
+ <record id="slide_channel_tag_view_form" model="ir.ui.view">
+ <field name="name">slide.channel.tag.view.form</field>
+ <field name="model">slide.channel.tag</field>
+ <field name="arch" type="xml">
+ <form string="Course Tag">
+ <sheet>
+ <group>
+ <field name="name"/>
+ <field name="group_id"/>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="slide_channel_tag_view_tree" model="ir.ui.view">
+ <field name="name">slide.channel.tag.view.tree</field>
+ <field name="model">slide.channel.tag</field>
+ <field name="arch" type="xml">
+ <tree string="Course Tags" editable="top">
+ <field name="sequence" widget="handle"/>
+ <field name="group_sequence" invisible="1"/>
+ <field name="name"/>
+ <field name="group_id"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="slide_channel_tag_action" model="ir.actions.act_window">
+ <field name="name">Course Tags</field>
+ <field name="res_model">slide.channel.tag</field>
+ <field name="view_mode">tree,form</field>
+ </record>
+
+ <!-- SLIDE.CHANNEL.TAG.GROUP -->
+ <record id="slide_channel_tag_group_view_search" model="ir.ui.view">
+ <field name="name">slide.channel.tag.group.view.search</field>
+ <field name="model">slide.channel.tag.group</field>
+ <field name="arch" type="xml">
+ <search string="Course Tag Groups">
+ <field name="name"/>
+ </search>
+ </field>
+ </record>
+
+ <record id="slide_channel_tag_group_view_form" model="ir.ui.view">
+ <field name="name">slide.channel.tag.group.view.form</field>
+ <field name="model">slide.channel.tag.group</field>
+ <field name="arch" type="xml">
+ <form string="Course Tag Group">
+ <sheet>
+ <group>
+ <div class="oe_title">
+ <label for="name" class="oe_edit_only" string="Group Name"/>
+ <h1><field name="name" default_focus="1" placeholder="Group Name"/></h1>
+ <label for="is_published" string="Menu Entry"/>
+ <field name="is_published"/><br/>
+ <field name="tag_ids">
+ <tree editable="bottom">
+ <field name="sequence" widget="handle"/>
+ <field name="group_sequence" invisible="1"/>
+ <field name="name" string="Tag Name"/>
+ <field name="color" string="Color" widget="color_picker"/>
+ <control>
+ <create string="Add a tag"/>
+ </control>
+ </tree>
+ </field>
+ </div>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="slide_channel_tag_group_view_tree" model="ir.ui.view">
+ <field name="name">slide.channel.tag.group.view.tree</field>
+ <field name="model">slide.channel.tag.group</field>
+ <field name="arch" type="xml">
+ <tree string="Course Tag Groups">
+ <field name="sequence" widget="handle"/>
+ <field name="name"/>
+ <field name="is_published" string="Menu Entry"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="slide_channel_tag_group_action" model="ir.actions.act_window">
+ <field name="name">Course Groups</field>
+ <field name="res_model">slide.channel.tag.group</field>
+ <field name="view_mode">tree,form</field>
+ </record>
+
+ </data>
+</odoo>
diff --git a/addons/website_slides/views/slide_channel_views.xml b/addons/website_slides/views/slide_channel_views.xml
new file mode 100644
index 00000000..f207e36a
--- /dev/null
+++ b/addons/website_slides/views/slide_channel_views.xml
@@ -0,0 +1,317 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data>
+ <!-- SLIDE.CHANNEL VIEWS -->
+ <record model="ir.ui.view" id="view_slide_channel_form">
+ <field name="name">slide.channel.view.form</field>
+ <field name="model">slide.channel</field>
+ <field name="arch" type="xml">
+ <form string="Channels">
+ <header>
+ <button name="action_channel_invite" string="Invite" type="object" class="oe_highlight" attrs="{'invisible': [('enroll', '!=', 'invite')]}"/>
+ </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_slides.group_website_slides_officer">
+ <div class="o_field_widget o_stat_info">
+ <span class="o_stat_value"><field name="total_views" nolabel="1"/> Visits</span>
+ <span class="o_stat_value"><field name="total_slides" nolabel="1"/> Contents</span>
+ </div>
+ </button>
+ <button name="action_redirect_to_done_members"
+ type="object"
+ icon="fa-trophy"
+ class="oe_stat_button"
+ groups="website_slides.group_website_slides_officer">
+ <div class="o_field_widget o_stat_info">
+ <span class="o_stat_value"><field name="members_done_count" nolabel="1"/></span>
+ <span name="members_done_count_label" class="o_stat_text">Finished</span>
+ </div>
+ </button>
+ <button name="action_redirect_to_members"
+ type="object"
+ icon="fa-users"
+ class="oe_stat_button"
+ groups="website_slides.group_website_slides_officer">
+ <field name="members_count" string="Attendees" widget="statinfo"/>
+ </button>
+ <button name="action_view_ratings"
+ type="object"
+ icon="fa-star"
+ class="oe_stat_button"
+ groups="website_slides.group_website_slides_officer"
+ attrs="{'invisible': [('allow_comment', '=', False)]}">
+ <div class="o_field_widget o_stat_info">
+ <span class="o_stat_value"><field name="rating_avg_stars" nolabel="1"/>/5</span>
+ <span name="rating_count_label" class="o_stat_text"><field name="rating_count" nolabel="1"/> Reviews</span>
+ </div>
+ </button>
+ <field name="is_published" widget="website_redirect_button"/>
+ </div>
+ <widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
+ <field name="image_1920" widget="image" class="oe_avatar" options="{'preview_image': 'image_128'}"/>
+ <div class="oe_title">
+ <label for="name" class="oe_edit_only" string="Course Title"/>
+ <h1><field name="name" default_focus="1" placeholder="Computer Science for kids"/></h1>
+ </div>
+ <div>
+ <field name="active" invisible="1"/>
+ <field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}" placeholder="Tags"/>
+ </div>
+ <notebook colspan="4">
+ <page name="content" string="Content">
+ <field name="slide_ids" string="Content" colspan="4" nolabel="1" widget="slide_category_one2many" mode="tree,kanban" context="{'default_channel_id': active_id, 'form_view_ref' : 'website_slides.view_slide_slide_form_wo_channel_id'}">
+ <tree decoration-bf="is_category" editable="bottom">
+ <field name="sequence" widget="handle"/>
+ <field name="name"/>
+ <field name="slide_type" attrs="{'invisible': [('slide_type', '=', 'category')]}"/>
+ <field name="completion_time" attrs="{'invisible': [('slide_type', '=', 'category')]}" string="Duration" widget="float_time"/>
+ <field name="total_views" attrs="{'invisible': [('slide_type', '=', 'category')]}"/>
+ <field name="is_preview" string="Preview"/>
+ <field name="is_published" string="Published"/>
+ <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"/>
+ </control>
+ </tree>
+ </field>
+ </page>
+ <page name="description" string="Description">
+ <group>
+ <field name="description" colspan="4" placeholder="Common tasks for a computer scientist is asking the right questions and answering questions. In this course, you'll study those topics with activities about mathematics, science and logic."/>
+ </group>
+ </page>
+ <page name="options" string="Options">
+ <group>
+ <group name="course" string="Course">
+ <field string="Type" name="channel_type" widget="radio"/>
+ <field name="user_id" domain="[('share', '=', False)]"/>
+ <field name="website_id" options="{'no_create': True}" groups="website.group_multi_website"/>
+ </group>
+ <group name="access_rights" string="Access Rights">
+ <field name="enroll" widget="radio" options="{'horizontal': true}"/>
+ <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')]" 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"/>
+ <field name="promote_strategy" widget="radio"
+ attrs="{'invisible': [('channel_type', '=', 'training')]}"/>
+ <field name="promoted_slide_id"
+ attrs="{'invisible': ['|', ('channel_type', '=', 'training'), ('promote_strategy', '!=', 'specific')],
+ 'required': [('channel_type', '!=', 'training'), ('promote_strategy', '=', 'specific')]}"
+ domain="[('channel_id', '=', active_id), ('is_category', '=', False)]"/>
+ </group>
+ </group>
+ <div attrs="{'invisible': [('enroll', '!=', 'invite')]}">
+ <label for="enroll_msg"/>
+ <field name="enroll_msg" colspan="4" nolabel="1"/>
+ </div>
+ </page>
+ <page string="Karma" name="karma_rules">
+ <group>
+ <group string="Rewards">
+ <field name="karma_gen_channel_rank" string="Review Course"/>
+ <field name="karma_gen_channel_finish" string="Finish Course"/>
+ </group>
+ <group string="Access Rights" attrs="{'invisible': [('allow_comment', '!=', True)]}">
+ <field name="karma_review" attrs="{'invisible': [('allow_comment', '!=', True)]}"/>
+ <field name="karma_slide_comment" attrs="{'invisible': [('allow_comment', '!=', True)]}"/>
+ <field name="karma_slide_vote" attrs="{'invisible': [('allow_comment', '!=', True)]}"/>
+ </group>
+ </group>
+ </page>
+ </notebook>
+ </sheet>
+ <div class="oe_chatter">
+ <field name="message_follower_ids"/>
+ <field name="activity_ids"/>
+ <field name="message_ids"/>
+ </div>
+ </form>
+ </field>
+ </record>
+
+
+ <record id="slide_channel_view_tree" model="ir.ui.view">
+ <field name="name">slide.channel.view.tree</field>
+ <field name="model">slide.channel</field>
+ <field name="arch" type="xml">
+ <tree string="Courses" sample="1">
+ <field name="sequence" widget="handle"/>
+ <field name="name"/>
+ <field name="channel_type"/>
+ <field name="visibility"/>
+ <field name="enroll" widget="badge" decoration-success="enroll == 'public'" decoration-info="enroll == 'invite'" decoration-warning="enroll == 'payment'"/>
+ <field name="user_id" widget="many2one_avatar_user"/>
+ <field name="website_id" groups="website.group_multi_website"/>
+ <field name="active" invisible="1"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="slide_channel_view_tree_report" model="ir.ui.view">
+ <field name="name">slide.channel.view.tree.report</field>
+ <field name="model">slide.channel</field>
+ <field name="priority">20</field>
+ <field name="arch" type="xml">
+ <tree string="Courses" create="false" default_order="total_views desc" sample="1">
+ <field name="name"/>
+ <field name="total_views"/>
+ <field name="total_time" widget="float_time" />
+ <field name="members_count"/>
+ <field name="total_votes"/>
+ <field name="rating_avg_stars"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="slide_channel_view_search" model="ir.ui.view">
+ <field name="name">slide.channel.view.search</field>
+ <field name="model">slide.channel</field>
+ <field name="arch" type="xml">
+ <search string="Courses">
+ <field name="name" string="Course"/>
+ <filter string="Archived" name="inactive" domain="[('active','=',False)]"/>
+ </search>
+ </field>
+ </record>
+
+ <record id="slide_channel_view_graph" model="ir.ui.view">
+ <field name="name">slide.channel.view.graph</field>
+ <field name="model">slide.channel</field>
+ <field name="arch" type="xml">
+ <graph string="Courses" type="bar" sample="1">
+ <field name="name"/>
+ <field name="total_views" type="measure"/>
+ </graph>
+ </field>
+ </record>
+
+ <record id="slide_channel_view_kanban" model="ir.ui.view">
+ <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_kanban breadcrumb_item active" edit="false" sample="1">
+ <field name="color"/>
+ <field name="website_published"/>
+ <templates>
+ <t t-name="kanban-box">
+ <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click">
+ <div class="o_dropdown_kanban dropdown">
+ <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <span class="fa fa-ellipsis-v" aria-hidden="false"/>
+ </a>
+ <div class="dropdown-menu" role="menu">
+ <ul class="oe_kanban_colorpicker" data-field="color"/>
+ <t t-if="widget.deletable">
+ <a class="dropdown-item" role="menuitem" type="delete">Delete</a>
+ </t>
+ <a class="dropdown-item" role="menuitem" type="edit">
+ Edit
+ </a>
+ <a class="dropdown-item" name="action_view_slides" role="menuitem" type="object">
+ Lessons
+ </a>
+ <a class="dropdown-item" name="action_channel_invite" role="menuitem" type="object">
+ Invite
+ </a>
+ </div>
+ </div>
+ <div class="o_kanban_card_header">
+ <div class="o_kanban_card_header_title mb16">
+ <div class="o_primary">
+ <a type="edit" class="mr-auto">
+ <span><field name="name" class="o_primary"/></span>
+ </a>
+ </div>
+ <div t-if="record.tag_ids">
+ <field name="tag_ids" widget="many2many_tags"/>
+ </div>
+ </div>
+ </div>
+ <div class="container o_kanban_card_content mt0">
+ <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" t-if="record.rating_count.raw_value">
+ <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">Duration</label></span>
+ <field name="total_time" widget="float_time"/>
+ </div>
+ </div>
+ </div>
+ <div class="row mt3">
+ <div class="col-4 border-right">
+ <a name="action_view_slides" type="object" class="d-flex flex-column align-items-center">
+ <span class="font-weight-bold"><field name="total_slides"/></span>
+ <span class="text-muted">Contents</span>
+ </a>
+ </div>
+ <div class="col-4 border-right">
+ <a name="action_redirect_to_members" type="object" class="d-flex flex-column align-items-center">
+ <span class="font-weight-bold"><field name="members_count"/></span>
+ <span class="text-muted">Attendees</span>
+ </a>
+ </div>
+ <div class="col-4">
+ <a name="action_redirect_to_done_members" type="object" class="d-flex flex-column align-items-center">
+ <span class="font-weight-bold"><field name="members_done_count"/></span>
+ <span name="done_members_count_label" class="text-muted">Finished</span>
+ </a>
+ </div>
+ </div>
+ </div>
+ </div>
+ </t>
+ </templates>
+ </kanban>
+ </field>
+ </record>
+
+ <record id="slide_channel_action_overview" model="ir.actions.act_window">
+ <field name="name">eLearning Overview</field>
+ <field name="res_model">slide.channel</field>
+ <field name="view_mode">kanban,tree,form</field>
+ <field name="view_id" ref="slide_channel_view_kanban"/>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_smiling_face">
+ Create a course
+ </p>
+ </field>
+ </record>
+
+ <record id="slide_channel_action_report" model="ir.actions.act_window">
+ <field name="name">Courses</field>
+ <field name="res_model">slide.channel</field>
+ <field name="view_mode">tree,graph,form</field>
+ <field name="view_id" ref="slide_channel_view_tree_report"/>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_smiling_face">
+ Create a course
+ </p>
+ </field>
+ </record>
+ </data>
+</odoo>
diff --git a/addons/website_slides/views/slide_question_views.xml b/addons/website_slides/views/slide_question_views.xml
new file mode 100644
index 00000000..5d406425
--- /dev/null
+++ b/addons/website_slides/views/slide_question_views.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <record id="slide_question_view_form" model="ir.ui.view">
+ <field name="name">slide.question.view.form</field>
+ <field name="model">slide.question</field>
+ <field name="arch" type="xml">
+ <form string="Quiz">
+ <sheet>
+ <div class="oe_edit_only">
+ <label for="question" string="Question Name"/>
+ </div>
+ <h1>
+ <field name="question" default_focus="1" placeholder="Name"/>
+ </h1>
+ <field name="answer_ids">
+ <tree editable="bottom" create="true" delete="true">
+ <field name="text_value"/>
+ <field name="is_correct"/>
+ <field name="comment"/>
+ </tree>
+ </field>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="slide_question_view_tree" model="ir.ui.view">
+ <field name="name">slide.question.view.tree</field>
+ <field name="model">slide.question</field>
+ <field name="arch" type="xml">
+ <tree string="Quizzes">
+ <field name="sequence" widget="handle"/>
+ <field name="question"/>
+ <field name="slide_id"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="slide_question_view_tree_report" model="ir.ui.view">
+ <field name="name">slide.question.view.tree.report</field>
+ <field name="model">slide.question</field>
+ <field name="priority">20</field>
+ <field name="arch" type="xml">
+ <tree string="Quizzes" create="0">
+ <field name="sequence" widget="handle"/>
+ <field name="question"/>
+ <field name="slide_id"/>
+ <field name="attempts_count"/>
+ <field name="attempts_avg"/>
+ <field name="done_count"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="slide_question_view_search" model="ir.ui.view">
+ <field name="name">slide.question.view.search</field>
+ <field name="model">slide.question</field>
+ <field name="arch" type="xml">
+ <search string="Quizzes">
+ <field name="question"/>
+ <field name="slide_id"/>
+ </search>
+ </field>
+ </record>
+
+ <record id="slide_question_action_report" model="ir.actions.act_window">
+ <field name="name">Quizzes</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">slide.question</field>
+ <field name="view_mode">tree,form</field>
+ <field name="view_id" ref="slide_question_view_tree_report"/>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_smiling_face">
+ There are no quizzes
+ </p>
+ <p>
+ Add quizzes at the end of your lessons to evaluate what your students understood.
+ </p>
+ </field>
+ </record>
+</odoo>
diff --git a/addons/website_slides/views/slide_slide_views.xml b/addons/website_slides/views/slide_slide_views.xml
new file mode 100644
index 00000000..467872a7
--- /dev/null
+++ b/addons/website_slides/views/slide_slide_views.xml
@@ -0,0 +1,331 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data>
+ <!-- SLIDE.TAG -->
+ <record id="view_slide_tag_form" model="ir.ui.view">
+ <field name="name">slide.tag.form</field>
+ <field name="model">slide.tag</field>
+ <field name="arch" type="xml">
+ <form string="Tag">
+ <sheet>
+ <group>
+ <field name="name"/>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="view_slide_tag_tree" model="ir.ui.view">
+ <field name="name">slide.tag.tree</field>
+ <field name="model">slide.tag</field>
+ <field name="arch" type="xml">
+ <tree string="Tags" editable="bottom">
+ <field name="name"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="action_slide_tag" model="ir.actions.act_window">
+ <field name="name">Content Tags</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">slide.tag</field>
+ <field name="view_mode">tree,form</field>
+ </record>
+
+ <!-- SLIDE.SLIDE -->
+ <record id="view_slide_slide_form" model="ir.ui.view">
+ <field name="name">slide.slide.form</field>
+ <field name="model">slide.slide</field>
+ <field name="arch" type="xml">
+ <form string="Lesson">
+ <sheet>
+ <div class="oe_button_box" name="button_box">
+ <field name="is_published" widget="website_redirect_button"
+ attrs="{'invisible': ['|',('is_category', '=', True), ('channel_id', '=', False)]}"/>
+ </div>
+ <widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
+ <field name="image_1920" widget="image" class="oe_avatar" options='{"preview_image": "image_256"}'
+ attrs="{'invisible': [('is_category', '=', True)]}"/>
+ <div class="oe_title">
+ <div>
+ <label for="name" string="Content Title" class="oe_edit_only"/>
+ </div>
+ <h1>
+ <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..."/>
+ </div>
+ <notebook attrs="{'invisible': [('is_category', '=', True)]}">
+ <page name="document" string="Document">
+ <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'))],
+ 'invisible': [('slide_type', 'not in', ('video'))]}" />
+ <field name="document_id" invisible="1"/>
+ <field name="mime_type" force_save="1" readonly="1" groups="base.group_no_one"/>
+ <field name="datas" string="Attachment"
+ attrs="{'invisible': [('slide_type', 'not in', ('document', 'presentation'))]}"/>
+ </group>
+ <group name="related_details">
+ <field name="user_id"/>
+ <label for="completion_time"/>
+ <div>
+ <field name="completion_time" widget="float_time" class="oe_inline"/>
+ <span> hours</span>
+ </div>
+ <field name="is_preview"/>
+ <field name="slide_resource_downloadable" attrs="{'invisible': [('slide_type', 'not in', ['presentation', 'document'])]}"/>
+ <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" 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="Additional Resources" name="external_links" >
+ <group string="External Links">
+ <field name="link_ids" widget="one2many" nolabel="1">
+ <tree editable="top">
+ <field name="name"/>
+ <field name="link" widget="url" placeholder="e.g. https://www.odoo.com"/>
+ </tree>
+ </field>
+ </group>
+ <group string="Resources">
+ <field name="slide_resource_ids" widget="one2many" nolabel="1">
+ <tree editable="top">
+ <field name="name"/>
+ <field name="data" string="Size" required="1"/>
+ </tree>
+ </field>
+ </group>
+ </page>
+ <page name="quiz" string="Quiz">
+ <group name="quiz_details">
+ <group name="quiz_rewards" string="Rewards">
+ <group>
+ <field string="First attempt" name="quiz_first_attempt_reward"/>
+ <field string="Second attempt" name="quiz_second_attempt_reward"/>
+ <field string="Third attempt" name="quiz_third_attempt_reward"/>
+ <field string="Fourth and more attempt" name="quiz_fourth_attempt_reward"/>
+ </group>
+ </group>
+ <group name="questions" string="Questions">
+ <field name="question_ids" nolabel="1">
+ <tree>
+ <field name="sequence" widget="handle"/>
+ <field name="question"/>
+ </tree>
+ </field>
+ </group>
+ </group>
+ </page>
+ <page name="statistics" string="Statistics">
+ <group>
+ <group name="view_statistics" string="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" string="Comments" attrs="{'invisible': [('channel_allow_comment', '!=', True)]}"/>
+ </group>
+ </group>
+ </page>
+ </notebook>
+ </sheet>
+ <div class="oe_chatter">
+ <field name="message_follower_ids"/>
+ <field name="message_ids"/>
+ </div>
+ </form>
+ </field>
+ </record>
+
+ <record id="view_slide_slide_form_wo_channel_id" model="ir.ui.view">
+ <field name="name">slide.slide.form.wo.channel_id</field>
+ <field name="model">slide.slide</field>
+ <field name="inherit_id" ref="view_slide_slide_form"/>
+ <field name="priority" eval="50"/>
+ <field name="mode">primary</field>
+ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <field name="channel_id" position="attributes">
+ <attribute name="invisible">1</attribute>
+ <attribute name="required">0</attribute>
+ </field>
+ </field>
+ </record>
+
+ <record id="slide_slide_view_kanban" model="ir.ui.view">
+ <field name="name">slide.slide.view.kanban</field>
+ <field name="model">slide.slide</field>
+ <field name="arch" type="xml">
+ <kanban edit="false" group_create="0"
+ records_draggable="0"
+ class="o_slide_kanban"
+ sample="1">
+ <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">
+ <t t-set="placeholder" t-value="'/website_slides/static/src/img/channel-training-default.jpg'"/>
+ <div class="o_kanban_image_fill_left d-none d-md-block"
+ t-attf-style="background-image:url('#{kanban_image('slide.slide', 'image_128', record.id.raw_value, placeholder)}')">
+ <img class="o_kanban_image_inner_pic"
+ t-att-alt="record.channel_id.value"
+ t-att-src="kanban_image('slide.channel', 'image_128', record.channel_id.raw_value)"/>
+ </div>
+ <div class="o_kanban_image rounded-circle d-md-none"
+ t-attf-style="background-image:url('#{kanban_image('slide.slide', 'image_128', record.id.raw_value, placeholder)}')">
+ <img class="o_kanban_image_inner_pic"
+ t-att-alt="record.channel_id.value"
+ t-att-src="kanban_image('slide.channel', 'image_128', record.channel_id.raw_value)"/>
+ </div>
+ <div class="oe_kanban_details d-flex flex-column">
+ <strong class="o_kanban_record_title oe_partner_heading"><field name="name"/></strong>
+ <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>
+ <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>
+ <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>
+ <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>
+ <t t-elif="record.slide_type.raw_value == 'webpage'">
+ <i class="fa fa-file-code-o mr-2" aria-label="Webpage" role="img" title="Webpage"/>
+ </t>
+ <t t-elif="record.slide_type.raw_value == 'video'">
+ <i class="fa fa-file-video-o mr-2" aria-label="Video" role="img" title="Video"/>
+ </t>
+ <t t-elif="record.slide_type.raw_value == 'quiz'">
+ <i class="fa fa-flag mr-2" aria-label="Quiz" role="img" title="Quiz"/>
+ </t>
+ <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>
+ <field name="user_id" widget="many2one_avatar_user"/>
+ </div>
+ </div>
+ </div>
+ </t>
+ </templates>
+ </kanban>
+ </field>
+ </record>
+
+ <record id="view_slide_slide_tree" model="ir.ui.view">
+ <field name="name">slide.slide.tree</field>
+ <field name="model">slide.slide</field>
+ <field name="arch" type="xml">
+ <tree string="Contents" sample="1">
+ <field name="name"/>
+ <field name="website_id" groups="website.group_multi_website"/>
+ <field name="active" invisible="1"/>
+ <field name="slide_type"/>
+ <field name="channel_id"/>
+ <field name="category_id"/>
+ <field name="date_published"/>
+ <field name="slide_views"/>
+ <field name="public_views"/>
+ <field name="total_views"/>
+ <field name="completion_time"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="view_slide_slide_search" model="ir.ui.view">
+ <field name="name">slide.slide.filter</field>
+ <field name="model">slide.slide</field>
+ <field name="arch" type="xml">
+ <search string="Search Contents">
+ <field name="name"/>
+ <filter name="published" string="Published" domain="[('is_published', '=', True)]"/>
+ <filter name="not_published" string="Waiting for validation" domain="[('is_published', '=', False)]"/>
+ <separator/>
+ <filter string="Archived" name="inactive" domain="[('active','=',False)]"/>
+ <group expand="0" string="Group By">
+ <filter string="Course" name="groupby_channel" domain="[]" context="{'group_by': 'channel_id'}"/>
+ <filter string="Category" name="groupby_category" domain="[]" context="{'group_by': 'category_id'}"/>
+ <filter string="Type" name="groupby_type" domain="[]" context="{'group_by': 'slide_type'}"/>
+ </group>
+ </search>
+ </field>
+ </record>
+
+ <record id="slide_slide_view_graph" model="ir.ui.view">
+ <field name="name">slide.slide.view.graph</field>
+ <field name="model">slide.slide</field>
+ <field name="arch" type="xml">
+ <graph string="Graph of Contents" stacked="False" sample="1">
+ <field name="channel_id" type="row"/>
+ <field name="slide_type" type="col"/>
+ <field name="total_views" type="measure"/>
+ </graph>
+ </field>
+ </record>
+
+ <record id="slide_slide_view_pivot" model="ir.ui.view">
+ <field name="name">slide.slide.view.pivot</field>
+ <field name="model">slide.slide</field>
+ <field name="arch" type="xml">
+ <pivot sample="1">
+ <field name="channel_id" type="row"/>
+ <field name="total_views" type="measure"/>
+ </pivot>
+ </field>
+ </record>
+
+ <record id="slide_slide_action" model="ir.actions.act_window">
+ <field name="name">Contents</field>
+ <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
+ </p>
+ </field>
+ </record>
+
+ <record id="slide_slide_action_report" model="ir.actions.act_window">
+ <field name="name">Contents</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">slide.slide</field>
+ <field name="view_mode">graph,tree,form,pivot</field>
+ <field name="view_id" ref="slide_slide_view_graph"/>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_smiling_face">
+ No data yet!
+ </p><p>
+ Create new content for your eLearning
+ </p>
+ </field>
+ </record>
+ </data>
+</odoo>
diff --git a/addons/website_slides/views/website_slides_menu_views.xml b/addons/website_slides/views/website_slides_menu_views.xml
new file mode 100644
index 00000000..2d19f546
--- /dev/null
+++ b/addons/website_slides/views/website_slides_menu_views.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <menuitem name="eLearning"
+ id="website_slides_menu_root"
+ web_icon="website_slides,static/description/icon.png"
+ groups="website_slides.group_website_slides_officer"
+ action="slide_channel_action_overview"/>
+
+ <!-- Main top menu elements -->
+ <menuitem name="Courses"
+ id="website_slides_menu_courses"
+ parent="website_slides_menu_root"
+ sequence="1"/>
+ <menuitem name="Reporting"
+ id="website_slides_menu_report"
+ parent="website_slides_menu_root"
+ groups="website_slides.group_website_slides_manager"
+ sequence="9"/>
+ <menuitem name="Configuration"
+ id="website_slides_menu_configuration"
+ parent="website_slides_menu_root"
+ sequence="99"/>
+
+ <!-- Courses sub-menu -->
+ <menuitem name="Courses"
+ id="website_slides_menu_courses_courses"
+ parent="website_slides_menu_courses"
+ sequence="1"
+ action="slide_channel_action_overview"/>
+ <menuitem name="Contents"
+ id="website_slides_menu_courses_content"
+ parent="website_slides_menu_courses"
+ sequence="2"
+ action="slide_slide_action"/>
+ <menuitem name="Reviews"
+ id="website_slides_menu_courses_reviews"
+ parent="website_slides_menu_courses"
+ sequence="3"
+ action="rating_rating_action_slide_channel"/>
+
+ <!-- Reporting sub-menu -->
+ <menuitem name="Courses"
+ id="website_slides_menu_report_courses"
+ parent="website_slides_menu_report"
+ sequence="1"
+ action="slide_channel_action_report"/>
+ <menuitem name="Contents"
+ id="website_slides_menu_report_contents"
+ parent="website_slides_menu_report"
+ sequence="2"
+ action="slide_slide_action_report"/>
+ <menuitem name="Reviews"
+ id="website_slides_menu_report_reviews"
+ parent="website_slides_menu_report"
+ sequence="6"
+ action="rating_rating_action_slide_channel_report"/>
+ <menuitem name="Quizzes"
+ id="website_slides_menu_report_quizzes"
+ parent="website_slides_menu_report"
+ sequence="7"
+ action="slide_question_action_report"/>
+
+ <!-- Settings sub-menu -->
+ <menuitem name="Settings"
+ id="website_slides_menu_config_settings"
+ parent="website_slides_menu_configuration"
+ sequence="1"
+ action="website_slides_action_settings"
+ groups="base.group_system"/>
+ <menuitem name="Course Groups"
+ id="website_slides_menu_config_course_groups"
+ parent="website_slides_menu_configuration"
+ sequence="2"
+ action="slide_channel_tag_group_action"/>
+ <menuitem name="Content Tags"
+ id="website_slides_menu_config_content_tags"
+ parent="website_slides_menu_configuration"
+ sequence="3"
+ action="action_slide_tag"/>
+
+</odoo>
diff --git a/addons/website_slides/views/website_slides_templates_course.xml b/addons/website_slides/views/website_slides_templates_course.xml
new file mode 100644
index 00000000..10587ef5
--- /dev/null
+++ b/addons/website_slides/views/website_slides_templates_course.xml
@@ -0,0 +1,848 @@
+<?xml version="1.0" ?>
+<odoo><data>
+
+<!-- Channels sub-template: header -->
+<template id="course_nav" name="Course Navigation Header">
+ <div class="o_wslides_course_nav">
+ <div class="container">
+ <div class="row align-items-center justify-content-between">
+ <!-- Desktop Mode -->
+ <nav aria-label="breadcrumb" class="col-md-8 d-none d-md-flex">
+ <ol class="breadcrumb bg-transparent mb-0 pl-0 py-0">
+ <li class="breadcrumb-item">
+ <a href="/slides">Courses</a>
+ </li>
+ <t t-set="breadcrumb_class" t-value="'breadcrumb-item %s' % ('active' if not slide else '')" />
+ <li t-att-class="'breadcrumb-item %s' % ('active' if not search_category and not search_tag and not search_slide_type and not slide else '')">
+ <a t-att-href="'/slides/%s' % slug(channel)"><span t-esc="channel.name"/></a>
+ </li>
+ <li t-att-class="breadcrumb_class" t-att-aria-current="'page' and search_category" t-if="search_category">
+ <a t-att-href="'/slides/%s/category/%s' % (slug(channel), slug(search_category))"><span t-esc="search_category.name"/></a>
+ </li>
+ <li t-att-class="breadcrumb_class" t-att-aria-current="'page' and search_tag" t-if="search_tag">
+ <a t-att-href="'/slides/%s/tag/%s' % (slug(channel), slug(search_tag))"><span t-esc="search_tag.name"/></a>
+ </li>
+ <li t-att-class="breadcrumb_class" t-att-aria-current="'page' and search_uncategorized" t-if="search_uncategorized">
+ <a t-att-href="'/slides/%s?search_uncategorized=1' % (slug(channel))">Uncategorized</a>
+ </li>
+ <li t-att-class="breadcrumb_class" t-att-aria-current="'page' and search_slide_type" t-if="search_slide_type">
+ <a t-att-href="'/slides/%s?slide_type=%s' % (slug(channel), search_slide_type)"><span t-esc="slide_types[search_slide_type]"/></a>
+ </li>
+ <li t-if="slide" class="breadcrumb-item active">
+ <a t-att-href="'/slides/slide/%s' % slug(slide)"><span t-esc="slide.name"/></a>
+ </li>
+ </ol>
+ </nav>
+
+ <div class="col-md-4 d-none d-md-flex flex-row align-items-center justify-content-end">
+ <!-- search -->
+ <form t-attf-action="/slides/all" role="search" method="get">
+ <div class="input-group o_wslides_course_nav_search ml-1 position-relative">
+ <span class="input-group-prepend">
+ <button class="btn btn-link text-white rounded-0 pr-1" type="submit" aria-label="Search" title="Search">
+ <i class="fa fa-search"></i>
+ </button>
+ </span>
+ <input type="text" class="form-control border-0 rounded-0 bg-transparent text-white" name="search" placeholder="Search courses"/>
+ </div>
+ </form>
+ </div>
+
+ <!-- Mobile Mode -->
+ <div class="col d-md-none py-1">
+ <div class="btn-group w-100 position-relative" role="group" aria-label="Mobile sub-nav">
+ <div class="btn-group w-100">
+ <a class="btn bg-black-25 text-white dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Nav</a>
+
+ <div class="dropdown-menu">
+ <a class="dropdown-item" href="/slides">Home</a>
+ <t t-set="dropdown_class" t-value="'dropdown-item %s' % ('active' if not slide else '')"/>
+ <a t-att-class="'dropdown-item %s' % ('active' if not search_category and not search_tag and not search_slide_type else '')" t-att-href="'/slides/%s' % slug(channel)">
+ &#9492;<span class="ml-1" t-esc="channel.name"/>
+ </a>
+ <a t-att-class="dropdown_class" t-att-aria-current="'page' and search_category" t-if="search_category" t-att-href="'/slides/%s/category/%s' % (slug(channel), slug(search_category))">
+ &#9492;<span class="ml-1" t-esc="search_category.name"/>
+ </a>
+ <a t-att-class="dropdown_class" t-att-aria-current="'page' and search_tag" t-if="search_tag" t-att-href="'/slides/%s/tag/%s' % (slug(channel), slug(search_tag))">
+ &#9492;<span class="ml-1" t-esc="search_tag.name"/>
+ </a>
+ <a t-att-class="dropdown_class" t-att-aria-current="'page' and search_uncategorized" t-if="search_uncategorized" t-att-href="'/slides/%s?search_uncategorized=1' % (slug(channel))">
+ &#9492;<span class="ml-1">Uncategorized</span>
+ </a>
+ <a t-att-class="dropdown_class" t-att-aria-current="'page' and search_slide_type" t-if="search_slide_type" t-att-href="'/slides/%s?slide_type=%s' % (slug(channel), search_slide_type)">
+ &#9492;<span class="ml-1" t-esc="slide_types[search_slide_type]"/>
+ </a>
+ <a t-if="slide" class="dropdown-item active" t-att-href="'/slides/slide/%s' % (slug(slide))">
+ &#9492;<span class="ml-1" t-esc="slide.name"/>
+ </a>
+ </div>
+ </div>
+
+ <div class="btn-group ml-1 position-static">
+ <a class="btn bg-black-25 text-white dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-search"></i></a>
+ <div class="dropdown-menu dropdown-menu-right w-100" style="right: 10px;">
+ <form class="px-3" t-attf-action="/slides/#{slug(channel)}" role="search" method="get">
+ <div class="input-group">
+ <input type="text" class="form-control" name="search" placeholder="Search courses"/>
+ <span class="input-group-append">
+ <button class="btn btn-primary" type="submit" aria-label="Search" title="Search">
+ <i class="fa fa-search"/>
+ </button>
+ </span>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+
+<!-- Channel main template -->
+<template id='course_main' name="Course Main" track="1">
+ <t t-set="head">
+ <t t-call-assets="web.pdf_js_lib" t-css="false"/>
+ <script type="text/javascript" src="/website_slides/static/lib/pdfslidesviewer/PDFSlidesViewer.js"></script>
+ </t>
+ <t t-set="body_classname" t-value="'o_wslides_body'"/>
+ <t t-call="website.layout">
+ <div id="wrap" t-attf-class="wrap mt-0">
+ <div t-attf-class="o_wslides_course_header o_wslides_gradient position-relative text-white pb-md-0 pt-2 pt-md-5 #{'pb-3' if channel.channel_type == 'training' else 'o_wslides_course_doc_header pb-5'}">
+ <t t-call="website_slides.course_nav"/>
+
+ <div class="container mt-5 mt-md-3 mt-xl-4">
+ <div class="row align-items-end align-items-md-stretch">
+ <!-- ==== Header Left ==== -->
+ <div class="col-12 col-md-4 col-lg-3">
+ <div class="d-flex align-items-end justify-content-around h-100">
+ <div t-if="channel.image_1920" t-field="channel.image_1920" t-options='{"widget": "image", "class": "o_wslides_course_pict d-inline-block mb-2 mt-3 my-md-0"}' class="h-100"/>
+ <div t-else="" class="h-100">
+ <img t-att-src="'/website_slides/static/src/img/channel-%s-default.jpg' % ('training' if channel.channel_type == 'training' else 'documentation')"
+ class="o_wslides_course_pict d-inline-block mb-2 mt-3 my-md-0"/>
+ </div>
+ </div>
+ </div>
+
+ <!-- ==== Header Right ==== -->
+ <div class="col-12 col-md-8 col-lg-9 d-flex flex-column">
+ <div class="d-flex flex-column">
+ <h1 t-field="channel.name"/>
+ <p class="mb-0 mb-xl-3" t-field="channel.description"/>
+
+ <div t-if="channel.channel_type == 'documentation'" class="d-flex mb-md-5">
+ <button role="button" class="btn text-white pl-0" title="Share Channel"
+ aria-label="Share Channel"
+ data-toggle="modal" t-att-data-target="'#slideChannelShareModal_%s' % channel.id">
+ <i class="fa fa-share-square"></i> Share
+ </button>
+ </div>
+ </div>
+ <div class="d-flex flex-column justify-content-center h5 flex-grow-1 mb-md-5" t-if="channel.allow_comment">
+ <t t-call="portal_rating.rating_stars_static_popup_composer">
+ <t t-set="rating_avg" t-value="rating_avg"/>
+ <t t-set="rating_total" t-value="rating_count"/>
+ <t t-set="object" t-value="channel"/>
+ <t t-set="token" t-value="channel.access_token"/>
+ <t t-set="hash" t-value="message_post_hash"/>
+ <t t-set="pid" t-value="message_post_pid"/>
+ <t t-set="default_message" t-value="last_message"/>
+ <t t-set="default_message_id" t-value="last_message_id"/>
+ <t t-set="default_rating_value" t-value="last_rating_value"/>
+ <t t-set="default_attachment_ids" t-value="last_message_attachment_ids"/>
+ <t t-set="force_submit_url" t-value="'/slides/mail/update_comment' if last_message_id else False"/>
+ <t t-set="disable_composer" t-value="not channel.can_review"/>
+ <t t-set="_link_btn_classes" t-value="'btn-link text-white'"/>
+ </t>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- Share modal : here to avoid having text-white from o_wslides_course_header -->
+ <t t-call="website_slides.slide_share_modal" t-if="channel.channel_type == 'documentation'">
+ <t t-set="record" t-value="channel"/>
+ </t>
+
+ <div class="o_wslides_course_main">
+ <!-- ========== TRAINING COURSE ========== -->
+ <div t-if="channel.channel_type == 'training'" class="container">
+ <div class="row">
+ <!-- Training Sidebar -->
+ <div class="col-12 col-md-4 col-lg-3 mt-3 mt-md-0">
+ <t t-call="website_slides.course_sidebar"/>
+ </div>
+
+ <!-- Training Content -->
+ <div class="col-12 col-md-8 col-lg-9">
+ <ul class="nav nav-tabs o_wslides_nav_tabs flex-nowrap" role="tablist" id="profile_extra_info_tablist">
+ <li class="nav-item">
+ <a t-att-class="'nav-link %s' % ('active' if active_tab == 'home' else '')"
+ id="home-tab" data-toggle="pill" href="#home" role="tab" aria-controls="home"
+ t-att-aria-selected="'true' if active_tab == 'home' else 'false'">
+ <i class="fa fa-home"/> Course
+ </a>
+ </li>
+ <li t-if="channel.allow_comment" class="nav-item o_wslides_course_header_nav_review_training">
+ <a t-att-class="'nav-link %s' % ('active' if active_tab == 'review' else '')"
+ id="review-tab" data-toggle="pill" href="#review" role="tab" aria-controls="review"
+ t-att-aria-selected="'true' if active_tab == 'review' else 'false'">
+ Reviews<t t-if="rating_count"> (<t t-esc="rating_count"/>)</t>
+ </a>
+ </li>
+ </ul>
+
+ <div class="tab-content py-4 o_wslides_tabs_content mb-4" id="courseMainTabContent">
+ <div t-att-class="'tab-pane fade %s' % ('show active' if active_tab == 'home' else '')" id="home" role="tabpanel" aria-labelledby="home-tab">
+ <div class="mb-2 pt-1">
+ <t t-if="channel.tag_ids">
+ <t t-foreach="channel.tag_ids" t-as="channel_tag">
+ <span t-attf-class="badge o_wslides_channel_tag #{'o_tag_color_'+str(channel_tag.color)}" t-esc="channel_tag.name"/>
+ </t>
+ </t>
+ <a t-if="channel.can_upload"
+ class="o_wslides_js_channel_tag_add border badge badge-light font-weight-normal py-1 m-1"
+ role="button"
+ aria-label="Add Tag"
+ href="#"
+ t-att-data-channel-id="channel.id"
+ t-att-data-channel-tag-ids="channel.tag_ids.ids">
+ <span>Add Tag</span>
+ </a>
+ </div>
+ <t t-if="channel.channel_type == 'training'" t-call="website_slides.course_slides_list"/>
+ </div>
+ <div t-if="channel.allow_comment" t-att-class="'tab-pane fade %s' % ('show active' if active_tab == 'review' else '')" id="review" role="tabpanel" aria-labelledby="review-tab">
+ <t t-call="portal.message_thread">
+ <t t-set="object" t-value="channel"/>
+ <t t-set="hash" t-value="message_post_hash"/>
+ <t t-set="pid" t-value="message_post_pid"/>
+ <t t-set="display_rating" t-value="True"/>
+ <t t-set="disable_composer" t-value="True"/>
+ </t>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- ========== DOCUMENTATION COURSE ========== -->
+ <t t-if="channel.channel_type == 'documentation'">
+ <div class="container">
+ <div class="row">
+ <div class="col-12 col-md-8 offset-md-4 col-lg-9 offset-lg-3">
+ <ul class="nav nav-tabs o_wslides_nav_tabs o_wslides_doc_nav_tabs flex-nowrap" role="tablist" id="profile_extra_info_tablist">
+ <li class="nav-item">
+ <a t-att-class="'nav-link %s' % ('active' if active_tab == 'home' else '')"
+ id="home-tab" data-toggle="pill" href="#home" role="tab" aria-controls="home"
+ t-att-aria-selected="'true' if active_tab == 'home' else 'false'">
+ <i class="fa fa-home"/>
+ Course
+ </a>
+ </li>
+ <li t-if="channel.allow_comment" class="nav-item o_wslides_course_header_nav_review_documentation">
+ <a t-att-class="'nav-link %s' % ('active' if active_tab == 'review' else '')"
+ id="review-tab" data-toggle="pill" href="#review" role="tab" aria-controls="review"
+ t-att-aria-selected="'true' if active_tab == 'review' else 'false'">
+ Reviews<t t-if="rating_count"> (<t t-esc="rating_count"/>)</t>
+ </a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+
+ <div class="tab-content pb-5" id="courseMainTabContent">
+ <div t-att-class="'tab-pane fade %s' % ('show active' if active_tab == 'home' else '')" id="home" role="tabpanel" aria-labelledby="home-tab">
+ <t t-if="channel.channel_type == 'documentation'" t-call="website_slides.course_slides_cards"/>
+ </div>
+ <div t-if="channel.allow_comment" t-att-class="'tab-pane fade %s' % ('show active' if active_tab == 'review' else '')" id="review" role="tabpanel" aria-labelledby="review-tab">
+ <div class="container pt-4">
+ <t t-call="portal.message_thread">
+ <t t-set="object" t-value="channel"/>
+ <t t-set="hash" t-value="message_post_hash"/>
+ <t t-set="pid" t-value="message_post_pid"/>
+ <t t-set="display_rating" t-value="True"/>
+ <t t-set="disable_composer" t-value="True"/>
+ </t>
+ </div>
+ </div>
+ </div>
+ </t>
+ </div>
+ </div>
+
+ <t t-call="website_slides.slide_share_modal">
+ <t t-set="record" t-value="channel"/>
+ </t>
+ </t>
+</template>
+
+<template id="course_sidebar" name="Course Sidebar (infos, CTA)">
+ <!-- Training-only: Channel sidebar (aka general information + CTAs) -->
+ <div class="o_wslides_course_sidebar bg-white px-3 py-2 py-md-3 mb-3 mb-md-5">
+
+ <div class="o_wslides_sidebar_top d-flex justify-content-between">
+ <div class="o_wslides_js_course_join flex-grow-1">
+ <a t-if="not channel.is_member and channel.enroll == 'public'" role="button"
+ class="btn btn-primary btn-block o_wslides_js_course_join_link"
+ title="Start Course" aria-label="Start Course Channel"
+ t-att-href="'#'"
+ t-att-data-channel-id="channel.id"
+ t-att-data-channel-enroll="channel.enroll">
+ <span class="cta-title text_small_caps">
+ <t t-if="channel.channel_type == 'documentation'">Start Course</t>
+ <t t-else="">Join Course</t>
+ </span>
+ </a>
+
+ <div t-if="not channel.is_member and channel.enroll == 'invite'" class="text-center">
+ <div t-attf-class="alert my-0 bg-100 p-2 #{'o_wslides_js_channel_enroll' if not is_public_user else ''}"
+ t-att-data-channel-id="channel.id">
+ Private Course
+ <div t-if="is_public_user">
+ <small>
+ Please <a t-att-href="'/web/login?redirect=/slides/%s' % (slug(channel))">sign in</a> to contact responsible.
+ </small>
+ </div>
+ <div t-elif="channel.has_requested_access">
+ <small class="text-success">
+ Request already sent
+ </small>
+ </div>
+ <div t-else="" class="o_wslides_enroll_msg">
+ <small>
+ <div t-field="channel.enroll_msg"/>
+ </small>
+ </div>
+ </div>
+ </div>
+ <t t-if="channel.is_member">
+ <button class="d-flex align-items-center alert my-0 px-2 px-xl-3 bg-100 w-100 o_wslides_js_channel_unsubscribe"
+ t-att-data-channel-id="channel.id"
+ t-att-data-is-follower="channel.message_is_follower"
+ t-att-data-enroll="channel.enroll">
+ <t t-call="website_slides.slides_misc_user_image">
+ <t t-set="img_class" t-value="'rounded-circle mr-1'"/>
+ <t t-set="img_style" t-value="'width: 1.4em; height: 1.4em; object-fit: cover;'"/>
+ </t>
+ <h6 class="d-flex flex-grow-1 my-0">You're enrolled</h6>
+ <i class="fa fa-check"/>
+ <i class="fa fa-times"/>
+ </button>
+ <div class="d-flex align-items-center pt-3">
+ <t t-if="channel.completed">
+ <span class="badge badge-pill badge-success py-1 px-2 mx-auto" style="font-size: 1em"><i class="fa fa-check"/> Completed</span>
+ </t>
+ <t t-else="">
+ <div class="progress flex-grow-1 bg-black-50" style="height: 6px;">
+ <div class="progress-bar" role="progressbar" t-attf-style="width: #{channel.completion}%" t-att-aria-valuenow="channel.completion" aria-valuemin="0" aria-valuemax="100"></div>
+ </div>
+ <div class="ml-3 small">
+ <span class="o_wslides_progress_percentage" t-esc="channel.completion"/> %
+ </div>
+ </t>
+ </div>
+ </t>
+ </div>
+ <button t-attf-class="btn d-md-none bg-white ml-1 border #{'alert' if channel.is_member else ''} #{'align-self-start' if channel.is_member or channel.enroll == 'invite' else 'align-self-end'}" type="button" data-toggle="collapse" data-target="#o_wslides_sidebar_collapse" aria-expanded="false" aria-controls="o_wslides_sidebar_collapse">More info</button>
+ </div>
+
+ <div id="o_wslides_sidebar_collapse" class="collapse d-md-block">
+ <table class="table table-sm mt-3">
+ <tr t-if="channel.user_id">
+ <th class="border-top-0">Responsible</th>
+ <td class="border-top-0"><span t-field="channel.user_id"/></td>
+ </tr>
+ <tr>
+ <th class="border-top-0">Last Update</th>
+ <td class="border-top-0"><t t-esc="channel.slide_last_update" t-options="{'widget': 'date'}"/></td>
+ </tr>
+ <tr t-if="channel.total_time">
+ <th class="border-top-0">Completion Time</th>
+ <td class="border-top-0"><t class="font-weight-bold" t-esc="channel.total_time" t-options="{'widget': 'duration', 'unit': 'hour', 'round': 'minute'}"/></td>
+ </tr>
+ <tr>
+ <th>Members</th>
+ <td><t t-esc="channel.members_count"/></td>
+ </tr>
+ </table>
+
+ <div class="mt-3">
+ <button role="button" class="btn btn-link btn-block" title="Share Channel"
+ aria-label="Share Channel"
+ data-toggle="modal" t-att-data-target="'#slideChannelShareModal_%s' % channel.id">
+ <i class="fa fa-share-square fa-fw"/> Share
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<template id="course_slides_list" name="Training Course content: list">
+ <div class="mb-5 o_wslides_slides_list" t-att-data-channel-id="channel.id">
+
+ <ul class="o_wslides_js_slides_list_container list-unstyled">
+ <t t-set="j" t-value="0"/>
+ <t t-foreach="category_data" t-as="category">
+ <t t-set="category_id" t-value="category['id'] if category['id'] else None"/>
+
+ <li t-if="category['total_slides'] or channel.can_publish" t-att-class="'o_wslides_slide_list_category o_wslides_js_list_item mb-2' if category_id else 'mt-4'" t-att-data-slide-id="category_id" t-att-data-category-id="category_id">
+ <div t-att-data-category-id="category_id"
+ t-att-class="'o_wslides_slide_list_category_header position-relative d-flex justify-content-between align-items-center mt8 %s %s' % ('bg-white shadow-sm border-bottom-0' if category_id else 'border-0', 'o_wslides_js_category py-0' if channel.can_upload else 'py-2')">
+ <div t-att-class="'d-flex align-items-center pl-3 %s' % ('o_wslides_slides_list_drag' if channel.can_publish else '')">
+ <div t-if="channel.can_publish and category_id" class="o_wslides_slides_list_drag py-2 pr-3">
+ <i class="fa fa-bars"/>
+ </div>
+ <span t-if="category_id" t-field="category['category'].name"/>
+ <small t-if="not category['total_slides'] and category_id" class="ml-1 text-muted"><b>(empty)</b></small>
+ </div>
+ <div t-if="category_id" class="o_text_link d-flex border-left">
+ <a t-if="channel.can_upload"
+ class="o_wslides_js_slide_upload px-3 py-2"
+ role="button"
+ aria-label="Upload Presentation"
+ href="#"
+ t-att-data-modules-to-install="modules_to_install"
+ t-att-data-channel-id="channel.id"
+ t-att-data-category-id="category_id"
+ t-att-data-can-upload="channel.can_upload"
+ t-att-data-can-publish="channel.can_publish">
+ <i class="fa fa-plus mr-1"/> <span class="d-none d-md-inline-block">Add Content</span>
+ </a>
+ </div>
+ </div>
+ <ul t-att-data-category-id="category_id" class="list-unstyled pb-1 border-top">
+ <li class="o_wslides_slides_list_slide o_not_editable border-0"/>
+ <li class="o_wslides_js_slides_list_empty border-0"/>
+
+ <t t-foreach="category['slides']" t-as="slide">
+ <t t-call="website_slides.course_slides_list_slide" />
+ <t t-set="j" t-value="j+1"/>
+ </t>
+ </ul>
+ </li>
+ </t>
+ </ul>
+ <div t-if="channel.can_upload" class="o_wslides_content_actions btn-group">
+ <a class="o_wslides_js_slide_upload mr-1 border btn btn-primary"
+ role="button"
+ aria-label="Upload Presentation"
+ href="#"
+ t-att-data-open-modal="enable_slide_upload"
+ t-att-data-modules-to-install="modules_to_install"
+ t-att-data-channel-id="channel.id"
+ t-att-data-can-upload="channel.can_upload"
+ t-att-data-can-publish="channel.can_publish"><i class="fa fa-plus mr-1"/><span>Add Content</span></a>
+ <a class="o_wslides_js_slide_section_add border btn btn-light bg-white" t-attf-channel_id="#{channel.id}"
+ href="#" role="button"
+ groups="website_slides.group_website_slides_officer"><i class="fa fa-folder-o mr-1"/><span>Add Section</span></a>
+ </div>
+ <t t-if="not channel.slide_ids and channel.can_publish">
+ <t t-call="website_slides.course_slides_list_sample"/>
+ </t>
+ </div>
+ <div t-field="channel.description_html"/>
+</template>
+
+<template id="course_slides_list_sample" name="Course Sample Content">
+ <ul class="list-unstyled mt-3" style="opacity: 50%;">
+ <li class="o_wslides_slide_list_category mb-2">
+ <div class="o_wslides_slide_list_category_header position-relative d-flex justify-content-between align-items-center mt8 bg-white shadow-sm border-bottom-0 py-2">
+ <div class="d-flex align-items-center pl-3">
+ <span class="text-muted">Common tasks for a computer scientist</span>
+ </div>
+ </div>
+ <ul class="list-unstyled pb-1 border-top">
+ <li class="o_wslides_slides_list_slide bg-white-50 border-top-0 d-flex align-items-center pl-2 py-1 pr-2">
+ <i class="fa fa-file-text py-2 mx-2"/>
+ <div class="text-truncate mr-auto">
+ <span>Asking Question</span>
+ </div>
+ <div class="d-flex flex-row">
+ <span class="badge font-weight-bold px-2 py-1 m-1 badge-warning">
+ <i class="fa fa-fw fa-flag"/> 10 xp
+ </span>
+ </div>
+ </li>
+ <li class="o_wslides_slides_list_slide bg-white-50 border-top-0 d-flex align-items-center pl-2 py-1 pr-2">
+ <i class="fa fa-question-circle py-2 mx-2"/>
+ <div class="text-truncate mr-auto">
+ <span>Asking the right question</span>
+ </div>
+ </li>
+ <li class="o_wslides_slides_list_slide bg-white-50 border-top-0 d-flex align-items-center pl-2 py-1 pr-2">
+ <i class="fa fa-file-pdf-o py-2 mx-2"/>
+ <div class="text-truncate mr-auto">
+ <span>Answering Questions</span>
+ </div>
+ <div class="d-flex flex-row">
+ <span class="badge badge-info badge-arrow-right font-weight-normal px-2 py-1 m-1">New</span>
+ </div>
+ </li>
+ </ul>
+ </li>
+ <li class="o_wslides_slide_list_category mb-2">
+ <div class="o_wslides_slide_list_category_header position-relative d-flex justify-content-between align-items-center mt8 bg-white shadow-sm border-bottom-0 py-2">
+ <div class="d-flex align-items-center pl-3">
+ <span class="text-muted">Parts of computer science</span>
+ </div>
+ </div>
+ <ul class="list-unstyled pb-1 border-top">
+ <li class="o_wslides_slides_list_slide bg-white-50 border-top-0 d-flex align-items-center pl-2 py-1 pr-2">
+ <i class="fa fa-file-pdf-o py-2 mx-2"/>
+ <div class="text-truncate mr-auto">
+ <span>Mathematics</span>
+ </div>
+ </li>
+ <li class="o_wslides_slides_list_slide bg-white-50 border-top-0 d-flex align-items-center pl-2 py-1 pr-2">
+ <i class="fa fa-file-pdf-o py-2 mx-2"/>
+ <div class="text-truncate mr-auto">
+ <span>Science</span>
+ </div>
+ </li>
+ <li class="o_wslides_slides_list_slide bg-white-50 border-top-0 d-flex align-items-center pl-2 py-1 pr-2">
+ <i class="fa fa-play py-2 mx-2"/>
+ <div class="text-truncate mr-auto">
+ <span>Logic</span>
+ </div>
+ <div class="d-flex flex-row">
+ <span class="badge badge-success font-weight-normal px-2 py-1 m-1">Preview</span>
+ </div>
+ </li>
+ </ul>
+ </li>
+ </ul>
+</template>
+
+<template id="course_slides_list_slide" name="Slide template for a training channel">
+ <li t-att-index="j" t-att-data-slide-id="slide.id" t-att-data-category-id="category_id" t-attf-class="o_wslides_slides_list_slide o_wslides_js_list_item bg-white-50 border-top-0 d-flex align-items-center pl-2 #{'py-1 pr-2' if not channel.can_upload else ''}">
+ <div t-if="channel.can_publish" class=" o_wslides_slides_list_drag border-right p-2">
+ <i class="fa fa-bars mr-2"></i>
+ </div>
+ <t t-call="website_slides.slide_icon">
+ <t t-set="icon_class" t-value="'py-2 mx-2'"/>
+ </t>
+ <div class="text-truncate mr-auto">
+ <a t-if="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"/>
+ </a>
+ <span t-else="">
+ <span t-esc="slide.name"/>
+ </span>
+ </div>
+
+ <div class="d-flex flex-row">
+ <a name="o_wslides_list_slide_add_quizz" t-if="channel.can_upload and not slide.question_ids" t-attf-href="/slides/slide/#{slug(slide)}?quiz_quick_create">
+ <span class="badge badge-light badge-hide border font-weight-normal px-2 py-1 m-1">Add Quiz</span>
+ </a>
+ <a t-if="channel.can_upload" href="#">
+ <span t-att-data-slide-id="slide.id" t-attf-class="o_wslides_js_slide_toggle_is_preview badge #{'badge-success' if slide.is_preview else 'badge-light badge-hide border'} font-weight-normal px-2 py-1 m-1"><span>Preview</span></span>
+ </a>
+ <t t-elif="slide.is_preview and not channel.is_member">
+ <span class="badge badge-success font-weight-normal px-2 py-1 m-1"><span>Preview</span></span>
+ </t>
+ <span t-if="slide.is_new_slide and not channel_progress[slide.id].get('completed')" class="badge badge-info badge-arrow-right font-weight-normal px-2 py-1 m-1">
+ New
+ </span>
+ <span t-if="slide.question_ids" t-att-class="'badge font-weight-bold px-2 py-1 m-1 %s' % ('badge-success' if channel_progress[slide.id].get('completed') else 'badge-warning')">
+ <i t-attf-class="fa fa-fw #{'fa-check' if channel_progress[slide.id].get('completed') else 'fa-flag'}"/>
+ <t t-esc="channel_progress[slide.id].get('quiz_karma_won', 0) if channel_progress[slide.id].get('completed') else channel_progress[slide.id].get('quiz_karma_gain', 0)"/> xp
+ </span>
+ <span class="badge badge-danger font-weight-normal px-2 py-1 m-1" t-if="not slide.website_published">Unpublished</span>
+ </div>
+
+ <div t-if="channel.is_member or channel.can_publish" class="pt-2 pb-2 border-left ml-2 mr-2 pl-2 d-flex flex-row align-items-center o_wslides_slides_list_slide_controls">
+ <t t-if="channel.is_member">
+ <i t-if="not channel_progress[slide.id].get('completed')" class="check-done fa fa-circle-o text-500 px-2"></i>
+ <i t-else="" class="check-done text-success fa fa-check-circle px-2"></i>
+ </t>
+ <span t-if="channel.can_publish" class="d-none d-md-flex">
+ <a t-if="slide.slide_type == 'webpage'" class="px-2 o_text_link text-primary" target="_blank" t-attf-href="/slides/slide/#{slug(slide)}?enable_editor=1"><span class="fa fa-pencil"/></a>
+ <a t-else="" class="px-2 o_text_link text-primary" target="_blank" t-attf-href="/web#id=#{slide.id}&amp;action=#{slide_action}&amp;model=slide.slide&amp;view_type=form" title="Edit in backend"><span class="fa fa-pencil"/></a>
+ <a href="#" t-att-data-slide-id="slide.id" class="o_text_link text-danger px-2 o_wslides_js_slide_archive"><span class="fa fa-trash"/></a>
+ </span>
+ </div>
+ </li>
+</template>
+
+<!-- ======= Documentation Course content: cards / categories======= -->
+<template id="course_promoted_slide" name="Documentation Course content: promoted slide">
+ <div class="o_wslides_promoted_slide">
+ <div t-if="not search and not search_slide_type and slide_promoted" class="container py-1 mb-2">
+ <div class="card flex-column flex-lg-row">
+ <t t-set="image_url" t-value="website.image_url(slide_promoted, 'image_1024')"/>
+
+ <a t-if="slide_promoted.is_preview or channel.is_member or is_slides_publisher"
+ t-attf-href="/slides/slide/#{slug(slide_promoted)}#{query_string}" class="w-100 w-lg-50 flex-shrink-0 rounded">
+ <div t-attf-style="background-image:url(#{image_url}); background-size: cover; background-position:center; padding-bottom: 35%;" class="h-lg-100"/>
+ </a>
+ <div t-else="" class="w-100 w-lg-50 flex-shrink-0 rounded">
+ <div t-attf-style="background-image:url(#{image_url}); background-size: cover; background-position:center; padding-bottom: 35%;" class="h-lg-100"/>
+ </div>
+
+ <div class="card-body">
+ <a t-if="slide_promoted.is_preview or channel.is_member or is_slides_publisher"
+ t-attf-href="/slides/slide/#{slug(slide_promoted)}#{query_string}"
+ class="h4 d-block" t-att-title="slide_promoted.name" t-field="slide_promoted.name"/>
+ <h4 t-else="" class="text-muted" t-field="slide_promoted.name"/>
+
+ <div t-if="slide_promoted.tag_ids" class="border-top mt-2 pt-1">
+ <t t-foreach="slide_promoted.tag_ids" t-as="tag">
+ <a t-att-href="'/slides/%s/tag/%s' % (slug(slide_promoted.channel_id), slug(tag))" class="badge badge-light" t-esc="tag.name"/>
+ </t>
+ </div>
+ <div class="o_wslides_desc_truncate_10 mt-3" t-field="slide_promoted.description"/>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<template id="course_slides_cards" name="Documentation Course content: cards / categories">
+ <div class="o_wslides_lesson_nav mb-4 border-bottom">
+ <div class="container">
+ <div class="row">
+ <nav class="navbar navbar-expand-lg navbar-light col d-flex align-items-start">
+ <a class="navbar-brand d-lg-none" href="#">Filter &amp; order</a>
+
+ <div class="form-inline ml-auto d-lg-none" t-if="search_slide_type or search">
+ <a t-att-href="'/slides/%s' % (slug(channel))" class="btn btn-info mr-3">
+ <i class="fa fa-eraser mr-1"/>Clear filters
+ </a>
+ </div>
+
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
+ <span class="navbar-toggler-icon"></span>
+ </button>
+
+ <div class="collapse navbar-collapse" id="navbarSupportedContent">
+ <ul class="navbar-nav mr-lg-auto align-items-lg-center">
+
+ <t t-set="slide_type_keys" t-value="slide_types.keys()"/>
+ <t t-foreach="slide_type_keys" t-as="slide_type_key">
+ <t t-if="search_category">
+ <li t-if="search_category['nbr_%s' % slide_type_key] > 0" class="nav-item">
+ <a t-att-href="'/slides/%s/category/%s?%s' % (slug(channel), slug(search_category), keep_query(slide_type=slide_type_key))"
+ t-att-class="'nav-link d-flex align-items-center justify-content-between pl-0 mr-1 %s' % ('active' if search_slide_type == slide_type_key else '')">
+ <t t-esc="slide_types[slide_type_key]"/>
+ <span t-attf-class="badge badge-pill ml-1 #{'badge-info' if search_slide_type == slide_type_key else 'bg-400'}" t-esc="search_category['nbr_%s' % slide_type_key]"/>
+ </a>
+ </li>
+ </t>
+ <t t-else="">
+ <li t-if="channel['nbr_%s' % slide_type_key] > 0" class="nav-item">
+ <a t-att-href="'/slides/%s?%s' % (slug(channel), keep_query(slide_type=slide_type_key))"
+ t-att-class="'nav-link d-flex align-items-center justify-content-between pl-0 mr-1 %s' % ('active' if search_slide_type == slide_type_key else '')">
+ <t t-esc="slide_types[slide_type_key]"/>
+ <span t-attf-class="badge badge-pill ml-1 #{'badge-info' if search_slide_type == slide_type_key else 'bg-400'}" t-esc="channel['nbr_%s' % slide_type_key]"/>
+ </a>
+ </li>
+ </t>
+ </t>
+ </ul>
+
+ <ul class="navbar-nav mr-auto">
+ <li class="nav-item dropdown ml-lg-auto">
+ <a class="nav-link dropdown-toggle dropdown-toggle align-items-center d-flex" type="button" id="slidesChannelDropdownSort"
+ data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" href="#">
+ <b>Order by</b>
+ <span class="d-none d-xl-inline">:
+ <t t-if="sorting == 'most_voted'">Most Voted</t>
+ <t t-elif="sorting == 'most_viewed'">Most Viewed</t>
+ <t t-else="">Newest</t>
+ </span>
+ </a>
+ <div class="dropdown-menu" aria-labelledby="slidesChannelDropdownSort" role="menu">
+ <h6 class="dropdown-header">Sort by</h6>
+ <a role="menuitem" t-att-href="'/slides/%s?%s' % (slug(channel), keep_query('slide_type', sorting='latest'))"
+ t-att-class="'dropdown-item %s' % ('active' if sorting and sorting == 'latest' else '')">Newest</a>
+ <a role="menuitem" t-att-href="'/slides/%s?%s' % (slug(channel), keep_query('slide_type', sorting='most_voted'))"
+ t-att-class="'dropdown-item %s' % ('active' if sorting and sorting == 'most_voted' else '')">Most Voted</a>
+ <a role="menuitem" t-att-href="'/slides/%s?%s' % (slug(channel), keep_query('slide_type', sorting='most_viewed'))"
+ t-att-class="'dropdown-item %s' % ('active' if sorting and sorting == 'most_viewed' else '')">Most Viewed</a>
+ </div>
+ </li>
+ </ul>
+
+ <div class="form-inline mr-3 d-none d-lg-inline-block">
+ <a t-if="search_slide_type or search" t-att-href="'/slides/%s' % (slug(channel))" class="btn btn-sm btn-info ml-1">
+ <i class="fa fa-eraser mr-1"/>Clear filters
+ </a>
+ </div>
+
+ <form t-attf-action="/slides/#{slug(channel)}" role="search" method="get" class="form-inline my-2 my-lg-0">
+ <div class="input-group position-relative">
+ <input type="text" class="form-control border" name="search" placeholder="Search in content" t-att-value="search"/>
+ <div class="input-group-append">
+ <button class="btn border" type="submit" aria-label="Search" title="Search">
+ <i class="fa fa-search"/>
+ </button>
+ </div>
+ </div>
+ </form>
+ </div>
+ </nav>
+ </div>
+ </div>
+ </div>
+
+ <div class="container">
+ <div class="row">
+ <div class="mb-2 pt-1 text-left col">
+ <t t-if="channel.tag_ids">
+ <t t-foreach="channel.tag_ids" t-as="channel_tag">
+ <span t-attf-class="badge o_wslides_channel_tag #{'o_tag_color_'+str(channel_tag.color)}" t-esc="channel_tag.name"/>
+ </t>
+ </t>
+ <a t-if="channel.can_upload"
+ class="o_wslides_js_channel_tag_add border badge badge-light font-weight-normal py-1 m-1"
+ role="button"
+ aria-label="Add Tag"
+ href="#"
+ t-att-data-channel-id="channel.id"
+ t-att-data-channel-tag-ids="channel.tag_ids.ids">
+ <i class="fa fa-plus mr-1"/><span>Add Tag</span>
+ </a>
+ </div>
+
+ <div t-if="channel.can_upload" class="text-right pb-2 col-auto">
+ <a class="btn btn-primary py-1 o_wslides_js_slide_upload"
+ title="Upload Presentation" role="button"
+ aria-label="Upload Presentation" href="#"
+ t-att-data-channel-id="channel.id"
+ t-att-data-can-upload="channel.can_upload"
+ t-att-data-can-publish="channel.can_publish">
+ <i class="fa fa-cloud-upload mr-1"/>Upload new content
+ </a>
+ <a class="btn btn-secondary py-1 o_wslides_js_slide_section_add"
+ title="Add Section" role="button"
+ aria-label="Add Section" href="#"
+ t-att-channel_id="channel.id">
+ <i class="fa fa-folder-o mr-1"/>Add a section
+ </a>
+ </div>
+ </div>
+ </div>
+ <!-- Featured lesson -->
+ <t t-if="channel.promote_strategy != 'none'">
+ <t t-call="website_slides.course_promoted_slide"/>
+ </t>
+
+ <div class="container py-2">
+ <t t-if="search">
+ <t t-set="search_results_number" t-value="0"/>
+ <t t-foreach="category_data" t-as="category">
+ <t t-set="search_results_number" t-value="search_results_number + category['total_slides']"/>
+ </t>
+ <div t-if="search_results_number == 0" class="alert alert-info mt-4 mb-5 text-center">
+ No content was found using your search <span class="font-weight-bold" t-esc="search"/>.
+ </div>
+ </t>
+
+ <t t-foreach="category_data" t-as="category">
+ <div class="mb-2" t-if="(category['slides'] or channel.can_publish) and (search_category and search_category.id == category['id'] or not search_category)">
+ <t t-set="is_empty_editable" t-value="not category['slides'] and channel.can_publish"/>
+ <div class="d-flex align-items-center justify-content-between border-bottom pb-2 mb-3" t-if="category['id'] and query_string != '?search_uncategorized=1'">
+ <h5 t-attf-class="m-0 #{'text-muted' if is_empty_editable else ''}"><t t-esc="category['name']"/></h5>
+ <a t-if="category['id'] and not is_empty_editable" t-att-href="'/slides/%s/category/%s' % (slug(channel), category['slug_name'])">View all</a>
+ </div>
+ <div class="d-flex align-items-center justify-content-between border-bottom pb-2 mb-3" t-if="not category['id'] and len(category['slides']) > 0">
+ <h5 t-if="len(category_data) > 1" t-attf-class="m-0 #{'text-muted' if is_empty_editable else ''}"><t t-esc="category['name']"/></h5>
+ <a t-att-href="'/slides/%s?uncategorized=1' % (slug(channel))">View all</a>
+ </div>
+ <div class="row mx-n2">
+ <t t-foreach="category['slides']" t-as="slide">
+ <div class="col-12 col-sm-6 col-lg-3 px-2 d-flex flex-grow-1" t-call="website_slides.lesson_card"/>
+ </t>
+ </div>
+ </div>
+ </t>
+
+ <div class="row">
+ <div class="col" t-field="channel.description_html"/>
+ </div>
+ </div>
+ <t t-if="search_category or search_uncategorized">
+ <div class="form-inline justify-content-center pb-5">
+ <t t-call="website_profile.pager_nobox"></t>
+ </div>
+ </t>
+</template>
+
+<template id='lesson_card' name="Lesson Card">
+ <div class="card w-100 o_wslides_lesson_card mb-4">
+ <t t-if="slide.is_new_slide and not channel_progress[slide.id].get('completed')" t-call="website_slides.course_card_information"/>
+ <t t-set="can_access" t-value="slide.is_preview or channel.is_member or channel.can_publish"/>
+
+ <t t-if="slide.image_1024">
+ <t t-set="lesson_image" t-value="website.image_url(slide, 'image_1024')"/>
+ <a t-if="can_access" t-attf-href="/slides/slide/#{slug(slide)}#{query_string}" t-title="slide.name">
+ <div class="card-img-top border-bottom" t-attf-style="padding-top: 50%; background-image: url(#{lesson_image}); background-size: cover; background-position:center"/>
+ </a>
+ <div t-else="" class="card-img-top border-bottom" t-attf-style="padding-top: 50%; background-image: url(#{lesson_image}); background-size: cover; background-position:center"/>
+ </t>
+ <t t-else="">
+ <a t-if="can_access" t-attf-href="/slides/slide/#{slug(slide)}#{query_string}" t-title="slide.name">
+ <div class="card-img-top border-bottom o_wslides_gradient" t-attf-style="padding-top: 50%;"/>
+ </a>
+ <div t-else="" class="card-img-top border-bottom o_wslides_gradient" t-attf-style="padding-top: 50%;"/>
+ </t>
+ <i t-if="channel_progress[slide.id].get('completed')" class="position-absolute py-1 px-2 h5 fa fa-check-circle text-primary" style="right:0; top:0;"/>
+
+ <div class="card-body p-3">
+ <a t-if="can_access" class="card-title h5 mb-2o_wslides_desc_truncate_2" t-attf-href="/slides/slide/#{slug(slide)}#{query_string}" t-esc="slide.name"/>
+ <span t-else="" class="card-title h5 mb-2 o_wslides_desc_truncate_2 text-muted" t-esc="slide.name"/>
+ <div class="card-subtitle mb-2 text-muted" t-if="slide.is_preview or (not slide.is_published and user.has_group('website_slides.group_website_slides_officer'))">
+ <t t-if="slide.is_preview">
+ <span class="badge badge-info">Preview</span>
+ </t>
+ <t t-if="not slide.is_published and channel.can_publish">
+ <span class="badge badge-danger">Unpublished</span>
+ </t>
+ </div>
+ <div class="card-text pt-2">
+ <div class="o_wslides_desc_truncate_3 font-weight-light oe_no_empty" t-field="slide.description"/>
+ <div t-if="slide.tag_ids" class="mt-2 pt-1 o_wslides_desc_truncate_2">
+ <t t-foreach="slide.tag_ids" t-as="tag">
+ <a t-att-href="'/slides/%s/tag/%s' % (slug(slide.channel_id), slug(tag))" class="badge badge-light" t-esc="tag.name"/>
+ </t>
+ </div>
+ </div>
+ </div>
+ <div class="card-footer bg-white text-600">
+ <div class="d-flex align-items-center small">
+ <span class="font-weight-bold mr-auto" t-field="slide.completion_time" t-options='{"widget": "float_time"}'/>
+ <div class="o_wslides_js_slide_like mr-2">
+ <span t-att-class="'o_wslides_js_slide_like_up %s' % ('disabled' if not channel.can_vote else '')" tabindex="0" data-toggle="popover" t-att-data-slide-id="slide.id">
+ <i class="fa fa-thumbs-up fa-1x" role="img" aria-label="Likes" title="Likes"></i>
+ <span t-esc="slide.likes"/>
+ </span>
+ <span t-att-class="'o_wslides_js_slide_like_down %s' % ('disabled' if not channel.can_vote else '')" tabindex="0" data-toggle="popover" t-att-data-slide-id="slide.id">
+ <i class="fa fa-thumbs-down fa-1x" role="img" aria-label="Dislikes" title="Dislikes"></i>
+ <span t-esc="slide.dislikes"/>
+ </span>
+ </div>
+ <t t-if="channel.is_member and channel_progress[slide.id].get('completed')">
+ <span class="badge badge-pill badge-success"><i class="fa fa-check"/> Completed</span>
+ </t>
+ </div>
+ </div>
+ </div>
+</template>
+
+<template id="slide_icon">
+ <t t-set="icon_class" t-value="icon_class if icon_class else 'mr-2 text-muted'"/>
+ <i t-if="slide.slide_type == 'document'" t-att-class="'fa fa-file-pdf-o %s' % icon_class"></i>
+ <i t-if="slide.slide_type == 'presentation'" t-att-class="'fa fa-file-pdf-o %s' % icon_class"></i>
+ <i t-if="slide.slide_type == 'infographic'" t-att-class="'fa fa-file-picture-o %s' % icon_class"></i>
+ <i t-if="slide.slide_type == 'video'" t-att-class="'fa fa-play-circle %s' % icon_class"></i>
+ <i t-if="slide.slide_type == 'link'" t-att-class="'fa fa-file-code-o %s' % icon_class"></i>
+ <i t-if="slide.slide_type == 'webpage'" t-att-class="'fa fa-file-text %s' % icon_class"></i>
+ <i t-if="slide.slide_type == 'quiz'" t-att-class="'fa fa-question-circle %s' % icon_class"></i>
+</template>
+
+</data></odoo>
diff --git a/addons/website_slides/views/website_slides_templates_homepage.xml b/addons/website_slides/views/website_slides_templates_homepage.xml
new file mode 100644
index 00000000..20a5089d
--- /dev/null
+++ b/addons/website_slides/views/website_slides_templates_homepage.xml
@@ -0,0 +1,508 @@
+<?xml version="1.0" ?>
+<odoo><data>
+
+<!-- Channels home template -->
+<template id='courses_home' name="Odoo Courses Homepage">
+ <t t-set="body_classname" t-value="'o_wslides_body'"/>
+ <t t-call="website.layout">
+ <div id="wrap" class="wrap o_wslides_wrap">
+ <section class="s_banner overflow-hidden bg-900" style="background-image: url(&quot;/website_slides/static/src/img/banner_default.svg&quot;); background-size: cover; background-position: 55% 65%" data-snippet="s_banner">
+ <div class="container align-items-center d-flex mb-5 mt-lg-5 pt-lg-4 pb-lg-1">
+ <div>
+ <h1 class="display-3 mb-0">Reach new heights</h1>
+ <h2 class="mb-4">Start your online course today!</h2>
+ <div class="row mt-1 mb-3">
+ <div class="col">
+ <p>Skill up and have an impact! Your business career starts here.<br/>Time to start a course.</p>
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+ <div class="container mt16 o_wslides_home_nav position-relative">
+ <nav class="navbar navbar-expand-lg navbar-light shadow-sm" style="background: white!important">
+ <form method="GET" class="form-inline o_wslides_nav_navbar_right order-lg-3" t-attf-action="/slides/all" role="search">
+ <div class="input-group">
+ <input type="search" name="search" class="form-control" placeholder="Search courses" aria-label="Search" t-att-value="search_term"/>
+ <div class="input-group-append">
+ <button class="btn border border-left-0 oe_search_button" type="submit" aria-label="Search" title="Search">
+ <i class="fa fa-search"/>
+ </button>
+ </div>
+ </div>
+ </form>
+ <button class="navbar-toggler px-2 order-1" type="button"
+ data-toggle="collapse" data-target="#navbarSlidesHomepage"
+ aria-controls="navbarSlidesHomepage" aria-expanded="false" aria-label="Toggle navigation">
+ <span class="navbar-toggler-icon"/>
+ </button>
+ <div class="collapse navbar-collapse order-2" id="navbarSlidesHomepage">
+ <div class="navbar-nav pt-3 pt-lg-0">
+ <a class="nav-link nav-link mr-md-2 o_wslides_home_all_slides" href="/slides/all"><i class="fa fa-graduation-cap mr-1"/>All courses</a>
+ </div>
+ </div>
+ </nav>
+ <div class="o_wprofile_email_validation_container">
+ <t t-call="website_profile.email_validation_banner">
+ <t t-set="redirect_url" t-value="'/slides'"/>
+ <t t-set="send_alert_classes" t-value="'alert alert-danger alert-dismissable mt-4 mb-0'"/>
+ <t t-set="done_alert_classes" t-value="'alert alert-success alert-dismissable mt-4 mb-0'"/>
+ <t t-set="send_validation_email_message">Click here to send a verification email allowing you to participate at the eLearning.</t>
+ <t t-set="additional_validated_email_message"> You may now participate in our eLearning.</t>
+ </t>
+ </div>
+ </div>
+
+ <div class="container o_wslides_home_main">
+ <div class="row">
+ <t t-set="has_side_column" t-value="is_view_active('website_slides.toggle_leaderboard')"/>
+ <t t-if="is_public_user">
+ <div t-if="has_side_column" class="col-lg-3 order-3 order-lg-2">
+ <div class="row">
+ <div class="col-12 col-md-5 col-lg-12">
+ <div class="pl-md-5 pl-lg-0">
+ <t t-call="website_slides.slides_home_users_small"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ </t>
+ <div t-else="" class="col-lg-3 order-lg-2">
+ <t t-set="has_side_column" t-value="True"/>
+ <div class="o_wslides_home_aside_loggedin card p-3 p-lg-0 mb-4">
+ <div class="o_wslides_home_aside_title">
+ <div class="d-flex align-items-center">
+ <t t-call="website_slides.slides_misc_user_image">
+ <t t-set="img_class" t-value="'rounded-circle mr-1'"/>
+ <t t-set="img_style" t-value="'width: 22px; height: 22px; object-fit: cover;'"/>
+ </t>
+ <h5 t-esc="user.name" class="d-flex flex-grow-1 mb-0"/>
+ <a class="d-none d-lg-block" t-att-href="'/profile/user/%s' % user.id">View</a>
+ <a class="d-lg-none btn btn-sm bg-white border" href="#" data-toggle="collapse" data-target="#o_wslides_home_aside_content">More info</a>
+ </div>
+ <hr class="d-none d-lg-block mt-2 pt-2 mb-1"/>
+ </div>
+ <div id="o_wslides_home_aside_content" class="collapse d-lg-block">
+ <div class="row no-gutters mb-5 mt-3 mt-lg-0">
+ <div class="col-12 col-sm-6 col-lg-12">
+ <t t-call="website_slides.slides_home_user_profile_small"/>
+ </div>
+ <div class="col-12 col-sm-6 col-lg-12 pl-md-5 pl-lg-0 mt-lg-4">
+ <t t-call="website_slides.slides_home_user_achievements_small"/>
+ </div>
+ <div class="col-12 col-md-7 col-lg-12 pl-md-5 pl-lg-0 mt-lg-4 mb-3">
+ <t t-call="website_slides.slides_home_achievements_small"/>
+ </div>
+ <div class="col-12 col-sm-6 col-lg-12 pl-md-5 pl-lg-0 mt-lg-4">
+ <t t-call="website_slides.slides_home_users_small"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div t-att-class="'col-lg-9 pr-lg-5 order-lg-1' if has_side_column else 'col-lg pr-lg'">
+ <div class="o_wslides_home_content_section mb-3"
+ t-if="not channels_popular">
+ <p class="h2">No Course created yet.</p>
+ <p groups="website_slides.group_website_slides_officer">Click on "New" in the top-right corner to write your first course.</p>
+ </div>
+ <t t-if="channels_my">
+ <t t-set="void_count" t-value="3 - len(channels_my[:3])"/>
+ <div class="o_wslides_home_content_section mb-3">
+ <div class="row o_wslides_home_content_section_title align-items-center">
+ <div class="col">
+ <a href="/slides/all?my=1" class="float-right">View all</a>
+ <h5 class="m-0">My courses</h5>
+ <hr class="mt-2 pb-1 mb-1"/>
+ </div>
+ </div>
+ <div class="row mx-n2 mt8">
+ <t t-foreach="channels_my[:3]" t-as="channel">
+ <div class="col-md-4 col-sm-6 px-2 col-xs-12 d-flex flex-grow-1">
+ <t t-call="website_slides.course_card"/>
+ </div>
+ </t>
+ </div>
+ </div>
+ </t>
+ <div class="o_wslides_home_content_section mb-3"
+ t-if="channels_popular">
+ <div class="row o_wslides_home_content_section_title align-items-center">
+ <div class="col">
+ <a href="slides/all" class="float-right">View all</a>
+ <h5 class="m-0">Most popular courses</h5>
+ <hr class="mt-2 pb-1 mb-1"/>
+ </div>
+ </div>
+ <div class="row mx-n2 mt8">
+ <t t-foreach="channels_popular[:3]" t-as="channel">
+ <div class="col-md-4 col-sm-6 px-2 col-xs-12 d-flex flex-grow-1">
+ <t t-call="website_slides.course_card"/>
+ </div>
+ </t>
+ </div>
+ </div>
+ <div class="o_wslides_home_content_section mb-3"
+ t-if="channels_newest">
+ <div class="row o_wslides_home_content_section_title align-items-center">
+ <div class="col">
+ <a href="slides/all" class="float-right">View all</a>
+ <h5 class="m-0">Newest courses</h5>
+ <hr class="mt-2 pb-1 mb-1"/>
+ </div>
+ </div>
+ <div class="row mx-n2 mt8">
+ <t t-foreach="channels_newest[:3]" t-as="channel">
+ <div class="col-md-4 col-sm-6 px-2 col-xs-12 d-flex flex-grow-1">
+ <t t-call="website_slides.course_card"/>
+ </div>
+ </t>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <t t-call="website_slides.courses_footer"></t>
+ </div>
+ </t>
+</template>
+
+<!-- Channel all/main template -->
+<template id='courses_all' name="Odoo All Courses">
+ <t t-set="body_classname" t-value="'o_wslides_body'"/>
+ <t t-call="website.layout">
+ <div id="wrap" class="wrap o_wslides_wrap">
+ <section class="s_banner bg-900" style="background-image: url(&quot;/website_slides/static/src/img/banner_default_all.svg&quot;); background-size: cover; background-position: 80% 20%" data-snippet="s_banner">
+ <div class="container py-5">
+ <h1 t-if="search_my" class="display-3 mb-0">My Courses</h1>
+ <h1 t-elif="search_slide_type=='certification'" class="display-3 mb-0">Certifications</h1>
+ <h1 t-else="" class="display-3 mb-0">All Courses</h1>
+ </div>
+ </section>
+ <div class="container mt16 o_wslides_home_nav position-relative">
+ <!-- Navbar dynamically composed using displayed channel tag groups. -->
+ <nav class="navbar navbar-expand-md navbar-light shadow-sm pl-0" style="background: white!important">
+ <div class="navbar-nav border-right">
+ <a class="nav-link nav-item px-3" href="/slides"><i class="fa fa-chevron-left"/></a>
+ </div>
+ <!-- Clear filtering (mobile)-->
+ <div class="form-inline text-nowrap ml-auto d-md-none" t-if="search_slide_type or search_my or search_tags or search_channel_tag_id">
+ <a href="/slides/all" class="btn btn-info mr-2" role="button" title="Clear filters">
+ <i class="fa fa-eraser"/> Clear filters
+ </a>
+ </div>
+ <form t-else="" method="GET" class="form-inline o_wslides_nav_navbar_right d-md-none">
+ <!-- Search box (mobile)-->
+ <div class="input-group">
+ <input type="search" name="search" class="form-control"
+ placeholder="Search courses" aria-label="Search"
+ t-att-value="search_term"/>
+ <input t-if="search_tags" type="hidden" name="tags" t-att-value="str(search_tags.ids)"/>
+ <input t-if="search_my" type="hidden" name="my" t-att-value="1"/>
+ <input t-if="search_slide_type" type="hidden" name="slide_type" t-att-value="search_slide_type" />
+ <div class="input-group-append">
+ <button class="btn border border-left-0 oe_search_button" type="submit" aria-label="Search" title="Search">
+ <i class="fa fa-search"/>
+ </button>
+ </div>
+ </div>
+ </form>
+ <button class="navbar-toggler px-1" type="button"
+ data-toggle="collapse" data-target="#navbarTagGroups"
+ aria-controls="navbarTagGroups" aria-expanded="false" aria-label="Toggle navigation">
+ <span class="navbar-toggler-icon small"/>
+ </button>
+ <div class="collapse navbar-collapse" id="navbarTagGroups">
+ <t t-set="search_tag_groups" t-value="search_tags.mapped('group_id')"/>
+ <ul class="navbar-nav flex-grow-1">
+ <t t-foreach="tag_groups" t-as="tag_group">
+ <li t-att-class="'nav-item dropdown ml16 %s' % ('active' if tag_group in search_tag_groups else '')">
+ <a class="nav-link dropdown-toggle"
+ href="/slides/all"
+ t-att-data-target="'#navToogleTagGroup%s' % tag_group.id"
+ role="button" data-toggle="dropdown"
+ aria-haspopup="true" aria-expanded="false"
+ t-esc="tag_group.name"/>
+ <div class="dropdown-menu" t-att-id="'navToogleTagGroup%s' % tag_group.id">
+ <t t-foreach="tag_group.tag_ids" t-as="tag">
+ <a rel="nofollow" t-att-class="'dropdown-item %s' % ('active' if tag in search_tags else '')"
+ t-att-href="'/slides/all?%s' % keep_query('*', tags=str((search_tags - tag).ids if tag in search_tags else (tag | search_tags).ids))"
+ t-esc="tag.name"/>
+ </t>
+ </div>
+ </li>
+ </t>
+ </ul>
+ <!-- Clear filtering (desktop)-->
+ <div class="form-inline ml-auto d-none d-md-flex" t-if="search_slide_type or search_my or search_tags or search_channel_tag_id">
+ <a href="/slides/all" class="btn btn-info text-nowrap mr-2" role="button" title="Clear filters">
+ <i class="fa fa-eraser"/> Clear filters
+ </a>
+ </div>
+ <!-- Search box (desktop) -->
+ <form method="GET" class="form-inline o_wslides_nav_navbar_right d-none d-md-flex">
+ <div class="input-group">
+ <input type="search" name="search" class="form-control"
+ placeholder="Search courses" aria-label="Search"
+ t-att-value="search_term"/>
+ <input t-if="search_tags" type="hidden" name="tags" t-att-value="str(search_tags.ids)"/>
+ <input t-if="search_my" type="hidden" name="my" t-att-value="1"/>
+ <input t-if="search_slide_type" type="hidden" name="slide_type" t-att-value="search_slide_type" />
+ <div class="input-group-append">
+ <button class="btn border border-left-0 oe_search_button" type="submit" aria-label="Search" title="Search">
+ <i class="fa fa-search"/>
+ </button>
+ </div>
+ </div>
+ </form>
+ </div>
+ </nav>
+ <div class="o_wprofile_email_validation_container mb16 mt16">
+ <t t-call="website_profile.email_validation_banner">
+ <t t-set="redirect_url" t-value="'/slides'"/>
+ <t t-set="send_validation_email_message">Click here to send a verification email allowing you to participate at the eLearning.</t>
+ <t t-set="additional_validated_email_message"> You may now participate in our eLearning.</t>
+ </t>
+ </div>
+ <!-- Display tags -->
+ <t t-if="search_my">
+ <span class="align-items-baseline border d-inline-flex pl-2 rounded mb-2">
+ <i class="fa fa-tag mr-2 text-muted"/>
+ My Courses
+ <a t-att-href="'/slides/all?%s' % keep_query('*', my=None)" class="btn border-0 py-1">&#215;</a>
+ </span>
+ </t>
+ <t t-if="search_term">
+ <span class="align-items-baseline border d-inline-flex pl-2 rounded mb-2">
+ <i class="fa fa-tag mr-2 text-muted"/>
+ <t t-esc="search_term"/>
+ <a t-att-href="'/slides/all?%s' % keep_query('*', search=None)" class="btn border-0 py-1">&#215;</a>
+ </span>
+ </t>
+ <t t-foreach="search_tags" t-as="tag">
+ <span class="align-items-baseline border d-inline-flex pl-2 rounded mb-2">
+ <i class="fa fa-tag mr-2 text-muted"/>
+ <t t-esc="tag.display_name"/>
+ <a t-att-href="'/slides/all?%s' % keep_query('*', tags=str((search_tags - tag).ids))" class="btn border-0 py-1">&#215;</a>
+ </span>
+ </t>
+ </div>
+ <div class="container o_wslides_home_main pb-5">
+ <div t-if="not channels and not search_term and not search_slide_type and not search_my and not search_tags and not search_channel_tag_id">
+ <p class="h2">No Course created yet.</p>
+ <p groups="website_slides.group_website_slides_officer">Click on "New" in the top-right corner to write your first course.</p>
+ </div>
+ <div t-elif="search_term and not channels" class="alert alert-info mb-5">
+ No course was found matching your search <code><t t-esc="search_term"/></code>.
+ </div>
+ <div t-elif="not channels" class="alert alert-info mb-5">
+ No course was found matching your search.
+ </div>
+ <div t-else="" class="row mx-n2">
+ <t t-foreach="channels" t-as="channel">
+ <div class="col-12 col-sm-6 col-md-4 col-lg-3 px-2 d-flex flex-grow-1">
+ <t t-call="website_slides.course_card"/>
+ </div>
+ </t>
+ </div>
+ </div>
+
+ <t t-call="website_slides.courses_footer"></t>
+ </div>
+ </t>
+</template>
+
+<template id='courses_footer'>
+ <section class="s_banner">
+ <div class="oe_structure oe_empty"/>
+ </section>
+</template>
+
+<template id='course_card' name="Course Card">
+ <div t-attf-class="card w-100 o_wslides_course_card mb-4 #{'o_wslides_course_unpublished' if not channel.is_published else ''}">
+ <t t-set="course_image" t-value="website.image_url(channel, 'image_1024')"/>
+ <a t-attf-href="/slides/#{slug(channel)}" t-title="channel.name">
+ <t t-if="channel.partner_has_new_content" t-call="website_slides.course_card_information"/>
+ <div t-if="channel.image_1024" class="card-img-top" t-attf-style="padding-top: 50%; background-image: url(#{course_image}); background-size: cover; background-position:center"/>
+ <div t-else="" class="o_wslides_gradient card-img-top position-relative" style="padding-top: 50%; opacity: 0.8">
+ <i class="fa fa-graduation-cap fa-2x mr-3 mb-3 position-absolute text-white-75" style="right:0; bottom: 0"/>
+ </div>
+ </a>
+ <div class="card-body p-3">
+ <a class="card-title h5 mb-2 o_wslides_desc_truncate_2" t-attf-href="/slides/#{slug(channel)}" t-esc="channel.name"/>
+ <span t-if="not channel.is_published" class="badge badge-danger p-1">Unpublished</span>
+ <div class="card-text mt-1">
+ <div class="font-weight-light o_wslides_desc_truncate_3" t-field="channel.description_short"/>
+ <div t-if="channel.tag_ids" class="mt-2 pt-1 o_wslides_desc_truncate_2">
+ <t t-foreach="channel.tag_ids" t-as="tag">
+ <t t-if="search_tags">
+ <a t-att-href="'/slides/all?%s' % keep_query('*', tags=str((tag | search_tags).ids))" t-attf-class="badge #{'badge-primary' if tag in search_tags else 'o_wslides_channel_tag o_tag_color_0'}" t-esc="tag.name"/>
+ </t>
+ <t t-else="">
+ <a t-att-href="'/slides/all?%s' % keep_query('*', tags=str((tag | search_tags).ids))" t-attf-class="badge o_wslides_channel_tag #{'o_tag_color_'+str(tag.color)}" t-esc="tag.name"/>
+ </t>
+ </t>
+ </div>
+ </div>
+ </div>
+ <div class="card-footer bg-white text-600 px-3">
+ <div class="d-flex justify-content-between align-items-center">
+ <small t-if="channel.total_time" class="font-weight-bold" t-esc="channel.total_time" t-options="{'widget': 'duration', 'unit': 'hour', 'round': 'minute'}"/>
+ <div class="d-flex flex-grow-1 justify-content-end">
+ <t t-if="channel.is_member and channel.completed">
+ <span class="badge badge-pill badge-success pull-right py-1 px-2"><i class="fa fa-check"/> Completed</span>
+ </t>
+ <div t-elif="channel.is_member and channel.channel_type != 'documentation'" class="progress w-50" style="height: 6px">
+ <div class="progress-bar" role="progressbar" t-att-aria-valuenow="channel.completion" aria-valuemin="0" aria-valuemax="100" t-attf-style="width:#{channel.completion}%;"/>
+ </div>
+ <small t-else=""><b t-esc="channel.total_slides"/> steps</small>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<template id="course_card_information" name='Course Information'>
+ <t id="course_card_information_content">
+ </t>
+</template>
+
+<template id="course_card_information_arrow" inherit_id="website_slides.course_card_information"
+ active="True" customize_show="True" name='New Content Ribbon'>
+ <xpath expr="//t[@id='course_card_information_content']" position="inside">
+ <span class="o_wslides_arrow">New Content</span>
+ </xpath>
+</template>
+
+<template id='slides_home_achievements_small' name="Users">
+ <t class="o_wslides_home_aside">
+ </t>
+</template>
+
+<template id="toggle_latest_achievements" inherit_id="website_slides.slides_home_achievements_small" active="True" customize_show="True" name='Display Achievements'>
+ <xpath expr="//t[hasclass('o_wslides_home_aside')]" position="inside">
+ <div t-if="achievements">
+ <div class="row o_wslides_home_aside_title">
+ <div class="col">
+ <h5 class="m-0">Latest achievements</h5>
+ <hr class="mt-2"/>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col">
+ <t t-foreach="achievements" t-as="achievement">
+ <t t-call="website_slides.achievement_card"/>
+ </t>
+ </div>
+ </div>
+ </div>
+ </xpath>
+</template>
+
+<template id='achievement_card' name="Achivement Card">
+ <div class="d-flex no-gutters mt8 align-items-center">
+ <t t-call="website_slides.slides_misc_user_image">
+ <t t-set="user" t-value="achievement.user_id"/>
+ </t>
+ <div style="line-height: 1.3">
+ <span class="font-weight-bold" t-esc="achievement.user_id.name"/> achieved <span class="font-weight-bold" t-esc="achievement.badge_id.name"/>
+ </div>
+ </div>
+</template>
+
+<template id='slides_home_users_small' name="Users">
+ <div class="o_wslides_home_aside">
+ </div>
+</template>
+
+<template id="toggle_leaderboard" inherit_id="website_slides.slides_home_users_small" active="True" customize_show="True" name='Display Leaderboard'>
+ <xpath expr="//div[hasclass('o_wslides_home_aside')]" position="inside">
+ <div class="row o_wslides_home_aside_title">
+ <div class="col">
+ <a href="/profile/users" class="float-right">View all</a>
+ <h5 class="m-0">Leaderboard</h5>
+ <hr class="mt-2 pt-2"/>
+ </div>
+ </div>
+ <div class="row">
+ <t t-if="users">
+ <div class="col">
+ <t t-set="counter" t-value="1"/>
+ <t t-foreach="users" t-as="user">
+ <t t-call="website_slides.user_quickkarma_card"/>
+ <t t-set="counter" t-value="counter + 1"/>
+ </t>
+ </div>
+ </t>
+ <t t-else=""><p class="col mt8">No leaderboard currently :(</p></t>
+ </div>
+ </xpath>
+</template>
+
+<template id='user_quickkarma_card' name="User QuickKarma Card">
+ <div class="d-flex mb-3 align-items-center">
+ <b class="mr-2 text-muted" t-esc="counter"/>
+ <t t-call="website_slides.slides_misc_user_image"/>
+ <div style="line-height:1.3">
+ <span class="font-weight-bold" t-esc="user.name"/>
+ <div class="d-flex align-items-center">
+ <t t-esc="user.rank_id.name"/>
+ <span class="text-500 mx-2">&#8226;</span>
+ <span class="badge badge-success"><t t-esc="user.karma"/> xp</span>
+ </div>
+ </div>
+ </div>
+</template>
+
+<template id='slides_home_user_profile_small' name="User Profile">
+ <div class="o_wslides_home_aside">
+ <div t-if="user.rank_id" class="d-flex align-items-center">
+ <span class="font-weight-bold text-muted mr-2">Current rank:</span>
+ <img t-att-src="website.image_url(user.rank_id, 'image_128')" width="16" height="16" alt="" class="o_object_fit_cover mr-1"/>
+ <a href="/profile/ranks_badges" t-field="user.rank_id"/>
+ </div>
+ <t t-set="next_rank_id" t-value="user._get_next_rank()"/>
+ <div t-if="next_rank_id" class="font-weight-bold text-muted mt-1">Next rank:</div>
+ <t t-if="next_rank_id or user.rank_id" t-call="website_profile.profile_next_rank_card">
+ <t t-set="bg_class" t-valuef="bg-200"/>
+ <t t-set="img_max_width" t-valuef="50%"/>
+ </t>
+ <div t-if="next_rank_id" t-field="next_rank_id.description_motivational"/>
+ <div t-else="">Congratulations, you have reached the last rank!</div>
+ </div>
+</template>
+
+<template id='slides_home_user_achievements_small' name="User Achievements">
+ <div class="o_wslides_home_aside flex-grow-1">
+ <div class="row o_wslides_home_aside_title">
+ <div class="col">
+ <a href="/profile/ranks_badges?badge_category=slides" class="float-right">View all</a>
+ <h5 class="m-0">Badges</h5>
+ <hr class="mt-2 pt-2"/>
+ </div>
+ </div>
+ <t t-foreach="challenges" t-as="challenge">
+ <t t-set="challenge_done" t-value="challenge in challenges_done if challenges_done else False"/>
+ <div t-attf-class="d-flex mb-3 align-items-center #{'o_wslides_entry_muted' if not challenge_done else ''}">
+ <img class="mr-2"
+ style="max-height: 36px;"
+ t-att-src="website.image_url(challenge.reward_id, 'image_128') if challenge.reward_id.image_1920 else
+ '/website_profile/static/src/img/badge_%s.svg' % (challenge.reward_id.level)"
+ t-att-alt="challenge.reward_id.name"/>
+ <div class="flex-grow-1">
+ <b class="text_small_caps" t-esc="challenge.reward_id.name"/><br/>
+ <span class="text-muted" t-esc="challenge.reward_id.description"/>
+ </div>
+ <i t-if="challenge_done" class="fa fa-check h5 text-success" aria-label="Done" title="Done" role="img"></i>
+ </div>
+ </t>
+ </div>
+</template>
+
+<template id='slides_misc_user_image' name="User Avatar">
+ <img t-att-class="img_class if img_class else 'rounded-circle float-left'"
+ t-att-style="img_style if img_style else 'width: 32px; height: 32px; object-fit: cover;'"
+ t-att-src="'/profile/avatar/%s?field=image_128' % user.id"
+ t-att-alt="user.name"/>
+</template>
+</data></odoo>
diff --git a/addons/website_slides/views/website_slides_templates_lesson.xml b/addons/website_slides/views/website_slides_templates_lesson.xml
new file mode 100644
index 00000000..a8e9ad2a
--- /dev/null
+++ b/addons/website_slides/views/website_slides_templates_lesson.xml
@@ -0,0 +1,563 @@
+<?xml version="1.0" ?>
+<odoo><data>
+
+<!-- Slide: main template: detailed view -->
+<template id="slide_main" name="Slide Detailed View" track="1">
+ <t t-set="body_classname" t-value="'o_wslides_body'"/>
+ <t t-call="website.layout">
+ <div id="wrap" class="wrap o_wslides_wrap">
+ <div class="o_wslides_lesson_header o_wslides_gradient position-relative text-white pb-0 pt-2 pt-md-5">
+ <t t-call="website_slides.course_nav">
+ <t t-set="channel" t-value="slide.channel_id"/>
+ </t>
+ <div class="container o_wslides_lesson_header_container mt-5 mt-md-3 mt-xl-4">
+ <div class="row align-items-end align-items-md-stretch">
+ <div t-attf-class="col-12 col-lg-9 d-flex flex-column #{'offset-lg-3' if slide.channel_id.channel_type == 'training' else ''}">
+ <h2 class="font-weight-medium w-100">
+ <a t-att-href="'/slides/%s' % (slug(slide.channel_id))" class="text-white text-decoration-none" t-field="slide.channel_id.name"/>
+ <t t-if="slide.channel_id.completed">
+ <small><span class="badge badge-pill badge-success pull-right my-1 py-1 px-2 font-weight-normal"><i class="fa fa-check"/> Completed</span></small>
+ </t>
+ </h2>
+
+ <div t-if="slide.channel_id.channel_type == 'documentation'" class="mb-3 small">
+ <span class="font-weight-normal">Last update:</span>
+ <t t-esc="slide.date_published" t-options="{'widget': 'date'}"/>
+ </div>
+
+ <div t-else="" t-if="not slide.channel_id.completed" class="d-flex align-items-center pb-3">
+ <div class="progress w-50 bg-black-25" style="height: 10px;">
+ <div class="progress-bar rounded-left" role="progressbar"
+ t-att-aria-valuenow="slide.channel_id.completion" aria-valuemin="0" aria-valuemax="100"
+ t-attf-style="width: #{slide.channel_id.completion}%;">
+ </div>
+ </div>
+ <i t-att-class="'fa fa-trophy m-0 ml-2 p-0 %s' % ('text-warning' if slide.channel_id.completed else 'text-black-50')"></i>
+ <small class="ml-2 text-white-50"><t t-esc="slide.channel_id.completion"/> %</small>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="container o_wslides_lesson_main">
+ <div class="row">
+ <div t-attf-class="o_wslides_lesson_aside col-lg-3 #{'order-2' if slide.channel_id.channel_type == 'documentation' else ''}">
+ <t t-if="slide.channel_id.channel_type == 'training'" t-call="website_slides.slide_aside_training"/>
+ <t t-if="slide.channel_id.channel_type == 'documentation'" t-call="website_slides.slide_aside_documentation"/>
+ </div>
+ <div t-attf-class="o_wslides_lesson_content col-lg-9 #{'order-1' if slide.channel_id.channel_type == 'documentation' else ''}">
+ <t t-call="website_slides.slide_content_detailed"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ </t>
+</template>
+
+<!-- Slide: sidebar documentation mode -->
+<template id="slide_aside_documentation" name="Slide: Sidebar in Documentation">
+ <div class="o_wslides_lesson_aside_doc position-relative bg-white pb-1 my-3 border-bottom">
+ <ul class="nav nav-tabs nav-fill" role="tablist">
+ <li class="nav-item"><a aria-controls="related" href="#related" class="nav-link rounded-0 border-top-0 border-left-0 py-2 active" data-toggle="tab">Related</a></li>
+ <li class="nav-item"><a aria-controls="most_viewed" href="#most_viewed" class="nav-link rounded-0 border-top-0 border-right-0 py-2" data-toggle="tab">Most Viewed</a></li>
+ </ul>
+ <div class="tab-content">
+ <div role="tabpanel" id="related" class="tab-pane active bg-100">
+ <ul class="list-group list-group-flush">
+ <t t-set="related_slides_list" t-value="list(related_slides)"/>
+ <t t-if="not related_slides_list">
+ No presentation available.
+ </t>
+ <t t-else="" t-foreach="related_slides_list" t-as="aside_slide">
+ <t t-call="website_slides.slide_aside_card"/>
+ </t>
+ </ul>
+ </div>
+ <div role="tabpanel" id="most_viewed" class="tab-pane bg-100">
+ <ul class="list-group list-group-flush">
+ <t t-set="most_viewed_slides_list" t-value="list(most_viewed_slides)"/>
+ <t t-if="not list(most_viewed_slides_list)">
+ No presentation available.
+ </t>
+ <t t-else="" t-foreach="most_viewed_slides_list" t-as="aside_slide">
+ <t t-call="website_slides.slide_aside_card"/>
+ </t>
+ </ul>
+ </div>
+ </div>
+ </div>
+</template>
+
+<!-- Slide sub-template: display an item in a list of related slides (Related, Most Viewed, ...) -->
+<template id="slide_aside_card" name="Related Slide">
+ <a class="list-group-item list-group-item-action d-flex align-items-start px-2" t-att-href="'/slides/slide/%s' % (slug(aside_slide))">
+ <t t-set="slide_image" t-value="website.image_url(aside_slide, 'image_1024')"/>
+
+ <div t-if="aside_slide.image_1024" class="flex-shrink-0 mr-1 border" t-attf-style="width: 20%; padding-top: 20%; background-image: url(#{slide_image}); background-size: cover; background-position:center"/>
+ <div t-else="" class="o_wslides_gradient flex-shrink-0 mr-1" t-attf-style="width: 20%; padding-top: 20%;"/>
+ <div class="overflow-hidden d-flex flex-column justify-content-start">
+ <h6 t-esc="aside_slide.name" class="o_wslides_desc_truncate_2 mb-1" style="line-height: 1.15"/>
+ <small class="text-600">
+ <t t-esc="aside_slide.total_views"/> Views &#8226; <timeago class="timeago" t-att-datetime="aside_slide.create_date"></timeago>
+ </small>
+ </div>
+ </a>
+</template>
+
+<!-- Slide: sidebar training mode -->
+<template id="slide_aside_training" name="Slide: Sidebar in Training">
+ <div class="o_wslides_lesson_aside_list position-relative bg-white border-bottom mt-4">
+ <div class="bg-100 text-600 h6 my-0 text-decoration-none border-bottom d-flex align-items-center justify-content-between">
+ <span class="p-2">Course content</span>
+ <a href="#collapse_slide_aside" data-toggle="collapse" class="d-lg-none p-2 text-decoration-none o_wslides_lesson_aside_collapse">
+ <i class="fa fa-chevron-down d-lg-none"/>
+ </a>
+ </div>
+ <ul id="collapse_slide_aside" class="list-unstyled my-0 pb-3 collapse d-lg-block">
+ <t t-set="i" t-value="0"/>
+ <t t-if="category.get('slides')" t-foreach="category_data" t-as="category">
+ <t t-call="website_slides.slide_aside_training_category">
+ <t t-set="category_slide_ids" t-value="category['slides']"/>
+ </t>
+ </t>
+ </ul>
+ </div>
+</template>
+
+<template id="slide_aside_training_category" name="Category item for the slide detailed view list">
+ <t t-if="category" t-set="category" t-value="category.get('category')"/>
+ <li class="o_wslides_fs_sidebar_section mt-2">
+ <a t-att-href="('#collapse-%s') % (category.id if category else 0)" data-toggle="collapse" role="button" aria-expanded="true"
+ class="o_wslides_lesson_aside_list_link pl-2 text-600 text-uppercase text-decoration-none py-1 small d-block"
+ t-att-aria-controls="('collapse-%s') % (category.id if category else 0)">
+ <t t-if="category">
+ <b t-field="category.name"/>
+ </t>
+ <t t-else="">
+ <b>Uncategorized</b>
+ </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-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"/>
+ <li class="p-0 pb-1">
+ <a t-att-href="'/slides/slide/%s' % (slug(aside_slide)) if can_access else '#'"
+ t-att-class="'o_wslides_lesson_aside_list_link d-flex align-items-top px-2 pt-1 text-decoration-none %s%s' % (('bg-100 py-1 active' if aside_slide == slide else ''), 'text-muted' if not can_access else '')">
+ <div t-if="is_member" >
+ <i t-att-id="'o_wslides_lesson_aside_slide_check_%s' % (aside_slide.id)"
+ t-att-class="'mr-1 fa fa-fw %s' % ('text-success fa-check-circle' if channel_progress[aside_slide.id].get('completed') else 'text-600 fa-circle')">
+ </i>
+ </div>
+ <div class="o_wslides_lesson_link_name">
+ <t t-call="website_slides.slide_icon">
+ <t t-set="slide" t-value="aside_slide"/>
+ </t>
+ <span t-esc="aside_slide.name" class="mr-2"/>
+ </div>
+ <div class="ml-auto" t-if="aside_slide.question_ids">
+ <span t-att-class="'badge badge-pill %s' % ('badge-success' if channel_progress[aside_slide.id].get('completed') else 'badge-light text-600')">
+ <t t-esc="channel_progress[aside_slide.id].get('quiz_karma_won') if channel_progress[aside_slide.id].get('completed') else channel_progress[aside_slide.id].get('quiz_karma_gain')"/> xp
+ </span>
+ </div>
+ </a>
+ <ul t-if="aside_slide.link_ids or aside_slide.slide_resource_ids or aside_slide.question_ids" class="list-group px-2 mb-1 list-unstyled">
+ <t t-foreach="aside_slide.link_ids" t-as="resource">
+ <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>
+ <div class="o_wslides_js_course_join pl-4" t-if="aside_slide.slide_resource_ids">
+ <t t-if="is_member or aside_slide.channel_id.can_publish">
+ <li t-foreach="aside_slide.slide_resource_ids" t-as="resource">
+ <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">
+ <i class="fa fa-download mr-1"/>
+ <t t-call="website_slides.join_course_link"/>
+ </li>
+ </div>
+ <li class="pl-4">
+ <a t-if="can_access and aside_slide.question_ids and aside_slide.slide_type != 'quiz'" t-att-href="'/slides/slide/%s#lessonQuiz' % (slug(aside_slide))" class="o_wslides_lesson_aside_list_link text-decoration-none small text-600">
+ <i class="fa fa-flag text-warning"/> Quiz
+ </a>
+ <span t-elif="not can_access and aside_slide.question_ids and aside_slide.slide_type != 'quiz'"
+ class="o_wslides_lesson_aside_list_link text-decoration-none small text-600 text-muted">
+ <i class="fa fa-flag text-warning"/> Quiz
+ </span>
+ </li>
+ </ul>
+ </li>
+ </t>
+ </ul>
+ </li>
+</template>
+
+<!-- Slide: all its content, not fullscreen mode -->
+<template id="slide_content_detailed" name="Slide: Detailed Content">
+ <t t-set="is_training_channel" t-value="slide.channel_id.channel_type == 'training'"/>
+ <div class="row align-items-center my-3">
+ <div class="col-12 col-md order-2 order-md-1 d-flex">
+ <div class="d-flex align-items-center">
+ <h1 class="h4 my-0">
+ <t t-call="website_slides.slide_icon">
+ <t t-set="icon_class" t-valuef="mr-1"/>
+ </t>
+ <span t-field="slide.name"/>
+ </h1>
+ <span t-if="slide.question_ids"
+ t-att-class="'ml-2 badge %s' % ('badge-success' if channel_progress[slide.id].get('completed') else 'badge-info')">
+ <span t-if="channel_progress[slide.id].get('completed')">
+ <i class="fa fa-check-circle"/>
+ <t t-esc="channel_progress[slide.id].get('quiz_karma_won', 0)"/>
+ </span>
+ <span t-else="" t-esc="channel_progress[slide.id].get('quiz_karma_gain', 0)"/>
+ <span>XP</span>
+ </span>
+ </div>
+ </div>
+ <div class="col-12 col-md order-1 order-md-2 text-nowrap flex-grow-0 d-flex justify-content-end mb-3 mb-md-0">
+ <div class="btn-group flex-grow-1 flex-sm-0" role="group" aria-label="Lesson Nav">
+ <a t-att-class="'btn btn-light border %s' % ('disabled' if not previous_slide else '')"
+ role="button" t-att-aria-disabled="'disabled' if not previous_slide else None"
+ t-att-href="'/slides/slide/%s' % (slug(previous_slide)) if previous_slide else '#'">
+ <i class="fa fa-chevron-left mr-2"></i> <span class="d-none d-sm-inline-block">Prev</span>
+ </a>
+ <t t-set="allow_done_btn" t-value="slide.slide_type in ['infographic', 'presentation', 'document', 'webpage', 'video'] and not slide.question_ids and not channel_progress[slide.id].get('completed') and slide.channel_id.is_member"/>
+ <a t-att-class="'btn btn-primary border text-white %s' % ('disabled' if not allow_done_btn else '')"
+ role="button" t-att-aria-disabled="'true' if not allow_done_btn else None"
+ t-att-href="'/slides/slide/%s/set_completed?%s' % (slide.id, 'next_slide_id=%s' % (next_slide.id) if next_slide else '') if allow_done_btn else '#'">
+ Set Done
+ </a>
+ <a t-att-class="'btn btn-light border %s' % ('disabled' if not next_slide else '')"
+ role="button" t-att-aria-disabled="'disabled' if not next_slide else None"
+ t-att-href="'/slides/slide/%s' % (slug(next_slide)) if next_slide else '#'">
+ <span class="d-none d-sm-inline-block">Next</span> <i class="fa fa-chevron-right ml-2"></i>
+ </a>
+ </div>
+ <a t-if="is_training_channel" class="btn btn-light border ml-2" role="button" t-att-href="'/slides/slide/%s?fullscreen=1' % (slug(slide))">
+ <i class="fa fa-desktop mr-2"/>
+ <span class="d-none d-sm-inline-block">Fullscreen</span>
+ </a>
+ </div>
+ </div>
+ <div t-if="slide.tag_ids" class="pb-2">
+ <t t-foreach="slide.tag_ids" t-as="tag">
+ <a t-att-href="'/slides/%s/tag/%s' % (slug(slide.channel_id), slug(tag))" class="badge badge-info py-1 px-2" t-esc="tag.name"/>
+ </t>
+ </div>
+ <div class="o_wslides_lesson_content_type">
+ <img t-if="slide.slide_type == 'infographic'"
+ t-att-src="website.image_url(slide, 'image_1024')" class="img-fluid" style="width:100%" t-att-alt="slide.name"/>
+ <div t-if="slide.slide_type in ('presentation', 'document')" class="embed-responsive embed-responsive-4by3 embed-responsive-item mb8" style="height: 600px;">
+ <t t-raw="slide.embed_code"/>
+ </div>
+ <div t-if="slide.slide_type == 'video' and slide.document_id" class="embed-responsive embed-responsive-16by9 embed-responsive-item mb8">
+ <t t-raw="slide.embed_code"/>
+ </div>
+ <div t-if="slide.slide_type == 'webpage'" class="bg-white p-3">
+ <div t-field="slide.html_content"/>
+ </div>
+ </div>
+
+ <div class="mb-5">
+ <ul class="nav nav-tabs o_wslides_lesson_nav" role="tablist">
+ <li class="nav-item">
+ <a href="#about" aria-controls="about" class="nav-link active" role="tab" data-toggle="tab">
+ <i class="fa fa-home"></i> About
+ </a>
+ </li>
+ <li t-if="slide.channel_id.allow_comment" class="nav-item">
+ <a href="#discuss" aria-controls="discuss" class="nav-link" role="tab" data-toggle="tab">
+ <i class="fa fa-comments"></i> Comments (<span t-esc="slide.comments_count"/>)
+ </a>
+ </li>
+ <li class="nav-item">
+ <a href="#statistic" aria-controls="statistic" class="nav-link" role="tab" data-toggle="tab">
+ <i class="fa fa-bar-chart"></i> Statistics
+ </a>
+ </li>
+ <li class="nav-item">
+ <a href="#share" aria-controls="share" class="nav-link" role="tab" data-toggle="tab">
+ <i class="fa fa-share-alt"></i> Share
+ </a>
+ </li>
+ </ul>
+ <div class="tab-content mt-3">
+ <div role="tabpanel" t-att-class="not comments and 'tab-pane fade in show active' or 'tab-pane fade'" id="about">
+ <div t-field="slide.description"/>
+ </div>
+ <div role="tabpanel" t-att-class="comments and 'tab-pane fade in show active' or 'tab-pane fade'" id="discuss">
+ <t t-call="portal.message_thread">
+ <t t-set="object" t-value="slide"/>
+ <t t-set="disable_composer" t-value="not (slide.channel_id.can_comment and slide.channel_id.allow_comment and slide.channel_id.channel_type == 'training')"/>
+ <t t-set="display_rating" t-value="False"/>
+ </t>
+ </div>
+ <div role="tabpanel" class="tab-pane fade" id="statistic" t-att-slide-url="slide.website_url">
+ <div class="row">
+ <div class="col-12 col-md">
+ <table class="table table-sm">
+ <tbody>
+ <tr>
+ <th colspan="2" class="border-top-0">Views</th>
+ </tr>
+ <tr class="border-top-0">
+ <th class="border-top-0"><span t-esc="slide.total_views"/></th>
+ <td class="border-top-0 w-100">Total Views</td>
+ </tr>
+ <tr>
+ <th><span t-esc="slide.slide_views"/></th>
+ <td>Members Views</td>
+ </tr>
+ <tr>
+ <th><span t-esc="slide.public_views"/></th>
+ <td>Public Views</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div t-if="slide.channel_id.allow_comment" class="col-12 col-md">
+ <table class="table table-sm">
+ <tbody>
+ <tr>
+ <th colspan="2" class="border-top-0">Actions</th>
+ </tr>
+ <tr class="border-top-0">
+ <th class="border-top-0"><span t-esc="slide.likes"/></th>
+ <td class="border-top-0 w-100">Likes</td>
+ </tr>
+ <tr>
+ <th><span t-esc="slide.dislikes"/></th>
+ <td>Dislikes</td>
+ </tr>
+ <tr>
+ <th><span t-esc="len(slide.website_message_ids)"/></th>
+ <td>Comments</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ <div role="tabpanel" class="tab-pane fade" t-if="slide.website_published" id="share">
+ <h4 t-if="not slide.website_published"><i class="fa fa-info-circle"></i>
+ The social sharing module will be unlocked when a moderator will allow your publication.
+ </h4>
+ <t t-if="slide.website_published">
+ <div class="row">
+ <div class="col-12 col-lg-6">
+ <h5 class="mt16">Share on Social Networks</h5>
+ <t t-call="website_slides.slide_share_social">
+ <t t-set="record" t-value="slide"/>
+ </t>
+ </div>
+ <div class="col-12 col-lg-6">
+ <t t-call="website_slides.slide_share_link">
+ <t t-set="record" t-value="slide"/>
+ <t t-set="website_url" t-value="slide.website_url"/>
+ </t>
+ </div>
+ </div>
+ <div class="row">
+ <div t-attf-class="col-12 #{'col-lg-6' if slide.embed_code else ''}">
+ <t t-call="website_slides.slide_social_email">
+ <t t-set="slide" t-value="slide"/>
+ </t>
+ </div>
+ <div class="col-12 col-lg-6" t-if="slide.embed_code">
+ <t t-call="website_slides.slide_social_embed">
+ <t t-set="slide" t-value="slide"/>
+ </t>
+ </div>
+ </div>
+ </t>
+ </div>
+ </div>
+ </div>
+ <div class="o_wslides_js_quiz_container" t-att-data-slide-id="slide.id">
+ <div class="row" t-if="slide.slide_type != 'certification'">
+ <t t-if="slide.question_ids">
+ <t t-call="website_slides.lesson_content_quiz"/>
+ </t>
+ <div t-else="" class="o_wslides_js_lesson_quiz col" t-att-data-id="slide.id">
+ <t t-if="slide.channel_id.can_upload" t-call="website_slides.lesson_content_quiz_add_buttons"/>
+ </div>
+ </div>
+ </div>
+ <div class="row mt-3 mb-3">
+ <div class="col-12 col-md d-flex align-items-start mb-4 mb-md-0" t-if="len(slide.link_ids)">
+ <span t-if="slide.link_ids" class="text-muted font-weight-bold mr-3">External sources</span>
+ <div class="text-muted mr-auto border-left pl-3">
+ <t t-foreach="slide.link_ids" t-as="link">
+ <a t-att-href="link.link" t-esc="link.name"/><br />
+ </t>
+ </div>
+ </div>
+ <div class="col-12 col-md d-flex align-items-start mb-4 mb-md-0 o_wslides_js_course_join" t-if="len(slide.slide_resource_ids)">
+ <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">
+ 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="slide.slide_resource_ids" t-as="resource">
+ <a t-attf-href="/web/content/slide.slide.resource/#{resource.id}/data?download=true" t-esc="resource.name"/><br />
+ </t>
+ </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>
+ <div t-if="slide.channel_id.allow_comment and slide.channel_id.channel_type == 'documentation'"
+ class="col-12 col-md d-flex align-items-start justify-content-md-end mb-2 mb-md-0">
+ <span class="text-muted font-weight-bold mr-3">Rating</span>
+ <div class="text-muted border-left pl-3">
+ <div class="o_wslides_js_slide_like mr-2">
+ <span t-att-class="('o_wslides_js_slide_like_up %s') % ('disabled' if not slide.channel_id.can_vote else '')" tabindex="0" data-toggle="popover" t-att-data-slide-id="slide.id">
+ <i class="fa fa-thumbs-up fa-1x" role="img" aria-label="Likes" title="Likes"></i>
+ <span t-esc="slide.likes"/>
+ </span>
+ <span t-att-class="('o_wslides_js_slide_like_down ml-3 %s') % ('disabled' if not slide.channel_id.can_vote else '')" tabindex="0" data-toggle="popover" t-att-data-slide-id="slide.id">
+ <i class="fa fa-thumbs-down fa-1x" role="img" aria-label="Dislikes" title="Dislikes"></i>
+ <span t-esc="slide.dislikes"/>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<!-- Slide sub-tempalte: render a quiz serverside. Should be sync with JS qweb template "slide.slide.quiz" -->
+<template id="lesson_content_quiz" name="Lesson: Quiz specific content">
+ <t t-set="slide_completed" t-value="channel_progress[slide.id].get('completed')"/>
+ <div class="o_wslides_js_lesson_quiz col" id="lessonQuiz"
+ t-att-data-id="slide.id"
+ t-att-data-name="slide.name"
+ t-att-data-slide-type="slide.slide_type"
+ t-att-data-is-member="slide.channel_id.is_member"
+ t-att-data-completed="1 if slide_completed else 0"
+ t-att-data-quiz-attempts-count="quiz_attempts_count"
+ t-att-data-quiz-karma-max="quiz_karma_max"
+ t-att-data-quiz-karma-gain="quiz_karma_gain"
+ t-att-data-quiz-karma-won="quiz_karma_won"
+ t-att-data-has-next="1 if next_slide else 0"
+ t-att-data-next-slide-url="'/slides/slide/%s' % (slug(next_slide)) if next_slide else None"
+ t-att-data-channel-id="slide.channel_id.id"
+ t-att-data-channel-enroll="slide.channel_id.enroll"
+ t-att-data-channel-requested-access="slide.channel_id.has_requested_access"
+ t-att-data-channel-can-upload="slide.channel_id.can_upload"
+ t-att-data-signup-allowed="signup_allowed"
+ t-att-data-session-answers="session_answers">
+ <t t-foreach="slide_questions" t-as="question">
+ <t t-call="website_slides.lesson_content_quiz_question"/>
+ </t>
+ <t t-if="slide.channel_id.can_upload" t-call="website_slides.lesson_content_quiz_add_buttons"/>
+ <div class="o_wslides_js_lesson_quiz_validation pt-3"/>
+ </div>
+</template>
+
+<template id="lesson_content_quiz_question" name="Lesson: Quiz question template">
+ <div t-att-class="'o_wslides_js_lesson_quiz_question mt-3 %s' % ('completed-disabled' if slide_completed else ('disabled' if not (slide.channel_id.is_member or slide.is_preview) else ''))"
+ t-att-data-question-id="question['id']" t-att-data-title="question['question']" >
+ <div class="row d-flex mb-2 mx-0">
+ <div class="h4">
+ <small class="text-muted">
+ <i class="o_wslides_js_quiz_icon o_wslides_js_quiz_sequence_handler fa fa-bars mr-1 text-muted" t-if="slide.channel_id.can_upload and not slide_completed" />
+ <t t-if="question_index != NoneType"><span class="o_wslides_quiz_question_sequence" t-esc="question_index+1"/>.</t>
+ <t t-else=""><span class="o_wslides_quiz_question_sequence" t-esc="question['sequence']"/>.</t>
+ </small>
+ <span t-esc="question['question']"/>
+ </div>
+ <div class="ml-auto o_wslides_js_quiz_edit_del" t-if="slide.channel_id.can_upload and not slide_completed" >
+ <i class="o_wslides_js_quiz_icon o_wslides_js_quiz_edit_question fa fa-pencil-square-o p-1 text-muted"></i>
+ <i class="o_wslides_js_quiz_icon o_wslides_js_quiz_delete_question fa fa-trash p-1 text-muted"></i>
+ </div>
+ </div>
+ <div class="list-group">
+ <t t-foreach="question['answer_ids']" t-as="answer">
+ <a t-att-data-answer-id="answer['id']" href="#"
+ t-att-data-text="answer['text_value']" t-att-data-is-correct="answer['is_correct']" t-att-data-comment="answer['comment']"
+ t-att-class="'o_wslides_quiz_answer list-group-item list-group-item-action d-flex align-items-center %s' % ('list-group-item-success' if slide_completed and answer['is_correct'] else '')">
+ <label class="my-0 d-flex align-items-center justify-content-center mr-2">
+ <input type="radio"
+ t-att-name="question['id']"
+ t-att-value="answer['id']"
+ class="d-none"
+ t-att-disabled="True if not slide.channel_id.is_member or slide_completed else ''"/>
+ <i t-att-class="'fa fa-circle text-400 %s' % ('d-none' if slide_completed and answer['is_correct'] else '')"/>
+ <i class="fa fa-times-circle text-danger d-none"></i>
+ <i t-att-class="'fa fa-check-circle text-success %s' % ('d-none' if not (slide_completed and answer['is_correct']) else '')"></i>
+ </label>
+ <span t-esc="answer['text_value']"/>
+ </a>
+ </t>
+ <div class="o_wslides_quiz_answer_info list-group-item list-group-item-info d-none">
+ <i class="fa fa-info-circle"/>
+ <span class="o_wslides_quiz_answer_comment"/>
+ </div>
+ </div>
+ </div>
+</template>
+
+<template id="lesson_content_quiz_add_buttons" name="Lesson: Quiz Add Buttons template">
+ <div class="o_wslides_js_lesson_quiz_new_question row mt-3">
+ <a t-attf-class="o_wslides_js_quiz_add o_wslides_js_quiz_add_quiz btn btn-light border ml-3 #{'d-none ' if slide.question_ids else ''}" role="button">
+ <i class="fa fa-plus mr-2"/>
+ <span>Add Quiz</span>
+ </a>
+ <a t-attf-class="o_wslides_js_quiz_add o_wslides_js_quiz_add_question btn btn-light border ml-3 #{'' if slide.question_ids else 'd-none '}" role="button">
+ <i class="fa fa-plus mr-2"/>
+ <span>Add Question</span>
+ </a>
+ </div>
+</template>
+
+<!-- Slide sub-template: share: send by email -->
+<template id='slide_social_email' name="Share by Email">
+ <h5 class="mt-4">Share by mail</h5>
+ <div t-if="not is_public_user" class="form-inline">
+ <form class="form-group oe_slide_js_share_email" role="form">
+ <div class="input-group">
+ <input type="email" class="form-control" placeholder="your-friend@domain.com"/>
+ <span class="input-group-append">
+ <button class="btn btn-primary" type="button"
+ data-loading-text="Sending..."
+ t-attf-data-slide-id="#{slide.id}"
+ style="border-top-right-radius: 4px;border-bottom-right-radius: 4px;">
+ <i class="fa fa-envelope"/> Send Email
+ </button>
+ </span>
+ </div>
+ <span class="form-text text-muted d-block w-100">Send presentation through email</span>
+ </form>
+ </div>
+ <div t-if="is_public_user" class="alert alert-info d-inline-block">
+ <p class="mb-0">Please <a t-attf-href="/web?redirect=#{request.httprequest.url}" class="font-weight-bold"> login </a> to share this <t t-esc="slide.slide_type"/> by email.</p>
+ </div>
+</template>
+
+<!-- Slide sub-template: share: embed in your website -->
+<template id="slide_social_embed" name="Share on Your Website">
+ <div class="oe_slide_js_embed_code_widget mt-4">
+ <h5 class="mt0">Embed in your website</h5>
+ <div class="form-group">
+ <textarea class="form-control slide_embed_code" readonly="readonly" onClick="this.select();"><t t-esc="slide.embed_code"/></textarea>
+ </div>
+ <div class="form-group d-flex" t-if="slide.slide_type in ('presentation', 'document')">
+ <div class="form-text p-0 col-xs-5 col-sm-5 col-md-5 col-lg-5">Select page to start with</div>
+ <div class="input-group col-xs-3 col-sm-2 col-md-2 col-lg-3">
+ <input type="number" value="1" class="form-control"/>
+ </div>
+ </div>
+ </div>
+</template>
+
+</data></odoo>
diff --git a/addons/website_slides/views/website_slides_templates_lesson_embed.xml b/addons/website_slides/views/website_slides_templates_lesson_embed.xml
new file mode 100644
index 00000000..cea80e38
--- /dev/null
+++ b/addons/website_slides/views/website_slides_templates_lesson_embed.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" ?>
+<odoo>
+ <data>
+ <!--
+ This template is the PDF Viewer. It will mostly rendered throught an iFrame.
+ The js file to bind event is slides_embed.js
+ -->
+ <template id="embed_slide" name="Embedded Slide Page">
+ <html>
+ <head>
+ <title><t t-esc="slide.name"/></title>
+ <t t-call-assets="web.assets_common" t-js="false"/>
+ <t t-call-assets="website_slides.slide_embed_assets" t-js="false"/>
+ <t t-call-assets="web.assets_common" t-css="false"/>
+ <t t-call-assets="website_slides.slide_embed_assets" t-css="false"/>
+ </head>
+ <body>
+ <div id="PDFViewer" class="o_wslides_fs_pdf_viewer d-flex flex-column h-100">
+ <!-- PDF Viewer Header : contains the name, and the share links -->
+ <div t-if="is_embedded" class="oe_slides_share_bar">
+ <div class="container-fluid">
+ <div class="row align-items-center">
+ <div class="col">
+ <div class="oe_slides_ellipsis">
+ <a target="_new" t-att-href="slide.website_url">
+ <span t-esc="slide.name" t-att-title="slide.name"/>
+ </a>
+ </div>
+ </div>
+ <div class="col flex-grow-0 d-flex text-nowrap small">
+ <a href="#" class="oe_slide_js_embed_option_link" data-slide-option-id="#slide_share"><i class="fa fa-share-alt"/> Share</a>
+ <a href="#" class="oe_slide_js_embed_option_link mx-4" data-slide-option-id="#slide_email"><i class="fa fa-envelope"/> Email</a>
+ <a href="#" class="oe_slide_js_embed_option_link" data-slide-option-id="#slide_embed"><i class="fa fa-code"/> Embed</a>
+ </div>
+ </div>
+ </div>
+ </div>
+ <!-- PDF Viewer Body : contains the canvas, the loader, or the image-->
+ <div id="PDFSlideViewer" class="d-flex align-items-start position-relative flex-grow-1 overflow-auto" style="height: 0;"
+ t-attf-data-slideid="#{slide.id}"
+ t-attf-data-slideurl="/slides/slide/#{slug(slide)}/pdf_content"
+ t-attf-data-downloadable="#{False}"
+ t-att-data-defaultpage="page">
+ <t t-if="is_embedded">
+ <div id="slide_share" class="oe_slide_embed_option">
+ <t t-call="website_slides.slide_share_modal">
+ <t t-set="record" t-value="slide"/>
+ <t t-set="website_url" t-value="slide.channel_id.website_url"/>
+ </t>
+ </div>
+ <div id="slide_email" class="oe_slide_embed_option">
+ <t t-call="website_slides.slide_social_email"/>
+ </div>
+ <div id="slide_embed" class="oe_slide_embed_option">
+ <t t-call="website_slides.slide_social_embed"/>
+ </div>
+ </t>
+ <div id="slide_suggest" class="oe_slide_embed_option bg-300 container-fluid overflow-auto d-none">
+ <div class="row">
+ <t t-foreach="related_slides" t-as="suggest_slide">
+ <div class="col-6 col-md-4 col-lg-3 oe_slides_suggestion_media">
+ <div class="card mb-3">
+ <a t-att-href="suggest_slide.website_url" target="_new" class="card-img-top embed-responsive embed-responsive-16by9">
+ <img t-att-src="website.image_url(suggest_slide, 'image_1024')" class="card-img-top embed-responsive-item" t-att-alt="suggest_slide.name"/>
+ </a>
+ <div class="card-body">
+ <h6 class="card-title">
+ <a t-att-href="suggest_slide.website_url" target="_new">
+ <t t-esc="suggest_slide.name"/>
+ </a>
+ </h6>
+ <div class="oe_slides_suggestion_caption"/>
+ </div>
+ </div>
+ </div>
+ </t>
+ </div>
+ </div>
+ <t t-if="slide.slide_type in ('presentation', 'document')">
+ <div id="PDFViewerLoader" class="oe_slides_loader mt-3 mx-2 w-100">
+ <div class="toast show mx-auto">
+ <div class="toast-header">
+ <i class="fa fa-circle-o-notch fa-spin mr-2"/><b>Loading...</b>
+ </div>
+ <div class="toast-body p-0">
+ <img class="img-fluid w-100" t-att-src="website.image_url(slide, 'image_256')"/>
+ </div>
+ </div>
+ </div>
+ <canvas id="PDFViewerCanvas" class="mx-auto" style="display: none;"></canvas>
+ </t>
+ <t t-if="slide.slide_type == 'infographic'">
+ <img t-att-src="website.image_url(slide, 'image_1024')" class="img-fluid" style="width: 100%" alt="Slide image"/>
+ </t>
+ </div>
+ <!-- Fixed bottom navbar -->
+ <div id="PDFViewerNav" class="pt-2 pb-2 bg-light text-white" role="navigation" t-if="slide.slide_type in ('presentation', 'document')">
+ <div class="container-fluid oe_slides_panel_footer">
+ <div class="row align-items-center">
+ <div class="col-3 d-flex align-items-center">
+ <div class="input-group input-group-sm flex-nowrap" style="max-width: 100px">
+ <input type="number" class="form-control text-center" id="page_number" style="min-width: 60px"/>
+ <div class="input-group-append">
+ <span class="input-group-text" id="page_count"/>
+ </div>
+ </div>
+ <a id="zoomout" href="#" class="text-decoration-none d-none d-sm-inline ml-2 mr-2" title="Zoom out" aria-label="Zoom out" role="button">
+ <i class="fa fa-search-minus" />
+ </a>
+ <a id="zoomin" href="#" class="text-decoration-none d-none d-sm-inline" title="Zoom in" aria-label="Zoom in" role="button">
+ <i class="fa fa-search-plus" />
+ </a>
+ </div>
+ <div class="col text-center">
+ <a id="first" href="#" onclick="return false;"
+ class="text-decoration-none mr-1 mr-sm-2" title="First slide"
+ role="button" aria-label="First slide"> <i class="fa fa-step-backward"/> </a>
+ <a id="previous" href="#" onclick="return false;"
+ class="text-decoration-none mx-1 mx-sm-2" title="Previous slide"
+ aria-label="Previous slide" role="button"> <i class="fa fa-arrow-circle-left"/> </a>
+ <a id="next" href="#" onclick="return false;"
+ class="text-decoration-none mx-1 mx-sm-2" title="Next slide"
+ aria-label="Next slide" role="button"> <i class="fa fa-arrow-circle-right"/> </a>
+ <a id="last" href="#" onclick="return false;"
+ class="text-decoration-none mx-1 mx-sm-2" title="Last slide"
+ aria-label="Last slide" role="button"> <i class="fa fa-step-forward"/> </a>
+ <a t-if="slide.slide_resource_downloadable" id="download" t-attf-href="/web/content/slide.slide/#{slide.id}/datas?download=true"
+ class="text-decoration-none ml-1 ml-sm-2" title="Download Content" role="img" aria-label="Download">
+ <i class="fa fa-download" />
+ </a>
+ </div>
+ <div class="col-3 text-right flex-grow-0">
+ <a id="fullscreen" href="#" onclick="return false;"
+ class="text-decoration-none ml-1 ml-sm-2"
+ title="View fullscreen" role="img" aria-label="Fullscreen">
+ <i class="fa fa-arrows-alt"/>
+ </a>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+ </html>
+ </template>
+
+ <!--
+ Template render isntead of Embedded Slide, it this one is forbidden.
+ So, it will mostly be rendered throught an iFrame
+ -->
+ <template id="embed_slide_forbidden" name="Forbidden Embedded Slide">
+ <html>
+ <head>
+ <t t-call-assets="website_slides.slide_embed_assets" t-js="false"/>
+ </head>
+ <body>
+ <div class="slide-private-view">
+ <h3 style="border-bottom: 1px solid !important;padding-bottom: 10px;"><i class="fa fa-exclamation-triangle" role="img" aria-label="Attention" title="Attention"></i> This document is private.</h3>
+ </div>
+ </body>
+ </html>
+ </template>
+ </data>
+</odoo>
diff --git a/addons/website_slides/views/website_slides_templates_lesson_fullscreen.xml b/addons/website_slides/views/website_slides_templates_lesson_fullscreen.xml
new file mode 100644
index 00000000..2fa732b2
--- /dev/null
+++ b/addons/website_slides/views/website_slides_templates_lesson_fullscreen.xml
@@ -0,0 +1,170 @@
+<?xml version="1.0" ?>
+<odoo><data>
+
+<!-- Slide template for the fullscreen mode -->
+<template id="slide_fullscreen" name="Fullscreen">
+ <t t-set="head">
+ <link rel="canonical" t-att-href="slide.website_url" />
+ </t>
+ <t t-call="website.layout">
+ <div class="o_wslides_fs_main d-flex flex-column font-weight-light"
+ t-att-data-channel-id="slide.channel_id.id"
+ t-att-data-channel-enroll="slide.channel_id.enroll"
+ t-att-data-signup-allowed="signup_allowed"
+ t-att-data-session-answers="session_answers">
+
+ <div class="o_wslides_slide_fs_header d-flex flex-shrink-0 text-white">
+ <div class="d-flex">
+ <a class="o_wslides_fs_toggle_sidebar d-flex align-items-center px-3" href="#" title="Lessons">
+ <i class="fa fa-bars"/><span class="d-none d-md-inline-block ml-1">Lessons</span>
+ </a>
+ <a class="o_wslides_fs_review d-flex align-items-center px-3" t-att-href="slide.channel_id.website_url + '?active_tab=review'" title="Reviews" t-if="slide.channel_id.allow_comment">
+ <i class="fa fa-pencil"/><span class="d-none d-md-inline-block ml-1">Write a review</span>
+ </a>
+ <a class="o_wslides_fs_share d-flex align-items-center px-3" href="#" title="Share">
+ <i class="fa fa-share-alt"/><span class="d-none d-md-inline-block ml-1">Share</span>
+ </a>
+ </div>
+ <div class="d-flex ml-auto">
+ <a class="d-flex align-items-center px-3 o_wslides_fs_exit_fullscreen" t-attf-href="/slides/slide/#{slug(slide)}">
+ <i class="fa fa-sign-out"/><span class="d-none d-md-inline-block ml-1">Exit Fullscreen</span>
+ </a>
+ <a class="d-flex align-items-center px-3" t-attf-href="/slides/#{slug(slide.channel_id)}">
+ <i class="fa fa-home"/><span class="d-none d-md-inline-block ml-1">Back to course</span>
+ </a>
+ </div>
+ </div>
+
+ <div class="o_wslides_fs_container d-flex position-relative overflow-hidden flex-grow-1">
+ <div class="o_wslides_fs_content align-items-stretch justify-content-center d-flex flex-grow-1 order-2"></div>
+
+ <div class="o_wslides_fs_sidebar o_wslides_fs_sidebar_hidden text-white flex-shrink-0 order-1">
+ <div class="o_wslides_fs_sidebar_content d-flex flex-column px-3 pt-3 h-100">
+ <div class="o_wslides_fs_sidebar_header mb-3">
+ <a class="h5 d-block mb-1" t-attf-href="/slides/#{slug(slide.channel_id)}">
+ <span t-field="slide.channel_id.name"/>
+ </a>
+ <div t-if="not is_public_user" class="d-flex align-items-center">
+ <t t-if="slide.channel_id.completed">
+ <span class="badge badge-pill badge-success py-1 px-2" style="font-size: 1em"><i class="fa fa-check"/> Completed</span>
+ </t>
+ <t t-else="">
+ <div class="progress flex-grow-1 bg-black-50" style="height: 6px;">
+ <div class="progress-bar" role="progressbar" t-attf-style="width: #{slide.channel_id.completion}%" t-att-aria-valuenow="slide.channel_id.completion" aria-valuemin="0" aria-valuemax="100"></div>
+ </div>
+ <div class="ml-3 small">
+ <span class="o_wslides_progress_percentage" t-esc="slide.channel_id.completion"/> %
+ </div>
+ </t>
+ </div>
+ </div>
+ <ul class="mx-n3 list-unstyled my-0 pb-2 overflow-auto">
+ <t t-foreach="category_data" t-as="category">
+ <t t-if="category.get('slides')">
+ <t t-call="website_slides.slide_fullscreen_sidebar_category">
+ <t t-set="slides" t-value="category['slides']"/>
+ <t t-set="current_slide" t-value="slide"/>
+ </t>
+ </t>
+ </t>
+ </ul>
+ </div>
+ <a href="#" class="o_wslides_fs_toggle_sidebar d-lg-none bg-black-50"/>
+ </div>
+ </div>
+ </div>
+ </t>
+</template>
+
+
+<template id="slide_fullscreen_sidebar_category" name="Slides category template for fullscreen view side bar">
+ <t t-if="category" t-set="category" t-value="category.get('category')"/>
+ <li class="o_wslides_fs_sidebar_section py-2 px-3">
+ <a t-if="category" class="text-uppercase text-500 py-1 small d-block" t-attf-id="category-collapse-#{category.id if category else 0}" data-toggle="collapse" role="button" aria-expanded="true" t-att-href="('#collapse-%s') % (category.id if category else 0)" t-attf-aria-controls="collapse-#{category.id if category else 0}">
+ <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-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"/>
+ <li t-att-class="'o_wslides_fs_sidebar_list_item d-flex align-items-top py-1 %s' % ('active' if slide.id == current_slide.id else '')"
+ t-att-data-id="slide.id"
+ t-att-data-can-access="can_access"
+ t-att-data-name="slide.name"
+ t-att-data-type="slide.slide_type"
+ t-att-data-slug="slug(slide)"
+ t-att-data-has-question="1 if slide.question_ids else 0"
+ t-att-data-is-quiz="0"
+ t-att-data-completed="1 if slide_completed else 0"
+ t-att-data-embed-code="slide.embed_code if slide.slide_type in ['video', 'document', 'presentation', 'infographic'] else False"
+ t-att-data-is-member="is_member"
+ t-att-data-session-answers="session_answers">
+ <span class="ml-3">
+ <i t-if="slide_completed and is_member" class="o_wslides_slide_completed fa fa-check fa-fw text-success" t-att-data-slide-id="slide.id"/>
+ <i t-if="not slide_completed and is_member" class="fa fa-circle-thin fa-fw" t-att-data-slide-id="slide.id"/>
+ </span>
+ <div class="ml-2">
+ <a t-if="can_access" class="d-block pt-1" href="#">
+ <div class="d-flex ">
+ <t t-call="website_slides.slide_icon"/>
+ <div class="o_wslides_fs_slide_name" t-esc="slide.name"/>
+ </div>
+ </a>
+ <span t-else="" class="d-block pt-1" href="#">
+ <div class="d-flex ">
+ <t t-set="icon_class" t-value="'mr-2 text-600'"/>
+ <t t-call="website_slides.slide_icon"/>
+ <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.link_ids or slide.slide_resource_ids or (slide.question_ids and not slide.slide_type =='quiz')" >
+ <li t-if="slide.link_ids" t-foreach="slide.link_ids" 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>
+ <div class="o_wslides_js_course_join pl-0" t-if="slide.slide_resource_ids">
+ <t t-if="is_member or slide.channel_id.can_publish">
+ <li t-foreach="slide.slide_resource_ids" 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">
+ <i class="fa fa-download mr-1"/>
+ <t t-call="website_slides.join_course_link"/>
+ </li>
+ </div>
+ <li class="o_wslides_fs_sidebar_list_item pl-0 mb-1" t-if="slide.question_ids and not slide.slide_type == 'quiz'"
+ t-att-data-id="slide.id"
+ t-att-data-can-access="can_access"
+ t-att-data-name="slide.name"
+ t-att-data-type="slide.slide_type"
+ t-att-data-slug="slug(slide)"
+ t-att-data-has-question="1 if slide.question_ids else 0"
+ t-att-data-is-quiz="1"
+ t-att-data-completed="1 if slide_completed else 0"
+ t-att-data-is-member="is_member"
+ t-att-data-session-answers="session_answers">
+ <a t-if="can_access" class="o_wslides_fs_slide_quiz" href="#" t-att-index="i">
+ <i class="fa fa-flag-checkered text-warning mr-2"/>Quiz
+ </a>
+ <span t-else="" class="text-600">
+ <i class="fa fa-flag-checkered text-warning mr-2"/>Quiz
+ </span>
+ </li>
+ </ul>
+ </div>
+ </li>
+ </t>
+ </ul>
+ </li>
+</template>
+
+
+</data></odoo>
diff --git a/addons/website_slides/views/website_slides_templates_profile.xml b/addons/website_slides/views/website_slides_templates_profile.xml
new file mode 100644
index 00000000..d1a5a3f6
--- /dev/null
+++ b/addons/website_slides/views/website_slides_templates_profile.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" ?>
+<odoo><data>
+ <!--Private profile-->
+ <template id="private_profile" inherit_id="website_profile.private_profile">
+ <xpath expr="//div[@id='private_profile_return_link_container']" position="inside">
+ <t t-if="request.params.get('channel_id')">
+ <p><a t-attf-href="/slides/course-#{request.params.get('channel_id')}">Return to the course.</a></p>
+ </t>
+ </xpath>
+ </template>
+
+ <template id="user_profile_content" inherit_id="website_profile.user_profile_content">
+ <xpath expr="//div[@id='profile_about_badge']" position="before">
+ <t t-if="channel">
+ <div class="mb32">
+ <h5 class="border-bottom pb-1">Completed Courses</h5>
+ <t t-if="courses_completed" t-call="website_slides.display_course">
+ <t t-set="courses" t-value="courses_completed"></t>
+ </t>
+ <div t-else="" class="text-muted d-inline-block">No completed courses yet!</div>
+ <div class="text-right d-inline-block pull-right">
+ <a href="/slides/all" class="btn btn-link btn-sm"><i class="fa fa-arrow-right mr-1"/>All Courses</a>
+ </div>
+ </div>
+ <div class="mb32">
+ <h5 class="border-bottom pb-1">Followed Courses</h5>
+ <t t-if="courses_ongoing" t-call="website_slides.display_course">
+ <t t-set="courses" t-value="courses_ongoing"></t>
+ </t>
+ <p t-else="" class="text-muted">No followed courses yet!</p>
+ </div>
+ </t>
+ </xpath>
+ </template>
+
+ <template id="display_course">
+ <div class="row">
+ <div class="col-12 col-lg-6" t-foreach="courses" t-as="course">
+ <div class="card mb-2">
+ <div class="card-body o_wprofile_slides_course_card_body p-0 d-flex"
+ t-attf-onclick="location.href='/slides/#{slug(course.channel_id)}';">
+
+ <div t-if="course.channel_id.image_1024" class="pl-5 pr-4 rounded-left" t-attf-style="background-image: url(#{website.image_url(course.channel_id, 'image_1024')}); background-size: cover; background-position: center"/>
+ <div t-else="" class="o_wslides_gradient pl-5 pr-4 rounded-left position-relative" style="opacity: 0.8">
+ <i class="fa fa-graduation-cap fa-fw mr-2 mt-3 position-absolute text-white-75" style="right:0; top: 0"/>
+ </div>
+
+ <div class="p-2 w-100">
+ <h5 class="mt-0 mb-1" t-field="course.channel_id.name"/>
+
+ <div class="overflow-hidden mb-1" style="height:24px">
+ <t t-foreach="course.channel_id.tag_ids" t-as="tag">
+ <a t-att-href="'/slides/all?channel_tag_id=%s' % tag.id" t-attf-class="badge o_wslides_channel_tag #{'o_tag_color_'+str(tag.color)}" t-esc="tag.name"/>
+ </t>
+ </div>
+
+ <div class="d-flex align-items-center">
+ <div class="progress flex-grow-1" style="height:0.5em">
+ <div class="progress-bar bg-primary" t-att-style="'width: '+ str(course.completion)+'%'"/>
+ </div>
+ <small class="font-weight-bold pl-2"><span t-esc="course.completion"/> %</small>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </template>
+</data></odoo>
diff --git a/addons/website_slides/views/website_slides_templates_utils.xml b/addons/website_slides/views/website_slides_templates_utils.xml
new file mode 100644
index 00000000..90591c6e
--- /dev/null
+++ b/addons/website_slides/views/website_slides_templates_utils.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" ?>
+<odoo><data>
+
+<!-- Share on social networks -->
+<template id='slide_share_social' name="Slides Media Share">
+ <div class="btn-group" role="group">
+ <a t-attf-href="https://www.facebook.com/sharer/sharer.php?u=#{record.website_url}" class="btn border bg-white o_wslides_js_social_share" social-key="facebook" aria-label="Share on Facebook" title="Share on Facebook"><i class="fa fa-facebook-square fa-fw"/></a>
+ <a t-attf-href="https://twitter.com/intent/tweet?text=#{record.name}&amp;url=#{record.website_url}" class="btn border bg-white o_wslides_js_social_share" social-key="twitter" aria-label="Share on Twitter" title="Share on Twitter"><i class="fa fa-twitter fa-fw"/></a>
+ <a t-attf-href="http://www.linkedin.com/sharing/share-offsite/?url=#{record.website_url}" social-key="linkedin" class="btn border bg-white o_wslides_js_social_share" aria-label="Share on LinkedIn" title="Share on LinkedIn"><i class="fa fa-linkedin fa-fw"/></a>
+ </div>
+</template>
+
+<!-- Share: social media -->
+<template id='slide_share_modal'>
+ <t t-if="not website_url">
+ <t t-set="website_url" t-value="record.website_url"/>
+ </t>
+ <div class="modal fade" t-att-id="'slideChannelShareModal_%s' % record.id" tabindex="-1" role="dialog" aria-labelledby="slideChannelShareModalLabel" aria-hidden="true">
+ <div class="modal-dialog" role="document">
+ <div class="modal-content">
+ <t t-call="website_slides.slide_share_modal_header"/>
+ <t t-call="website_slides.slide_share_modal_body"/>
+ </div>
+ </div>
+ </div>
+</template>
+
+<template id="slide_share_modal_header">
+ <div class="modal-header">
+ <h5 class="modal-title" id="slideChannelShareModalLabel">
+ Share
+ </h5>
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+ <span>×</span>
+ </button>
+ </div>
+</template>
+
+<template id="slide_share_modal_body">
+ <div class="modal-body">
+ <h5>Share on Social Networks</h5>
+ <t t-call="website_slides.slide_share_social"/>
+ <t t-call="website_slides.slide_share_link"/>
+ </div>
+</template>
+
+<template id="slide_share_link">
+ <h5 class="mt16">Share Link</h5>
+ <div class="input-group">
+ <input type="text" t-att-id="'wslides_share_link_id_%s' % record.id" class="form-control o_wslides_js_share_link" readonly="readonly" onclick="this.select();"
+ t-att-value="website_url"/>
+ <div class="input-group-append">
+ <button t-att-id="'share_link_clipboard_button_id_%s' % record.id" class="btn btn-sm btn-primary o_clipboard_button" >
+ <span class="fa fa-clipboard"> Copy Text</span>
+ </button>
+ </div>
+ </div>
+</template>
+
+<!-- Website edit page -->
+<template id="slide_edit_options" inherit_id="website.user_navbar" name="Edit Slide Options">
+ <xpath expr="//li[@id='edit-page-menu']" position="after">
+ <t t-if="main_object._name == 'slide.slide'" t-set="action" t-value="'website_slides.slide_slide_action'"/>
+ </xpath>
+</template>
+
+<!-- User Navbar -->
+<template id="user_navbar_inherit_website_slides" inherit_id="website.user_navbar">
+ <xpath expr="//div[@id='o_new_content_menu_choices']//div[@name='module_website_slides']" position="attributes">
+ <attribute name="name"/>
+ <attribute name="t-att-data-module-id"/>
+ <attribute name="t-att-data-module-shortdesc"/>
+ <attribute name="groups">website_slides.group_website_slides_officer</attribute>
+ </xpath>
+</template>
+
+<template id="join_course_link" name="Join Course Link">
+ <a class="o_wslides_js_course_join_link" href="#"
+ t-att-data-channel-id="slide.channel_id.id">
+ Join Course
+ </a> to download resources
+</template>
+
+</data></odoo>