Skip to content

Commit c645914

Browse files
authored
DataGrid (cherry-pick) - Add warning when trying to set fixed state for child columns (#30862)
1 parent 11cc058 commit c645914

File tree

6 files changed

+275
-9
lines changed

6 files changed

+275
-9
lines changed

e2e/testcafe-devextreme/tests/dataGrid/common/fixedColumns.ts

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,3 +436,212 @@ test('DataGrid - Group summary is not updated when a column is fixed on the righ
436436
},
437437
],
438438
}));
439+
440+
const mockCountries = [
441+
{
442+
ID: 1,
443+
Country: 'Brazil',
444+
Area: 8515767,
445+
Population_Urban: 0.85,
446+
Population_Rural: 0.15,
447+
Population_Total: 205809000,
448+
GDP_Agriculture: 0.054,
449+
GDP_Industry: 0.274,
450+
GDP_Services: 0.672,
451+
GDP_Total: 2353025,
452+
},
453+
{
454+
ID: 2,
455+
Country: 'China',
456+
Area: 9388211,
457+
Population_Urban: 0.54,
458+
Population_Rural: 0.46,
459+
Population_Total: 1375530000,
460+
GDP_Agriculture: 0.091,
461+
GDP_Industry: 0.426,
462+
GDP_Services: 0.483,
463+
GDP_Total: 10380380,
464+
},
465+
{
466+
ID: 3,
467+
Country: 'France',
468+
Area: 675417,
469+
Population_Urban: 0.79,
470+
Population_Rural: 0.21,
471+
Population_Total: 64529000,
472+
GDP_Agriculture: 0.019,
473+
GDP_Industry: 0.183,
474+
GDP_Services: 0.798,
475+
GDP_Total: 2846889,
476+
},
477+
];
478+
479+
test('Warning should be shown when trying to set fixed state for child columns', async (t) => {
480+
const consoleMessages = await t.getBrowserConsoleMessages();
481+
const warnings = consoleMessages?.warn.filter((message) => message.startsWith('W1028')) || [];
482+
await t.expect(warnings.length).eql(1, 'There is warning W1028');
483+
}).before(async () => {
484+
await createWidget(
485+
'dxDataGrid',
486+
{
487+
dataSource: mockCountries,
488+
keyExpr: 'ID',
489+
columnAutoWidth: true,
490+
allowColumnReordering: true,
491+
width: 600,
492+
showBorders: true,
493+
columnChooser: { enabled: true },
494+
columns: [
495+
{
496+
dataField: 'Country',
497+
fixed: true,
498+
fixedPosition: 'left',
499+
},
500+
{
501+
dataField: 'Area',
502+
fixed: true,
503+
fixedPosition: 'left',
504+
},
505+
{
506+
caption: 'Population',
507+
columns: [
508+
{
509+
caption: 'Total',
510+
dataField: 'Population_Total',
511+
format: 'fixedPoint',
512+
fixed: true,
513+
fixedPosition: 'left',
514+
},
515+
{
516+
caption: 'Urban',
517+
dataField: 'Population_Urban',
518+
format: 'percent',
519+
fixed: true,
520+
fixedPosition: 'left',
521+
},
522+
],
523+
},
524+
],
525+
},
526+
'#container',
527+
);
528+
});
529+
530+
test('Warning should work when columns changed in real time', async (t) => {
531+
const grid = new DataGrid('#container');
532+
533+
let consoleMessages = await t.getBrowserConsoleMessages();
534+
let warnings = consoleMessages?.warn.filter((message) => message.startsWith('W1028')) || [];
535+
536+
await t.expect(warnings.length).eql(0, 'There is not any warning W1028');
537+
538+
await grid.option('columns', [
539+
{
540+
dataField: 'test3',
541+
caption: 'test3',
542+
},
543+
{
544+
caption: 'test3 group',
545+
columns: [
546+
{
547+
dataField: 'test4',
548+
caption: 'test4',
549+
fixed: true,
550+
},
551+
{
552+
dataField: 'test5',
553+
caption: 'test5',
554+
fixed: true,
555+
},
556+
],
557+
},
558+
]);
559+
consoleMessages = await t.getBrowserConsoleMessages();
560+
warnings = consoleMessages?.warn.filter((message) => message.startsWith('W1028')) || [];
561+
await t.expect(warnings.length).eql(1, 'There is warning W1028');
562+
}).before(async () => {
563+
await createWidget(
564+
'dxDataGrid',
565+
{
566+
dataSource: [],
567+
},
568+
'#container',
569+
);
570+
});
571+
572+
test('Warning should be shown one time for every dataGrid instance', async (t) => {
573+
const otherGrid = new DataGrid('#otherContainer');
574+
575+
await otherGrid.apiAddColumn({
576+
dataField: 'test',
577+
caption: 'test',
578+
columns: [
579+
{
580+
dataField: 'test1',
581+
caption: 'test1',
582+
fixed: true,
583+
},
584+
{
585+
dataField: 'test2',
586+
caption: 'test2',
587+
fixed: true,
588+
},
589+
],
590+
});
591+
const consoleMessages = await t.getBrowserConsoleMessages();
592+
const warnings = consoleMessages?.warn.filter((message) => message.startsWith('W1028')) || [];
593+
await t.expect(warnings.length).eql(2, 'There are two warnings W1028');
594+
}).before(async () => {
595+
await createWidget(
596+
'dxDataGrid',
597+
{
598+
dataSource: mockCountries,
599+
keyExpr: 'ID',
600+
columnAutoWidth: true,
601+
allowColumnReordering: true,
602+
width: 600,
603+
showBorders: true,
604+
columnChooser: { enabled: true },
605+
columns: [
606+
{
607+
dataField: 'Country',
608+
fixed: true,
609+
fixedPosition: 'left',
610+
},
611+
{
612+
dataField: 'Area',
613+
fixed: true,
614+
fixedPosition: 'left',
615+
},
616+
{
617+
caption: 'Population',
618+
columns: [
619+
{
620+
caption: 'Total',
621+
dataField: 'Population_Total',
622+
format: 'fixedPoint',
623+
fixed: true,
624+
fixedPosition: 'left',
625+
},
626+
{
627+
caption: 'Urban',
628+
dataField: 'Population_Urban',
629+
format: 'percent',
630+
fixed: true,
631+
fixedPosition: 'left',
632+
},
633+
],
634+
},
635+
],
636+
},
637+
'#container',
638+
);
639+
640+
await createWidget(
641+
'dxDataGrid',
642+
{
643+
dataSource: [],
644+
},
645+
'#otherContainer',
646+
);
647+
});

