Skip to content

DataGrid - AI Assistant: Implement messageTemplate#33265

Open
Alyar666 wants to merge 8 commits intoDevExpress:26_1from
Alyar666:datagrid_ai_assistant_message_template_26_1
Open

DataGrid - AI Assistant: Implement messageTemplate#33265
Alyar666 wants to merge 8 commits intoDevExpress:26_1from
Alyar666:datagrid_ai_assistant_message_template_26_1

Conversation

@Alyar666
Copy link
Copy Markdown
Contributor

No description provided.

@Alyar666 Alyar666 marked this pull request as ready for review April 20, 2026 10:17
Copilot AI review requested due to automatic review settings April 20, 2026 10:17
@Alyar666 Alyar666 requested review from a team as code owners April 20, 2026 10:17
Copy link
Copy Markdown
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

Implements richer AI Assistant chat message rendering in the DataGrid/TreeList AI Assistant UI, introducing status-aware message templates (pending/success/error) and moving message state management into a dedicated controller.

Changes:

  • Add messageTemplate rendering for AI Assistant messages (status icon/header/body, command result list, pending progress bar, regenerate action).
  • Introduce AIAssistantController to manage message store/data source and AI request lifecycle.
  • Refactor/extend AI chat styles (new aiChat layout, theme-specific includes) and add new localization keys for message headers.

Reviewed changes

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

Show a summary per file
File Description
packages/devextreme/js/localization/messages/ar.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/bg.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/ca.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/cs.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/da.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/de.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/el.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/en.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/es.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/fa.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/fi.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/fr.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/hu.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/it.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/ja.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/ko.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/lt.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/lv.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/nb.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/nl.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/pl.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/pt.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/ro.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/ru.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/sl.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/sv.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/tr.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/uk.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/vi.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/zh.json Add AI chat pending/error header message keys
packages/devextreme/js/localization/messages/zh-tw.json Add AI chat pending/error header message keys
packages/devextreme/js/__internal/grids/tree_list/module_not_extended/ai_assistant.ts Register new AI assistant controller and keep view controller under a new key
packages/devextreme/js/__internal/grids/data_grid/module_not_extended/ai_assistant.ts Register new AI assistant controller and keep view controller under a new key
packages/devextreme/js/__internal/grids/grid_core/m_types.ts Update controller type map for new AI assistant controller naming
packages/devextreme/js/__internal/grids/grid_core/ai_chat/types.ts Re-export command result types and add message status union type
packages/devextreme/js/__internal/grids/grid_core/ai_chat/const.ts Expand AI chat CSS class constants and add regenerate/icon constants
packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.ts Implement custom messageTemplate rendering and status-specific UI
packages/devextreme/js/__internal/grids/grid_core/ai_chat/ai_chat.test.ts Add Jest coverage for new message template behaviors
packages/devextreme/js/__internal/grids/grid_core/ai_assistant/types.ts Introduce AI command/response/result types and callbacks contract
packages/devextreme/js/__internal/grids/grid_core/ai_assistant/grid_commands.ts Add placeholder grid command validation/execution layer
packages/devextreme/js/__internal/grids/grid_core/ai_assistant/const.ts Add AI assistant author constants and shared message status enum
packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_view.ts Move message data source + request sending into controller
packages/devextreme/js/__internal/grids/grid_core/ai_assistant/ai_assistant_controller.ts New controller: message store lifecycle, AI integration callbacks, status transitions
packages/devextreme/js/__internal/grids/grid_core/ai_assistant/tests/ai_assistant_view.test.ts Update tests to mock controller-driven data source and message sending
packages/devextreme/js/__internal/grids/grid_core/ai_assistant/tests/ai_assistant_controller.test.ts Add unit tests for controller request lifecycle and message updates
packages/devextreme-scss/scss/widgets/material/gridBase/layout/aiChat/_index.scss Theme include for new aiChat mixins
packages/devextreme-scss/scss/widgets/material/gridBase/_index.scss Wire aiChat layout module and remove inline empty-view include
packages/devextreme-scss/scss/widgets/generic/gridBase/layout/aiChat/_index.scss Theme include for new aiChat mixins
packages/devextreme-scss/scss/widgets/generic/gridBase/_index.scss Wire aiChat layout module and remove inline empty-view include
packages/devextreme-scss/scss/widgets/fluent/gridBase/layout/aiChat/_index.scss Theme include for new aiChat mixins
packages/devextreme-scss/scss/widgets/fluent/gridBase/_index.scss Wire aiChat layout module and remove inline empty-view include
packages/devextreme-scss/scss/widgets/base/gridBase/layout/aiChat/_mixins.scss New mixins for empty view and pending message styling
packages/devextreme-scss/scss/widgets/base/gridBase/layout/aiChat/_index.scss New base aiChat layout styles (message template layout + progress bar positioning)
packages/devextreme-scss/scss/widgets/base/gridBase/layout/ai-chat/_mixins.scss Remove legacy ai-chat mixins (superseded by aiChat)
packages/devextreme-scss/scss/widgets/base/gridBase/layout/ai-chat/_index.scss Remove legacy ai-chat base styles (superseded by aiChat)
packages/devextreme-scss/scss/widgets/base/gridBase/_mixins.scss Remove legacy forward for ai-chat mixins (path removed)
packages/devextreme-scss/scss/widgets/base/gridBase/_index.scss Switch base gridBase to use new layout/aiChat module

