chore: update Theme Alan version to 18.0.1.0, refactor RPC service usage across components, and enhance header/footer snippet configurations

This commit is contained in:
hoangvv
2026-08-14 10:52:51 +07:00
parent 49226d0343
commit 62ca567ea4
19 changed files with 58 additions and 39 deletions
+2 -1
View File
@@ -2,7 +2,7 @@
{ {
'name': "Theme Alan", 'name': "Theme Alan",
'category': 'Theme/eCommerce', 'category': 'Theme/eCommerce',
'version': '1.0', 'version': '18.0.1.0',
'license': 'OPL-1', 'license': 'OPL-1',
'author': 'Atharva System', 'author': 'Atharva System',
'support': 'support@atharvasystem.com', 'support': 'support@atharvasystem.com',
@@ -90,4 +90,5 @@
'currency': 'EUR', 'currency': 'EUR',
'images': ['static/description/alan_description.jpg','static/description/alan_screenshot.gif'], 'images': ['static/description/alan_description.jpg','static/description/alan_screenshot.gif'],
'application': False, 'application': False,
'installable': True,
} }
+1 -2
View File
@@ -17,7 +17,6 @@ from odoo.addons.auth_signup.models.res_users import SignupError
from odoo.addons.website_sale.controllers.main import WebsiteSale, TableCompute from odoo.addons.website_sale.controllers.main import WebsiteSale, TableCompute
from odoo.addons.website_sale.controllers.variant import WebsiteSaleVariantController from odoo.addons.website_sale.controllers.variant import WebsiteSaleVariantController
from odoo.addons.website.controllers.main import Website from odoo.addons.website.controllers.main import Website
from odoo.addons.http_routing.models.ir_http import slug
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@@ -108,7 +107,7 @@ class WebsiteSaleAlanShop(WebsiteSale):
res = super(WebsiteSaleAlanShop, self).shop(page, category, search, min_price, max_price, ppg, **post) res = super(WebsiteSaleAlanShop, self).shop(page, category, search, min_price, max_price, ppg, **post)
url = '/shop' url = '/shop'
if category: if category:
url = "/shop/category/%s" % slug(category) url = "/shop/category/%s" % request.env['ir.http']._slug(category)
as_search_prds = res.qcontext['search_product'] as_search_prds = res.qcontext['search_product']
# Load More # Load More
if request.website.active_load_more: if request.website.active_load_more:
@@ -5,6 +5,7 @@ import { useService } from '@web/core/utils/hooks';
import { Dialog } from "@web/core/dialog/dialog"; import { Dialog } from "@web/core/dialog/dialog";
import { _t } from '@web/core/l10n/translation'; import { _t } from '@web/core/l10n/translation';
import { rpc } from "@web/core/network/rpc";
const { Component, onWillStart } = owl; const { Component, onWillStart } = owl;
class AlanConfigDialog extends Dialog {} class AlanConfigDialog extends Dialog {}
@@ -19,7 +20,7 @@ AlanConfigDialog.defaultProps = {
class AlanConfiguration extends Component { class AlanConfiguration extends Component {
setup(){ setup(){
this.rpc = useService("rpc"); this.rpc = rpc;
onWillStart(this._fetch_configuration); onWillStart(this._fetch_configuration);
} }
@@ -5,12 +5,13 @@ import { SnippetBox } from 'theme_alan.SnippetBox';
import { useService } from "@web/core/utils/hooks"; import { useService } from "@web/core/utils/hooks";
import { UserInformDialog } from "theme_alan.UserInformDialog" import { UserInformDialog } from "theme_alan.UserInformDialog"
import { rpc } from "@web/core/network/rpc";
const { Component, onMounted } = owl; const { Component, onMounted } = owl;
class FrameData extends Component { class FrameData extends Component {
setup(){ setup(){
this.dialog = useService("dialog"); this.dialog = useService("dialog");
this._rpc = useService("rpc"); this._rpc = rpc;
onMounted(() => { onMounted(() => {
/** Mount the frame */ /** Mount the frame */
if(this.env.SnippetBuilder.PreviewframeTemplate != false){ if(this.env.SnippetBuilder.PreviewframeTemplate != false){
@@ -1,7 +1,7 @@
/** @odoo-module alias=theme_alan.FrameMaker **/ /** @odoo-module alias=theme_alan.FrameMaker **/
import { useService } from "@web/core/utils/hooks";
import { rpc } from "@web/core/network/rpc";
const { Component, useState, useSubEnv, onMounted, onWillStart } = owl; const { Component, useState, useSubEnv, onMounted, onWillStart } = owl;
class FrameOption extends Component { class FrameOption extends Component {
@@ -161,7 +161,7 @@ class DefaultFrame extends Component {
/** shows all the alan default and custom frame */ /** shows all the alan default and custom frame */
setup(){ setup(){
this.rpc = useService("rpc"); this.rpc = rpc;
onWillStart(async()=>{ onWillStart(async()=>{
this.data = await this.rpc('/get_default_frame'); this.data = await this.rpc('/get_default_frame');
}) })
@@ -1,14 +1,14 @@
/** @odoo-module alias=theme_alan.FramePreview **/ /** @odoo-module alias=theme_alan.FramePreview **/
import { useService } from "@web/core/utils/hooks";
import { alanTemplate } from "theme_alan.mixins"; import { alanTemplate } from "theme_alan.mixins";
import { rpc } from "@web/core/network/rpc";
const { Component, onMounted } = owl; const { Component, onMounted } = owl;
class FramePreview extends Component { class FramePreview extends Component {
setup(){ setup(){
/** setup method */ /** setup method */
this.rpc = useService("rpc"); this.rpc = rpc;
onMounted(async ()=>{ onMounted(async ()=>{
let $preview_template = await this.env.SnippetBuilder._getPreviewframeTemplate(false) let $preview_template = await this.env.SnippetBuilder._getPreviewframeTemplate(false)
$(this.__owl__.bdom.parentEl).find(".as-preview-section").empty().append($preview_template); $(this.__owl__.bdom.parentEl).find(".as-preview-section").empty().append($preview_template);
@@ -5,6 +5,7 @@ import { _t } from "@web/core/l10n/translation";
import { useService } from "@web/core/utils/hooks"; import { useService } from "@web/core/utils/hooks";
import { UserInformDialog } from 'theme_alan.UserInformDialog'; import { UserInformDialog } from 'theme_alan.UserInformDialog';
import { rpc } from "@web/core/network/rpc";
const { Component, useState, onMounted } = owl; const { Component, useState, onMounted } = owl;
class SelectData extends Component { class SelectData extends Component {
@@ -12,7 +13,7 @@ class SelectData extends Component {
// Initlized data of snippets.... // Initlized data of snippets....
this.dialog = useService("dialog"); this.dialog = useService("dialog");
this.state = useState({'record_info':[], 'record_ids':[]}) this.state = useState({'record_info':[], 'record_ids':[]})
this.rpc = useService("rpc"); this.rpc = rpc;
this.design_editor = useState(this.props.design_and_edit); this.design_editor = useState(this.props.design_and_edit);
this.bindedSortable = []; this.bindedSortable = [];
@@ -1,6 +1,7 @@
/** @odoo-module alias=theme_alan.SnippetBuilder **/ /** @odoo-module alias=theme_alan.SnippetBuilder **/
import { useService } from "@web/core/utils/hooks"; import { useService } from "@web/core/utils/hooks";
import { rpc } from "@web/core/network/rpc";
// import { useWowlService } from '@web/legacy/utils'; // import { useWowlService } from '@web/legacy/utils';
import { Dialog } from "@web/core/dialog/dialog"; import { Dialog } from "@web/core/dialog/dialog";
import { FrameMaker } from "theme_alan.FrameMaker"; import { FrameMaker } from "theme_alan.FrameMaker";
@@ -22,7 +23,7 @@ class SnippetBuilder extends Component {
setup() { setup() {
/** setup method */ /** setup method */
this.rpc = useService("rpc"); this.rpc = rpc;
useSubEnv({'SnippetBuilder':this}); useSubEnv({'SnippetBuilder':this});
onWillStart(this.initlized); onWillStart(this.initlized);
this.state = useState({ active_component: this._get_state() }); this.state = useState({ active_component: this._get_state() });
@@ -3,6 +3,7 @@
import publicWidget from "@web/legacy/js/public/public_widget"; import publicWidget from "@web/legacy/js/public/public_widget";
import VariantMixin from "@website_sale/js/variant_mixin"; import VariantMixin from "@website_sale/js/variant_mixin";
import wSaleUtils from "@website_sale/js/website_sale_utils"; import wSaleUtils from "@website_sale/js/website_sale_utils";
import { rpc } from "@web/core/network/rpc";
const cartHandlerMixin = wSaleUtils.cartHandlerMixin; const cartHandlerMixin = wSaleUtils.cartHandlerMixin;
publicWidget.registry.MegaMenuTabsSnippets = publicWidget.Widget.extend({ publicWidget.registry.MegaMenuTabsSnippets = publicWidget.Widget.extend({
@@ -39,7 +40,7 @@ publicWidget.registry.MegaMenuSnippets = publicWidget.Widget.extend({
}, },
init: function () { init: function () {
this._super.apply(this, arguments); this._super.apply(this, arguments);
this.rpc = this.bindService("rpc"); this.rpc = rpc;
}, },
_showMegaMenu: async function(ev){ _showMegaMenu: async function(ev){
if(!this.is_clicked && !this.editableMode){ if(!this.is_clicked && !this.editableMode){
@@ -75,7 +76,7 @@ publicWidget.registry.MegaMenuSnippets = publicWidget.Widget.extend({
let AlanSliders = publicWidget.Widget.extend({ let AlanSliders = publicWidget.Widget.extend({
init: function () { init: function () {
this._super.apply(this, arguments); this._super.apply(this, arguments);
this.rpc = this.bindService("rpc"); this.rpc = rpc;
}, },
_getProductSlider:function(){ _getProductSlider:function(){
for (const product_slider of this.$target) { for (const product_slider of this.$target) {
@@ -174,7 +175,7 @@ publicWidget.registry.AlanAddCart = publicWidget.Widget.extend(cartHandlerMixin,
}, },
init: function () { init: function () {
this._super.apply(this, arguments); this._super.apply(this, arguments);
this.rpc = this.bindService("rpc"); this.rpc = rpc;
}, },
_addToCart:function(ev){ _addToCart:function(ev){
ev.preventDefault(); ev.preventDefault();
@@ -3,6 +3,7 @@
import Dialog from '@web/legacy/js/core/dialog'; import Dialog from '@web/legacy/js/core/dialog';
import publicWidget from "@web/legacy/js/public/public_widget"; import publicWidget from "@web/legacy/js/public/public_widget";
import { rpc } from "@web/core/network/rpc";
export const ProductDetailInfo = publicWidget.Widget.extend({ export const ProductDetailInfo = publicWidget.Widget.extend({
selector:".as-product-detail", selector:".as-product-detail",
events:{ events:{
@@ -13,7 +14,7 @@ export const ProductDetailInfo = publicWidget.Widget.extend({
}, },
init: function () { init: function () {
this._super.apply(this, arguments); this._super.apply(this, arguments);
this.rpc = this.bindService("rpc"); this.rpc = rpc;
}, },
start: function () { start: function () {
new Swiper(".as-al-ass-swiper", { new Swiper(".as-al-ass-swiper", {
@@ -121,7 +122,7 @@ let AlanAdvanceInfo = Dialog.extend({
renderHeader: false, renderHeader: false,
renderFooter: false, renderFooter: false,
}); });
this.rpc = this.bindService("rpc"); this.rpc = rpc;
}, },
willStart: async function () { willStart: async function () {
var template = this.rpc('/get_advance_info', { advance_info_id: this.advance_info_id }); var template = this.rpc('/get_advance_info', { advance_info_id: this.advance_info_id });
@@ -7,10 +7,12 @@ import '@website_sale_wishlist/js/website_sale_wishlist';
import '@website_sale_comparison/js/website_sale_comparison'; import '@website_sale_comparison/js/website_sale_comparison';
import { _t } from '@web/core/l10n/translation'; import { _t } from '@web/core/l10n/translation';
import { debounce } from "@web/core/utils/timing"; import { debounce } from "@web/core/utils/timing";
const { DateTime } = luxon; import { rpc } from "@web/core/network/rpc";
import { deserializeDateTime, formatDateTime } from "@web/core/l10n/dates"; import { deserializeDateTime, formatDateTime } from "@web/core/l10n/dates";
import VariantMixin from "@website_sale/js/variant_mixin"; import VariantMixin from "@website_sale/js/variant_mixin";
const { DateTime } = luxon;
// Color Variant Icon >--------------------------------- // Color Variant Icon >---------------------------------
const ColorVariantDetails = Dialog.extend({ const ColorVariantDetails = Dialog.extend({
init(ele, otps) { init(ele, otps) {
@@ -23,7 +25,7 @@ const ColorVariantDetails = Dialog.extend({
renderHeader: true, renderHeader: true,
renderFooter: false, renderFooter: false,
}); });
this.rpc = this.bindService("rpc"); this.rpc = rpc;
}, },
willStart: async function () { willStart: async function () {
var template = this.rpc('/get_color_product', { product_id: this.product_id }); var template = this.rpc('/get_color_product', { product_id: this.product_id });
@@ -74,7 +76,7 @@ const AlanSimilarProduct = Dialog.extend({
renderHeader: false, renderHeader: false,
renderFooter: false, renderFooter: false,
}); });
this.rpc = this.bindService("rpc"); this.rpc = rpc;
}, },
willStart: async function () { willStart: async function () {
var template = this.rpc('/get_similar_product', { product_id: this.product_id }); var template = this.rpc('/get_similar_product', { product_id: this.product_id });
@@ -140,7 +142,7 @@ let LoginPopup = Dialog.extend({
renderHeader: false, renderHeader: false,
renderFooter: false, renderFooter: false,
}, otps); }, otps);
this.rpc = this.bindService("rpc"); this.rpc = rpc;
}, },
willStart: async function(){ willStart: async function(){
var template = this.rpc('/get_login_popup', {'test':'test'}); var template = this.rpc('/get_login_popup', {'test':'test'});
@@ -230,7 +232,7 @@ const AlanQuickView = Dialog.extend({
renderHeader: false, renderHeader: false,
renderFooter: false, renderFooter: false,
}); });
this.rpc = this.bindService("rpc"); this.rpc = rpc;
}, },
QuickViewLOad:function(){ QuickViewLOad:function(){
var self = this var self = this
@@ -275,7 +277,7 @@ export const AjaxProductLoad = publicWidget.Widget.extend({
init: function () { init: function () {
this._super.apply(this, arguments); this._super.apply(this, arguments);
this.rpc = this.bindService("rpc"); this.rpc = rpc;
}, },
InitLoadProducts:function(){ InitLoadProducts:function(){
@@ -561,7 +563,7 @@ const AlanMiniCartProduct = Dialog.extend({
renderHeader: false, renderHeader: false,
renderFooter: false, renderFooter: false,
}); });
this.rpc = this.bindService("rpc"); this.rpc = rpc;
this._changeCartQuantity = debounce(this._changeCartQuantity.bind(this), 500); this._changeCartQuantity = debounce(this._changeCartQuantity.bind(this), 500);
}, },
willStart: async function () { willStart: async function () {
@@ -1,14 +1,14 @@
/** @odoo-module alias=theme_alan.BestSellingProduct **/ /** @odoo-module alias=theme_alan.BestSellingProduct **/
import { useService } from "@web/core/utils/hooks";
import { SelectData } from "theme_alan.SelectData"; import { SelectData } from "theme_alan.SelectData";
import { rpc } from "@web/core/network/rpc";
const { Component, useSubEnv, onWillStart } = owl; const { Component, useSubEnv, onWillStart } = owl;
class BestSellingProduct extends Component { class BestSellingProduct extends Component {
setup(){ setup(){
/** Setup Method */ /** Setup Method */
this._rpc = useService("rpc"); this._rpc = rpc;
onWillStart(this._get_best_selling_product) onWillStart(this._get_best_selling_product)
// Required to go back // Required to go back
@@ -1,14 +1,14 @@
/** @odoo-module alias=theme_alan.LatestProduct **/ /** @odoo-module alias=theme_alan.LatestProduct **/
import { useService } from "@web/core/utils/hooks";
import { SelectData } from "theme_alan.SelectData"; import { SelectData } from "theme_alan.SelectData";
import { rpc } from "@web/core/network/rpc";
const { Component, useSubEnv, onWillStart } = owl; const { Component, useSubEnv, onWillStart } = owl;
class LatestProduct extends Component { class LatestProduct extends Component {
setup(){ setup(){
/** Setup Method */ /** Setup Method */
this._rpc = useService("rpc"); this._rpc = rpc;
onWillStart(this._get_latest_product) onWillStart(this._get_latest_product)
// Required to go back // Required to go back
@@ -4,11 +4,12 @@ import publicWidget from "@web/legacy/js/public/public_widget";
import { renderToElement } from "@web/core/utils/render"; import { renderToElement } from "@web/core/utils/render";
import Dialog from '@web/legacy/js/core/dialog'; import Dialog from '@web/legacy/js/core/dialog';
import { rpc } from "@web/core/network/rpc";
export const ImgHotSpot = publicWidget.Widget.extend({ export const ImgHotSpot = publicWidget.Widget.extend({
selector:'.hotspot', selector:'.hotspot',
init: function () { init: function () {
this._super.apply(this, arguments); this._super.apply(this, arguments);
this.rpc = this.bindService("rpc"); this.rpc = rpc;
}, },
start:function(ev){ start:function(ev){
@@ -6,6 +6,7 @@ import { renderToElement } from "@web/core/utils/render";
import Dialog from '@web/legacy/js/core/dialog'; import Dialog from '@web/legacy/js/core/dialog';
import { loadLanguages,_t } from "@web/core/l10n/translation"; import { loadLanguages,_t } from "@web/core/l10n/translation";
import { rpc } from "@web/core/network/rpc";
var popoverShow = false; var popoverShow = false;
options.SnippetOptionWidget.include({ options.SnippetOptionWidget.include({
@@ -58,7 +59,7 @@ options.registry.img_hotspots_slider_actions = options.Class.extend({
}, },
init: function () { init: function () {
this._super.apply(this, arguments); this._super.apply(this, arguments);
this.rpc = this.bindService("rpc"); this.rpc = rpc;
}, },
_set_hotspot_translation : async function(ev){ _set_hotspot_translation : async function(ev){
var cr = this; var cr = this;
@@ -5,6 +5,7 @@ import { alanTemplate } from "theme_alan.mixins";
import { useService } from "@web/core/utils/hooks"; import { useService } from "@web/core/utils/hooks";
import { SelectData } from "theme_alan.SelectData"; import { SelectData } from "theme_alan.SelectData";
import { rpc } from "@web/core/network/rpc";
const { Component, useSubEnv, onMounted, useState } = owl; const { Component, useSubEnv, onMounted, useState } = owl;
class SubCategory extends Component { class SubCategory extends Component {
@@ -14,7 +15,7 @@ class SubCategory extends Component {
this.header = true; this.header = true;
this.search = "product.public.category" this.search = "product.public.category"
this.props.selected_cat = []; this.props.selected_cat = [];
this.rpc = useService("rpc"); this.rpc = rpc;
onMounted(this._select2); onMounted(this._select2);
} }
@@ -94,7 +95,7 @@ class MegaMenuCategory extends Component {
this.subCategory = useState({'second_level':[],'second_level_ids':[]}); this.subCategory = useState({'second_level':[],'second_level_ids':[]});
// dialog subcategory // dialog subcategory
this.dialog = useService("dialog"); this.dialog = useService("dialog");
this.rpc = useService("rpc"); this.rpc = rpc;
// Search // Search
this.props.search = "product.public.category"; this.props.search = "product.public.category";
// Quick Search Option // Quick Search Option
+2 -2
View File
@@ -3,7 +3,7 @@
<!-- Header options --> <!-- Header options -->
<template id="as_header_switches" inherit_id="website.snippet_options"> <template id="as_header_switches" inherit_id="website.snippet_options">
<xpath expr="//div/we-select[@data-variable='header-template']" position="inside"> <xpath expr="//we-select[@data-variable='header-template']/we-button[last()]" position="after">
<we-button title="Alan: Header 1" <we-button title="Alan: Header 1"
data-name="as_header_opt1" data-name="as_header_opt1"
data-customize-website-views="theme_alan.as_header_1" data-customize-website-views="theme_alan.as_header_1"
@@ -76,7 +76,7 @@
<!-- Footer Options --> <!-- Footer Options -->
<template id="alan_footer_switches" inherit_id="website.snippet_options"> <template id="alan_footer_switches" inherit_id="website.snippet_options">
<xpath expr="//div/we-select[@data-variable='footer-template']" position="inside"> <xpath expr="//we-select[@data-variable='footer-template']/we-button[last()]" position="after">
<we-button title="Alan: Footer 1" <we-button title="Alan: Footer 1"
data-customize-website-views="theme_alan.alan_footer_1" data-customize-website-views="theme_alan.alan_footer_1"
data-customize-website-variable="'alan_footer1'" data-customize-website-variable="'alan_footer1'"
+4 -3
View File
@@ -19,10 +19,11 @@
</template> </template>
<template id="snippets" name="template_name" inherit_id="website.snippets"> <template id="snippets" name="template_name" inherit_id="website.snippets">
<xpath expr="//div[@id='snippet_effect']/div[hasclass('o_panel_body')]/t" position="before"> <xpath expr="//snippets[@id='snippet_structure']" position="inside">
<t t-snippet="theme_alan.s_alan_dynamic_snippets" <t t-snippet="theme_alan.s_alan_dynamic_snippets"
t-thumbnail="/theme_alan/static/src/img/snippets/alan-dynamic.svg" group="theme_alan"
/> string="Alan Dynamic Snippets"
t-thumbnail="/theme_alan/static/src/img/snippets/alan-dynamic.svg"/>
</xpath> </xpath>
</template> </template>
</odoo> </odoo>
@@ -33,10 +33,17 @@
</xpath> </xpath>
</template> </template>
<!-- Alan Builder Snippet Thumbnail --> <!-- Alan Builder Snippet Thumbnail (Odoo 18 snippet groups) -->
<template id="alan_websiite_builder" name="Website builder" inherit_id="website.snippets"> <template id="alan_websiite_builder" name="Website builder" inherit_id="website.snippets">
<xpath expr="//div[@id='snippet_structure']/div[hasclass('o_panel_body')]" position="inside"> <xpath expr="//snippets[@id='snippet_groups']/t[@id='installed_snippets_hook']" position="before">
<t t-snippet="theme_alan.website_builder" t-thumbnail="/theme_alan/static/src/img/snippets/alan-builder.svg"/> <t snippet-group="theme_alan" t-snippet="website.s_snippet_group" string="Alan"
t-thumbnail="/theme_alan/static/src/img/snippets/alan-builder.svg"/>
</xpath>
<xpath expr="//snippets[@id='snippet_structure']" position="inside">
<t t-snippet="theme_alan.website_builder"
group="theme_alan"
string="Alan Website Builder"
t-thumbnail="/theme_alan/static/src/img/snippets/alan-builder.svg"/>
</xpath> </xpath>
</template> </template>
</odoo> </odoo>