packages/devextreme/js/__internal/grids/grid_core/columns_controller/const.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,10 @@ export const COLUMN_INDEX_OPTIONS = {
2727
};
2828
export const GROUP_LOCATION = 'group';
2929
export const COLUMN_CHOOSER_LOCATION = 'columnChooser';
30+
31+
export const UNSUPPORTED_PROPERTIES_FOR_CHILD_COLUMNS = [
32+
'fixed',
33+
'fixedPosition',
34+
'type',
35+
'buttons',
36+
];

packages/devextreme/js/__internal/grids/grid_core/columns_controller/m_columns_controller.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ export class ColumnsController extends modules.Controller {
133133

134134
protected _stateStoringController!: StateStoringController;
135135

136+
public _isWarnedAboutUnsupportedProperties?: boolean;
137+
136138
public init(isApplyingUserState?): void {
137139
this._dataController = this.getController('data');
138140
this._focusController = this.getController('focus');

packages/devextreme/js/__internal/grids/grid_core/columns_controller/m_columns_controller_utils.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
isDefined, isFunction, isNumeric, isObject, isString, type,
1313
} from '@js/core/utils/type';
1414
import variableWrapper from '@js/core/utils/variable_wrapper';
15+
import errors from '@js/ui/widget/ui.errors';
1516

1617
import { HIDDEN_COLUMNS_WIDTH } from '../adaptivity/const';
1718
import gridCoreUtils from '../m_utils';
@@ -24,11 +25,36 @@ import {
2425
GROUP_COMMAND_COLUMN_NAME,
2526
GROUP_LOCATION,
2627
IGNORE_COLUMN_OPTION_NAMES,
28+
UNSUPPORTED_PROPERTIES_FOR_CHILD_COLUMNS,
2729
USER_STATE_FIELD_NAMES,
2830
USER_STATE_FIELD_NAMES_15_1,
2931
} from './const';
3032
import type { ColumnsController } from './m_columns_controller';
3133

34+
const warnFixedInChildColumnsOnce = (controller: ColumnsController, childColumns: any[]): void => {
35+
if (controller?._isWarnedAboutUnsupportedProperties) return;
36+
if (!childColumns || !Array.isArray(childColumns) || childColumns?.length === 0) return;
37+
38+
let unsupportedProperty: string | null = null;
39+
40+
for (const column of childColumns) {
41+
if (unsupportedProperty) break;
42+
if (!column || typeof column !== 'object' || column === null) continue;
43+
44+
for (const property of UNSUPPORTED_PROPERTIES_FOR_CHILD_COLUMNS) {
45+
if (property in column) {
46+
unsupportedProperty = property;
47+
break;
48+
}
49+
}
50+
}
51+
52+
if (unsupportedProperty) {
53+
controller && (controller._isWarnedAboutUnsupportedProperties = true);
54+
errors.log('W1028', unsupportedProperty);
55+
}
56+
};
57+
3258
export const setFilterOperationsAsDefaultValues = function (column) {
3359
column.filterOperations = column.defaultFilterOperations;
3460
};
@@ -47,7 +73,7 @@ export const createColumn = function (that: ColumnsController, columnOptions, us
4773

4874
that.setName(columnOptions);
4975

50-
let result = { };
76+
let result = {};
5177
if (columnOptions.command) {
5278
result = deepExtendArraySafe(commonColumnOptions, columnOptions);
5379
} else {
@@ -90,6 +116,7 @@ export const createColumnsFromOptions = function (that: ColumnsController, colum
90116
result.push(column);
91117

92118
if (column.columns) {
119+
warnFixedInChildColumnsOnce(that, column.columns);
93120
result = result.concat(createColumnsFromOptions(that, column.columns, column, result.length));
94121
delete column.columns;
95122
column.hasColumns = true;
@@ -945,7 +972,7 @@ const isFirstOrLastBandColumn = function (
945972
fixedPosition?: StickyPosition,
946973
): boolean {
947974
return bandColumns.every((column, index) => onlyWithinBandColumn && index === 0
948-
|| isFirstOrLastColumnCore(that, column, index, onlyWithinBandColumn, isLast, fixedPosition));
975+
|| isFirstOrLastColumnCore(that, column, index, onlyWithinBandColumn, isLast, fixedPosition));
949976
};
950977

951978
const isFirstOrLastColumnCore = function (

packages/devextreme/js/ui/widget/ui.errors.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,4 +365,16 @@ export default errorUtils(errors.ERROR_MESSAGES, {
365365
* @name ErrorsUIWidgets.W1025
366366
*/
367367
W1025: '\'scrolling.mode\' is set to \'virtual\' or \'infinite\'. Specify the height of the component.',
368+
/**
369+
* @name ErrorsUIWidgets.W1026
370+
*/
371+
W1026: 'The \'ai\' toolbar item is defined, but aiIntegration is missing.',
372+
/**
373+
* @name ErrorsUIWidgets.W1027
374+
*/
375+
W1027: 'A prompt should be specified for a custom command.',
376+
/**
377+
* @name ErrorsUIWidgets.W1028
378+
*/
379+
W1028: 'Nested/banded columns do not support the following properties: {0}.',
368380
});

packages/testcafe-models/dataGrid/index.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ export default class DataGrid extends Widget {
231231

232232
getFilterEditor<T>(
233233
columnIndex: number,
234-
EditorType: new(mainElement: Selector) => T,
234+
EditorType: new (mainElement: Selector) => T,
235235
): T {
236236
return new EditorType(this.getHeaders().getFilterRow().getFilterCell(columnIndex).getEditor());
237237
}
@@ -659,7 +659,7 @@ export default class DataGrid extends Widget {
659659
const { getInstance } = this;
660660
return ClientFunction(
661661
() => {
662-
(getInstance() as DataGridInstance).refresh().catch(() => {});
662+
(getInstance() as DataGridInstance).refresh().catch(() => { });
663663
},
664664
{ dependencies: { getInstance } },
665665
)();
@@ -718,6 +718,15 @@ export default class DataGrid extends Widget {
718718
)();
719719
}
720720

721+
apiAddColumn(config: any): Promise<void> {
722+
const { getInstance } = this;
723+
724+
return ClientFunction(
725+
() => (getInstance() as DataGridInstance).addColumn(config),
726+
{ dependencies: { getInstance, config } },
727+
)();
728+
}
729+
721730
moveRow(rowIndex: number, x: number, y: number, isStart = false): Promise<void> {
722731
const { getInstance } = this;
723732

@@ -739,7 +748,7 @@ export default class DataGrid extends Widget {
739748
)();
740749
}
741750

742-
resizeHeader(columnIndex: number, offset: number, needToTriggerPointerUp = true): Promise<void> {
751+
resizeHeader(columnIndex: number, offset: number, needToTriggerPointerUp = true): Promise<void> {
743752
const { getInstance } = this;
744753

745754
return ClientFunction(
@@ -919,10 +928,10 @@ export default class DataGrid extends Widget {
919928
): Promise<void> {
920929
const { getInstance } = this;
921930
return ClientFunction(
922-
() => {
923-
(getInstance() as DataGridInstance).option('selection.sensitivity', sensitivity);
924-
},
925-
{ dependencies: { getInstance, sensitivity } },
931+
() => {
932+
(getInstance() as DataGridInstance).option('selection.sensitivity', sensitivity);
933+
},
934+
{ dependencies: { getInstance, sensitivity } },
926935
)();
927936
}
928937
}

0 commit comments

Comments
 (0)