Skip to content

Conversation

@AlisherAmonulloev
Copy link
Contributor

No description provided.

@AlisherAmonulloev AlisherAmonulloev self-assigned this Jan 26, 2026
@AlisherAmonulloev AlisherAmonulloev requested a review from a team as a code owner January 26, 2026 07:54
Copilot AI review requested due to automatic review settings January 26, 2026 07:54
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes PivotGrid header depth calculation in scenarios where hideEmptySummaryCells hides an entire column (e.g., when calculateSummaryValue returns null), preventing incorrect header layout/export results after expand/collapse operations.

Changes:

  • Adjusted PivotGrid header depth computation to skip fully empty header items.
  • Added PivotGrid QUnit regression tests covering expand/collapse behavior and export column stability when empty summary cells are hidden.
  • Added ExcelJS exporter regression test verifying export output when hideEmptySummaryCells is enabled and summary values can be null.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

File Description
packages/devextreme/js/__internal/grids/pivot_grid/data_controller/m_data_controller.ts Updates header depth calculation to ignore empty header items when computing depth.
packages/devextreme/testing/tests/DevExpress.ui.widgets.pivotGrid/pivotGrid.tests.js Adds UI-level regression tests around expand/collapse sequences and exported column stability with hidden empty cells.
packages/devextreme/testing/tests/DevExpress.exporter/exceljsParts/exceljs.pivotGrid.tests.js Adds exporter regression test to ensure hidden empty columns aren’t exported after expand/collapse.

assert.deepEqual(dataSource.expandAll.lastCall.args, [1], 'collapseLevel args');
});

QUnit.test('Expand all should not mark hidden columns as expanded when hideEmptySummaryCells enabled with calculateSummaryValue returning null', function(assert) {
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test name mentions “mark hidden columns as expanded”, but the assertions validate Grand Total column width stability. Please align the test name (or add an assertion that actually checks expanded state / rendered columns) so the intent and coverage are clear.

Suggested change
QUnit.test('Expand all should not mark hidden columns as expanded when hideEmptySummaryCells enabled with calculateSummaryValue returning null', function(assert) {
QUnit.test('Expand all should not change Grand Total column width when hideEmptySummaryCells enabled with calculateSummaryValue returning null', function(assert) {

Copilot uses AI. Check for mistakes.
Comment on lines +2459 to +2462
// Output widths for examination
assert.ok(true, `Initial Grand Total width: ${initialGrandTotalWidth}`);
assert.ok(true, `Final Grand Total width: ${finalGrandTotalWidth}`);

Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These assert.ok(true, ...) calls act as debug logging and add unconditional passing assertions, which can hide real failures and add noise to test output. Please remove them (or replace with a meaningful assertion on the expected values).

Suggested change
// Output widths for examination
assert.ok(true, `Initial Grand Total width: ${initialGrandTotalWidth}`);
assert.ok(true, `Final Grand Total width: ${finalGrandTotalWidth}`);

Copilot uses AI. Check for mistakes.
Comment on lines +2463 to +2465
assert.strictEqual(
finalGrandTotalWidth,
initialGrandTotalWidth,
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comparing DOM widths with assert.strictEqual is likely to be flaky across browsers/font rendering/subpixel rounding. Since this file already uses assert.roughEqual for width-related checks, consider switching this to a tolerant comparison (e.g., roughEqual with a small epsilon) to reduce intermittent failures.

Suggested change
assert.strictEqual(
finalGrandTotalWidth,
initialGrandTotalWidth,
assert.roughEqual(
finalGrandTotalWidth,
initialGrandTotalWidth,
1,

Copilot uses AI. Check for mistakes.
this.clock.tick(10);

const initialColumnCount = initialItems[0].length;
assert.ok(true, `Initial export column count: ${initialColumnCount}`);
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert.ok(true, ...) here is unconditional and acts like debug logging rather than validating behavior. Please remove it or replace it with an assertion that checks an expected property (e.g., an explicit expected column count).

Suggested change
assert.ok(true, `Initial export column count: ${initialColumnCount}`);
assert.ok(initialColumnCount > 0, `Initial export column count should be greater than 0, actual: ${initialColumnCount}`);

Copilot uses AI. Check for mistakes.
Comment on lines +2556 to +2558
const finalColumnCount = finalItems[0].length;
assert.ok(true, `Final export column count: ${finalColumnCount}`);

Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert.ok(true, ...) here is unconditional and acts like debug logging rather than validating behavior. Please remove it or replace it with an assertion that checks an expected property (e.g., an explicit expected column count).

Copilot uses AI. Check for mistakes.
Comment on lines +171 to +177
let { isEmpty } = item;

if (isEmpty?.length) {
isEmpty = item.isEmpty.filter((v) => v).length === isEmpty.length;
}

if (item && isEmpty) {
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isEmpty can be an array (set in summary display mode). With the current logic, an empty array ([]) will skip the isEmpty?.length branch, remain truthy, and then be treated as “empty” later, causing this callback to return and potentially undercount header depth. Consider normalizing to an explicit boolean, e.g. const isFullyEmpty = Array.isArray(item.isEmpty) ? item.isEmpty.length > 0 && item.isEmpty.every(Boolean) : !!item.isEmpty; and use that for the emptiness check.

Suggested change
let { isEmpty } = item;
if (isEmpty?.length) {
isEmpty = item.isEmpty.filter((v) => v).length === isEmpty.length;
}
if (item && isEmpty) {
const isEmptyValue = item?.isEmpty;
const isFullyEmpty = Array.isArray(isEmptyValue)
? isEmptyValue.length > 0 && isEmptyValue.every(Boolean)
: !!isEmptyValue;
if (item && isFullyEmpty) {

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants