[IMP] project : optimize SCSS

SCSS optimization of the right side panel in project module.

Remove custom SCSS and use Bootstrap classes instead.

task : 2977963

X-original-commit: 9045dfbaece4e2cef153597632fd473cbb6cdb6f
Part-of: odoo/odoo#102686
This commit is contained in:
Antoine (anso)
2022-10-07 18:48:08 +02:00
parent 975e8f911e
commit fa048082f2
8 changed files with 106 additions and 218 deletions
@@ -27,7 +27,7 @@ export class ProjectMilestone extends Component {
}
_getColorClass() {
return this.milestone.is_deadline_exceeded && !this.milestone.can_be_marked_as_done ? "o_milestone_danger" : this.milestone.can_be_marked_as_done ? "o_color_green" : "";
return this.milestone.is_deadline_exceeded && !this.milestone.can_be_marked_as_done ? "text-danger" : this.milestone.can_be_marked_as_done ? "text-success" : "";
}
_getCheckBoxIcon() {
@@ -2,21 +2,23 @@
<templates id="template" xml:space="preserve">
<t t-name="project.ProjectMilestone" owl="1">
<div class="o_rightpanel_milestone" t-att-class="state.colorClass">
<span class="o_milestone_checkbox" t-on-click="toggleIsReached">
<i class="fa" t-att-class="state.checkboxIcon"></i>
</span>
<div class="o_milestone_detail" t-on-click="onOpenMilestone">
<div class="o_milestone_info">
<t t-esc="milestone.name"/>
<div class="list-group mb-2">
<div class="o_rightpanel_milestone list-group-item list-group-item-action d-flex cursor-pointer" t-att-class="state.colorClass">
<span t-on-click="toggleIsReached">
<i class="fa position-absolute pt-1" t-att-class="state.checkboxIcon"/>
</span>
<div class="o_milestone_detail d-flex justify-content-between ps-4 w-100" t-on-click="onOpenMilestone">
<div class="d-flex flex-column">
<t t-esc="milestone.name"/>
</div>
<span class="d-flex justify-content-center align-items-center">
<t t-esc="deadline"/>
</span>
</div>
<span class="o_rightpanel_center_col">
<t t-esc="deadline"/>
<span class="d-flex align-items-center ms-3">
<a t-on-click="onDeleteMilestone" title="Delete Milestone"><i class="fa fa-trash"/></a>
</span>
</div>
<span class="o_rightpanel_right_col">
<a class="o_delete_icon" t-on-click="onDeleteMilestone" title="Delete Milestone"><i class="fa fa-trash"></i></a>
</span>
</div>
</t>
@@ -1,86 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<templates id="template" xml:space="preserve">
<t t-name="project.ProjectProfitability" owl="1">
<div class="o_rightpanel_subsection" t-if="revenues.data.length">
<table class="w-100 table-striped">
<div class="o_rightpanel_subsection pb-3" t-if="revenues.data.length">
<table class="table table-striped table-hover mb-0">
<thead>
<tr>
<th style="width: 40%">Revenues</th>
<th style="width: 20%; text-align: right;">Invoiced</th>
<th style="width: 20%; text-align: right;">To Invoice</th>
<th style="width: 20%; text-align: right;">Expected</th>
<th>Revenues</th>
<th class="text-end">Invoiced</th>
<th class="text-end">To Invoice</th>
<th class="text-end">Expected</th>
</tr>
</thead>
<tbody>
<tr t-foreach="revenues.data" t-as="revenue" t-key="revenue.id" t-if="revenue.invoiced !== 0 || revenue.to_invoice !== 0">
<t t-set="revenue_label" t-value="props.labels[revenue.id] or revenue.id"/>
<td>
<a t-if="revenue.action" class="o_rightpanel_button"
<td class="align-middle">
<a t-if="revenue.action" href="#"
t-on-click="() => this.props.onClick(revenue.action)"
>
<t t-esc="revenue_label"/>
</a>
<t t-esc="revenue_label" t-else=""/>
</td>
<td align="right" t-attf-class="{{ revenue.invoiced === 0 ? 'text-muted' : ''}}"><t t-esc="props.formatMonetary(revenue.invoiced)"/></td>
<td align="right" t-attf-class="{{ revenue.to_invoice === 0 ? 'text-muted' : ''}}"><t t-esc="props.formatMonetary(revenue.to_invoice)"/></td>
<td align="right" t-attf-class="{{ revenue.invoiced + revenue.to_invoice === 0 ? 'text-muted' : ''}}"><t t-esc="props.formatMonetary(revenue.invoiced + revenue.to_invoice)"/></td>
<td t-attf-class="text-end align-middle {{ revenue.invoiced === 0 ? 'text-500' : ''}}"><t t-esc="props.formatMonetary(revenue.invoiced)"/></td>
<td t-attf-class="text-end align-middle {{ revenue.to_invoice === 0 ? 'text-500' : ''}}"><t t-esc="props.formatMonetary(revenue.to_invoice)"/></td>
<td t-attf-class="text-end align-middle {{ revenue.invoiced + revenue.to_invoice === 0 ? 'text-500' : ''}}"><t t-esc="props.formatMonetary(revenue.invoiced + revenue.to_invoice)"/></td>
</tr>
</tbody>
<tfoot>
<tr>
<tr class="fw-bolder">
<td>Total</td>
<td align="right" t-attf-class="{{ revenues.total.invoiced === 0 ? 'text-muted' : ''}}"><t t-esc="props.formatMonetary(revenues.total.invoiced)"/></td>
<td align="right" t-attf-class="{{ revenues.total.to_invoice === 0 ? 'text-muted' : ''}}"><t t-esc="props.formatMonetary(revenues.total.to_invoice)"/></td>
<td align="right" t-attf-class="{{ revenues.total.invoiced + revenues.total.to_invoice === 0 ? 'text-muted' : ''}}"><t t-esc="props.formatMonetary(revenues.total.invoiced + revenues.total.to_invoice)"/></td>
<td t-attf-class="text-end {{ revenues.total.invoiced === 0 ? 'text-500' : ''}}"><t t-esc="props.formatMonetary(revenues.total.invoiced)"/></td>
<td t-attf-class="text-end {{ revenues.total.to_invoice === 0 ? 'text-500' : ''}}"><t t-esc="props.formatMonetary(revenues.total.to_invoice)"/></td>
<td t-attf-class="text-end {{ revenues.total.invoiced + revenues.total.to_invoice === 0 ? 'text-500' : ''}}"><t t-esc="props.formatMonetary(revenues.total.invoiced + revenues.total.to_invoice)"/></td>
</tr>
</tfoot>
</table>
</div>
<div class="o_rightpanel_subsection" t-if="costs.data.length">
<table class="w-100 table-striped">
<div class="o_rightpanel_subsection pb-3" t-if="costs.data.length">
<table class="table table-striped table-hover mb-0">
<thead>
<tr>
<th style="width: 40%">Costs</th>
<th style="width: 20%; text-align: right;">Billed</th>
<th style="width: 20%; text-align: right;">To Bill</th>
<th style="width: 20%; text-align: right;">Expected</th>
<th>Costs</th>
<th class="text-end">Billed</th>
<th class="text-end">To Bill</th>
<th class="text-end">Expected</th>
</tr>
</thead>
<tbody>
<tr t-foreach="costs.data" t-as="cost" t-key="cost.id" t-if="cost.billed !== 0 || cost.to_bill !== 0">
<t t-set="cost_label" t-value="props.labels[cost.id] or cost.id"/>
<td>
<a t-if="cost.action" class="o_rightpanel_button"
<td class="align-middle">
<a t-if="cost.action" href="#"
t-on-click="() => this.props.onClick(cost.action)"
>
<t t-esc="cost_label"/>
</a>
<t t-esc="cost_label" t-else=""/>
</td>
<td align="right" t-attf-class="{{ cost.billed === 0 ? 'text-muted' : ''}}"><t t-esc="props.formatMonetary(cost.billed)"/></td>
<td align="right" t-attf-class="{{ cost.to_bill === 0 ? 'text-muted' : ''}}"><t t-esc="props.formatMonetary(cost.to_bill)"/></td>
<td align="right" t-attf-class="{{ cost.billed + cost.to_bill === 0 ? 'text-muted' : ''}}"><t t-esc="props.formatMonetary(cost.billed + cost.to_bill)"/></td>
<td t-attf-class="text-end align-middle {{ cost.billed === 0 ? 'text-500' : ''}}"><t t-esc="props.formatMonetary(cost.billed)"/></td>
<td t-attf-class="text-end align-middle {{ cost.to_bill === 0 ? 'text-500' : ''}}"><t t-esc="props.formatMonetary(cost.to_bill)"/></td>
<td t-attf-class="text-end align-middle {{ cost.billed + cost.to_bill === 0 ? 'text-500' : ''}}"><t t-esc="props.formatMonetary(cost.billed + cost.to_bill)"/></td>
</tr>
</tbody>
<tfoot>
<tr>
<tr class="fw-bolder">
<td>Total</td>
<td align="right" t-attf-class="{{ costs.total.billed === 0 ? 'text-muted' : ''}}"><t t-esc="props.formatMonetary(costs.total.billed)"/></td>
<td align="right" t-attf-class="{{ costs.total.to_bill === 0 ? 'text-muted' : ''}}"><t t-esc="props.formatMonetary(costs.total.to_bill)"/></td>
<td align="right" t-attf-class="{{ costs.total.billed + costs.total.to_bill === 0 ? 'text-muted' : ''}}"><t t-esc="props.formatMonetary(costs.total.billed + costs.total.to_bill)"/></td>
<td t-attf-class="text-end {{ costs.total.billed === 0 ? 'text-500' : ''}}"><t t-esc="props.formatMonetary(costs.total.billed)"/></td>
<td t-attf-class="text-end {{ costs.total.to_bill === 0 ? 'text-500' : ''}}"><t t-esc="props.formatMonetary(costs.total.to_bill)"/></td>
<td t-attf-class="text-end {{ costs.total.billed + costs.total.to_bill === 0 ? 'text-500' : ''}}"><t t-esc="props.formatMonetary(costs.total.billed + costs.total.to_bill)"/></td>
</tr>
</tfoot>
</table>
</div>
<div class="o_rightpanel_subsection">
<table class="w-100 table-striped">
<table class="w-100 table table-borderless mb-4">
<thead>
<tr>
<th style="width: 40%">Margin</th>
<th style="width: 20%; text-align: right;" t-att-class="margin.invoiced_billed &lt; 0 ? 'o_color_red' : 'o_color_green'"><t t-esc="props.formatMonetary(margin.invoiced_billed)"/></th>
<th style="width: 20%; text-align: right;" t-att-class="margin.to_invoice_to_bill &lt; 0 ? 'o_color_red' : 'o_color_green'"><t t-esc="props.formatMonetary(margin.to_invoice_to_bill)"/></th>
<th style="width: 20%; text-align: right;" t-att-class="margin.total &lt; 0 ? 'o_color_red' : 'o_color_green'"><t t-esc="props.formatMonetary(margin.total)"/></th>
<th>Margin</th>
<th class="text-end" t-att-class="margin.invoiced_billed &lt; 0 ? 'text-danger' : 'text-success'"><t t-esc="props.formatMonetary(margin.invoiced_billed)"/></th>
<th class="text-end" t-att-class="margin.to_invoice_to_bill &lt; 0 ? 'text-danger' : 'text-success'"><t t-esc="props.formatMonetary(margin.to_invoice_to_bill)"/></th>
<th class="text-end" t-att-class="margin.total &lt; 0 ? 'text-danger' : 'text-success'"><t t-esc="props.formatMonetary(margin.total)"/></th>
</tr>
</thead>
</table>
@@ -2,14 +2,14 @@
<templates id="template" xml:space="preserve">
<t t-name="project.ProjectRightSidePanelSection" owl="1">
<div class="o_rightpanel_section" t-att-name="props.name" t-if="props.show">
<div class="o_rightpanel_header" t-if="props.header">
<div class="o_rightpanel_title cursor-default" t-if="props.slots.title">
<t t-slot="title"/>
<div class="o_rightpanel_section py-0" t-att-name="props.name" t-if="props.show">
<div class="o_rightpanel_header d-flex align-items-center justify-content-between py-4" t-if="props.header">
<div class="o_rightpanel_title d-flex flex-row-reverse align-items-center" t-if="props.slots.title">
<h3 class="m-0 lh-lg"><t t-slot="title"/></h3>
</div>
<t t-slot="header"/>
</div>
<div class="o_rightpanel_data" t-if="props.showData">
<div class="o_rightpanel_data fs-6" t-if="props.showData">
<t t-slot="default"/>
</div>
</div>
@@ -29,71 +29,17 @@ $o-rightpanel-filter-default-color: #D59244;
.o_rightpanel {
flex: 0 0 37%;
overflow: auto;
height: 100%;
padding: $o-rightpanel-p-small $o-rightpanel-p $o-rightpanel-p*2 $o-rightpanel-p;
border-left: 1px solid $gray-300;
background-color: white;
min-width: 400px;
max-width: 1140px;
.o_rightpanel_section {
padding-bottom: $o-rightpanel-p;
padding-top: $o-rightpanel-p;
&:nth-child(n+3){
border-top: 1px solid $gray-300;
}
&:first-child{
padding-bottom: 0px;
}
&:nth-child(2){
padding-top: 0px;
}
.o_rightpanel_button {
cursor: pointer;
font-size: small;
color: $o-brand-primary;
&:hover {
color: #001d1f;
text-decoration: none;
}
}
.o_rightpanel_header {
padding: $o-rightpanel-p-tiny 0 $o-rightpanel-p-small 0;
.o_rightpanel_title {
padding: 8px 0;
font-weight: bold;
font-size: large;
display:inline;
}
.o_rightpanel_button {
font-weight: bold;
float: right;
padding-top: $o-rightpanel-p-tiny;
}
&:nth-child(n+3) {
border-top: 1px solid $border-color;
}
/* UNUSED SCSS TO REMOVE
.o_rightpanel_data {
font-size: small;
.table-striped{
tbody tr:nth-of-type(odd) {
background-color: $gray-100;
}
}
.o_rightpanel_data_row, table > tbody > tr {
&:not(.o_rightpanel_nohover):hover {
background-color: $gray-200;
border-radius: 5px;
}
}
.o_rightpanel_left_col {
font-size: small;
padding-top: 0;
@@ -106,99 +52,21 @@ $o-rightpanel-filter-default-color: #D59244;
padding-right: $o-rightpanel-p-small;
}
}
.o_rightpanel_right_col {
float: right;
display: flex;
align-items: center;
.o_milestone_checkbox {
display: flex;
align-items: center;
}
}
.o_rightpanel_center_col {
flex-grow: 1;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.o_rightpanel_milestone {
margin-bottom: $o-rightpanel-p-small;
display: flex;
&.o_milestone_danger {
color: $red;
}
.o_milestone_checkbox {
cursor: pointer;
padding-right: $o-rightpanel-p-tiny;
}
.o_milestone_detail {
cursor: pointer;
display: flex;
justify-content: space-between;
flex-grow: 1;
.o_milestone_info {
display: flex;
flex-direction: column;
flex: 30%;
}
}
.o_delete_icon {
cursor: pointer;
padding-left: $o-rightpanel-p-tiny;
}
}
.o_rightpanel_subsection {
&:not(:last-child) {
padding-bottom: 1rem;
}
}
td.text-bold {
font-weight: bold;
}
table > tfoot {
font-weight: bold;
border-top: 1px solid black;
}
}
.o_rightpanel_hidden {
display: none;
}
.o_color_red {
color: $red;
}
.o_color_green {
color: $green;
}
*/
.o_form_view {
.oe_button_box {
display: flex;
flex-wrap: wrap;
margin-left: -16px;
margin-right: -16px;
@media screen and (max-device-width: 768px) {
margin-top: -4px;
margin-bottom: 0px;
}
margin: -1px (-$o-rightpanel-p) 0;
.oe_stat_button {
flex-basis: 25%;
border: 1px solid $border-color;
margin-top: -1px;
margin-left: -1px;
height: 57.5px;
&:nth-child(4n):not(:last-child){
border-right-width: 0px;
&:nth-child(4n):not(:last-child) {
border-right-width: 0;
}
.o_stat_text {
@@ -211,13 +79,25 @@ $o-rightpanel-filter-default-color: #D59244;
flex-basis: 33.33%;
&:nth-child(3n):not(:last-child) {
border-right-width: 0px;
border-right-width: 0px !important;
}
&:nth-child(4n):not(:last-child){
border-right-width: 1px;
}
}
}
}
}
}
.o_rightpanel_header {
@include media-breakpoint-down(md) {
cursor: pointer;
}
}
tr th:not(:first-child) {
width: 20%;
}
}
}
@@ -2,18 +2,19 @@
<templates id="template" xml:space="preserve">
<t t-name="project.ProjectRightSidePanel" owl="1">
<div t-if="projectId" class="o_rightpanel">
<ProjectRightSidePanelSection
<div t-if="projectId" class="o_rightpanel pt-0 bg-white border-start overflow-auto">
<ProjectRightSidePanelSection
name="'stat_buttons'"
header="false"
show="!!state.data.buttons"
>
<div class="o_form_view">
<div class="oe_button_box o-form-buttonbox">
<div class="oe_button_box o-form-buttonbox d-flex flex-wrap">
<t t-foreach="state.data.buttons" t-as="button" t-key="button.action">
<ViewButton
t-if="button.show"
defaultRank="'oe_stat_button'"
className="'h-auto py-2 border border-start-0 border-top-0'"
icon="`fa-${button.icon}`"
title="button.text"
clickParams="_getStatButtonClickParams(button)"
@@ -53,7 +54,7 @@
show="!!state.data.milestones &amp;&amp; !!state.data.milestones.data"
>
<t t-set-slot="header" owl="1">
<span class="o_rightpanel_button">
<span class="btn btn-secondary">
<div class="o_add_milestone">
<a t-on-click="addMilestone">Add Milestone</a>
</div>
@@ -80,15 +80,15 @@
<t t-esc="record.user_id.value"/>
</div>
</div>
<div class="col-sm-2 text-sm-start col-6 text-end align-end">
<div class="col-sm-2 text-sm-start col-6 align-end">
<field name="color" invisible="1"/>
<b><field name="status" widget="status_with_color" options="{'color_field': 'color'}"/></b>
</div>
<div class="col-sm-2 col-6">
<div class="col-sm-2 col-6 pb-0">
<b><field name="progress_percentage" widget="percentage"/></b>
<div>Progress</div>
</div>
<div class="col-sm-2 col-6">
<div class="col-sm-2 col-6 pb-0">
<b><field name="date"/></b>
<div>Date</div>
</div>
@@ -10,13 +10,13 @@
<t t-set-slot="title" owl="1">
Sales
</t>
<table class="w-100 table-striped">
<table class="table table-striped table-hover mb-4">
<thead>
<tr>
<th style="width: 40%">Sales Order Items</th>
<th style="width: 20%; text-align: right;">Sold</th>
<th style="width: 20%; text-align: right;">Delivered</th>
<th style="width: 20%; text-align: right;">Invoiced</th>
<th>Sales Order Items</th>
<th class="text-end">Sold</th>
<th class="text-end">Delivered</th>
<th class="text-end">Invoiced</th>
</tr>
</thead>
<tbody>
@@ -24,25 +24,30 @@
<t t-set="uom_name" t-value="sale_item.product_uom and sale_item.product_uom[1]"/>
<td>
<t t-set="sol_name" t-value="sale_item.display_name"/>
<a t-if="sale_item.action" class="o_rightpanel_button"
t-on-click="() => this.onProjectActionClick(sale_item.action)"
>
<a t-if="sale_item.action" class="o_rightpanel_button" href="#" t-on-click="() => this.onProjectActionClick(sale_item.action)">
<t t-esc="sol_name"/>
</a>
<t t-else="" t-esc="sol_name"/>
</td>
<td align="right"><t t-esc="formatValue(sale_item.product_uom_qty, uom_name)"/> <t t-esc="uom_name"/></td>
<td align="right"><t t-esc="formatValue(sale_item.qty_delivered, uom_name)"/> <t t-esc="uom_name"/></td>
<td align="right"><t t-esc="formatValue(sale_item.qty_invoiced, uom_name)"/> <t t-esc="uom_name"/></td>
<td class="text-end align-middle"><t t-esc="formatValue(sale_item.product_uom_qty, uom_name)"/> <t t-esc="uom_name"/></td>
<td class="text-end align-middle"><t t-esc="formatValue(sale_item.qty_delivered, uom_name)"/> <t t-esc="uom_name"/></td>
<td class="text-end align-middle"><t t-esc="formatValue(sale_item.qty_invoiced, uom_name)"/> <t t-esc="uom_name"/></td>
</tr>
<tr class="o_rightpanel_nohover" t-if="state.data.sale_items.total &gt; state.data.sale_items.data.length">
<td>
<a class="o_rightpanel_button text-bold" t-on-click="onLoadSalesOrderLinesClick">
</tbody>
<tfoot>
<tr class="o_rightpanel_nohover border-0" t-if="state.data.sale_items.total &gt; state.data.sale_items.data.length">
<td class="pb-0 border-0 text-center" colspan="4">
<a class="btn btn-link" t-on-click="onLoadSalesOrderLinesClick">
Load more
</a>
</td>
</tr>
</tbody>
<tr t-else="">
<td class="pb-0 border-0 shadow-none text-center" colspan="4">
<small class="text-muted">All items have been loaded</small>
</td>
</tr>
</tfoot>
</table>
</ProjectRightSidePanelSection>
</xpath>