vanilla 17.0

This commit is contained in:
Ernad Husremovic 2025-10-08 10:47:08 +02:00
parent d72e748793
commit a9bcec8e91
1986 changed files with 1613876 additions and 568976 deletions

View file

@ -16,17 +16,16 @@
<field name="font" widget="selection" required="1"/>
<field name="logo" widget="image" options="{'size': [0, 50]}"/>
<label for="primary_color" string="Colors" />
<div class="o_document_layout_colors">
<field name="primary_color" widget="color"/>
<field name="secondary_color" widget="color"/>
<div class="o_custom_colors" title="Reset to logo colors"
attrs="{'invisible': [('custom_colors', '=', False)]}">
<span class="fa fa-refresh fa-2x"></span>
<field name="custom_colors" nolabel="1"/>
</div>
<div class="o_document_layout_colors d-flex align-items-end mb-4">
<field name="primary_color" widget="color" class="w-auto m-0 me-1"/>
<field name="secondary_color" widget="color" class="w-auto m-0"/>
<a class="o_custom_colors btn btn-secondary btn-sm position-relative ms-2" role="button" title="Reset to logo colors" invisible="not custom_colors">
<i class="fa fa-repeat"/> Reset
<field name="custom_colors" class="position-absolute top-0 start-0 w-100 h-100 opacity-0" nolabel="1"/>
</a>
</div>
<field name="layout_background" widget="selection" required="1"/>
<field name="layout_background_image" options="{'accepted_file_extensions': 'image/*'}" attrs="{'invisible': [('layout_background', '!=', 'Custom')], 'required': [('layout_background', '=', 'Custom')]}">Upload your file</field>
<field name="layout_background_image" options="{'accepted_file_extensions': 'image/*'}" invisible="layout_background != 'Custom'" required="layout_background == 'Custom'">Upload your file</field>
<field name="report_header" placeholder="e.g. Global Business Solutions" options="{'resizable': false}"/>
<field name="company_details" string="Company Details" options="{'resizable': false}"/>
<field name="report_footer" string="Footer" options="{'resizable': false}"/>
@ -34,19 +33,18 @@
</group>
<div>
<field name="preview" widget="iframe_wrapper" />
<button name="web.action_report_layout_preview" string="Download PDF Preview" type="action" class="oe_link" icon="fa-arrow-right"/>
<button name="web.action_report_layout_preview" string="Download PDF Preview" type="action" class="oe_link" icon="oi-arrow-right"/>
</div>
</group>
<footer>
<button string="Save" class="btn-primary" type="object" name="document_layout_save" data-hotkey="q"/>
<button special="cancel" data-hotkey="z" string="Cancel" />
<button special="cancel" data-hotkey="x" string="Cancel" />
</footer>
</form>
</field>
</record>
<record id="action_base_document_layout_configurator" model="ir.actions.act_window">
<field name="type">ir.actions.act_window</field>
<field name="name">Configure your document layout</field>
<field name="view_mode">form</field>
<field name="target">new</field>
@ -56,4 +54,3 @@
</data>
</odoo>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="assets_backend_legacy_lazy" name="Lazy assets for legacy Views" groups="base.group_user">
<t t-call-assets="web.assets_backend_legacy_lazy" />
</template>
</odoo>

View file

@ -11,7 +11,7 @@
display: block;
font-size: 16px;
{{ neutralize_banner_style or '' }}">
<t t-out="neutralize_banner_text">This database is neutralized.</t>
<t t-out="neutralize_banner_text">Database neutralized for testing: no emails sent, etc.</t>
</span>
</div>
</xpath>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record model="ir.actions.server" id="download_contact">
<field name="name">Download (vCard)</field>
<field name="model_id" ref="model_res_partner"/>
<field name="binding_model_id" ref="model_res_partner"/>
<field name="binding_view_types">form,list</field>
<field name="state">code</field>
<field name="code">
action = {
'type': 'ir.actions.act_url',
'url': '/web/partner/vcard?partner_ids=' + ','.join(map(str, records.ids)),
'target': 'download',
}
</field>
</record>
</odoo>

