Skip to content

Commit f442fef

Browse files
committed
add readme
1 parent 796d771 commit f442fef

File tree

4 files changed

+273
-13
lines changed

4 files changed

+273
-13
lines changed

README.md

Lines changed: 273 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,291 @@
33
[![](https://img.shields.io/badge/📖_How_to_use_DevExpress_Examples-e9f6fc?style=flat-square)](https://docs.devexpress.com/GeneralInformation/403183)
44
[![](https://img.shields.io/badge/💬_Leave_Feedback-feecdd?style=flat-square)](#does-this-example-address-your-development-requirementsobjectives)
55
<!-- default badges end -->
6-
# Product/Platform - Task
6+
# Report Viewer and Data Grid for Blazor — Integrate an AI Assistant based on Azure OpenAI
77

8-
This is the repository template for creating new examples. Describe the solved task here.
8+
This example integrates an AI assistant into DevExpress Blazor Components. User requests and assistant responses are displayed on-screen using the [DevExpress Blazor AI Chat](http://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.DxAIChat?v=24.2) component.
99

10-
Put a screenshot that illustrates the result here.
10+
With an AI Assistant integrated in our AI-chat component, you can filter and manipulate data, generate document summaries, and ask context-aware questions about report content, table data, and more — all within the user interface.
1111

12-
Then, add implementation details (steps, code snippets, and other technical information in a free form), or add a link to an existing document with implementation details.
12+
This example demonstrates the following DevExpress Blazor Components:
13+
14+
- [Blazor Data Grid](https://www.devexpress.com/blazor/data-grid/)
15+
16+
The Grid is bound to a project management data that tracks tasks or issues across various projects. It includes details like task subject, owner and assignee, status, priority, and key dates (created, modified, fixed). You can ask the AI Assistant questions about task data:
17+
- What tasks should the team focus on first?
18+
- How many tasks are currently marked as New?
19+
- What tasks are of the highest priority for Mike Roller?
20+
21+
- [Blazor Report Viewer](https://www.devexpress.com/subscriptions/reporting/)
22+
23+
The Report Viewer presents multiple reports bound to different data sources. The available reports include:
24+
25+
- The *Drill-Down Report* displays invoices where the expandable/collapsible sections list purchased products. You can ask the AI Assistant: Which invoice has the highest total order value? How many orders are currently in transit, pending, or delivered? What is the average order value per invoice?
26+
- The *Market Share Report* includes sales figures, changes from the prior year, and current market share percentages for various regions and countries across different time periods. ou can ask the AI Assistant: Which region had the highest market share in September? How did market share change for India? How does Canada’s market share growth compare to the USA’s?
27+
- The *Restaurant Menu* includes multiple groups, each group represents a different category and sub-category of meals and beverages. ou can ask the AI Assistant: What are the price ranges for the menu items? Are there any vegetarian or non-meat options on this menu?
28+
29+
To navigate to page with the component, click in the corresponding card on the root page:
30+
31+
![Cards](images/index-page.png)
32+
33+
>[!TIP]
34+
> Please note that AI Assistant initialization takes time. The assistant tab appears once Microsoft Azure scans the source document (i.e., grid or report data) on the server side.
35+
36+
## Implementation Details
37+
38+
### Register AI Services
39+
40+
> [!NOTE]
41+
> DevExpress AI-powered extensions follow the "bring your own key" principle. DevExpress does not offer a REST API and does not ship any built-in LLMs/SLMs. You need an active Azure/Open AI subscription to obtain the REST API endpoint, key, and model deployment name. These variables must be specified at application startup to register AI clients and enable DevExpress AI-powered Extensions in your application.
42+
43+
Create an Azure OpenAI resource in the Azure portal to use AI Assistants. Refer to the following help topic for details: [Microsoft - Create and deploy an Azure OpenAI Service resource](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource?pivots=web-portal).
44+
45+
Once you obtain a private endpoint and an API key, register them as `AZURE_OPENAI_ENDPOINT` and `AZURE_OPENAI_APIKEY` environment variables in your application.
46+
47+
Add the following code to the *Program.cs* file to register the AI Services and an [OpenAI Assistant](https://platform.openai.com/docs/assistants/overview) in your application:
48+
49+
```cs
50+
using Azure.AI.OpenAI;
51+
using DevExpress.AIIntegration;
52+
using Microsoft.Extensions.AI;
53+
using System.ClientModel;
54+
//...
55+
string azureOpenAIEndpoint = "AZURE_OPENAI_ENDPOINT";
56+
string azureOpenAIKey = "AZURE_OPENAI_API_KEY";
57+
string deploymentName = "YOUR_MODEL_NAME";
58+
//...
59+
var azureClient = new AzureOpenAIClient(
60+
new Uri(azureOpenAIEndpoint),
61+
new ApiKeyCredential(azureOpenAIKey));
62+
builder.Services.AddChatClient(config =>
63+
config.Use(azureClient.AsChatClient(deploymentName))
64+
);
65+
builder.Services.AddDevExpressAI((config) => {
66+
config.RegisterOpenAIAssistants(azureClient, deploymentName);
67+
});
68+
```
69+
70+
For more information on AI Assistants, refer to the following topic: [AI Service Assistants in the DxAIChat component](https://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.DxAIChat#ai-service-assistants).
71+
72+
**Files to Review:**
73+
74+
- [Program.cs](./DevExpress.AI.Samples.Blazor/Program.cs)
75+
76+
### Add an AI Assistant to Grid
77+
78+
The following image displays page with `DxGrid` and `DxAIChat` components implemented in this example:
79+
80+
![Blazor Grid and Integrated AI Assistant](images/data-grid.png)
81+
82+
For the `DxGrid` configuration (data binding and customizations), review the [Grid.razor](./DevExpress.AI.Samples.Blazor/Components/Pages/Grid.razor) file.
83+
84+
#### Add AI Chat to the Grid Page
85+
86+
The following code snippet adds the [`DxAIChat`](https://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.DxAIChat) to the page:
87+
88+
```razor
89+
@using DevExpress.AIIntegration.Blazor.Chat
90+
@using Markdig
91+
92+
<DxGrid @ref="grid" Data="@DataSource" CssClass="my-grid" ShowGroupPanel="true" TextWrapEnabled="false">
93+
@* ... *@
94+
</DxGrid>
95+
<DxAIChat @ref="chat" CssClass="my-grid-chat">
96+
<MessageContentTemplate>
97+
<div class="my-chat-content">
98+
@ToHtml(context.Content)
99+
</div>
100+
</MessageContentTemplate>
101+
</DxAIChat>
102+
103+
@code {
104+
MarkupString ToHtml(string text) {
105+
return (MarkupString)Markdown.ToHtml(text);
106+
}
107+
}
108+
```
109+
110+
Use the [`MessageContentTemplate`](https://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.DxAIChat.MessageContentTemplate) property to display any render fragment in a message bubble. For more information on appearance customization, refer to the following help document: [Customizable Message Appearance and Empty Message Area](https://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.DxAIChat#customizable-message-appearance-and-empty-message-area). To display rich formatted messages, use a markdown processor to convert the response content to HTML code.
111+
112+
**Files to Review:**
113+
114+
- [Grid.razor](./DevExpress.AI.Samples.Blazor/Components/Pages/Grid.razor)
115+
116+
#### Set Up the AI Assistant
117+
118+
Handle the `OnAfterRenderAsync` event and call the [`SetupAssistantAsync`](https://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.IAIChat.SetupAssistantAsync(DevExpress.AIIntegration.Services.Assistant.AIAssistantOptions)) method to create an AI assistant and provide it with data and instructions. In this example, grid data is exported to XLSX using the [`ExportToXlsxAsync`](https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxGrid.ExportToXlsxAsync.overloads) method and is passed to the assistant along with the instructions:
119+
120+
```razor
121+
@using DevExpress.AIIntegration.OpenAI.Services
122+
123+
@* ... *@
124+
@code {
125+
protected override async Task OnAfterRenderAsync(bool firstRender) {
126+
if(firstRender) {
127+
using(MemoryStream ms = new MemoryStream()) {
128+
grid.BeginUpdate();
129+
grid.ShowGroupedColumns = true;
130+
await grid.ExportToXlsxAsync(ms, new GridXlExportOptions() {
131+
ExportDisplayText = true
132+
});
133+
await chat.SetupAssistantAsync(new OpenAIAssistantOptions("grid_data.xlsx", ms) {
134+
Instructions = AssistantHelper.GetAIAssistantInstructions("xlsx"),
135+
UseFileSearchTool = false
136+
});
137+
grid.ShowGroupedColumns = false;
138+
grid.EndUpdate();
139+
}
140+
}
141+
await base.OnAfterRenderAsync(firstRender);
142+
}
143+
}
144+
```
145+
146+
You can review and tailor assistant instructions according to your needs in the following file: [Instructions.cs](./DevExpress.AI.Samples.Blazor/Instructions.cs).
147+
148+
For information on OpenAI Assistants, refer to the following article: [Assistants API overview](https://platform.openai.com/docs/assistants/overview).
149+
150+
**Files to Review:**
151+
152+
- [Grid.razor](./DevExpress.AI.Samples.Blazor/Components/Pages/Grid.razor)
153+
- [Instructions.cs](./DevExpress.AI.Samples.Blazor/Instructions.cs)
154+
155+
### Add an AI Assistant to Report Viewer
156+
157+
The following image displays Blazor Report Viewer UI implemented in this example. The AI Assistant tab uses the `DxAIChat` component to display requests and responses:
158+
159+
![Blazor Report Viewer and Integrated AI Assistant](images/report-viewer.png)
160+
161+
Use the [DxListBox](https://docs.devexpress.com/Blazor/DevExpress.Blazor.DxListBox-2) component to select a report and explore how different data is handled.
162+
163+
#### Add a New Tab
164+
165+
Use the [`OnCustomizeTabs`](https://docs.devexpress.com/XtraReports/DevExpress.Blazor.DxViewer.OnCustomizeTabs) event to add a new tab:
166+
167+
```razor
168+
@using DevExpress.AI.Samples.Blazor.Components.Reporting
169+
@using DevExpress.AI.Samples.Blazor.Models
170+
@using DevExpress.Blazor.Reporting.Models
171+
172+
@* ... *@
173+
<DxReportViewer @ref="Viewer" CssClass="my-report" OnCustomizeTabs="OnCustomizeTabs">
174+
</DxReportViewer>
175+
@* ... *@
176+
177+
@code {
178+
// ...
179+
void OnCustomizeTabs(List<TabModel> tabs) {
180+
tabs.Add(new TabModel(new UserAssistantTabContentModel(() => CurrentReport), "AI", "AI Assistant") {
181+
TabTemplate = (tabModel) => {
182+
return (builder) => {
183+
builder.OpenComponent<AITabRenderer>(0);
184+
builder.AddComponentParameter(1, "Model", tabModel.ContentModel);
185+
builder.CloseComponent();
186+
};
187+
}
188+
});
189+
}
190+
}
191+
```
192+
193+
A new [`TabModel`](https://docs.devexpress.com/XtraReports/DevExpress.Blazor.Reporting.Models.TabModel._members) object is added to the list of tabs. The `UserAssistantTabContentModel` class implements the [`ITabContentModel`](https://docs.devexpress.com/XtraReports/DevExpress.Blazor.Reporting.Models.ITabContentModel) interface which defines the logic used to determine when the AI Assistant tab is displayed. The AI Assistant tab is only displayed when the report is initialized and contains at least one page.
194+
195+
The `TabTemplate` property specifies the content of the tab. It dynamically renders an `DxAIChat` component inside the tab and passes the `ContentModel` as a parameter to control the tab's content.
196+
197+
The content fot the AI Assistant tab is defined in the [AITabRenderer.razor](./DevExpress.AI.Samples.Blazor/Components/Reporting/AITabRenderer.razor) file:
198+
199+
```razor
200+
@using DevExpress.AI.Samples.Blazor.Models
201+
@using DevExpress.AIIntegration.Blazor.Chat
202+
@using System.Text.RegularExpressions
203+
@using Markdig
204+
205+
<DxAIChat CssClass="my-report-chat">
206+
<MessageContentTemplate>
207+
<div class="my-chat-content">
208+
@ToHtml(context.Content)
209+
</div>
210+
</MessageContentTemplate>
211+
</DxAIChat>
212+
213+
@code {
214+
[Parameter] public UserAssistantTabContentModel Model { get; set; }
215+
string ClearAnnotations(string text) {
216+
//To clear out the annotations in a response from assistant.
217+
return Regex.Replace(text, @"\【.*?】", "");
218+
}
219+
220+
MarkupString ToHtml(string text) {
221+
text = ClearAnnotations(text);
222+
return (MarkupString)Markdown.ToHtml(text);
223+
}
224+
}
225+
```
226+
227+
Use the [`MessageContentTemplate`](https://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.DxAIChat.MessageContentTemplate) property to display any render fragment in a message bubble. For more information on appearance customization, refer to the following help document: [Customizable Message Appearance and Empty Message Area](https://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.DxAIChat#customizable-message-appearance-and-empty-message-area). To display rich formatted messages, use a markdown processor to convert the response content to HTML code.
228+
229+
**Files to Review:**
230+
231+
- [ReportViewer.razor](./DevExpress.AI.Samples.Blazor/Components/Pages/ReportViewer.razor)
232+
- [AITabRenderer.razor](./DevExpress.AI.Samples.Blazor/Components/Reporting/AITabRenderer.razor)
233+
- [UserAssistantTabContentModel.cs](./DevExpress.AI.Samples.Blazor/Models/UserAssistantTabContentModel.cs)
234+
235+
#### Set Up the AI Assistant
236+
237+
Handle the [`Initialized`](https://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.DxAIChat.Initialized) event and call the [`SetupAssistantAsync`](https://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.IAIChat.SetupAssistantAsync(DevExpress.AIIntegration.Services.Assistant.AIAssistantOptions)) method to create an AI assistant and provide it with data and instructions. In this example, report data is exported to PDF using the [`ExportToPdf`](https://docs.devexpress.com/CoreLibraries/DevExpress.XtraPrinting.PrintingSystemBase.ExportToPdf(System.IO.Stream)) method and is passed to the assistant along with the instructions:
238+
239+
```razor
240+
@using DevExpress.AIIntegration.Blazor.Chat
241+
@using DevExpress.AIIntegration.OpenAI.Services
242+
243+
<DxAIChat CssClass="my-report-chat" Initialized="ChatInitialized">
244+
@* ... *@
245+
</DxAIChat>
246+
247+
@code {
248+
// ...
249+
async Task ChatInitialized(IAIChat aIChat) {
250+
using (MemoryStream ms = Model.GetReportData()) {
251+
await aIChat.SetupAssistantAsync(new OpenAIAssistantOptions("report.pdf", ms) {
252+
Instructions = AssistantHelper.GetAIAssistantInstructions("pdf")
253+
});
254+
}
255+
}
256+
}
257+
```
258+
259+
You can review and tailor instructions to your needs in the following file: [Instructions.cs](./DevExpress.AI.Samples.Blazor/Instructions.cs).
260+
261+
For information on OpenAI Assistants, refer to the following article: [Assistants API overview](https://platform.openai.com/docs/assistants/overview).
262+
263+
**Files to Review:**
264+
265+
- [ReportViewer.razor](./DevExpress.AI.Samples.Blazor/Components/Pages/ReportViewer.razor)
266+
- [AITabRenderer.razor](./DevExpress.AI.Samples.Blazor/Components/Reporting/AITabRenderer.razor)
267+
- [UserAssistantTabContentModel.cs](./DevExpress.AI.Samples.Blazor/Models/UserAssistantTabContentModel.cs)
268+
- [Instructions.cs](./DevExpress.AI.Samples.Blazor/Instructions.cs)
13269

14270
## Files to Review
15271

16-
- link.cs (VB: link.vb)
17-
- link.js
18-
- ...
272+
- [Program.cs](./DevExpress.AI.Samples.Blazor/Program.cs)
273+
- [ReportViewer.razor](./DevExpress.AI.Samples.Blazor/Components/Pages/ReportViewer.razor)
274+
- [Grid.razor](./DevExpress.AI.Samples.Blazor/Components/Pages/Grid.razor)
275+
- [AITabRenderer.razor](./DevExpress.AI.Samples.Blazor/Components/Reporting/AITabRenderer.razor)
276+
- [UserAssistantTabContentModel.cs](./DevExpress.AI.Samples.Blazor/Models/UserAssistantTabContentModel.cs)
277+
- [Instructions.cs](./DevExpress.AI.Samples.Blazor/Instructions.cs)
19278

20279
## Documentation
21280

22-
- link
23-
- link
24-
- ...
281+
- [Blazor AI Chat](https://docs.devexpress.com/Blazor/DevExpress.AIIntegration.Blazor.Chat.DxAIChat)
282+
- [Blazor Grid](https://docs.devexpress.com/Blazor/403143/components/grid)
283+
- [Blazor Report Viewer](https://docs.devexpress.com/XtraReports/403594/web-reporting/blazor-reporting/server/blazor-report-viewer-native)
284+
- [AI-powered Extensions for DevExpress Reporting](https://docs.devexpress.com/XtraReports/405211/ai-powered-functionality/ai-for-devexpress-reporting)
25285

26286
## More Examples
27287

28-
- link
29-
- link
30-
- ...
288+
- [Reporting for Blazor - Integrate AI-powered Summarize and Translate Features based on Azure OpenAI](https://github.com/DevExpress-Examples/blazor-reporting-ai/)
289+
- [AI Chat for Blazor - How to add DxAIChat component in Blazor, MAUI, WPF, and WinForms applications](https://github.com/DevExpress-Examples/devexpress-ai-chat-samples)
290+
- [Rich Text Editor and HTML Editor for Blazor - How to integrate AI-powered extensions](https://github.com/DevExpress-Examples/blazor-ai-integration-to-text-editors)
31291
<!-- feedback -->
32292
## Does this example address your development requirements/objectives?
33293

images/data-grid.png

147 KB
Loading

images/index-page.png

47.5 KB
Loading

images/report-viewer.png

92.4 KB
Loading

0 commit comments

Comments
 (0)