19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:32:12 +01:00
parent 79f83631d5
commit 73afc09215
6267 changed files with 1534193 additions and 1130106 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View file

@ -1 +0,0 @@
<?xml version="1.0" ?><svg id="solid" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><title/><path d="M407.951,343.116a7.2,7.2,0,0,1,.048.733c.121,13.4-15.891,29.5-41.725,41.981C345.344,395.944,309.222,408,256,408s-89.344-12.056-110.274-22.17C119.892,373.348,103.88,357.246,104,343.849a7.2,7.2,0,0,1,.048-.733L115.1,243.624a7,7,0,0,1,9.82-5.615L242.911,290.9a32.043,32.043,0,0,0,26.179,0l117.986-52.89a7,7,0,0,1,9.82,5.615ZM474.988,153.4l-205.9-92.3a32.037,32.037,0,0,0-26.179,0l-205.9,92.3a16,16,0,0,0,0,29.2l205.9,92.3a32.043,32.043,0,0,0,26.179,0L440,198.284v59.874A15.98,15.98,0,0,0,432,272V376h32V272a15.98,15.98,0,0,0-8-13.842V191.111l18.987-8.511a16,16,0,0,0,0-29.2Z" style="fill:#3b3b3b"/></svg>

Before

Width:  |  Height:  |  Size: 713 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 753 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Before After
Before After

View file

