[FIX] web, base_setup: template didn't exist because of deps
An enterprise without apps would crash on launch because of a template web_enterprise would inherit but was only there with base_setup installed. closes odoo/odoo#97017 Related: odoo/enterprise#29919 Signed-off-by: Simon Genin (ges@odoo) <ges@odoo.com>
This commit is contained in:
@@ -1,20 +0,0 @@
|
||||
/** @odoo-modules */
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
|
||||
export const demoDataService = {
|
||||
dependencies: ["rpc"],
|
||||
async start(env, { rpc }) {
|
||||
let isDemoDataActiveProm;
|
||||
return {
|
||||
isDemoDataActive() {
|
||||
if (!isDemoDataActiveProm) {
|
||||
isDemoDataActiveProm = rpc("/base_setup/demo_active");
|
||||
}
|
||||
return isDemoDataActiveProm;
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
registry.category("services").add("demo_data", demoDataService);
|
||||
@@ -1,37 +0,0 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
|
||||
const { Component, onWillStart } = owl;
|
||||
|
||||
/**
|
||||
* Widget in the settings that handles the "Developer Tools" section.
|
||||
* Can be used to enable/disable the debug modes.
|
||||
* Can be used to load the demo data.
|
||||
*/
|
||||
class ResConfigDevTool extends Component {
|
||||
setup() {
|
||||
this.isDebug = Boolean(odoo.debug);
|
||||
this.isAssets = odoo.debug.includes("assets");
|
||||
this.isTests = odoo.debug.includes("tests");
|
||||
|
||||
this.action = useService("action");
|
||||
this.demo = useService("demo_data");
|
||||
|
||||
onWillStart(async () => {
|
||||
this.isDemoDataActive = await this.demo.isDemoDataActive();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces demo data to be installed in a database without demo data installed.
|
||||
*/
|
||||
onClickForceDemo() {
|
||||
this.action.doAction("base.demo_force_install_action");
|
||||
}
|
||||
}
|
||||
|
||||
ResConfigDevTool.template = "res_config_dev_tool";
|
||||
|
||||
registry.category("view_widgets").add("res_config_dev_tool", ResConfigDevTool);
|
||||
@@ -1,24 +0,0 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { session } from "@web/session";
|
||||
|
||||
const { Component } = owl;
|
||||
const { DateTime } = luxon;
|
||||
|
||||
/**
|
||||
* Widget in the settings that handles a part of the "About" section.
|
||||
* Contains info about the odoo version, database expiration date and copyrights.
|
||||
*/
|
||||
class ResConfigEdition extends Component {
|
||||
setup() {
|
||||
this.serverVersion = session.server_version;
|
||||
this.expirationDate = session.expiration_date
|
||||
? DateTime.fromSQL(session.expirationDate).toLocaleString(DateTime.DATE_FULL)
|
||||
: DateTime.now().plus({ days: 30 }).toLocaleString(DateTime.DATE_FULL);
|
||||
}
|
||||
}
|
||||
|
||||
ResConfigEdition.template = "res_config_edition";
|
||||
|
||||
registry.category("view_widgets").add("res_config_edition", ResConfigEdition);
|
||||
@@ -1,124 +0,0 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { unique } from "@web/core/utils/arrays";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
|
||||
const { Component, useState, onWillStart } = owl;
|
||||
|
||||
class ResConfigInviteUsers extends Component {
|
||||
setup() {
|
||||
this.orm = useService("orm");
|
||||
this.invite = useService("user_invite");
|
||||
this.action = useService("action");
|
||||
this.notification = useService("notification");
|
||||
|
||||
this.state = useState({
|
||||
status: "idle", // idle, inviting
|
||||
emails: "",
|
||||
invite: null,
|
||||
});
|
||||
|
||||
onWillStart(async () => {
|
||||
this.state.invite = await this.invite.fetchData();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} email
|
||||
* @returns {boolean} true if the given email address is valid
|
||||
*/
|
||||
validateEmail(email) {
|
||||
const re = /^([a-z0-9][-a-z0-9_\+\.]*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,63}(?:\.[a-z]{2})?)$/i;
|
||||
return re.test(email);
|
||||
}
|
||||
|
||||
get emails() {
|
||||
return unique(
|
||||
this.state.emails
|
||||
.split(/[ ,;\n]+/)
|
||||
.map((email) => email.trim())
|
||||
.filter((email) => email.length)
|
||||
);
|
||||
}
|
||||
|
||||
validate() {
|
||||
if (!this.emails.length) {
|
||||
throw new Error(_t("Empty email address"));
|
||||
}
|
||||
const invalidEmails = [];
|
||||
for (const email of this.emails) {
|
||||
if (!this.validateEmail(email)) {
|
||||
invalidEmails.push(email);
|
||||
}
|
||||
}
|
||||
if (invalidEmails.length) {
|
||||
throw new Error(`${_t("Invalid email address")}${ invalidEmails.length > 1 ? "es" : "" }: ${invalidEmails.join(", ")}`);
|
||||
}
|
||||
}
|
||||
|
||||
get inviteButtonText() {
|
||||
if (this.state.status === "inviting") {
|
||||
return _t("Inviting...");
|
||||
}
|
||||
return _t("Invite");
|
||||
}
|
||||
|
||||
onClickMore(ev) {
|
||||
this.action.doAction(this.state.invite.action_pending_users);
|
||||
}
|
||||
|
||||
onClickUser(ev, user) {
|
||||
const action = Object.assign({}, this.state.invite.action_pending_users, {
|
||||
res_id: user[0],
|
||||
});
|
||||
this.action.doAction(action);
|
||||
}
|
||||
|
||||
onKeydownUserEmails(ev) {
|
||||
const keys = ["Enter", "Tab", ","];
|
||||
if (keys.includes(ev.key)) {
|
||||
if (ev.key === "Tab" && !this.emails.length) {
|
||||
return;
|
||||
}
|
||||
ev.preventDefault();
|
||||
this.sendInvite();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send invitation for valid and unique email addresses
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
async sendInvite() {
|
||||
try {
|
||||
this.validate();
|
||||
} catch (e) {
|
||||
this.notification.add(e.message, { type: "danger" });
|
||||
return;
|
||||
}
|
||||
|
||||
this.state.status = "inviting";
|
||||
|
||||
const pendingUserEmails = this.state.invite.pending_users.map((user) => user[1]);
|
||||
const emailsLeftToProcess = this.emails.filter(
|
||||
(email) => !pendingUserEmails.includes(email)
|
||||
);
|
||||
|
||||
try {
|
||||
if (emailsLeftToProcess) {
|
||||
await this.orm.call("res.users", "web_create_users", [emailsLeftToProcess]);
|
||||
this.state.invite = await this.invite.fetchData(true);
|
||||
}
|
||||
} finally {
|
||||
this.state.emails = "";
|
||||
this.state.status = "idle";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResConfigInviteUsers.template = "res_config_invite_users";
|
||||
|
||||
registry.category("view_widgets").add("res_config_invite_users", ResConfigInviteUsers);
|
||||
@@ -1,20 +0,0 @@
|
||||
/** @odoo-modules */
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
|
||||
export const userInviteService = {
|
||||
dependencies: ["rpc"],
|
||||
async start(env, { rpc }) {
|
||||
let dataProm;
|
||||
return {
|
||||
fetchData(reload = false) {
|
||||
if (!dataProm || reload) {
|
||||
dataProm = rpc("/base_setup/data");
|
||||
}
|
||||
return dataProm;
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
registry.category("services").add("user_invite", userInviteService);
|
||||
@@ -1,17 +0,0 @@
|
||||
.o_setting_container {
|
||||
.o_web_settings_user {
|
||||
font-size: 95%;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.o_doc_link {
|
||||
text-decoration: none;
|
||||
font-weight: normal;
|
||||
|
||||
&::after{
|
||||
content: "\f059"; //fa-question-circle
|
||||
font-family: 'FontAwesome';
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<template>
|
||||
<div t-name='res_config_dev_tool' owl="1">
|
||||
<div id="developer_tool">
|
||||
<h2>Developer Tools</h2>
|
||||
<div class="row mt16 o_settings_container">
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="devel_tool">
|
||||
<div class="o_setting_right_pane">
|
||||
<a t-if="!isDebug" class="d-block" href="?debug=1">Activate the developer mode</a>
|
||||
<a t-if="!isAssets" class="d-block" href="?debug=assets">Activate the developer mode (with assets)</a>
|
||||
<a t-if="!isTests" class="d-block" href="?debug=assets,tests">Activate the developer mode (with tests assets)</a>
|
||||
<a t-if="isDebug" class="d-block" href="?debug=">Deactivate the developer mode</a>
|
||||
<a t-if="isDebug and !isDemoDataActive" t-on-click.prevent="onClickForceDemo" class="o_web_settings_force_demo" href="#">Load demo data</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<template>
|
||||
<div t-name='res_config_edition' owl="1">
|
||||
<div class="col-12 o_setting_box" id="edition">
|
||||
<div class="o_setting_right_pane">
|
||||
<div class="user-heading">
|
||||
<h3 class="px-0">
|
||||
Odoo <t t-esc="serverVersion"/>
|
||||
(Community Edition)
|
||||
</h3>
|
||||
</div>
|
||||
<div>
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" id="settings" class="tab-pane active text-muted o_web_settings_compact_subtitle">
|
||||
<small>Copyright © 2004 <a target="_blank" href="https://www.odoo.com" style="text-decoration: underline;">Odoo S.A.</a> <a id="license" target="_blank" href="http://www.gnu.org/licenses/lgpl.html" style="text-decoration: underline;">GNU LGPL Licensed</a></small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<templates>
|
||||
<div t-name='res_config_invite_users' owl="1">
|
||||
<p class="o_form_label">Invite New Users</p>
|
||||
|
||||
<div class="d-flex">
|
||||
<input t-model="state.emails" t-att-disabled="state.status != 'idle'" class="o_user_emails o_input mt8" t-on-keydown="onKeydownUserEmails" type="text" placeholder="Enter e-mail address"/>
|
||||
<button t-att-disabled="state.status != 'idle'" class="btn btn-primary o_web_settings_invite" t-on-click="sendInvite"><strong><t t-esc="inviteButtonText"/></strong></button>
|
||||
</div>
|
||||
<t t-if="state.invite.pending_users.length">
|
||||
<p class="o_form_label pt-3">Pending Invitations:</p>
|
||||
<span t-foreach="state.invite.pending_users" t-as="pending" t-key="pending[0]">
|
||||
<a href="#" class="badge rounded-pill text-primary o_web_settings_user" t-on-click.prevent="(ev) => this.onClickUser(ev, pending)"> <t t-esc="pending[1]"/> </a>
|
||||
</span>
|
||||
<t t-if="state.invite.pending_users.length < state.invite.pending_count">
|
||||
<br/>
|
||||
<a href="#" class="o_web_settings_more" t-on-click.prevent="onClickMore"><t t-esc="state.invite.pending_count - state.invite.pending_users.length"/> more </a>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
</templates>
|
||||
Reference in New Issue
Block a user