Skip to content

Commit 1ea6be0

Browse files
authored
DataGrid - AI Column: Create header DropDownButton and sparcle chat icon (#31499)
Co-authored-by: Alyar <>
1 parent 8fe6482 commit 1ea6be0

File tree

51 files changed

+818
-152
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+818
-152
lines changed

apps/react-storybook/stories/tree_list/TreeList.stories.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type EditingMode = typeof editingModes[number];
1717

1818
interface HumanReadableProps {
1919
showSelectCheckboxes: boolean;
20+
aiColumnEnabled: boolean;
2021
showRowLines: boolean;
2122
rtlEnabled: boolean;
2223
editingMode: EditingMode;
@@ -70,13 +71,15 @@ const mergeProps = (
7071
): Record<PropertyKey, any> => {
7172
const result = { ...defaultProps };
7273
const {
74+
aiColumnEnabled,
7375
showSelectCheckboxes,
7476
firstColumnContentType,
7577
showRowLines,
7678
rtlEnabled,
7779
firstColumnFixed,
7880
editingMode,
7981
} = humanReadableProps;
82+
const hasAIColumn = result.columns.some((col) => col?.type === 'ai');
8083

8184
result.selection = { mode: showSelectCheckboxes ? 'multiple' : 'none' };
8285

@@ -87,6 +90,19 @@ const mergeProps = (
8790
fixedPosition: firstColumnFixed === 'left' ? 'left' : 'right',
8891
}
8992

93+
if (aiColumnEnabled) {
94+
if (!hasAIColumn) {
95+
result.columns.unshift({
96+
type: 'ai',
97+
caption: 'Smart Column',
98+
name: 'myAIColumn',
99+
width: 200,
100+
});
101+
}
102+
} else if (hasAIColumn) {
103+
result.columns = result.columns.filter((col) => col?.type !== 'ai');
104+
}
105+
90106
result.showRowLines = showRowLines;
91107
result.rtlEnabled = rtlEnabled;
92108

@@ -143,7 +159,8 @@ type Story = StoryObj<typeof TreeList>;
143159

144160
export const Overview: Story = {
145161
args: {
146-
showSelectCheckboxes: false,
162+
aiColumnEnabled: true,
163+
showSelectCheckboxes: true,
147164
showRowLines: false,
148165
rtlEnabled: false,
149166
editingMode: 'none',
866 Bytes
Loading
10.4 KB
Loading

e2e/testcafe-devextreme/tests/common/treeList/aiColumn/visual.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,48 @@ test('Default render', async (t) => {
5050
},
5151
],
5252
}));
53+
54+
test('AI Column when multiple selection is enabled', async (t) => {
55+
// arrange, act
56+
const { takeScreenshot, compareResults } = createScreenshotsComparer(t);
57+
const treeList = new TreeList(TREE_LIST_SELECTOR);
58+
59+
await t.expect(treeList.isReady()).ok();
60+
61+
await testScreenshot(t, takeScreenshot, 'treelist__ai-column__multiple-selection.png', { element: treeList.element });
62+
63+
// assert
64+
await t
65+
.expect(compareResults.isValid())
66+
.ok(compareResults.errorMessages());
67+
}).before(async () => createWidget('dxTreeList', {
68+
dataSource: [
69+
{
70+
id: 1, parentId: 0, name: 'Name 1', value: 10,
71+
},
72+
{
73+
id: 2, parentId: 1, name: 'Name 2', value: 20,
74+
},
75+
{
76+
id: 3, parentId: 0, name: 'Name 3', value: 30,
77+
},
78+
{
79+
id: 4, parentId: 3, name: 'Name 4', value: 40,
80+
},
81+
],
82+
keyExpr: 'id',
83+
parentIdExpr: 'parentId',
84+
expandedRowKeys: [3],
85+
selection: {
86+
mode: 'multiple',
87+
},
88+
columns: [
89+
{
90+
type: 'ai',
91+
caption: 'AI Column',
92+
},
93+
{ dataField: 'id', caption: 'ID' },
94+
{ dataField: 'name', caption: 'Name' },
95+
{ dataField: 'value', caption: 'Value' },
96+
],
97+
}));

e2e/testcafe-devextreme/tests/dataGrid/common/aiColumn/columnReordering.functional.ts

Lines changed: 3 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ test('Column reordering should work when allowColumnReordering is true', async (
1818
await t.expect(await headerRow.getHeaderTexts()).eql(['AI Column', 'ID', 'Name', 'Value']);
1919

2020
// act
21-
await t.drag(headerRow.getHeaderCell(0).element, 100, 0);
21+
await t.drag(headerRow.getHeaderCell(0).element, 150, 0);
2222

2323
// assert
2424
await t.expect(await headerRow.getHeaderTexts()).eql(['ID', 'AI Column', 'Name', 'Value']);
@@ -53,7 +53,7 @@ test('Column reordering should not work when allowColumnReordering is false', as
5353
await t.expect(await headerRow.getHeaderTexts()).eql(['AI Column', 'ID', 'Name', 'Value']);
5454

5555
// act
56-
await t.drag(headerRow.getHeaderCell(0).element, 100, 0);
56+
await t.drag(headerRow.getHeaderCell(0).element, 150, 0);
5757

5858
// assert
5959
await t.expect(await headerRow.getHeaderTexts()).eql(['AI Column', 'ID', 'Name', 'Value']);
@@ -88,7 +88,7 @@ test('Column reordering should not work when it has allowReordering set to false
8888
await t.expect(await headerRow.getHeaderTexts()).eql(['AI Column', 'ID', 'Name', 'Value']);
8989

9090
// act
91-
await t.drag(headerRow.getHeaderCell(0).element, 100, 0);
91+
await t.drag(headerRow.getHeaderCell(0).element, 150, 0);
9292

9393
// assert
9494
await t.expect(await headerRow.getHeaderTexts()).eql(['AI Column', 'ID', 'Name', 'Value']);
@@ -112,42 +112,3 @@ test('Column reordering should not work when it has allowReordering set to false
112112
{ dataField: 'value', caption: 'Value' },
113113
],
114114
}));
115-
116-
test('The draggable AI column should have a caption', async (t) => {
117-
// arrange
118-
const dataGrid = new DataGrid(DATA_GRID_SELECTOR);
119-
120-
await t.expect(dataGrid.isReady()).ok();
121-
122-
// act
123-
await dataGrid.moveHeader(0, 100, 5, true);
124-
125-
// assert
126-
await t
127-
.expect(dataGrid.getDraggableHeader().visible).ok()
128-
.expect(dataGrid.getDraggableHeader().innerText).eql('AI Column');
129-
130-
// act
131-
await dataGrid.dropHeader(0);
132-
133-
// assert
134-
await t.expect(dataGrid.getDraggableHeader().visible).notOk();
135-
}).before(async () => createWidget('dxDataGrid', {
136-
dataSource: [
137-
{ id: 1, name: 'Name 1', value: 10 },
138-
{ id: 2, name: 'Name 2', value: 20 },
139-
{ id: 3, name: 'Name 3', value: 30 },
140-
],
141-
allowColumnReordering: true,
142-
columnWidth: 125,
143-
columns: [
144-
{
145-
type: 'ai',
146-
caption: 'AI Column',
147-
name: 'myAiColumn',
148-
},
149-
{ dataField: 'id', caption: 'ID' },
150-
{ dataField: 'name', caption: 'Name' },
151-
{ dataField: 'value', caption: 'Value' },
152-
],
153-
}));
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import DataGrid from 'devextreme-testcafe-models/dataGrid';
2+
import { createScreenshotsComparer } from 'devextreme-screenshot-comparer';
3+
import url from '../../../../helpers/getPageUrl';
4+
import { createWidget } from '../../../../helpers/createWidget';
5+
6+
fixture.disablePageReloads`Ai Column.ColumnReordering.Visual`
7+
.page(url(__dirname, '../../../container.html'));
8+
9+
const DATA_GRID_SELECTOR = '#container';
10+
11+
test('The draggable AI column should display correctly', async (t) => {
12+
// arrange
13+
const dataGrid = new DataGrid(DATA_GRID_SELECTOR);
14+
const { takeScreenshot, compareResults } = createScreenshotsComparer(t);
15+
16+
await t.expect(dataGrid.isReady()).ok();
17+
18+
await dataGrid.moveHeader(0, 100, 5, true);
19+
20+
// assert
21+
await t.expect(dataGrid.getDraggableHeader().visible).ok();
22+
23+
await takeScreenshot('datagrid__ai-column__dragging.png', dataGrid.element);
24+
25+
// act
26+
await dataGrid.dropHeader(0);
27+
28+
// assert
29+
await t
30+
.expect(dataGrid.getDraggableHeader().visible)
31+
.notOk()
32+
.expect(compareResults.isValid())
33+
.ok(compareResults.errorMessages());
34+
}).before(async () => createWidget('dxDataGrid', {
35+
dataSource: [
36+
{ id: 1, name: 'Name 1', value: 10 },
37+
{ id: 2, name: 'Name 2', value: 20 },
38+
{ id: 3, name: 'Name 3', value: 30 },
39+
],
40+
allowColumnReordering: true,
41+
columnWidth: 200,
42+
columns: [
43+
{
44+
type: 'ai',
45+
caption: 'AI Column',
46+
name: 'myAiColumn',
47+
},
48+
{ dataField: 'id', caption: 'ID' },
49+
{ dataField: 'name', caption: 'Name' },
50+
{ dataField: 'value', caption: 'Value' },
51+
],
52+
}));

e2e/testcafe-devextreme/tests/dataGrid/common/aiColumn/columnResizing.functional.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ const DATA_GRID_SELECTOR = '#container';
2020
.expect(dataGrid.getHeaders().getHeaderRow(0).getHeaderCell(0).element.textContent)
2121
.eql('AI Column')
2222
.expect(dataCell.element.clientWidth)
23-
.eql(100);
23+
.eql(120);
2424

2525
// act
2626
await dataGrid.resizeHeader(1, 50);
2727

2828
// assert
29-
await t.expect(dataCell.element.clientWidth).eql(150);
29+
await t.expect(dataCell.element.clientWidth).eql(170);
3030
}).before(async () => createWidget('dxDataGrid', {
3131
dataSource: [
3232
{ id: 1, name: 'Name 1', value: 10 },
@@ -59,13 +59,13 @@ const DATA_GRID_SELECTOR = '#container';
5959
.expect(dataGrid.getHeaders().getHeaderRow(0).getHeaderCell(0).element.textContent)
6060
.eql('AI Column')
6161
.expect(dataCell.element.clientWidth)
62-
.eql(100);
62+
.eql(120);
6363

6464
// act
6565
await dataGrid.resizeHeader(1, 50);
6666

6767
// assert
68-
await t.expect(dataCell.element.clientWidth).eql(150);
68+
await t.expect(dataCell.element.clientWidth).eql(170);
6969
}).before(async () => createWidget('dxDataGrid', {
7070
dataSource: [
7171
{ id: 1, name: 'Name 1', value: 10 },
@@ -104,13 +104,13 @@ const DATA_GRID_SELECTOR = '#container';
104104
.expect(dataGrid.getHeaders().getHeaderRow(0).getHeaderCell(0).element.textContent)
105105
.eql('AI Column')
106106
.expect(dataCell.element.clientWidth)
107-
.eql(100);
107+
.eql(120);
108108

109109
// act
110110
await dataGrid.resizeHeader(1, 50);
111111

112112
// assert
113-
await t.expect(dataCell.element.clientWidth).eql(100);
113+
await t.expect(dataCell.element.clientWidth).eql(120);
114114
}).before(async () => createWidget('dxDataGrid', {
115115
dataSource: [
116116
{ id: 1, name: 'Name 1', value: 10 },
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import DataGrid from 'devextreme-testcafe-models/dataGrid';
2+
import { createScreenshotsComparer } from 'devextreme-screenshot-comparer';
3+
import url from '../../../../helpers/getPageUrl';
4+
import { createWidget } from '../../../../helpers/createWidget';
5+
6+
fixture.disablePageReloads`Ai Column.ColumnResizing.Visual`
7+
.page(url(__dirname, '../../../container.html'));
8+
9+
const DATA_GRID_SELECTOR = '#container';
10+
11+
test('Resize AI Column when wordWrapEnabled is true', async (t) => {
12+
// arrange
13+
const dataGrid = new DataGrid(DATA_GRID_SELECTOR);
14+
const { takeScreenshot, compareResults } = createScreenshotsComparer(t);
15+
16+
await t.expect(dataGrid.isReady()).ok();
17+
18+
await takeScreenshot('datagrid__ai-column__column-resizing(wordWrapEnabled=true)-1.png', dataGrid.element);
19+
20+
// act
21+
await dataGrid.resizeHeader(1, -150);
22+
23+
await takeScreenshot('datagrid__ai-column__column-resizing(wordWrapEnabled=true)-2.png', dataGrid.element);
24+
25+
// assert
26+
await t
27+
.expect(compareResults.isValid())
28+
.ok(compareResults.errorMessages());
29+
}).before(async () => createWidget('dxDataGrid', {
30+
dataSource: [
31+
{ id: 1, name: 'Name 1', value: 10 },
32+
{ id: 2, name: 'Name 2', value: 20 },
33+
{ id: 3, name: 'Name 3', value: 30 },
34+
],
35+
allowColumnResizing: true,
36+
wordWrapEnabled: true,
37+
columnWidth: 100,
38+
columns: [
39+
{
40+
type: 'ai',
41+
caption: 'AI Column AI Column',
42+
width: 250,
43+
},
44+
{ dataField: 'id', caption: 'ID' },
45+
{ dataField: 'name', caption: 'Name' },
46+
{ dataField: 'value', caption: 'Value' },
47+
],
48+
}));
8.76 KB
Loading
8.76 KB
Loading

0 commit comments

Comments
 (0)