@ -1,8 +1,6 @@
odoo.define('website_sale_slides.course.join.widget', function (require) {
"use strict";
import CourseJoin from "@website_slides/js/slides_course_join";
var CourseJoinWidget = require('@website_slides/js/slides_course_join')[Symbol.for("default")].courseJoinWidget;
const wUtils = require('website.utils');
const CourseJoinWidget = CourseJoin.courseJoinWidget;
CourseJoinWidget.include({
init: function (parent, options) {
@ -28,10 +26,18 @@ CourseJoinWidget.include({
if (this.channel.channelEnroll === 'payment' && !this.publicUser) {
const self = this;
this.beforeJoin().then(function () {
wUtils.sendRequest('/shop/cart/update', {
product_id: self.productId,
express: 1,
});
self.call('cart', 'add',
{
// TODO VCR Ensure productTemplateId is always provided to `addToCart`.
// Currently, this works because the product configurator check is bypassed
// when the `isBuyNow` option is `True`.
productTemplateId: false,
productId: self.productId,
},
{
isBuyNow: true,
},
);
});
} else {
this._super.apply(this, arguments);
@ -39,6 +45,4 @@ CourseJoinWidget.include({
},
});
return CourseJoinWidget;
});
export default CourseJoinWidget;

View file

@ -1,11 +1,8 @@
odoo.define('website_sale_slides.quiz', function (require) {
"use strict";
const {websiteSlidesQuizNoFullscreen} = require('@website_slides/js/slides_course_quiz');
import {websiteSlidesQuizNoFullscreen} from "@website_slides/js/slides_course_quiz";
websiteSlidesQuizNoFullscreen.include({
_extractChannelData: function (slideData) {
return _.extend({}, this._super.apply(this, arguments), {
return Object.assign({}, this._super.apply(this, arguments), {
productId: slideData.productId,
enroll: slideData.enroll,
currencyName: slideData.currencyName,
@ -15,4 +12,3 @@ websiteSlidesQuizNoFullscreen.include({
});
}
});
});

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="website_sales_slides.CoursePageOption">
<BuilderRow label.translate="Buy Now Button">
<BuilderCheckbox action="'websiteConfig'" actionParam="{views: ['website_sale_slides.course_option_buy_course_now']}"/>
</BuilderRow>
</t>
</templates>

View file

@ -0,0 +1,21 @@
import { BaseOptionComponent } from "@html_builder/core/utils";
import { Plugin } from "@html_editor/plugin";
import { _t } from "@web/core/l10n/translation";
import { registry } from "@web/core/registry";
export class CoursePageOption extends BaseOptionComponent {
static template = "website_sales_slides.CoursePageOption";
static selector = "main:has(.o_wslides_course_header)";
static title = _t("Course Page");
static groups = ["website.group_website_designer"];
static editableOnly = false;
}
class CoursePageOptionPlugin extends Plugin {
static id = "coursePageOption";
resources = {
builder_options: [CoursePageOption],
};
}
registry.category("website-plugins").add(CoursePageOptionPlugin.id, CoursePageOptionPlugin);

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-extend="slide.course.join">
<t t-jquery=".o_wslides_js_course_join_link" t-operation="append">
<t t-inherit="slide.course.join" t-inherit-mode="extension">
<xpath expr="//*[hasclass('o_wslides_js_course_join_link')]" position="inside">
<t t-if="widget.channel.channelEnroll == 'payment'">
<t t-if="widget.publicUser">
Sign in
@ -10,6 +10,6 @@
Buy this Course
</t>
</t>
</t>
</xpath>
</t>
</templates>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-extend="slide.slide.quiz.validation">
<t t-jquery=".o_wslides_quiz_join_course_message" t-operation="append">
<t t-inherit="slide.slide.quiz.validation" t-inherit-mode="extension">
<xpath expr="//*[hasclass('o_wslides_quiz_join_course_message')]" position="inside">
<span t-if="widget.channel.channelEnroll == 'payment'">
<t t-if="widget.publicUser">
Sign in and buy the course to take the quiz
@ -10,6 +10,6 @@
Buy the course to validate your answers!
</t>
</span>
</t>
</xpath>
</t>
</templates>

View file

@ -1,16 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-extend="slides.course.unsubscribe.modal.leave">
<t t-jquery="p:last" t-operation="after">
<t t-if="widget.enroll === 'payment'">
<p class="alert alert-warning">
<i class="fa fa-exclamation-triangle fa-3x float-start me-3"></i>
This course is paid.<br/>
Leaving the course and re-enrolling afterwards means that you'll be charged again.
<t t-inherit="website_slides.SlideUnsubscribeDialog" t-inherit-mode="extension">
<xpath expr="//t[@t-if=&quot;state.mode === 'leave'&quot;] //p[last()]" position="after">
<t t-if="props.enroll === 'payment'">
<p class="d-flex align-items-center gap-3 alert alert-warning mb-0">
<i class="fa fa-exclamation-triangle fa-3x"></i>
<div>
This course is paid.<br/>
Leaving the course and re-enrolling afterwards means that you'll be charged again.
</div>
</p>
</t>
</t>
</xpath>
</t>
</templates>

View file

@ -0,0 +1,41 @@
import { registry } from "@web/core/registry";
registry.category("web_tour.tours").add("invited_on_payment_course_logged", {
steps: () => [
{
trigger: 'a:contains("Add to Cart")',
content: "Check that the course can be bought but not joined",
run: function () {
if (document.querySelector(".o_wslides_js_course_join_link")) {
console.error("The course should not be joinable before buying");
}
},
},
// Chatter is lazy loading. Wait for it.
{
trigger: "a[id=review-tab]",
run: "click",
},
{
content: "Wait for the whole page to load",
trigger: "#chatterRoot:shadow .o-mail-Chatter",
},
{
trigger: "a[id=home-tab]",
run: "click",
},
{
trigger: '.o_wslides_slides_list_slide:contains("Home Gardening")',
content: "Check that non-preview slides are not accessible",
run: function () {
if (this.anchor.querySelector(".o_wslides_js_slides_list_slide_link")) {
console.error("Invited attendee should not access non-preview slides");
}
},
},
{
trigger: 'a:contains("Gardening: The Know-How")',
content: "Check that preview slides are accessible",
},
],
});

View file

@ -0,0 +1,58 @@
import { registry } from "@web/core/registry";
registry.category("web_tour.tours").add("invited_on_payment_course_public", {
steps: () => [
{
content: "Check that there is an identification banner",
trigger: ".o_wslides_identification_banner a:contains(Log in)",
},
{
trigger: ".o_wslides_js_course_join:not(:has(#add_to_cart)) a:contains(Log in)",
},
{
trigger:
".o_wslides_slides_list_slide:contains(Gardening: The Know-How):not(:has(.o_wslides_js_slides_list_slide_link))",
},
{
isActive: ["body:has(.modal:not(.o_inactive_modal):contains(oops))"],
content: "Close Oops modal",
trigger: ".modal button:contains(close)",
run: "click",
},
{
trigger: ".o_wslides_identification_banner a.o_underline:contains(Log in)",
run: "click",
expectUnloadPage: true,
},
{
trigger: 'input[id="password"]',
run: "edit portal",
},
{
trigger: 'button:contains("Log in")',
run: "click",
expectUnloadPage: true,
},
{
trigger: "a:contains(Gardening: The Know-How)",
content: "Check that preview slides are now accessible",
},
// Chatter is lazy loading. Wait for it.
{
trigger: "a[id=review-tab]",
run: "click",
},
{
content: "Wait for the whole page to load",
trigger: "#chatterRoot:shadow .o-mail-Chatter",
},
{
trigger: "a[id=home-tab]",
run: "click",
},
{
trigger: '.o_wslides_js_course_join:contains("Add to Cart")',
content: "Check that the course can now be bought",
},
],
});