portal_templates.xml
35.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="frontend_layout" name="Main Frontend Layout" inherit_id="web.frontend_layout">
<xpath expr="//div[@id='wrapwrap']" position="attributes">
<attribute name="t-attf-class" add="#{request.env['res.lang']._lang_get(request.env.lang).direction == 'rtl' and 'o_rtl' or ''}" separator=" "/>
<attribute name="t-attf-class" add="#{'o_portal' if is_portal else ''}" separator=" "/>
</xpath>
<xpath expr="//div[@id='wrapwrap']/header/img" position="replace">
<nav class="navbar navbar-expand navbar-light bg-light">
<div class="container">
<a href="/" class="navbar-brand logo">
<img t-att-src="'/logo.png?company=%s' % res_company.id" t-att-alt="'Logo of %s' % res_company.name" t-att-title="res_company.name"/>
</a>
<ul id="top_menu" class="nav navbar-nav ml-auto">
<t t-call="portal.placeholder_user_sign_in">
<t t-set="_item_class" t-value="'nav-item'"/>
<t t-set="_link_class" t-value="'nav-link'"/>
</t>
<t t-call="portal.user_dropdown">
<t t-set="_user_name" t-value="true"/>
<t t-set="_item_class" t-value="'nav-item dropdown'"/>
<t t-set="_link_class" t-value="'nav-link'"/>
<t t-set="_dropdown_menu_class" t-value="'dropdown-menu-right'"/>
</t>
</ul>
</div>
</nav>
</xpath>
<xpath expr="//div[@id='wrapwrap']/main/t[@t-raw='0']" position="before">
<div t-if="o_portal_fullwidth_alert" class="alert alert-info alert-dismissible rounded-0 fade show d-print-none css_editable_mode_hidden">
<div class="container">
<t t-raw="o_portal_fullwidth_alert"/>
</div>
</div>
</xpath>
</template>
<!-- Added by another template so that it can be disabled if needed -->
<template id="footer_language_selector" inherit_id="portal.frontend_layout" name="Footer Language Selector">
<xpath expr="//*[hasclass('o_footer_copyright_name')]" position="after">
<t id="language_selector_call" t-call="portal.language_selector">
<t t-set="_div_classes" t-value="(_div_classes or '') + ' dropup'"/>
</t>
</xpath>
</template>
<template id="language_selector" name="Language Selector">
<t t-set="active_lang" t-value="list(filter(lambda lg : lg[0] == lang, languages))[0]"/>
<t t-set="language_selector_visible" t-value="len(languages) > 1"/>
<div t-attf-class="js_language_selector #{_div_classes}" t-if="language_selector_visible">
<button class="btn btn-sm btn-outline-secondary border-0 dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<span t-if="not no_text"
class="align-middle"
t-esc="active_lang[2].split('/').pop()"/>
</button>
<div class="dropdown-menu" role="menu">
<t t-foreach="languages" t-as="lg">
<a t-att-href="url_for(request.httprequest.path + '?' + keep_query(), lang_code=lg[0])"
class="dropdown-item js_change_lang"
t-att-data-url_code="lg[1]">
<span t-if="not no_text"
t-esc="lg[2].split('/').pop()"/>
</a>
</t>
</div>
</div>
</template>
<template id="user_dropdown" name="Portal User Dropdown">
<t t-set="is_connected" t-value="not user_id._is_public()"/>
<li t-if="is_connected" t-attf-class="#{_item_class} o_no_autohide_item">
<a href="#" role="button" data-toggle="dropdown" t-attf-class="dropdown-toggle #{_link_class}">
<t t-if="_avatar">
<t t-if="user_id.image_256" t-set="avatar_source" t-value="image_data_uri(user_id.image_256)"/>
<t t-else="" t-set="avatar_source" t-value="'/web/static/src/img/placeholder.png'"/>
<img t-att-src="avatar_source" t-attf-class="rounded-circle #{_avatar_class}" width="24" height="24" alt="" loading="eager"/>
</t>
<i t-if="_icon" t-attf-class="fa fa-1x fa-fw fa-user-circle-o #{_icon_class}"/>
<span t-if="_user_name" t-attf-class="#{_user_name_class}" t-esc="user_id.name[:23] + '...' if user_id.name and len(user_id.name) > 25 else user_id.name"/>
</a>
<div t-attf-class="dropdown-menu js_usermenu #{_dropdown_menu_class}" role="menu">
<div id="o_logout_divider" class="dropdown-divider"/>
<a t-attf-href="/web/session/logout?redirect=/" role="menuitem" id="o_logout" class="dropdown-item">Logout</a>
</div>
</li>
</template>
<template id="portal_breadcrumbs" name="Portal Breadcrumbs">
<ol t-if="page_name != 'home'" class="o_portal_submenu breadcrumb mb-0 py-2 flex-grow-1 row">
<li class="breadcrumb-item ml-1"><a href="/my/home" aria-label="Home" title="Home"><i class="fa fa-home"/></a></li>
<li t-if="page_name == 'my_details'" class="breadcrumb-item">Details</li>
</ol>
</template>
<template id="portal_back_in_edit_mode" name="Back to edit mode">
<div t-ignore="true" class="text-center">
<t t-if="custom_html" t-raw="custom_html"/>
<t t-else="">This is a preview of the customer portal.</t>
<a t-att-href="backend_url"><i class="fa fa-arrow-right mr-1"/>Back to edit mode</a>
</div>
<button type="button" class="close" data-dismiss="alert" aria-label="Close"> × </button>
</template>
<template id="portal_layout" name="Portal Layout">
<t t-call="portal.frontend_layout">
<t t-set="is_portal" t-value="True"/>
<div t-if="not no_breadcrumbs and not my_details and not breadcrumbs_searchbar" class="o_portal container mt-3">
<div class="row align-items-center bg-white no-gutters border rounded">
<div class="col-10">
<t t-call="portal.portal_breadcrumbs"></t>
</div>
<div t-if="prev_record or next_record" class="col-2 flex-grow-0 text-center">
<t t-call='portal.record_pager'/>
</div>
</div>
</div>
<div id="wrap" class='o_portal_wrap'>
<div class="container mb64">
<t t-if="my_details">
<div class="row justify-content-between mt-4">
<div t-attf-class="col-12 col-md col-lg-6">
<t t-raw="0"/>
</div>
<div id="o_my_sidebar" class="pt-3 pt-lg-0 col-12 col-md col-lg-4 col-xl-3 o_my_sidebar">
<div class="o_my_contact" t-if="sales_user">
<t t-call="portal.portal_contact"/>
</div>
<div class="o_portal_my_details">
<h4>Details <a role="button" href="/my/account" class="btn btn-sm btn-link"><i class="fa fa-pencil"/> Edit</a></h4>
<hr class="mt-1 mb-0"/>
<div t-field="user_id.partner_id" t-options='{"widget": "contact", "fields": ["email", "phone", "address", "name"]}'/>
</div>
<div class="o_portal_my_security mt-3">
<h4>Account Security </h4>
<hr class="mt-1 mb-1"/>
<a href="/my/security"><i class="fa fa-pencil mx-1"/>Edit Security Settings</a>
</div>
</div>
</div>
</t>
<t t-else="">
<t t-raw="0"/>
</t>
</div>
</div>
</t>
</template>
<template id="placeholder_user_sign_in" name="User Sign In Placeholder"/>
<template id="user_sign_in" name="User Sign In" inherit_id="portal.placeholder_user_sign_in">
<xpath expr="." position="inside">
<li groups="base.group_public" t-attf-class="#{_item_class} o_no_autohide_item">
<a t-attf-href="/web/login" t-attf-class="#{_link_class}">Sign in</a>
</li>
</xpath>
</template>
<template id="portal_my_home" name="My Portal">
<t t-call="portal.portal_layout">
<t t-set="my_details" t-value="True"/>
<div class="o_portal_my_home">
<div class="oe_structure" id="oe_structure_portal_my_home_1"/>
<h3>Documents</h3>
<div class="o_portal_docs list-group">
</div>
</div>
<div class="oe_structure" id="oe_structure_portal_my_home_2"/>
</t>
</template>
<template id="portal_docs_entry" name="My Portal Docs Entry">
<a t-att-href="url" t-att-title="title" class="list-group-item list-group-item-action d-flex align-items-center justify-content-between">
<t t-esc="title"/>
<t t-if='count'>
<span class="badge badge-secondary badge-pill" t-esc="count"/>
</t>
<t t-elif="placeholder_count">
<span class="badge badge-secondary badge-pill" t-att-data-placeholder_count="placeholder_count">
<i class="fa fa-spin fa-spinner"></i>
</span>
</t>
</a>
</template>
<template id="portal_table" name="My Portal Table">
<div t-attf-class="table-responsive border rounded border-top-0 #{classes if classes else ''}">
<table class="table rounded mb-0 bg-white o_portal_my_doc_table">
<t t-raw="0"/>
</table>
</div>
<div t-if="pager" class="o_portal_pager text-center">
<t t-call="portal.pager"/>
</div>
</template>
<template id="portal_record_sidebar" name="My Portal Record Sidebar">
<div t-attf-class="#{classes}">
<div class="card bg-white mb-4 sticky-top" id="sidebar_content">
<div t-if="title" class="card-body text-center pb-2 pt-3">
<t t-raw="title"/>
</div>
<t t-if="entries" t-raw="entries"/>
<div class="card-footer small text-center text-muted border-top-0 pt-1 pb-1 d-none d-lg-block">
Powered by <a target="_blank" href="http://www.odoo.com?utm_source=db&utm_medium=portal" title="odoo"><img src="/web/static/src/img/logo.png" alt="Odoo Logo" height="15"/></a>
</div>
</div>
</div>
</template>
<!--
The search bar is composed of 2 buttons : a "filter by" and a "sort by". Changing the 'sortby'
criteria will keep the number of page, query params, ... Changing the 'filterby' param will
redirect the user to the beginning of document list, keeping query parameters.
These 2 buttons can be prepended by a advanced search input, to activate it, search_input need
to be initialized at 'True' and the content of the t-call is the list of li elements searchable.
:param dict searchbar_sortings : containing the sort criteria like
{'date': {'label': _('Newest'), 'order': 'create_date desc'}}
:param string sortby : name of the sort criteria
:param dict searchbar_filters : containing the filter criteria like
{'open': {'label': _('In Progress'), 'domain': [('state', '=', 'open')]}}
:param string filterby : name of the filter criteria
:param default_url : the base url of the pages (like '/my/orders')
:param boolean breadcrumbs_searchbar : set to True to show breadcrumbs rather than the title
:param boolean o_portal_search_panel : set to True to active the input search
:param html $0 : content of the t-call
:param title : bavbar title
:param classes : navbar classes
-->
<template id="portal_searchbar" name="Portal Search Bar">
<nav t-attf-class="navbar navbar-light navbar-expand-lg border py-0 mb-2 o_portal_navbar {{classes if classes else ''}} {{'mt-3 rounded' if breadcrumbs_searchbar else 'border-top-0' }}">
<!-- Navbar breadcrumb or title -->
<t t-if="breadcrumbs_searchbar">
<t t-call="portal.portal_breadcrumbs"/>
</t>
<span t-else="" class="navbar-brand mb-0 h1 mr-auto" t-esc="title or 'No title'"/>
<!-- Collapse button -->
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#o_portal_navbar_content" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle filters">
<span class="navbar-toggler-icon small"/>
</button>
<!-- Collapsable content -->
<div class="collapse navbar-collapse" id="o_portal_navbar_content">
<div class="nav flex-column flex-lg-row ml-auto p-0 mb-3 mb-lg-0 mt-1 mt-lg-0">
<div t-if="searchbar_sortings" class="form-inline">
<span class="small mr-1 navbar-text">Sort By:</span>
<div class="btn-group">
<button id="portal_searchbar_sortby" data-toggle="dropdown" class="btn btn-secondary btn-sm dropdown-toggle">
<t t-esc="searchbar_sortings[sortby].get('label', 'Newest')"/>
</button>
<div class="dropdown-menu" aria-labelledby="portal_searchbar_sortby">
<t t-foreach="searchbar_sortings" t-as="option">
<a t-att-href="request.httprequest.path + '?' + keep_query('*', sortby=option)"
t-attf-class="dropdown-item#{sortby == option and ' active' or ''}">
<span t-esc="searchbar_sortings[option].get('label')"/>
</a>
</t>
</div>
</div>
</div>
<div t-if="searchbar_filters" class="form-inline ml-lg-2">
<span class="small mr-1 navbar-text">Filter By:</span>
<div class="btn-group">
<button id="portal_searchbar_filters" data-toggle="dropdown" class="btn btn-secondary btn-sm dropdown-toggle">
<t t-esc="searchbar_filters.get(filterby,searchbar_filters.get('all')).get('label', 'All')"/>
</button>
<div class="dropdown-menu" aria-labelledby="portal_searchbar_filters">
<t t-foreach="searchbar_filters" t-as="option">
<a t-att-href="default_url + '?' + keep_query('*', filterby=option)"
t-attf-class="dropdown-item#{filterby == option and ' active' or ''}">
<span t-esc="searchbar_filters[option].get('label')"/>
</a>
</t>
</div>
</div>
</div>
<div t-if="searchbar_groupby" class="form-inline ml-lg-2">
<span class="small mr-1 navbar-text">Group By:</span>
<div class="btn-group">
<button id="portal_searchbar_groupby" data-toggle="dropdown" class="btn btn-secondary btn-sm dropdown-toggle">
<t t-esc="searchbar_groupby[groupby].get('label', 'None')"/>
</button>
<div class="dropdown-menu" aria-labelledby="portal_searchbar_groupby">
<t t-foreach="searchbar_groupby" t-as="option">
<a t-att-href="default_url + '?' + keep_query('*', groupby=option)"
t-attf-class="dropdown-item#{groupby == option and ' active' or ''}">
<span t-esc="searchbar_groupby[option].get('label')"/>
</a>
</t>
</div>
</div>
</div>
<t t-raw="0"/>
</div>
<form t-if="searchbar_inputs" class="form-inline o_portal_search_panel ml-lg-4 col-xl-4 col-md-5">
<div class="input-group input-group-sm w-100">
<div class="input-group-prepend">
<button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown"/>
<div class="dropdown-menu" role="menu">
<t t-foreach='searchbar_inputs' t-as='input'>
<a t-att-href="'#' + searchbar_inputs[input]['input']"
t-attf-class="dropdown-item#{search_in == searchbar_inputs[input]['input'] and ' active' or ''}">
<span t-raw="searchbar_inputs[input]['label']"/>
</a>
</t>
</div>
</div>
<input type="text" class="form-control form-control-sm" placeholder="Search" t-att-value='search' name="search"/>
<span class="input-group-append">
<button class="btn btn-secondary search-submit" type="button">
<span class="fa fa-search"/>
</button>
</span>
</div>
</form>
</div>
</nav>
</template>
<template id="portal_record_layout" name="Portal single record layout">
<div t-attf-class="card mt-0 border-top-0 rounded-0 rounded-bottom #{classes if classes else ''}">
<div t-if="card_header" t-attf-class="card-header #{header_classes if header_classes else ''}">
<t t-raw="card_header"/>
</div>
<div t-if="card_body" t-attf-class="card-body #{body_classes if body_classes else ''}">
<t t-raw="card_body"/>
</div>
</div>
</template>
<template id="portal_contact" name="Contact">
<div class="o_portal_contact_details mb-5">
<h4><t t-if="title" t-esc="title"/><t t-else="">Your contact</t></h4>
<hr class="mt-1 mb0"/>
<h6 class="mb-1"><b t-esc="sales_user.name"/></h6>
<div class="d-flex align-items-center mb-1">
<div class="fa fa-envelope fa-fw mr-1"></div>
<a t-att-href="'mailto:'+sales_user.email" t-esc="sales_user.email"/>
</div>
<div class="d-flex flex-nowrap align-items-center mb-1">
<div class="fa fa-phone fa-fw mr-1"></div>
<span t-esc="sales_user.phone"/>
</div>
<div class="d-flex flex-nowrap align-items-center mb-1">
<div class="fa fa-map-marker fa-fw mr-1"></div>
<span t-esc="sales_user.city"/>
</div>
</div>
</template>
<template id="portal_my_details">
<t t-call="portal.portal_layout">
<t t-set="additional_title">Contact Details</t>
<form action="/my/account" method="post">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<div class="row o_portal_details">
<div class="col-lg-8">
<div class="row">
<t t-set="partner_can_edit_vat" t-value="partner.can_edit_vat()"/>
<div class="col-lg-12">
<div t-if="error_message" class="alert alert-danger" role="alert">
<t t-foreach="error_message" t-as="err"><t t-esc="err"/><br /></t>
</div>
</div>
<div t-attf-class="form-group #{error.get('name') and 'o_has_error' or ''} col-xl-6">
<label class="col-form-label" for="name">Name</label>
<input type="text" name="name" t-attf-class="form-control #{error.get('name') and 'is-invalid' or ''}" t-att-value="name or partner.name" />
</div>
<div t-attf-class="form-group #{error.get('email') and 'o_has_error' or ''} col-xl-6">
<label class="col-form-label" for="email">Email</label>
<input type="email" name="email" t-attf-class="form-control #{error.get('email') and 'is-invalid' or ''}" t-att-value="email or partner.email" />
</div>
<div class="clearfix" />
<div t-attf-class="form-group #{error.get('company_name') and 'o_has_error' or ''} col-xl-6">
<label class="col-form-label label-optional" for="company_name">Company Name</label>
<!-- The <input> is replace by a <p> to avoid sending an unauthorized value on form submit.
The user might not have rights to change company_name but should still be able to see it.
-->
<p t-if="not partner_can_edit_vat" t-attf-class="form-control" readonly="1" t-esc="partner.commercial_company_name" title="Changing company name is not allowed once document(s) have been issued for your account. Please contact us directly for this operation."/>
<input t-else="" type="text" name="company_name" t-attf-class="form-control #{error.get('company_name') and 'is-invalid' or ''}" t-att-value="company_name or partner.commercial_company_name"/>
</div>
<div t-attf-class="form-group #{error.get('vat') and 'o_has_error' or ''} col-xl-6">
<label class="col-form-label label-optional" for="vat">VAT Number</label>
<t t-set="vat_not_editable_message">Changing VAT number is not allowed once document(s) have been issued for your account. Please contact us directly for this operation.</t>
<input type="text" name="vat" t-attf-class="form-control #{error.get('vat') and 'is-invalid' or ''}" t-att-value="vat or partner.vat" t-att-readonly="None if partner_can_edit_vat else '1'" t-att-title="None if partner_can_edit_vat else vat_not_editable_message" />
</div>
<div t-attf-class="form-group #{error.get('phone') and 'o_has_error' or ''} col-xl-6">
<label class="col-form-label" for="phone">Phone</label>
<input type="tel" name="phone" t-attf-class="form-control #{error.get('phone') and 'is-invalid' or ''}"
t-att-value="phone or partner.phone" />
</div>
<div class="clearfix" />
<div t-attf-class="form-group #{error.get('street') and 'o_has_error' or ''} col-xl-6">
<label class="col-form-label" for="street">Street</label>
<input type="text" name="street" t-attf-class="form-control #{error.get('street') and 'is-invalid' or ''}" t-att-value="street or partner.street"/>
</div>
<div t-attf-class="form-group #{error.get('city') and 'o_has_error' or ''} col-xl-6">
<label class="col-form-label" for="city">City</label>
<input type="text" name="city" t-attf-class="form-control #{error.get('city') and 'is-invalid' or ''}" t-att-value="city or partner.city" />
</div>
<div t-attf-class="form-group #{error.get('zip') and 'o_has_error' or ''} col-xl-6">
<label class="col-form-label label-optional" for="zipcode">Zip / Postal Code</label>
<input type="text" name="zipcode" t-attf-class="form-control #{error.get('zip') and 'is-invalid' or ''}" t-att-value="zipcode or partner.zip" />
</div>
<div t-attf-class="form-group #{error.get('country_id') and 'o_has_error' or ''} col-xl-6">
<label class="col-form-label" for="country_id">Country</label>
<select name="country_id" t-attf-class="form-control #{error.get('country_id') and 'is-invalid' or ''}">
<option value="">Country...</option>
<t t-foreach="countries or []" t-as="country">
<option t-att-value="country.id" t-att-selected="country.id == int(country_id) if country_id else country.id == partner.country_id.id">
<t t-esc="country.name" />
</option>
</t>
</select>
</div>
<div t-attf-class="form-group #{error.get('state_id') and 'o_has_error' or ''} col-xl-6">
<label class="col-form-label label-optional" for="state_id">State / Province</label>
<select name="state_id" t-attf-class="form-control #{error.get('state_id') and 'is-invalid' or ''}">
<option value="">select...</option>
<t t-foreach="states or []" t-as="state">
<option t-att-value="state.id" style="display:none;" t-att-data-country_id="state.country_id.id" t-att-selected="state.id == partner.state_id.id">
<t t-esc="state.name" />
</option>
</t>
</select>
</div>
<input type="hidden" name="redirect" t-att-value="redirect"/>
</div>
<div class="clearfix">
<button type="submit" class="btn btn-primary float-right mb32 ">
Confirm
<span class="fa fa-long-arrow-right" />
</button>
</div>
</div>
</div>
</form>
</t>
</template>
<template id="portal_my_security">
<t t-call="portal.portal_layout"><div class="o_portal_security_body">
<t t-set="additional_title">Security</t>
<t t-set="no_breadcrumbs" t-value="1"/>
<div class="alert alert-danger" role="alert" t-if="get_error(errors)">
<t t-esc="errors"/>
</div>
<section>
<h3>Change Password</h3>
<t t-set="path">password</t>
<div class="alert alert-success" role="alert" t-if="success and success.get('password')">
Password Updated!
</div>
<div class="alert alert-danger" role="alert" t-if="get_error(errors, 'password')">
<t t-esc="errors['password']"/>
</div>
<form action="/my/security" method="post" class="oe_reset_password_form">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<input type="hidden" name="op" value="password"/>
<div class="form-group">
<label for="current">Password:</label>
<input type="password" t-attf-class="form-control form-control-sm {{ 'is-invalid' if get_error(errors, 'password.old') else '' }}"
id="current" name="old"
autocomplete="current-password" required="required"/>
<div class="invalid-feedback">
<t t-esc="get_error(errors, 'password.old')"/>
</div>
</div>
<div class="form-group">
<label for="new">New Password:</label>
<input type="password" t-attf-class="form-control form-control-sm {{ 'is-invalid' if get_error(errors, 'password.new1') else '' }}"
id="new" name="new1"
autocomplete="new-password" required="required"/>
<div class="invalid-feedback">
<t t-esc="get_error(errors, 'password.new1')"/>
</div>
</div>
<div class="form-group">
<label for="new2">Verify New Password:</label>
<input type="password" t-attf-class="form-control form-control-sm {{ 'is-invalid' if get_error(errors, 'password.new2') else '' }}"
id="new2" name="new2"
autocomplete="new-password" required="required"/>
<div class="invalid-feedback">
<t t-esc="get_error(errors, 'password.new2')"/>
</div>
</div>
<button type="submit" class="btn btn-danger">Change Password</button>
</form>
</section>
</div></t>
</template>
<template id="record_pager" name="Portal Record Pager">
<t t-if='prev_record or next_record'>
<div class="record_pager btn-group" role="group">
<a role="button" t-att-class="'btn btn-link %s' % ('disabled' if not prev_record else '')" t-att-href="prev_record or '#'" ><i class="fa fa-chevron-left" role="img" aria-label="Previous" title="Previous"></i></a>
<a role="button" t-att-class="'btn btn-link %s' % ('disabled' if not next_record else '')" t-att-href="next_record or '#'" ><i class="fa fa-chevron-right" role="img" aria-label="Next" title="Next"></i></a>
</div>
</t>
</template>
<template id="pager" name="Pager">
<ul t-if="pager['page_count'] > 1" t-attf-class="#{ classname or '' } pagination m-0 #{_classes}" t-att-style="style or None">
<li t-attf-class="page-item #{'disabled' if pager['page']['num'] == 1 else ''}">
<a t-att-href=" pager['page_previous']['url'] if pager['page']['num'] != 1 else None" t-attf-class="page-link #{extraLinkClass}">Prev</a>
</li>
<t t-foreach="pager['pages']" t-as="page">
<li t-attf-class="page-item #{'active' if page['num'] == pager['page']['num'] else ''}"> <a t-att-href="page['url']" t-attf-class="page-link #{extraLinkClass}" t-raw="page['num']"></a></li>
</t>
<li t-attf-class="page-item #{'disabled' if pager['page']['num'] == pager['page_count'] else ''}">
<a t-att-href="pager['page_next']['url'] if pager['page']['num'] != pager['page_count'] else None" t-attf-class="page-link #{extraLinkClass}">Next</a>
</li>
</ul>
</template>
<template id="my_account_link" name="Link to frontend portal" inherit_id="portal.user_dropdown">
<xpath expr="//*[@id='o_logout_divider']" position="before">
<a href="/my/home" role="menuitem" class="dropdown-item">My Account</a>
</xpath>
</template>
<!--
Generic chatter template for the frontend
This template provide the container of the chatter. The rest is done in js.
To use this template, you need to call it after setting the following variable in your template or in your controller:
:object browserecord : the mail_thread object
:message_per_page int (optional): number of message per chatter page
:token string (optional): if you want your chatter to be available for non-logged user,
you can use a token to verify the identity of the user;
the message will be posted with the identity of the partner_id of the object
:hash : signed token with the partner_id using `_sign_token` method (on mail.thread)
:pid : identifier of the partner signing the token
-->
<template id="message_thread">
<div id="discussion" data-anchor="true" class="d-print-none o_portal_chatter o_not_editable p-0"
t-att-data-token="token" t-att-data-res_model="object._name" t-att-data-pid="pid" t-att-data-hash="hash" t-att-data-res_id="object.id" t-att-data-pager_step="message_per_page or 10" t-att-data-allow_composer="'0' if disable_composer else '1'">
</div>
</template>
<!--
Snippet to request user signature in the portal. The feature comes with
the JS file `portal_signature.js`.
The following variable has to be set:
- {string} call_url: url where to send the name and signature by RPC
The url should contain a query string if additional parameters
have to be sent, such as an access token.
The following variables are optional:
- {string} default_name: the default name to display
- {string} mode: 'draw', 'auto', or 'load'
- {string} send_label: label of the send button
- {number} signature_ratio: ratio of the signature area
- {string} signature_type: 'signature' or 'initial'
For the default values and more information, see init() of the widgets
SignatureForm and NameAndSignature.
-->
<template id="portal.signature_form" name="Ask Signature">
<div class="o_portal_signature_form"
t-att-data-call-url="call_url"
t-att-data-default-name="default_name"
t-att-data-mode="mode"
t-att-data-send-label="send_label"
t-att-data-signature-ratio="signature_ratio"
t-att-data-signature-type="signature_type"
t-att-data-font-color="font_color"
/>
</template>
<template id="portal_sidebar" name="Sidebar">
<t t-call="portal.portal_layout">
<body data-spy="scroll" data-target=".navspy" data-offset="50">
<div class="container o_portal_sidebar"></div>
<div class="oe_structure mb32" id="oe_structure_portal_sidebar_1"/>
</body>
</t>
</template>
</odoo>