19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:32:28 +01:00
parent 20ddc1b4a3
commit c0efcc53f5
1162 changed files with 125577 additions and 105287 deletions

View file

@ -1,49 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="auth_signup.login" inherit_id="web.login" name="Sign up - Reset Password">
<xpath expr="//button[@type='submit']" position="after">
<div class="justify-content-between mt-2 d-flex small">
<a t-if="signup_enabled" t-attf-href="/web/signup?{{ keep_query() }}">Don't have an account?</a>
<a t-if="reset_password_enabled" t-attf-href="/web/reset_password?{{ keep_query() }}">Reset Password</a>
</div>
<xpath expr="//div[hasclass('oe_login_buttons')]/button" position="after">
<a t-if="signup_enabled" class="btn btn-link btn-sm mt-2" t-attf-href="/web/signup?{{ keep_query() }}">Don't have an account?</a>
</xpath>
<xpath expr="//label[@for='password']" position="after">
<a t-if="reset_password_enabled" class="btn btn-link btn-sm" tabindex="1" t-attf-href="/web/reset_password?{{ keep_query() }}">Reset Password</a>
</xpath>
</template>
<template id="auth_signup.fields" name="Auth Signup/ResetPassword form fields">
<div class="mb-3 field-login">
<label for="login">Your Email</label>
<input type="text" name="login" t-att-value="login" id="login" class="form-control form-control-sm" autofocus="autofocus"
autocapitalize="off" required="required" t-att-readonly="'readonly' if only_passwords else None"/>
</div>
<div class="mb-3 field-name">
<label for="name">Your Name</label>
<input type="text" name="name" t-att-value="name" id="name" class="form-control form-control-sm" placeholder="e.g. John Doe"
required="required" t-att-readonly="'readonly' if only_passwords else None"
t-att-autofocus="'autofocus' if login and not only_passwords else None" />
</div>
<div class="mb-3 field-password pt-2">
<label for="password">Password</label>
<input type="password" name="password" id="password" class="form-control form-control-sm"
required="required" t-att-autofocus="'autofocus' if only_passwords else None"/>
<div class="mb-3 field-password pt-2 o_caps_lock_warning">
<label for="password" class="form-label">Password</label>
<div class="input-group mb-1">
<input type="password" name="password" id="password" class="form-control"
required="required" t-att-autofocus="'autofocus' if autofocus else None" placeholder="••••••••••"/>
<button type="button" class="btn btn-sm border border-start-0 o_show_password">
<i class="fa fa-eye"/>
</button>
</div>
</div>
<div class="mb-3 field-confirm_password">
<label for="confirm_password">Confirm Password</label>
<input type="password" name="confirm_password" id="confirm_password" class="form-control form-control-sm" required="required"/>
<label for="confirm_password" class="form-label">Confirm Password</label>
<div class="input-group mb-1">
<input type="password" name="confirm_password" id="confirm_password" class="form-control" required="required" placeholder="••••••••••"/>
<button type="button" class="btn btn-sm border border-start-0 o_show_password">
<i class="fa fa-eye"/>
</button>
</div>
</div>
</template>
<template id="auth_signup.signup" name="Sign up login">
<t t-call="web.login_layout">
<form class="oe_signup_form" role="form" method="post" t-if="not message">
<div class="oe_structure" id="oe_structure_signup_top"/>
<form class="oe_signup_form" role="form" method="post" t-if="not message" data-captcha="signup">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<t t-call="auth_signup.fields">
<t t-set="only_passwords" t-value="bool(token and not invalid_token)"/>
</t>
<div class="mb-3 field-name">
<label for="name" class="form-label">Name</label>
<input type="text" name="name" t-att-value="name" id="name" class="form-control" placeholder="John Doe"
autofocus="autofocus" required="required"/>
</div>
<div class="mb-3 field-login">
<label for="login" class="form-label">Email</label>
<input type="text" name="login" t-att-value="login" id="login" class="form-control"
t-att-autofocus="'autofocus' if login else None"
autocapitalize="off" required="required" placeholder="name@example.com"/>
</div>
<t t-call="auth_signup.fields"/>
<p class="alert alert-danger" t-if="error" role="alert">
<t t-esc="error"/>
@ -51,16 +59,18 @@
<input type="hidden" name="redirect" t-att-value="redirect"/>
<input type="hidden" name="token" t-att-value="token"/>
<div class="text-center oe_login_buttons d-grid pt-3">
<button type="submit" class="btn btn-primary"> Sign up</button>
<a t-attf-href="/web/login?{{ keep_query() }}" class="btn btn-link btn-sm" role="button">Already have an account?</a>
<div class="o_login_auth"/>
<button type="submit" class="btn btn-primary mb-1"> Sign up</button>
<a t-attf-href="/web/login?{{ keep_query() }}" class="btn btn-link btn-sm mt-2" role="button">Already have an account?</a>
<t t-call="web.login_oauth"/>
</div>
</form>
<div class="oe_structure" id="oe_structure_signup_bottom"/>
</t>
</template>
<template id="auth_signup.reset_password" name="Reset password">
<t t-call="web.login_layout">
<div class="oe_structure" id="oe_structure_reset_password_top"/>
<div t-if="message" class="oe_login_form clearfix">
<p class="alert alert-success" t-if="message" role="status">
<t t-esc="message"/>
@ -68,18 +78,18 @@
<a href="/web/login" class="btn btn-link btn-sm float-start" role="button">Back to Login</a>
</div>
<form class="oe_reset_password_form" role="form" method="post" t-if="not message">
<form class="oe_reset_password_form" role="form" method="post" t-if="not message" data-captcha="password_reset">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<t t-if="token and not invalid_token">
<t t-call="auth_signup.fields">
<t t-set="only_passwords" t-value="1"/>
<t t-set="autofocus" t-value="1"/>
</t>
</t>
<t t-if="not token">
<div class="mb-3 field-login">
<label for="login" class="col-form-label">Your Email</label>
<label for="login" class="col-form-label">Email</label>
<input type="text" name="login" t-att-value="login" id="login" class="form-control"
autofocus="autofocus" required="required" autocapitalize="off"/>
</div>
@ -96,10 +106,11 @@
<a t-if="not token" t-attf-href="/web/login?{{ keep_query() }}">Back to Login</a>
<a t-if="invalid_token" href="/web/login">Back to Login</a>
</div>
<div class="o_login_auth"/>
<t t-call="web.login_oauth"/>
</div>
</form>
<div class="oe_structure" id="oe_structure_reset_password_bottom"/>
</t>
</template>

