diff --git a/blazor-toc.html b/blazor-toc.html index 6789609612..6c884531ca 100644 --- a/blazor-toc.html +++ b/blazor-toc.html @@ -5000,9 +5000,9 @@
|
- |
-
-
-
+
+
+ }
+
+
+
-```
+{% 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
-
-
-
- @card.Title
-
-
-
|
+ if (ShowScore)
+ {
+ Delivered
+ |
+ }
+}
+
+{% 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).
-
\ No newline at end of file
+
+
+## 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:
+
+- **Invalid API Key or Endpoint**: Verify that the `openAIApiKey`, `azureOpenAIKey`, or Ollama `Endpoint` is correct and the service is accessible.
+- **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.
+
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..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
@@ -228,342 +228,215 @@ 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 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.
-(`Home.razor`)
+### UI Structure
+
+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.
+
+- **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.
+
+{% tabs %}
+{% highlight %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{% endhighlight %}
+{% endtabs %}
+
+### Generating Tasks with AI
+
+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.
+
+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()
{
-
-
+ 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
-
-
-
-
-
- AI Smart Task Suggestion-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- @if (showBacklogs)
- {
-
-
-}
-Kanban Board-
-
-
-
-
+
-
+
- if (!showBacklogBoard)
- {
-
+
@card.Title
-
- }
- else if (showBacklogBoard)
- {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- }
- }
-
-
- }
-
-
-
-
-
- @card.Title
-
-
-
- @card.Description
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
- @card.Description
-
-
-
+ }
+
+
+
+
+{% 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 %}
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
-
+
+
+
+
+
+
+ @if (this.enableRephraseChips)
+ {
+
+
-
+ Target Language
+
+
+
+
-
- @if (this.enableRephraseChips)
- {
-
+ }
- Target Language
-
-
-
- }
-
-
-
+
+
-
+
+
+
+
+ @if (!isContentGenerating)
+ {
+ @if (noResultsFound)
{
- @if (noResultsFound)
- {
-
+
+
- @if (!isContentGenerating)
+
-
- }
- else {
-
-
-
-
-
- No results found
-
-
-
-
-
+
+ }
+ else {
+
- }
- } else {
+
+
+
No results found
-
-
+
+ - - - - -
-
+ } else {
+
+
+
+
-
+
+
+ + + + +
- @if (!string.IsNullOrEmpty(sentiment)) {
-
- }
-
+
+
+
+
-
+
-
-
-
+
+
+ @if (!string.IsNullOrEmpty(sentiment)) {
+
+ }
+
+
+ Integrate AI with the EditorIntegrate 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. SummarizeThis function condenses the selected content into a brief summary, capturing the main points succinctly. ElaborateThis function expands the selected content, adding additional details and context. RephraseThis 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 GrammarThis function reviews and corrects the grammar of the selected content, ensuring it adheres to standard grammatical rules. TranslateThis 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 | ||||||||||||||||||||||||||||||||||||||||||||||