View file

@ -14,15 +14,17 @@
<meta charset="utf-8"/>
<meta name="viewport" content="initial-scale=1"/>
<title><t t-esc="title or 'Odoo Report'"/></title>
<t t-call-assets="web.report_assets_common" t-js="false"/>
<!--The following is kind of a hack-->
<!--in an iframe, we don't want the session to perform qweb_templates rpc-->
<t t-call-assets="web.report_assets_common"/>
<!-- Temporary code: only used to maintain CSS for legacy HTML reports (full width...) -->
<!-- Should be removed once the reports are fully converted. -->
<script type="text/javascript">
window.odoo = {};
window.odoo.__session_info__ = {is_report: true};
document.addEventListener('DOMContentLoaded', () => {
if (window.self !== window.top) {
document.body.classList.add("o_in_iframe", "container-fluid");
document.body.classList.remove("container");
}
});
</script>
<t t-call-assets="web.assets_common" t-css="false"/>
<t t-call-assets="web.report_assets_common" t-css="false"/>
</head>
<body t-att-class="'container' if not full_width else 'container-fluid'" t-att-dir="env['res.lang']._lang_get(lang or env.user.lang).direction or 'ltr'">
<div id="wrapwrap">
@ -47,7 +49,6 @@
<meta name="viewport" content="initial-scale=1"/>
<title><t t-esc="title or 'Odoo Report'"/></title>
<t t-call-assets="web.report_assets_common" t-js="false"/>
<t t-call-assets="web.assets_common" t-css="false"/>
<style>
<t t-out="preview_css"/>
@ -145,7 +146,7 @@
<th name="th_description" class="text-start"><span>Description</span></th>
<th name="th_quantity" class="text-end"><span>Quantity</span></th>
<th name="th_priceunit" class="text-end d-md-table-cell"><span>Unit Price</span></th>
<th name="th_taxes" class="text-start d-md-table-cell"><span>Taxes</span></th>
<th name="th_taxes" class="text-end d-md-table-cell"><span>Taxes</span></th>
<th name="th_subtotal" class="text-end">
<span>Amount</span>
</th>
@ -161,7 +162,7 @@
<td class="text-end d-md-table-cell">
<span class="text-nowrap">1,500.00</span>
</td>
<td class="text-start d-md-table-cell">
<td class="text-end d-md-table-cell">
<span id="line_tax_ids">Tax 15%</span>
</td>
<td class="text-end o_price_total">
@ -177,7 +178,7 @@
<td class="text-end d-md-table-cell">
<span class="text-nowrap">2,350.00</span>
</td>
<td class="text-start d-md-table-cell">
<td class="text-end d-md-table-cell">
<span id="line_tax_ids">Tax 15%</span>
</td>
<td class="text-end o_price_total">
@ -186,9 +187,9 @@
</tr>
</tbody>
</table>
<div class="clearfix">
<div id="total" class="row">
<div class="col-6 ms-auto">
<div id="right-elements" t-attf-class="#{'col-5' if report_type != 'html' else 'col-12 col-md-5'} ms-5 d-inline-block float-end">
<div id="total" class="clearfix row">
<div class="ms-auto">
<table class="table table-sm table-borderless" style="page-break-inside: avoid; position:relative;">
<tbody><tr class="border-black o_subtotal" style="">
<td><strong>Untaxed Amount</strong></td>
@ -213,13 +214,16 @@
</div>
</div>
</div>
<p class="mt-4">
Please use the following communication for your payment : <b><span>
INV/2023/00003</span></b>
</p>
<p name="payment_term">
<span>Payment terms: 30 Days</span>
</p>
<div id="payment_term">
<div class="mb-3">
<p name="payment_term">
<span>Payment terms: 30 Days</span>
</p>
<p name="payment_communication">
Payment Communication: <b><span>INV/2023/00003</span></b>
</p>
</div>
</div>
</div>
</t>
</t>
@ -276,35 +280,58 @@
<template id="address_layout">
<t t-set="colclass" t-value="('col-sm-5' if report_type == 'html' else 'col-5') + ' ms-auto'"/>
<t t-if="address">
<div class="address row">
<t t-if="information_block">
<t t-set="colclass" t-value="'col-5 offset-1'"/>
<div name="information_block" class="col-6">
<t t-out="information_block"/>
<div t-if="address" class="address row " title="This block is not always present depending on the printed document.">
<t t-if="information_block">
<t t-set="colclass" t-value="'col-5 offset-1'"/>
<div name="information_block" class="col-6">
<t t-out="information_block or None">
<div class="bg-light border-1 rounded h-100 d-flex flex-column align-items-center justify-content-center p-4 opacity-75 text-muted text-center">
<strong>Information block</strong>
<div>Usually contains a source address or a complementary address.</div>
</div>
</t>
</div>
</t>
<div name="address" t-att-class="colclass">
<t t-esc="address or None">
<div class="bg-light border-1 rounded h-100 d-flex flex-column align-items-center justify-content-center p-4 opacity-75 text-muted text-center">
<strong>Address block</strong>
<div>Usually contains the address of the document's recipient.</div>
</div>
</t>
<div name="address" t-att-class="colclass">
<t t-esc="address"/>
</div>
</div>
</t>
</div>
<div class="oe_structure" t-else=""></div>
</template>
<template id="external_layout_striped">
<div t-attf-class="o_company_#{company.id}_layout header" t-att-style="report_header_style">
<div class="o_background_header">
<div class="float-end">
<div class="mt0 text-end h3" t-field="company.report_header"/>
<div class="mt0 text-end h3" t-if="company.report_header" t-field="company.report_header">Company tagline</div>
</div>
<img t-if="company.logo" t-att-src="image_data_uri(company.logo)" class="float-start" alt="Logo"/>
<div class="float-start company_address">
<ul class="list-unstyled">
<li t-if="company.is_company_details_empty"><t t-esc="company.partner_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}'/></li>
<li t-else=""><t t-esc="company.company_details"/></li>
<li t-if="forced_vat">
<t t-esc="company.country_id.vat_label or 'Tax ID'"/>:
<span t-esc="forced_vat"/>
<ul class="list-unstyled" name='company_address_list'>
<li t-if="company.is_company_details_empty"><span t-field="company.partner_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}'>
<div class="bg-light border-1 rounded h-100 d-flex flex-column align-items-center justify-content-center p-4 w-100 opacity-75 text-muted text-center">
<strong>Company address block</strong>
<div>Contains the company address.</div>
</div>
</span></li>
<li t-else="">
<span t-field="company.company_details">
<div class="bg-light border-1 rounded h-100 d-flex flex-column align-items-center justify-content-center p-4 w-100 opacity-75 text-muted text-center">
<strong>Company details block</strong>
<div>Contains the company details.</div>
</div>
</span>
</li>
<li t-if="not forced_vat"/>
<li t-else="">
<t t-esc="company.country_id.vat_label or 'Tax ID'">Tax ID</t>:
<span t-esc="forced_vat">US12345671</span>
</li>
</ul>
</div>
@ -331,7 +358,7 @@
<span class="topage"/>
</div>
<div t-if="report_type == 'pdf' and display_name_in_footer" class="text-muted">
<span t-field="o.name"/>
<span t-out="o.name">(document name)</span>
</div>
</div>
</div>
@ -349,12 +376,25 @@
<div class="mt0 h4" t-field="company.report_header"/>
</t>
<div name="company_address" class="float-end mb4">
<ul class="list-unstyled">
<li t-if="company.is_company_details_empty"><t t-esc="company.partner_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}'/></li>
<li t-else=""><t t-esc="company.company_details"/></li>
<li t-if="forced_vat">
<t t-esc="company.country_id.vat_label or 'Tax ID'"/>:
<span t-esc="forced_vat"/>
<ul class="list-unstyled" name="company_address_list">
<li t-if="company.is_company_details_empty"><span t-field="company.partner_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}'>
<div class="bg-light border-1 rounded h-100 d-flex flex-column align-items-center justify-content-center p-4 w-100 opacity-75 text-muted text-center">
<strong>Company address block</strong>
<div>Contains the company address.</div>
</div>
</span></li>
<li t-else="">
<span t-field="company.company_details">
<div class="bg-light border-1 rounded h-100 d-flex flex-column align-items-center justify-content-center p-4 w-100 opacity-75 text-muted text-center">
<strong>Company details block</strong>
<div>Contains the company details.</div>
</div>
</span>
</li>
<li t-if="not forced_vat"/>
<li t-else="">
<t t-esc="company.country_id.vat_label or 'Tax ID'">Tax ID</t>:
<span t-esc="forced_vat">US12345671</span>
</li>
</ul>
</div>
@ -375,12 +415,12 @@
<div t-attf-class="footer o_boxed_footer o_company_#{company.id}_layout">
<div class="text-center">
<div t-field="company.report_footer"/>
<div t-field="company.report_footer">Company Report Footer</div>
<div t-if="report_type == 'pdf'">
Page: <span class="page"/> / <span class="topage"/>
</div>
<div t-if="report_type == 'pdf' and display_name_in_footer" class="text-muted">
<span t-field="o.name"/>
<span t-out="o.name">(document name)</span>
</div>
</div>
</div>
@ -394,12 +434,25 @@
<img t-if="company.logo" t-att-src="image_data_uri(company.logo)" alt="Logo"/>
</div>
<div class="col-5 offset-1" name="company_address">
<ul class="list-unstyled">
<li t-if="company.is_company_details_empty"><t t-esc="company.partner_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}'/></li>
<li t-else=""><t t-esc="company.company_details"/></li>
<li t-if="forced_vat">
<t t-esc="company.country_id.vat_label or 'Tax ID'"/>:
<span t-esc="forced_vat"/>
<ul class="list-unstyled" name='company_address_list'>
<li t-if="company.is_company_details_empty"><span t-field="company.partner_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}'>
<div class="bg-light border-1 rounded h-100 d-flex flex-column align-items-center justify-content-center p-4 w-100 opacity-75 text-muted text-center">
<strong>Company address block</strong>
<div>Contains the company address.</div>
</div>
</span></li>
<li t-else="">
<span t-field="company.company_details">
<div class="bg-light border-1 rounded h-100 d-flex flex-column align-items-center justify-content-center p-4 w-100 opacity-75 text-muted text-center">
<strong>Company details block</strong>
<div>Contains the company details.</div>
</div>
</span>
</li>
<li t-if="not forced_vat"/>
<li t-else="">
<t t-esc="company.country_id.vat_label or 'Tax ID'">Tax ID</t>:
<span t-esc="forced_vat">US12345671</span>
</li>
</ul>
</div>
@ -424,7 +477,7 @@
<span t-else="" t-field="company.company_details"/>
</div>
<div class="col-3">
<div class="mt0 mb0 h5" t-field="company.report_header"/>
<div class="mt0 mb0 h5" t-if="company.report_header" t-field="company.report_header">Company tagline</div>
</div>
<div class="col-1">
<ul t-if="report_type == 'pdf'" class="list-inline pagenumber float-end text-center">
@ -441,7 +494,7 @@
<div class="col-3 mb4">
<img t-if="company.logo" t-att-src="image_data_uri(company.logo)" style="max-height: 45px;" alt="Logo"/>
</div>
<div class="col-9 text-end" style="margin-top:22px;" t-field="company.report_header" name="moto"/>
<div class="col-9 text-end" style="margin-top:22px;" t-if="company.report_header" t-field="company.report_header" name="moto">Company tagline</div>
</div>
<div t-if="company.logo or company.report_header" class="row zero_min_height">
<div class="col-12">
@ -450,12 +503,25 @@
</div>
<div class="row">
<div class="col-6" name="company_address">
<ul class="list-unstyled">
<li t-if="company.is_company_details_empty"><t t-esc="company.partner_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}'/></li>
<li t-else=""><t t-esc="company.company_details"/></li>
<li t-if="forced_vat">
<t t-esc="company.country_id.vat_label or 'Tax ID'"/>:
<span t-esc="forced_vat"/>
<ul class="list-unstyled" name="company_address_list">
<li t-if="company.is_company_details_empty"><span t-field="company.partner_id" t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}'>
<div class="bg-light border-1 rounded h-100 d-flex flex-column align-items-center justify-content-center p-4 w-100 opacity-75 text-muted text-center">
<strong>Company address block</strong>
<div>Contains the company address.</div>
</div>
</span></li>
<li t-else="">
<span t-field="company.company_details">
<div class="bg-light border-1 rounded h-100 d-flex flex-column align-items-center justify-content-center p-4 w-100 opacity-75 text-muted text-center">
<strong>Company details block</strong>
<div>Contains the company details.</div>
</div>
</span>
</li>
<li t-if="not forced_vat"/>
<li t-else="">
<t t-esc="company.country_id.vat_label or 'Tax ID'">Tax ID</t>:
<span t-esc="forced_vat">US12345671</span>
</li>
</ul>
</div>
@ -482,7 +548,7 @@
Page: <span class="page"/> / <span class="topage"/>
</div>
<div t-if="report_type == 'pdf' and display_name_in_footer" class="text-muted">
<span t-field="o.name"/>
<span t-out="o.name">(document name)</span>
</div>
</div>
</div>
@ -613,7 +679,7 @@
}
}
.row > div > table,
div#total table {
div#total table, .totals_taxes_company_currency table {
&amp;:first-child,
&amp;:last-child,
&amp;.o_subtotal,
@ -629,6 +695,9 @@
#total strong {
color: <t t-esc='primary'/>;
}
.totals_taxes_company_currency strong{
color: <t t-esc='primary'/>;
}
#informations strong {
color: <t t-esc='secondary'/>;
}
@ -653,7 +722,7 @@
}
}
.row > div > table,
div#total table {
div#total table, .totals_taxes_company_currency table {
tr {
&amp;.o_total td {
background-color: rgba(<t t-esc='primary'/>, 0.9);
@ -692,7 +761,7 @@
}
}
}
#total {
#total, .totals_taxes_company_currency {
strong {
color: <t t-esc='secondary'/>;
}
@ -710,6 +779,9 @@
#total strong{
color: <t t-esc='primary'/>;
}
.totals_taxes_company_currency strong{
color: <t t-esc='primary'/>;
}
table {
thead {
color: <t t-esc='secondary'/>;

View file

@ -3,14 +3,22 @@
<!-- Call this template instead of "web.assets_tests" to have the proper conditional check -->
<template id="conditional_assets_tests" name="Tests Assets Bundle">
<t t-call-assets="web.assets_tests" t-if="'tests' in debug or test_mode_enabled" defer_load="True" />
<t t-if="'tests' in debug or test_mode_enabled">
<t t-if="ignore_missing_deps">
<!-- FIXME: This is only to ignore the errors for the lazy loading. To allow all tests assets and tours to be in the same bundle, the assets_tests bundle ignores missing dependencies -->
<t t-call-assets="web.__assets_tests_call__" defer_load="True" />
</t>
<t t-else="">
<t t-call-assets="web.assets_tests" defer_load="True" />
</t>
</t>
</template>
<template id="web.layout" name="Web layout">&lt;!DOCTYPE html&gt;
<html t-att="html_data or {}">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title t-esc="title or 'Odoo'"/>
<link type="image/x-icon" rel="shortcut icon" t-att-href="x_icon or '/web/static/img/favicon.ico'"/>
<script id="web.layout.odooscript" type="text/javascript">
@ -44,7 +52,9 @@
}
</script>
<t t-call-assets="web.assets_frontend_minimal" t-css="false" defer_load="True"/>
<t t-call="web.conditional_assets_tests"/>
<t t-call="web.conditional_assets_tests">
<t t-set="ignore_missing_deps" t-value="True"/>
</t>
<t t-call-assets="web.assets_frontend_lazy" t-css="false" lazy_load="True"/>
</xpath>
<xpath expr="//t[@t-out='0']" position="replace">
@ -187,7 +197,7 @@
body {
position: relative; /* bootstrap-datepicker needs this */
}
body:not(.debug) .modal-backdrop, body:not(.debug) .modal, body:not(.debug) .ui-autocomplete {
body:not(.debug) .modal-backdrop, body:not(.debug) .modal:not(.o_module_error), body:not(.debug) .ui-autocomplete {
opacity: 0 !important;
}
#qunit-testrunner-toolbar label {
@ -207,11 +217,6 @@
<t t-set="html_data" t-value="{'style': 'height: 100%;'}"/>
<t t-set="title">Web Tests</t>
<t t-set="head">
<t t-call-assets="web.assets_common" t-js="false"/>
<t t-call-assets="web.assets_backend" t-js="false"/>
<t t-call-assets="web.tests_assets_common" t-css="false"/>
<t t-call-assets="web.assets_backend" t-css="false"/>
<t t-call="web.test_helpers"/>
<t t-call-assets="web.qunit_suite_tests" t-js="false"/>
@ -229,11 +234,6 @@
<t t-set="head">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>
<t t-call-assets="web.assets_common" t-js="false"/>
<t t-call-assets="web.assets_backend" t-js="false"/>
<t t-call-assets="web.tests_assets_common" t-css="false"/>
<t t-call-assets="web.assets_backend" t-css="false"/>
<t t-call="web.test_helpers"/>
<t t-call-assets="web.qunit_mobile_suite_tests" t-js="false"/>
@ -244,91 +244,37 @@
</t>
</template>
<template id="web.benchmark_suite">
<t t-call="web.layout">
<t t-set="html_data" t-value="{'style': 'height: 100%;'}"/>
<t t-set="title">Web Benchmarks</t>
<t t-set="head">
<script type="text/javascript" src="/web/static/lib/benchmarkjs/lodash.js"></script>
<script type="text/javascript" src="/web/static/lib/benchmarkjs/benchmark.js"></script>
<t t-call-assets="web.assets_common" t-js="false"/>
<t t-call-assets="web.assets_backend" t-js="false"/>
<t t-call-assets="web.assets_common" t-css="false"/>
<t t-call-assets="web.assets_backend" t-css="false"/>
<t t-call="web.test_helpers"/>
<script type="text/javascript">
QUnit.config.hidepassed = false;
</script>
<style>
body:not(.debug) .modal-backdrop, body:not(.debug) .modal, body:not(.debug) .ui-autocomplete {
opacity: 0 !important;
}
#qunit-testrunner-toolbar label {
font-weight: inherit;
margin-bottom: inherit;
}
#qunit-testrunner-toolbar input[type=text] {
width: inherit;
display: inherit;
}
</style>
<script type="text/javascript" src="/web/static/tests/views/list_benchmarks.js"></script>
<script type="text/javascript" src="/web/static/tests/views/kanban_benchmarks.js"></script>
<script type="text/javascript" src="/web/static/tests/views/form_benchmarks.js"></script>
</t>
<div id="qunit"/>
<div id="qunit-fixture"/>
</t>
</template>
<template id="web.webclient_bootstrap">
<t t-call="web.layout">
<t t-set="head_web">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>
<!-- Chrome, Firefox OS and Opera -->
<meta name="theme-color" content="#875A7B"/>
<link rel="icon" sizes="192x192" href="/web/static/img/mobile-icons/android-192x192.png"/>
<!-- iOS Safari -->
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
<link rel="apple-touch-icon" href="/web/static/img/mobile-icons/apple-152x152.png"/>
<!-- Windows Phone -->
<meta name="msapplication-navbutton-color" content="#875A7B"/>
<meta name="msapplication-TileColor" content="#875A7B"/>
<meta name="msapplication-TileImage" content="/web/static/img/mobile-icons/windows-144x144.png"/>
<meta name="theme-color" content="#71639e"/>
<link rel="manifest" href="/web/manifest.webmanifest" crossorigin="use-credentials"/>
<link rel="apple-touch-icon" href="/web/static/img/odoo-icon-ios.png"/>
<script type="text/javascript">
odoo.__session_info__ = <t t-out="json.dumps(session_info)"/>;
odoo.reloadMenus = () => fetch(`/web/webclient/load_menus/${odoo.__session_info__.cache_hashes.load_menus}`).then(res => res.json());
odoo.loadMenusPromise = odoo.reloadMenus();
// Block to avoid leaking variables in the script scope
{
odoo.__session_info__ = <t t-out="json.dumps(session_info)"/>;
const { user_context, cache_hashes } = odoo.__session_info__;
const lang = new URLSearchParams(document.location.search).get("lang");
let menuURL = `/web/webclient/load_menus/${cache_hashes.load_menus}`;
if (lang) {
user_context.lang = lang;
menuURL += `?lang=${lang}`
}
odoo.reloadMenus = () => fetch(menuURL).then(res => res.json());
odoo.loadMenusPromise = odoo.reloadMenus();
// Prefetch translations to speedup webclient. This is done in JS because link rel="prefetch"
// is not yet supported on safari.
fetch(`/web/webclient/translations/${cache_hashes.translations}?lang=${user_context.lang}`);
}
</script>
<t t-if="request.httprequest.cookies.get('color_scheme') == 'dark'">
<t t-call-assets="web.dark_mode_assets_common" t-js="false"/>
<t t-call-assets="web.dark_mode_assets_backend" t-js="false"/>
<t t-call-assets="web.assets_web_dark"/>
</t>
<t t-else="">
<t t-call-assets="web.assets_common" t-js="false"/>
<t t-call-assets="web.assets_backend" t-js="false"/>
<t t-call-assets="web.assets_web"/>
</t>
<t t-call-assets="web.assets_common" t-css="false"/>
<t t-call-assets="web.assets_backend" t-css="false"/>
<t t-call-assets="web.assets_backend_prod_only" t-css="false"/>
<t t-call="web.conditional_assets_tests"/>
</t>
<t t-set="head" t-value="head_web + (head or '')"/>
@ -336,4 +282,56 @@
</t>
</template>
<template id="webclient_offline">
<t t-call="web.layout">
<t t-set="html_data" t-value="{'style': 'height: 100%;'}"/>
<t t-set="title">Offline</t>
<t t-set="head">
<script type="text/javascript">
window.addEventListener('online', () => location.reload());
</script>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Ubuntu, "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
padding:0;
margin:0;
background-color: #fff;
color: rgb(17, 24, 39);
display: flex;
align-items: center;
justify-content: center;
text-align: center;
height: 100vh;
width: 100vw;
user-select: none;
}
.card {
width: 80%;
}
.card img {
width: 96px;
height: auto;
filter: grayscale(.6);
}
.card button {
background-color: #714B67;
color: #FFFFFF;
border: 1px solid #714B67;
border-radius: .25rem;
padding: .5rem 1rem;
cursor: pointer;
font-size: 1.2rem;
font-weight: 500;
}
</style>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
</t>
<div class="card">
<img t-attf-src="data:image/png;base64,{{odoo_icon}}" alt="Odoo logo"/>
<h1>You are offline</h1>
<p>Check your network connection and come back here. Odoo will load as soon as you're back online.</p>
<button onclick="location.reload()">Check again</button>
</div>
</t>
</template>
</odoo>