View file

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="reset_password_email" name="User Reset Password">
<table border="0" cellpadding="0" cellspacing="0" style="padding-top: 16px; background-color: #FFFFFF; font-family:Verdana, Arial,sans-serif; color: #454748; width: 100%; border-collapse:separate;"><tr><td align="center">
<table border="0" cellpadding="0" cellspacing="0" width="590" style="padding: 16px; background-color: #FFFFFF; color: #454748; border-collapse:separate;">
<tbody>
<!-- HEADER -->
<tr>
<td align="center" style="min-width: 590px;">
<table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="middle">
<span style="font-size: 10px;">Your Account</span><br/>
<span style="font-size: 20px; font-weight: bold;">
<t t-out="object.name or ''">Marc Demo</t>
</span>
</td><td valign="middle" align="right" t-if="not object.company_id.uses_default_logo">
<img t-attf-src="/logo.png?company={{ object.company_id.id }}" style="padding: 0px; margin: 0px; height: auto; width: 80px;" t-att-alt="object.company_id.name"/>
</td></tr>
<tr><td colspan="2" style="text-align:center;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;"/>
</td></tr>
</table>
</td>
</tr>
<!-- CONTENT -->
<tr>
<td align="center" style="min-width: 590px;">
<table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="top" style="font-size: 13px;">
<div>
Dear <t t-out="object.name or ''">Marc Demo</t>,<br/><br/>
A password reset was requested for the account linked to this email.
You may change your password by following this link which will remain valid during <t t-out="user.env['ir.config_parameter'].sudo().get_param('auth_signup.reset_password.validity.hours',4)"></t> hours:<br/>
<div style="margin: 16px 0px 16px 0px;">
<a t-att-href="object.partner_id._get_signup_url()"
t-attf-style="background-color: {{object.company_id.email_secondary_color or '#875A7B'}}; padding: 8px 16px 8px 16px; text-decoration: none; color: {{object.company_id.email_primary_color or '#FFFFFF'}}; border-radius: 5px; font-size:13px;">
Change password
</a>
</div>
If you do not expect this, you can safely ignore this email.<br/><br/>
Thanks,
<t t-if="user.signature">
<br/>
<t t-out="user.signature">--<br/>Mitchell Admin</t>
</t>
</div>
</td></tr>
<tr><td style="text-align:center;">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;"/>
</td></tr>
</table>
</td>
</tr>
<!-- FOOTER -->
<tr>
<td align="center" style="min-width: 590px;">
<table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; font-size: 11px; padding: 0px 8px 0px 8px; border-collapse:separate;">
<tr><td valign="middle" align="left">
<t t-out="object.company_id.name or ''">YourCompany</t>
</td></tr>
<tr><td valign="middle" align="left" style="opacity: 0.7;">
<t t-out="object.company_id.phone or ''">+1 650-123-4567</t>
<t t-if="object.company_id.email">
| <a t-att-href="'mailto:%s' % object.company_id.email" style="text-decoration:none; color: #454748;" t-out="object.company_id.email">info@yourcompany.com</a>
</t>
<t t-if="object.company_id.website">
| <a t-att-href="'%s' % object.company_id.website" style="text-decoration:none; color: #454748;" t-out="object.company_id.website">http://www.example.com</a>
</t>
</td></tr>
</table>
</td>
</tr>
</tbody>
</table>
</td></tr>
<!-- POWERED BY -->
<tr><td align="center" style="min-width: 590px;">
<table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: #F1F1F1; color: #454748; padding: 8px; border-collapse:separate;">
<tr><td style="text-align: center; font-size: 13px;">
Powered by <a target="_blank" href="https://www.odoo.com?utm_source=db&amp;utm_medium=auth" t-attf-style="color: {{object.company_id.email_secondary_color or '#875A7B'}};">Odoo</a>
</td></tr>
</table>
</td></tr>
</table>
</template>
</odoo>

