[MERGE][IMP] website_slides: improve the frontend UI for slide_channels

PURPOSE
---------------

Add small improvements to the frontend UI for slide_channels.

SPECIFICATION
-----------------------

Current behavior before PR:

1. We can't display all uncategorized slides of a course.

2. When you upload an image or PDF, the name field is replaced by the filename even it was filled before selecting the file. This leads to rewrite the name a second time before uploading the slide.

3. There is no way for the website designer to choose if he wants to display or hide the promoted slide of a course.

Desired behavior after PR is merged:

1. Slides without a category are displayed correctly, now you have access to the link "View all" which allows the user to display all uncategorized slides with a possible pager.
You have also the possibility to create a section/category with the new button "Add a section" next to the button to upload content.

2. When you upload an image or a PDF, the name field is no more replace automatically by the filename. Now, it's replaced only if the field is empty when you select the file.

3. Now, there is a new button under the Customize tab to display or hide the promoted slide on the courses. By default, the promoted slide is displayed on the course.

task-2161391

closes odoo/odoo#42420

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
Odoo's Mergebot
2020-02-12 15:59:10 +01:00
committed by GitHub
3 changed files with 69 additions and 41 deletions
+14 -3
View File
@@ -348,9 +348,12 @@ class WebsiteSlides(WebsiteProfile):
'/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.slide"):category>',
'/slides/<model("slide.channel"):channel>/category/<model("slide.slide"):category>/page/<int:page>'
'/slides/<model("slide.channel"):channel>/category/<model("slide.slide"):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, uncategorized=False, sorting=None, search=None, **kw):
"""
Will return all necessary data to display the requested slide_channel along with a possible category.
"""
if not channel.can_access_from_current_website():
raise werkzeug.exceptions.NotFound()
@@ -376,7 +379,7 @@ class WebsiteSlides(WebsiteProfile):
pager_url += "/tag/%s" % tag.id
if uncategorized:
domain += [('category_id', '=', False)]
pager_url += "?uncategorized=1"
pager_args['uncategorized'] = 1
elif slide_type:
domain += [('slide_type', '=', slide_type)]
pager_url += "?slide_type=%s" % slide_type
@@ -463,10 +466,18 @@ class WebsiteSlides(WebsiteProfile):
# documentation mode may display less slides than content by category but overhead of
# computation is reasonable
values['slide_promoted'] = request.env['slide.slide'].sudo().search(domain, limit=1, order=order)
limit_category_data = False
if channel.channel_type == 'documentation':
if category or uncategorized:
limit_category_data = self._slides_per_page
else:
limit_category_data = self._slides_per_category
values['category_data'] = channel._get_categorized_slides(
domain, order,
force_void=not category,
limit=False if channel.channel_type != 'documentation' else self._slides_per_page if category else self._slides_per_category,
limit=limit_category_data,
offset=pager['offset'])
values['channel_progress'] = self._get_channel_progress(channel, include_quiz=True)
@@ -516,7 +516,9 @@ var SlideUploadDialog = Dialog.extend({
if (!preventOnchange) {
var input = file.name;
var inputVal = input.substr(0, input.lastIndexOf('.')) || input;
this._formSetFieldValue('name', inputVal);
if (this._formGetFieldValue('name') === "") {
this._formSetFieldValue('name', inputVal);
}
}
},
_onChangeSlideUrl: function (ev) {
@@ -452,6 +452,38 @@
</template>
<!-- ======= Documentation Course content: cards / categories======= -->
<template id="course_promoted_slide" name="Documentation Course content: promoted slide">
<div class="o_wslides_promoted_slide d-none">
<div t-if="not search and not search_slide_type and slide_promoted" class="container py-1 mb-2">
<div class="card flex-column flex-lg-row">
<t t-set="image_url" t-value="website.image_url(slide_promoted, 'image_1024')"/>
<a t-if="slide_promoted.is_preview or channel.is_member or is_slides_publisher"
t-attf-href="/slides/slide/#{slug(slide_promoted)}#{query_string}" class="w-100 w-lg-50 flex-shrink-0 rounded">
<div t-attf-style="background-image:url(#{image_url}); background-size: cover; background-position:center; padding-bottom: 35%;" class="h-lg-100"/>
</a>
<div t-else="" class="w-100 w-lg-50 flex-shrink-0 rounded">
<div t-attf-style="background-image:url(#{image_url}); background-size: cover; background-position:center; padding-bottom: 35%;" class="h-lg-100"/>
</div>
<div class="card-body">
<a t-if="slide_promoted.is_preview or channel.is_member or is_slides_publisher"
t-attf-href="/slides/slide/#{slug(slide_promoted)}#{query_string}"
class="h4 d-block" t-att-title="slide_promoted.name" t-field="slide_promoted.name"/>
<h4 t-else="" class="text-muted" t-field="slide_promoted.name"/>
<div t-if="slide_promoted.tag_ids" class="border-top mt-2 pt-1">
<t t-foreach="slide_promoted.tag_ids" t-as="tag">
<a t-att-href="'/slides/%s/tag/%s' % (slug(slide_promoted.channel_id), slug(tag))" class="badge badge-light" t-esc="tag.name"/>
</t>
</div>
<div class="o_wslides_desc_truncate_10 mt-3" t-field="slide_promoted.description"/>
</div>
</div>
</div>
</div>
</template>
<template id="course_slides_cards" name="Documentation Course content: cards / categories">
<div class="o_wslides_lesson_nav mb-4 border-bottom">
<div class="container">
@@ -549,35 +581,15 @@
t-att-data-can-publish="channel.can_publish">
<i class="fa fa-cloud-upload mr-1"/>Upload new content
</a>
<a class="btn btn-secondary py-1 o_wslides_js_slide_section_add"
title="Add Section" role="button"
aria-label="Add Section" href="#"
t-att-channel_id="channel.id">
<i class="fa fa-folder-o mr-1"/>Add a section
</a>
</div>
<!-- Featured lesson -->
<div t-if="not search and not search_slide_type and slide_promoted" class="container py-1 mb-2">
<div class="card flex-column flex-lg-row">
<t t-set="image_url" t-value="website.image_url(slide_promoted, 'image_1024')"/>
<a t-if="slide_promoted.is_preview or channel.is_member or is_slides_publisher"
t-attf-href="/slides/slide/#{slug(slide_promoted)}#{query_string}" class="w-100 w-lg-50 flex-shrink-0 rounded">
<div t-attf-style="background-image:url(#{image_url}); background-size: cover; background-position:center; padding-bottom: 35%;" class="h-lg-100"/>
</a>
<div t-else="" class="w-100 w-lg-50 flex-shrink-0 rounded">
<div t-attf-style="background-image:url(#{image_url}); background-size: cover; background-position:center; padding-bottom: 35%;" class="h-lg-100"/>
</div>
<div class="card-body">
<a t-if="slide_promoted.is_preview or channel.is_member or is_slides_publisher"
t-attf-href="/slides/slide/#{slug(slide_promoted)}#{query_string}"
class="h4 d-block" t-att-title="slide_promoted.name" t-field="slide_promoted.name"/>
<h4 t-else="" class="text-muted" t-field="slide_promoted.name"/>
<div t-if="slide_promoted.tag_ids" class="border-top mt-2 pt-1">
<t t-foreach="slide_promoted.tag_ids" t-as="tag">
<a t-att-href="'/slides/%s/tag/%s' % (slug(slide_promoted.channel_id), slug(tag))" class="badge badge-light" t-esc="tag.name"/>
</t>
</div>
<div class="o_wslides_desc_truncate_10 mt-3" t-field="slide_promoted.description"/>
</div>
</div>
</div>
<t t-call="website_slides.course_promoted_slide"/>
<div class="container py-2">
<t t-if="search">
@@ -592,11 +604,14 @@
<t t-foreach="category_data" t-as="category">
<div class="mb-2" t-if="(category['slides'] or channel.can_publish) and (search_category and search_category.id == category['id'] or not search_category)">
<div class="d-flex align-items-center justify-content-between border-bottom pb-2 mb-3" t-if="category['name'] != 'Uncategorized'">
<t t-set="is_empty_editable" t-value="not category['slides'] and channel.can_publish"/>
<t t-set="is_empty_editable" t-value="not category['slides'] and channel.can_publish"/>
<div class="d-flex align-items-center justify-content-between border-bottom pb-2 mb-3" t-if="category['id'] and query_string != '?search_uncategorized=1'">
<h5 t-attf-class="m-0 #{'text-muted' if is_empty_editable else ''}"><t t-esc="category['name']"/></h5>
<a t-if="category['id'] and not is_empty_editable" t-att-href="'/slides/%s/category/%s' % (slug(channel), category['slug_name'])">View all</a>
<a t-elif="not is_empty_editable" t-att-href="'/slides/%s?uncategorized=1' % (slug(channel))">View all</a>
</div>
<div class="d-flex align-items-center justify-content-between border-bottom pb-2 mb-3" t-if="not category['id'] and len(category['slides']) > 0">
<h5 t-if="len(category_data) > 1" t-attf-class="m-0 #{'text-muted' if is_empty_editable else ''}"><t t-esc="category['name']"/></h5>
<a t-att-href="'/slides/%s?uncategorized=1' % (slug(channel))">View all</a>
</div>
<div class="row mx-n2">
<t t-foreach="category['slides']" t-as="slide">
@@ -609,14 +624,8 @@
<div class="row">
<div class="col" t-field="channel.description_html"/>
</div>
<t t-if="search_category">
<div class="form-inline justify-content-center">
<t t-call="website_profile.pager_nobox"></t>
</div>
</t>
</div>
<t t-if="search_category">
<t t-if="search_category or search_uncategorized">
<div class="form-inline justify-content-center pb-5">
<t t-call="website_profile.pager_nobox"></t>
</div>
@@ -694,4 +703,10 @@
<i t-if="slide.slide_type == 'quiz'" t-att-class="'fa fa-question-circle %s' % icon_class"></i>
</template>
<template name="Display Promoted Slide" id="display_promoted_slide" inherit_id="website_slides.course_promoted_slide" active="True" customize_show="True">
<xpath expr="//div[hasclass('o_wslides_promoted_slide')]" position="attributes">
<attribute name="class">o_wslides_promoted_slide</attribute>
</xpath>
</template>
</data></odoo>