[IMP] website_slides: new homepage and main channel page
This commit proposes a new homepage for slides module evolving towards
an eLearning platform. It includes
* a new main page displaying top courses / channels. It displays 3 most
popular and newest channels as well as its ongoing courses (if logged).
Achievements and karma update done by eLearning community allow to give
a gamification look and feel;
* an 'All' page displaying all courses / channels. Tag groups and tags
allow to search / filter displayed courses;
* a new pimped and revamped display for main course / channel page;
For more details about specifications, send an email to aware people that
will be able to send you mockups. Or see the related task. Thanks to
@qmo-odoo who helped developing this homepage based on its work.
This commit is linked to task ID 1936153 and PR #30770.
Co-Authored-By: qmo-odoo <qmo@odoo.com>
Co-Authored-By: Thibault Delavallee <tde@odoo.com>
This commit is contained in:
co-authored by
qmo-odoo
parent
c437832e55
commit
2cfacfc632
@@ -25,6 +25,7 @@ Share and Publish Videos, Presentations and Documents'
|
||||
'data': [
|
||||
'views/assets.xml',
|
||||
'views/res_config_settings_views.xml',
|
||||
'views/website_slides_templates_homepage.xml',
|
||||
'views/website_slides_templates.xml',
|
||||
'views/website_slides_embed_templates.xml',
|
||||
'views/slide_slide_views.xml',
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import base64
|
||||
import itertools
|
||||
import logging
|
||||
import werkzeug
|
||||
|
||||
@@ -21,10 +22,10 @@ _logger = logging.getLogger(__name__)
|
||||
class WebsiteSlides(WebsiteProfile):
|
||||
_slides_per_page = 12
|
||||
_slides_per_list = 20
|
||||
_order_by_criterion = {
|
||||
'date': 'date_published desc',
|
||||
_channel_order_by_criterion = {
|
||||
'vote': 'total_votes desc',
|
||||
'view': 'total_views desc',
|
||||
'vote': 'likes desc',
|
||||
'date': 'create_date desc',
|
||||
}
|
||||
|
||||
def sitemap_slide(env, rule, qs):
|
||||
@@ -47,13 +48,6 @@ class WebsiteSlides(WebsiteProfile):
|
||||
slide.action_set_viewed()
|
||||
return True
|
||||
|
||||
def _prepare_user_values(self, **kwargs):
|
||||
values = super(WebsiteSlides, self)._prepare_user_values(**kwargs)
|
||||
channel = self._get_channels(**kwargs)
|
||||
if channel:
|
||||
values['channel'] = channel
|
||||
return values
|
||||
|
||||
def _get_slide_detail(self, slide):
|
||||
most_viewed_slides = slide.get_most_viewed_slides(self._slides_per_list)
|
||||
related_slides = slide.get_related_slides(self._slides_per_list)
|
||||
@@ -66,57 +60,144 @@ class WebsiteSlides(WebsiteProfile):
|
||||
'comments': slide.website_message_ids or [],
|
||||
}
|
||||
|
||||
def _extract_channel_tag_search(self, **post):
|
||||
tags = request.env['slide.channel.tag']
|
||||
for key in (_key for _key in post if _key.startswith('channel_tag_group_id_')):
|
||||
group_id, tag_id = False, False
|
||||
try:
|
||||
group_id = int(key.lstrip('channel_tag_group_id_'))
|
||||
tag_id = int(post[key])
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
search_tag = request.env['slide.channel.tag'].search([('id', '=', tag_id), ('group_id', '=', group_id)]).exists()
|
||||
if search_tag:
|
||||
tags |= search_tag
|
||||
return tags
|
||||
|
||||
def _build_channel_domain(self, base_domain, **post):
|
||||
search_term = post.get('search')
|
||||
category_id = post.get('category_id')
|
||||
channel_tag_id = post.get('channel_tag_id')
|
||||
tags = self._extract_channel_tag_search(**post)
|
||||
|
||||
domain = base_domain
|
||||
if search_term:
|
||||
domain = expression.AND([
|
||||
domain,
|
||||
['|', ('name', 'ilike', search_term), ('description', 'ilike', search_term)]])
|
||||
if category_id:
|
||||
domain = expression.AND([domain, [('category_ids', 'in', [category_id])]])
|
||||
elif channel_tag_id:
|
||||
domain = expression.AND([domain, [('tag_ids', 'in', [channel_tag_id])]])
|
||||
elif tags:
|
||||
domain = expression.AND([domain, [('tag_ids', 'in', tags.ids)]])
|
||||
return domain
|
||||
|
||||
# --------------------------------------------------
|
||||
# MAIN / SEARCH
|
||||
# --------------------------------------------------
|
||||
|
||||
@http.route('/slides', type='http', auth="public", website=True)
|
||||
def slides_index(self, *args, **post):
|
||||
""" Returns a list of available channels: if only one is available,
|
||||
redirects directly to its slides
|
||||
"""
|
||||
def slides_channel_home(self, **post):
|
||||
""" Home page for eLearning platform. Is mainly a container page, does not allow search / filter. """
|
||||
domain = request.website.website_domain()
|
||||
# search bar
|
||||
search_term = post.get('search')
|
||||
if search_term:
|
||||
domain = expression.AND([domain, ['|', ('name', 'ilike', search_term), ('description', 'ilike', search_term)]])
|
||||
channels_all = request.env['slide.channel'].search(domain)
|
||||
if not request.env.user._is_public():
|
||||
channels_my = channels_all.filtered(lambda channel: channel.completion > 0).sorted('completion', reverse=True)[:3]
|
||||
else:
|
||||
channels_my = request.env['slide.channel']
|
||||
channels_popular = channels_all.sorted('total_votes', reverse=True)[:3]
|
||||
channels_newest = channels_all.sorted('create_date', reverse=True)[:3]
|
||||
|
||||
channels = request.env['slide.channel'].search(domain, order='sequence, id')
|
||||
if not channels:
|
||||
return request.render("website_slides.channel_not_found", {'search_term': search_term})
|
||||
elif len(channels) == 1 and not search_term: # don't auto redirect to only result when searching
|
||||
return request.redirect("/slides/%s" % channels.id)
|
||||
return request.render('website_slides.channels', {
|
||||
'channels': channels,
|
||||
# fetch 'latests achievements' for non logged people
|
||||
if request.env.user._is_public():
|
||||
achievements = request.env['gamification.badge.user'].sudo().search([], limit=5)
|
||||
challenges = None
|
||||
challenges_done = None
|
||||
else:
|
||||
achievements = None
|
||||
challenges = request.env['gamification.challenge'].sudo().search([('category', '=', 'slides')], order='id asc', limit=5)
|
||||
challenges_done = request.env['gamification.badge.user'].sudo().search([
|
||||
('challenge_id', 'in', challenges.ids),
|
||||
('user_id', '=', request.env.user.id)
|
||||
]).mapped('challenge_id')
|
||||
|
||||
# fetch 'heroes of the week' for non logged people
|
||||
if request.env.user._is_public():
|
||||
users = request.env['res.users'].sudo().search([
|
||||
('karma', '>', 0),
|
||||
('website_published', '=', True)], limit=5, order='create_date desc')
|
||||
else:
|
||||
users = None
|
||||
|
||||
return request.render('website_slides.courses_home', {
|
||||
'user': request.env.user,
|
||||
'is_public_user': request.website.is_public_user(),
|
||||
'search_term': search_term,
|
||||
'channels_my': channels_my,
|
||||
'channels_popular': channels_popular,
|
||||
'channels_newest': channels_newest,
|
||||
'achievements': achievements,
|
||||
'users': users,
|
||||
'challenges': challenges,
|
||||
'challenges_done': challenges_done,
|
||||
})
|
||||
|
||||
@http.route('/slides/all', type='http', auth="public", website=True)
|
||||
def slides_channel_all(self, **post):
|
||||
""" Home page displaying a list of courses displayed according to some
|
||||
criterion and search terms.
|
||||
|
||||
: param dict post: post parameters, including
|
||||
* search_term: keywords entered in the search box, used to filter on slide content;
|
||||
* category_id: id of a slide.category;
|
||||
* channel_tag_id: id of a channel.tag;
|
||||
"""
|
||||
domain = request.website.website_domain()
|
||||
domain = self._build_channel_domain(domain, **post)
|
||||
|
||||
order = self._channel_order_by_criterion.get(post.get('sorting', 'date'), 'create_date desc')
|
||||
|
||||
channels = request.env['slide.channel'].search(domain, order=order)
|
||||
channels_layouted = list(itertools.zip_longest(*[iter(channels)] * 4, fillvalue=None))
|
||||
|
||||
tag_groups = request.env['slide.channel.tag.group'].search(['&', ('tag_ids', '!=', False), ('website_published', '=', True)])
|
||||
search_tags = self._extract_channel_tag_search(**post)
|
||||
|
||||
return request.render('website_slides.courses_all', {
|
||||
'user': request.env.user,
|
||||
'is_public_user': request.website.is_public_user(),
|
||||
'channels_layouted': channels_layouted,
|
||||
'tag_groups': tag_groups,
|
||||
'search_term': post.get('search'),
|
||||
'search_tags': search_tags,
|
||||
})
|
||||
|
||||
def _prepare_additional_channel_values(self, values, **kwargs):
|
||||
return values
|
||||
|
||||
@http.route([
|
||||
'''/slides/<model("slide.channel"):channel>''',
|
||||
'''/slides/<model("slide.channel"):channel>/page/<int:page>''',
|
||||
|
||||
'''/slides/<model("slide.channel"):channel>/<string:slide_type>''',
|
||||
'''/slides/<model("slide.channel"):channel>/<string:slide_type>/page/<int:page>''',
|
||||
|
||||
'''/slides/<model("slide.channel"):channel>/tag/<model("slide.tag"):tag>''',
|
||||
'''/slides/<model("slide.channel"):channel>/tag/<model("slide.tag"):tag>/page/<int:page>''',
|
||||
'''/slides/<model("slide.channel"):channel>/category/<model("slide.category"):category>''',
|
||||
'''/slides/<model("slide.channel"):channel>/category/<model("slide.category"):category>/page/<int:page>''',
|
||||
|
||||
'''/slides/<model("slide.channel"):channel>/category/<model("slide.category"):category>/<string:slide_type>''',
|
||||
'''/slides/<model("slide.channel"):channel>/category/<model("slide.category"):category>/<string:slide_type>/page/<int:page>'''],
|
||||
type='http', auth="public", website=True, sitemap=sitemap_slide)
|
||||
def channel(self, channel, category=None, tag=None, page=1, slide_type=None, sorting='creation', search=None, **kw):
|
||||
'/slides/<model("slide.channel"):channel>',
|
||||
'/slides/<model("slide.channel"):channel>/page/<int:page>',
|
||||
'/slides/<model("slide.channel"):channel>/tag/<model("slide.tag"):tag>',
|
||||
'/slides/<model("slide.channel"):channel>/tag/<model("slide.tag"):tag>/page/<int:page>',
|
||||
'/slides/<model("slide.channel"):channel>/category/<model("slide.category"):category>',
|
||||
'/slides/<model("slide.channel"):channel>/category/<model("slide.category"):category>/page/<int:page>'
|
||||
], type='http', auth="public", website=True, sitemap=sitemap_slide)
|
||||
def channel(self, channel, category=None, tag=None, page=1, slide_type=None, sorting=None, search=None, **kw):
|
||||
if not channel.can_access_from_current_website():
|
||||
raise werkzeug.exceptions.NotFound()
|
||||
|
||||
user = request.env.user
|
||||
Slide = request.env['slide.slide']
|
||||
domain = [('channel_id', '=', channel.id)]
|
||||
if not request.env.user.has_group('website.group_website_publisher'):
|
||||
domain = expression.AND([
|
||||
domain,
|
||||
['&', ('website_published', '=', True), ('channel_id.website_published', '=', True)]
|
||||
])
|
||||
|
||||
pager_url = "/slides/%s" % (channel.id)
|
||||
pager_args = {}
|
||||
slide_types = dict(request.env['slide.slide']._fields['slide_type']._description_selection(request.env))
|
||||
|
||||
if search:
|
||||
domain += [
|
||||
@@ -135,35 +216,42 @@ class WebsiteSlides(WebsiteProfile):
|
||||
pager_url += "/tag/%s" % tag.id
|
||||
if slide_type:
|
||||
domain += [('slide_type', '=', slide_type)]
|
||||
pager_url += "/%s" % slide_type
|
||||
pager_url += "?slide_type=%s" % slide_type
|
||||
|
||||
if not sorting or sorting not in self._order_by_criterion:
|
||||
sorting = 'date'
|
||||
order = self._order_by_criterion[sorting]
|
||||
pager_args['sorting'] = sorting
|
||||
# sorting criterion
|
||||
actual_sorting = sorting if sorting and sorting in request.env['slide.slide']._order_by_strategy else channel.promote_strategy
|
||||
order = request.env['slide.slide']._order_by_strategy[actual_sorting]
|
||||
pager_args['sorting'] = actual_sorting
|
||||
|
||||
pager_count = Slide.search_count(domain)
|
||||
pager_count = request.env['slide.slide'].sudo().search_count(domain)
|
||||
pager = request.website.pager(url=pager_url, total=pager_count, page=page,
|
||||
step=self._slides_per_page, scope=self._slides_per_page,
|
||||
url_args=pager_args)
|
||||
|
||||
slides = Slide.search(domain, limit=self._slides_per_page, offset=pager['offset'], order=order)
|
||||
values = {
|
||||
'channel': channel,
|
||||
'category': category,
|
||||
'slides': slides,
|
||||
'tag': tag,
|
||||
'slide_type': slide_type,
|
||||
'sorting': sorting,
|
||||
# search
|
||||
'search_category': category,
|
||||
'search_tag': tag,
|
||||
'search_slide_type': slide_type,
|
||||
'slide_types': slide_types,
|
||||
'sorting': actual_sorting,
|
||||
'search': search,
|
||||
'user': user,
|
||||
'pager': pager,
|
||||
'is_public_user': request.website.is_public_user(),
|
||||
# chatter
|
||||
'rating_avg': channel.rating_avg,
|
||||
'rating_count': channel.rating_count,
|
||||
# display data
|
||||
'user': request.env.user,
|
||||
'pager': pager,
|
||||
'is_public_user': request.website.is_public_user(),
|
||||
}
|
||||
if not request.env.user._is_public():
|
||||
last_message_values = request.env['mail.message'].search([('model', '=', channel._name), ('res_id', '=', channel.id), ('author_id', '=', user.partner_id.id), ('website_published', '=', True)], order='write_date DESC', limit=1).read(['body', 'rating_value'])
|
||||
last_message_values = request.env['mail.message'].search([
|
||||
('model', '=', channel._name),
|
||||
('res_id', '=', channel.id),
|
||||
('author_id', '=', request.env.user.partner_id.id),
|
||||
('website_published', '=', True)
|
||||
], order='write_date DESC', limit=1).read(['body', 'rating_value'])
|
||||
last_message_data = last_message_values[0] if last_message_values else {}
|
||||
values.update({
|
||||
'message_post_hash': channel._sign_token(request.env.user.partner_id.id),
|
||||
@@ -174,21 +262,32 @@ class WebsiteSlides(WebsiteProfile):
|
||||
})
|
||||
|
||||
# Display uncategorized slides
|
||||
if not slide_type and not category:
|
||||
category_datas = []
|
||||
for category in Slide.read_group(domain, ['category_id'], ['category_id']):
|
||||
# fetch slides; done as sudo because we want to display all of them but
|
||||
# unreachable ones won't be clickable (+ slide controller will crash anyway)
|
||||
if not category:
|
||||
category_data = []
|
||||
for category in request.env['slide.slide'].sudo().read_group(domain, ['category_id'], ['category_id']):
|
||||
category_id, name = category.get('category_id') or (False, _('Uncategorized'))
|
||||
category_datas.append({
|
||||
category_data.append({
|
||||
'id': category_id,
|
||||
'name': name,
|
||||
'total_slides': category['category_id_count'],
|
||||
'slides': Slide.search(category['__domain'], limit=4, offset=0, order=order)
|
||||
'slides': request.env['slide.slide'].sudo().search(category['__domain'], limit=4, offset=0, order=order)
|
||||
})
|
||||
values.update({
|
||||
'category_datas': category_datas,
|
||||
})
|
||||
else:
|
||||
slides_sudo = request.env['slide.slide'].sudo().search(domain, limit=self._slides_per_page, offset=pager['offset'], order=order)
|
||||
category_data = [{
|
||||
'id': category.id,
|
||||
'name': category.name,
|
||||
'total_slides': len(slides_sudo),
|
||||
'slides': slides_sudo,
|
||||
}]
|
||||
values['slide_promoted'] = request.env['slide.slide'].sudo().search(domain, limit=1, order=order)
|
||||
values['category_data'] = category_data
|
||||
|
||||
return request.render('website_slides.home', values)
|
||||
values = self._prepare_additional_channel_values(values, **kw)
|
||||
|
||||
return request.render('website_slides.course_main', values)
|
||||
|
||||
@http.route(['/slides/channel/add'], type='http', auth='user', methods=['POST'], website=True)
|
||||
def slide_channel_create(self, *args, **kw):
|
||||
@@ -411,8 +510,17 @@ class WebsiteSlides(WebsiteProfile):
|
||||
# if the slide can be embedded, and properly display the error message.
|
||||
return request.render('website_slides.embed_slide_forbidden', {})
|
||||
|
||||
# Profile
|
||||
# ---------------------------------------------------
|
||||
# --------------------------------------------------
|
||||
# PROFILE
|
||||
# --------------------------------------------------
|
||||
|
||||
def _prepare_user_values(self, **kwargs):
|
||||
values = super(WebsiteSlides, self)._prepare_user_values(**kwargs)
|
||||
channel = self._get_channels(**kwargs)
|
||||
if channel:
|
||||
values['channel'] = channel
|
||||
return values
|
||||
|
||||
def _get_channels(self, **kwargs):
|
||||
channels = []
|
||||
if kwargs.get('channel'):
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 135 KiB |
@@ -15,6 +15,266 @@ $MAX-Z-INDEX : 2147483647 !default;
|
||||
object-position: top;
|
||||
}
|
||||
|
||||
|
||||
// Common to new slides pages
|
||||
// **************************************************
|
||||
|
||||
.o_wslides_wrap {
|
||||
.text_small_caps {
|
||||
font-variant: small-caps;
|
||||
}
|
||||
.image-muted {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.cta-title {
|
||||
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;
|
||||
}
|
||||
}
|
||||
// responsive card-deck like
|
||||
.row.o_wslides_row > div[class*='col-'] {
|
||||
display: flex;
|
||||
flex:1 0 auto;
|
||||
.card {
|
||||
width:100%;
|
||||
}
|
||||
}
|
||||
|
||||
// tools
|
||||
// ****************************************
|
||||
.text_small_caps {
|
||||
font-variant: small-caps;
|
||||
}
|
||||
|
||||
.image-muted {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.o_wslides_home_circled {
|
||||
border-radius: 50%;
|
||||
width: 1.2em;
|
||||
height: 1.2em;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
border: 0.2em solid #666;
|
||||
text-align: center;
|
||||
box-sizing: initial;
|
||||
}
|
||||
|
||||
.progress {
|
||||
overflow: visible;
|
||||
margin-bottom: 0em;
|
||||
height: 4px;
|
||||
.progress-bar {
|
||||
background-color: #00A09D;
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
span {
|
||||
background-color: #00A09D;
|
||||
position: absolute;
|
||||
bottom: -20px;
|
||||
font-size: 10px;
|
||||
line-height: 10px;
|
||||
padding: 2px 3px 2px 4px;
|
||||
right: -1.4em;
|
||||
border-radius: 2px;
|
||||
}
|
||||
span:after {
|
||||
bottom: 100%;
|
||||
left: 50%;
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border-color: rgba(255, 255, 255, 0);
|
||||
border-bottom-color: #00A09D;
|
||||
border-width: 5px;
|
||||
margin-left: -5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// New course page
|
||||
// **************************************************
|
||||
|
||||
.o_wslides_container {
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
max-width: 1140px;
|
||||
padding: 32px 32px 0px 32px;
|
||||
}
|
||||
|
||||
.o_wslides_course_nav {
|
||||
margin: auto;
|
||||
background: linear-gradient(150deg, #875A7B 20%, #62495B 80%) !important;
|
||||
opacity: 0.95;
|
||||
|
||||
nav {
|
||||
.breadcrumb-item::before {
|
||||
font-weight: bold;
|
||||
color: #FFFFFF;
|
||||
opacity: 0.8;
|
||||
}
|
||||
.breadcrumb-item {
|
||||
a {
|
||||
font-weight: bold;
|
||||
color: #FFFFFF;
|
||||
opacity: 0.8;
|
||||
transition: opacity linear .3s;
|
||||
}
|
||||
&.active {
|
||||
a {
|
||||
opacity: 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
ol {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.o_wslides_course_header {
|
||||
margin: auto;
|
||||
background: linear-gradient(150deg, #875A7B 20%, #62495B 80%) !important;
|
||||
border-bottom: 48px solid #66445e;
|
||||
|
||||
.o_wslides_course_header_container {
|
||||
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 {
|
||||
img {
|
||||
width: 100%;
|
||||
max-width: 256px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.o_wslides_course_content {
|
||||
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;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
.o_wslides_course_content_aside {
|
||||
top: 1px;
|
||||
width: 256px;
|
||||
max-width: 256px;
|
||||
margin-left: 15px;
|
||||
background-color: white;
|
||||
|
||||
.o_wslides_course_aside_line {
|
||||
}
|
||||
}
|
||||
|
||||
.o_wslides_lesson_card {
|
||||
.card-footer {
|
||||
padding-top: 0.75em;
|
||||
padding-bottom: 0.75em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Old brol to clean someday
|
||||
// **************************************************
|
||||
|
||||
.oe_slides_panel_footer .fa, .oe_slide_js_embed_option_link{
|
||||
color : theme-color('primary');
|
||||
cursor: pointer;
|
||||
@@ -61,10 +321,6 @@ img.oe_slides_promote_image {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.oe_slides_box_shadow {
|
||||
box-shadow: 0 0 5px #CCC;
|
||||
}
|
||||
|
||||
.oe_slides_apart_small {
|
||||
@include top-covered-image;
|
||||
height: 60px;
|
||||
|
||||
@@ -5,85 +5,12 @@
|
||||
<!-- Tools template: share on social networkds -->
|
||||
<template id='slides_share' name="Slides Media Share">
|
||||
<div>
|
||||
<a t-attf-href="https://www.facebook.com/sharer/sharer.php?u=#{slide.website_url}" class="o_slides_social_share" social-key="facebook" aria-label="Share on Facebook" title="Share on Facebook"><i class="fa fa-facebook-square fa-2x"/></a>
|
||||
<a t-attf-href="https://twitter.com/intent/tweet?text=#{slide.name}&url=#{slide.website_url}" class="o_slides_social_share" social-key="twitter" aria-label="Share on Twitter" title="Share on Twitter"><i class="fa fa-twitter fa-2x"/></a>
|
||||
<a t-attf-href="http://www.linkedin.com/shareArticle?mini=true&url=#{slide.website_url}&title=#{slide.name}&" social-key="linkedin" class="o_slides_social_share" aria-label="Share on LinkedIn" title="Share on LinkedIn"><i class="fa fa-linkedin fa-2x"/></a>
|
||||
<a t-attf-href="https://plus.google.com/share?url=#{slide.website_url}" class="o_slides_social_share" social-key="gplus" aria-label="Share on Google Plus" title="Share on Google Plus"><i class="fa fa-google-plus-square fa-2x"/></a>
|
||||
<a t-attf-href="https://www.facebook.com/sharer/sharer.php?u=#{record.website_url}" class="o_slides_social_share" social-key="facebook" aria-label="Share on Facebook" title="Share on Facebook"><i class="fa fa-facebook-square fa-2x"/></a>
|
||||
<a t-attf-href="https://twitter.com/intent/tweet?text=#{record.name}&url=#{record.website_url}" class="o_slides_social_share" social-key="twitter" aria-label="Share on Twitter" title="Share on Twitter"><i class="fa fa-twitter fa-2x"/></a>
|
||||
<a t-attf-href="http://www.linkedin.com/shareArticle?mini=true&url=#{record.website_url}&title=#{record.name}&" social-key="linkedin" class="o_slides_social_share" aria-label="Share on LinkedIn" title="Share on LinkedIn"><i class="fa fa-linkedin fa-2x"/></a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Channels View: main template, display list of available channels -->
|
||||
<template id="channels" name="Channels">
|
||||
<t t-call="website.layout">
|
||||
<div class="container mt16">
|
||||
<div class="d-flex justify-content-between mb-4">
|
||||
<h1 t-if="not search_term">Select a Channel</h1>
|
||||
<h1 t-if="search_term">Channel found for "<i><t t-esc="search_term"/></i>"</h1>
|
||||
<div class="form-inline justify-content-center">
|
||||
<form method="GET" class="o_website_slides_search">
|
||||
<div class="input-group">
|
||||
<input type="text" name="search" class="search-query form-control oe_search_box" placeholder="Search..." t-att-value="search_term"/>
|
||||
<div class="input-group-append">
|
||||
<button type="submit" class="btn btn-primary oe_search_button" aria-label="Search" title="Search">
|
||||
<i class="fa fa-search"/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<t t-foreach="channels" t-as="channel">
|
||||
<div t-if="channel_index % 3 == 0" class="clearfix"/>
|
||||
<div class="col-md-4 mb32">
|
||||
<div class="card card-body">
|
||||
<div>
|
||||
<a t-attf-href="/slides/#{slug(channel)}">
|
||||
<img t-if="channel.image" t-attf-src="/web/image/slide.channel/#{channel.id}/image_medium"
|
||||
class="img-fluid oe_slides_channel_thumbnail"
|
||||
t-att-alt="channel.name"/>
|
||||
<img t-if="not channel.image" src="/website_slides/static/src/img/channel-default.jpg"
|
||||
class="img-fluid oe_slides_opacity"
|
||||
t-att-alt="channel.name"/>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<div class="mt4 float-right">
|
||||
<t t-call="website.publish_management">
|
||||
<t t-set="object" t-value="channel"/>
|
||||
<t t-set="publish_edit" t-value="True"/>
|
||||
<t t-set="action" t-value="'website_slides.action_slide_channels'"/>
|
||||
</t>
|
||||
</div>
|
||||
<h3 class="mt4 mb4 lead" t-att-title="channel.name" style="width:55%">
|
||||
<a t-attf-href="/slides/#{slug(channel)}" t-esc="channel.name"/>
|
||||
</h3>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-muted oe_no_empty" t-field="channel.description"/>
|
||||
</div>
|
||||
<t t-call="website_rating.rating_widget_stars_static">
|
||||
<t t-set="rating_avg" t-value="channel.rating_avg"/>
|
||||
<t t-set="rating_count" t-value="channel.rating_count"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Channels View: option: subscription -->
|
||||
<template id="opt_subscription_on_channels" name="Subscription" customize_show="True" inherit_id="website_slides.channels">
|
||||
<xpath expr="//p[@t-field='channel.description']" position="after">
|
||||
<t t-call="website_mail.follow">
|
||||
<t t-set="email" t-value="user.email"/>
|
||||
<t t-set="object" t-value="channel"/>
|
||||
</t>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Channels: no channel found -->
|
||||
<template id="channel_not_found" name="Private Presentation">
|
||||
<t t-call="website.layout">
|
||||
@@ -101,52 +28,40 @@
|
||||
</template>
|
||||
|
||||
<!-- Channels sub-template: header -->
|
||||
<template id="slides_channel_header" name="Slides Channel Header">
|
||||
<section class="oe_slides_box_shadow">
|
||||
<template id="course_nav" name="Course Navigation Header">
|
||||
<div class="o_wslides_course_nav">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<!-- Name and breadcrumb -->
|
||||
<div class="float-left col-lg-8 col-md-12 col-12 mt16 mb8">
|
||||
<div class="row">
|
||||
<h3 class="mt0">
|
||||
<a t-attf-href="/slides/#{slug(channel)}" t-esc="channel.name"/>
|
||||
<span t-if="not channel.is_member" class="o_wslides_join_channel">
|
||||
<a role="button" class="btn btn-primary o_wslides_join_channel_link"
|
||||
title="Join Channel" aria-label="Join Channel" href="#"
|
||||
t-att-data-channel-id="channel.id">
|
||||
<i class="fa fa-chevron-right"></i> Join
|
||||
</a>
|
||||
</span>
|
||||
<span t-if="channel.is_member">
|
||||
<a role="button" class="btn btn-primary o_wslides_join_channel_link"
|
||||
title="Join Channel" aria-label="Join Channel" href="#">
|
||||
<i class="fa fa-chevron-right"></i> Joined
|
||||
</a>
|
||||
</span>
|
||||
<t t-if="category">
|
||||
/ <a t-attf-href="/slides/#{slug(channel)}/category/#{slug(category)}" t-esc="category.name"/>
|
||||
</t>
|
||||
<t t-if="channel.can_upload">
|
||||
<a role="button" class="btn btn-primary oe_slide_js_upload" 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>
|
||||
</t>
|
||||
</h3>
|
||||
<ul class="navbar-nav ml-auto float-right pt-2">
|
||||
<li class="nav-item">
|
||||
<a t-attf-href="/profile/user/#{user.id}?channel_id=#{channel.id}" t-attf-class="text-dark font-weight-bold nav-link}">
|
||||
<i class="fa fa-diamond text-secondary" /> <t t-esc="user_id.karma"/>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Search box -->
|
||||
<div class="col-lg-4 col-md-12 col-12 pul-right mt16 mb8">
|
||||
<div class="row align-items-center justify-content-between">
|
||||
<!-- nav -->
|
||||
<nav aria-label="breadcrumb" class="col-6">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="/slides">Home</a>
|
||||
</li>
|
||||
<li t-att-class="'breadcrumb-item %s' % ('active' if not search_category and not search_tag and not search_slide_type else '')">
|
||||
<a t-att-href="'/slides/%s' % slug(channel)"><span t-esc="channel.name"/></a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active" 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 class="breadcrumb-item active" 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 class="breadcrumb-item active" 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>
|
||||
</ol>
|
||||
</nav>
|
||||
<div class="col-4 d-flex flex-row">
|
||||
<!-- karma -->
|
||||
<!-- <ul class="navbar-nav ml-auto float-right pt-2">
|
||||
<li class="nav-item">
|
||||
<a t-attf-href="/profile/user/#{user.id}?channel_id=#{channel.id}" t-attf-class="text-dark font-weight-bold nav-link}">
|
||||
<i class="fa fa-diamond text-secondary" /> <t t-esc="user_id.karma"/>
|
||||
</a>
|
||||
</li>
|
||||
</ul> -->
|
||||
<!-- search -->
|
||||
<form t-attf-action="/slides/#{slug(channel)}" role="search" method="get">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="search" t-attf-placeholder="Search in #{channel.name}" t-att-value="search"/>
|
||||
@@ -157,247 +72,308 @@
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" t-if="not search">
|
||||
<!-- Navigation -->
|
||||
<div class="col-lg-8 col-md-12 col-12">
|
||||
<ul class="nav nav-tabs nav-tabs-border" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a t-attf-href="/slides/#{slug(channel)}#{category and '/category/' + slug(category) or ''}"
|
||||
t-attf-class="nav-link#{not slide_type and ' active' or ''}"> <i class="fa fa-home"/> Home</a>
|
||||
</li>
|
||||
<li t-if="header_object.nbr_presentations" class="nav-item">
|
||||
<a t-attf-href="/slides/#{slug(channel)}#{category and '/category/' + slug(category) or ''}/presentation"
|
||||
t-attf-class="nav-link#{slide_type == 'presentation' and ' active' or ''}">
|
||||
<span class="badge badge-pill" t-esc="header_object.nbr_presentations"/> Presentations
|
||||
</a>
|
||||
</li>
|
||||
<li t-if="header_object.nbr_videos" class="nav-item">
|
||||
<a t-attf-href="/slides/#{slug(channel)}#{category and '/category/' + slug(category) or ''}/video"
|
||||
t-attf-class="nav-link#{slide_type == 'video' and ' active' or ''}">
|
||||
<span class="badge badge-pill" t-esc="header_object.nbr_videos"/> Videos
|
||||
</a>
|
||||
</li>
|
||||
<li t-if="header_object.nbr_documents" class="li nav-item">
|
||||
<a t-attf-href="/slides/#{slug(channel)}#{category and '/category/' + slug(category) or ''}/document"
|
||||
t-attf-class="nav-link#{slide_type == 'document' and ' active' or ''}">
|
||||
<span class="badge badge-pill" t-esc="header_object.nbr_documents"/> Documents
|
||||
</a>
|
||||
</li>
|
||||
<li t-if="header_object.nbr_infographics" class="nav-item">
|
||||
<a t-attf-href="/slides/#{slug(channel)}#{category and '/category/' + slug(category) or ''}/infographic"
|
||||
t-attf-class="nav-link#{slide_type == 'infographic' and ' active' or ''}">
|
||||
<span class="badge badge-pill" t-esc="header_object.nbr_infographics"/> Infographics
|
||||
</a>
|
||||
</li>
|
||||
<li t-if="header_object.nbr_webpages" class="nav-item">
|
||||
<a t-attf-href="/slides/#{slug(channel)}#{category and '/category/' + slug(category) or ''}/webpage"
|
||||
t-attf-class="nav-link#{slide_type == 'webpage' and ' active' or ''}">
|
||||
<span class="badge badge-pill" t-esc="header_object.nbr_webpages"/> Pages
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Sort options -->
|
||||
<div class="col-lg-4 col-md-12 col-12">
|
||||
<span class="float-right">
|
||||
<span class="text-muted">Sort by:</span>
|
||||
<a href="?sorting=date">
|
||||
<span t-attf-style="#{sorting and sorting == 'date' and 'font-weight:bold;' ''}">Newest</span>
|
||||
</a>
|
||||
<span class="text-muted">|</span>
|
||||
<a href="?sorting=view">
|
||||
<span t-attf-style="#{sorting and sorting == 'view' and 'font-weight:bold;' ''}">Most Viewed</span>
|
||||
</a>
|
||||
<span class="text-muted">|</span>
|
||||
<a href="?sorting=vote">
|
||||
<span t-attf-style="#{sorting and sorting == 'vote' and 'font-weight:bold;' ''}">Most Voted</span>
|
||||
</a>
|
||||
</span>
|
||||
<!-- sort / filter -->
|
||||
<small class="dropdown float-right ml-2">
|
||||
<h6 class="m-0">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="slidesChannelDropdownSort"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<t t-if="sorting == 'most_voted'">Most Voted</t>
|
||||
<t t-elif="sorting == 'most_viewed'">Most Viewed</t>
|
||||
<t t-else="">Newest</t>
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="slidesChannelDropdownSort" role="menu">
|
||||
<div role="separator" class="dropdown-header">Sort by</div>
|
||||
<a role="menuitem" t-att-href="'/slides/%s?%s' % (slug(channel), keep_query('debug', '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('debug', '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('debug', 'slide_type', sorting='most_viewed'))"
|
||||
t-att-class="'dropdown-item %s' % ('active' if sorting and sorting == 'most_viewed' else '')">Most Viewed</a>
|
||||
</div>
|
||||
</h6>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Channel main template -->
|
||||
<template id='home' name="Odoo Slides">
|
||||
<t t-set="head">
|
||||
<template id='course_main' name="Course Main">
|
||||
<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-call="website.layout">
|
||||
<div class="wrap">
|
||||
<div class="wrap o_wslides_wrap">
|
||||
<t t-set="main_object" t-value="channel"/>
|
||||
<t t-call="website_slides.slides_channel_header">
|
||||
<t t-if="not category">
|
||||
<t t-set="header_object" t-value="channel"/>
|
||||
</t>
|
||||
<t t-if="category">
|
||||
<t t-set="header_object" t-value="category"/>
|
||||
</t>
|
||||
</t>
|
||||
<section t-if="not tag and not slide_type and not search and not is_public_user and not category" class="wrap mt16 mb0" groups="website.group_website_designer">
|
||||
<div class="container">
|
||||
<div class="alert alert-danger alert-dismissable mb0" role="alert">
|
||||
<p>
|
||||
Review your channel settings to promote your most viewed or recent published presentation
|
||||
</p>
|
||||
<a t-attf-href="/web#return_label=Website&id=#{channel.id}&view_type=form&model=slide.channel&action=#{request.env.ref('website_slides.action_slide_channels').id }" class="fa fa-arrow-right mt8">
|
||||
Channel Settings
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="oe_slides_promote_box" t-if="channel.slide_ids and not tag and not slide_type and not search and not category">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-5 mt16 mb16">
|
||||
<a t-attf-href="/slides/slide/#{slug(channel.slide_ids[0])}">
|
||||
<img t-attf-src="/web/image/slide.slide/#{channel.slide_ids[0].id}/image_medium" class="img-fluid shadow oe_slides_promote_image" alt="Promoted slide"/>
|
||||
</a>
|
||||
<t t-call="website_slides.course_nav"/>
|
||||
|
||||
<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">
|
||||
<img class="mr-3" t-att-src="'/web/image/slide.channel/%s/image' % channel.id"/>
|
||||
</div>
|
||||
<div class="col-lg-7 mt16 mb16">
|
||||
<h3 class="row">
|
||||
<a t-attf-href="/slides/slide/#{slug(channel.slide_ids[0])}">
|
||||
<t t-esc="channel.slide_ids[0].name"/>
|
||||
</a>
|
||||
</h3>
|
||||
<div class="row mt8 mb8" t-if="channel.slide_ids[0].tag_ids">
|
||||
<t t-foreach="channel.slide_ids[0].tag_ids" t-as="slide_tag">
|
||||
<a t-attf-href="/slides/#{slug(channel)}/tag/#{slug(slide_tag)}" t-attf-class="badge badge-secondary #{tag and tag.id == slide_tag.id and 'badge-primary' ''}" t-field="slide_tag.name"/>
|
||||
</t>
|
||||
</div>
|
||||
<div class="row oe_no_empty" t-esc="channel.slide_ids[0].description"/>
|
||||
<p class="row 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"/>
|
||||
<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="default_message_id" t-value="last_message_id"/>
|
||||
<t t-set="default_message" t-value="last_message"/>
|
||||
<t t-set="default_rating_value" t-value="last_rating_value"/>
|
||||
<t t-set="force_submit_url" t-value="'/slides/mail/update_comment' if last_message_id else False"/>
|
||||
</t>
|
||||
</p>
|
||||
<p class="row mt8">
|
||||
<b>Share:</b>
|
||||
<t t-call="website_slides.slides_share">
|
||||
<t t-set="slide" t-value="channel.slide_ids[0]"/>
|
||||
</t>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="o_slides_discussion_rating">
|
||||
<div class="container mt16 mb16">
|
||||
<hr/>
|
||||
<div class="row">
|
||||
<div class="col-lg-8 offset-lg-2">
|
||||
<t t-call="portal.message_thread">
|
||||
<t t-set="object" t-value="channel"/>
|
||||
<t t-set="display_rating" t-value="True"/>
|
||||
<t t-set="disable_composer" t-value="True"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<div class="container mt16">
|
||||
<div class="row">
|
||||
<div class="col-12" t-if="search and not slides">
|
||||
<div class="alert alert-danger" role="alert">
|
||||
Sorry, but nothing matches your search criteria <b><t t-esc="search"/></b>. Please try again with different keywords.
|
||||
<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="row">
|
||||
<div class="col-12 o_wslides_course_description" t-field="channel.description"/>
|
||||
<div class="col-6 mt8 mb64">
|
||||
<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"/>
|
||||
<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="default_message_id" t-value="last_message_id"/>
|
||||
<t t-set="default_message" t-value="last_message"/>
|
||||
<t t-set="default_rating_value" t-value="last_rating_value"/>
|
||||
<t t-set="force_submit_url" t-value="'/slides/mail/update_comment' if last_message_id else False"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-12 col-lg-12 col-md-12 col-12" style="padding-left: 15px;padding-right: 15px;" t-if="channel.total_slides == 0">
|
||||
<div class="jumbotron">
|
||||
<h1>No presentation published yet.</h1>
|
||||
<p>
|
||||
The <i><t t-esc="channel.name"/></i> is empty.
|
||||
<span t-if="channel.can_upload">
|
||||
Upload PDF presentations, documents, videos or infographic using the button below.
|
||||
</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_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.visibility == '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>
|
||||
</p>
|
||||
<p>
|
||||
<!-- Public user has not right to create/write on slide-->
|
||||
<a role="button" t-if="channel.can_upload" class="btn btn-primary oe_slide_js_upload" t-attf-channel-id="#{channel.id}" aria-label="Upload Presentation" title="Upload Presentation" href="#">
|
||||
<i class="fa fa-cloud-upload"></i> Upload
|
||||
</a>
|
||||
<t t-if="not channel.is_member and channel.visibility == 'invite'">
|
||||
<a role="button" class="col-10 btn btn-light" t-att-href="'#'">
|
||||
<span class="cta-title text_small_caps">Private Course</span>
|
||||
</a>
|
||||
</p>
|
||||
<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>
|
||||
|
||||
<div class="col-xl-12 col-lg-12 col-md-12 col-12" t-if="slide_type or category or tag">
|
||||
<div class="alert alert-success mb0" role="status" t-if="tag">
|
||||
Results for <strong t-esc="tag.name"/>
|
||||
<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>
|
||||
<t t-call="website_slides.slides_grid_view"/>
|
||||
</div>
|
||||
<div class="row text-center" t-if="slide_type or category or tag">
|
||||
<t t-call="website.pager"/>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-12 col-lg-12 col-md-12 col-12 mb16" t-if="not slide_type and category_datas and not tag">
|
||||
<t t-foreach="category_datas" t-as="category">
|
||||
<div class="col-xl-12 col-lg-12 col-md-12 col-12">
|
||||
<div class="col-xl-12 col-lg-12 col-md-12 col-12 mt8 oe_slides_bottom_border">
|
||||
<a t-if="category['id']" t-attf-href="/slides/#{slug(channel)}/category/#{category['id']}" class="h3 mt0 mb0">
|
||||
<t t-esc="category['name']"/>
|
||||
</a>
|
||||
<span t-if="not category['id']" title="Uncategorized presentation" class="h3 mt0 mb0">
|
||||
<t t-esc="category['name']"/>
|
||||
</span>
|
||||
<a t-attf-href="/slides/#{slug(channel)}/category/#{category['id']}" class="float-right" t-if="category['total_slides'] - 4 > 0 and category['id']">
|
||||
<i class="fa fa-arrow-right"/> See all
|
||||
</a>
|
||||
<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_%ss' % slide_type_key]"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span class="badge badge-pill badge-info" t-esc="channel['nbr_%ss' % slide_type_key]"/>
|
||||
</t>
|
||||
</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>&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>
|
||||
<t t-if="not search">
|
||||
<t t-call="website_slides.slides_grid_view">
|
||||
<t t-set="slides" t-value="category['slides']"/>
|
||||
|
||||
</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>
|
||||
</div>
|
||||
<!-- Channel content, aka slides (lessons in documentation mode) -->
|
||||
<div class="col-8 mt24 ml32 o_wslides_channel_content_promoted">
|
||||
<div class="row mt16 align-items-center">
|
||||
<div class="col">
|
||||
<h3><i class="fa fa-plus-square"/> Featured lesson</h3>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" t-if="slide_promoted">
|
||||
<div class="col-4">
|
||||
<img class="img img-fluid" t-att-src="'/web/image/slide.slide/%s/image' % slide_promoted.id"/>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
<div class="row">
|
||||
<h3 class="col-6" t-att-title="slide_promoted.name">
|
||||
<t t-if="slide_promoted.is_preview or channel.is_member">
|
||||
<a t-attf-href="/slides/slide/#{slug(slide_promoted)}" class="font-weight-bold text-muted" t-field="slide_promoted.name"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span class="font-weight-bold text-muted" t-field="slide_promoted.name"/>
|
||||
</t>
|
||||
</h3>
|
||||
<div class="col-12" t-field="slide_promoted.description"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Channel content, aka slides (lessons in documentation mode) -->
|
||||
<div 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">
|
||||
<div class="row mt16 align-items-center">
|
||||
<div class="col">
|
||||
<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>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
<t t-call="website_slides.slides_grid_view">
|
||||
<t t-set="slides" t-value="category['slides']"/>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-call="website_slides.slides_grid_view"/>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Embedded template: display a list of slides in a grid view -->
|
||||
<template id='slides_grid_view' name="Slides (Grid View)">
|
||||
<div class="row">
|
||||
<div class="col-xl-3 col-lg-4 col-md-6 col-12 mt16 mb16" t-foreach="slides" t-as="slide">
|
||||
<div class="card card-body">
|
||||
<a t-attf-href="/slides/slide/#{slug(slide)}">
|
||||
<img t-attf-src="/web/image/slide.slide/#{slide.id}/image_medium" class="img-fluid img-thumbnail oe_slides_grid_thumbnail" alt="slide.name"/>
|
||||
</a>
|
||||
<span t-if="not slide.website_published" class="badge badge-danger" style="position: absolute;right: 20px;top: 7px;">Unpublished</span>
|
||||
|
||||
<div style="padding: 5px;">
|
||||
<h4 class="mt4 mb8 oe_slides_ellipsis">
|
||||
<a t-att-title="slide.name" t-attf-href="/slides/slide/#{slug(slide)}" t-esc="slide.name"/>
|
||||
</h4>
|
||||
<div class="text-muted clearfix">
|
||||
<small class="float-left"><t t-esc="slide.total_views"/> Views</small>
|
||||
<small class="float-right"><timeago class="timeago" t-att-datetime="slide.create_date"></timeago></small>
|
||||
</div>
|
||||
<p t-if="slide.tag_ids" style="padding-top: 5px;">
|
||||
<t t-foreach="slide.tag_ids" t-as="att_tag">
|
||||
<a t-attf-href="/slides/#{slug(channel)}/tag/#{slug(att_tag)}" t-attf-class="badge badge-secondary #{tag and tag.name == att_tag.name and 'badge-primary' ''}" t-field="att_tag.name"/>
|
||||
<div class="row o_wslides_row mt8">
|
||||
<div class="col-lg-3 col-md-6 col-12" t-foreach="slides" t-as="slide">
|
||||
<div class="card o_wslides_lesson_card">
|
||||
<img class="card-img-top img-fuild"
|
||||
style="max-height: 160px;"
|
||||
t-att-src="'/web/image/slide.slide/%s/image_large' % slide.id if slide.image else '/website_slides/static/src/img/channel-default.jpg'"
|
||||
t-att-alt="channel.name"/>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title" t-att-title="slide.name">
|
||||
<t t-if="slide.is_preview or channel.is_member">
|
||||
<a t-attf-href="/slides/slide/#{slug(slide)}" t-esc="slide.name"/>
|
||||
</t>
|
||||
</p>
|
||||
<t t-else="">
|
||||
<span class="text-muted" t-esc="slide.name"/>
|
||||
</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>
|
||||
<t t-if="not slide.is_published and user.has_group('website.group_website_publisher')">
|
||||
<span class="badge badge-danger">Unpublished</span>
|
||||
</t>
|
||||
</h6>
|
||||
<div class="card-text">
|
||||
<div class="text-muted oe_no_empty" t-field="slide.description"/>
|
||||
<div t-if="slide.tag_ids">
|
||||
<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-secondary">
|
||||
<t t-esc="tag.name"/>
|
||||
</a>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<!-- CHECKME: like only if logged -->
|
||||
<div class="float-right text-right o_wslides_like">
|
||||
<span class="o_wslides_like_up" 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 class="o_wslides_like_down" 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>
|
||||
<small class="text-muted">
|
||||
<t t-call="website_slides.slides_misc_float_time">
|
||||
<t t-set="value" t-value="slide.completion_time"/>
|
||||
</t>
|
||||
<!-- <t t-esc="slide.total_views"/> Views
|
||||
<timeago class="timeago" t-att-datetime="slide.create_date"></timeago> -->
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -435,7 +411,7 @@
|
||||
<div clas="row">
|
||||
<div class="col-lg-8" t-if="slide.tag_ids">
|
||||
<t t-foreach="slide.tag_ids" t-as="slide_tag">
|
||||
<a t-attf-href="/slides/#{slug(slide.channel_id)}/tag/#{slug(slide_tag)}" t-attf-class="badge badge-secondary ml4 mb4 float-right #{tag and tag.id == slide_tag.id and 'badge-primary' ''}" t-field="slide_tag.name"/>
|
||||
<a t-attf-href="/slides/#{slug(slide.channel_id)}/tag/#{slug(slide_tag)}" t-attf-class="badge badge-secondary ml4 mb4 float-right #{search_tag and search_tag.id == slide_tag.id and 'badge-primary' ''}" t-field="slide_tag.name"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
@@ -723,7 +699,9 @@
|
||||
<!-- Slide sub-template: share: social media -->
|
||||
<template id='slide_social_media' name="Share on Social Networks">
|
||||
<h4 class="mt0">Share on Social Networks</h4>
|
||||
<t t-call="website_slides.slides_share"/>
|
||||
<t t-call="website_slides.slides_share">
|
||||
<t t-set="record" t-value="slide"/>
|
||||
</t>
|
||||
<h4 class="mt-3">Share Link</h4>
|
||||
<input type="text" class="form-control" t-att-value="slide.website_url" readonly="readonly" onClick="this.select();"/>
|
||||
<span class="form-text">Use permanent link to share in social media</span>
|
||||
|
||||
@@ -0,0 +1,429 @@
|
||||
<?xml version="1.0" ?>
|
||||
<odoo><data>
|
||||
|
||||
<!-- 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">
|
||||
<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>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarSlidesHomepage">
|
||||
<a class="navbar-brand" href="#"></a>
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item">
|
||||
<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-certificate"/> Certifications</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>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="container mt16 o_wslides_home_main">
|
||||
<div class="row">
|
||||
<div class="col-md-9">
|
||||
<t t-if="channels_my">
|
||||
<t t-set="void_count" t-value="3 - len(channels_my[:3])"/>
|
||||
<div class="o_wslides_home_content_section">
|
||||
<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>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row o_wslides_row mt8">
|
||||
<t t-foreach="channels_my[:3]" t-as="channel">
|
||||
<div class="col-md-4 col-sm-6 col-xs-12" t-call="website_slides.course_card"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
<div class="o_wslides_home_content_section">
|
||||
<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-fire"/> Most popular courses</h3>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row o_wslides_row mt8">
|
||||
<t t-foreach="channels_popular[:3]" t-as="channel">
|
||||
<div class="col-md-4 col-sm-6 col-xs-12" t-call="website_slides.course_card"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_wslides_home_content_section">
|
||||
<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-plus-square"/> Newest courses</h3>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row o_wslides_row mt8">
|
||||
<t t-foreach="channels_newest[:3]" t-as="channel">
|
||||
<div class="col-md-4 col-sm-6 col-xs-12" t-call="website_slides.course_card"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<t t-if="is_public_user">
|
||||
<t t-call="website_slides.slides_home_achievements_small"/>
|
||||
<t t-call="website_slides.slides_home_users_small"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-call="website_slides.slides_home_user_profile_small"/>
|
||||
<hr />
|
||||
<t t-call="website_slides.slides_home_user_achievements_small"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</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">
|
||||
<!-- 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>
|
||||
<button class="navbar-toggler" type="button"
|
||||
data-toggle="collapse" data-target="#navbarTagGroups"
|
||||
aria-controls="navbarTagGroups" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</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">
|
||||
<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"
|
||||
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>
|
||||
<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 '')"
|
||||
t-att-href="'/slides/all?%s' % keep_query('*', **{'channel_tag_group_id_%s' % tag_group.id: tag.id if tag not in search_tags else False})"
|
||||
t-esc="tag.name"/>
|
||||
</t>
|
||||
</div>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
<form method="GET" class="form-inline justify-content-center">
|
||||
<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">
|
||||
<i class="fa fa-search"/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="container mt16 o_wslides_home_main">
|
||||
<t t-if="search_term and not channels_layouted">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<p class="alert alert-info">No channel was found matching your search <t t-esc="search_term"/>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-foreach="channels_layouted" t-as="channels_row">
|
||||
<t t-set="missing" t-value="0"/>
|
||||
<div class="card-deck mb32">
|
||||
<t t-foreach="channels_row" t-as="channel">
|
||||
<t t-if="channel">
|
||||
<t t-call="website_slides.course_card"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-set="missing" t-value="missing + 1"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="missing">
|
||||
<div t-att-class="'col-%s' % (missing * 3)"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</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("/website_slides/static/src/img/channel_banner_moutain.jpg"); 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("/website/static/src/img/backgrounds/people.jpg"); 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"
|
||||
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-alt="channel.name"/>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title" t-att-title="channel.name">
|
||||
<a t-attf-href="/slides/#{slug(channel)}" t-esc="channel.name"/>
|
||||
</h5>
|
||||
<div class="card-text">
|
||||
<div class="text-muted oe_no_empty" t-field="channel.description"/>
|
||||
<div t-if="channel.tag_ids">
|
||||
<t t-foreach="channel.tag_ids" t-as="tag">
|
||||
<a t-att-href="'/slides/all?channel_tag_id=%s' % tag.id" class="badge badge-secondary">
|
||||
<t t-esc="tag.name"/>
|
||||
</a>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</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">
|
||||
<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="len(channel.slide_ids)"/> steps</small>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id='slides_home_achievements_small' name="Latest Achievements">
|
||||
<div class="o_wslides_home_aside">
|
||||
<div class="row mt16 o_wslides_home_aside_title">
|
||||
<div class="col">
|
||||
<a href="slides" class="text-muted float-right">
|
||||
<small class="float-right">View all</small>
|
||||
</a>
|
||||
<h3>Latest achievements</h3>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<t t-if="achievements">
|
||||
<div class="col">
|
||||
<t t-foreach="achievements" t-as="achievement">
|
||||
<t t-call="website_slides.achievement_card"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
<t t-else=""><p class="col mt8">No achievements currently :(</p></t>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id='achievement_card' name="Achivement Card">
|
||||
<div class="row no-gutters mt8 align-items-center">
|
||||
<div class="col-2">
|
||||
<t t-call="website_slides.slides_misc_user_image">
|
||||
<t t-set="user" t-value="achievement.user_id"/>
|
||||
<t t-set="record" t-value="channels_popular[:1]"/>
|
||||
</t>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="font-weight-bold" t-esc="achievement.user_id.name"/> achieved <a href="/slides"><span t-esc="achievement.badge_id.name"/></a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id='slides_home_users_small' name="Latest Users">
|
||||
<div class="o_wslides_home_aside">
|
||||
<div class="row mt16 o_wslides_home_aside_title">
|
||||
<div class="col">
|
||||
<a href="slides" class="text-muted float-right">
|
||||
<small class="float-right">View all</small>
|
||||
</a>
|
||||
<h3>Heroes of the week</h3>
|
||||
<hr/>
|
||||
</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 heroes currently :(</p></t>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id='user_quickkarma_card' name="User QuickKarma Card">
|
||||
<div class="row no-gutters mt8 align-items-center">
|
||||
<div class="col-2">
|
||||
<span class="font-weight-bold text-muted o_wslides_home_circled" t-esc="counter"/>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<t t-call="website_slides.slides_misc_user_image">
|
||||
<t t-set="record" t-value="channels_popular[:1]"/>
|
||||
</t>
|
||||
</div>
|
||||
<div class="col">
|
||||
<span class="font-weight-bold" t-esc="user.name"/>
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="text-muted" t-esc="user.rank_id.name"/><span class="ml8 mr8">•</span><span t-esc="user.karma" class="badge badge-success"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id='slides_home_user_profile_small' name="User Profile">
|
||||
<div class="o_wslides_home_aside">
|
||||
<div class="row mt16 o_wslides_home_aside_title align-items-center">
|
||||
<div class="col">
|
||||
<t t-call="website_slides.slides_misc_user_image">
|
||||
<t t-set="record" t-value="channels_popular[:1]"/>
|
||||
</t>
|
||||
<a t-att-href="'/slides'" class="float-right">Edit</a>
|
||||
<h4 t-esc="user.name" class="font-weight-bold"/>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt8">
|
||||
<p class="col">INSERT DBE TEMPLATE HERE</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id='slides_home_user_achievements_small' name="User Achievements">
|
||||
<div class="o_wslides_home_aside mt16">
|
||||
<t t-foreach="challenges" t-as="challenge">
|
||||
<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 ''"
|
||||
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"/>
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<span t-att-class="'font-weight-bold text_small_caps %s' % 'text-muted' if not challenge_done else ''" t-esc="challenge.reward_id.name"/><br/>
|
||||
<span class="text-muted" t-esc="challenge.reward_id.description"/>
|
||||
</div>
|
||||
<div class="col-2" t-if="challenge_done">
|
||||
<i class="fa fa-check float-right" aria-label="Done" title="Done" role="img"></i>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id='slides_misc_user_image' name="Float Time">
|
||||
<img t-att-class="img_class if img_class else 'rounded-circle float-left'"
|
||||
t-att-style="img_style if img_style else 'max-height: 32px;'"
|
||||
t-att-src="'/profile/avatar/%s?field=image_medium%s' % (user.id, '&res_model=%s&res_id=%s' % (record._name, record.id) if record else '')"
|
||||
t-att-alt="user.name"/>
|
||||
</template>
|
||||
|
||||
<template id='slides_misc_float_time' name="Float Time">
|
||||
<t t-set="hours" t-value="int(value)"/>
|
||||
<t t-set="minuts" t-value="int(60.0 * (value - int(value)))"/>
|
||||
<span t-esc="hours"/> hr
|
||||
<t t-if="minuts">
|
||||
<span t-esc="minuts"/> mins
|
||||
</t>
|
||||
</template>
|
||||
|
||||
</data></odoo>
|
||||
Reference in New Issue
Block a user