View file

@ -6,38 +6,18 @@
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="base_setup.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@id='access_rights']" position="before">
<div class="col-12 col-lg-6 o_setting_box"
id="login_documents"
title=" To send invitations in B2B mode, open a contact or select several ones in list view and click on 'Portal Access Management' option in the dropdown menu *Action*.">
<div class="o_setting_left_pane">
</div>
<div class="o_setting_right_pane">
<label for="auth_signup_uninvited"/>
<div class="text-muted">
Let your customers log in to see their documents
</div>
<xpath expr="//setting[@id='access_rights']" position="before">
<setting id="login_documents" title="To send invitations in B2B mode, open a contact or select several ones in list view and click on 'Portal Access Management' option in the dropdown menu *Action*." help="Let your customers log in to see their documents">
<field name="auth_signup_uninvited" class="o_light_label" widget="radio" options="{'horizontal': true}" required="True"/>
<div class="content-group" invisible="auth_signup_uninvited == 'b2b'">
<div class="mt8">
<field name="auth_signup_uninvited" class="o_light_label" widget="radio" options="{'horizontal': true}" required="True"/>
</div>
<div class="content-group" attrs="{'invisible': [('auth_signup_uninvited','=','b2b')]}">
<div class="mt8">
<button type="object" name="action_open_template_user" string="Default Access Rights" icon="fa-arrow-right" class="btn-link"/>
</div>
<button type="object" name="action_open_template_user" string="Default Access Rights" icon="oi-arrow-right" class="btn-link"/>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="enable_password_reset">
<div class="o_setting_left_pane">
<field name="auth_signup_reset_password"/>
</div>
<div class="o_setting_right_pane">
<label string="Password Reset" for="auth_signup_reset_password"/>
<div class="text-muted">
Enable password reset from Login page
</div>
</div>
</div>
</setting>
<setting string="Password Reset" help="Enable password reset from Login page" id="enable_password_reset">
<field name="auth_signup_reset_password"/>
</setting>
</xpath>
</field>
</record>

View file

@ -8,47 +8,35 @@
<field name="arch" type="xml">
<!-- add state field in header -->
<xpath expr="//header" position="inside">
<button string="Send Password Reset Instructions"
type="object" name="action_reset_password"
attrs="{'invisible': [('state', '!=', 'active')]}"/>
<button string="Send an Invitation Email"
type="object" name="action_reset_password" context="{'create_user': 1}"
attrs="{'invisible': [('state', '!=', 'new')]}"/>
invisible="state != 'new'"/>
<field name="state" widget="statusbar"/>
</xpath>
<xpath expr="//sheet" position="before">
<div class="alert alert-success text-center o_form_header alert-dismissible" attrs="{'invisible': [('signup_valid', '!=', True)]}" role="status">
<button class="btn-close" data-bs-dismiss="alert" aria-label="Close"/>
<div attrs="{'invisible': [('state', '!=', 'active')]}">
<strong>A password reset has been requested for this user. An email containing the following link has been sent:</strong>
</div>
<div attrs="{'invisible': [('state', '!=', 'new')]}">
<strong>An invitation email containing the following subscription link has been sent:</strong>
</div>
<div><field name="signup_url" widget="url"/></div>
<field name="signup_valid" invisible="1"/>
</div>
</xpath>
<xpath expr="//div[@name='auth']" position="inside">
<button string="Send Password Reset"
type="object" name="action_reset_password"
invisible="id == uid or state != 'active'" class="btn btn-secondary h-100 ms-2 my-auto"/>
</xpath>
</field>
</record>
<record id="view_users_state_tree" model="ir.ui.view">
<field name="name">res.users.tree.inherit</field>
<field name="name">res.users.list.inherit</field>
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_tree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='company_id']" position="after">
<field name="state" widget="badge"
<list position="inside">
<field name="state" widget="badge" optional="hide"
decoration-info="state == 'new'" decoration-success="state == 'active'"/>
</xpath>
</list>
</field>
</record>
<record id="action_send_password_reset_instructions" model="ir.actions.server">
<field name="name">Send Password Reset Instructions</field>
<field name="model_id" ref="base.model_res_users"/>
<field name="groups_id" eval="[(4, ref('base.group_erp_manager'))]"/>
<field name="group_ids" eval="[(4, ref('base.group_erp_manager'))]"/>
<field name="binding_model_id" ref="base.model_res_users" />
<field name="state">code</field>
<field name="code">records.action_reset_password()</field>