diff --git a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_controller.test.ts b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_controller.test.ts index 3d8d66628625..bd59cf11867a 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_controller.test.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_controller.test.ts @@ -72,6 +72,7 @@ describe('AIAssistantController', () => { () => ({ validate: jest.fn().mockReturnValue(true), executeCommands: jest.fn<() => Promise>().mockResolvedValue([{ status: 'success', message: 'sort' }]), + abort: jest.fn(), }), ); }); @@ -274,4 +275,158 @@ describe('AIAssistantController', () => { await expect(promise).rejects.toThrow('Default error message'); }); }); + + describe('isProcessing', () => { + it('should return false by default', () => { + const controller = createController({ + 'aiAssistant.aiIntegration': mockAIIntegration, + }); + + expect(controller.isProcessing()).toBe(false); + }); + + it('should return true after sendRequestToAI is called', () => { + const controller = createController({ + 'aiAssistant.aiIntegration': mockAIIntegration, + }); + + // eslint-disable-next-line @typescript-eslint/no-floating-promises + controller.sendRequestToAI({ + author: { id: 'user', name: 'User' }, + text: 'Generate values', + timestamp: '2026-04-16T10:00:00.000Z', + } as Message); + + expect(controller.isProcessing()).toBe(true); + }); + + it('should return false after successful command completion', async () => { + const controller = createController({ + 'aiAssistant.aiIntegration': mockAIIntegration, + }); + + const promise = controller.sendRequestToAI({ + author: { id: 'user', name: 'User' }, + text: 'Generate values', + timestamp: '2026-04-16T10:00:00.000Z', + } as Message); + + const actions = [{ name: 'sort', args: { column: 'Name' } }]; + sendRequestCallbacks.onComplete?.({ actions }); + + await promise; + + expect(controller.isProcessing()).toBe(false); + }); + + it('should return false after onError callback', async () => { + const controller = createController({ + 'aiAssistant.aiIntegration': mockAIIntegration, + }); + + const promise = controller.sendRequestToAI({ + author: { id: 'user', name: 'User' }, + text: 'Generate values', + timestamp: '2026-04-16T10:00:00.000Z', + } as Message); + promise.catch(() => {}); + + sendRequestCallbacks.onError?.(new Error('Network error')); + + await expect(promise).rejects.toThrow('Network error'); + + expect(controller.isProcessing()).toBe(false); + }); + + it('should return false after failed command processing', async () => { + const controller = createController({ + 'aiAssistant.aiIntegration': mockAIIntegration, + }); + + const promise = controller.sendRequestToAI({ + author: { id: 'user', name: 'User' }, + text: 'Generate values', + timestamp: '2026-04-16T10:00:00.000Z', + } as Message); + promise.catch(() => {}); + + sendRequestCallbacks.onComplete?.({} as ExecuteGridAssistantCommandResult); + + await expect(promise).rejects.toThrow('Default error message'); + + expect(controller.isProcessing()).toBe(false); + }); + }); + + describe('abortRequest', () => { + it('should fail message with abort error when request is aborted', async () => { + const controller = createController({ + 'aiAssistant.aiIntegration': mockAIIntegration, + }); + + const promise = controller.sendRequestToAI({ + author: { id: 'user', name: 'User' }, + text: 'Generate values', + timestamp: '2026-04-16T10:00:00.000Z', + } as Message); + promise.catch(() => {}); + + controller.abortRequest(); + + const messages = await getStore(controller).load(); + + expect(messages).toEqual([ + expect.objectContaining({ + status: MessageStatus.Failure, + headerText: 'Failed to process request', + text: MessageStatus.Failure, + errorText: 'Request stopped.', + }), + ]); + + await expect(promise).rejects.toThrow('Request stopped.'); + }); + + it('should set isProcessing to false when request is aborted', async () => { + const controller = createController({ + 'aiAssistant.aiIntegration': mockAIIntegration, + }); + + const promise = controller.sendRequestToAI({ + author: { id: 'user', name: 'User' }, + text: 'Generate values', + timestamp: '2026-04-16T10:00:00.000Z', + } as Message); + promise.catch(() => {}); + + expect(controller.isProcessing()).toBe(true); + + controller.abortRequest(); + + await expect(promise).rejects.toThrow(); + + expect(controller.isProcessing()).toBe(false); + }); + + it('should call gridCommands.abort when request is aborted', async () => { + const controller = createController({ + 'aiAssistant.aiIntegration': mockAIIntegration, + }); + + const promise = controller.sendRequestToAI({ + author: { id: 'user', name: 'User' }, + text: 'Generate values', + timestamp: '2026-04-16T10:00:00.000Z', + } as Message); + promise.catch(() => {}); + + const gridCommandsInstance = MockedGridCommands.mock.results[0].value as { abort: jest.Mock }; + + controller.abortRequest(); + + await expect(promise).rejects.toThrow(); + + expect(gridCommandsInstance.abort).toHaveBeenCalledTimes(1); + }); + }); }); diff --git a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_integration_controller.integration.test.ts b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_integration_controller.integration.test.ts index e15adc3d8abc..3f5ba0087f54 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_integration_controller.integration.test.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_integration_controller.integration.test.ts @@ -212,6 +212,106 @@ describe('AIAssistantIntegrationController', () => { }); }); + describe('onAbort callback', () => { + it('should call onAbort callback when request is aborted', async () => { + const onAbort = jest.fn(); + const aiIntegration = createMockAIIntegration(); + + const controller = await createController({ + aiAssistant: { enabled: true, aiIntegration }, + }); + + controller.sendRequest('Sort by name', { + onComplete: jest.fn(), + onError: jest.fn(), + onAbort, + }); + + controller.abortRequest(); + + expect(onAbort).toHaveBeenCalledTimes(1); + }); + + it('should call onAbort callback when new request aborts previous one', async () => { + const onAbort = jest.fn(); + const aiIntegration = createMockAIIntegration(); + + const controller = await createController({ + aiAssistant: { enabled: true, aiIntegration }, + }); + + controller.sendRequest('Sort by name', { + onComplete: jest.fn(), + onError: jest.fn(), + onAbort, + }); + + controller.sendRequest('Sort by id'); + + expect(onAbort).toHaveBeenCalledTimes(1); + }); + + it('should not call onAbort when no callback is provided', async () => { + const aiIntegration = createMockAIIntegration(); + + const controller = await createController({ + aiAssistant: { enabled: true, aiIntegration }, + }); + + controller.sendRequest('Sort by name'); + + expect(() => { + controller.abortRequest(); + }).not.toThrow(); + }); + + it('should not call onAbort when request completes via onComplete', async () => { + let capturedCallbacks: RequestCallbacks = {}; + const onAbort = jest.fn(); + const aiIntegration = createMockAIIntegration((_params, callbacks) => { + capturedCallbacks = callbacks; + }); + + const controller = await createController({ + aiAssistant: { enabled: true, aiIntegration }, + }); + + controller.sendRequest('Sort by name', { + onComplete: jest.fn(), + onError: jest.fn(), + onAbort, + }); + + capturedCallbacks.onComplete?.({ + actions: [{ name: 'sort', args: { column: 'Name' } }], + } as ExecuteGridAssistantCommandResult); + + expect(onAbort).not.toHaveBeenCalled(); + }); + + it('should not call onAbort when request completes via onError', async () => { + let capturedCallbacks: RequestCallbacks = {}; + const onAbort = jest.fn(); + const aiIntegration = createMockAIIntegration((_params, callbacks) => { + capturedCallbacks = callbacks; + }); + + const controller = await createController({ + aiAssistant: { enabled: true, aiIntegration }, + }); + + controller.sendRequest('Sort by name', { + onComplete: jest.fn(), + onError: jest.fn(), + onAbort, + }); + + capturedCallbacks.onError?.(new Error('Network error')); + + expect(onAbort).not.toHaveBeenCalled(); + }); + }); + describe('dispose', () => { it('should abort request on dispose', async () => { const abortSpy = jest.fn(); diff --git a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_view.test.ts b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_view.test.ts index 66ababe9498a..74b85890af8b 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_view.test.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_view.test.ts @@ -39,6 +39,8 @@ const mockMessageDataSource = { store: new ArrayStore({ key: 'id' }), reshapeOnP const mockAIAssistantController = { getMessageDataSource: jest.fn().mockReturnValue(mockMessageDataSource), sendRequestToAI: jest.fn(), + isProcessing: jest.fn().mockReturnValue(false), + abortRequest: jest.fn(), }; const createAIAssistantView = ({ @@ -280,6 +282,17 @@ describe('AIAssistantView', () => { }); }); + describe('onHidden', () => { + it('should call abortRequest on controller when popup onHidden is triggered', () => { + createAIAssistantView(); + + const aiChatConfig = (AIChat as jest.Mock).mock.calls[0][0] as AIChatOptions; + aiChatConfig.popupOptions?.onHidden?.({} as any); + + expect(mockAIAssistantController.abortRequest).toHaveBeenCalledTimes(1); + }); + }); + describe('chat event handlers', () => { describe('onChatCleared', () => { it('should call clear on aiChatInstance when triggered', () => { @@ -312,12 +325,10 @@ describe('AIAssistantView', () => { expect(mockAIAssistantController.sendRequestToAI).toHaveBeenCalledWith(message); }); - it('should not send request when chat is disabled', () => { + it('should not send request when request is already processing', () => { createAIAssistantView(); - const aiChatInstance = (AIChat as jest.Mock) - .mock.results[0].value as { isDisabled: jest.Mock; setDisabled: jest.Mock }; - aiChatInstance.isDisabled.mockReturnValue(true); + mockAIAssistantController.isProcessing.mockReturnValueOnce(true); const aiChatConfig = (AIChat as jest.Mock).mock.calls[0][0] as AIChatOptions; const message = { @@ -368,8 +379,8 @@ describe('AIAssistantView', () => { }); it('should call setDisabled(false) after request fails', async () => { - mockAIAssistantController.sendRequestToAI.mockReturnValue( - Promise.reject(new Error('Network error')), + mockAIAssistantController.sendRequestToAI.mockImplementation( + () => Promise.reject(new Error('Network error')), ); createAIAssistantView(); diff --git a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_view_controller.integration.test.ts b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_view_controller.integration.test.ts index 78c9aa12e26b..74fe060dbc00 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_view_controller.integration.test.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/__tests__/ai_assistant_view_controller.integration.test.ts @@ -379,5 +379,33 @@ describe('AIAssistantViewController', () => { expect(findMessageElements().length).toBe(0); }); + + it('should render abort message after closing and reopening AI chat', async () => { + const { instance } = await createDataGridWithAIAssistant(); + + sendAIRequest(instance, 'Sort by Name'); + + expect(findMessageElements().length).toBe(1); + expect(getMessageStatusClass(findMessageElements().eq(0))).toBe(MessageStatus.Pending); + + const viewController = instance.getController('aiAssistantViewController'); + + // Close the AI assistant popup + await viewController.toggle(); + jest.runAllTimers(); + await flushAsync(); + + // Reopen the AI assistant popup + await viewController.toggle(); + jest.runAllTimers(); + await flushAsync(); + + const $messages = findMessageElements(); + + expect($messages.length).toBe(1); + expect(getMessageStatusClass($messages.eq(0))).toBe(MessageStatus.Failure); + expect($messages.eq(0).find(`.${CLASSES.messageErrorText}`).text()) + .toBe('Request stopped.'); + }); }); }); diff --git a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_controller.ts b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_controller.ts index 5d340ed6598c..42971568b6d6 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_controller.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_controller.ts @@ -23,6 +23,8 @@ export class AIAssistantController extends Controller { private aiAssistantIntegrationController?: AIAssistantIntegrationController; + private processing = false; + // TODO: need to implement method for getting customized response title private getCustomizedResponseTitle(): string { return ''; @@ -112,6 +114,10 @@ export class AIAssistantController extends Controller { }); } + private setProcessing(value: boolean): void { + this.processing = value; + } + public init(): void { // TODO: initialize default commands list when they are ready this.gridCommands = new GridCommands(this.component, []); @@ -128,8 +134,13 @@ export class AIAssistantController extends Controller { }; } + public isProcessing(): boolean { + return this.processing; + } + public sendRequestToAI(message: Message): Promise { const aiMessageId = this.createPendingAIMessage(message); + this.setProcessing(true); return new Promise((resolve, reject) => { this.aiAssistantIntegrationController?.sendRequest(message.text, { @@ -137,6 +148,7 @@ export class AIAssistantController extends Controller { fromPromise(this.processResponse(response)) .done((commands: CommandResults) => { this.completeAIMessage(aiMessageId, commands); + this.setProcessing(false); resolve(); }) .fail((errorMessage) => { @@ -145,17 +157,31 @@ export class AIAssistantController extends Controller { : new Error(String(errorMessage)); this.failAIMessage(aiMessageId, error); + this.setProcessing(false); reject(error); }); }, onError: (error: Error): void => { this.failAIMessage(aiMessageId, error); + this.setProcessing(false); + reject(error); + }, + onAbort: (): void => { + const error = new Error(messageLocalization.format('dxDataGrid-aiAssistantAbortMessage')); + + this.failAIMessage(aiMessageId, error); + this.setProcessing(false); reject(error); }, }); }); } + public abortRequest(): void { + this.aiAssistantIntegrationController?.abortRequest(); + this.gridCommands?.abort(); + } + public dispose(): void { super.dispose(); this.aiAssistantIntegrationController?.dispose(); diff --git a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_integration_controller.ts b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_integration_controller.ts index 732b2ffa92af..d719f8f8ff91 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_integration_controller.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_integration_controller.ts @@ -6,6 +6,7 @@ import type { import errors from '@js/ui/widget/ui.errors'; import { Controller } from '../m_modules'; +import type { AIAssistantRequestCallbacks } from './types'; export class AIAssistantIntegrationController extends Controller { private abort?: () => void; @@ -31,7 +32,7 @@ export class AIAssistantIntegrationController extends Controller { public sendRequest( text: string, - callbacks?: RequestCallbacks, + callbacks?: AIAssistantRequestCallbacks, ): void { if (this.isRequestAwaitingCompletion()) { this.abortRequest(); @@ -57,7 +58,7 @@ export class AIAssistantIntegrationController extends Controller { return; } - this.abort = aiIntegration.executeGridAssistant( + const abortRequest = aiIntegration.executeGridAssistant( { text, context: args.context, @@ -66,6 +67,11 @@ export class AIAssistantIntegrationController extends Controller { }, this.getAICommandCallbacks(callbacks), ); + + this.abort = (): void => { + abortRequest(); + callbacks?.onAbort?.(); + }; } public isRequestAwaitingCompletion(): boolean { @@ -101,11 +107,10 @@ export class AIAssistantIntegrationController extends Controller { } private processCommandCompletion(): void { - this.abortRequest(); + this.abort = undefined; } // TODO: implement buildContext with grid commands - // eslint-disable-next-line class-methods-use-this private buildContext(): Record { return {}; } diff --git a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_view.ts b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_view.ts index 99fb47f58ce4..529848eae183 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_view.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_view.ts @@ -83,6 +83,7 @@ export class AIAssistantView extends View { }, onHidden: (): void => { this.visibilityChanged?.fire(false); + this.aiAssistantController.abortRequest(); }, ...this.option('aiAssistant.popup'), }; @@ -93,7 +94,7 @@ export class AIAssistantView extends View { dataSource: this.aiAssistantController.getMessageDataSource(), reloadOnChange: true, onMessageEntered: (e): void => { - if (this.aiChatInstance?.isDisabled()) { + if (this.aiAssistantController.isProcessing()) { return; } diff --git a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/types.ts b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/types.ts index 3c64923fc1e9..02807eb65a2e 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/types.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/ai_assistant/types.ts @@ -1,3 +1,4 @@ +import type { RequestCallbacks } from '@js/common/ai-integration'; import type { InternalGrid } from '@ts/grids/grid_core/m_types'; import type { z, ZodObject, ZodRawShape } from 'zod'; import type { JsonSchema7Type } from 'zod-to-json-schema'; @@ -56,3 +57,7 @@ export type CustomizeResponseText = ( commandName: string, commandArgs: Record, ) => Partial | undefined; + +export type AIAssistantRequestCallbacks = RequestCallbacks & { + onAbort?: () => void; +}; diff --git a/packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.test.ts b/packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.test.ts index 02c0bd716c42..f6729534c590 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.test.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.test.ts @@ -835,31 +835,6 @@ describe('AIChat', () => { }); }); - describe('isDisabled', () => { - it('should return false by default', () => { - const { aiChat } = createAIChat(); - - expect(aiChat.isDisabled()).toBe(false); - }); - - it('should return true after setDisabled(true)', () => { - const { aiChat } = createAIChat(); - - aiChat.setDisabled(true); - - expect(aiChat.isDisabled()).toBe(true); - }); - - it('should return false after setDisabled(false)', () => { - const { aiChat } = createAIChat(); - - aiChat.setDisabled(true); - aiChat.setDisabled(false); - - expect(aiChat.isDisabled()).toBe(false); - }); - }); - describe('regenerate button in disabled state', () => { it('should not call onRegenerate when chat is disabled', () => { const onRegenerate = jest.fn(); diff --git a/packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.ts b/packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.ts index a85260550599..af41c0d6e0e7 100644 --- a/packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.ts +++ b/packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.ts @@ -316,10 +316,6 @@ export class AIChat { this.setClearChatButtonDisabled(disabled); } - public isDisabled(): boolean { - return this.disabled; - } - public renderAIMessage(message: Message, container: HTMLElement): void { const $message = $('
') .addClass(`${CLASSES.message} ${getMessageStateClass(message.status)}`) diff --git a/packages/devextreme/js/localization/messages/ar.json b/packages/devextreme/js/localization/messages/ar.json index 95a4548d92b4..c76883eb3da9 100644 --- a/packages/devextreme/js/localization/messages/ar.json +++ b/packages/devextreme/js/localization/messages/ar.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/bg.json b/packages/devextreme/js/localization/messages/bg.json index 344c8580a5fe..72dbe90b6ce9 100644 --- a/packages/devextreme/js/localization/messages/bg.json +++ b/packages/devextreme/js/localization/messages/bg.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/ca.json b/packages/devextreme/js/localization/messages/ca.json index d820ab2e7218..1791f38a28c4 100644 --- a/packages/devextreme/js/localization/messages/ca.json +++ b/packages/devextreme/js/localization/messages/ca.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/cs.json b/packages/devextreme/js/localization/messages/cs.json index e5e551e3db55..de7d6f4fcb54 100644 --- a/packages/devextreme/js/localization/messages/cs.json +++ b/packages/devextreme/js/localization/messages/cs.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/da.json b/packages/devextreme/js/localization/messages/da.json index 12adf88a77e7..c2d0af06b3ab 100644 --- a/packages/devextreme/js/localization/messages/da.json +++ b/packages/devextreme/js/localization/messages/da.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/de.json b/packages/devextreme/js/localization/messages/de.json index d57ab3762741..f7071efedff8 100644 --- a/packages/devextreme/js/localization/messages/de.json +++ b/packages/devextreme/js/localization/messages/de.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/el.json b/packages/devextreme/js/localization/messages/el.json index 8a08c122170d..b249f49e5bbc 100644 --- a/packages/devextreme/js/localization/messages/el.json +++ b/packages/devextreme/js/localization/messages/el.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/en.json b/packages/devextreme/js/localization/messages/en.json index 276cb8dfeddf..755fff6a6566 100644 --- a/packages/devextreme/js/localization/messages/en.json +++ b/packages/devextreme/js/localization/messages/en.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/es.json b/packages/devextreme/js/localization/messages/es.json index a6c2b6601400..54ecaa1dc82d 100644 --- a/packages/devextreme/js/localization/messages/es.json +++ b/packages/devextreme/js/localization/messages/es.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/fa.json b/packages/devextreme/js/localization/messages/fa.json index 6d8dbeeaea96..2c7784ad28a2 100644 --- a/packages/devextreme/js/localization/messages/fa.json +++ b/packages/devextreme/js/localization/messages/fa.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/fi.json b/packages/devextreme/js/localization/messages/fi.json index 79bca31153e1..e653ff26affe 100644 --- a/packages/devextreme/js/localization/messages/fi.json +++ b/packages/devextreme/js/localization/messages/fi.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/fr.json b/packages/devextreme/js/localization/messages/fr.json index 211de17db919..2ab4f80d2df1 100644 --- a/packages/devextreme/js/localization/messages/fr.json +++ b/packages/devextreme/js/localization/messages/fr.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/hu.json b/packages/devextreme/js/localization/messages/hu.json index 96c8b4987d38..fadf3a727b58 100644 --- a/packages/devextreme/js/localization/messages/hu.json +++ b/packages/devextreme/js/localization/messages/hu.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/it.json b/packages/devextreme/js/localization/messages/it.json index 209acb848652..716a965291ee 100644 --- a/packages/devextreme/js/localization/messages/it.json +++ b/packages/devextreme/js/localization/messages/it.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/ja.json b/packages/devextreme/js/localization/messages/ja.json index a943d2a2a681..63d18e7ecf60 100644 --- a/packages/devextreme/js/localization/messages/ja.json +++ b/packages/devextreme/js/localization/messages/ja.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/ko.json b/packages/devextreme/js/localization/messages/ko.json index 05a6dec18786..1ab99ce0b716 100644 --- a/packages/devextreme/js/localization/messages/ko.json +++ b/packages/devextreme/js/localization/messages/ko.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/lt.json b/packages/devextreme/js/localization/messages/lt.json index c0cd590e862c..0357ddd346ce 100644 --- a/packages/devextreme/js/localization/messages/lt.json +++ b/packages/devextreme/js/localization/messages/lt.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/lv.json b/packages/devextreme/js/localization/messages/lv.json index 3f9d49141d6e..c4ec853d42e8 100644 --- a/packages/devextreme/js/localization/messages/lv.json +++ b/packages/devextreme/js/localization/messages/lv.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/nb.json b/packages/devextreme/js/localization/messages/nb.json index 2b1379c1461f..c0bd664f6669 100644 --- a/packages/devextreme/js/localization/messages/nb.json +++ b/packages/devextreme/js/localization/messages/nb.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/nl.json b/packages/devextreme/js/localization/messages/nl.json index 1e3137f4662e..5d58cfe6d586 100644 --- a/packages/devextreme/js/localization/messages/nl.json +++ b/packages/devextreme/js/localization/messages/nl.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/pl.json b/packages/devextreme/js/localization/messages/pl.json index 55459f1e00fc..672e80a0b385 100644 --- a/packages/devextreme/js/localization/messages/pl.json +++ b/packages/devextreme/js/localization/messages/pl.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/pt.json b/packages/devextreme/js/localization/messages/pt.json index f3a342511b3d..0106658d81b1 100644 --- a/packages/devextreme/js/localization/messages/pt.json +++ b/packages/devextreme/js/localization/messages/pt.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/ro.json b/packages/devextreme/js/localization/messages/ro.json index 4d7e6835420b..08b80432fc1f 100644 --- a/packages/devextreme/js/localization/messages/ro.json +++ b/packages/devextreme/js/localization/messages/ro.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/ru.json b/packages/devextreme/js/localization/messages/ru.json index a2679472af63..1e04e295a2b3 100644 --- a/packages/devextreme/js/localization/messages/ru.json +++ b/packages/devextreme/js/localization/messages/ru.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/sl.json b/packages/devextreme/js/localization/messages/sl.json index 2c5a502f5845..1e70c12a9b8b 100644 --- a/packages/devextreme/js/localization/messages/sl.json +++ b/packages/devextreme/js/localization/messages/sl.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/sv.json b/packages/devextreme/js/localization/messages/sv.json index c68cec2e3b59..0f3fdc824f60 100644 --- a/packages/devextreme/js/localization/messages/sv.json +++ b/packages/devextreme/js/localization/messages/sv.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/tr.json b/packages/devextreme/js/localization/messages/tr.json index 461e455463d0..ed68215e84db 100644 --- a/packages/devextreme/js/localization/messages/tr.json +++ b/packages/devextreme/js/localization/messages/tr.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/uk.json b/packages/devextreme/js/localization/messages/uk.json index 310b10fb8acc..17ec136d484d 100644 --- a/packages/devextreme/js/localization/messages/uk.json +++ b/packages/devextreme/js/localization/messages/uk.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/vi.json b/packages/devextreme/js/localization/messages/vi.json index 778713b2007b..55d63a3e0baf 100644 --- a/packages/devextreme/js/localization/messages/vi.json +++ b/packages/devextreme/js/localization/messages/vi.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/zh-tw.json b/packages/devextreme/js/localization/messages/zh-tw.json index 7a25712ce126..ce913207383f 100644 --- a/packages/devextreme/js/localization/messages/zh-tw.json +++ b/packages/devextreme/js/localization/messages/zh-tw.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted", diff --git a/packages/devextreme/js/localization/messages/zh.json b/packages/devextreme/js/localization/messages/zh.json index bbad56686352..131c7dfe26e6 100644 --- a/packages/devextreme/js/localization/messages/zh.json +++ b/packages/devextreme/js/localization/messages/zh.json @@ -111,6 +111,7 @@ "dxDataGrid-aiAssistantProcessingMessageHeader": "Request in progress", "dxDataGrid-aiAssistantProcessingMessage": "Processing...", "dxDataGrid-aiAssistantErrorMessageHeader": "Failed to process request", + "dxDataGrid-aiAssistantAbortMessage": "Request stopped.", "dxDataGrid-aiAssistantSuccessMessage": "Success", "dxDataGrid-aiAssistantErrorMessage": "Error", "dxDataGrid-aiAssistantExecutionAbortMessage": "Execution Interrupted",