[REF] portal, *: use a template for tables

Use a template in order to simplify maintenance and keep a consistent design
This commit is contained in:
sri-odoo
2018-09-12 09:37:56 +02:00
committed by qsm-odoo
parent 1f946a2bec
commit c78a2dbd8f
8 changed files with 233 additions and 244 deletions
@@ -32,46 +32,43 @@
<t t-if="not invoices">
<p>There are currently no invoices and payments for your account.</p>
</t>
<div t-if="invoices" class="card">
<div class="table-responsive"><table class="table table-hover o_portal_my_doc_table">
<thead>
<tr class="active">
<th>Invoice #</th>
<th>Invoice Date</th>
<th class='d-none d-md-table-cell'>Due Date</th>
<th></th>
<th>Amount Due</th>
</tr>
</thead>
<t t-if="invoices" t-call="portal.portal_table">
<thead>
<tr class="active">
<th>Invoice #</th>
<th>Invoice Date</th>
<th class='d-none d-md-table-cell'>Due Date</th>
<th/>
<th class="text-right">Amount Due</th>
</tr>
</thead>
<tbody>
<t t-foreach="invoices" t-as="invoice">
<tr>
<td>
<a t-att-href="invoice.get_portal_url()" t-att-title="invoice.number">
<t t-esc="invoice.number" t-if="invoice.number"/>
<t t-else="">Draft Invoice</t>
<em t-else="">Draft Invoice</em>
</a>
</td>
<td><span t-field="invoice.date_invoice"/></td>
<td class='d-none d-md-table-cell'><span t-field="invoice.date_due"/></td>
<td class="tx_status">
<t t-if="invoice.state == 'open'">
<span class="badge badge-info"><i class="fa fa-fw fa-clock-o" aria-label="Opened" title="Opened" role="img"></i><span class="d-none d-md-inline"> Waiting for Payment</span></span>
<span class="badge badge-pill badge-info"><i class="fa fa-fw fa-clock-o" aria-label="Opened" title="Opened" role="img"></i><span class="d-none d-md-inline"> Waiting for Payment</span></span>
</t>
<t t-if="invoice.state == 'paid'">
<span class="badge badge-secondary"><i class="fa fa-fw fa-check" aria-label="Paid" title="Paid" role="img"></i><span class="d-none d-md-inline"> Paid</span></span>
<span class="badge badge-pill badge-success"><i class="fa fa-fw fa-check" aria-label="Paid" title="Paid" role="img"></i><span class="d-none d-md-inline"> Paid</span></span>
</t>
<t t-if="invoice.state == 'cancel'">
<span class="badge badge-secondary"><i class="fa fa-fw fa-remove" aria-label="Cancelled" title="Cancelled" role="img"></i><span class="d-none d-md-inline"> Cancelled</span></span>
<span class="badge badge-pill badge-warning"><i class="fa fa-fw fa-remove" aria-label="Cancelled" title="Cancelled" role="img"></i><span class="d-none d-md-inline"> Cancelled</span></span>
</t>
</td>
<td><span t-esc="-invoice.residual if invoice.type == 'out_refund' else invoice.residual" t-options='{"widget": "monetary", "display_currency": invoice.currency_id}'/></td>
<td class="text-right"><span t-esc="-invoice.residual if invoice.type == 'out_refund' else invoice.residual" t-options='{"widget": "monetary", "display_currency": invoice.currency_id}'/></td>
</tr>
</t>
</table></div>
<div t-if="pager" class="o_portal_pager text-center">
<t t-call="portal.pager"/>
</div>
</div>
</tbody>
</t>
</t>
</template>
@@ -1,35 +1,35 @@
<odoo>
<template id="portal_my_invoices_payment" name="Payment on My Invoices" inherit_id="account.portal_my_invoices">
<xpath expr="//table[hasclass('o_portal_my_doc_table')]/thead/tr/th[last()]" position="before">
<th>Status</th>
<xpath expr="//t[@t-call='portal.portal_table']/thead/tr/th[last()]" position="before">
<th class="text-center">Status</th>
</xpath>
<xpath expr="//t[@t-foreach='invoices']/tr/td[last()]" position="before">
<td>
<td class="text-center">
<t t-set="tx_ids" t-value="invoice.transaction_ids.filtered(lambda tx: tx.state in ('pending', 'authorized', 'done'))"/>
<t t-set="pending_manual_txs" t-value="tx_ids.filtered(lambda tx: tx.state == 'pending' and tx.acquirer_id.provider in ('transfer', 'manual'))"/>
<a t-if="invoice.state == 'open' and invoice.amount_total and invoice.type == 'out_invoice' and (pending_manual_txs or not tx_ids)"
t-att-href="invoice.get_portal_url(anchor='portal_pay')" title="Pay now" aria-label="Pay now" class="btn btn-sm btn-primary" role="button">
t-att-href="invoice.get_portal_url(anchor='portal_pay')" title="Pay now" aria-label="Pay now" class="btn btn-sm btn-success" role="button">
<i class="fa fa-arrow-circle-right"/><span class='d-none d-md-inline'> Pay Now</span>
</a>
</td>
</xpath>
<xpath expr="//t[@t-foreach='invoices']/tr/td[hasclass('tx_status')]" position="replace">
<t t-set="last_tx" t-value="invoice.get_portal_last_transaction()"/>
<td class="tx_status">
<td class="tx_status text-center">
<t t-if="invoice.state == 'open' and (last_tx.state not in ['pending', 'authorized', 'done', 'cancel'] or (last_tx.state == 'pending' and last_tx.acquirer_id.provider in ('transfer', 'manual')))">
<span class="badge badge-info"><i class="fa fa-fw fa-clock-o"></i><span class="d-none d-md-inline"> Waiting for Payment</span></span>
<span class="badge badge-pill badge-info"><i class="fa fa-fw fa-clock-o"></i><span class="d-none d-md-inline"> Waiting for Payment</span></span>
</t>
<t t-if="invoice.state == 'open' and last_tx.state == 'authorized'">
<span class="badge badge-success"><i class="fa fa-fw fa-check"/><span class="d-none d-md-inline"> Authorized</span></span>
<span class="badge badge-pill badge-primary"><i class="fa fa-fw fa-check"/><span class="d-none d-md-inline"> Authorized</span></span>
</t>
<t t-if="invoice.state == 'open' and last_tx.state == 'pending' and last_tx.acquirer_id.provider not in ('transfer', 'manual')">
<span class="badge badge-warning"><span class="d-none d-md-inline"> Pending</span></span>
<span class="badge badge-pill badge-warning"><span class="d-none d-md-inline"> Pending</span></span>
</t>
<t t-if="invoice.state == 'paid' or last_tx.state == 'done'">
<span class="badge badge-secondary"><i class="fa fa-fw fa-check"></i><span class="d-none d-md-inline"> Paid</span></span>
<span class="badge badge-pill badge-success"><i class="fa fa-fw fa-check"></i><span class="d-none d-md-inline"> Paid</span></span>
</t>
<t t-if="invoice.state == 'cancel'">
<span class="badge badge-secondary"><i class="fa fa-fw fa-remove"></i><span class="d-none d-md-inline"> Cancelled</span></span>
<span class="badge badge-pill badge-danger"><i class="fa fa-fw fa-remove"></i><span class="d-none d-md-inline"> Cancelled</span></span>
</t>
</td>
</xpath>
+19 -4
View File
@@ -11,6 +11,13 @@ $o-portal-mobile-toolbar: true; // Enable/Disable custom design
$o-portal-mobile-toolbar-border: $border-color;
$o-portal-mobile-toolbar-bg: $gray-200;
// Portal Tables
$o-portal-table-th-pt: map-get($spacers, 2) !default; // bts4 pt-2
$o-portal-table-th-pb: map-get($spacers, 2) !default; // bts4 pb-2
$o-portal-table-td-pt: map-get($spacers, 1) !default; // bts4 pt-1
$o-portal-table-td-pb: map-get($spacers, 1) !default; // bts4 pb-1
// Resize and vertically align navbar’s items relative to navbar
@mixin o-w-fill-navbar($ratio: 1) {
height: round($-navbar-height * $ratio * 100) / 100;
@@ -349,11 +356,19 @@ img.o_we_custom_image {
}
.o_portal_my_doc_table {
td, th {
text-align: right;
th {
padding-top: $o-portal-table-th-pt;
padding-bottom: $o-portal-table-th-pb;
}
tr > :first-child {
text-align: left;
td {
padding-top: $o-portal-table-td-pt;
padding-bottom: $o-portal-table-td-pb;
}
td, th {
vertical-align: middle;
white-space: nowrap;
}
}
+11
View File
@@ -146,6 +146,17 @@
</a>
</template>
<template id="portal_table" name="My Portal Table">
<div t-attf-class="table-responsive border border-top-0 #{classes if classes else ''}">
<table class="table mb-0 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>
<!--
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
@@ -46,32 +46,21 @@
There are no projects.
</div>
</t>
<div t-if="projects" class="card">
<div class="table-responsive"><table class="table table-hover o_portal_my_doc_table">
<thead>
<tr class="active">
<th class="col-lg-6">Name</th>
<th>Tasks</th>
</tr>
</thead>
<tbody>
<tr t-foreach="projects" t-as="project">
<td>
<a t-attf-href="/my/project/#{project.id}?{{ keep_query() }}"><span t-field="project.name"/></a>
</td>
<td>
<a t-attf-href="/my/tasks?{{keep_query('debug', filterby=project.id)}}">
<t t-esc="project.task_count" />
<t t-esc="project.label_tasks" />
</a>
</td>
</tr>
</tbody>
</table></div>
</div>
<div t-if="pager" class="o_portal_pager text-center">
<t t-call="portal.pager"/>
</div>
<t t-if="projects" t-call="portal.portal_table">
<tbody>
<tr t-foreach="projects" t-as="project">
<td>
<a t-attf-href="/my/project/#{project.id}?{{ keep_query() }}"><span t-field="project.name"/></a>
</td>
<td class="text-right">
<a t-attf-href="/my/tasks?{{keep_query('debug', filterby=project.id)}}">
<t t-esc="project.task_count" />
<t t-esc="project.label_tasks" />
</a>
</td>
</tr>
</tbody>
</t>
</t>
</template>
@@ -130,40 +119,37 @@
There are no tasks.
</div>
</t>
<div t-if="grouped_tasks" class="card">
<div class="table-responsive">
<t t-if="grouped_tasks">
<t t-call="portal.portal_table">
<t t-foreach="grouped_tasks" t-as="tasks">
<table class="table table-hover o_portal_my_doc_table">
<thead>
<tr class="active">
<th t-if="groupby == 'none'" class="col-lg-9">Name</th>
<th t-else="" class="col-lg-9"><span t-field="tasks[0].sudo().project_id.label_tasks"/> for project: <span t-field="tasks[0].sudo().project_id.name"/></th>
<th class="col-lg-2">Stage</th>
<th>Ref</th>
<thead>
<tr t-attf-class="{{'thead-light' if not groupby == 'none' else ''}}">
<th t-if="groupby == 'none'">Name</th>
<th t-else="">
<em class="font-weight-normal text-muted"><span t-field="tasks[0].sudo().project_id.label_tasks"/> for project:</em>
<span t-field="tasks[0].sudo().project_id.name"/></th>
<th class="text-center">Stage</th>
<th class="text-left">Ref</th>
</tr>
</thead>
<tbody>
<t t-foreach="tasks" t-as="task">
<tr>
<td>
<a t-attf-href="/my/task/#{task.id}?{{ keep_query() }}"><span t-field="task.name"/></a>
</td>
<td class="text-center">
<span class="badge badge-pill badge-info" title="Current stage of the task" t-esc="task.stage_id.name" />
</td>
<td class="text-left">
#<span t-esc="task.id"/>
</td>
</tr>
</thead>
<tbody>
<t t-foreach="tasks" t-as="task">
<tr>
<td>
<a t-attf-href="/my/task/#{task.id}?{{ keep_query() }}"><span t-field="task.name"/></a>
</td>
<td>
<span class="badge badge-info" title="Current stage of the task" t-esc="task.stage_id.name" />
</td>
<td>
<span t-esc="task.id"/>
</td>
</tr>
</t>
</tbody>
</table>
</t>
</tbody>
</t>
</div>
</div>
<div t-if="pager" class="o_portal_pager text-center">
<t t-call="portal.pager"/>
</div>
</t>
</t>
</t>
</template>
+19 -25
View File
@@ -28,8 +28,7 @@
<t t-call="portal.portal_searchbar">
<t t-set="title">Purchase Orders</t>
</t>
<div t-if="orders" class="card">
<div class="table-responsive"><table class="table table-hover o_portal_my_doc_table">
<t t-if="orders" t-call="portal.portal_table">
<thead>
<tr class="active">
<th>Purchase Orders #</th>
@@ -38,29 +37,24 @@
<th>Total</th>
</tr>
</thead>
<t t-foreach="orders" t-as="order">
<tr>
<td>
<a t-attf-href="/my/purchase/#{order.id}?#{keep_query()}"><t t-esc="order.name"/></a>
</td>
<td><span t-field="order.date_order"/></td>
<td>
<t t-if="order.invoice_status == 'to invoice'">
<span class="badge badge-info"><i class="fa fa-fw fa-file-text"/> Waiting for Bill</span>
</t>
<t t-if="order.state == 'cancel'">
<span class="badge badge-secondary"><i class="fa fa-fw fa-remove"/> Cancelled</span>
</t>
</td>
<td><span t-field="order.amount_total" t-options='{"widget": "monetary", "display_currency": order.currency_id}'/>
</td>
</tr>
</t>
</table></div>
<div t-if="pager" class="o_portal_pager text-center">
<t t-call="portal.pager"/>
</div>
</div>
<tbody>
<t t-foreach="orders" t-as="order">
<tr>
<td><a t-attf-href="/my/purchase/#{order.id}?#{keep_query()}"><t t-esc="order.name"/></a></td>
<td><span t-field="order.date_order"/></td>
<td>
<t t-if="order.invoice_status == 'to invoice'">
<span class="badge badge-info"><i class="fa fa-fw fa-file-text"/> Waiting for Bill</span>
</t>
<t t-if="order.state == 'cancel'">
<span class="badge badge-secondary"><i class="fa fa-fw fa-remove"/> Cancelled</span>
</t>
</td>
<td><span t-field="order.amount_total" t-options='{"widget": "monetary", "display_currency": order.currency_id}'/></td>
</tr>
</t>
</tbody>
</t>
</t>
</template>
+61 -71
View File
@@ -43,42 +43,37 @@
<t t-if="not quotations">
<p>There are currently no quotations for your account.</p>
</t>
<div t-if="quotations" class="card">
<div class="table-responsive"><table class="table table-hover o_portal_my_doc_table">
<thead>
<tr class="active">
<th>Quotation #</th>
<th>Order Date</th>
<th>Valid Until</th>
<th></th>
<th>Total</th>
</tr>
</thead>
<t t-foreach="quotations" t-as="quotation">
<tr>
<td>
<a t-att-href="quotation.get_portal_url()"><t t-esc="quotation.name"/></a>
</td>
<td><span t-field="quotation.date_order"/></td>
<td><span t-field="quotation.validity_date"/></td>
<td>
<t t-if="quotation.state == 'cancel'">
<span class="badge badge-secondary"><i class="fa fa-fw fa-remove"/> Cancelled</span>
</t>
<t t-if="quotation.is_expired">
<span class="badge badge-secondary"><i class="fa fa-fw fa-clock-o"/> Expired</span>
</t>
</td>
<td>
<span t-field="quotation.amount_total"/>
</td>
</tr>
</t>
</table></div>
<div t-if="pager" class="o_portal_pager text-center">
<t t-call="portal.pager"/>
</div>
</div>
<t t-if="quotations" t-call="portal.portal_table">
<thead>
<tr class="active">
<th>Quotation #</th>
<th>Order Date</th>
<th>Valid Until</th>
<th></th>
<th>Total</th>
</tr>
</thead>
<t t-foreach="quotations" t-as="quotation">
<tr>
<td>
<a t-att-href="quotation.get_portal_url()"><t t-esc="quotation.name"/></a>
</td>
<td><span t-field="quotation.date_order"/></td>
<td><span t-field="quotation.validity_date"/></td>
<td>
<t t-if="quotation.state == 'cancel'">
<span class="badge badge-secondary"><i class="fa fa-fw fa-remove"/> Cancelled</span>
</t>
<t t-if="quotation.is_expired">
<span class="badge badge-secondary"><i class="fa fa-fw fa-clock-o"/> Expired</span>
</t>
</td>
<td>
<span t-field="quotation.amount_total"/>
</td>
</tr>
</t>
</t>
</t>
</template>
@@ -90,41 +85,36 @@
<t t-if="not orders">
<p>There are currently no orders for your account.</p>
</t>
<div t-if="orders" class="card">
<div class="table-responsive"><table class="table table-hover o_portal_my_doc_table">
<thead>
<tr class="active">
<th>
<span class='d-none d-md-inline'>Sales Order #</span>
<span class='d-block d-md-none'>Ref.</span>
</th>
<th>Order Date</th>
<th ></th>
<th>Total</th>
</tr>
</thead>
<t t-foreach="orders" t-as="order">
<tr>
<td>
<a t-att-href="order.get_portal_url()"><t t-esc="order.name"/></a>
</td>
<td>
<span t-field="order.date_order" t-options="{'widget': 'date'}"/>&amp;nbsp;
<span class='d-none d-md-inline' t-field="order.date_order" t-options="{'time_only': True}"/>
</td>
<td>
<t t-if="order.state == 'done'">
<span class="badge badge-success d-none d-md-inline-block"><i class="fa fa-fw fa-check" role="img" aria-label="Done" title="Done"></i><span class="d-none d-md-inline"> Done</span></span>
</t>
</td>
<td><span t-field="order.amount_total"/></td>
</tr>
</t>
</table></div>
<div t-if="pager" class="o_portal_pager text-center">
<t t-call="portal.pager"/>
</div>
</div>
<t t-if="orders" t-call="portal.portal_table">
<thead>
<tr class="active">
<th>
<span class='d-none d-md-inline'>Sales Order #</span>
<span class='d-block d-md-none'>Ref.</span>
</th>
<th>Order Date</th>
<th ></th>
<th>Total</th>
</tr>
</thead>
<t t-foreach="orders" t-as="order">
<tr>
<td>
<a t-att-href="order.get_portal_url()"><t t-esc="order.name"/></a>
</td>
<td>
<span t-field="order.date_order" t-options="{'widget': 'date'}"/>&amp;nbsp;
<span class='d-none d-md-inline' t-field="order.date_order" t-options="{'time_only': True}"/>
</td>
<td>
<t t-if="order.state == 'done'">
<span class="badge badge-success d-none d-md-inline-block"><i class="fa fa-fw fa-check" role="img" aria-label="Done" title="Done"></i><span class="d-none d-md-inline"> Done</span></span>
</t>
</td>
<td><span t-field="order.amount_total"/></td>
</tr>
</t>
</t>
</t>
</template>
@@ -235,40 +235,41 @@
<div t-if="not leads" class="alert alert-warning mt8" role="alert">
There are no leads.
</div>
<div t-if="leads" class="card">
<table class="table table-hover">
<thead>
<tr class="active">
<th class="col-2">Date</th>
<th class="col-5">Name</th>
<th>Contact Name</th>
</tr>
</thead>
<tbody>
<tr t-foreach="leads" t-as="lead">
<td><span t-field="lead.create_date" t-options='{"widget": "date"}' /></td>
<td>
<a t-attf-href="/my/lead/#{lead.id}"><span t-field="lead.name"/></a>
</td>
<td><span t-field="lead.contact_name" /></td>
</tr>
</tbody>
</table>
</div>
<div t-if="pager" class="o_portal_pager text-center">
<t t-call="website.pager"/>
</div>
<t t-if="leads" t-call="portal.portal_table">
<thead>
<tr>
<th>Date</th>
<th class="w-75">Name</th>
<th>Contact Name</th>
</tr>
</thead>
<tbody>
<tr t-foreach="leads" t-as="lead">
<td><span t-field="lead.create_date" t-options='{"widget": "date"}' /></td>
<td>
<a t-attf-href="/my/lead/#{lead.id}"><span t-field="lead.name"/></a>
</td>
<td><span t-field="lead.contact_name" /></td>
</tr>
</tbody>
</t>
</t>
</template>
<template id="portal_my_opportunities" name="My Opportunities">
<t t-call="portal.portal_layout">
<t t-set="breadcrumbs_searchbar" t-value="True"/>
<t t-call="portal.portal_searchbar">
<t t-set="title">My Opportunities</t>
<li class="float-left"><button t-if="request.env.user.partner_id.grade_id or request.env.user.commercial_partner_id.grade_id" name='new_opp' data-toggle="modal" data-target=".modal_new_opp" class="btn btn-secondary navbar-btn ml16" title="Add an opportunity" aria-label="Add an opportunity"><i class="fa fa-plus"/></button></li>
<div class="form-inline ml-lg-4" t-if="request.env.user.partner_id.grade_id or request.env.user.commercial_partner_id.grade_id">
<button class="btn btn-success btn-sm" name='new_opp' data-toggle="modal" data-target=".modal_new_opp" title="Add an opportunity" aria-label="Add an opportunity">
<i class="fa fa-plus"/> Create New
</button>
</div>
</t>
<div class="modal fade modal_new_opp" role="form">
<div class="modal-dialog">
<form method="POST" class="modal-content js_website_submit_form new_opp_form">
@@ -303,37 +304,32 @@
There are no opportunities.
</div>
</t>
<div class="card" t-if="opportunities">
<table class="table table-hover">
<thead>
<tr class="active">
<th class="col-2">Date</th>
<th class="col-lg-4">Name</th>
<th class="col-lg-2">Expected</th>
<th>Contact Name</th>
<th>Stage</th>
</tr>
</thead>
<tbody>
<tr t-foreach="opportunities" t-as="opp">
<td><span t-field="opp.create_date" t-options='{"widget": "date"}' /></td>
<td>
<a t-attf-href="/my/opportunity/#{opp.id}"><span t-field="opp.name"/></a>
</td>
<td>
<span class="text-nowrap" t-esc="opp.planned_revenue" t-options="{'widget': 'monetary', 'display_currency': opp.company_currency}"/> at <span t-field="opp.probability" />%
</td>
<td><span t-field="opp.contact_name" /></td>
<td>
<span class="badge badge-primary" title="Current stage of the opportunity" t-esc="opp.stage_id.name" />
</td>
</tr>
</tbody>
</table>
</div>
<div t-if="pager" class="o_portal_pager text-center">
<t t-call="website.pager"/>
</div>
<t t-if="opportunities" t-call="portal.portal_table">
<thead>
<tr class="active">
<th>Date</th>
<th class="w-50">Name</th>
<th>Contact</th>
<th>Expected</th>
<th>Stage</th>
</tr>
</thead>
<tbody>
<tr t-foreach="opportunities" t-as="opp">
<td><span t-field="opp.create_date" t-options='{"widget": "date"}' /></td>
<td>
<a t-attf-href="/my/opportunity/#{opp.id}"><span t-field="opp.name"/></a>
</td>
<td><span t-field="opp.contact_name" /></td>
<td>
<span class="text-nowrap" t-esc="opp.planned_revenue" t-options="{'widget': 'monetary', 'display_currency': opp.company_currency}"/> at <span t-field="opp.probability" />%
</td>
<td>
<span class="badge badge-info badge-pill" title="Current stage of the opportunity" t-esc="opp.stage_id.name" />
</td>
</tr>
</tbody>
</t>
</t>
</template>