container: this.element(),
createComponent: this._createComponent.bind(this),
onChatCleared: (): void => {},
onRegenerate: (): void => {},
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

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

AIAssistantView passes an empty onRegenerate callback into AIChat. Because AIChat uses the presence of onRegenerate to decide whether to render the regenerate button, this will display a regenerate icon that does nothing when clicked. Either wire this to real regenerate logic or omit the callback until it’s implemented.

Suggested change
onRegenerate: (): void => {},

Copilot uses AI. Check for mistakes.
data: {
id: aiMessageId,
timestamp: parsedTimestamp,
// TODO: need to localize author name and move it to constants or options
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

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

This TODO is partially outdated: the author is already centralized in AI_ASSISTANT_AUTHOR constants. Consider updating the comment to focus on the remaining work (e.g., localization/configurability), so it doesn’t imply the constant extraction is still pending.

Suggested change
// TODO: need to localize author name and move it to constants or options
// TODO: need to make author name configurable/localizable

Copilot uses AI. Check for mistakes.
if (this.isAIChatMessage(message)) {
this.renderAIMessage(message, container);
} else {
$(container).text(message?.text);
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

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

In the non-assistant branch, $(container).text(message?.text) will call the getter overload when message.text is undefined (because jQuery treats undefined as “no argument”), potentially leaving stale content if the container is reused. Use an explicit fallback (e.g., empty string) to ensure the template always writes deterministic content.

Suggested change
$(container).text(message?.text);
$(container).text(message.text ?? '');

Copilot uses AI. Check for mistakes.

// TODO: need to implement real command execution logic
public executeCommands(commands: Command[]): Promise<CommandResults> {
return Promise.resolve([...commands] as unknown as CommandResults);
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

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

executeCommands currently returns the incoming Command[] array cast to CommandResults, but CommandResults items are expected to have { status, message }. This will make the chat template render undefined messages and misclassify statuses. Even as a stub, return properly shaped CommandResult objects (or adjust the types) so the UI can render consistently.

Suggested change
return Promise.resolve([...commands] as unknown as CommandResults);
const results: CommandResults = commands.map(() => ({
status: 'success' as CommandResults[number]['status'],
message: 'Command execution is not implemented yet.',
}));
return Promise.resolve(results);

Copilot uses AI. Check for mistakes.
Comment on lines +53 to +60
if (!response?.commands || response?.explanation) {
// TODO: need to localize default error message when there are no commands
return Promise.reject(new Error(response.explanation || 'Default error message'));
}

if (!this.gridCommands.validate(response.commands)) {
// TODO: need to localize error message on validation fail
return Promise.reject(new Error('Received invalid commands'));
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

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

processResponse rejects whenever response.explanation is truthy, even if valid commands are present. It also doesn't explicitly treat an empty commands array as an error when explanation is empty. Consider checking commands?.length to detect “no commands”, and only using explanation as an error message when commands are missing/invalid.

Suggested change
if (!response?.commands || response?.explanation) {
// TODO: need to localize default error message when there are no commands
return Promise.reject(new Error(response.explanation || 'Default error message'));
}
if (!this.gridCommands.validate(response.commands)) {
// TODO: need to localize error message on validation fail
return Promise.reject(new Error('Received invalid commands'));
if (!response?.commands?.length) {
// TODO: need to localize default error message when there are no commands
return Promise.reject(new Error(response.explanation || 'Default error message'));
}
if (!this.gridCommands.validate(response.commands)) {
// TODO: need to localize error message on validation fail
return Promise.reject(new Error(response.explanation || 'Received invalid commands'));

Copilot uses AI. Check for mistakes.
Comment on lines +206 to +209
private renderPendingState($parent: dxElementWrapper): void {
$('<div>')
.addClass(CLASSES.messageStatus)
.text('Processing...')
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

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

The pending-state status text is hardcoded as "Processing...". Since other AI assistant strings are localized via messageLocalization, this should be localized as well (or derived from an existing localized string) to avoid showing English text in non-English locales.

Suggested change
private renderPendingState($parent: dxElementWrapper): void {
$('<div>')
.addClass(CLASSES.messageStatus)
.text('Processing...')
private getPendingStateText(): string {
return messageLocalization.format('dxDataGrid-aiAssistantProcessing');
}
private renderPendingState($parent: dxElementWrapper): void {
$('<div>')
.addClass(CLASSES.messageStatus)
.text(this.getPendingStateText())

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants