From 2b5a1e6bd00beed226dc356473ee19f7e9ee77e3 Mon Sep 17 00:00:00 2001 From: Kokila Poovendran Date: Wed, 12 Nov 2025 18:30:10 +0530 Subject: [PATCH 1/6] 990970: AI-Samples documentation --- .../ai-samples/kanban/sentiment-analysis.md | 4 ---- .../kanban/smart-task-suggestion.md | 4 ---- .../rich-text-editor/writting-assistance.md | 24 ++++++++++++++----- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/blazor/smart-ai-solutions/ai-samples/kanban/sentiment-analysis.md b/blazor/smart-ai-solutions/ai-samples/kanban/sentiment-analysis.md index d66c1982d1..ecb6b144a5 100644 --- a/blazor/smart-ai-solutions/ai-samples/kanban/sentiment-analysis.md +++ b/blazor/smart-ai-solutions/ai-samples/kanban/sentiment-analysis.md @@ -520,10 +520,6 @@ If the AI service fails to return a valid response, the Kanban will display an e - **Network Issues**: Check connectivity to the AI service endpoint, especially for self-hosted Ollama instances. - **Large Prompts**: Processing large text inputs may cause timeouts. Consider reducing the prompt size or optimizing the request for efficiency. -## Performance Considerations - -When handling large text content, ensure the Ollama server has sufficient resources (CPU/GPU) to process requests efficiently. For long-form content or batch operations, consider splitting the input into smaller segments to avoid performance bottlenecks. Test the application with your specific use case to determine optimal performance. - ## Sample Code A complete working example is available in the [Syncfusion Blazor AI Samples GitHub repository](https://github.com/syncfusion/smart-ai-samples). diff --git a/blazor/smart-ai-solutions/ai-samples/kanban/smart-task-suggestion.md b/blazor/smart-ai-solutions/ai-samples/kanban/smart-task-suggestion.md index a8034ddae5..3962904116 100644 --- a/blazor/smart-ai-solutions/ai-samples/kanban/smart-task-suggestion.md +++ b/blazor/smart-ai-solutions/ai-samples/kanban/smart-task-suggestion.md @@ -573,10 +573,6 @@ If the AI service fails to return a valid response, the Kanban will display an e - **Network Issues**: Check connectivity to the AI service endpoint, especially for self-hosted Ollama instances. - **Large Prompts**: Processing large text inputs may cause timeouts. Consider reducing the prompt size or optimizing the request for efficiency. -## Performance Considerations - -When handling large text content, ensure the Ollama server has sufficient resources (CPU/GPU) to process requests efficiently. For long-form content or batch operations, consider splitting the input into smaller segments to avoid performance bottlenecks. Test the application with your specific use case to determine optimal performance. - ## Sample Code A complete working example is available in the [Syncfusion Blazor AI Samples GitHub repository](https://github.com/syncfusion/smart-ai-samples). diff --git a/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md b/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md index 3074d17360..29b921985d 100644 --- a/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md +++ b/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md @@ -228,9 +228,17 @@ await builder.Build().RunAsync(); {% endhighlight %} {% endtabs %} -## Razor Component +## AI-powered Rich Text Editor in Blazor -This section implements the Syncfusion Blazor Rich Text Editor with AI-powered content assistance features such as rephrase, correct grammar, summarize, elaborate, and translate. +The Syncfusion Blazor Rich Text Editor can integrate AI features to help users create better content. It supports grammar correction, rephrasing for clarity, summarizing long text, elaborating short text, and translating content into different languages. These features work by sending selected text to an AI service and updating the editor with improved content. + +### How AI Works in Rich Text Editor + +When a user selects text and chooses an AI option, the editor captures the text and opens a dialog. The dialog shows the original text and a placeholder for AI-generated content. The selected text and chosen action are sent to the AI service, which processes the request and returns the result. Users can then regenerate, copy, or replace the content in the editor. + +### UI Implementation in Razor (`Home.razor`) + +The Razor file sets up the Rich Text Editor with custom toolbar items for AI actions. It includes an AI Assistant dropdown for options like Rephrase, Summarize, and Translate, and a dialog to display AI suggestions. Additional UI elements like chips for tone and dropdowns for language selection make the experience interactive. (`Home.razor`) @@ -388,6 +396,10 @@ This section implements the Syncfusion Blazor Rich Text Editor with AI-powered c ``` +### Backend Logic in C# (`Home.razor.cs`) + +The C# file manages dialog visibility, button states, and AI calls. When an option is selected, `DialogueOpen()` captures the selected text and opens the dialog. `UpdateAISuggestionsData()` sends the query to the AI service and updates the UI with the result. Users can regenerate or replace content easily. + `Home.razor.cs` ```csharp @@ -687,6 +699,10 @@ namespace AISamples.Components.Pages ``` +## Workflow Summary + +Select text → Choose AI action → Dialog opens → AI processes → Updated content displayed → User copies or replaces content. + ## Error Handling and Troubleshooting If the AI service fails to return a valid response, the Rich Text Editor will display an error message ("Oops! Please try again!"). Common issues include: @@ -696,10 +712,6 @@ If the AI service fails to return a valid response, the Rich Text Editor will di - **Network Issues**: Check connectivity to the AI service endpoint, especially for self-hosted Ollama instances. - **Large Prompts**: Processing large text inputs may cause timeouts. Consider reducing the prompt size or optimizing the request for efficiency. -## Performance Considerations - -When handling large text content, ensure the Ollama server has sufficient resources (CPU/GPU) to process requests efficiently. For long-form content or batch operations, consider splitting the input into smaller segments to avoid performance bottlenecks. Test the application with your specific use case to determine optimal performance. - ## Sample Code A complete working example is available in the [Syncfusion Blazor AI Samples GitHub repository](https://github.com/syncfusion/smart-ai-samples). From 33c791b6ceb85f71e70d158eadc9742a7f8e560f Mon Sep 17 00:00:00 2001 From: Kokila Poovendran Date: Thu, 13 Nov 2025 11:01:34 +0530 Subject: [PATCH 2/6] 990970: AI-Samples documentation --- .../ai-samples/kanban/sentiment-analysis.md | 16 ++++++++++++-- .../kanban/smart-task-suggestion.md | 22 +++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/blazor/smart-ai-solutions/ai-samples/kanban/sentiment-analysis.md b/blazor/smart-ai-solutions/ai-samples/kanban/sentiment-analysis.md index ecb6b144a5..e35814a715 100644 --- a/blazor/smart-ai-solutions/ai-samples/kanban/sentiment-analysis.md +++ b/blazor/smart-ai-solutions/ai-samples/kanban/sentiment-analysis.md @@ -228,9 +228,21 @@ await builder.Build().RunAsync(); {% endhighlight %} {% endtabs %} -## Razor Component +## AI-powered Sentiment Analysis in Kanban -This section demonstrates how to implement sentiment analysis in the Syncfusion Blazor Kanban component using AI. The AI Assistant evaluates the emotional tone of each task description and displays a corresponding emoji (😊, 😐, 😞) to help teams quickly assess the mood or urgency of tasks. This can be especially useful in agile workflows where emotional context can influence task priority and team communication. +The AI-powered sentiment analysis feature in Syncfusion Blazor Kanban evaluates customer feedback for delivered tasks and displays emojis (😊, 😐, 😞) to indicate positive, neutral, or negative sentiment. This helps teams quickly assess satisfaction levels and prioritize follow-up actions, improving customer experience in service workflows. + +### UI Structure and User Interaction (`Home.razor`) + +The Razor page includes a Kanban board for managing pizza orders across columns like Menu, Order, Ready to Serve, and Delivered. A progress button triggers sentiment analysis, while custom card templates display task details such as title, description, and delivery date. After analysis, an emoji appears on delivered tasks to represent sentiment. A dialog template supports editing fields like category, size, and feedback, with conditional rendering based on task type. + +### AI Sentiment Analysis Logic (`Home.razor.cs`) + +The `GetScore` method serializes Kanban data to JSON and sends it to the AI service with a prompt requesting a `SentimentScore` (1–5) based on feedback. The AI response is cleaned and deserialized into the data model, updating each task’s score and assigning emojis: 😢 for 1–2, 😐 for 3, and 😀 for 4–5. State flags like `ShowScore` control rendering, while progress events (`Begin`, `End`) update button text during processing. + +### Data Binding and Error Handling + +The `SfKanban` binds to the `Pizza` list using `Category` as the `KeyField`, with dynamic columns from `columnData`. Card templates conditionally render sentiment emojis for delivered tasks. If AI analysis fails, the spinner state prevents premature interactions, and `StateHasChanged()` refreshes the UI after completion. (`Home.razor`) diff --git a/blazor/smart-ai-solutions/ai-samples/kanban/smart-task-suggestion.md b/blazor/smart-ai-solutions/ai-samples/kanban/smart-task-suggestion.md index 3962904116..baedc607b9 100644 --- a/blazor/smart-ai-solutions/ai-samples/kanban/smart-task-suggestion.md +++ b/blazor/smart-ai-solutions/ai-samples/kanban/smart-task-suggestion.md @@ -228,9 +228,27 @@ await builder.Build().RunAsync(); {% endhighlight %} {% endtabs %} -## Razor Component +## AI-powered Kanban Smart Card Generation -This section demonstrates how to implement the Syncfusion Blazor Kanban component with AI-powered task generation. The AI Assistant analyzes the provided project description and automatically suggests relevant tasks, which are then displayed in the Kanban board. +The AI-powered Kanban feature integrates Syncfusion Blazor Kanban with an AI service to automatically create structured task cards from user input. It combines a simple UI for project details with backend logic that generates tasks and updates the Kanban board dynamically. + +### UI Structure and User Interaction (`Home.razor`) + +The Razor page includes an input form for project details and a Kanban board for visualizing tasks. Users enter a project description and task count, then click Generate Tasks to start AI processing. A modal dialog ensures clean input for new projects, while conditional rendering switches between input and Kanban views. Cards display essential details like title, description, and story points with drag-and-drop support. + +### AI Task Generation Logic (`Home.razor.cs`) + +The `GenerateProjectTasks` method builds a prompt for the AI service, requesting tasks in strict JSON format with fields like Id, Title, Status, and Due Date. The response is cleaned and deserialized into `SmartSuggestionDataModel` objects, which are added to the Kanban data source. Progress button events provide feedback during generation, and default values like `Status="Open"` and `Color="#000000"` are applied to new tasks. + +### Data Binding and Kanban Configuration + +The `SfKanban` component binds to the `smartSuggestion` list, using `Status` as the `KeyField` to organize cards into columns (To Do, In Progress, Review, Done). +Card templates are customized via `KanbanCardSettings` to show essential task details with visual clarity. +A fallback `SfGrid` view allows tabular task management with inline editing, while a toggle button switches between Grid and Kanban layouts. + +### Error Handling and User Feedback + +If AI generation fails, a toast notification displays an error message without disrupting the workflow. Input validation ensures both project details and task count are provided before submission. State flags manage UI transitions and prevent issues during asynchronous operations. (`Home.razor`) From 16956b7acc766a9106f15d777279cb10b63cd9f1 Mon Sep 17 00:00:00 2001 From: Kokila Poovendran Date: Fri, 14 Nov 2025 13:27:01 +0530 Subject: [PATCH 3/6] 990970: AI-Samples documentation --- .../rich-text-editor/writting-assistance.md | 722 ++++++++---------- 1 file changed, 326 insertions(+), 396 deletions(-) diff --git a/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md b/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md index 29b921985d..47ac25706c 100644 --- a/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md +++ b/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md @@ -230,442 +230,374 @@ await builder.Build().RunAsync(); ## AI-powered Rich Text Editor in Blazor -The Syncfusion Blazor Rich Text Editor can integrate AI features to help users create better content. It supports grammar correction, rephrasing for clarity, summarizing long text, elaborating short text, and translating content into different languages. These features work by sending selected text to an AI service and updating the editor with improved content. +This guide explains how to integrate a full-featured AI writing assistant into the Blazor Rich Text Editor using Azure OpenAI (via Semantic Kernel). The implementation supports **Rephrase**, **Correct Grammar**, **Summarize**, **Elaborate**, and **Translate** with live preview, dynamic tone/language controls, skeleton loading, and safe, undoable content replacement. -### How AI Works in Rich Text Editor +## How the Custom Toolbar is Rendered -When a user selects text and chooses an AI option, the editor captures the text and opens a dialog. The dialog shows the original text and a placeholder for AI-generated content. The selected text and chosen action are sent to the AI service, which processes the request and returns the result. Users can then regenerate, copy, or replace the content in the editor. +The toolbar uses [RichTextEditorCustomToolbarItems](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.RichTextEditor.RichTextEditorCustomToolbarItems.html) to inject a custom item named AI. -### UI Implementation in Razor (`Home.razor`) +Inside the template, an `SfDropDownButton` is rendered with: -The Razor file sets up the Rich Text Editor with custom toolbar items for AI actions. It includes an AI Assistant dropdown for options like Rephrase, Summarize, and Translate, and a dialog to display AI suggestions. Additional UI elements like chips for tone and dropdowns for language selection make the experience interactive. +- **Icon**: AI icon (e-icons e-ai-chat) +- **Dropdown Items**: Rephrase, Grammar, Summarize, Elaborate, Translate +- **Event Binding**: ItemSelected="AIQuerySelectedMenu" triggers the AI workflow when an option is selected. -(`Home.razor`) +An additional `SfButton` for **Rephrase** is provided for quick access. -```csharp -@inject AzureAIService semanticKernelAI -@inject IJSRuntime JSRuntime -@using AISamples.Components.Service -@using Syncfusion.Blazor.RichTextEditor -@using Syncfusion.Blazor.SplitButtons -@using Syncfusion.Blazor.Buttons -@using Syncfusion.Blazor.Popups -@using Syncfusion.Blazor.Notifications -@using Syncfusion.Blazor.DropDowns - -
- - - - - - - - - - - - - -
-
- - -
AI Assistant
- -
-
-
- - +{% tabs %} +{% highlight razor %} + + + + + + + + + + + + +{% endhighlight %} +{% endtabs %} + +## AI Assistant Dialog – Layout and Dynamic Controls + +The AI Assistant dialog provides a responsive, user-friendly interface for interacting with AI-generated content. It is designed as a modal dialog that overlays the editor and ensures proper z-index stacking for seamless integration. + +### Dialog Structure + +The dialog is divided into two main rows: + +**Row 1:** Action Selection and Dynamic Controls + +- **Action Dropdown:** Allows users to switch between AI actions (Rephrase, Grammar, Summarize, Elaborate, Translate). +- **Dynamic Controls:** + - **Tone Chips** (Standard, Fluent, Professional) appear when the selected action is Rephrase. + - **Language Dropdown** (15+ languages) appears when the selected action is Translate. + +**Row 2:** Original Text vs AI Result + +- **Left Panel:** Displays the original selected text in a read-only Rich Text Editor. +- **Right Panel:** Shows AI-generated content in another Rich Text Editor. +- **Loading State:** While AI processes the request, a progressive skeleton loader animates from 100% to 10% width for visual feedback. +- **Fallback State:** If no result is returned, a “No results found” message with a warning icon is displayed. + +**Footer Actions** + +- **Regenerate:** Requests a new AI output for the same prompt. +- **Copy:** Copies the AI-generated content to the clipboard. +- **Replace:** Inserts the AI-generated content back into the original editor with undo support. + +{% tabs %} +{% highlight %} + + + + +
+ AI Assistant +
+ + + +
+
+
+ + + + + + +
+
+ +
+ @if (this.enableRephraseChips) + { + + + + + + + + + + } + else if (this.enableLanguageList) + { +
+ Target Language +
+
+ + - +
-
-
- @if (this.enableRephraseChips) - { - - - - - - - - - } - else if (this.enableLanguageList) - { -
- Target Language -
-
- - - - -
- } -
+ }
-
-
-
- - - -
+
+ +
+
+
+ + + +
- @if (!isContentGenerating) +
+ + @if (!isContentGenerating) + { + @if (noResultsFound) { - @if (noResultsFound) - { -
-
-
- -
No results found
-
-
-
- } - else { -
-
- - - + +
+
+
+ +
No results found
- } - } else { +
+ } + else {
-
-
-
-
-
-
- -
+ + + +
} -
- - -
-
+ } else { +
- Regenerate +
+ +
+
+
+
+
+ +
-
- @if (!string.IsNullOrEmpty(sentiment)) { - - } - Copy - Replace + } +
+ + + +
+
+
+ + Regenerate
- - - - -
- - - +
+ @if (!string.IsNullOrEmpty(sentiment)) { + + } + + Copy + Replace +
+
+ + + + + +{% endhighlight %} +{% endtabs %} + +## Opening the AI Dialog and Preserving Selection + +The `DialogueOpen()` method opens the AI dialog when an action is selected and prepares the editor for processing. It first uses `GetSelectedHtmlAsync()` to capture the highlighted content with its formatting. If no text is selected, a toast message alerts the user to select content before proceeding. + +When valid text is found, the method makes the dialog visible, stores the selected HTML for AI processing, and calls `SaveSelectionAsync()` to preserve the cursor position so the AI output can replace only the selected text later. It then refreshes the dialog’s editor and updates AI suggestions based on the chosen action. + + +```csharp +private async Task Rephrase() +{ + // Directly open dialog for Rephrase action + await DialogueOpen("Rephrase"); +} +private async Task AIQuerySelectedMenu(MenuEventArgs args) +{ + // Open dialog based on selected dropdown item + await DialogueOpen(args.Item.Text); +} +private async Task DialogueOpen(string selectedQuery) +{ + // Get the selected text from the RichTextEditor + var selectionText = await rteObj.GetSelectedHtmlAsync(); + + if (!string.IsNullOrEmpty(selectionText)) + { + // Make the dialog visible + dialogVisible = true; + + // Identify the selected query and map it to its ID + + dropVal = QueryList.FirstOrDefault(q => q.Text.Equals(selectedQuery, StringComparison.OrdinalIgnoreCase))?.ID; + + // Store the selected text for AI processing + promptQuery = selectionText; + + // Save the current selection so AI output can be inserted later + await this.rteObj.SaveSelectionAsync(); + + // Refresh the left-side RichTextEditor in the dialog to show original text + await this.leftRteChildObj.RefreshUIAsync(); + + // Update AI suggestions based on the selected query + await UpdateAISuggestionsData(selectedQuery); + } + else + { + // Show a toast notification if no text is selected + await this.ToastObj.ShowAsync(new ToastModel { ContentTemplate = @GetTemplate(true), ShowCloseButton = true, Timeout = 0 }); + } +} ``` -### Backend Logic in C# (`Home.razor.cs`) +## Building and Sending the AI + +The AI prompt is built in two parts: **user intent** and **system instruction**. + +1. **User Intent (subQuery)** - Defines what the AI should do, such as summarizing, rephrasing with a specific tone, or translating into a target language. This makes the prompt context-aware and action-specific. -The C# file manages dialog visibility, button states, and AI calls. When an option is selected, `DialogueOpen()` captures the selected text and opens the dialog. `UpdateAISuggestionsData()` sends the query to the AI service and updates the UI with the result. Users can regenerate or replace content easily. +2. **System Instruction (HTML preservation)** - Enforces formatting rules, for example: “Retain existing HTML structure. Modify content only.” This ensures that the AI preserves elements like bold text, lists, and links while updating the content. -`Home.razor.cs` +Both parts are combined and sent to `semanticKernelAI.GetCompletionAsync()` via Semantic Kernel, resulting in an AI-generated output that is accurate and safe to insert back into the editor. ```csharp -using Markdig; -using Microsoft.AspNetCore.Components; -using Microsoft.JSInterop; -using Syncfusion.Blazor.DropDowns; -using Syncfusion.Blazor.Inputs; -using Syncfusion.Blazor.Notifications; -using Syncfusion.Blazor.RichTextEditor; -using Syncfusion.Blazor.SplitButtons; - -namespace AISamples.Components.Pages + +private async Task UpdateAISuggestionsData(string selectedQuery) { - public partial class Home + enableRephraseChips = false; + enableLanguageList = false; + isSentimentCheck = false; + switch (selectedQuery) { - SfToast ToastObj; - private string ToastTarget { get; set; } = "#scroll-restricted"; - SfRichTextEditor rteObj; - SfRichTextEditor leftRteChildObj; - SfRichTextEditor rightRteChildObj; - private string Value { get; set; } = "
Integrate AI with the Editor

