Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions addons/website_sale/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@
'website_sale/static/src/scss/kanban_record.scss',
'website_sale/static/src/js/website_sale_dashboard/**/*',
'website_sale/static/src/views/**/*',
('remove', 'website_sale/static/src/js/website_sale_dashboard/**/*.dark.scss'),
],
"web.assets_web_dark": [
'website_sale/static/src/js/website_sale_dashboard/**/*.dark.scss',
],
'website.website_builder_assets': [
'website_sale/static/src/js/website_sale_form_editor.js',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class DateFilterButton extends Component {
static template = 'website_sale.DateFilterButton';
static components = { Dropdown, DropdownItem };
static props = {
selectedFilter: {
selectedDateFilter: {
type: Object,
optional: true,
shape: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates>
<t t-name="website_sale.DateFilterButton">
<Dropdown navigationOptions="{ 'shouldFocusChildInput': false }">
<button class="btn btn-secondary">
<i class="fa fa-calendar me-2"/>
<span t-esc="props.selectedFilter.label"/>
<Dropdown navigationOptions="{ 'shouldFocusChildInput': false }" position="'bottom-end'">
<button class="border-0 bg-transparent fw-normal">
<i class="fa fa-calendar-o me-2"/>
<span t-esc="props.selectedDateFilter.label"/>
<i class="fa fa-caret-down ms-2"/>
</button>
<t t-set-slot="content">
<t t-foreach="dateFilters" t-as="filter" t-key="filter.id">
<DropdownItem
tag="'div'"
class="{ 'selected': props.selectedFilter.id === filter.id, 'd-flex justify-content-between': true }"
class="{ 'selected': props.selectedDateFilter.id === filter.id, 'd-flex justify-content-between': true }"
closingMode="'none'"
onSelected="() => this.props.update(filter)"
>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.o_dashboard_card {
--DashboardCard__purple-bg-color: #{$purple-200};
--DashboardCard__purple-bg-color--active: #{$purple-300};
--DashboardCard__orange-bg-color: #{$orange-200};
--DashboardCard__orange-bg-color--active: #{$orange-300};
--DashboardCard__cyan-bg-color: #{$cyan-200};
--DashboardCard__cyan-bg-color--active: #{$cyan-300};
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useService } from '@web/core/utils/hooks';
import { useService, useBus } from '@web/core/utils/hooks';
import { Component, onWillStart, onWillUpdateProps, useState } from '@odoo/owl';
import { DateFilterButton, DATE_OPTIONS } from './date_filter_button/date_filter_button';

Expand All @@ -10,10 +10,17 @@ export class WebsiteSaleDashboard extends Component {
setup() {
this.state = useState({
eCommerceData: {},
selectedFilter: DATE_OPTIONS[0],
selectedDateFilter: DATE_OPTIONS[0],
selectedFilter: [],
});
this.orm = useService('orm');

useBus(this.env.searchModel, 'update', () => {
if(!this.isSameFilter(this.state.selectedFilter)) {
this.state.selectedFilter = null;
}
});

onWillStart(async () => {
await this.updateDashboardState();
});
Expand All @@ -24,10 +31,10 @@ export class WebsiteSaleDashboard extends Component {

async updateDashboardState(filter = false) {
if (filter) {
this.state.selectedFilter = filter;
this.state.selectedDateFilter = filter;
}
this.state.eCommerceData = await this.orm.call('sale.order', 'retrieve_dashboard', [
this.state.selectedFilter.id,
this.state.selectedDateFilter.id,
]);
}

Expand All @@ -45,6 +52,15 @@ export class WebsiteSaleDashboard extends Component {
for (const item of searchItems) {
this.env.searchModel.toggleSearchItem(item.id);
}
this.state.selectedFilter = filters;
}

isSameFilter(filters) {
if (!filters) {
return false;
}
const activeSearchFilterNames = this.env.searchModel.getSearchItems(el => el.isActive && el.type === 'filter')?.map(el => el.name).sort();
return filters.length === activeSearchFilterNames?.length && filters.sort().every((val, i) => val === activeSearchFilterNames[i]);
}

getPeriodCardClass(dataName) {
Expand All @@ -53,6 +69,26 @@ export class WebsiteSaleDashboard extends Component {
} else if (this.state.eCommerceData['period_gain'][dataName] < 0) {
return 'text-danger';
}
return 'text-muted';
return '';
}

getDashboardCardAdditionalClass(filterName) {
const dashboardCardColor = {
'to_fulfill': 'purple',
'to_confirm': 'orange',
'to_invoice': 'cyan',
};
let dashboardCardClasses = [];
const noData = this.state.eCommerceData['overall'][filterName] == 0;
if(noData) {
dashboardCardClasses.push('bg-secondary text-secondary-emphasis disabled');
} else {
dashboardCardClasses.push('o_dashboard_card_' + dashboardCardColor[filterName]);
}
const filters = filterName == 'to_confirm' ? [filterName, 'from_website'] : [filterName, 'from_website','order_confirmed'];
if(this.isSameFilter(filters)) {
dashboardCardClasses.push('active');
}
return dashboardCardClasses.join(' ');
}
}
Original file line number Diff line number Diff line change
@@ -1,73 +1,59 @@
.o_dashboard_card {
min-width: 120px;
min-height: 90px;
align-content: center;
}

.o_purple_card {
background-color: $purple-300;
}

.o_orange_card {
background-color: $orange-300;
}

.o_blue_card {
background-color: $blue-300;
}

@media (max-width: 768px) {
.o_website_sale_dashboard {
flex-direction: column !important;
align-items: center !important;
justify-content: center !important;
gap: 1.5rem !important;
}

/* Left Section: 3 cards in one row */
.o_left_section {
flex-direction: row !important;
justify-content: center !important;
flex-wrap: wrap !important;
gap: 1rem !important;
}

/* Right Section: DateFilterButton first, then metrics in one row */
.o_right_section {
flex-direction: column !important;
align-items: center !important;
justify-content: center !important;
gap: 1rem !important;
}

.o_date_filter_wrapper {
order: -1;
justify-content: center !important;
width: 100% !important;
margin-bottom: 0.5rem !important;
}

.o_cards_container {
flex-direction: row !important;
justify-content: center !important;
flex-wrap: wrap !important;
gap: 0.8rem !important;
$dashboard-colors: (
purple: (
bg: var(--DashboardCard__purple-bg-color, #{$purple-100}),
bg-active: var(--DashboardCard__purple-bg-color--active, #{$purple-200}),
color: var(--DashboardCard__purple-color, #{$purple-700}),
color-active: var(--DashboardCard__purple-color--active, #{$purple-800}),
),
cyan: (
bg: var(--DashboardCard__cyan-bg-color, #{$cyan-100}),
bg-active: var(--DashboardCard__cyan-bg-color--active, #{$cyan-200}),
color: var(--DashboardCard__cyan-color, #{$cyan-700}),
color-active: var(--DashboardCard__cyan-color--active, #{$cyan-800}),
),
orange: (
bg: var(--DashboardCard__orange-bg-color, #{$orange-100}),
bg-active: var(--DashboardCard__orange-bg-color--active, #{$orange-200}),
color: var(--DashboardCard__orange-color, #{$orange-700}),
color-active: var(--DashboardCard__orange-color--active, #{$orange-800}),
),
);

@each $name, $states in $dashboard-colors {
&.o_dashboard_card_#{$name} {
--btn-bg: #{map-get($states, bg)};
--btn-hover-bg: #{map-get($states, bg-active)};
--btn-active-bg: #{map-get($states, bg-active)};
--btn-active-border-color: transparent;

.o_dashboard_card_data {
color: #{map-get($states, color)};
}

&.active {
outline: $border-width $border-style #{map-get($states, color-active)};
outline-offset: $border-width;

.o_dashboard_card_data {
color: #{map-get($states, color-active)};
}
}
}
}
}

/* Card Sizing */
.o_dashboard_card {
width: 90px !important;
max-width: 130px !important;
text-align: center !important;
.o_date_filter_wrapper {
@include media-breakpoint-up(md) {
border-right: $border-width $border-style $border-color;
background: transparent !important;
}
}

/* Font Adjustments */
.o_dashboard_card_data {
font-size: 1.1rem !important;
}
.o_website_sale_dashboard {
background-color: $o-control-panel-background-color;

.o_dashboard_card_text {
margin-top: 4px;
font-size: 0.7rem !important;
@include media-breakpoint-up(md) {
border-bottom: $border-width $border-style $border-color;
}
}
Loading