Skip to content

Commit 5c7be56

Browse files
Merge branch '25_2' into 25_2_check_angular_21_in_demos
2 parents 0216add + e41512b commit 5c7be56

File tree

14 files changed

+1048
-394
lines changed

14 files changed

+1048
-394
lines changed

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

Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,30 @@
11
import DataGrid from 'devextreme-testcafe-models/dataGrid';
2+
import { ClientFunction } from 'testcafe';
23
import url from '../../../../helpers/getPageUrl';
34
import { createWidget } from '../../../../helpers/createWidget';
45

5-
fixture.disablePageReloads`Ai Column.Adaptivity`
6-
.page(url(__dirname, '../../../container.html'));
6+
fixture`Ai Column.Adaptivity`
7+
.page(url(__dirname, './pages/containerWithAIIntegration.html'));
78

89
const DATA_GRID_SELECTOR = '#container';
910

11+
const resolveAIRequest = ClientFunction((): void => {
12+
const { aiResponseData } = (window as any);
13+
const { aiResolve } = (window as any);
14+
15+
if (aiResponseData && aiResolve) {
16+
aiResolve(aiResponseData);
17+
18+
(window as any).aiResponseData = null;
19+
(window as any).aiResolve = null;
20+
}
21+
});
22+
23+
const deleteGlobalVariables = ClientFunction((): void => {
24+
delete (window as any).aiResponseData;
25+
delete (window as any).aiResolve;
26+
});
27+
1028
test('The AI column should be hidden when columnHidingEnabled is true', async (t) => {
1129
// arrange, act
1230
const dataGrid = new DataGrid(DATA_GRID_SELECTOR);
@@ -129,3 +147,79 @@ test('The AI column should not be hidden when there is a second AI column with a
129147
{ dataField: 'value', caption: 'Value' },
130148
],
131149
}));
150+
151+
test('The AI column should have value in the adaptive detail row', async (t) => {
152+
const dataGrid = new DataGrid(DATA_GRID_SELECTOR);
153+
154+
// act
155+
await resolveAIRequest();
156+
157+
// assert
158+
await t.expect(dataGrid.isReady()).ok();
159+
160+
const adaptiveButton = dataGrid.getAdaptiveButton();
161+
162+
await t.expect(adaptiveButton.exists).ok();
163+
164+
await t.click(adaptiveButton);
165+
166+
const adaptiveRow = dataGrid.getAdaptiveRow(0);
167+
168+
await t.expect(adaptiveRow.element.exists).ok();
169+
170+
const aiFormItem = adaptiveRow.getAdaptiveCellByText('AI Column');
171+
172+
await t.expect(aiFormItem.element.exists).ok();
173+
174+
await t.expect(aiFormItem.getAdaptiveCellValue()).contains('Response 1');
175+
}).before(async () => createWidget('dxDataGrid', () => ({
176+
dataSource: [
177+
{ id: 1, name: 'Name 1', value: 10 },
178+
{ id: 2, name: 'Name 2', value: 20 },
179+
{ id: 3, name: 'Name 3', value: 30 },
180+
],
181+
keyExpr: 'id',
182+
width: 400,
183+
columnHidingEnabled: true,
184+
showBorders: true,
185+
columns: [
186+
{
187+
dataField: 'id', caption: 'ID', width: 150, hidingPriority: 3,
188+
},
189+
{
190+
dataField: 'name', caption: 'Name', width: 150, hidingPriority: 2,
191+
},
192+
{
193+
dataField: 'value', caption: 'Value', width: 100, hidingPriority: 1,
194+
},
195+
{
196+
name: 'AIcolumn',
197+
caption: 'AI Column',
198+
type: 'ai',
199+
ai: {
200+
prompt: 'Send me nothing',
201+
// eslint-disable-next-line new-cap
202+
aiIntegration: new (window as any).DevExpress.aiIntegration({
203+
sendRequest({ data }) {
204+
return {
205+
promise: new Promise<string>((resolve) => {
206+
const obj = {};
207+
Object.entries(data?.data).forEach(([key, value]) => {
208+
obj[key] = `Response ${(value as any).id}`;
209+
});
210+
211+
(window as any).aiResponseData = JSON.stringify(obj);
212+
(window as any).aiResolve = resolve;
213+
}),
214+
abort: (): void => {},
215+
};
216+
},
217+
}),
218+
},
219+
width: 200,
220+
hidingPriority: 0,
221+
},
222+
],
223+
}))).after(async () => {
224+
await deleteGlobalVariables();
225+
});

