diff --git a/addons/website_slides/__init__.py b/addons/website_slides/__init__.py index 7d34c7c054abd3105d5bb41fe9674111e1c27c16..8871070722787374e6f51f62f0f636847d986285 100644 --- a/addons/website_slides/__init__.py +++ b/addons/website_slides/__init__.py @@ -3,3 +3,4 @@ from . import controllers from . import models +from . import wizard diff --git a/addons/website_slides/__manifest__.py b/addons/website_slides/__manifest__.py index 32b4f407e67576e4e258247a2ba72afc146912b1..a5df3cf0cefa483f71c9a6f14621c976dbfb7516 100644 --- a/addons/website_slides/__manifest__.py +++ b/addons/website_slides/__manifest__.py @@ -25,16 +25,18 @@ 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', 'views/slide_channel_partner_views.xml', 'views/slide_channel_views.xml', 'views/slide_channel_tag_views.xml', - 'views/slide_channel_invite_views.xml', 'views/website_slides_menu_views.xml', + 'views/website_slides_templates_homepage.xml', + 'views/website_slides_templates_course.xml', + 'views/website_slides_templates_lesson.xml', + 'views/website_slides_templates_lesson_embed.xml', 'views/website_slides_templates_profile.xml', + 'views/website_slides_templates_utils.xml', + 'wizard/slide_channel_invite_views.xml', 'data/ir_data.xml', 'data/gamification_data.xml', 'data/mail_data.xml', diff --git a/addons/website_slides/controllers/__init__.py b/addons/website_slides/controllers/__init__.py index acf000fd92ccb4db69e8ae184403ef04dcb2a851..5f1516578614a94738c485fc7e7874be8ee7b554 100644 --- a/addons/website_slides/controllers/__init__.py +++ b/addons/website_slides/controllers/__init__.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. from . import mail from . import main diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py index 50cea64c0781e452263c7c2625648d0f6c00d341..f02484629949544b9baab0bf0ffd04d4c9b4833f 100644 --- a/addons/website_slides/controllers/main.py +++ b/addons/website_slides/controllers/main.py @@ -53,8 +53,8 @@ class WebsiteSlides(WebsiteProfile): return True 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) + most_viewed_slides = slide._get_most_viewed_slides(self._slides_per_list) + related_slides = slide._get_related_slides(self._slides_per_list) values = { 'slide': slide, 'most_viewed_slides': most_viewed_slides, @@ -521,7 +521,7 @@ class WebsiteSlides(WebsiteProfile): @http.route(['/slides/slide/send_share_email'], type='json', auth='user', website=True) def slide_send_share_email(self, slide_id, email): slide = request.env['slide.slide'].browse(int(slide_id)) - result = slide.send_share_email(email) + result = slide._send_share_email(email) return result # -------------------------------------------------- diff --git a/addons/website_slides/models/__init__.py b/addons/website_slides/models/__init__.py index 2768668e3e416629c6883ec4cd420fcb0cc3a7ba..9a55188c7aede7c683ddbdc3673a21243a1d42b4 100644 --- a/addons/website_slides/models/__init__.py +++ b/addons/website_slides/models/__init__.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. from . import gamification_challenge from . import slide_slide from . import slide_question from . import slide_channel from . import slide_channel_tag -from . import slide_channel_invite from . import res_config_settings from . import website from . import res_users diff --git a/addons/website_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py index 766fde193a0f86e3e2922226e5dd23a806e48f4b..edb496a14e8dfa61ee94947f3c3fab0cadb203cd 100644 --- a/addons/website_slides/models/slide_channel.py +++ b/addons/website_slides/models/slide_channel.py @@ -259,41 +259,6 @@ class Channel(models.Model): if channel.id: # avoid to perform a slug on a not yet saved record in case of an onchange. channel.website_url = '%s/slides/%s' % (base_url, slug(channel)) - @api.multi - def action_redirect_to_members(self): - action = self.env.ref('website_slides.slide_channel_partner_action').read()[0] - action['view_mode'] = 'tree' - action['domain'] = [('channel_id', 'in', self.ids)] - if len(self) == 1: - action['context'] = {'default_channel_id': self.id} - - return action - - @api.multi - def action_channel_invite(self): - self.ensure_one() - - if self.enroll != 'invite': - raise UserError(_("You cannot send invitations for channels that are not set as 'invite'.")) - - template = self.env.ref('website_slides.mail_template_slide_channel_invite', raise_if_not_found=False) - - local_context = dict( - self.env.context, - default_channel_id=self.id, - default_use_template=bool(template), - default_template_id=template and template.id or False, - notif_layout='mail.mail_notification_light', - ) - return { - 'type': 'ir.actions.act_window', - 'view_type': 'form', - 'view_mode': 'form', - 'res_model': 'slide.channel.invite', - 'target': 'new', - 'context': local_context, - } - # --------------------------------------------------------- # ORM Overrides # --------------------------------------------------------- @@ -364,6 +329,41 @@ class Channel(models.Model): # Business / Actions # --------------------------------------------------------- + @api.multi + def action_redirect_to_members(self): + action = self.env.ref('website_slides.slide_channel_partner_action').read()[0] + action['view_mode'] = 'tree' + action['domain'] = [('channel_id', 'in', self.ids)] + if len(self) == 1: + action['context'] = {'default_channel_id': self.id} + + return action + + @api.multi + def action_channel_invite(self): + self.ensure_one() + + if self.visibility != 'invite': + raise UserError(_("You cannot send invitations for channels that are not set as 'invite'.")) + + template = self.env.ref('website_slides.mail_template_slide_channel_invite', raise_if_not_found=False) + + local_context = dict( + self.env.context, + default_channel_id=self.id, + default_use_template=bool(template), + default_template_id=template and template.id or False, + notif_layout='mail.mail_notification_light', + ) + return { + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'slide.channel.invite', + 'target': 'new', + 'context': local_context, + } + def action_add_member(self, **member_values): """ Adds the logged in user in the channel members. (see '_action_add_members' for more info) @@ -413,11 +413,6 @@ class Channel(models.Model): for channel in self: channel._action_add_members(channel.mapped('enroll_group_ids.users.partner_id')) - def list_all(self): - return { - 'channels': [{'id': channel.id, 'name': channel.name, 'website_url': channel.website_url} for channel in self.search([])] - } - # --------------------------------------------------------- # Rating Mixin API # --------------------------------------------------------- diff --git a/addons/website_slides/models/slide_slide.py b/addons/website_slides/models/slide_slide.py index fe022f83b31cffbcb3dbe857ed8df15d5b09f526..24e043be6e309cb4c3078708fa1f951f78546ae6 100644 --- a/addons/website_slides/models/slide_slide.py +++ b/addons/website_slides/models/slide_slide.py @@ -77,17 +77,6 @@ class SlideTag(models.Model): class Slide(models.Model): - """ This model represents actual presentations. Those must be one of four - types: - - - Presentation - - Document - - Infographic - - Video - - Webpage - - Slide has various statistics like view count, embed count, like, dislikes """ - _name = 'slide.slide' _inherit = ['mail.thread', 'website.seo.metadata', 'website.published.mixin', 'rating.mixin'] _description = 'Slides' @@ -99,10 +88,6 @@ class Slide(models.Model): } _order = 'category_sequence asc, sequence asc' - _sql_constraints = [ - ('exclusion_html_content_and_url', "CHECK(html_content IS NULL OR url IS NULL)", "A slide is either filled with a document url or HTML content. Not both.") - ] - def _default_access_token(self): return str(uuid.uuid4()) @@ -161,13 +146,17 @@ class Slide(models.Model): likes = fields.Integer('Likes', compute='_compute_user_info', store=True) dislikes = fields.Integer('Dislikes', compute='_compute_user_info', store=True) user_vote = fields.Integer('User vote', compute='_compute_user_info') - embed_code = fields.Text('Embed Code', readonly=True, compute='_get_embed_code') + embed_code = fields.Text('Embed Code', readonly=True, compute='_compute_embed_code') # views embedcount_ids = fields.One2many('slide.embed', 'slide_id', string="Embed Count") slide_views = fields.Integer('# of Website Views', store=True, compute="_compute_slide_views") public_views = fields.Integer('# of Public Views') total_views = fields.Integer("Total # Views", default="0", compute='_compute_total', store=True) + _sql_constraints = [ + ('exclusion_html_content_and_url', "CHECK(html_content IS NULL OR url IS NULL)", "A slide is either filled with a document url or HTML content. Not both.") + ] + @api.depends('slide_views', 'public_views') def _compute_total(self): for record in self: @@ -216,7 +205,8 @@ class Slide(models.Model): self.env['slide.slide.partner'] ) - def _get_embed_code(self): + @api.depends('document_id', 'slide_type', 'mime_type') + def _compute_embed_code(self): base_url = request and request.httprequest.url_root or self.env['ir.config_parameter'].sudo().get_param('web.base.url') if base_url[-1] == '/': base_url = base_url[:-1] @@ -235,7 +225,7 @@ class Slide(models.Model): record.embed_code = False @api.onchange('url') - def on_change_url(self): + def _on_change_url(self): self.ensure_one() if self.url: res = self._parse_document_url(self.url) @@ -250,6 +240,7 @@ class Slide(models.Model): @api.multi @api.depends('name') def _compute_website_url(self): + # TDE FIXME: clena this link.tracker strange stuff super(Slide, self)._compute_website_url() base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') for slide in self: @@ -321,6 +312,10 @@ class Slide(models.Model): self._post_publication() return res + # --------------------------------------------------------- + # Mail/Rating + # --------------------------------------------------------- + @api.multi def get_access_action(self, access_uid=None): """ Instead of the classic form view, redirect to website if it is published. """ @@ -335,10 +330,6 @@ class Slide(models.Model): } return super(Slide, self).get_access_action(access_uid) - # --------------------------------------------------------- - # Business Methods - # --------------------------------------------------------- - @api.multi def _notify_get_groups(self, message, groups): """ Add access button to everyone if the document is active. """ @@ -350,7 +341,12 @@ class Slide(models.Model): return groups - def get_related_slides(self, limit=20): + # --------------------------------------------------------- + # Business Methods + # --------------------------------------------------------- + + def _get_related_slides(self, limit=20): + # TDE FIXME: should build a smarter domain domain = request.website.website_domain() domain += [('website_published', '=', True), ('id', '!=', self.id)] if self.category_id: @@ -358,7 +354,8 @@ class Slide(models.Model): for record in self.search(domain, limit=limit): yield record - def get_most_viewed_slides(self, limit=20): + def _get_most_viewed_slides(self, limit=20): + # TDE FIXME: should build a smarter domain domain = request.website.website_domain() domain += [('website_published', '=', True), ('id', '!=', self.id)] for record in self.search(domain, limit=limit, order='total_views desc'): @@ -387,10 +384,13 @@ class Slide(models.Model): self.write({'access_token': self._default_access_token()}) return self._sign_token(partner_id) - @api.one - def send_share_email(self, email): + def _send_share_email(self, email): + # TDE FIXME: template to check + mail_ids = [] base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') - return self.channel_id.share_template_id.with_context(email=email, base_url=base_url).send_mail(self.id, notif_layout='mail.mail_notification_light') + for record in self: + mail_ids.append(self.channel_id.share_template_id.with_context(email=email, base_url=base_url).send_mail(record.id, notif_layout='mail.mail_notification_light')) + return mail_ids def action_like(self): self.check_access_rights('read') diff --git a/addons/website_slides/views/website_slides_templates_course.xml b/addons/website_slides/views/website_slides_templates_course.xml new file mode 100644 index 0000000000000000000000000000000000000000..5df196a2e1b459a18bb029a686c5aeef7dfaf8f4 --- /dev/null +++ b/addons/website_slides/views/website_slides_templates_course.xml @@ -0,0 +1,420 @@ +<?xml version="1.0" ?> +<odoo><data> + +<!-- Channels sub-template: header --> +<template id="course_nav" name="Course Navigation Header"> + <div class="o_wslides_course_nav"> + <div class="container"> + <div class="row align-items-center justify-content-between"> + <!-- 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-6 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"/> + </a> + <!-- 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"/> + <span class="input-group-append"> + <button class="btn btn-primary" type="submit" aria-label="Search" title="Search"> + <i class="fa fa-search"></i> + </button> + </span> + </div> + </form> + <!-- sort / filter --> + <small class="dropdown float-right ml-3"> + <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> + </div> +</template> + +<!-- Channel main template --> +<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 o_wslides_wrap"> + <t t-set="main_object" t-value="channel"/> + <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 main_image"> + <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="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> + </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.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> + </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_%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> + + </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> + <!-- training mode ==============================================--> + <div t-if="channel.channel_type == 'training'" style="width:70%;" class="d-flex align-items-center ml-4 justify-content-center"> + <div class="course-content oe_js_course_slides_list" style="width: 100%"> + <ul> + <t t-set="i" t-value="1"/> + <t t-set="j" t-value="0"/> + <t t-foreach="channel.category_ids" t-as="category"> + <li t-attf-class="#{'section-draggable' if user == user_id else ''}" t-attf-category_id="#{category.id}"> + <div t-attf-category_id="#{category.id}" class="course-section text-muted font-weight-bold pt-0 pb-0 pl-2 pr-2 d-flex justify-content-between align-items-center"> + <div style="width:50%;" class="d-flex align-items-center"> + <i t-if="channel.user_id == user" class="fa fa-arrows mr-3 text-muted"></i> + <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" + href="#" + style="font-size: 1.5rem;text-decoration: none;" + t-att-data-channel-id="channel.id" + t-att-data-category-id="category.id" + t-att-data-can-upload="channel.can_upload" + t-att-data-can-publish="channel.can_publish">+</a> + <t t-set="i" t-value="i+1"/> + </div> + <ul t-attf-category_id="#{category.id}" > + <t t-foreach="category.slide_ids" t-as="slide"> + <li t-att-index="j" t-attf-slide_id="#{slide.id}" t-attf-category_id="#{category.id}" t-attf-class="#{'content-slide slide-draggable d-flex justify-content-between align-items-center p-2' if channel.user_id == user else 'content-slide d-flex justify-content-between align-items-center p-2'}"> + <div class="content-slide-infos ml-2"> + <i t-if="channel.user_id == user" class="fa fa-arrows mr-2 text-muted"></i> + <i t-if="slide.slide_type == 'document'" class="fa fa-file-pdf-o mr-2 text-muted"></i> + <i t-if="slide.slide_type == 'infographic'" class="fa fa-file-picture-o mr-2 text-muted"></i> + <i t-if="slide.slide_type == 'video'" class="fa fa-play-circle mr-2 text-muted"></i> + <i t-if="slide.slide_type == 'link'" class="fa fa-file-code-o mr-2 text-muted"></i> + <i t-if="slide.slide_type == 'webpage'" class="fa fa-file-text mr-2 text-muted"></i> + <i t-if="slide.slide_type == 'quiz'" class="fa fa-question-circle mr-2 text-muted"></i> + <i t-if="slide.slide_type == 'certification'" class="fa fa-trophy mr-2 text-muted"></i> + <a class="link-to-slide" t-attf-href="/slides/slide/#{slug(slide)}"><span t-field="slide.name"/></a> + </div> + <div class="content-slide-controls mr-2"> + <i t-if="not slide.id in user_progress or not user_progress[slide.id].completed" class="check-done fa fa-check-circle text-muted mr-1"></i> + <i t-if="slide.id in user_progress and user_progress[slide.id].completed" class="check-done text-primary fa fa-check-circle mr-1"></i> + <a t-if="channel.user_id == user and not slide.slide_type == 'webpage'" t-attf-href="/web#id=#{slide.id}&action=#{slide_action}&model=slide.slide&view_type=form"><i class="fa fa-pencil text-muted mr-1"></i></a> + <a t-if="channel.user_id == user and slide.slide_type == 'webpage'" t-attf-href="/slides/slide/#{slug(slide)}?enable_editor=1"><i class="fa fa-pencil text-muted mr-1"></i></a> + <i t-if="channel.user_id == user" t-attf-slide_id="#{slide.id}" class="fa fa-trash text-muted oe_slide_js_delete_slide"></i> + </div> + </li> + <t t-set="j" t-value="j+1"/> + </t> + </ul> + </li> + </t> + </ul> + <div t-if="channel.user_id == user" class="content-actions"> + <a class="mr-2 oe_slide_js_upload" + role="button" + aria-label="Upload Presentation" + href="#" + t-att-data-channel-id="channel.id" + t-att-data-can-upload="channel.can_upload" + t-att-data-can-publish="channel.can_publish">Add Content</a> + <a class="oe_slide_js_add_section" t-attf-channel_id="#{channel.id}" href="#">Add Section</a> + </div> + </div> + </div> + <!-- Channel content, aka slides (lessons in documentation mode) --> + <div t-if="channel.channel_type == 'documentation'" 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" style="" + t-att-src="'/slides/slide/%s/get_image?field=image_large' % slide_promoted.id" + t-att-alt="slide_promoted.name"/> + </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 or is_slides_publisher"> + <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 t-if="channel.channel_type == 'documentation'" 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> + </div> + </div> + </div> + </div> + </div> + </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 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="'/slides/slide/%s/get_image?field=image_large' % slide.id" + t-att-alt="slide.name"/> + <div class="card-body"> + <h5 class="card-title" t-att-title="slide.name"> + <t t-if="slide.is_preview or channel.is_member or is_slides_publisher"> + <a t-attf-href="/slides/slide/#{slug(slide)}" t-esc="slide.name"/> + </t> + <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> + </div> +</template> + +</data></odoo> diff --git a/addons/website_slides/views/website_slides_templates.xml b/addons/website_slides/views/website_slides_templates_lesson.xml similarity index 57% rename from addons/website_slides/views/website_slides_templates.xml rename to addons/website_slides/views/website_slides_templates_lesson.xml index 7f0bc0d955368e400125b6900622b6770202a573..3b3600b6e4700055d54e7d22661745b3ee147283 100644 --- a/addons/website_slides/views/website_slides_templates.xml +++ b/addons/website_slides/views/website_slides_templates_lesson.xml @@ -1,454 +1,7 @@ <?xml version="1.0" ?> -<odoo> -<data> - -<!-- 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=#{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: no channel found --> -<template id="channel_not_found" name="Private Presentation"> - <t t-call="website.layout"> - <div class="container"> - <div class="oe_structure"> - <t t-if="search_term"> - <h2>No channel found when searching "<i><t t-esc="search_term"/></i>".</h2> - </t> - <t t-else=""> - <h2>No channel created or published yet.</h2> - </t> - </div> - </div> - </t> -</template> - -<!-- Channels sub-template: header --> -<template id="course_nav" name="Course Navigation Header"> - <div class="o_wslides_course_nav"> - <div class="container"> - <div class="row align-items-center justify-content-between"> - <!-- 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-6 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"/> - </a> - <!-- 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"/> - <span class="input-group-append"> - <button class="btn btn-primary" type="submit" aria-label="Search" title="Search"> - <i class="fa fa-search"></i> - </button> - </span> - </div> - </form> - <!-- sort / filter --> - <small class="dropdown float-right ml-3"> - <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> - </div> -</template> - -<!-- Channel main template --> -<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 o_wslides_wrap"> - <t t-set="main_object" t-value="channel"/> - <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 main_image"> - <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="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> - </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.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> - </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_%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> - - </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> - <!-- training mode ==============================================--> - <div t-if="channel.channel_type == 'training'" style="width:70%;" class="d-flex align-items-center ml-4 justify-content-center"> - <div class="course-content oe_js_course_slides_list" style="width: 100%"> - <ul> - <t t-set="i" t-value="1"/> - <t t-set="j" t-value="0"/> - <t t-foreach="channel.category_ids" t-as="category"> - <li t-attf-class="#{'section-draggable' if user == user_id else ''}" t-attf-category_id="#{category.id}"> - <div t-attf-category_id="#{category.id}" class="course-section text-muted font-weight-bold pt-0 pb-0 pl-2 pr-2 d-flex justify-content-between align-items-center"> - <div style="width:50%;" class="d-flex align-items-center"> - <i t-if="channel.user_id == user" class="fa fa-arrows mr-3 text-muted"></i> - <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" - href="#" - style="font-size: 1.5rem;text-decoration: none;" - t-att-data-channel-id="channel.id" - t-att-data-category-id="category.id" - t-att-data-can-upload="channel.can_upload" - t-att-data-can-publish="channel.can_publish">+</a> - <t t-set="i" t-value="i+1"/> - </div> - <ul t-attf-category_id="#{category.id}" > - <t t-foreach="category.slide_ids" t-as="slide"> - <li t-att-index="j" t-attf-slide_id="#{slide.id}" t-attf-category_id="#{category.id}" t-attf-class="#{'content-slide slide-draggable d-flex justify-content-between align-items-center p-2' if channel.user_id == user else 'content-slide d-flex justify-content-between align-items-center p-2'}"> - <div class="content-slide-infos ml-2"> - <i t-if="channel.user_id == user" class="fa fa-arrows mr-2 text-muted"></i> - <i t-if="slide.slide_type == 'document'" class="fa fa-file-pdf-o mr-2 text-muted"></i> - <i t-if="slide.slide_type == 'infographic'" class="fa fa-file-picture-o mr-2 text-muted"></i> - <i t-if="slide.slide_type == 'video'" class="fa fa-play-circle mr-2 text-muted"></i> - <i t-if="slide.slide_type == 'link'" class="fa fa-file-code-o mr-2 text-muted"></i> - <i t-if="slide.slide_type == 'webpage'" class="fa fa-file-text mr-2 text-muted"></i> - <i t-if="slide.slide_type == 'quiz'" class="fa fa-question-circle mr-2 text-muted"></i> - <i t-if="slide.slide_type == 'certification'" class="fa fa-trophy mr-2 text-muted"></i> - <a class="link-to-slide" t-attf-href="/slides/slide/#{slug(slide)}"><span t-field="slide.name"/></a> - </div> - <div class="content-slide-controls mr-2"> - <i t-if="not slide.id in user_progress or not user_progress[slide.id].completed" class="check-done fa fa-check-circle text-muted mr-1"></i> - <i t-if="slide.id in user_progress and user_progress[slide.id].completed" class="check-done text-primary fa fa-check-circle mr-1"></i> - <a t-if="channel.user_id == user and not slide.slide_type == 'webpage'" t-attf-href="/web#id=#{slide.id}&action=#{slide_action}&model=slide.slide&view_type=form"><i class="fa fa-pencil text-muted mr-1"></i></a> - <a t-if="channel.user_id == user and slide.slide_type == 'webpage'" t-attf-href="/slides/slide/#{slug(slide)}?enable_editor=1"><i class="fa fa-pencil text-muted mr-1"></i></a> - <i t-if="channel.user_id == user" t-attf-slide_id="#{slide.id}" class="fa fa-trash text-muted oe_slide_js_delete_slide"></i> - </div> - </li> - <t t-set="j" t-value="j+1"/> - </t> - </ul> - </li> - </t> - </ul> - <div t-if="channel.user_id == user" class="content-actions"> - <a class="mr-2 oe_slide_js_upload" - role="button" - aria-label="Upload Presentation" - href="#" - t-att-data-channel-id="channel.id" - t-att-data-can-upload="channel.can_upload" - t-att-data-can-publish="channel.can_publish">Add Content</a> - <a class="oe_slide_js_add_section" t-attf-channel_id="#{channel.id}" href="#">Add Section</a> - </div> - </div> - </div> - <!-- Channel content, aka slides (lessons in documentation mode) --> - <div t-if="channel.channel_type == 'documentation'" 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" style="" - t-att-src="'/slides/slide/%s/get_image?field=image_large' % slide_promoted.id" - t-att-alt="slide_promoted.name"/> - </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 or is_slides_publisher"> - <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 t-if="channel.channel_type == 'documentation'" 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> - </div> - </div> - </div> - </div> - </div> - </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 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="'/slides/slide/%s/get_image?field=image_large' % slide.id" - t-att-alt="slide.name"/> - <div class="card-body"> - <h5 class="card-title" t-att-title="slide.name"> - <t t-if="slide.is_preview or channel.is_member or is_slides_publisher"> - <a t-attf-href="/slides/slide/#{slug(slide)}" t-esc="slide.name"/> - </t> - <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> - </div> -</template> +<odoo><data> <!-- Slide: main template: detailed view --> -<template id="slide_edit_options" inherit_id="website.user_navbar" name="Edit Slide Options"> - <xpath expr="//li[@id='edit-page-menu']" position="after"> - <t t-if="main_object._name == 'slide.slide'" t-set="action" t-value="'website_slides.action_slides_slides'" /> - </xpath> -</template> <template id="slide_detail_view" name="Slide Detailed View"> <t t-call="website.layout"> <t t-set="main_object" t-value="slide"/> @@ -1004,19 +557,6 @@ </li> </template> - -<!-- 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-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> -</template> - - <!-- Slide sub-template: share: send by email --> <template id='slide_social_email' name="Share by Email"> <h4 class="mt-3">Share with a friend</h4> @@ -1057,15 +597,4 @@ </div> </template> -<!-- User Navbar --> -<template id="user_navbar_inherit_website_slides" inherit_id="website.user_navbar"> - <xpath expr="//div[@id='o_new_content_menu_choices']//div[@name='module_website_slides']" position="attributes"> - <attribute name="name"/> - <attribute name="t-att-data-module-id"/> - <attribute name="t-att-data-module-shortdesc"/> - <attribute name="groups">website.group_website_designer</attribute> - </xpath> -</template> - -</data> -</odoo> +</data></odoo> diff --git a/addons/website_slides/views/website_slides_embed_templates.xml b/addons/website_slides/views/website_slides_templates_lesson_embed.xml similarity index 100% rename from addons/website_slides/views/website_slides_embed_templates.xml rename to addons/website_slides/views/website_slides_templates_lesson_embed.xml diff --git a/addons/website_slides/views/website_slides_templates_utils.xml b/addons/website_slides/views/website_slides_templates_utils.xml new file mode 100644 index 0000000000000000000000000000000000000000..57d5c2fced5d7d6070dd969f08b44d0600970dea --- /dev/null +++ b/addons/website_slides/views/website_slides_templates_utils.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" ?> +<odoo><data> + +<!-- Share on social networks --> +<template id='slides_share' name="Slides Media Share"> + <div> + <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> + +<!-- 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-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> +</template> + +<!-- Website edit page --> +<template id="slide_edit_options" inherit_id="website.user_navbar" name="Edit Slide Options"> + <xpath expr="//li[@id='edit-page-menu']" position="after"> + <t t-if="main_object._name == 'slide.slide'" t-set="action" t-value="'website_slides.action_slides_slides'" /> + </xpath> +</template> + +<!-- User Navbar --> +<template id="user_navbar_inherit_website_slides" inherit_id="website.user_navbar"> + <xpath expr="//div[@id='o_new_content_menu_choices']//div[@name='module_website_slides']" position="attributes"> + <attribute name="name"/> + <attribute name="t-att-data-module-id"/> + <attribute name="t-att-data-module-shortdesc"/> + <attribute name="groups">website.group_website_designer</attribute> + </xpath> +</template> + +</data></odoo> diff --git a/addons/website_slides/wizard/__init__.py b/addons/website_slides/wizard/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..4020988908bf05c8f64bf1e7fd228466d025dff6 --- /dev/null +++ b/addons/website_slides/wizard/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import slide_channel_invite diff --git a/addons/website_slides/models/slide_channel_invite.py b/addons/website_slides/wizard/slide_channel_invite.py similarity index 100% rename from addons/website_slides/models/slide_channel_invite.py rename to addons/website_slides/wizard/slide_channel_invite.py diff --git a/addons/website_slides/views/slide_channel_invite_views.xml b/addons/website_slides/wizard/slide_channel_invite_views.xml similarity index 100% rename from addons/website_slides/views/slide_channel_invite_views.xml rename to addons/website_slides/wizard/slide_channel_invite_views.xml