From 8eccc5c3d4be34cd40a254313c5fdf7582c78c59 Mon Sep 17 00:00:00 2001 From: Diana Gromova <72144169+16adianay@users.noreply.github.com> Date: Fri, 9 Oct 2026 17:23:50 +0400 Subject: [PATCH 01/12] Fix a mixed use case --- .../Chat/PageLevelAIAssistant/Angular/app/app.service.ts | 4 ++-- apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/chatRouter.ts | 4 ++-- apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.service.ts b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.service.ts index e24da4a89d5b..535a62511542 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.service.ts +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.service.ts @@ -124,6 +124,8 @@ function buildGridResultsPromise( const columnNames = getGridColumnNames(gridInstance); const prompt = `${buildGridSystemPrompt(columnNames)}\n\nUser request: '${text}'`; + gridInstance?.instance.beginCustomLoading(''); + return executeAiCommand(prompt, aiIntegration) .then((parsed) => { const actions = Array.isArray((parsed as { actions?: ExecuteGridAssistantAction[] })?.actions) @@ -219,8 +221,6 @@ async function runCommand( } if (target === 'grid') { - gridInstance?.instance.beginCustomLoading(''); - const { results: gridResults, error: gridError } = await buildGridResultsPromise(gridInstance, aiIntegration, text); return joinSucceededOrThrow(gridResults, gridError); diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/chatRouter.ts b/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/chatRouter.ts index 4d711a1d243c..06e09175c776 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/chatRouter.ts +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/chatRouter.ts @@ -126,6 +126,8 @@ function buildGridResultsPromise( const columnNames = getGridColumnNames(gridInstance); const prompt = `${buildGridSystemPrompt(columnNames)}\n\nUser request: '${text}'`; + gridInstance?.beginCustomLoading(''); + return executeAiCommand(prompt, aiIntegration) .then((parsed) => { const actions = Array.isArray((parsed as { actions?: ExecuteGridAssistantAction[] })?.actions) @@ -221,8 +223,6 @@ async function runCommand( } if (target === 'grid') { - gridInstance?.beginCustomLoading(''); - const { results: gridResults, error: gridError } = await buildGridResultsPromise(gridInstance, aiIntegration, text); return joinSucceededOrThrow(gridResults, gridError); diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js index a600327f0824..6f0ac4ef4c61 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js @@ -811,6 +811,8 @@ function buildGridResultsPromise(gridInstance, aiIntegration, text) { const columnNames = getGridColumnNames(gridInstance); const prompt = `${buildGridSystemPrompt(columnNames)}\n\nUser request: '${text}'`; + gridInstance?.beginCustomLoading(''); + return executeAiCommand(prompt, aiIntegration) .then((parsed) => { const actions = Array.isArray(parsed.actions) ? parsed.actions : []; @@ -906,8 +908,6 @@ async function runCommand(text, { form, gridInstance, aiIntegration }) { } if (target === 'grid') { - gridInstance?.beginCustomLoading(''); - const { results: gridResults, error: gridError } = await buildGridResultsPromise(gridInstance, aiIntegration, text); From e60bfb1b5a2e6ea1613a6ec3e4ab4da16df3c1db Mon Sep 17 00:00:00 2001 From: Diana Gromova <72144169+16adianay@users.noreply.github.com> Date: Fri, 9 Oct 2026 17:28:04 +0400 Subject: [PATCH 02/12] Fix default form target to smart_paste when formAction is missing https://github.com/DevExpress/DevExtreme/pull/35603#discussion_r4230333514 --- .../Chat/PageLevelAIAssistant/Angular/app/app.service.ts | 2 +- .../Demos/Chat/PageLevelAIAssistant/React/chat-router.ts | 2 +- .../Demos/Chat/PageLevelAIAssistant/ReactJs/chat-router.js | 2 +- apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js | 6 +++++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.service.ts b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.service.ts index 535a62511542..8c22123a59f7 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.service.ts +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.service.ts @@ -215,7 +215,7 @@ async function runCommand( } if (target === 'form') { - const { results: formResults, error: formError } = await buildFormResultsPromise(form, formAction, text); + const { results: formResults, error: formError } = await buildFormResultsPromise(form, formAction ?? { type: 'smart_paste' }, text); return joinSucceededOrThrow(formResults, formError); } diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/React/chat-router.ts b/apps/demos/Demos/Chat/PageLevelAIAssistant/React/chat-router.ts index 9f2fc2939d96..b95dd22953fe 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/React/chat-router.ts +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/React/chat-router.ts @@ -212,7 +212,7 @@ async function runCommand(text: string, { form, gridInstance, aiIntegration }: R } if (target === 'form') { - const { results, error } = await buildFormResultsPromise(form, formAction, text); + const { results, error } = await buildFormResultsPromise(form, formAction ?? { type: 'smart_paste' }, text); return joinSucceededOrThrow(results, error); } diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/chat-router.js b/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/chat-router.js index 663870eda590..2119f2b36e5e 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/chat-router.js +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/chat-router.js @@ -176,7 +176,7 @@ async function runCommand(text, { form, gridInstance, aiIntegration }) { ); } if (target === 'form') { - const { results, error } = await buildFormResultsPromise(form, formAction, text); + const { results, error } = await buildFormResultsPromise(form, formAction ?? { type: 'smart_paste' }, text); return joinSucceededOrThrow(results, error); } if (target === 'grid') { diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js index 6f0ac4ef4c61..05c7fc01b1de 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js @@ -902,7 +902,11 @@ async function runCommand(text, { form, gridInstance, aiIntegration }) { if (target === 'form') { const { results: formResults, error: formError } = - await buildFormResultsPromise(form, formAction, text); + await buildFormResultsPromise( + form, + formAction ?? { type: 'smart_paste' }, + text, + ); return joinSucceededOrThrow(formResults, formError); } From 597bfa67ec12a6ece0f51e82fbd48503b8f43e4c Mon Sep 17 00:00:00 2001 From: Diana Gromova <72144169+16adianay@users.noreply.github.com> Date: Wed, 14 Oct 2026 12:10:41 +0400 Subject: [PATCH 03/12] Remove an unused class --- .../Demos/Chat/PageLevelAIAssistant/jQuery/styles.css | 7 ------- 1 file changed, 7 deletions(-) diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/styles.css b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/styles.css index 9945431922a2..115676262ddf 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/styles.css +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/styles.css @@ -27,13 +27,6 @@ height: 556px; } -.ai-chat-empty-icon { - font-size: 32px; - color: #337ab7; - text-align: center; - margin-bottom: 12px; -} - .ai-chat-empty-message { font-size: 18px; font-weight: 400; From a31991b44d1e46729c6fe1e32c256c3dc61dd097 Mon Sep 17 00:00:00 2001 From: Diana Gromova <72144169+16adianay@users.noreply.github.com> Date: Wed, 14 Oct 2026 18:12:59 +0400 Subject: [PATCH 04/12] Fix an input placeholder (according to EU law on AI content labeling) --- .../Chat/PageLevelAIAssistant/Angular/app/app.component.ts | 2 +- apps/demos/Demos/Chat/PageLevelAIAssistant/React/App.tsx | 2 +- apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/App.js | 2 +- apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/App.vue | 2 +- apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.component.ts b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.component.ts index 3bd87ec8e3a5..bdad4fc97e87 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.component.ts +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.component.ts @@ -36,7 +36,7 @@ config({ loadMessages({ en: { - 'dxChat-textareaPlaceholder': 'Enter a prompt...', + 'dxChat-textareaPlaceholder': 'Ask AI Assistant...', }, }); diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/React/App.tsx b/apps/demos/Demos/Chat/PageLevelAIAssistant/React/App.tsx index 8c2284149f6d..acbb932ddb5d 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/React/App.tsx +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/React/App.tsx @@ -8,7 +8,7 @@ import TaskGrid from './TaskGrid.tsx'; import AiAssistant from './AiAssistant.tsx'; import { aiIntegration } from './service.ts'; -loadMessages({ en: { 'dxChat-textareaPlaceholder': 'Enter a prompt...' } }); +loadMessages({ en: { 'dxChat-textareaPlaceholder': 'Ask AI Assistant...' } }); config({ editorStylingMode: 'filled', floatingActionButtonConfig: { diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/App.js b/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/App.js index b495885a042b..f43349ccaf03 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/App.js +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/App.js @@ -6,7 +6,7 @@ import TaskGrid from './TaskGrid.js'; import AiAssistant from './AiAssistant.js'; import { aiIntegration } from './service.js'; -loadMessages({ en: { 'dxChat-textareaPlaceholder': 'Enter a prompt...' } }); +loadMessages({ en: { 'dxChat-textareaPlaceholder': 'Ask AI Assistant...' } }); config({ editorStylingMode: 'filled', floatingActionButtonConfig: { diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/App.vue b/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/App.vue index 42cf8128034c..331564266cec 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/App.vue +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/App.vue @@ -38,7 +38,7 @@ config({ loadMessages({ en: { - 'dxChat-textareaPlaceholder': 'Enter a prompt...', + 'dxChat-textareaPlaceholder': 'Ask AI Assistant...', }, }); diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js index 05c7fc01b1de..c202e2cd9942 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js @@ -13,7 +13,7 @@ $(() => { DevExpress.localization.loadMessages({ en: { - 'dxChat-textareaPlaceholder': 'Enter a prompt...', + 'dxChat-textareaPlaceholder': 'Ask AI Assistant...', }, }); From e2edde3bd83013219d77ccaf2b61ff55b0c083a1 Mon Sep 17 00:00:00 2001 From: Diana Gromova <72144169+16adianay@users.noreply.github.com> Date: Wed, 14 Oct 2026 18:40:07 +0400 Subject: [PATCH 05/12] Move chatStore and chatDataSource to useState --- .../React/AiAssistant.tsx | 10 +++---- .../ReactJs/AiAssistant.js | 27 ++++++++++--------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/React/AiAssistant.tsx b/apps/demos/Demos/Chat/PageLevelAIAssistant/React/AiAssistant.tsx index 2b811cd7a96e..a59c7f900901 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/React/AiAssistant.tsx +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/React/AiAssistant.tsx @@ -9,8 +9,6 @@ import { routeMessage } from './chat-router.ts'; import { emptyViewMessage } from './data.ts'; import type { AiAssistantProps, PushMessage } from './data.ts'; -const chatStore = new ArrayStore({ key: 'id' }); -const chatDataSource = new DataSource({ store: chatStore, paginate: false }); const chatSuggestionItems = [ { text: 'Show Completed Tasks', prompt: 'Show Completed Tasks' }, { text: 'Change State to Texas', prompt: 'Change State to Texas' }, @@ -35,14 +33,16 @@ export default function AiAssistant({ formRef, gridRef, aiIntegration }: AiAssis const clearButtonInstance = useRef | null>(null); const [visible, setVisible] = useState(false); const [disabled, setDisabled] = useState(false); + const [chatStore] = useState(() => new ArrayStore({ key: 'id' })); + const [chatDataSource] = useState(() => new DataSource({ store: chatStore, paginate: false })); const updateClearButtonState = useCallback((): void => { clearButtonInstance.current?.option('disabled', chatDataSource.items().length === 0); - }, []); + }, [chatDataSource]); const pushMessage: PushMessage = useCallback((message) => { chatStore.push([{ type: 'insert', data: { id: Date.now() + Math.random(), timestamp: new Date(), ...message } }]); - }, []); + }, [chatStore]); const handleUserMessage = useCallback((message: ChatTypes.Message): void => { const form = formRef.current?.instance(); @@ -80,7 +80,7 @@ export default function AiAssistant({ formRef, gridRef, aiIntegration }: AiAssis chatStore.clear(); chatDataSource.reload(); updateClearButtonState(); - }, [updateClearButtonState]); + }, [chatStore, chatDataSource, updateClearButtonState]); const onPopupShowing = useCallback((): void => setVisible(true), []); const onPopupHiding = useCallback((): void => setVisible(false), []); diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/AiAssistant.js b/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/AiAssistant.js index 5d32f66a884b..777dd108ddf4 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/AiAssistant.js +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/AiAssistant.js @@ -8,8 +8,6 @@ import { ArrayStore, DataSource } from 'devextreme-react/common/data'; import { routeMessage } from './chat-router.js'; import { emptyViewMessage } from './data.js'; -const chatStore = new ArrayStore({ key: 'id' }); -const chatDataSource = new DataSource({ store: chatStore, paginate: false }); const chatSuggestionItems = [ { text: 'Show Completed Tasks', prompt: 'Show Completed Tasks' }, { text: 'Change State to Texas', prompt: 'Change State to Texas' }, @@ -37,17 +35,22 @@ export default function AiAssistant({ formRef, gridRef, aiIntegration }) { const clearButtonInstance = useRef(null); const [visible, setVisible] = useState(false); const [disabled, setDisabled] = useState(false); + const [chatStore] = useState(() => new ArrayStore({ key: 'id' })); + const [chatDataSource] = useState(() => new DataSource({ store: chatStore, paginate: false })); const updateClearButtonState = useCallback(() => { clearButtonInstance.current?.option('disabled', chatDataSource.items().length === 0); - }, []); - const pushMessage = useCallback((message) => { - chatStore.push([ - { - type: 'insert', - data: { id: Date.now() + Math.random(), timestamp: new Date(), ...message }, - }, - ]); - }, []); + }, [chatDataSource]); + const pushMessage = useCallback( + (message) => { + chatStore.push([ + { + type: 'insert', + data: { id: Date.now() + Math.random(), timestamp: new Date(), ...message }, + }, + ]); + }, + [chatStore], + ); const handleUserMessage = useCallback( (message) => { const form = formRef.current?.instance(); @@ -93,7 +96,7 @@ export default function AiAssistant({ formRef, gridRef, aiIntegration }) { chatStore.clear(); chatDataSource.reload(); updateClearButtonState(); - }, [updateClearButtonState]); + }, [chatStore, chatDataSource, updateClearButtonState]); const onPopupShowing = useCallback(() => setVisible(true), []); const onPopupHiding = useCallback(() => setVisible(false), []); const onClearButtonInitialized = useCallback( From 8895d8f080afc1f7c72f3767accf9e8d54f67420 Mon Sep 17 00:00:00 2001 From: Diana Gromova <72144169+16adianay@users.noreply.github.com> Date: Wed, 14 Oct 2026 18:50:56 +0400 Subject: [PATCH 06/12] Remove SystemJS --- .../PageLevelAIAssistant/Angular/app/app.component.ts | 10 ++-------- .../components/ai-assistant/ai-assistant.component.ts | 10 ++-------- .../employee-form/employee-form.component.ts | 10 ++-------- .../app/components/task-grid/task-grid.component.ts | 10 ++-------- 4 files changed, 8 insertions(+), 32 deletions(-) diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.component.ts b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.component.ts index bdad4fc97e87..ac8548c5a945 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.component.ts +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/app.component.ts @@ -16,12 +16,6 @@ if (!/localhost/.test(document.location.host)) { enableProdMode(); } -let modulePrefix = ''; -// @ts-ignore -if (window && window.config?.packageConfigPaths) { - modulePrefix = '/app'; -} - config({ floatingActionButtonConfig: { position: { @@ -42,8 +36,8 @@ loadMessages({ @Component({ selector: 'demo-app', - templateUrl: `.${modulePrefix}/app.component.html`, - styleUrls: [`.${modulePrefix}/app.component.css`], + templateUrl: './app.component.html', + styleUrls: ['./app.component.css'], providers: [AiService], imports: [ AiAssistantComponent, diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/ai-assistant/ai-assistant.component.ts b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/ai-assistant/ai-assistant.component.ts index ca7d0455ee97..5a42902172f6 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/ai-assistant/ai-assistant.component.ts +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/ai-assistant/ai-assistant.component.ts @@ -12,12 +12,6 @@ import { CLASSES, chatSuggestions, EMPTY_VIEW_MESSAGE, EMPTY_VIEW_PROMPT, } from '../../data'; -let modulePrefix = ''; -// @ts-ignore -if (window && window.config?.packageConfigPaths) { - modulePrefix = '/app'; -} - @Component({ selector: 'app-ai-assistant', imports: [ @@ -25,8 +19,8 @@ if (window && window.config?.packageConfigPaths) { DxChatModule, DxSpeedDialActionModule, ], - templateUrl: `.${modulePrefix}/components/ai-assistant/ai-assistant.component.html`, - styleUrls: [`.${modulePrefix}/components/ai-assistant/ai-assistant.component.css`], + templateUrl: './ai-assistant.component.html', + styleUrls: ['./ai-assistant.component.css'], }) export class AiAssistantComponent { @Input() disabled = false; diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/employee-form/employee-form.component.ts b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/employee-form/employee-form.component.ts index 90b2747075db..96fa92fcfa60 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/employee-form/employee-form.component.ts +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/employee-form/employee-form.component.ts @@ -6,17 +6,11 @@ import type { AIIntegration } from 'devextreme-angular/common/ai-integration'; import { DxButtonTypes } from 'devextreme-angular/ui/button'; import { employee, formFieldsConfig, type Employee } from '../../data'; -let modulePrefix = ''; -// @ts-ignore -if (window && window.config?.packageConfigPaths) { - modulePrefix = '/app'; -} - @Component({ selector: 'app-employee-form', imports: [CommonModule, DxFormModule, DxToastModule], - templateUrl: `.${modulePrefix}/components/employee-form/employee-form.component.html`, - styleUrls: [`.${modulePrefix}/components/employee-form/employee-form.component.css`], + templateUrl: './employee-form.component.html', + styleUrls: ['./employee-form.component.css'], }) export class EmployeeFormComponent { @Input({ required: true }) aiIntegration!: AIIntegration; diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.ts b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.ts index 74ec9745ba7d..1dfdba3eeee5 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.ts +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.ts @@ -4,17 +4,11 @@ import { colors, tasks, type ColumnFilterExpression, type Task, } from '../../data'; -let modulePrefix = ''; -// @ts-ignore -if (window && window.config?.packageConfigPaths) { - modulePrefix = '/app'; -} - @Component({ selector: 'app-task-grid', imports: [DxDataGridModule], - templateUrl: `.${modulePrefix}/components/task-grid/task-grid.component.html`, - styleUrls: [`.${modulePrefix}/components/task-grid/task-grid.component.css`], + templateUrl: './task-grid.component.html', + styleUrls: ['./task-grid.component.css'], }) export class TaskGridComponent { @ViewChild(DxDataGridComponent) private dxDataGrid!: DxDataGridComponent; From 60d0f5ebe8698e30a9bbfa9cf0820dcab31c1269 Mon Sep 17 00:00:00 2001 From: Diana Gromova <72144169+16adianay@users.noreply.github.com> Date: Wed, 14 Oct 2026 18:53:41 +0400 Subject: [PATCH 07/12] Remove unnecessary dx-chat-messagelist-empty-view --- .../components/ai-assistant/ai-assistant.component.html | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/ai-assistant/ai-assistant.component.html b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/ai-assistant/ai-assistant.component.html index 1ee1572074ad..9486aeb93772 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/ai-assistant/ai-assistant.component.html +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/ai-assistant/ai-assistant.component.html @@ -46,10 +46,7 @@ [onItemClick]="onSuggestionClick" > -
+
@@ -58,7 +55,7 @@ class="ai-chat-empty-prompt" [innerHTML]="emptyViewPromptHtml" >
- + From d6040033d385d0ba22caa5cfaba4834744415849 Mon Sep 17 00:00:00 2001 From: Diana Gromova <72144169+16adianay@users.noreply.github.com> Date: Wed, 14 Oct 2026 18:55:23 +0400 Subject: [PATCH 08/12] Remove the form-container class --- .../app/components/employee-form/employee-form.component.html | 2 +- apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/EmployeeForm.vue | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/employee-form/employee-form.component.html b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/employee-form/employee-form.component.html index 7e0a47e77edc..fc9bf7ff00ef 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/employee-form/employee-form.component.html +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/employee-form/employee-form.component.html @@ -1,4 +1,4 @@ -
+
Date: Wed, 14 Oct 2026 11:29:25 +0000 Subject: [PATCH 09/12] Scheduler: mask the whole recurrence end date in visual tests (#35687) Co-authored-by: Cursor --- ...-form__readonly (fluent.blue.light)_mask.png | Bin 227 -> 141 bytes ...ce-form__weekly (fluent.blue.light)_mask.png | Bin 227 -> 141 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/e2e/testcafe-devextreme/tests/scheduler/common/appointmentForm/etalons/scheduler__appointment__recurrence-form__readonly (fluent.blue.light)_mask.png b/e2e/testcafe-devextreme/tests/scheduler/common/appointmentForm/etalons/scheduler__appointment__recurrence-form__readonly (fluent.blue.light)_mask.png index bf1f8ff5c902630d42fad35d4cc12c20109fc110..cbea79d4b285404e83df9e02023f2c8a390b0bf8 100644 GIT binary patch delta 112 zcmaFN*vmLUC6g_{C&cyt|NjgO455cE*8wRfPZ!6KiaBpj8*(uy2rzH>_22z^q(#8@ w6n`e5EGoFOW}XsH3zzZ2Lq0E@p;9OI^DgxLW0K@Mmk}i5>FVdQ&MBb@00>PY0ssI2 literal 227 zcmeAS@N?(olHy`uVBq!ia0y~yV60(aVA5q|28u8U2fG1D#^NA%C&rs6b?Si}&H|6f zVg?3oVGw3ym^DWND99Gz6XN>+|9>De^w8xxAXVn+;uumf=j|CsE(Qf2X2;L}?Yrey zIQg^Av`wFMRR^eo46wiHO%W#pg8^HfJyzZQd>Rv^^mc7-eFc*CboFyt=akR{0PG_u AjsO4v diff --git a/e2e/testcafe-devextreme/tests/scheduler/common/appointmentForm/etalons/scheduler__appointment__recurrence-form__weekly (fluent.blue.light)_mask.png b/e2e/testcafe-devextreme/tests/scheduler/common/appointmentForm/etalons/scheduler__appointment__recurrence-form__weekly (fluent.blue.light)_mask.png index bf1f8ff5c902630d42fad35d4cc12c20109fc110..cbea79d4b285404e83df9e02023f2c8a390b0bf8 100644 GIT binary patch delta 112 zcmaFN*vmLUC6g_{C&cyt|NjgO455cE*8wRfPZ!6KiaBpj8*(uy2rzH>_22z^q(#8@ w6n`e5EGoFOW}XsH3zzZ2Lq0E@p;9OI^DgxLW0K@Mmk}i5>FVdQ&MBb@00>PY0ssI2 literal 227 zcmeAS@N?(olHy`uVBq!ia0y~yV60(aVA5q|28u8U2fG1D#^NA%C&rs6b?Si}&H|6f zVg?3oVGw3ym^DWND99Gz6XN>+|9>De^w8xxAXVn+;uumf=j|CsE(Qf2X2;L}?Yrey zIQg^Av`wFMRR^eo46wiHO%W#pg8^HfJyzZQd>Rv^^mc7-eFc*CboFyt=akR{0PG_u AjsO4v From 36e3e153eff41f931c0bfbaf993c3a229e9e7103 Mon Sep 17 00:00:00 2001 From: Diana Gromova <72144169+16adianay@users.noreply.github.com> Date: Thu, 15 Oct 2026 14:04:45 +0400 Subject: [PATCH 10/12] Change the priority badge color declaration --- .../task-grid/task-grid.component.css | 14 +++++++++++++- .../task-grid/task-grid.component.html | 2 +- .../task-grid/task-grid.component.ts | 6 +----- .../PageLevelAIAssistant/Angular/app/data.ts | 6 ------ .../PageLevelAIAssistant/Vue/TaskGrid.vue | 19 +++++++++++++++---- .../Chat/PageLevelAIAssistant/Vue/data.ts | 6 ------ .../Chat/PageLevelAIAssistant/jQuery/data.js | 1 - .../Chat/PageLevelAIAssistant/jQuery/index.js | 3 +-- .../PageLevelAIAssistant/jQuery/styles.css | 12 ++++++++++++ 9 files changed, 43 insertions(+), 26 deletions(-) diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.css b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.css index 325bc76a4130..259f9ff313ac 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.css +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.css @@ -3,9 +3,21 @@ min-height: 360px; } -::ng-deep .priority-badge { +.priority-badge { border-radius: 24px; padding: 2px 8px; display: inline-block; text-align: center; } + +.priority-badge--high { + background: #f1bbbc; +} + +.priority-badge--normal { + background: #f9e2ae; +} + +.priority-badge--low { + background: #9fd89f; +} diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.html b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.html index f7f955e42c05..b844ae761ee3 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.html +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.html @@ -36,7 +36,7 @@ >
-
{{ +
{{ data.value }}
diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.ts b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.ts index 1dfdba3eeee5..e4b59a575b8e 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.ts +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.ts @@ -1,8 +1,6 @@ import { Component, ViewChild } from '@angular/core'; import { DxDataGridModule, DxDataGridComponent } from 'devextreme-angular/ui/data-grid'; -import { - colors, tasks, type ColumnFilterExpression, type Task, -} from '../../data'; +import { tasks, type ColumnFilterExpression, type Task } from '../../data'; @Component({ selector: 'app-task-grid', @@ -15,8 +13,6 @@ export class TaskGridComponent { readonly tasks = tasks; - readonly colors = colors; - readonly completionEditorOptions = { elementAttr: { 'aria-label': 'Completed' }, }; diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/data.ts b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/data.ts index c65cafd5e169..d17c02fe6be4 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/data.ts +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/data.ts @@ -145,12 +145,6 @@ export const FORM_ACTION_TYPES = new Set(['clear_field', 'clear_ export const titles = ['Mr.', 'Mrs.', 'Ms.']; -export const colors: Record = { - High: '#F1BBBC', - Normal: '#F9E2AE', - Low: '#9FD89F', -}; - export const states = ['California', 'New York', 'Texas']; export const positions = [ diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/TaskGrid.vue b/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/TaskGrid.vue index 442dc832de54..2fd949af721a 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/TaskGrid.vue +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/TaskGrid.vue @@ -29,8 +29,7 @@ /> import { ref } from 'vue'; import { DxDataGrid, DxColumn, DxFilterRow, DxHeaderFilter } from 'devextreme-vue/data-grid'; -import { colors, tasks } from './data.ts'; -import type { ColumnFilterExpression, Task, TaskPriority } from './data.ts'; +import { tasks } from './data.ts'; +import type { ColumnFilterExpression, Task } from './data.ts'; const dataGridRef = ref>(); @@ -91,4 +90,16 @@ defineExpose({ display: inline-block; text-align: center; } + +.priority-badge--high { + background: #f1bbbc; +} + +.priority-badge--normal { + background: #f9e2ae; +} + +.priority-badge--low { + background: #9fd89f; +} diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/data.ts b/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/data.ts index c55184c8bf97..938220d1a66a 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/data.ts +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/data.ts @@ -154,12 +154,6 @@ export const FORM_ACTION_TYPES = new Set(['clear_field', 'clear_ export const titles = ['Mr.', 'Mrs.', 'Ms.']; -export const colors: Record = { - High: '#F1BBBC', - Normal: '#F9E2AE', - Low: '#9FD89F', -}; - export const states = ['California', 'New York', 'Texas']; export const positions = [ diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/data.js b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/data.js index 9ab8d249738a..abec2e9f6c00 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/data.js +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/data.js @@ -19,7 +19,6 @@ const ROUTER_TARGETS = new Set(['form', 'grid', 'mixed', 'none']); const FORM_ACTION_TYPES = new Set(['clear_field', 'clear_all', 'smart_paste']); const titles = ['Mr.', 'Mrs.', 'Ms.']; -const colors = { High: '#F1BBBC', Normal: '#F9E2AE', Low: '#9FD89F' }; const states = ['California', 'New York', 'Texas']; const positions = [ 'CEO', diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js index c202e2cd9942..00856ca404a2 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/index.js @@ -309,8 +309,7 @@ $(() => { caption: 'Priority', cellTemplate: (container, options) => { $('
') - .addClass('priority-badge') - .css('background', colors[options.value]) + .addClass(`priority-badge priority-badge--${options.value.toLowerCase()}`) .text(options.value) .appendTo(container); }, diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/styles.css b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/styles.css index 115676262ddf..e378dcab0858 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/styles.css +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/styles.css @@ -16,6 +16,18 @@ text-align: center; } +.priority-badge--high { + background: #f1bbbc; +} + +.priority-badge--normal { + background: #f9e2ae; +} + +.priority-badge--low { + background: #9fd89f; +} + #form-container { border: 1px solid var(--dx-color-border); padding: 16px; From 863b80d285e9c70163cb84ae2cf3f8a877ed73dc Mon Sep 17 00:00:00 2001 From: Diana Gromova <72144169+16adianay@users.noreply.github.com> Date: Thu, 15 Oct 2026 14:09:29 +0400 Subject: [PATCH 11/12] Change emptyViewMessage --- apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/data.ts | 2 +- apps/demos/Demos/Chat/PageLevelAIAssistant/React/data.ts | 2 +- apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/data.js | 2 +- apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/data.ts | 2 +- apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/data.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/data.ts b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/data.ts index d17c02fe6be4..c496733a738f 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/data.ts +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/data.ts @@ -131,7 +131,7 @@ export const AI_SERVICE_CONFIG = { apiKey: 'DEMO', }; -export const EMPTY_VIEW_MESSAGE = 'How can I help with this page?'; +export const EMPTY_VIEW_MESSAGE = 'AI Assistant is ready to help you'; export const EMPTY_VIEW_PROMPT = 'Update employee Form fields.\nFilter or sort tasks, display or hide DataGrid columns, or clear all filters and sorting.'; diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/React/data.ts b/apps/demos/Demos/Chat/PageLevelAIAssistant/React/data.ts index e85b58deaee1..e995027efb44 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/React/data.ts +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/React/data.ts @@ -141,7 +141,7 @@ export class ChatCommandError extends Error { } } -export const emptyViewMessage = 'How can I help with this page?'; +export const emptyViewMessage = 'AI Assistant is ready to help you'; export const employee: Employee = { ID: 1, diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/data.js b/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/data.js index 8999ab914240..5bbbc574af78 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/data.js +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/ReactJs/data.js @@ -17,7 +17,7 @@ export class ChatCommandError extends Error { Object.setPrototypeOf(this, ChatCommandError.prototype); } } -export const emptyViewMessage = 'How can I help with this page?'; +export const emptyViewMessage = 'AI Assistant is ready to help you'; export const employee = { ID: 1, Prefix: 'Mr.', diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/data.ts b/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/data.ts index 938220d1a66a..38e4165ce9e6 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/data.ts +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Vue/data.ts @@ -140,7 +140,7 @@ export const AI_SERVICE_CONFIG = { export const MAX_PROMPT_SIZE = 20000; export const RATE_LIMIT_RETRY_DELAY_MS = 30000; -export const EMPTY_VIEW_MESSAGE = 'How can I help with this page?'; +export const EMPTY_VIEW_MESSAGE = 'AI Assistant is ready to help you'; export const EMPTY_VIEW_PROMPT = 'Update employee Form fields.\nFilter or sort tasks, display or hide DataGrid columns, or clear all filters and sorting.'; diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/data.js b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/data.js index abec2e9f6c00..24345c3a2474 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/data.js +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/jQuery/data.js @@ -7,7 +7,7 @@ const apiVersion = '2024-02-01'; const endpoint = 'https://public-api.devexpress.com/demo-openai'; const apiKey = 'DEMO'; -const emptyViewMessage = 'How can I help with this page?'; +const emptyViewMessage = 'AI Assistant is ready to help you'; const emptyViewPrompt = 'Update employee Form fields.\nFilter or sort tasks, display or hide DataGrid columns, or clear all filters and sorting.'; From e603a7710870fc4ee6850a9f9d3605edb35cd965 Mon Sep 17 00:00:00 2001 From: Diana Gromova <72144169+16adianay@users.noreply.github.com> Date: Thu, 15 Oct 2026 15:05:22 +0400 Subject: [PATCH 12/12] Fix prettier --- .../app/components/task-grid/task-grid.component.html | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.html b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.html index b844ae761ee3..6d0793a3448d 100644 --- a/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.html +++ b/apps/demos/Demos/Chat/PageLevelAIAssistant/Angular/app/components/task-grid/task-grid.component.html @@ -36,8 +36,9 @@ >
-
{{ - data.value - }}
+
{{ data.value }}