packages/devextreme-angular/src/ui/scheduler/nested/form.ts

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -216,14 +216,6 @@ export class DxoSchedulerFormComponent extends NestedOption implements OnDestroy
216216
this._setOption('minColWidth', value);
217217
}
218218

219-
@Input()
220-
get onCanceled(): ((formData: any) => void) {
221-
return this._getOption('onCanceled');
222-
}
223-
set onCanceled(value: ((formData: any) => void)) {
224-
this._setOption('onCanceled', value);
225-
}
226-
227219
@Input()
228220
get onContentReady(): ((e: ContentReadyEvent) => void) {
229221
return this._getOption('onContentReady');
@@ -272,14 +264,6 @@ export class DxoSchedulerFormComponent extends NestedOption implements OnDestroy
272264
this._setOption('onOptionChanged', value);
273265
}
274266

275-
@Input()
276-
get onSaved(): ((formData: any) => void) {
277-
return this._getOption('onSaved');
278-
}
279-
set onSaved(value: ((formData: any) => void)) {
280-
this._setOption('onSaved', value);
281-
}
282-
283267
@Input()
284268
get onSmartPasted(): ((e: SmartPastedEvent) => void) {
285269
return this._getOption('onSmartPasted');

packages/devextreme-react/src/scheduler.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,14 +498,12 @@ type IFormProps = React.PropsWithChildren<{
498498
labelLocation?: LabelLocation;
499499
labelMode?: FormLabelMode;
500500
minColWidth?: number;
501-
onCanceled?: ((formData: any) => void);
502501
onContentReady?: ((e: FormContentReadyEvent) => void);
503502
onDisposing?: ((e: FormDisposingEvent) => void);
504503
onEditorEnterKey?: ((e: EditorEnterKeyEvent) => void);
505504
onFieldDataChanged?: ((e: FieldDataChangedEvent) => void);
506505
onInitialized?: ((e: FormInitializedEvent) => void);
507506
onOptionChanged?: ((e: FormOptionChangedEvent) => void);
508-
onSaved?: ((formData: any) => void);
509507
onSmartPasted?: ((e: SmartPastedEvent) => void);
510508
onSmartPasting?: ((e: SmartPastingEvent) => void);
511509
optionalMark?: string;

packages/devextreme-vue/src/scheduler.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -784,14 +784,12 @@ const DxFormConfig = {
784784
"update:labelLocation": null,
785785
"update:labelMode": null,
786786
"update:minColWidth": null,
787-
"update:onCanceled": null,
788787
"update:onContentReady": null,
789788
"update:onDisposing": null,
790789
"update:onEditorEnterKey": null,
791790
"update:onFieldDataChanged": null,
792791
"update:onInitialized": null,
793792
"update:onOptionChanged": null,
794-
"update:onSaved": null,
795793
"update:onSmartPasted": null,
796794
"update:onSmartPasting": null,
797795
"update:optionalMark": null,
@@ -832,14 +830,12 @@ const DxFormConfig = {
832830
labelLocation: String as PropType<LabelLocation>,
833831
labelMode: String as PropType<FormLabelMode>,
834832
minColWidth: Number,
835-
onCanceled: Function as PropType<((formData: any) => void)>,
836833
onContentReady: Function as PropType<((e: FormContentReadyEvent) => void)>,
837834
onDisposing: Function as PropType<((e: FormDisposingEvent) => void)>,
838835
onEditorEnterKey: Function as PropType<((e: EditorEnterKeyEvent) => void)>,
839836
onFieldDataChanged: Function as PropType<((e: FieldDataChangedEvent) => void)>,
840837
onInitialized: Function as PropType<((e: FormInitializedEvent) => void)>,
841838
onOptionChanged: Function as PropType<((e: FormOptionChangedEvent) => void)>,
842-
onSaved: Function as PropType<((formData: any) => void)>,
843839
onSmartPasted: Function as PropType<((e: SmartPastedEvent) => void)>,
844840
onSmartPasting: Function as PropType<((e: SmartPastingEvent) => void)>,
845841
optionalMark: String,

packages/devextreme/js/__internal/grids/data_grid/__tests__/__mock__/model/data_grid.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,23 @@ export class DataGridModel extends GridCoreModel<DataGrid> {
1717

1818
return this.getInstance().getVisibleColumns(headerLevel);
1919
}
20+
21+
public setDataGridOptions(options: Record<string, unknown>): void {
22+
const instance = this.getInstance();
23+
24+
Object.entries(options).forEach(([optionName, optionValue]) => {
25+
instance.option(optionName, optionValue);
26+
});
27+
}
28+
29+
public setDataGridColumnOptions(
30+
columnName: string,
31+
options: Record<string, unknown>,
32+
): void {
33+
const instance = this.getInstance();
34+
35+
Object.entries(options).forEach(([optionName, optionValue]) => {
36+
instance.columnOption(columnName, optionName, optionValue);
37+
});
38+
}
2039
}

packages/devextreme/js/__internal/grids/grid_core/__tests__/__mock__/model/grid_core.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ const SELECTORS = {
2222
toast: 'dx-toast',
2323
loadPanel: 'dx-loadpanel',
2424
editForm: 'edit-form',
25+
headerCellIndicators: 'dx-column-indicators',
26+
headerCellFilter: 'dx-header-filter',
2527
};
2628

2729
export abstract class GridCoreModel<TInstance extends GridBase = GridBase> {
@@ -48,6 +50,13 @@ export abstract class GridCoreModel<TInstance extends GridBase = GridBase> {
4850
);
4951
}
5052

53+
public getHeaderCellFilter(columnIndex: number): dxElementWrapper {
54+
const $headerCell = $(this.getHeaderCells()[columnIndex]);
55+
const headerFilterSelector = `.${SELECTORS.headerCellIndicators} > .${SELECTORS.headerCellFilter}`;
56+
57+
return $headerCell.find(headerFilterSelector);
58+
}
59+
5160
public getDataRows(): NodeListOf<HTMLElement> {
5261
return this.root.querySelectorAll(`.${SELECTORS.dataRowClass}`);
5362
}

packages/devextreme/js/__internal/grids/grid_core/adaptivity/m_adaptivity.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { isMaterial } from '@js/ui/themes';
1919
import type { ResizingController } from '@ts/grids/grid_core/views/m_grid_view';
2020

2121
import type { ExportController } from '../../data_grid/export/m_export';
22+
import { AI_COLUMN_NAME } from '../ai_column/const';
2223
import type { Column, ColumnsController } from '../columns_controller/m_columns_controller';
2324
import type { ColumnsResizerViewController, DraggingHeaderViewController } from '../columns_resizing_reordering/m_columns_resizing_reordering';
2425
import type { DataController } from '../data_controller/m_data_controller';
@@ -160,6 +161,10 @@ export class AdaptiveColumnsController extends modules.ViewController {
160161
return ['isAdaptiveDetailRowExpanded', 'expandAdaptiveDetailRow', 'collapseAdaptiveDetailRow'];
161162
}
162163

164+
private _getValueFromCellOptions(columnIndex: number, cellOptions: any) {
165+
return cellOptions.row.values[columnIndex];
166+
}
167+
163168
private _isRowEditMode() {
164169
const editMode = this._getEditMode();
165170
return editMode === EDIT_MODE_ROW;
@@ -183,7 +188,12 @@ export class AdaptiveColumnsController extends modules.ViewController {
183188
}
184189
});
185190
const rowData = cellOptions.row.data;
186-
const value = column.calculateCellValue(rowData);
191+
const columnIndex = that._columnsController.getVisibleIndex(column.index);
192+
193+
const value = column.type === AI_COLUMN_NAME
194+
? this._getValueFromCellOptions(columnIndex, cellOptions)
195+
: column.calculateCellValue(rowData);
196+
187197
const displayValue = gridCoreUtils.getDisplayValue(column, value, rowData, cellOptions.rowType);
188198
const text = gridCoreUtils.formatValue(displayValue, column);
189199
const isCellOrBatchEditMode = this._editingController.isCellOrBatchEditMode();
@@ -242,7 +252,7 @@ export class AdaptiveColumnsController extends modules.ViewController {
242252

243253
const renderFormTemplate = function () {
244254
const isItemEdited = that._isItemEdited(item);
245-
templateOptions.value = cellOptions.row.values[columnIndex];
255+
templateOptions.value = that._getValueFromCellOptions(columnIndex, cellOptions);
246256
if (isItemEdited || column.showEditorAlways) {
247257
editingController.renderFormEditorTemplate(templateOptions, item, options, $container, !isItemEdited);
248258
} else {
@@ -257,7 +267,7 @@ export class AdaptiveColumnsController extends modules.ViewController {
257267
if (templateOptions.watch) {
258268
const dispose = templateOptions.watch(() => ({
259269
isItemEdited: that._isItemEdited(item),
260-
value: cellOptions.row.values[columnIndex],
270+
value: that._getValueFromCellOptions(columnIndex, cellOptions),
261271
}), () => {
262272
$container.contents().remove();
263273
$container.removeClass(ADAPTIVE_ITEM_TEXT_CLASS);

0 commit comments

Comments
 (0)