Integrate the AI assistant into the rich text editor by capturing the content from the editor, sending it to the AI service, and displaying the results or suggestions back in the editor.

Summarize

This function condenses the selected content into a brief summary, capturing the main points succinctly.

Elaborate

This function expands the selected content, adding additional details and context.

Rephrase

This function rewrites the selected content to convey the same meaning using different words or structures. It also enables rephrase options and disables language selection.

Correct Grammar

This function reviews and corrects the grammar of the selected content, ensuring it adheres to standard grammatical rules.

Translate

This function translates the selected content into the specified language, enabling language selection and disabling rephrase options.

"; - private bool dialogVisible { get; set; } - private bool enabelAIAssitantButton { get; set; } = false; - private bool enabelRegenerateContentButton { get; set; } = false; - private bool enabelContentButton { get; set; } = true; - private string promptQuery = string.Empty; - private string subQuery = string.Empty; - private string[] chipValue = new[] { "Standard" }; - private string translatelanguage = "EN"; - private string dropVal { get; set; } = "Rephrase"; - private bool enableRephraseChips { get; set; } = true; - private bool enableLanguageList { get; set; } = false; - private bool noResultsFound { get; set; } = false; - public bool isContentGenerating { get; set; } = true; - private string AIResult { get; set; } = string.Empty; - private bool isSentimentCheck { get; set; } = false; - private MarkdownPipeline pipeline { get; set; } = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build(); - private string sentiment = ""; - private string apiResultData = ""; - private string ButtonClass = "e-tbar-btn"; - private void UpdateStatus(Syncfusion.Blazor.RichTextEditor.ChangeEventArgs args) - { - Value = args.Value; - enabelAIAssitantButton = string.IsNullOrWhiteSpace(Value); - } - private void OnActionCompleteHandler(Syncfusion.Blazor.RichTextEditor.ActionCompleteEventArgs args) - { - if (args.RequestType == "SourceCode") - { - this.ButtonClass = "e-tbar-btn e-overlay"; - } - if (args.RequestType == "Preview") - { - this.ButtonClass = "e-tbar-btn"; - } - } - private void UpdateTextAreaStatus(InputEventArgs args) - { - Value = args.Value; - enabelRegenerateContentButton = string.IsNullOrWhiteSpace(Value); - } - private async Task AIQuerySelectedMenu(MenuEventArgs args) - { - await DialogueOpen(args.Item.Text); - } - private async Task Rephrase() - { - await DialogueOpen("Rephrase"); - } - private async Task DialogueOpen(string selectedQuery) - { - var selectionText = await rteObj.GetSelectedHtmlAsync(); - if (!string.IsNullOrEmpty(selectionText)) - { - dialogVisible = true; - dropVal = QueryList.FirstOrDefault(q => q.Text.Equals(selectedQuery, StringComparison.OrdinalIgnoreCase))?.ID; - promptQuery = selectionText; - await this.rteObj.SaveSelectionAsync(); - await this.leftRteChildObj.RefreshUIAsync(); - await UpdateAISuggestionsData(selectedQuery); - } - else - { - await this.ToastObj.ShowAsync(new ToastModel { ContentTemplate = @GetTemplate(true), ShowCloseButton = true, Timeout = 0 }); - } - } - private async Task SelectedChipsChanged(Syncfusion.Blazor.Buttons.SelectionChangedEventArgs args) - { - if (chipValue.Length == 0 && args != null && args.RemovedItems.Length > 0) - { - chipValue = new [] { args.RemovedItems[0] }; - } - await UpdateAISuggestionsData("Rephrase"); - } - private async Task AITranslateDropdownList(ChangeEventArgs args) - { - await UpdateAISuggestionsData("Translate"); - } - private async Task AIQuerySelectedDropdownList(ChangeEventArgs args) - { - if (!string.IsNullOrEmpty(dropVal)) - { - chipValue = new[] { "Standard" }; - translatelanguage = "EN"; - var selectedQuery = QueryList.FirstOrDefault(q => q.ID.Equals(dropVal, StringComparison.OrdinalIgnoreCase))?.Text; - await UpdateAISuggestionsData(selectedQuery); - } - } - private async Task UpdateAISuggestionsData(string selectedQuery) - { - enableRephraseChips = false; - enableLanguageList = false; - isSentimentCheck = false; - switch (selectedQuery) - { - case "Summarize": - subQuery = "Briefly summarize the following text in a short and concise manner."; - break; - case "Elaborate": - subQuery = "Elaborate/Expand on the following text, providing more detail and context."; - break; - case "Rephrase": - enableRephraseChips = true; - enableLanguageList = false; - subQuery = $"Rephrase the following text in a {chipValue[0]} [tone/style], ensuring clarity and maintaining the original meaning."; - break; - case "Correct Grammar": - subQuery = "Correct any grammatical errors in the following text, ensuring it is clear and well-structured."; - break; - case "Translate": - enableLanguageList = true; - enableRephraseChips = false; - subQuery = $"Translate the following text into {translatelanguage}, preserving the original meaning and tone."; - break; - } - UpdateAISuggestionsData(); - } - private async Task RegenerateContent() - { - UpdateAISuggestionsData(); - } - private async Task ReplaceContent() - { - ExecuteCommandOption executeCommandOption = new ExecuteCommandOption(); - executeCommandOption.Undo = true; - await this.rteObj.RestoreSelectionAsync(); - await this.rteObj.ExecuteCommandAsync(CommandName.InsertHTML, this.apiResultData, executeCommandOption); - await CloseDialog(); - } - private async Task CopyContent() - { - await JSRuntime.InvokeVoidAsync("copyToClipboard", Markdig.Markdown.ToPlainText(AIResult, pipeline)); - } - private async Task CloseDialog() - { - dialogVisible = false; - promptQuery = string.Empty; - AIResult = string.Empty; - chipValue = new[] { "Standard" }; - dropVal = "Query1"; + case "Summarize": + subQuery = "Briefly summarize the following text in a short and concise manner."; + break; + case "Elaborate": + subQuery = "Elaborate/Expand on the following text, providing more detail and context."; + break; + case "Rephrase": enableRephraseChips = true; enableLanguageList = false; - sentiment = ""; - apiResultData = ""; - } - private async Task UpdateAISuggestionsData() + subQuery = $"Rephrase the following text in a {chipValue[0]} [tone/style], ensuring clarity and maintaining the original meaning."; + break; + case "Correct Grammar": + subQuery = "Correct any grammatical errors in the following text, ensuring it is clear and well-structured."; + break; + case "Translate": + enableLanguageList = true; + enableRephraseChips = false; + subQuery = $"Translate the following text into {translatelanguage}, preserving the original meaning and tone."; + break; + } + UpdateAISuggestionsData(); +} + +private async Task UpdateAISuggestionsData() +{ + try + { + if (!string.IsNullOrEmpty(promptQuery)) { - try + enabelRegenerateContentButton = isContentGenerating = enabelContentButton = true; + string systemPrompt = subQuery.Contains("emoji followed by the sentiment in the format") ? "You are a helpful assistant. Please respond in string format." : "NOTE:Please retain the existing HTML structure and modify the content only. Ensure that the response adheres to the specified formatting."; + apiResultData = await semanticKernelAI.GetCompletionAsync(promptQuery, false, false, (subQuery + systemPrompt)); + if (apiResultData != null) { - if (!string.IsNullOrEmpty(promptQuery)) - { - enabelRegenerateContentButton = isContentGenerating = enabelContentButton = true; - string systemPrompt = subQuery.Contains("emoji followed by the sentiment in the format") ? "You are a helpful assistant. Please respond in string format." : "NOTE:Please retain the existing HTML structure and modify the content only. Ensure that the response adheres to the specified formatting."; - apiResultData = await semanticKernelAI.GetCompletionAsync(promptQuery, false, false, (subQuery + systemPrompt)); - if (apiResultData != null) - { - isContentGenerating = false; - sentiment = isSentimentCheck ? apiResultData.Replace("\"", "").Replace("'", "") : ""; - AIResult = isSentimentCheck ? promptQuery : apiResultData; - noResultsFound = string.IsNullOrEmpty(AIResult) || string.IsNullOrEmpty(promptQuery); - enabelRegenerateContentButton = enabelContentButton = noResultsFound; - await InvokeAsync(StateHasChanged); - } - else - { - isContentGenerating = false; - await InvokeAsync(StateHasChanged); - } - } - } - catch - { - await this.ToastObj.ShowAsync(new ToastModel { ContentTemplate = @GetTemplate(), ShowCloseButton = true, Timeout = 0 }); - } + isContentGenerating = false; + sentiment = isSentimentCheck ? apiResultData.Replace("\"", "").Replace("'", "") : ""; + AIResult = isSentimentCheck ? promptQuery : apiResultData; + noResultsFound = string.IsNullOrEmpty(AIResult) || string.IsNullOrEmpty(promptQuery); + enabelRegenerateContentButton = enabelContentButton = noResultsFound; + await InvokeAsync(StateHasChanged); } - private RenderFragment GetTemplate(bool hasTextSelection = false) => builder => - { - builder.OpenElement(0, "div"); - builder.AddContent(1, hasTextSelection ? "Please select the content to perform the AI operation." : "An error occurred during the AI process, Please try again."); - builder.CloseElement(); - }; - public class SubQuery - { - public string ID { get; set; } - public string Text { get; set; } - } - public class Languages + else { - public string ID { get; set; } - public string Text { get; set; } + isContentGenerating = false; + await InvokeAsync(StateHasChanged); } - public List QueryList = new List - { - new SubQuery { ID = "Rephrase", Text = "Rephrase" }, - new SubQuery { ID = "Grammar", Text = "Correct Grammar" }, - new SubQuery { ID = "Summarize", Text = "Summarize" }, - new SubQuery { ID = "Elaborate", Text = "Elaborate" }, - new SubQuery { ID = "Translate", Text = "Translate" } - }; - public List LanguageList = new List - { - new Languages { ID = "EN", Text = "English" }, - new Languages { ID = "ZH", Text = "Chinese (Simplified)" }, - new Languages { ID = "ZHT", Text = "Chinese (Traditional)" }, - new Languages { ID = "ES", Text = "Spanish" }, - new Languages { ID = "HI", Text = "Hindi" }, - new Languages { ID = "AR", Text = "Arabic" }, - new Languages { ID = "BN", Text = "Bengali" }, - new Languages { ID = "PT", Text = "Portuguese" }, - new Languages { ID = "RU", Text = "Russian" }, - new Languages { ID = "JA", Text = "Japanese" }, - new Languages { ID = "DE", Text = "German" }, - new Languages { ID = "KO", Text = "Korean" }, - new Languages { ID = "FR", Text = "French" }, - new Languages { ID = "IT", Text = "Italian" }, - new Languages { ID = "TR", Text = "Turkish" } - }; - private List Tools = new List() - { - new ToolbarItemModel() { Name = "AIAssistant", TooltipText = "AI Assistant" }, - new ToolbarItemModel() { Name = "Rephrase", TooltipText = "Rephrase" }, - new ToolbarItemModel() { Command = ToolbarCommand.Bold }, - new ToolbarItemModel() { Command = ToolbarCommand.Italic }, - new ToolbarItemModel() { Command = ToolbarCommand.Underline }, - new ToolbarItemModel() { Command = ToolbarCommand.Separator }, - new ToolbarItemModel() { Command = ToolbarCommand.FontName }, - new ToolbarItemModel() { Command = ToolbarCommand.FontSize }, - new ToolbarItemModel() { Command = ToolbarCommand.FontColor }, - new ToolbarItemModel() { Command = ToolbarCommand.Separator }, - new ToolbarItemModel() { Command = ToolbarCommand.BackgroundColor }, - new ToolbarItemModel() { Command = ToolbarCommand.Formats }, - new ToolbarItemModel() { Command = ToolbarCommand.Alignments }, - new ToolbarItemModel() { Command = ToolbarCommand.Separator }, - new ToolbarItemModel() { Command = ToolbarCommand.NumberFormatList }, - new ToolbarItemModel() { Command = ToolbarCommand.BulletFormatList }, - new ToolbarItemModel() { Command = ToolbarCommand.CreateLink }, - new ToolbarItemModel() { Command = ToolbarCommand.Image }, - new ToolbarItemModel() { Command = ToolbarCommand.Separator }, - new ToolbarItemModel() { Command = ToolbarCommand.CreateTable }, - new ToolbarItemModel() { Command = ToolbarCommand.SourceCode }, - new ToolbarItemModel() { Command = ToolbarCommand.Undo }, - new ToolbarItemModel() { Command = ToolbarCommand.Redo }, - }; + } + } + catch + { + await this.ToastObj.ShowAsync(new ToastModel { ContentTemplate = @GetTemplate(), ShowCloseButton = true, Timeout = 0 }); } } + +``` + +## Replacing AI Result Back into the Editor (with Undo Support) + +Once the AI-generated content is ready, it needs to be inserted exactly where the user originally selected text, without disturbing the rest of the document. This is achieved using the [ExecuteCommandAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.RichTextEditor.SfRichTextEditor.html#Syncfusion_Blazor_RichTextEditor_SfRichTextEditor_ExecuteCommandAsync_Syncfusion_Blazor_RichTextEditor_CommandName_System_String_Syncfusion_Blazor_RichTextEditor_ExecuteCommandOption_) method with the `InsertHTML` command. The `Undo` option is enabled to allow users to revert changes if needed. + +Additionally, users can copy the AI-generated content to the clipboard for use elsewhere. This is handled via a `JavaScript interop` function that copies plain text extracted from the AI result. + +{% tabs %} +{% highlight %} + + + Copy + Replace + + +{% endhighlight %} +{% endtabs %} + +```csharp + +private async Task ReplaceContent() +{ + ExecuteCommandOption executeCommandOption = new ExecuteCommandOption(); + executeCommandOption.Undo = true; + await this.rteObj.RestoreSelectionAsync(); // Return to original selection + await this.rteObj.ExecuteCommandAsync(CommandName.InsertHTML, this.apiResultData, executeCommandOption); + await CloseDialog(); +} +private async Task CopyContent() +{ + await JSRuntime.InvokeVoidAsync("copyToClipboard", Markdig.Markdown.ToPlainText(AIResult, pipeline)); +} + +``` + -``` - ## Workflow Summary Select text → Choose AI action → Dialog opens → AI processes → Updated content displayed → User copies or replaces content. From 89d961652d362acf9ce7b4f4aea6d681c18a51d9 Mon Sep 17 00:00:00 2001 From: Kokila Poovendran Date: Fri, 14 Nov 2025 13:37:45 +0530 Subject: [PATCH 4/6] 990970: AI-Samples documentation --- .../rich-text-editor/writting-assistance.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md b/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md index 47ac25706c..4a5f3adbf3 100644 --- a/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md +++ b/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md @@ -232,7 +232,7 @@ await builder.Build().RunAsync(); This guide explains how to integrate a full-featured AI writing assistant into the Blazor Rich Text Editor using Azure OpenAI (via Semantic Kernel). The implementation supports **Rephrase**, **Correct Grammar**, **Summarize**, **Elaborate**, and **Translate** with live preview, dynamic tone/language controls, skeleton loading, and safe, undoable content replacement. -## How the Custom Toolbar is Rendered +### How the Custom Toolbar is Rendered The toolbar uses [RichTextEditorCustomToolbarItems](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.RichTextEditor.RichTextEditorCustomToolbarItems.html) to inject a custom item named AI. @@ -278,11 +278,11 @@ An additional `SfButton` for **Rephrase** is provided for quick access. {% endhighlight %} {% endtabs %} -## AI Assistant Dialog – Layout and Dynamic Controls +### AI Assistant Dialog – Layout and Dynamic Controls The AI Assistant dialog provides a responsive, user-friendly interface for interacting with AI-generated content. It is designed as a modal dialog that overlays the editor and ensures proper z-index stacking for seamless integration. -### Dialog Structure +#### Dialog Structure The dialog is divided into two main rows: @@ -436,7 +436,7 @@ The dialog is divided into two main rows: {% endhighlight %} {% endtabs %} -## Opening the AI Dialog and Preserving Selection +### Opening the AI Dialog and Preserving Selection The `DialogueOpen()` method opens the AI dialog when an action is selected and prepares the editor for processing. It first uses `GetSelectedHtmlAsync()` to capture the highlighted content with its formatting. If no text is selected, a toast message alerts the user to select content before proceeding. @@ -489,7 +489,7 @@ private async Task DialogueOpen(string selectedQuery) ``` -## Building and Sending the AI +### Building and Sending the AI The AI prompt is built in two parts: **user intent** and **system instruction**. @@ -564,7 +564,7 @@ private async Task UpdateAISuggestionsData() ``` -## Replacing AI Result Back into the Editor (with Undo Support) +### Replacing AI Result Back into the Editor (with Undo Support) Once the AI-generated content is ready, it needs to be inserted exactly where the user originally selected text, without disturbing the rest of the document. This is achieved using the [ExecuteCommandAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.RichTextEditor.SfRichTextEditor.html#Syncfusion_Blazor_RichTextEditor_SfRichTextEditor_ExecuteCommandAsync_Syncfusion_Blazor_RichTextEditor_CommandName_System_String_Syncfusion_Blazor_RichTextEditor_ExecuteCommandOption_) method with the `InsertHTML` command. The `Undo` option is enabled to allow users to revert changes if needed. From 78c1f0dbd70cd2c5549012850903a1faefb2726c Mon Sep 17 00:00:00 2001 From: Kokila Poovendran Date: Fri, 14 Nov 2025 17:27:56 +0530 Subject: [PATCH 5/6] 990970: AI-Samples documentation --- .../kanban/smart-task-suggestion.md | 506 ++++++------------ .../rich-text-editor/writting-assistance.md | 14 +- 2 files changed, 185 insertions(+), 335 deletions(-) diff --git a/blazor/smart-ai-solutions/ai-samples/kanban/smart-task-suggestion.md b/blazor/smart-ai-solutions/ai-samples/kanban/smart-task-suggestion.md index baedc607b9..a4ad47896a 100644 --- a/blazor/smart-ai-solutions/ai-samples/kanban/smart-task-suggestion.md +++ b/blazor/smart-ai-solutions/ai-samples/kanban/smart-task-suggestion.md @@ -230,358 +230,213 @@ await builder.Build().RunAsync(); ## AI-powered Kanban Smart Card Generation -The AI-powered Kanban feature integrates Syncfusion Blazor Kanban with an AI service to automatically create structured task cards from user input. It combines a simple UI for project details with backend logic that generates tasks and updates the Kanban board dynamically. +The AI-powered Kanban feature integrates Blazor Kanban with an AI service to automatically generate structured task cards based on user input. This functionality simplifies project planning by allowing users to enter basic project details and the desired number of tasks. The backend logic then uses AI to create well-defined tasks, including fields like **Title**, **Description**, **Status**, and **Story Points**, and dynamically updates the Kanban board. This approach ensures faster task creation, consistent formatting, and an interactive experience for managing projects. -### UI Structure and User Interaction (`Home.razor`) +### UI Structure -The Razor page includes an input form for project details and a Kanban board for visualizing tasks. Users enter a project description and task count, then click Generate Tasks to start AI processing. A modal dialog ensures clean input for new projects, while conditional rendering switches between input and Kanban views. Cards display essential details like title, description, and story points with drag-and-drop support. +The Kanban AI interface starts with a simple form where users provide **Project Details** and the **Number of Tasks** to generate. Below these inputs, a Progress Button labeled “Generate Tasks” triggers the AI process. This button shows a loading state during task generation for better user feedback. -### AI Task Generation Logic (`Home.razor.cs`) +- **Project Details:** A multiline text box for describing the project. +- **Number of Tasks:** A numeric input for specifying how many tasks to generate. +- **Generate Button:** A progress-enabled button that calls `GenerateTasks()` to start AI-based task creation. -The `GenerateProjectTasks` method builds a prompt for the AI service, requesting tasks in strict JSON format with fields like Id, Title, Status, and Due Date. The response is cleaned and deserialized into `SmartSuggestionDataModel` objects, which are added to the Kanban data source. Progress button events provide feedback during generation, and default values like `Status="Open"` and `Color="#000000"` are applied to new tasks. - -### Data Binding and Kanban Configuration +{% tabs %} +{% highlight %} + +
+ +
+
+ +
+
+ +
+
+ +
+
+ + + +
-The `SfKanban` component binds to the `smartSuggestion` list, using `Status` as the `KeyField` to organize cards into columns (To Do, In Progress, Review, Done). -Card templates are customized via `KanbanCardSettings` to show essential task details with visual clarity. -A fallback `SfGrid` view allows tabular task management with inline editing, while a toggle button switches between Grid and Kanban layouts. +{% endhighlight %} +{% endtabs %} -### Error Handling and User Feedback +### Generating Tasks with AI -If AI generation fails, a toast notification displays an error message without disrupting the workflow. Input validation ensures both project details and task count are provided before submission. State flags manage UI transitions and prevent issues during asynchronous operations. +After the user enters project details and the number of tasks, clicking Generate Tasks calls `GenerateTasks()`, which triggers `GenerateProjectTasks()` to build a detailed prompt for the AI service. This prompt includes the project description, task count, and strict instructions to return data in JSON format with fields like Id, Title, Description, Status, StoryPoints, and Color. -(`Home.razor`) +The prompt is then sent to the AI using `GetCompletionAsync()`, which processes the request and returns a JSON response containing the generated tasks. The response is cleaned to remove unnecessary formatting and deserialized into a list of `SmartSuggestionDataModel` objects. These tasks are stored in `smartSuggestion` and displayed in the Kanban board or backlog view. ```csharp -@rendermode InteractiveServer -@inject AzureAIService OpenAIService -@using Syncfusion.Blazor.Kanban -@using Syncfusion.Blazor.Buttons -@using Syncfusion.Blazor.SplitButtons -@using Syncfusion.Blazor.Popups -@using Syncfusion.Blazor.Inputs -@using Syncfusion.Blazor.Notifications -@using BlazorApp4.Components.Models -@using BlazorApp4.Components.Service -@using Syncfusion.Blazor.Grids - -@if (isHomapage) +private async Task GenerateProjectTasks() { -
-
-
-
-

AI Smart Task Suggestion

-
-
-
-
-
-
- -
-
- -
-
- -
-
- -
-
- - - -
-
-
-
-
-
-
-
+ try + { + if (!string.IsNullOrEmpty(TextBoxValue) && !string.IsNullOrEmpty(TasksValue)) + { + string result = ""; + var description = $"Generate {TasksValue} task recommendations for {TextBoxValue}. Each task should include the following fields: Id (like example: ID should be in project name simple 4char word - 1), Title, Status, Description, Assignee, StoryPoints, Color and Due Date, formatted according to the dataset. Assign each task to the Assignee: empty string, set the Status to 'Open', and use black for the Color. Use the dataset provided below to create your recommendations. IMPORTANT: Return the data strictly in JSON format with all the required fields. Only the JSON data is needed, no additional text.Return only the JSON array format without any explanations."; + result = await OpenAIService.GetCompletionAsync(description); + if (result != null) + { + string data = result.Replace("```json", "").Replace("```", "").Replace("\r", "").Replace("\n", "").Replace("\t", "").Trim(); + List modifiedData; + modifiedData = JsonSerializer.Deserialize>(data); + smartSuggestion = modifiedData != null ? smartSuggestion.Concat(modifiedData).ToList() : smartSuggestion; + this.isGeneratedProjectTasks = true; + } + ContentGenerateTask = "Generate Tasks"; + } + else + { + waringText = string.IsNullOrEmpty(TextBoxValue) && string.IsNullOrEmpty(TasksValue) ? "Enter the required task creation details" : !string.IsNullOrEmpty(TasksValue) ? "Enter the Project Details" : "Enter the number of tasks"; + } + } + catch + { + await this.ToastObj.ShowAsync(new ToastModel { ContentTemplate = @GetTemplate(), ShowCloseButton = true, Timeout = 0 }); + } } -else -{ -
-
-
- @if (showBacklogs) - { -
-

Kanban Board

-
- Add New Projects -
-
- + +``` + +### Displaying AI-Generated Tasks in Kanban Cards + +Once the AI-generated tasks are processed and stored in `smartSuggestion`, they are displayed in two ways: + +1. Kanban Board View +2. Backlog Grid View + +#### Kanban Board View + +The Kanban board uses `SfKanban` to organize tasks into columns like **To Do**, **In Progress**, **Review**, and **Done**, based on the Status field. Each card shows the task title, description, and story points using a custom template for better readability. + +- **Kanban Columns:** Defined by KeyField values such as Open, InProgress, Review, and Close. +- **Card Template:** Displays Title, Description, and StoryPoints in a structured layout. +- **Dynamic Binding:** The [DataSource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Kanban.SfKanban-1.html#Syncfusion_Blazor_Kanban_SfKanban_1_DataSource) property binds to `smartSuggestion`, ensuring that newly generated tasks appear instantly. + +{% tabs %} +{% highlight %} + + + + + + + + + + + + + +{% endhighlight %} +{% endtabs %} + +#### Backlog Grid View + +When users switch to **Backlog View**, tasks are displayed in a grid using `SfGrid`. This view allows adding, deleting, and editing tasks through a **dialog popup** for structured input. + +- **Dialog Editing:** Uses [GridEditSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_EditSettings) with [Dialog](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridEditSettings.html#Syncfusion_Blazor_Grids_GridEditSettings_Dialog) mode for structured editing. +- **Validation:** Ensures required fields like Task ID, Title, and Status are filled. +- **Data Binding:** The [DataSource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_DataSource) property binds to `smartSuggestion`, just like Kanban. + +{% tabs %} +{% highlight %} + + + + + + + + + + + + + + -``` +{% endhighlight %} +{% endtabs %} + +**View Toggle:** Users can switch between **Kanban** and **Grid** using the button below: + +{% tabs %} +{% highlight %} + + -`Home.razor.cs` +{% endhighlight %} +{% endtabs %} ```csharp -using System.Text.Json; -using AISamples.Components.Models; -using Microsoft.AspNetCore.Components; -using Syncfusion.Blazor.Grids; -using Syncfusion.Blazor.Kanban; -using Syncfusion.Blazor.Notifications; - -namespace AISamples.Components.Pages +private void GoToBacklogBoardView() { - public partial class Home + if (BacklogButtonViewContent == "View as Board") { - SfToast ToastObj; - public string[] SelectedAssignees { get; set; } = new string[] { }; - private string ToastTarget { get; set; } = "#toast-kanban-observable"; - SfKanban kanbanObj; - public string ContentGenerateTask = "Generate Tasks"; - public string BacklogButtonViewContent = "View as Backlog"; - private string TextBoxValue = string.Empty; - private string TasksValue = string.Empty; - private bool enableProjectDetailsDialog = false; - private bool isGeneratedProjectTasks = false; - private bool enableTaskEditing = false; - private bool isHomapage = true; - private bool showSprintBoard = false; - private bool showBacklogs = false; - private bool showBacklogBoard = true; - private List smartSuggestion = new List(); - private DialogSettings DialogParams = new DialogSettings { MinHeight = "400px", Width = "450px" }; - private string waringText = "Click \"Generate Tasks\" to preview"; - private void GoToBacklogBoardView() - { - if (BacklogButtonViewContent == "View as Board") - { - BacklogButtonViewContent = "View as Backlog"; - showBacklogBoard = true; - } - else - { - showBacklogBoard = false; - BacklogButtonViewContent = "View as Board"; - } - showSprintBoard = false; - } - private RenderFragment GetTemplate() => builder => - { - builder.OpenElement(0, "div"); - builder.AddContent(1, "An error occurred during the AI process, Please try again."); - builder.CloseElement(); - }; - public void BeginGenerateTasks(Syncfusion.Blazor.SplitButtons.ProgressEventArgs args) - { - ContentGenerateTask = "Generating..."; - } - public async Task EndGenerateTasks(Syncfusion.Blazor.SplitButtons.ProgressEventArgs args) - { - while (!isGeneratedProjectTasks) - { - await Task.Delay(1000); - } - this.isHomapage = false; - this.CloseDialog(); - showBacklogs = true; - } - private async Task GenerateProjectTasks() - { - try - { - if (!string.IsNullOrEmpty(TextBoxValue) && !string.IsNullOrEmpty(TasksValue)) - { - string result = ""; - var description = $"Generate {TasksValue} task recommendations for {TextBoxValue}. Each task should include the following fields: Id (like example: ID should be in project name simple 4char word - 1), Title, Status, Description, Assignee, StoryPoints, Color and Due Date, formatted according to the dataset. Assign each task to the Assignee: empty string, set the Status to 'Open', and use black for the Color. Use the dataset provided below to create your recommendations. IMPORTANT: Return the data strictly in JSON format with all the required fields. Only the JSON data is needed, no additional text.Return only the JSON array format without any explanations."; - result = await OpenAIService.GetCompletionAsync(description); - if (result != null) - { - string data = result.Replace("```json", "").Replace("```", "").Replace("\r", "").Replace("\n", "").Replace("\t", "").Trim(); - List modifiedData; - modifiedData = JsonSerializer.Deserialize>(data); - smartSuggestion = modifiedData != null ? smartSuggestion.Concat(modifiedData).ToList() : smartSuggestion; - this.isGeneratedProjectTasks = true; - } - ContentGenerateTask = "Generate Tasks"; - } - else - { - waringText = string.IsNullOrEmpty(TextBoxValue) && string.IsNullOrEmpty(TasksValue) ? "Enter the required task creation details" : !string.IsNullOrEmpty(TasksValue) ? "Enter the Project Details" : "Enter the number of tasks"; - } - } - catch - { - await this.ToastObj.ShowAsync(new ToastModel { ContentTemplate = @GetTemplate(), ShowCloseButton = true, Timeout = 0 }); - } - } - private void OpenProjectDetailsDialog() - { - this.enableProjectDetailsDialog = true; - } - private async Task GenerateTasks() - { - this.isGeneratedProjectTasks = false; - await this.GenerateProjectTasks(); - } - private void SaveTask() - { - this.enableProjectDetailsDialog = false; - this.TasksValue = string.Empty; - this.TextBoxValue = string.Empty; - this.isGeneratedProjectTasks = false; - StateHasChanged(); - } - private void CloseDialog() - { - this.enableProjectDetailsDialog = false; - this.TasksValue = string.Empty; - this.TextBoxValue = string.Empty; - this.isGeneratedProjectTasks = false; - StateHasChanged(); - } - public void TaskEditingHandler(Syncfusion.Blazor.Grids.ActionEventArgs args) - { - if (args.RequestType.ToString() == "Add") - { - enableTaskEditing = true; - } - else - { - enableTaskEditing = false; - } - } - public void RowCreatedHandler(RowCreatedEventArgs args) - { - args.Data.Status = "Open"; - args.Data.Color = "#000000"; - } + BacklogButtonViewContent = "View as Backlog"; + showBacklogBoard = true; + } + else + { + showBacklogBoard = false; + BacklogButtonViewContent = "View as Board"; } } - ``` +## Sample Code + +A complete working example is available in the [Syncfusion Blazor AI Samples GitHub repository](https://github.com/syncfusion/smart-ai-samples). + +![Kanban AI Assistant - Output](../../ai/images/smart-task-suggestion.png) + ## Error Handling and Troubleshooting If the AI service fails to return a valid response, the Kanban will display an error message ("Oops! Please try again!"). Common issues include: @@ -591,8 +446,3 @@ If the AI service fails to return a valid response, the Kanban will display an e - **Network Issues**: Check connectivity to the AI service endpoint, especially for self-hosted Ollama instances. - **Large Prompts**: Processing large text inputs may cause timeouts. Consider reducing the prompt size or optimizing the request for efficiency. -## Sample Code - -A complete working example is available in the [Syncfusion Blazor AI Samples GitHub repository](https://github.com/syncfusion/smart-ai-samples). - -![Kanban AI Assistant - Output](../../ai/images/smart-task-suggestion.png) \ No newline at end of file diff --git a/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md b/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md index 4a5f3adbf3..f6c75df29c 100644 --- a/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md +++ b/blazor/smart-ai-solutions/ai-samples/rich-text-editor/writting-assistance.md @@ -230,7 +230,7 @@ await builder.Build().RunAsync(); ## AI-powered Rich Text Editor in Blazor -This guide explains how to integrate a full-featured AI writing assistant into the Blazor Rich Text Editor using Azure OpenAI (via Semantic Kernel). The implementation supports **Rephrase**, **Correct Grammar**, **Summarize**, **Elaborate**, and **Translate** with live preview, dynamic tone/language controls, skeleton loading, and safe, undoable content replacement. +This guide explains how to integrate a full-featured AI writing assistant into the Blazor Rich Text Editor using Azure OpenAI (via Semantic Kernel). The implementation supports **Rephrase**, **Correct Grammar**, **Summarize**, **Elaborate**, and **Translate** with live preview, dynamic tone and language controls, skeleton loading, and safe content replacement with undo support. ### How the Custom Toolbar is Rendered @@ -633,6 +633,12 @@ private async Task CopyContent() Select text → Choose AI action → Dialog opens → AI processes → Updated content displayed → User copies or replaces content. +## Sample Code + +A complete working example is available in the [Syncfusion Blazor AI Samples GitHub repository](https://github.com/syncfusion/smart-ai-samples). + +![Rich Text Editor AI Assistant - Output](../../ai/images/richtexteditor-ai-assistant.png) + ## Error Handling and Troubleshooting If the AI service fails to return a valid response, the Rich Text Editor will display an error message ("Oops! Please try again!"). Common issues include: @@ -641,9 +647,3 @@ If the AI service fails to return a valid response, the Rich Text Editor will di - **Model Unavailable**: Ensure the specified `openAIModel`, `azureOpenAIModel`, or `ModelName` is deployed and supported. - **Network Issues**: Check connectivity to the AI service endpoint, especially for self-hosted Ollama instances. - **Large Prompts**: Processing large text inputs may cause timeouts. Consider reducing the prompt size or optimizing the request for efficiency. - -## Sample Code - -A complete working example is available in the [Syncfusion Blazor AI Samples GitHub repository](https://github.com/syncfusion/smart-ai-samples). - -![Rich Text Editor AI Assistant - Output](../../ai/images/richtexteditor-ai-assistant.png) \ No newline at end of file From ab4c796889eab12ad36cdf96cf727c083307da6d Mon Sep 17 00:00:00 2001 From: Kokila Poovendran Date: Fri, 14 Nov 2025 18:44:35 +0530 Subject: [PATCH 6/6] 990970: AI-Samples documentation --- .../ai-samples/kanban/sentiment-analysis.md | 461 ++++++++---------- 1 file changed, 191 insertions(+), 270 deletions(-) diff --git a/blazor/smart-ai-solutions/ai-samples/kanban/sentiment-analysis.md b/blazor/smart-ai-solutions/ai-samples/kanban/sentiment-analysis.md index e35814a715..ed365c4934 100644 --- a/blazor/smart-ai-solutions/ai-samples/kanban/sentiment-analysis.md +++ b/blazor/smart-ai-solutions/ai-samples/kanban/sentiment-analysis.md @@ -230,299 +230,225 @@ await builder.Build().RunAsync(); ## AI-powered Sentiment Analysis in Kanban -The AI-powered sentiment analysis feature in Syncfusion Blazor Kanban evaluates customer feedback for delivered tasks and displays emojis (😊, 😐, 😞) to indicate positive, neutral, or negative sentiment. This helps teams quickly assess satisfaction levels and prioritize follow-up actions, improving customer experience in service workflows. +The AI-powered sentiment analysis feature in Blazor Kanban evaluates customer feedback for delivered tasks and displays emojis (😊, 😐, 😞) to indicate positive, neutral, or negative sentiment. This helps teams quickly assess satisfaction levels and prioritize follow-up actions, improving customer experience in service workflows. -### UI Structure and User Interaction (`Home.razor`) +### UI Structure -The Razor page includes a Kanban board for managing pizza orders across columns like Menu, Order, Ready to Serve, and Delivered. A progress button triggers sentiment analysis, while custom card templates display task details such as title, description, and delivery date. After analysis, an emoji appears on delivered tasks to represent sentiment. A dialog template supports editing fields like category, size, and feedback, with conditional rendering based on task type. +The Kanban sentiment analysis interface starts with a Progress Button labeled **Check Customer Sentiments**. When clicked, it triggers the AI process to analyze customer feedback. The button shows a loading state during analysis for better user feedback. -### AI Sentiment Analysis Logic (`Home.razor.cs`) +- **Sentiment Analysis Button:** A progress-enabled button that calls `GetScore()` to start AI-based sentiment analysis. +- **Kanban Board:** Displays pizza orders grouped by Category (Menu, Order, Ready to Serve, Delivered). Each card shows pizza details and later displays sentiment emoji for delivered items. -The `GetScore` method serializes Kanban data to JSON and sends it to the AI service with a prompt requesting a `SentimentScore` (1–5) based on feedback. The AI response is cleaned and deserialized into the data model, updating each task’s score and assigning emojis: 😢 for 1–2, 😐 for 3, and 😀 for 4–5. State flags like `ShowScore` control rendering, while progress events (`Begin`, `End`) update button text during processing. - -### Data Binding and Error Handling - -The `SfKanban` binds to the `Pizza` list using `Category` as the `KeyField`, with dynamic columns from `columnData`. Card templates conditionally render sentiment emojis for delivered tasks. If AI analysis fails, the spinner state prevents premature interactions, and `StateHasChanged()` refreshes the UI after completion. +{% tabs %} +{% highlight %} -(`Home.razor`) + + + -```csharp -@using Syncfusion.Blazor.Kanban -@using Syncfusion.Blazor.SplitButtons -@using Syncfusion.Blazor.Calendars -@using Syncfusion.Blazor.Inputs -@using Syncfusion.Blazor.DropDowns -@using AISamples.Components.Models -@using AISamples.Components.Service -@inject AzureAIService OpenAIService - -
- - - -
-
-
- - - @foreach (ColumnModel item in columnData) - { - - } - - - + + -``` +{% endhighlight %} +{% endtabs %} -`Home.razor.cs` +### Analyzing Sentiments with AI -```csharp +After the user clicks **Check Customer Sentiments** button, the `GetScore()` method runs. It serializes the Kanban data into JSON and builds a prompt for the AI service using the `GetCompletionAsync` method. The prompt instructs the AI to: + +- Provide a `SentimentScore` out of 5 based on the feedback. +- Skip scoring if feedback is null. +- Return the updated data strictly in JSON format with all fields included. -using System.Text.Json; -using AISamples.Components.Models; -using Syncfusion.Blazor.DropDowns; -using Syncfusion.Blazor.Inputs; -using Syncfusion.Blazor.Kanban; +The AI response is cleaned to remove extra formatting and deserialized into a list of PizzaDataModel objects. Each item’s `SentimentScore` is mapped to an emoji: -namespace AISamples.Components.Pages +- Score > 3 → 😊 smiling face +- Score = 3 → 😐 neutral face +- Score ≤ 2 → 😞 disappointed face + +Finally, `ShowScore` is set to `true`, and the Kanban board updates to display emojis for delivered items. + +```csharp +private async Task GetScore() { - public partial class Home + this.IsSpinner = true; + string result = ""; + string json = JsonSerializer.Serialize(Pizza, new JsonSerializerOptions { WriteIndented = true }); + var description = "Provide a SentimentScore out of 5 (whole numbers only) based on the Feedback. If the feedback is null, do not give a SentimentScore. Use the dataset provided below to make recommendations. NOTE: Return the data in JSON format with all fields included, and return only JSON data, no explanatory text." + json; + result = await OpenAIService.GetCompletionAsync(description); + string data = result.Replace("```json", "").Replace("```", "").Replace("\r", "").Replace("\n", "").Replace("\t", "").Trim(); + this.Pizza = JsonSerializer.Deserialize>(data); + this.IsSpinner = false; + foreach(var item in Pizza) { - SfDropDownList CategoryRef; - SfTextBox DescriptionRef; - private string SelectedAPI = "Open AI"; - private bool ShowScore = false; - private bool IsSpinner = false; - private List Pizza = new PizzaDataModel().GetPizzaData(); - public string Content = "Check Customer Sentiments"; - private async Task GetScore() + if(item.SentimentScore > 0 && item.SentimentScore <= 2) { - this.IsSpinner = true; - string result = ""; - string json = JsonSerializer.Serialize(Pizza, new JsonSerializerOptions { WriteIndented = true }); - var description = "Provide a SentimentScore out of 5 (whole numbers only) based on the Feedback. If the feedback is null, do not give a SentimentScore. Use the dataset provided below to make recommendations. NOTE: Return the data in JSON format with all fields included, and return only JSON data, no explanatory text." + json; - result = await OpenAIService.GetCompletionAsync(description); - string data = result.Replace("```json", "").Replace("```", "").Replace("\r", "").Replace("\n", "").Replace("\t", "").Trim(); - this.Pizza = JsonSerializer.Deserialize>(data); - this.IsSpinner = false; - foreach(var item in Pizza) - { - if(item.SentimentScore > 0 && item.SentimentScore <= 2) - { - item.Emoji = "😢"; - } - else if (item.SentimentScore > 3 && item.SentimentScore <= 5) - { - item.Emoji = "😀"; - } - else if (item.SentimentScore == 3) - { - item.Emoji = "😐"; - } - } - this.ShowScore = true; - StateHasChanged(); - } - private List CategoryData = new List() - { - new DropDownModel { Id = 0, Value = "Menu" }, - new DropDownModel { Id = 1, Value = "Order" }, - new DropDownModel { Id = 2, Value = "Ready to Serve" }, - new DropDownModel { Id = 3, Value = "Delivered"}, - new DropDownModel { Id = 3, Value = "Served"}, - }; - private class DropDownModel - { - public int Id { get; set; } - public string Value { get; set; } + item.Emoji = "😢"; } - private List columnData = new List() { - new ColumnModel(){ HeaderText= "Menu", KeyField= new List() { "Menu" } }, - new ColumnModel(){ HeaderText= "Order", KeyField= new List() { "Order" } }, - new ColumnModel(){ HeaderText= "Ready to Serve", KeyField= new List() { "Ready to Serve"} }, - new ColumnModel(){ HeaderText= "Delivered", KeyField=new List() { "Delivered", "Served" } } - }; - public void Begin(Syncfusion.Blazor.SplitButtons.ProgressEventArgs args) + else if (item.SentimentScore > 3 && item.SentimentScore <= 5) { - Content = "Analyzing..."; + item.Emoji = "😀"; } - public async Task End(Syncfusion.Blazor.SplitButtons.ProgressEventArgs args) + else if (item.SentimentScore == 3) { - while (this.IsSpinner) - { - await Task.Delay(1000); - } - Content = "Check Cusotomer Sentiments"; + item.Emoji = "😐"; } } + this.ShowScore = true; + StateHasChanged(); } + ``` +### Displaying Sentiment Results on Kanban Cards + +Once the AI response is processed and `ShowScore` is set to `true`, the Kanban board updates dynamically. For cards in the Delivered or Served categories: + +- The Emoji field is shown alongside delivery details. +- Emojis represent the sentiment score: + - 😊 Smiling face for positive feedback (score > 3) + - 😐 Neutral face for average feedback (score = 3) + - 😞 Disappointed face for negative feedback (score ≤ 2) + +This is handled in the Kanban card template using conditional rendering: + +{% tabs %} +{% highlight %} + +if (card.Category == "Delivered" || card.Category == "Served") +{ +
Delivered
+ if (ShowScore) + { + +
+
+
@card.Emoji
+
+ + } +} + +{% endhighlight %} +{% endtabs %} + +## Sample Code + +A complete working example is available in the [Syncfusion Blazor AI Samples GitHub repository](https://github.com/syncfusion/smart-ai-samples). + +![Kanban AI Assistant - Output](../../ai/images/sentiment-analysis.png) + ## Error Handling and Troubleshooting If the AI service fails to return a valid response, the Kanban will display an error message ("Oops! Please try again!"). Common issues include: @@ -532,8 +458,3 @@ If the AI service fails to return a valid response, the Kanban will display an e - **Network Issues**: Check connectivity to the AI service endpoint, especially for self-hosted Ollama instances. - **Large Prompts**: Processing large text inputs may cause timeouts. Consider reducing the prompt size or optimizing the request for efficiency. -## Sample Code - -A complete working example is available in the [Syncfusion Blazor AI Samples GitHub repository](https://github.com/syncfusion/smart-ai-samples). - -![Kanban AI Assistant - Output](../../ai/images/sentiment-analysis.png) \ No newline at end of file