[REF] web, crm: adapt Kanban progressbar to be a component
This commit moves some parts of the code used by the progress bar of kanban to its own component. It is now clearer to distinguished its code from the renderer code (see crm_kanban_renderer). Also, it allows to re-use this component in other views without making a direct use of 'kanban' elements. The KanbanAnimatedNumber component has simply be renamed to AnimatedNumber, as this naming suggested the element was only used as a Kanban element. This more generic name now indicates that the element can be imported and used in other places. Part-of: odoo/odoo#107916 Co-authored-by: Florent Dardenne <dafl@odoo.com>
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
/** @odoo-module */
|
||||
|
||||
import { onWillStart } from "@odoo/owl";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { ColumnProgress } from "@web/views/view_components/column_progress";
|
||||
import { session } from "@web/session";
|
||||
|
||||
export class CrmColumnProgress extends ColumnProgress {
|
||||
static props = {
|
||||
...ColumnProgress.props,
|
||||
progressAttributes: true,
|
||||
};
|
||||
static template = "crm.ColumnProgress";
|
||||
setup() {
|
||||
super.setup();
|
||||
this.user = useService("user");
|
||||
this.showRecurringRevenue = false;
|
||||
|
||||
onWillStart(async () => {
|
||||
if (this.props.progressAttributes.recurring_revenue_sum_field) {
|
||||
this.showRecurringRevenue = await this.user.hasGroup("crm.group_use_recurring_revenues");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getRecurringRevenueGroupAggregate(group) {
|
||||
const rrField = this.props.progressAttributes.recurring_revenue_sum_field;
|
||||
const value = group.getAggregates(rrField.name);
|
||||
const title = rrField.string || this.env._t("Count");
|
||||
let currency = false;
|
||||
if (value && rrField.currency_field) {
|
||||
currency = session.currencies[session.company_currency_id];
|
||||
}
|
||||
return { value, currency, title };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates>
|
||||
<t t-name="crm.ColumnProgress" t-inherit="web.ColumnProgress" t-inherit-mode="primary" owl="1">
|
||||
<xpath expr="//div[hasclass('o_column_progress')]" position="attributes">
|
||||
<attribute name="class" remove="w-75" add="w-50" separator=" "/>
|
||||
</xpath>
|
||||
<AnimatedNumber position="after">
|
||||
<t t-if="showRecurringRevenue">
|
||||
<t t-set="rrmAggregate" t-value="getRecurringRevenueGroupAggregate(props.group)"/>
|
||||
<AnimatedNumber
|
||||
value="rrmAggregate.value"
|
||||
title="rrmAggregate.title"
|
||||
duration="1000"
|
||||
currency="props.aggregate.currency"
|
||||
animationClass="'o_animated_grow_huge'"
|
||||
>
|
||||
<t t-set-slot="prefix">
|
||||
<strong>+</strong>
|
||||
</t>
|
||||
</AnimatedNumber>
|
||||
</t>
|
||||
</AnimatedNumber>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -1,33 +1,11 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { CrmColumnProgress } from "./crm_column_progress";
|
||||
import { KanbanRenderer } from "@web/views/kanban/kanban_renderer";
|
||||
import { session } from "@web/session";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
|
||||
const { onWillStart } = owl;
|
||||
|
||||
export class CrmKanbanRenderer extends KanbanRenderer {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.user = useService("user");
|
||||
|
||||
this.showRecurringRevenue = false;
|
||||
onWillStart(async () => {
|
||||
this.showRecurringRevenue =
|
||||
this.props.list.model.progressAttributes.recurring_revenue_sum_field &&
|
||||
(await this.user.hasGroup("crm.group_use_recurring_revenues"));
|
||||
});
|
||||
}
|
||||
|
||||
getRecurringRevenueGroupAggregate(group) {
|
||||
const rrField = this.props.list.model.progressAttributes.recurring_revenue_sum_field;
|
||||
const value = group.getAggregates(rrField.name);
|
||||
const title = rrField.string || this.env._t("Count");
|
||||
let currency = false;
|
||||
if (value && rrField.currency_field) {
|
||||
currency = session.currencies[session.company_currency_id];
|
||||
}
|
||||
return { value, currency, title };
|
||||
}
|
||||
}
|
||||
export class CrmKanbanRenderer extends KanbanRenderer {}
|
||||
CrmKanbanRenderer.template = "crm.CrmKanbanRenderer";
|
||||
CrmKanbanRenderer.components = {
|
||||
...KanbanRenderer.components,
|
||||
CrmColumnProgress,
|
||||
};
|
||||
|
||||
@@ -1,24 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates>
|
||||
<t t-name="crm.CrmKanbanRenderer" t-inherit="web.KanbanRenderer" t-inherit-mode="primary" owl="1">
|
||||
<xpath expr="//div[hasclass('o_kanban_counter_progress')]" position="attributes">
|
||||
<attribute name="class" remove="w-75" add="w-50" separator=" "/>
|
||||
<xpath expr="//ColumnProgress" position="replace">
|
||||
<CrmColumnProgress group="group" aggregate="getGroupAggregate(group)" progressAttributes="props.list.model.progressAttributes"/>
|
||||
</xpath>
|
||||
<KanbanAnimatedNumber position="after">
|
||||
<t t-if="showRecurringRevenue">
|
||||
<t t-set="rrmAggregate" t-value="getRecurringRevenueGroupAggregate(group)"/>
|
||||
<KanbanAnimatedNumber
|
||||
value="rrmAggregate.value"
|
||||
title="rrmAggregate.title"
|
||||
duration="1000"
|
||||
currency="aggregate.currency"
|
||||
animationClass="'o_kanban_grow_huge'"
|
||||
>
|
||||
<t t-set-slot="prefix">
|
||||
<strong>+</strong>
|
||||
</t>
|
||||
</KanbanAnimatedNumber>
|
||||
</t>
|
||||
</KanbanAnimatedNumber>
|
||||
</t>
|
||||
</templates>
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
getFixture,
|
||||
patchWithCleanup,
|
||||
} from '@web/../tests/helpers/utils';
|
||||
import { KanbanAnimatedNumber } from "@web/views/kanban/kanban_animated_number";
|
||||
import { AnimatedNumber } from "@web/views/view_components/animated_number";
|
||||
|
||||
const serviceRegistry = registry.category("services");
|
||||
|
||||
@@ -18,7 +18,7 @@ let serverData;
|
||||
|
||||
QUnit.module('Crm Kanban Progressbar', {
|
||||
beforeEach: function () {
|
||||
patchWithCleanup(KanbanAnimatedNumber, { enableAnimations: false });
|
||||
patchWithCleanup(AnimatedNumber, { enableAnimations: false });
|
||||
serverData = {
|
||||
models: {
|
||||
'res.users': {
|
||||
@@ -124,7 +124,7 @@ QUnit.module('Crm Kanban Progressbar', {
|
||||
</kanban>`,
|
||||
});
|
||||
|
||||
const reccurringRevenueValues = [...target.querySelectorAll('.o_kanban_counter_side:nth-child(3)')].map((elem) => elem.textContent);
|
||||
const reccurringRevenueValues = [...target.querySelectorAll('.o_animated_number:nth-child(3)')].map((elem) => elem.textContent);
|
||||
|
||||
// When no values are given in column it should return 0 and counts value if given.
|
||||
assert.deepEqual(reccurringRevenueValues, ["+20", "+0", "+45"],
|
||||
@@ -157,7 +157,7 @@ QUnit.module('Crm Kanban Progressbar', {
|
||||
});
|
||||
|
||||
//MRR before state change
|
||||
let reccurringRevenueNoValues = [...target.querySelectorAll('.o_kanban_counter_side:nth-child(3)')].map((elem) => elem.textContent);
|
||||
let reccurringRevenueNoValues = [...target.querySelectorAll('.o_animated_number:nth-child(3)')].map((elem) => elem.textContent);
|
||||
assert.deepEqual(reccurringRevenueNoValues, ['+30','+35'],
|
||||
"counter should display the sum of recurring_revenue_monthly values");
|
||||
|
||||
@@ -169,7 +169,7 @@ QUnit.module('Crm Kanban Progressbar', {
|
||||
);
|
||||
|
||||
//check MRR after drag&drop
|
||||
reccurringRevenueNoValues = [...target.querySelectorAll('.o_kanban_counter_side:nth-child(3)')].map((elem) => elem.textContent);
|
||||
reccurringRevenueNoValues = [...target.querySelectorAll('.o_animated_number:nth-child(3)')].map((elem) => elem.textContent);
|
||||
assert.deepEqual(reccurringRevenueNoValues, ['+25', '+40'],
|
||||
"counter should display the sum of recurring_revenue_monthly correctly after drag and drop");
|
||||
|
||||
@@ -177,7 +177,7 @@ QUnit.module('Crm Kanban Progressbar', {
|
||||
await click(target.querySelector('.o_kanban_group:nth-child(2) .progress-bar[aria-valuenow="2"]'), null);
|
||||
|
||||
//check MRR after applying filter
|
||||
reccurringRevenueNoValues = [...target.querySelectorAll('.o_kanban_counter_side:nth-child(3)')].map((elem) => elem.textContent);
|
||||
reccurringRevenueNoValues = [...target.querySelectorAll('.o_animated_number:nth-child(3)')].map((elem) => elem.textContent);
|
||||
assert.deepEqual(reccurringRevenueNoValues, ['+25','+25'],
|
||||
"counter should display the sum of recurring_revenue_monthly only of overdue filter in 1st column");
|
||||
});
|
||||
|
||||
@@ -111,6 +111,7 @@
|
||||
'web/static/src/views/kanban/**/*',
|
||||
'web/static/src/views/list/**/*',
|
||||
'web/static/src/views/view_button/**/*',
|
||||
'web/static/src/views/view_components/**/*',
|
||||
'web/static/src/views/view_dialogs/**/*',
|
||||
'web/static/src/views/widgets/**/*',
|
||||
'web/static/src/webclient/**/*',
|
||||
|
||||
@@ -1,15 +1,3 @@
|
||||
@keyframes kanban-counter-grow {
|
||||
30% {
|
||||
transform: scale3d(1.1, 1.1, 1.1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes kanban-counter-grow-huge {
|
||||
30% {
|
||||
transform: scale3d(1.3, 1.3, 1.3);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin o-kanban-css-filter($class, $accent-color) {
|
||||
// Provide CSS reordering and highlight
|
||||
&.o_kanban_group_show_#{$class} {
|
||||
@@ -44,21 +32,9 @@
|
||||
.o_kanban_counter {
|
||||
transition: opacity 0.3s ease 0s;
|
||||
|
||||
> .o_kanban_counter_progress {
|
||||
> .o_column_progress {
|
||||
height: $font-size-sm;
|
||||
}
|
||||
|
||||
> .o_kanban_counter_side {
|
||||
transform-origin: right center;
|
||||
|
||||
&.o_kanban_grow {
|
||||
animation: kanban-counter-grow 1s ease 0s 1 normal none running;
|
||||
}
|
||||
|
||||
&.o_kanban_grow_huge {
|
||||
animation: kanban-counter-grow-huge 1s ease 0s 1 normal none running;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_group {
|
||||
|
||||
@@ -69,7 +69,7 @@ function getColorName(value) {
|
||||
* exist
|
||||
* @returns {string}
|
||||
*/
|
||||
function getImageSrcFromRecordInfo(record, model, field, idOrIds, placeholder) {
|
||||
export function getImageSrcFromRecordInfo(record, model, field, idOrIds, placeholder) {
|
||||
const id = (Array.isArray(idOrIds) ? idOrIds[0] : idOrIds) || null;
|
||||
const isCurrentRecord =
|
||||
record.resModel === model && (record.resId === id || (!record.resId && !id));
|
||||
@@ -99,7 +99,7 @@ function getImageSrcFromRecordInfo(record, model, field, idOrIds, placeholder) {
|
||||
* @param {string} fieldName
|
||||
* @returns {any}
|
||||
*/
|
||||
function getRawValue(record, fieldName) {
|
||||
export function getRawValue(record, fieldName) {
|
||||
const field = record.fields[fieldName];
|
||||
const value = record.data[fieldName];
|
||||
switch (field.type) {
|
||||
@@ -127,7 +127,7 @@ function getRawValue(record, fieldName) {
|
||||
* @param {string} fieldName
|
||||
* @returns {string}
|
||||
*/
|
||||
function getValue(record, fieldName) {
|
||||
export function getValue(record, fieldName) {
|
||||
const field = record.fields[fieldName];
|
||||
const value = record.data[fieldName];
|
||||
const formatter = formatters.get(field.type, String);
|
||||
@@ -149,7 +149,7 @@ function isBinSize(value) {
|
||||
* @param {string} innerHTML
|
||||
* @returns {boolean} true if no content found or if containing only formatting tags
|
||||
*/
|
||||
function isHtmlEmpty(innerHTML = "") {
|
||||
export function isHtmlEmpty(innerHTML = "") {
|
||||
const div = Object.assign(document.createElement("div"), { innerHTML });
|
||||
return div.innerText.trim() === "";
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import { isAllowedDateField } from "@web/views/relational_model";
|
||||
import { isNull, isRelational } from "@web/views/utils";
|
||||
import { FormViewDialog } from "@web/views/view_dialogs/form_view_dialog";
|
||||
import { useBounceButton } from "@web/views/view_hook";
|
||||
import { KanbanAnimatedNumber } from "./kanban_animated_number";
|
||||
import { ColumnProgress } from "@web/views/view_components/column_progress";
|
||||
import { KanbanColumnQuickCreate } from "./kanban_column_quick_create";
|
||||
import { KanbanRecord } from "./kanban_record";
|
||||
import { KanbanRecordQuickCreate } from "./kanban_record_quick_create";
|
||||
@@ -616,7 +616,7 @@ KanbanRenderer.props = [
|
||||
KanbanRenderer.components = {
|
||||
Dropdown,
|
||||
DropdownItem,
|
||||
KanbanAnimatedNumber,
|
||||
ColumnProgress,
|
||||
KanbanColumnQuickCreate,
|
||||
KanbanRecord,
|
||||
KanbanRecordQuickCreate,
|
||||
|
||||
@@ -56,31 +56,7 @@
|
||||
</button>
|
||||
</div>
|
||||
<div t-if="(env.isSmall or !group.isFolded) and group.progressBars.length" class="o_kanban_counter position-relative d-flex align-items-center justify-content-between" t-att-class="{ 'opacity-25': !group.count }">
|
||||
<div class="o_kanban_counter_progress progress w-75 bg-300">
|
||||
<t t-foreach="group.progressBars" t-as="progressBar" t-key="progressBar.value">
|
||||
<div t-if="progressBar.count"
|
||||
role="progressbar"
|
||||
class="progress-bar o_bar_has_records cursor-pointer"
|
||||
t-att-class="{ 'progress-bar-animated progress-bar-striped': group.progressValue.active === progressBar.value, 'border border-white': !group.isFolded and group.hasActiveProgressValue }"
|
||||
t-attf-class="bg-{{ progressBar.color }}"
|
||||
t-attf-style="width: {{ progressBar.count / (group.count or 1) * 100 }}%;"
|
||||
aria-valuemin="0"
|
||||
t-att-aria-valuemax="group.count"
|
||||
t-att-aria-valuenow="progressBar.count"
|
||||
t-attf-data-tooltip="{{ progressBar.count }} {{ progressBar.string }}"
|
||||
data-tooltip-delay="0"
|
||||
t-on-click="() => group.filterProgressValue(progressBar.value)"
|
||||
/>
|
||||
</t>
|
||||
</div>
|
||||
<t t-set="aggregate" t-value="getGroupAggregate(group)" />
|
||||
<KanbanAnimatedNumber
|
||||
value="aggregate.value"
|
||||
title="aggregate.title"
|
||||
duration="1000"
|
||||
currency="aggregate.currency"
|
||||
animationClass="aggregate.value > 999 ? 'o_kanban_grow' : 'o_kanban_grow_huge'"
|
||||
/>
|
||||
<ColumnProgress group="group" aggregate="getGroupAggregate(group)" />
|
||||
</div>
|
||||
</div>
|
||||
<t t-if="!group.isFolded">
|
||||
|
||||
+18
-18
@@ -5,7 +5,24 @@ import { formatInteger } from "@web/views/fields/formatters";
|
||||
|
||||
import { Component, onWillUpdateProps, onWillUnmount, useState } from "@odoo/owl";
|
||||
|
||||
export class KanbanAnimatedNumber extends Component {
|
||||
export class AnimatedNumber extends Component {
|
||||
static template = "web.AnimatedNumber";
|
||||
static props = {
|
||||
value: Number,
|
||||
duration: Number,
|
||||
animationClass: { type: String, optional: true },
|
||||
currency: { type: [Object, Boolean], optional: true },
|
||||
title: { type: String, optional: true },
|
||||
slots: {
|
||||
type: Object,
|
||||
shape: {
|
||||
prefix: { type: Object, optional: true },
|
||||
},
|
||||
optional: true,
|
||||
},
|
||||
};
|
||||
static enableAnimations = true;
|
||||
|
||||
setup() {
|
||||
this.formatInteger = formatInteger;
|
||||
this.state = useState({ value: this.props.value });
|
||||
@@ -37,20 +54,3 @@ export class KanbanAnimatedNumber extends Component {
|
||||
return this.formatInteger(value, { humanReadable: true, decimals: 0, minDigits: 3 });
|
||||
}
|
||||
}
|
||||
|
||||
KanbanAnimatedNumber.template = "web.KanbanAnimatedNumber";
|
||||
KanbanAnimatedNumber.props = {
|
||||
value: Number,
|
||||
duration: Number,
|
||||
animationClass: { type: String, optional: true },
|
||||
currency: { type: [Object, Boolean], optional: true },
|
||||
title: { type: String, optional: true },
|
||||
slots: {
|
||||
type: Object,
|
||||
shape: {
|
||||
prefix: { type: Object, optional: true },
|
||||
},
|
||||
optional: true,
|
||||
},
|
||||
};
|
||||
KanbanAnimatedNumber.enableAnimations = true;
|
||||
@@ -0,0 +1,23 @@
|
||||
@keyframes animated-counter-grow {
|
||||
30% {
|
||||
transform: scale3d(1.1, 1.1, 1.1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animated-counter-grow-huge {
|
||||
30% {
|
||||
transform: scale3d(1.3, 1.3, 1.3);
|
||||
}
|
||||
}
|
||||
|
||||
.o_animated_number {
|
||||
transform-origin: right center;
|
||||
|
||||
&.o_animated_grow {
|
||||
animation: animated-counter-grow 1s ease 0s 1 normal none running;
|
||||
}
|
||||
|
||||
&.o_animated_grow_huge {
|
||||
animation: animated-counter-grow-huge 1s ease 0s 1 normal none running;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="web.KanbanAnimatedNumber" owl="1">
|
||||
<div class="o_kanban_counter_side ms-2 text-900 text-nowrap" t-att-class="state.value !== props.value and props.animationClass" t-att-title="props.title">
|
||||
<t t-name="web.AnimatedNumber" owl="1">
|
||||
<div class="o_animated_number ms-2 text-900 text-nowrap" t-att-class="state.value !== props.value and props.animationClass" t-att-title="props.title">
|
||||
<t t-slot="prefix"/>
|
||||
<span t-if="props.currency and props.currency.position === 'before'" t-esc="props.currency.symbol" class="ms-1"/>
|
||||
<b t-esc="format(state.value)" />
|
||||
@@ -0,0 +1,15 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { Component } from "@odoo/owl";
|
||||
import { AnimatedNumber } from "./animated_number";
|
||||
|
||||
export class ColumnProgress extends Component {
|
||||
static components = {
|
||||
AnimatedNumber,
|
||||
};
|
||||
static template = "web.ColumnProgress";
|
||||
static props = {
|
||||
aggregate: { type: Object },
|
||||
group: { type: Object },
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="web.ColumnProgress" owl="1">
|
||||
<div class="o_column_progress progress bg-300 w-75">
|
||||
<t t-foreach="props.group.progressBars" t-as="progressBar" t-key="progressBar.value">
|
||||
<div t-if="progressBar.count"
|
||||
role="progressbar"
|
||||
class="progress-bar o_bar_has_records cursor-pointer"
|
||||
t-att-class="{ 'progress-bar-animated progress-bar-striped': props.group.progressValue.active === progressBar.value, 'border border-white': !props.group.isFolded and props.group.hasActiveProgressValue }"
|
||||
t-attf-class="bg-{{ progressBar.color }}"
|
||||
t-attf-style="width: {{ progressBar.count / (props.group.count or 1) * 100 }}%;"
|
||||
aria-valuemin="0"
|
||||
t-att-aria-valuemax="props.group.count"
|
||||
t-att-aria-valuenow="progressBar.count"
|
||||
t-attf-data-tooltip="{{ progressBar.count }} {{ progressBar.string }}"
|
||||
data-tooltip-delay="0"
|
||||
t-on-click="() => props.group.filterProgressValue(progressBar.value)"
|
||||
/>
|
||||
</t>
|
||||
</div>
|
||||
<AnimatedNumber
|
||||
value="props.aggregate.value"
|
||||
title="props.aggregate.title"
|
||||
duration="1000"
|
||||
currency="props.aggregate.currency"
|
||||
animationClass="props.aggregate.value > 999 ? 'o_animated_grow' : 'o_animated_grow_huge'"
|
||||
/>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -34,7 +34,7 @@ import { tooltipService } from "@web/core/tooltip/tooltip_service";
|
||||
import { nbsp } from "@web/core/utils/strings";
|
||||
import { getNextTabableElement } from "@web/core/utils/ui";
|
||||
import { session } from "@web/session";
|
||||
import { KanbanAnimatedNumber } from "@web/views/kanban/kanban_animated_number";
|
||||
import { AnimatedNumber } from "@web/views/view_components/animated_number";
|
||||
import { KanbanController } from "@web/views/kanban/kanban_controller";
|
||||
import { kanbanView } from "@web/views/kanban/kanban_view";
|
||||
import { DynamicRecordList } from "@web/views/relational_model";
|
||||
@@ -82,19 +82,17 @@ function getCardTexts(groupIndex) {
|
||||
}
|
||||
|
||||
function getCounters() {
|
||||
return [...target.querySelectorAll(".o_kanban_counter_side")].map(
|
||||
(counter) => counter.innerText
|
||||
);
|
||||
return [...target.querySelectorAll(".o_animated_number")].map((counter) => counter.innerText);
|
||||
}
|
||||
|
||||
function getProgressBars(columnIndex) {
|
||||
const column = getColumn(columnIndex);
|
||||
return [...column.querySelectorAll(".o_kanban_counter_progress .progress-bar")];
|
||||
return [...column.querySelectorAll(".o_column_progress .progress-bar")];
|
||||
}
|
||||
|
||||
function getTooltips(groupIndex) {
|
||||
const root = groupIndex >= 0 ? getColumn(groupIndex) : target;
|
||||
return [...root.querySelectorAll(".o_kanban_counter_progress .progress-bar")]
|
||||
return [...root.querySelectorAll(".o_column_progress .progress-bar")]
|
||||
.map((card) => card.dataset.tooltip)
|
||||
.filter(Boolean);
|
||||
}
|
||||
@@ -162,7 +160,7 @@ let target;
|
||||
|
||||
QUnit.module("Views", (hooks) => {
|
||||
hooks.beforeEach(() => {
|
||||
patchWithCleanup(KanbanAnimatedNumber, { enableAnimations: false });
|
||||
patchWithCleanup(AnimatedNumber, { enableAnimations: false });
|
||||
serverData = {
|
||||
models: {
|
||||
partner: {
|
||||
@@ -8715,31 +8713,24 @@ QUnit.module("Views", (hooks) => {
|
||||
|
||||
assert.containsN(target, ".o_kanban_group", 2);
|
||||
assert.deepEqual(getCounters(), ["1", "4"]);
|
||||
assert.containsN(
|
||||
target,
|
||||
".o_kanban_group:last-child .o_kanban_counter_progress .progress-bar",
|
||||
4
|
||||
);
|
||||
assert.containsN(target, ".o_kanban_group:last-child .o_column_progress .progress-bar", 4);
|
||||
assert.containsOnce(
|
||||
target,
|
||||
".o_kanban_group:last-child .o_kanban_counter_progress .progress-bar.bg-200",
|
||||
".o_kanban_group:last-child .o_column_progress .progress-bar.bg-200",
|
||||
"should have false kanban color"
|
||||
);
|
||||
assert.hasClass(
|
||||
target.querySelector(
|
||||
".o_kanban_group:last-child .o_kanban_counter_progress .progress-bar.bg-200"
|
||||
".o_kanban_group:last-child .o_column_progress .progress-bar.bg-200"
|
||||
),
|
||||
"bg-200"
|
||||
);
|
||||
|
||||
await click(
|
||||
target,
|
||||
".o_kanban_group:last-child .o_kanban_counter_progress .progress-bar.bg-200"
|
||||
);
|
||||
await click(target, ".o_kanban_group:last-child .o_column_progress .progress-bar.bg-200");
|
||||
|
||||
assert.hasClass(
|
||||
target.querySelector(
|
||||
".o_kanban_group:last-child .o_kanban_counter_progress .progress-bar.bg-200"
|
||||
".o_kanban_group:last-child .o_column_progress .progress-bar.bg-200"
|
||||
),
|
||||
"progress-bar-animated"
|
||||
);
|
||||
@@ -8781,14 +8772,11 @@ QUnit.module("Views", (hooks) => {
|
||||
assert.containsN(target, ".o_kanban_group", 2);
|
||||
assert.deepEqual(getCounters(), ["-4", "51"]);
|
||||
|
||||
await click(
|
||||
target,
|
||||
".o_kanban_group:last-child .o_kanban_counter_progress .progress-bar.bg-200"
|
||||
);
|
||||
await click(target, ".o_kanban_group:last-child .o_column_progress .progress-bar.bg-200");
|
||||
|
||||
assert.hasClass(
|
||||
target.querySelector(
|
||||
".o_kanban_group:last-child .o_kanban_counter_progress .progress-bar.bg-200"
|
||||
".o_kanban_group:last-child .o_column_progress .progress-bar.bg-200"
|
||||
),
|
||||
"progress-bar-animated"
|
||||
);
|
||||
@@ -8942,7 +8930,7 @@ QUnit.module("Views", (hooks) => {
|
||||
groupBy: ["bar"],
|
||||
});
|
||||
|
||||
await click(target, ".o_kanban_counter_progress .progress-bar.bg-success");
|
||||
await click(target, ".o_column_progress .progress-bar.bg-success");
|
||||
|
||||
assert.deepEqual(getCardTexts(), ["5"], "we should have 1 record shown");
|
||||
|
||||
@@ -11363,7 +11351,7 @@ QUnit.module("Views", (hooks) => {
|
||||
// Initial state: 2 columns, the "Yes" column contains 2 records "abc", 1 "def" and 1 "ghi"
|
||||
assert.deepEqual(getCounters(), ["1", "4"]);
|
||||
assert.containsN(getColumn(1), ".o_kanban_record", 4);
|
||||
assert.containsN(getColumn(1), ".o_kanban_counter_progress .progress-bar", 3);
|
||||
assert.containsN(getColumn(1), ".o_column_progress .progress-bar", 3);
|
||||
assert.strictEqual(getProgressBars(1)[0].style.width, "50%"); // abc: 2
|
||||
assert.strictEqual(getProgressBars(1)[1].style.width, "25%"); // def: 1
|
||||
assert.strictEqual(getProgressBars(1)[2].style.width, "25%"); // ghi: 1
|
||||
@@ -11373,7 +11361,7 @@ QUnit.module("Views", (hooks) => {
|
||||
|
||||
assert.deepEqual(getCounters(), ["1", "2"]);
|
||||
assert.containsN(getColumn(1), ".o_kanban_record", 2);
|
||||
assert.containsN(getColumn(1), ".o_kanban_counter_progress .progress-bar", 3);
|
||||
assert.containsN(getColumn(1), ".o_column_progress .progress-bar", 3);
|
||||
assert.strictEqual(getProgressBars(1)[0].style.width, "50%"); // abc: 2
|
||||
assert.strictEqual(getProgressBars(1)[1].style.width, "25%"); // def: 1
|
||||
assert.strictEqual(getProgressBars(1)[2].style.width, "25%"); // ghi: 1
|
||||
@@ -11385,7 +11373,7 @@ QUnit.module("Views", (hooks) => {
|
||||
|
||||
assert.deepEqual(getCounters(), ["1", "1"]);
|
||||
assert.containsN(getColumn(1), ".o_kanban_record", 2);
|
||||
assert.containsN(getColumn(1), ".o_kanban_counter_progress .progress-bar", 3);
|
||||
assert.containsN(getColumn(1), ".o_column_progress .progress-bar", 3);
|
||||
assert.strictEqual(getProgressBars(1)[0].style.width, "25%"); // abc: 1
|
||||
assert.strictEqual(getProgressBars(1)[1].style.width, "50%"); // def: 2
|
||||
assert.strictEqual(getProgressBars(1)[2].style.width, "25%"); // ghi: 1
|
||||
|
||||
Reference in New Issue
Block a user