[MERGE] website_slides: various fixes for frontend and first design tweaks

Purpose of this merge is to provide several fixes related to new elearning
application. Those are mainly fixes for front-end templates and first
design improvements / fixes.

See sub commits for more details.

Merge linked to task ID 1941250 and PR #31279.

closes odoo/odoo#31306
This commit is contained in:
Robot Odoo
2019-02-21 08:49:21 +01:00
committed by GitHub
21 changed files with 373 additions and 430 deletions
+3 -1
View File
@@ -36,7 +36,6 @@ class WebsiteProfile(http.Controller):
content = base64.b64encode(image)
dictheaders = dict(headers) if headers else {}
dictheaders['Content-Type'] = 'image/png'
headers = list(dictheaders.items())
if not (width or height):
suffix = field.split('_')[-1] if '_' in field else 'large'
if suffix in ('small', 'medium', 'large', 'big'):
@@ -45,6 +44,9 @@ class WebsiteProfile(http.Controller):
def _check_user_profile_access(self, user_id):
user_sudo = request.env['res.users'].sudo().browse(user_id)
# User can access - no matter what - his own profile
if user_sudo.id == request.env.user.id:
return user_sudo
if user_sudo.karma == 0 or not user_sudo.website_published or \
(user_sudo.id != request.session.uid and request.env.user.karma < request.website.karma_profile_min):
return False
+1 -1
View File
@@ -5,7 +5,7 @@
'summary': 'Sell your courses online',
'description': """Sell your courses using the e-commerce features of the website.""",
'category': 'Hidden',
'version': '0.1',
'version': '1.0',
'depends': ['website_slides', 'website_sale'],
'installable': True,
+13 -11
View File
@@ -1,21 +1,23 @@
# -*- coding: utf-8 -*-
{
'name': 'Slides',
'version': '1.0',
'name': 'eLearning',
'version': '2.0',
'sequence': 145,
'summary': 'Publish videos, slides and documents',
'summary': 'Create online Courses',
'website': 'https://www.odoo.com/page/slides',
'category': 'Website',
'description': """
Share and Publish Videos, Presentations and Documents'
======================================================
Create Online Courses
=====================
* Website Application
* Channel Management
* Filters and Tagging
* Statistics of Presentation
* Channel Subscription
* Supported document types : PDF, images, YouTube videos and Google Drive documents)
Featuring
* Integrated course and lesson management
* Fullscreen navigation
* Support Youtube videos, Google documents, PDF, images, web pages
* Test knowledge with quizzes
* Filter and Tag
* Statistics
""",
'depends': [
'website',
@@ -102,7 +102,7 @@ will learn the basics of wood characteristics.</field>
<field name="promote_strategy">most_voted</field>
<field name="website_published" eval="True"/>
<field name="enroll">invite</field>
<field name="image" type="base64" file="website_slides/static/src/img/channel_demo_furniture.jpg"/>
<field name="image" type="base64" file="website_slides/static/src/img/channel_demo_furniture_2.jpg"/>
<field name="description">We're also Santa Claus! Belligerent and numerous. I am the man with no name, Zapp Brannigan!</field>
</record>
<record id="slide_category_demo_4_0" model="slide.category">
Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

@@ -66,7 +66,7 @@
.o_wslides_fullscreen_container {
display: flex;
align-items: stretch;
height: 100%;
height: calc(100% - 50px);
position: relative;
background-color: #313A44;
}
@@ -19,56 +19,37 @@ $MAX-Z-INDEX : 2147483647 !default;
// Common to new slides pages
// **************************************************
.o_wslides_container {
margin: auto;
width: 100%;
max-width: 1140px;
padding: 0px 32px 0px 32px;
}
.o_wslides_wrap {
.text_small_caps {
font-variant: small-caps;
}
.image-muted {
opacity: 0.5;
}
background-color: desaturate(map-get($grays, "200"), 80%);
.cta-title {
font-size: 1.2em;
font-size: 1.2em;
}
}
// New home page
// **************************************************
div .o_wslides_home_nav {
position: relative;
top: -50px;
}
div .o_wslides_home_main {
.o_wslides_home_header {
}
.o_wslides_home_footer {
}
.o_wslides_home_aside {
.fa-check {
color: #00A09D;
font-size: 1.2em;
}
}
.o_wslides_home_content_section_title, .o_wslides_home_aside_title {
h3 {
font-size: 1.4em;
}
h4 {
font-size: 1.3em;
}
}
.o_wslides_course_card {
.card-body {
padding: 0.75em 1em;
}
.card-footer {
padding-top: 0.75em 1em;
padding: 0.75em 1em;
}
}
.o_wslides_lesson_card {
.card-body {
padding: 0.75em 1em;
}
.card-footer {
padding: 0.75em 1em;
}
}
// responsive card-deck like
.row.o_wslides_row > div[class*='col-'] {
display: flex;
@@ -80,13 +61,17 @@ div .o_wslides_home_main {
// tools
// ****************************************
.text_small_caps {
font-variant: small-caps;
}
.image-muted {
img.o_wslides_img_muted {
opacity: 0.5;
}
img.o_wslides_img_center_crop {
object-fit: cover;
object-position: center;
}
.o_wslides_home_circled {
border-radius: 50%;
@@ -134,16 +119,44 @@ div .o_wslides_home_main {
}
}
// New course page
// New home page
// **************************************************
.o_wslides_container {
margin: auto;
width: 100%;
max-width: 1140px;
padding: 32px 32px 0px 32px;
div .o_wslides_home_nav {
top: -40px;
@include media-breakpoint-up(md) {
font-size: 1rem;
.o_wslides_nav_navbar_right {
margin-left: auto;
padding-left: $spacer;
border-left: 1px solid $border-color;
}
}
}
div .o_wslides_home_main {
.o_wslides_home_aside {
.fa-check {
color: #00A09D;
font-size: 1.2em;
}
}
.o_wslides_home_content_section_title, .o_wslides_home_aside_title {
h3 {
font-size: 1.4em;
}
h4 {
font-size: 1.3em;
}
}
}
// New course page
// **************************************************
.o_wslides_course_nav {
margin: auto;
background: linear-gradient(150deg, #875A7B 20%, #62495B 80%) !important;
@@ -153,6 +166,10 @@ div .o_wslides_home_main {
color: #FFFFFF;
}
small a {
color: #000000;
}
nav {
.breadcrumb-item::before {
font-weight: bold;
@@ -187,66 +204,54 @@ div .o_wslides_home_main {
top: 48px;
padding-top: 0px;
.o_wslides_course_header_content {
font-size: 16px;
color: #FFFFFF;
.o_wslides_course_description {
margin-right: 36px;
}
}
.o_wslides_course_header_aside {
max-width: 286px;
img {
width: 100%;
max-width: 256px;
}
}
.o_wslides_course_header_content {
font-size: 16px;
color: #FFFFFF;
.o_wslides_course_header_nav {
ul.o_wslides_nav_tabs {
border-bottom: 0px;
li.nav-item {
margin-bottom: 0px;
}
a.nav-link {
color: white;
border-radius: 0px;
height: 48px;
font-weight: bold;
padding-top: 12px;
border-left: 2px solid #875A7B;
text-align: center;
width: 120px;
&:hover {
border: 0px;
border-radius: 0px;
background-color: #875A7B;
}
&.active {
color: #212529;
background-color: #f2f2f2;
border: 0px;
}
}
}
}
}
}
}
.o_wslides_course_content {
.o_wslides_course_main {
margin: auto;
background-color: #f2f2f2;
.o_wslides_content_container {
position: relative;
top: -80px;
}
// responsive card-deck like
.row.o_wslides_row > div[class*='col-'] {
display: flex;
flex:1 0 auto;
.card {
width:100%;
}
}
.o_wslides_course_content_nav {
.o_wslides_nav_tabs {
border-bottom: 0px;
}
.o_wslides_navlink {
color: white;
border-radius: 0px;
height: 48px;
font-weight: bold;
padding-top: 12px;
border-left: 2px solid #875A7B;
text-align: center;
width: 120px;
&:hover {
border: 0px;
border-radius: 0px;
background-color: #875A7B;
}
}
.o_wslides_navlink.active {
color: #212529;
background-color: #f2f2f2;
border: 0px;
}
}
.o_wslides_course_content_main {
h3 {
font-size: 1.4em;
@@ -257,22 +262,20 @@ div .o_wslides_home_main {
}
.o_wslides_course_content_aside {
top: 1px;
width: 256px;
max-width: 256px;
margin-left: 15px;
background-color: white;
max-width: 286px;
.bg-white {
max-width: 256px;
background-color: white;
padding-bottom: 8px;
> div.row {
padding-left: 15px;
padding-right: 15px;
}
}
.o_wslides_course_aside_line {
}
}
.o_wslides_lesson_card {
.card-footer {
padding-top: 0.75em;
padding-bottom: 0.75em;
}
}
}
}
@@ -297,34 +300,6 @@ div .o_wslides_home_main {
overflow-y: auto !important;
}
.oe_slide_embed_wrapper {
position: relative;
}
section.oe_slides_promote_box {
background-color: $panel-footer-bg;
border-bottom: 1px solid $nav-tabs-border-color;
border-top: 1px solid $nav-tabs-border-color;
}
img.oe_slides_channel_thumbnail {
@include top-covered-image;
height: 250px;
width: 100%
}
img.oe_slides_opacity {
opacity: .5;
}
img.oe_slides_promote_image {
@include top-covered-image;
max-height: 300px;
width: 100%;
overflow: hidden;
display: block;
}
.oe_slides_apart_small {
@include top-covered-image;
height: 60px;
@@ -340,26 +315,12 @@ img.oe_slides_promote_image {
max-height: 500px;
}
.oe_slides_bottom_border {
border-bottom: 1px solid $nav-tabs-border-color;
}
.o_wslides_like_up, .o_wslides_like_down {
cursor: pointer;
color: $link-color;
}
textarea.o_slides_comment {
resize: vertical;
}
// Thumbnails
.oe_slides_grid_thumbnail {
@include top-covered-image;
height: 200px;
width: 100%;
overflow: hidden;
}
.oe_slides_ellipsis {
white-space: nowrap;
width: 100%;
@@ -3,11 +3,11 @@
<div t-if="slide.slide_type == 'video' &amp;&amp; !showMiniQuiz" class="player embed-responsive embed-responsive-16by9 embed-responsive-item">
<iframe id="youtube-player" t-att-src="embed_url" allowFullScreen="true" frameborder="0" enablejsapi="1" autoplay="1" allow="autoplay"></iframe>
</div>
<div t-if="slide.slide_type in ['presentation', 'document'] &amp;&amp; !showMiniQuiz" class="embed-responsive embed-responsive-4by3 embed-responsive-item ">
<div t-if="['presentation', 'document'].indexOf(slide.slide_type) !== -1 &amp;&amp; !showMiniQuiz" class="embed-responsive embed-responsive-4by3 embed-responsive-item ">
<iframe t-att-src="embed_url" class="o_wslides_iframe_viewer" allowFullScreen="true" height="315" width="420" frameborder="0"></iframe>
</div>
<div style="width:100%;height:100%;" t-if="slide.slide_type == 'infographic' &amp;&amp; !showMiniQuiz">
<img t-attf-src="/web/image/slide.slide/#{slide.id}/datas" class="img-fluid" style="width: 100%" alt="Slide image"/>
<div style="width:100%;height:100%;text-align:center;" t-if="slide.slide_type == 'infographic' &amp;&amp; !showMiniQuiz">
<img t-attf-src="/web/image/slide.slide/#{slide.id}/image" class="img-fluid" style="height: 100%" alt="Slide image"/>
</div>
<div t-if="(slide.slide_type == 'quiz' || showMiniQuiz) &amp;&amp; questions " class="o_wslides_fullscreen_quiz">
<div>
@@ -7,7 +7,7 @@
<div class="container">
<div class="row align-items-center justify-content-between">
<!-- nav -->
<nav aria-label="breadcrumb" class="col-6">
<nav aria-label="breadcrumb" class="col-md-6 col-xs-12">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/slides">Home</a>
@@ -26,7 +26,7 @@
</li>
</ol>
</nav>
<div class="col-6 d-flex flex-row align-items-center">
<div class="col-md-6 col-xs-12 d-flex flex-row align-items-center">
<!-- karma / profile -->
<a t-if="not is_public_user" t-att-href="'/profile/user/%s?channel_id=%s' % (user.id, channel.id)" class="font-weight-bold mr-3">
<i class="fa fa-diamond" /> <t t-esc="user_id.karma"/>
@@ -81,15 +81,15 @@
<div class="row o_wslides_course_header">
<div class="col-lg-12 o_wslides_container o_wslides_course_header_container">
<div class="row align-items-end">
<div class="col o_wslides_course_header_aside main_image">
<div t-field="channel.image" widget="image" t-options="{'widget': 'image'}"/>
<div class="row align-items-end d-flex">
<div class="col-md-4 d-none d-sm-block o_wslides_course_header_aside">
<div t-field="channel.image" widget="image" t-options="{'widget': 'image'}"/>
</div>
<div class="col-8 o_wslides_course_header_content">
<h3 class="row"><span class="font-weight-bold col" t-field="channel.name"/></h3>
<div class="col-md-8 col-xs-12 align-self-stretch d-flex flex-column o_wslides_course_header_content">
<div class="row">
<div class="col-12 o_wslides_course_description" t-field="channel.description"/>
<div class="col-6 mt8 mb64">
<h3 class="col-12"><span class="font-weight-bold" t-field="channel.name"/></h3>
<div class="col-12" t-field="channel.description"/>
<div class="col-xs-12 col-md-6 mt8">
<t t-call="website_rating.rating_stars_static_popup_composer">
<t t-set="rating_avg" t-value="rating_avg"/>
<t t-set="rating_total" t-value="rating_count"/>
@@ -103,129 +103,132 @@
</t>
</div>
</div>
<div class="row mt-auto o_wslides_course_header_nav">
<div class="col-xs-12 col-md-8">
<ul class="nav nav-tabs o_wslides_nav_tabs" role="tablist" id="profile_extra_info_tablist">
<li class="nav-item o_wslides_nav_tabs_item_home">
<a t-att-href="'/slides/%s%s?%s' % (slug(channel), '/%s' % slug(category) if category else '', keep_query('debug'))"
t-att-class="'nav-link %s' % ('' if search_slide_type else 'active')">
<i class="fa fa-home"/> Course</a>
</li>
<li class="nav-item">
<a t-att-href="'/slides/%s' % (slug(channel))"
t-att-class="'nav-link'">Review</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row o_wslides_course_content">
<div class="col-lg-12 o_wslides_container o_wslides_content_container">
<div class="row justify-content-end o_wslides_course_content_nav">
<div class="col-8">
<ul class="nav nav-tabs o_wslides_nav_tabs" role="tablist" id="profile_extra_info_tablist">
<li class="nav-item o_wslides_nav_tabs_item_home">
<a t-att-href="'/slides/%s%s?%s' % (slug(channel), '/%s' % slug(category) if category else '', keep_query('debug'))"
t-att-class="'nav-link o_wslides_navlink %s' % ('' if search_slide_type else 'active')">
<i class="fa fa-home"/> Home</a>
</li>
<li class="nav-item">
<a t-att-href="'/slides/%s' % (slug(channel))"
t-att-class="'nav-link o_wslides_navlink'">Review</a>
</li>
</ul>
</div>
</div>
<div class="row o_wslides_course_main">
<div class="col-lg-12 o_wslides_container o_wslides_content_containerUNFUCKME">
<div class="row o_wslides_course_content_main">
<!-- Channel presentation, aka general information + CTAs -->
<div class="col-4 o_wslides_course_content_aside">
<div class="row justify-content-center mt8 o_wslides_join_channel">
<a t-if="not channel.is_member and channel.enroll == 'public'" role="button"
class="col-10 btn btn-primary o_wslides_join_channel_link"
title="Start Course" aria-label="Start Course Channel"
t-att-href="'#'"
t-att-data-channel-id="channel.id">
<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>
<t t-if="not channel.is_member and channel.enroll == 'invite'">
<a role="button" class="col-10 btn btn-light" t-att-href="'#'">
<span class="cta-title text_small_caps">Private Course</span>
<div class="col-md-4 col-xs-12 o_wslides_course_content_aside">
<div class="bg-white">
<div class="row justify-content-center o_wslides_join_channel">
<a t-if="not channel.is_member and channel.enroll == 'public'" role="button"
class="col-10 mt8 btn btn-primary o_wslides_join_channel_link"
title="Start Course" aria-label="Start Course Channel"
t-att-href="'#'"
t-att-data-channel-id="channel.id">
<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="channel.enroll_msg" t-field="channel.enroll_msg"/>
<span t-if="not channel.enroll_msg">Contact website administrator.</span>
</t>
<span t-if="channel.is_member" class="col-10 btn btn-primary">
<i class="fa fa-chevron-right"></i>
<span class="cta-title text_small_caps">Already member</span>
</span>
</div>
<div class="row mt8">
<span class="col-5">Last Update</span>
<span class="col"><t t-esc="channel.slide_last_update" t-options="{'widget': 'date'}"/></span>
</div>
<div class="row mt8">
<span class="col-5">Members</span>
<span class="col" t-esc="channel.members_count"/>
</div>
<div class="row mt8"><div class="col"><hr/></div></div>
<t t-set="slide_type_keys" t-value="slide_types.keys()"/>
<t t-foreach="slide_type_keys" t-as="slide_type_key">
<div class="row mt8 align-items-center">
<span class="col-5">
<t t-if="search_category">
<a t-att-href="'/slides/%s/category/%s?%s' % (slug(channel), slug(search_category), keep_query('debug', slide_type=slide_type_key))"
t-att-class="'%s' % ('active' if search_slide_type == slide_type_key else '')">
<t t-esc="slide_types[slide_type_key]"/>
</a>
</t>
<t t-else="">
<a t-att-href="'/slides/%s?%s' % (slug(channel), keep_query('debug', slide_type=slide_type_key))"
t-att-class="'%s' % ('active' if search_slide_type == slide_type_key else '')">
<t t-esc="slide_types[slide_type_key]"/>
</a>
</t>
</span>
<span class="col">
<t t-if="search_category">
<span class="badge badge-pill badge-info" t-esc="search_category['nbr_%s' % slide_type_key]"/>
</t>
<t t-else="">
<span class="badge badge-pill badge-info" t-esc="channel['nbr_%s' % slide_type_key]"/>
</t>
<t t-if="not channel.is_member and channel.enroll == 'invite'">
<a role="button" class="col-10 mt8 btn btn-light" t-att-href="'#'">
<span class="cta-title text_small_caps">Private Course</span>
</a>
<div t-if="channel.enroll_msg" t-field="channel.enroll_msg"/>
<span t-if="not channel.enroll_msg">Contact website administrator.</span>
</t>
<span t-if="channel.is_member" class="col-10 mt8 btn btn-primary">
<i class="fa fa-chevron-right"></i>
<span class="cta-title text_small_caps">Already member</span>
</span>
</div>
</t>
<div class="row mt8"><div class="col"><hr/></div></div>
<div class="row justify-content-center mt8">
<button role="button" class="btn btn-primary col-10" title="Share Channel"
aria-label="Share Channel"
data-toggle="modal" data-target="#slideChannelShareModal">
<i class="fa fa-share-square"></i> Share
</button>
<div class="modal fade" id="slideChannelShareModal" tabindex="-1" role="dialog" aria-labelledby="slideChannelShareModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="slideChannelShareModalLabel">
Share
</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span>&amp;times;</span>
</button>
</div>
<div class="modal-body">
<h5>Share on Social Networks</h5>
<t t-call="website_slides.slides_share">
<t t-set="record" t-value="channel"/>
<div class="row mt8">
<span class="col-5">Last Update</span>
<span class="col"><t t-esc="channel.slide_last_update" t-options="{'widget': 'date'}"/></span>
</div>
<div class="row mt8">
<span class="col-5">Members</span>
<span class="col" t-esc="channel.members_count"/>
</div>
<div class="row mt8"><div class="col"><hr/></div></div>
<t t-if="channel.channel_type == 'documentation'">
<t t-set="slide_type_keys" t-value="slide_types.keys()"/>
<t t-foreach="slide_type_keys" t-as="slide_type_key">
<div class="row mt8 align-items-center">
<span class="col-5">
<t t-if="search_category">
<a t-att-href="'/slides/%s/category/%s?%s' % (slug(channel), slug(search_category), keep_query('debug', slide_type=slide_type_key))"
t-att-class="'%s' % ('active' if search_slide_type == slide_type_key else '')">
<t t-esc="slide_types[slide_type_key]"/>
</a>
</t>
<h5 class="mt16">Share Link</h5>
<input type="text" class="form-control" readonly="readonly" onclick="this.select();"
t-att-value="channel.website_url"/>
<t t-else="">
<a t-att-href="'/slides/%s?%s' % (slug(channel), keep_query('debug', slide_type=slide_type_key))"
t-att-class="'%s' % ('active' if search_slide_type == slide_type_key else '')">
<t t-esc="slide_types[slide_type_key]"/>
</a>
</t>
</span>
<span class="col">
<t t-if="search_category">
<span class="badge badge-pill badge-info" t-esc="search_category['nbr_%s' % slide_type_key]"/>
</t>
<t t-else="">
<span class="badge badge-pill badge-info" t-esc="channel['nbr_%s' % slide_type_key]"/>
</t>
</span>
</div>
</t>
</t>
<div class="row mt8"><div class="col"><hr/></div></div>
<div class="row justify-content-center mt8">
<button role="button" class="btn btn-primary col-10" title="Share Channel"
aria-label="Share Channel"
data-toggle="modal" data-target="#slideChannelShareModal">
<i class="fa fa-share-square"></i> Share
</button>
<div class="modal fade" id="slideChannelShareModal" tabindex="-1" role="dialog" aria-labelledby="slideChannelShareModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="slideChannelShareModalLabel">
Share
</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span>&amp;times;</span>
</button>
</div>
<div class="modal-body">
<h5>Share on Social Networks</h5>
<t t-call="website_slides.slides_share">
<t t-set="record" t-value="channel"/>
</t>
<h5 class="mt16">Share Link</h5>
<input type="text" class="form-control" readonly="readonly" onclick="this.select();"
t-att-value="channel.website_url"/>
</div>
</div>
</div>
</div>
</div>
</div>
<div t-if="channel.can_upload" class="row justify-content-center mt8 mb8">
<a role="button" class="btn btn-primary oe_slide_js_upload col-10" title="Upload Presentation"
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"></i> Upload
</a>
<div t-if="channel.can_upload" class="row justify-content-center mt8 mb8">
<a role="button" class="btn btn-primary oe_slide_js_upload col-10" title="Upload Presentation"
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"></i> Upload
</a>
</div>
</div>
</div>
<t t-if="channel.channel_type == 'training'" t-call="website_slides.course_content_training"/>
@@ -251,7 +254,6 @@
<div class="mr-2">Section <span class="section-index" t-esc="i"/>:</div>
<span t-field="category.name"/>
</div>
<!-- <a t-if="channel.user_id == user" title="Add content to this section" class="mr-2 p-0 oe_slide_js_add_slide" href="#" t-attf-channel_id="#{channel.id}" t-attf-category_id="#{category.id}">+</a> -->
<a class="mr-2 oe_slide_js_upload"
role="button"
aria-label="Upload Presentation"
@@ -291,7 +293,7 @@
</li>
</t>
</ul>
<div t-if="channel.user_id == user" class="content-actions">
<div t-if="channel.can_upload" class="content-actions">
<a class="mr-2 oe_slide_js_upload"
role="button"
aria-label="Upload Presentation"
@@ -299,7 +301,8 @@
t-att-data-channel-id="channel.id"
t-att-data-can-upload="channel.can_upload"
t-att-data-can-publish="channel.can_publish">Add Content</a>
<a class="oe_slide_js_add_section" t-attf-channel_id="#{channel.id}" href="#">Add Section</a>
<a class="oe_slide_js_add_section" t-attf-channel_id="#{channel.id}" href="#"
groups="website.group_website_publisher">Add Section</a>
</div>
</div>
<div t-field="channel.description_html"/>
@@ -307,10 +310,10 @@
</template>
<template id="course_content_documentation" name="Content of a training channel">
<div class="col-8 mt24 ml32 o_wslides_channel_content_promoted">
<div class="row mt16 align-items-center">
<div t-if="not search" class="col-md-8 col-xs-12 mt16 o_wslides_channel_content_promoted">
<div class="row align-items-center">
<div class="col">
<h3><i class="fa fa-plus-square"/> Featured lesson</h3>
<h3> Featured lesson</h3>
<hr/>
</div>
</div>
@@ -335,7 +338,14 @@
</div>
</div>
</div>
<div class="col-12">
<div t-if="search and not category_data" class="col-12">
<div class="row mt16 justify-content-end">
<div class="col-12">
<p class="text-center">No content was found using your search <span class="font-weight-bold" t-esc="search"/>.</p>
</div>
</div>
</div>
<div t-if="category_data" class="col-12">
<div class="tab-content mt16" id="slideChannelContent">
<div class="tab-pane active" role="tabpanel" aria-labelledby="profile-tab" id="slideChannelContentAbout">
<t t-foreach="category_data" t-as="category">
@@ -344,7 +354,7 @@
<a t-att-href="'/slides/%s/category/%s' % (slug(channel), category['id'])" class="float-right">
View all
</a>
<h3><i class="fa fa-plus-square"/> <t t-esc="category['name']"/></h3>
<h3><t t-esc="category['name']"/></h3>
<hr/>
</div>
</div>
@@ -376,11 +386,6 @@
</t>
</h5>
<h6 class="card-subtitle mb-2 text-muted">
<t t-if="user.has_group('website.group_website_publisher')">
<i class="fa fa-globe float-right o_wslides_slide_manage_publish"></i>
<i class="fa fa-pencil float-right o_wslides_slide_manage_edit"></i>
<i class="fa fa-trash float-right o_wslides_slide_manage_unlink"></i>
</t>
<t t-if="slide.is_preview">
<span class="badge badge-info">Free preview</span>
</t>
@@ -411,13 +416,9 @@
<span t-esc="slide.dislikes"/>
</span>
</div>
<small class="text-muted">
<t t-call="website_slides.slides_misc_float_time">
<t t-set="value" t-value="slide.completion_time"/>
</t>
<small class="text-muted" t-field="slide.completion_time" t-options='{"widget": "float_time"}'/>
<!-- <t t-esc="slide.total_views"/> Views
<timeago class="timeago" t-att-datetime="slide.create_date"></timeago> -->
</small>
</div>
</div>
</div>
@@ -4,35 +4,39 @@
<!-- Channels home template -->
<template id='courses_home' name="Odoo Courses Homepage">
<t t-call="website.layout">
<t t-call="website_slides.courses_header">
<t t-set="header_title" t-value="'Reach new heights'"/>
<t t-set="header_subtitle" t-value="'Start your online course today !'"/>
<t t-set="header_text" t-value="'Skill up and have an impact! Your business career starts here. Time to start a course.'"/>
<t t-set="header_cta_url" t-value="'slides'"/>
<t t-set="header_cta_title" t-value="'Pick a course'"/>
</t>
<div class="wrap">
<div class="container mt16 o_wslides_home_nav">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="wrap o_wslides_wrap">
<section class="s_banner bg-900" style="background-image: url(&quot;/website_slides/static/src/img/channel_banner_mountain.jpg&quot;); background-size: cover; background-position: 65% 55%">
<div class="container py-5">
<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-lg-4">
<p>Skill up and have an impact! Your business career starts here. Time to start a course.</p>
</div>
<div class="col-lg-3">
<a href="/slides/all" class="btn btn-primary btn-lg">Pick a course</a>
</div>
</div>
</div>
</section>
<div class="container mt16 o_wslides_home_nav position-relative">
<nav class="navbar navbar-expand-md navbar-light shadow-sm" style="background: white!important">
<button class="navbar-toggler" type="button"
data-toggle="collapse" data-target="#navbarSlidesHomepage"
aria-controls="navbarSlidesHomepage" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
<span class="navbar-toggler-icon"/>
</button>
<div class="collapse navbar-collapse" id="navbarSlidesHomepage">
<a class="navbar-brand" href="#"></a>
<ul class="navbar-nav mr-auto">
<li class="nav-item o_wslides_home_all_slides">
<h4><a class="nav-link" href="/slides/all"><i class="fa fa-rocket"/> All courses</a></h4>
</li>
<li class="nav-item ml16">
<h4><a class="nav-link" href="/slides/all"><i class="fa fa-file"/> My courses</a></h4>
</li>
</ul>
<div class="navbar-nav">
<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 class="navbar-nav o_wslides_nav_navbar_right">
<a class="nav-link nav-link" href="/slides/all"><i class="fa fa-file mr-1"/>My courses</a>
</div>
</div>
</nav>
</div>
<div class="container mt16 o_wslides_home_main">
<div class="container o_wslides_home_main">
<div class="row">
<div class="col-md-9">
<t t-if="channels_my">
@@ -41,7 +45,7 @@
<div class="row mt16 o_wslides_home_content_section_title align-items-center">
<div class="col">
<a href="slides/all" class="float-right">View all</a>
<h3><i class="fa fa-certificate"/> Complete latest courses</h3>
<h3><i class="fa fa-trophy"/> Complete latest courses</h3>
<hr/>
</div>
</div>
@@ -94,28 +98,40 @@
</div>
</div>
</div>
<section class="s_banner bg-900" style="background-image: url(&quot;/website/static/src/img/backgrounds/people.jpg&quot;); background-size: cover; background-position: 65% 55%">
<div class="container py-5">
<h1 class="display-3 mb-0">Meet the people who transformed their company</h1>
<h2 class="mb-4">Nobody gave me a real text so instead of a lorem ipsum I put that one.</h2>
<div class="row mt-1 mb-3">
<div class="col-lg-4">
<p>Nobody gave me a real text so instead of a lorem ipsum I put that one.</p>
</div>
<div class="col-lg-3">
<a href="/profile/users" class="btn btn-primary btn-lg">Go meet them</a>
</div>
</div>
</div>
</section>
</div>
<t t-call="website_slides.courses_footer">
<t t-set="footer_title" t-value="'Meet the people who transformed their company'"/>
<t t-set="footer_text" t-value="'Nobody gave me a real text so instead of a lorem ipsum I put that one.'"/>
<t t-set="footer_cta_url" t-value="'slides'"/>
<t t-set="footer_cta_title" t-value="'Go meet them'"/>
</t>
</t>
</template>
<!-- Channel all/main template -->
<template id='courses_all' name="Odoo All Courses">
<t t-call="website.layout">
<t t-call="website_slides.courses_header">
<t t-set="header_title" t-value="'All Courses'"/>
<t t-set="header_subtitle" t-value="'Start your online course today !'"/>
</t>
<div class="wrap">
<div class="container mt16 o_wslides_home_nav">
<div class="wrap o_wslides_wrap">
<section class="s_banner bg-900" style="background-image: url(&quot;/website_slides/static/src/img/channel_banner_mountain_all.jpg&quot;); background-size: cover; background-position: 65% 45%">
<div class="container py-5">
<h1 class="display-3 mb-0">All Courses</h1>
<h3 class="mb-4">Start your online course today !</h3>
</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-lg navbar-light bg-light">
<a class="navbar-brand" t-att-href="'/slides?%s' % keep_query('debug')"><i class="fa fa-chevron-left"/></a>
<nav class="navbar navbar-expand-md navbar-light shadow-sm" style="background: white!important">
<div class="navbar-nav border-right pr-3">
<a class="nav-link nav-item" t-att-href="'/slides?%s' % keep_query('debug')"><i class="fa fa-chevron-left"/></a>
</div>
<button class="navbar-toggler" type="button"
data-toggle="collapse" data-target="#navbarTagGroups"
aria-controls="navbarTagGroups" aria-expanded="false" aria-label="Toggle navigation">
@@ -123,15 +139,15 @@
</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 mr-auto">
<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 '')">
<h4><a class="nav-link dropdown-toggle"
<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"/></h4>
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 t-att-class="'dropdown-item %s' % ('active' if tag in search_tags else '')"
@@ -141,19 +157,21 @@
</div>
</li>
</t>
<!-- karma / profile -->
<li class="nav-item ml-auto" t-if="not is_public_user">
<a t-att-href="'/profile/user/%s' % user.id" class="nav-link mr-2">
<i class="fa fa-diamond"/> <t t-esc="user_id.karma"/>
</a>
</li>
</ul>
<!-- karma / profile -->
<a t-if="not is_public_user" t-att-href="'/profile/user/%s' % user.id" class="font-weight-bold mr-3">
<i class="fa fa-diamond"/> <t t-esc="user_id.karma"/>
</a>
<!-- search box -->
<form method="GET" class="form-inline justify-content-center">
<form method="GET" class="form-inline o_wslides_nav_navbar_right">
<div class="input-group">
<input type="search" name="search" class="form-control"
placeholder="Search something" aria-label="Search"
t-att-value="search_term"/>
<div class="input-group-append">
<button class="btn btn-outline-success oe_search_button" type="submit" aria-label="Search" title="Search">
<button class="btn border oe_search_button" type="submit" aria-label="Search" title="Search">
<i class="fa fa-search"/>
</button>
</div>
@@ -162,7 +180,7 @@
</div>
</nav>
</div>
<div class="container mt16 o_wslides_home_main">
<div class="container o_wslides_home_main">
<t t-if="search_term and not channels_layouted">
<div class="row">
<div class="col">
@@ -187,67 +205,29 @@
</div>
</t>
</div>
<section class="s_banner bg-900" style="background-image: url(&quot;/website/static/src/img/backgrounds/people.jpg&quot;); background-size: cover; background-position: 65% 55%">
<div class="container py-5">
<h1 class="display-3 mb-0">Meet the people who transformed their company</h1>
<h2 class="mb-4">Nobody gave me a real text so instead of a lorem ipsum I put that one.</h2>
<div class="row mt-1 mb-3">
<div class="col-lg-4">
<p>Nobody gave me a real text so instead of a lorem ipsum I put that one.</p>
</div>
<div class="col-lg-3">
<a href="/profile/users" class="btn btn-primary btn-lg">Go meet them</a>
</div>
</div>
</div>
</section>
</div>
<t t-call="website_slides.courses_footer">
<t t-set="footer_title" t-value="'Meet the people who transformed their company'"/>
<t t-set="footer_text" t-value="'Nobody gave me a real text so instead of a lorem ipsum I put that one.'"/>
<t t-set="footer_cta_url" t-value="'slides'"/>
<t t-set="footer_cta_title" t-value="'Go meet them'"/>
</t>
</t>
</template>
<template id="courses_header">
<section class="s_cover parallax bg-black-50 pt40 pb40 o_wslides_home_header" data-scroll-background-ratio="0" style="background-image: none;">
<span class="s_parallax_bg oe_img_bg oe_custom_bg" style="background-image: url(&quot;/website_slides/static/src/img/channel_banner_moutain.jpg&quot;); background-position: 52.1% 17.69%;"></span>
<div class="container">
<div class="row s_nb_column_fixed">
<div class="s_title pt0 col-lg-12" data-name="Title">
<h1 class="s_title_small_caps" style="font-size: 62px; text-align: left;"><t t-esc="header_title"/></h1>
<h4 t-if="header_subtitle" class="s_title_small_caps" style="font-size: 34px; text-align: left;"><t t-esc="header_subtitle"/></h4>
</div>
</div>
<div class="row s_nb_column_fixed">
<div t-if="header_text" class="col-lg-3 s_text pt16 pb16" data-name="Text">
<p class="lead" style="text-align: left;"><t t-esc="header_text"/></p>
</div>
<div t-if="header_cta_title" class="col-lg-3 s_btn text-center pt16 pb16" data-name="Buttons">
<a t-att-href="header_cta_url"
class="btn btn-primary o_default_snippet_text text_small_caps"><t t-esc="header_cta_title"/></a>
</div>
</div>
</div>
</section>
</template>
<template id="courses_footer">
<section class="s_cover parallax bg-black-50 pt40 pb40 o_wslides_home_footer mt16" data-scroll-background-ratio="0" style="background-image: none;">
<span class="s_parallax_bg oe_img_bg oe_custom_bg" style="background-image: url(&quot;/website/static/src/img/backgrounds/people.jpg&quot;); background-position: 50.11% 29.1%;"></span>
<div class="container">
<div class="row s_nb_column_fixed">
<div class="col-lg-12 s_title" data-name="Title">
<h1 class="s_title_small_caps" style="font-size: 40px; text-align: left;"><t t-esc="footer_title"/></h1>
<h4 t-if="footer_subtitle" class="s_title_small_caps" style="font-size: 26px; text-align: left;"><t t-esc="footer_subtitle"/></h4>
</div>
</div>
<div class="row s_nb_column_fixed">
<div t-if="footer_text" class="col-lg-3 s_text pt16 pb16" data-name="Text">
<p class="lead o_default_snippet_text" style="text-align: left;"><t t-esc="footer_text"/></p>
</div>
<div t-if="footer_cta_title" class="col-lg-3 s_btn text-center pt16 pb16" data-name="Buttons">
<a t-att-href="footer_cta_url"
class="btn btn-primary o_default_snippet_text text_small_caps"><t t-esc="footer_cta_title"/></a>
</div>
</div>
</div>
</section>
</template>
<template id='course_card' name="Course Card">
<div class="card o_wslides_course_card">
<img class="card-img-top img-fuild"
<img class="card-img-top img-fuild o_wslides_img_center_crop"
style="max-height: 160px;"
t-att-src="'/web/image/slide.channel/%s/image_large' % channel.id if channel.image else '/website_slides/static/src/img/channel-default.jpg'"
t-att-src="'/web/image/slide.channel/%s/image_large' % channel.id"
t-att-alt="channel.name"/>
<div class="card-body">
<h5 class="card-title" t-att-title="channel.name">
@@ -266,22 +246,24 @@
</div>
<div class="card-footer">
<div class="row justify-content-between align-items-center">
<small class="text-muted col-3">
<t t-call="website_slides.slides_misc_float_time">
<t t-set="value" t-value="channel.total_time"/>
</t>
</small>
<t t-if="channel.is_member">
<small class="text-muted col-3" t-field="channel.total_time" t-options='{"widget": "float_time"}'/>
<t t-if="channel.is_member and channel.completed">
<div class="col-5">
<span class="badge badge-pill badge-success pull-right"><i class="fa fa-check"/> Completed</span>
</div>
</t>
<t t-elif="channel.is_member">
<div class="col">
<div class="progress">
<div class="progress-bar" role="progressbar" t-att-aria-valuenow="channel.completion" aria-valuemin="0" aria-valuemax="100" t-attf-style="width:#{channel.completion}%;">
<!-- <span><t t-esc="channel.completion"/>%</span> -->
</div>
</div>
</div>
</t>
<t t-else="">
<small class="text-muted col-5"><span t-esc="channel.total_slides"/> steps</small>
<div class="col-5">
<small class="text-muted pull-right"><span t-esc="channel.total_slides"/> steps</small>
</div>
</t>
</div>
</div>
@@ -393,7 +375,7 @@
<t t-set="challenge_done" t-value="challenge in challenges_done if challenges_done else False"/>
<div class="row no-gutters mt8 align-items-center">
<div class="col-3">
<img t-att-class="'rounded-circle float-left %s' % 'image-muted' if not challenge_done else ''"
<img t-att-class="'rounded-circle float-left %s' % 'o_wslides_img_muted' if not challenge_done else ''"
style="max-height: 36px;"
t-att-src="'/web/image/gamification.badge/%s/image_medium' % challenge.reward_id.id"
t-att-alt="challenge.reward_id.name"/>
@@ -95,8 +95,8 @@
<div class="row">
<div style="width:100%;">
<div class="o_w_slides_slide_detail_container" style="width: 100%;">
<t t-if="slide.datas and slide.slide_type == 'infographic'">
<img t-attf-src="/web/image/slide.slide/#{slide.id}/datas" class="img-fluid" style="width:100%" alt="Slide image"/>
<t t-if="slide.slide_type == 'infographic'">
<img t-attf-src="/web/image/slide.slide/#{slide.id}/image" class="img-fluid" style="width:100%" alt="Slide image"/>
</t>
<div style="height: 600px;" t-if="slide.slide_type in ('presentation', 'document')" class="embed-responsive embed-responsive-4by3 embed-responsive-item mb8">
<t t-raw="slide.embed_code"/>
@@ -80,8 +80,8 @@
</div>
<canvas id="PDFViewerCanvas" class="img-fluid" style="margin: auto; height: 100%; display: none;"></canvas>
</t>
<t t-if="slide.slide_type in ('infographic')">
<img t-attf-src="/web/image/slide.slide/#{slide.id}/datas" class="img-fluid" style="width: 100%" alt="Slide image"/>
<t t-if="slide.slide_type == 'infographic'">
<img t-attf-src="/web/image/slide.slide/#{slide.id}/image" class="img-fluid" style="width: 100%" alt="Slide image"/>
</t>
</div>
<!-- Fixed bottom navbar -->
+1 -1
View File
@@ -2,7 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': 'Forum on course',
'name': 'Forum on Courses',
'category': 'Hidden',
'version': '1.0',
'summary': 'Allows to link forum on a course',
@@ -5,7 +5,7 @@
<xpath expr="//li[hasclass('o_wslides_nav_tabs_item_home')]" position="after">
<li class="nav-item" t-if="channel.forum_id">
<a t-att-href="'/forum/%s' % (slug(channel.forum_id))"
t-att-class="'nav-link o_wslides_navlink'" target="new">Forum</a>
t-att-class="'nav-link'" target="new">Forum</a>
</li>
</xpath>
</template>
@@ -17,5 +17,4 @@
</xpath>
</template>
</data></odoo>
+2 -2
View File
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': "Course certifications",
'name': "Course Certifications",
'summary': 'Add certification capabilities to your courses',
'description': """This module lets you use the full power of certifications within your courses.""",
'category': 'Hidden',
'version': '0.1',
'version': '1.0',
'depends': ['website_slides', 'website_survey'],
'installable': True,
'auto_install': True,
@@ -4,6 +4,7 @@
<field name="name">Furniture Creation Certification</field>
<field name="slide_type">certification</field>
<field name="channel_id" ref="website_slides.slide_channel_demo_5_furn2"/>
<field name="category_id" ref="website_slides.slide_category_demo_5_0"/>
<field name="survey_id" ref="website_slides_survey.furniture_certification"/>
<field name="website_published" eval="True"/>
<field name="is_preview" eval="False"/>
@@ -1,10 +1,7 @@
.o_wslides_fullscreen_certification {
background-color: #f6f6f6;
display: flex;
justify-content: center;
align-items: center;
width: 400px;
height: 300px;
position: absolute;
top: 50%;
left: 50%;
@@ -3,7 +3,7 @@
<t t-extend="website.slides.fullscreen">
<t t-jquery=".o_wslides_fullscreen_content" t-operation="append">
<div class="o_wslides_fullscreen_certification" t-if="slide.slide_type == 'certification'">
<a t-att-href="'/slides/slide/' + slide.slug" target="new">Pass Certification</a>
<a class="btn btn-primary" t-att-href="'/slides/slide/' + slide.slug" target="new"><i class="fa fa-trophy"/> Pass Certification</a>
</div>
</t>
</t>
@@ -2,10 +2,8 @@
<odoo>
<data>
<template id="courses_home_inherit_survey" inherit_id="website_slides.courses_home">
<xpath expr="//li[hasclass('o_wslides_home_all_slides')]" position="after">
<li class="nav-item ml16">
<h4><a class="nav-link" href="/slides/all?slide_type=certification"><i class="fa fa-trophy"/> Certifications</a></h4>
</li>
<xpath expr="//a[hasclass('o_wslides_home_all_slides')]" position="after">
<a class="nav-link nav-link" href="/slides/all?slide_type=certification"><i class="fa fa-trophy mr-1"/>Certifications</a>
</xpath>
</template>
</data>