diff --git a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/AiService.cs b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/AiService.cs new file mode 100644 index 0000000..d35919c --- /dev/null +++ b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/AiService.cs @@ -0,0 +1,261 @@ +using Microsoft.Extensions.Configuration; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; + +namespace Telerik.Examples.Mvc.Controllers +{ + public class AiService + { + private readonly HttpClient _http; + private readonly string _apiKey; + private readonly string _endpoint; + private readonly string _deployment; + + public AiService(IConfiguration config) + { + _http = new HttpClient(); + _apiKey = config["OpenAI:ApiKey"]; + _endpoint = config["OpenAI:Endpoint"]; + _deployment = config["OpenAI:DeploymentName"]; + } + + private async Task SendAsync(string url, object payload) + { + _http.DefaultRequestHeaders.Clear(); + _http.DefaultRequestHeaders.Add("api-key", _apiKey); + + var content = new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json"); + var response = await _http.PostAsync(url, content); + var text = await response.Content.ReadAsStringAsync(); + + if (!response.IsSuccessStatusCode) + return $"Azure OpenAI API error: {response.StatusCode}"; + + var json = JObject.Parse(text); + return json["choices"]?[0]?["message"]?["content"]?.ToString()?.Trim() ?? ""; + } + + public async Task ProcessAsync(string prompt) + { + try + { + var url = $"{_endpoint}openai/deployments/{_deployment}/chat/completions?api-version=2024-02-15-preview"; + var payload = new + { + messages = new[] + { + new { role = "system", content = "You are a helpful assistant." }, + new { role = "user", content = prompt } + }, + temperature = 0.3, + max_tokens = 1500 + }; + + return await SendAsync(url, payload); + } + catch + { + return "AI configuration missing"; + } + } + + public async Task AnalyzeGridDataAsync(string instructions, string gridDataJson) + { + var systemPrompt = @" + You are an AI assistant analyzing Kendo UI Grid data. + + You ALWAYS receive: + 1) The full raw data (JSON array) + 2) A user question + + RULES: + 1. If the user explicitly asks for filtering or sorting: + Return ONLY a JSON object such as: + { ""action"": ""filter"", ""field"": ""Month"", ""operator"": ""eq"", ""value"": ""July"" } + + or: + + { ""action"": ""sort"", ""field"": ""Total"", ""dir"": ""desc"" } + + 2. For ALL OTHER QUESTIONS: + Return a short natural language answer using ONLY the supplied data. + + No code, no markdown, no explanations. + "; + + try + { + var url = $"{_endpoint}openai/deployments/{_deployment}/chat/completions?api-version=2024-02-15-preview"; + var payload = new + { + messages = new[] + { + new { role = "system", content = systemPrompt }, + new { role = "user", content = $"Grid Data:\n{gridDataJson}" }, + new { role = "user", content = $"Question:\n{instructions}" } + }, + temperature = 0.3, + max_tokens = 1500 + }; + + return await SendAsync(url, payload); + } + catch + { + return "AI configuration missing"; + } + } + + public async Task EditTextAsync(string text, string instruction) + { + try + { + var url = $"{_endpoint}openai/deployments/{_deployment}/chat/completions?api-version=2024-02-15-preview"; + var payload = new + { + messages = new[] + { + new + { + role = "system", + content = + "You are an AI text editor. Modify the text ONLY according to the user's instruction while preserving existing formatting. " + + "If the user requests color, bold, or styles, return the text wrapped in proper HTML inline styles (e.g., text). " + + "Do not apply additional formatting unless explicitly requested." + }, + new + { + role = "user", + content = + $"Modify this text:\n\n{text}\n\nInstruction: {instruction}\n\nReturn the modified text as valid HTML with inline styles only if formatting changes are required." + } + }, + temperature = 0.3, + max_tokens = 500 + }; + + return await SendAsync(url, payload); + } + catch + { + return "AI configuration missing"; + } + } + + public async Task GenerateChartConfigAsync(string instructions) + { + var url = $"{_endpoint}openai/deployments/{_deployment}/chat/completions?api-version=2024-02-15-preview"; + + var payload = new + { + messages = new[] + { + new { role = "system", content = "Return ONLY valid JSON for a Kendo UI Chart." }, + new { role = "user", content = $"Generate a Kendo UI Chart JSON configuration. Instructions: {instructions}" } + }, + temperature = 0.2, + max_tokens = 600 + }; + + var raw = await SendAsync(url, payload); + if (string.IsNullOrWhiteSpace(raw)) return "{}"; + + string config = raw.Trim(); + + int start = config.IndexOf('{'); + int end = config.LastIndexOf('}'); + if (start >= 0 && end > start) + config = config.Substring(start, end - start + 1); + + try + { + JObject.Parse(config); + return config; + } + catch + { + config = config.Replace(",]", "]").Replace(",}", "}"); + try + { + JObject.Parse(config); + return config; + } + catch + { + return "{}"; + } + } + } + + public async Task GenerateSchedulerConfigAsync(string instructions) + { + var url = $"{_endpoint}openai/deployments/{_deployment}/chat/completions?api-version=2024-02-15-preview"; + + var systemPrompt = @" + Return ONLY valid JSON for a Kendo UI Scheduler. + + The JSON object MUST contain: + { + ""date"": ""2025-01-10T00:00:00Z"", + ""events"": [ + { + ""id"": 1, + ""title"": ""Design Review"", + ""start"": ""2025-01-10T10:00:00Z"", + ""end"": ""2025-01-10T11:00:00Z"" + } + ] + } + + RULES: + - Convert all dates into ISO UTC strings. + - The 'events' array must contain the tasks created or modified. + - Do NOT include Kendo configuration like views or transport. + "; + + var payload = new + { + messages = new[] + { + new { role = "system", content = systemPrompt }, + new { role = "user", content = instructions } + }, + temperature = 0.2, + max_tokens = 600 + }; + + var raw = await SendAsync(url, payload); + if (string.IsNullOrWhiteSpace(raw)) return "{}"; + + string config = raw.Trim(); + + int start = config.IndexOf("{"); + int end = config.LastIndexOf("}"); + if (start >= 0 && end > start) + config = config.Substring(start, end - start + 1); + + try + { + JObject.Parse(config); + return config; + } + catch + { + config = config.Replace(",]", "]").Replace(",}", "}"); + try + { + JObject.Parse(config); + return config; + } + catch + { + return "{}"; + } + } + } + } +} diff --git a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/Chart/SmartChartController.cs b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/Chart/SmartChartController.cs new file mode 100644 index 0000000..99853c7 --- /dev/null +++ b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/Chart/SmartChartController.cs @@ -0,0 +1,49 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System; +using System.Threading.Tasks; + +namespace Telerik.Examples.Mvc.Controllers.Chart +{ + public class SmartChartController : Controller + { + private readonly AiService _chartService; + private readonly ILogger _logger; + + public SmartChartController(AiService chartService, ILogger logger) + { + _chartService = chartService; + _logger = logger; + } + + [HttpPost] + [Route("SmartChart/GenerateChart")] + public async Task GenerateChart([FromBody] ChartRequest request) + { + if (string.IsNullOrWhiteSpace(request.Instructions)) + return BadRequest("Instructions cannot be empty."); + + try + { + var chartConfig = await _chartService.GenerateChartConfigAsync(request.Instructions); + return Json(new { config = chartConfig }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error generating chart"); + return StatusCode(500, new { error = ex.Message }); + } + } + + [HttpGet] + public IActionResult SmartChart() + { + return View(); + } + } + + public class ChartRequest + { + public string Instructions { get; set; } + } +} diff --git a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/Chat/AiService.cs b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/Chat/AiService.cs deleted file mode 100644 index 66b188c..0000000 --- a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/Chat/AiService.cs +++ /dev/null @@ -1,53 +0,0 @@ -using Microsoft.Extensions.Configuration; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; - -namespace Telerik.Examples.Mvc.Controllers.Chat -{ - public class AiService - { - private readonly HttpClient _http; - private readonly string _apiKey; - private readonly string _endpoint; - private readonly string _deployment; - - public AiService(IConfiguration config) - { - _http = new HttpClient(); - _apiKey = config["OpenAI:ApiKey"]; - _endpoint = config["OpenAI:Endpoint"]; - _deployment = config["OpenAI:DeploymentName"]; - } - - public async Task ProcessAsync(string prompt) - { - var url = $"{_endpoint}openai/deployments/{_deployment}/chat/completions?api-version=2024-02-15-preview"; - var payload = new - { - messages = new[] - { - new { role = "system", content = "You are a helpful assistant." }, - new { role = "user", content = prompt } - }, - temperature = 0.3, - max_tokens = 1500 - }; - - _http.DefaultRequestHeaders.Clear(); - _http.DefaultRequestHeaders.Add("api-key", _apiKey); - - var content = new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json"); - var response = await _http.PostAsync(url, content); - var text = await response.Content.ReadAsStringAsync(); - - if (!response.IsSuccessStatusCode) - return $"Azure OpenAI API error: {response.StatusCode}"; - - var json = JObject.Parse(text); - return json["choices"]?[0]?["message"]?["content"]?.ToString()?.Trim() ?? ""; - } - } -} diff --git a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/Editor/SmartEditorController.cs b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/Editor/SmartEditorController.cs new file mode 100644 index 0000000..e94eb18 --- /dev/null +++ b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/Editor/SmartEditorController.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Telerik.Examples.Mvc.Models; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace Telerik.Examples.Mvc.Controllers.Editor +{ + public class SmartEditorController : Controller + { + private readonly AiService _smartEditorService; + + public SmartEditorController(AiService smartEditorService) + { + _smartEditorService = smartEditorService; + } + + public IActionResult SmartEditor() + { + return View(); + } + + [HttpPost] + [Route("api/smarteditor/edit")] + public async Task EditText([FromBody] EditRequest request) + { + if (string.IsNullOrEmpty(request.Text) || string.IsNullOrEmpty(request.Instruction)) + return BadRequest("Both text and instruction are required."); + + var revisedText = await _smartEditorService.EditTextAsync(request.Text, request.Instruction); + return Ok(new { Suggestions = revisedText }); + } + } + + public class EditRequest + { + public string Text { get; set; } + public string Instruction { get; set; } + } +} \ No newline at end of file diff --git a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/Grid/SmartGridController.cs b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/Grid/SmartGridController.cs new file mode 100644 index 0000000..946d48c --- /dev/null +++ b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/Grid/SmartGridController.cs @@ -0,0 +1,74 @@ +using Kendo.Mvc.Extensions; +using Kendo.Mvc.UI; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Threading.Tasks; +using Telerik.Examples.Mvc.Models; + +namespace Telerik.Examples.Mvc.Controllers.Grid +{ + public class SmartGridController : Controller + { + private readonly AiService _smartGridService; + + public SmartGridController(AiService smartGridService) + { + _smartGridService = smartGridService; + } + + public IActionResult SmartGrid() + { + return View(); + } + + [HttpPost] + public IActionResult GetSales([DataSourceRequest] DataSourceRequest request) + { + return Json(GetFullSalesData().ToDataSourceResult(request)); + } + + [HttpPost] + public async Task Analyze([FromBody] GridAnalysisRequest request) + { + var result = await _smartGridService.AnalyzeGridDataAsync(request.Instructions, request.GridJson); + return Json(new { result }); + } + + private List GetFullSalesData() + { + return new List + { + new SaleRecord { Id = 1, SalesPerson = "Alice", Region = "North", UnitsSold = 120, Total = 24000, Month = "January" }, + new SaleRecord { Id = 2, SalesPerson = "Bob", Region = "South", UnitsSold = 80, Total = 16000, Month = "January" }, + new SaleRecord { Id = 3, SalesPerson = "Charlie", Region = "West", UnitsSold = 150, Total = 30000, Month = "February" }, + new SaleRecord { Id = 4, SalesPerson = "Alice", Region = "North", UnitsSold = 130, Total = 26000, Month = "February" }, + new SaleRecord { Id = 5, SalesPerson = "Bob", Region = "South", UnitsSold = 90, Total = 18000, Month = "March" }, + new SaleRecord { Id = 6, SalesPerson = "Charlie", Region = "West", UnitsSold = 170, Total = 34000, Month = "March" }, + new SaleRecord { Id = 7, SalesPerson = "Alice", Region = "East", UnitsSold = 100, Total = 20000, Month = "April" }, + new SaleRecord { Id = 8, SalesPerson = "David", Region = "South", UnitsSold = 75, Total = 15000, Month = "April" }, + new SaleRecord { Id = 9, SalesPerson = "Eva", Region = "North", UnitsSold = 110, Total = 22000, Month = "May" }, + new SaleRecord { Id = 10, SalesPerson = "Bob", Region = "South", UnitsSold = 95, Total = 19000, Month = "May" }, + new SaleRecord { Id = 11, SalesPerson = "Charlie", Region = "West", UnitsSold = 160, Total = 32000, Month = "June" }, + new SaleRecord { Id = 12, SalesPerson = "Alice", Region = "East", UnitsSold = 115, Total = 23000, Month = "June" }, + new SaleRecord { Id = 13, SalesPerson = "David", Region = "North", UnitsSold = 105, Total = 21000, Month = "July" }, + new SaleRecord { Id = 14, SalesPerson = "Eva", Region = "West", UnitsSold = 135, Total = 27000, Month = "July" }, + new SaleRecord { Id = 15, SalesPerson = "Alice", Region = "East", UnitsSold = 125, Total = 25000, Month = "August" }, + new SaleRecord { Id = 16, SalesPerson = "Charlie", Region = "South", UnitsSold = 140, Total = 28000, Month = "August" }, + new SaleRecord { Id = 17, SalesPerson = "David", Region = "North", UnitsSold = 100, Total = 20000, Month = "September" }, + new SaleRecord { Id = 18, SalesPerson = "Bob", Region = "West", UnitsSold = 155, Total = 31000, Month = "September" }, + new SaleRecord { Id = 19, SalesPerson = "Eva", Region = "South", UnitsSold = 85, Total = 17000, Month = "October" }, + new SaleRecord { Id = 20, SalesPerson = "Charlie", Region = "East", UnitsSold = 145, Total = 29000, Month = "October" } + }; + } + + public class GridAnalysisRequest + { + public string Instructions { get; set; } + public string GridJson { get; set; } + } + } +} diff --git a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/Scheduler/SmartSchedulerController.cs b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/Scheduler/SmartSchedulerController.cs new file mode 100644 index 0000000..8ea1af0 --- /dev/null +++ b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Controllers/Scheduler/SmartSchedulerController.cs @@ -0,0 +1,50 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System; +using System.Threading.Tasks; +using Telerik.Examples.Mvc.Controllers; + +namespace Telerik.Examples.Mvc.Controllers.Scheduler +{ + public class SmartSchedulerController : Controller + { + private readonly AiService _aiService; + private readonly ILogger _logger; + + public SmartSchedulerController(AiService aiService, ILogger logger) + { + _aiService = aiService; + _logger = logger; + } + + [HttpPost] + [Route("SmartScheduler/GenerateSchedule")] + public async Task GenerateSchedule([FromBody] SchedulerRequest request) + { + if (string.IsNullOrWhiteSpace(request.Instructions)) + return BadRequest("Instructions cannot be empty."); + + try + { + var config = await _aiService.GenerateSchedulerConfigAsync(request.Instructions); + return Json(new { config }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Scheduler generation error"); + return StatusCode(500, new { error = ex.Message }); + } + } + + [HttpGet] + public IActionResult SmartScheduler() + { + return View(); + } + } + + public class SchedulerRequest + { + public string Instructions { get; set; } + } +} diff --git a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Models/SaleRecord.cs b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Models/SaleRecord.cs new file mode 100644 index 0000000..3937861 --- /dev/null +++ b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Models/SaleRecord.cs @@ -0,0 +1,12 @@ +namespace Telerik.Examples.Mvc.Models +{ + public class SaleRecord + { + public int Id { get; set; } + public string SalesPerson { get; set; } + public string Region { get; set; } + public int UnitsSold { get; set; } + public decimal Total { get; set; } + public string Month { get; set; } + } +} diff --git a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Program.cs b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Program.cs index f22ae9f..7cf9221 100644 --- a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Program.cs +++ b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Program.cs @@ -22,7 +22,7 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using Telerik.Examples.Mvc.Controllers.Chat; +using Telerik.Examples.Mvc.Controllers; using Telerik.Examples.Mvc.Database; using Telerik.Examples.Mvc.Hubs; using Telerik.Examples.Mvc.Models; @@ -67,6 +67,7 @@ options.ViewLocationFormats.Add("/Views/Captcha/{0}" + RazorViewEngine.ViewExtension); options.ViewLocationFormats.Add("/Views/chat/{0}" + RazorViewEngine.ViewExtension); options.ViewLocationFormats.Add("/Views/Grid/{0}" + RazorViewEngine.ViewExtension); + options.ViewLocationFormats.Add("/Views/Charts/{0}" + RazorViewEngine.ViewExtension); options.ViewLocationFormats.Add("/Views/ImageEditor/{0}" + RazorViewEngine.ViewExtension); options.ViewLocationFormats.Add("/Views/Editor/{0}" + RazorViewEngine.ViewExtension); options.ViewLocationFormats.Add("/Views/Forms/{0}" + RazorViewEngine.ViewExtension); diff --git a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Views/Charts/SmartChart.cshtml b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Views/Charts/SmartChart.cshtml new file mode 100644 index 0000000..a09ff54 --- /dev/null +++ b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Views/Charts/SmartChart.cshtml @@ -0,0 +1,132 @@ +
+ Try one of these examples: +
    +
  • + • Generate a Kendo UI Bar Chart showing the latest global smartphone vendor market share using data from https://www.statista.com/statistics/271496/global-market-share-held-by-smartphone-vendors/. +
  • +
  • + • Create a Kendo UI Line Chart showing historical unemployment rate in the European Union from https://tradingeconomics.com/european-union/unemployment-rate. +
  • +
  • + • Generate a Kendo UI Pie Chart using the latest Global browser market share data from https://gs.statcounter.com/browser-market-share. Only use desktop and mobile combined. +
  • +
+
+ +@(Html.Kendo().TextArea() + .Name("chartInstructions") + .Placeholder("Enter your chart instructions here...") + .Rows(10) + .Rounded(Rounded.Medium) + .MaxLength(200) + .HtmlAttributes(new + { + style = "width: 60%", + required = true, + data_required_msg = "Please enter a text.", + data_max_msg = "Enter value between 1 and 200" + }) +) + +
+
+ +@(Html.Kendo().Button() + .Name("generateChart") + .ThemeColor(ThemeColor.Success) + .Content("Generate Chart") +) + +
+
+
+ + + + diff --git a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Views/Editor/SmartEditor.cshtml b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Views/Editor/SmartEditor.cshtml new file mode 100644 index 0000000..e0f6ed3 --- /dev/null +++ b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Views/Editor/SmartEditor.cshtml @@ -0,0 +1,177 @@ +@{ + ViewData["Title"] = "Smart AI Editor"; +} + + + +
+

Smart AI-Powered Editor

+ +
+ @(Html.Kendo().Editor() + .Name("textEditor") + .Tools(tools => tools + .Clear().Bold().Italic().Underline() + .InsertUnorderedList().InsertOrderedList() + .FontSize().ForeColor().BackColor() + .CustomButton(c => c.Name("aiEditorButton") + .Tooltip("Improve with AI") + .Exec("openAIWindow") + .Icon("none") + ) + ) + .Value("I am a Smart AI-Powered Editor") + .HtmlAttributes(new { style = "width:100%; height:300px;" }) + ) +
+ + @(Html.Kendo().Window() + .Name("window") + .Title("Smart AI Editor") + .Visible(false) + .Content(@ +

AI-Powered Refinement

+

Describe how you want AI to improve the text and click 'Refine with AI'.

+ + + + @(Html.Kendo().Button() + .Name("aiEditButton") + .ThemeColor(ThemeColor.Success) + .Content("Refine with AI") + ) +
) + .Width(600) + .Position(p => p.Top(450).Left(650)) + .Actions(actions => actions.Pin().Minimize().Maximize().Close()) + .Events(e => e.Open("onWindowOpen").Close("onWindowClose")) + ) + +
+ + + + + + + + + diff --git a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Views/Grid/SmartGrid.cshtml b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Views/Grid/SmartGrid.cshtml new file mode 100644 index 0000000..31dd44b --- /dev/null +++ b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Views/Grid/SmartGrid.cshtml @@ -0,0 +1,153 @@ +@{ + ViewData["Title"] = "AI Grid Insights"; +} + +

Sales Data Grid + AI Insights

+ +@(Html.Kendo().Grid() + .Name("salesGrid") + .Columns(columns => + { + columns.Bound(c => c.Id).Width(80); + columns.Bound(c => c.SalesPerson); + columns.Bound(c => c.Region); + columns.Bound(c => c.UnitsSold); + columns.Bound(c => c.Total); + columns.Bound(c => c.Month); + }) + .Scrollable(s => s.Height("300px")) + .DataSource(ds => ds.Ajax() + .Read(read => read.Url("/SmartGrid/GetSales")) + ) + .Sortable() + .Filterable() +) + +
+ + +
    +
  • Which salesperson has the highest total sales?
  • +
  • What is the average units sold per region?
  • +
  • Show the month with the lowest performance.
  • +
  • Sort the grid by Total descending
  • +
  • Filter to only show data from July
  • +
  • Show only rows where Units Sold is greater than 130
  • +
  • What is the total revenue by month?
  • +
  • How many units did Alice sell in total?
  • +
+ + + @(Html.Kendo().TextArea() + .Name("instructionBox") + .Placeholder("e.g. Which region had the lowest total?") + .Rows(4) + .HtmlAttributes(new { style = "width:100%; background-color:#1f1f1f; color:white;", @class = "k-textbox" }) + ) + +
+ @(Html.Kendo().Button() + .Name("analyzeButton") + .Content("Analyze") + .ThemeColor(ThemeColor.Success) + .HtmlAttributes(new { onclick = "analyzeGrid()" }) + ) +
+
+ +
+ AI Response: +
+
+ +@section scripts { + +} + + diff --git a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Views/Scheduler/SmartScheduler.cshtml b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Views/Scheduler/SmartScheduler.cshtml new file mode 100644 index 0000000..6154136 --- /dev/null +++ b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/Views/Scheduler/SmartScheduler.cshtml @@ -0,0 +1,107 @@ +
+ Try one of these examples: +
    +
  • • Add three meetings on December 10, 2025: design review at 10:00, sprint planning at 13:00, and QA sync at 16:00.
  • +
  • • Create a team event on December 15, 2025 from 09:00 to 17:00 titled Development Day.
  • +
  • • Schedule a recurring daily stand-up from December 1 to December 7, 2025 at 09:30.
  • +
+
+ + +@(Html.Kendo().TextArea() + .Name("schedulerInstructions") + .Placeholder("Enter your scheduling instructions here...") + .Rows(8) + .Rounded(Rounded.Medium) + .MaxLength(300) + .HtmlAttributes(new { + style="width:60%", + required=true, + data_required_msg="Please enter a description.", + data_max_msg="Maximum length is 300 characters." + }) +) + +

+ +@(Html.Kendo().Button() + .Name("generateSchedule") + .ThemeColor(ThemeColor.Success) + .Content("Generate Schedule") +) + +
+ +
+ @(Html.Kendo().Scheduler() + .Name("scheduler") + .StartTime(6,30,0) + .Height(600) + .WorkWeekStart(1) + .WorkWeekEnd(7) + .Views(v => { + v.DayView(); + v.WorkWeekView(); + v.WeekView(); + v.MonthView(m => m.Selected(true)); + v.AgendaView(); + v.TimelineView(); + }) + .Timezone("Etc/UTC") + .DataSource(d => d + .Model(m => { + m.Id(f => f.TaskID); + m.Field(f => f.Title).DefaultValue("No title"); + m.RecurrenceId(f => f.RecurrenceID); + }) + .Read(r => r.Action("Read", "SchedulerServerFiltering")) + .Create("Create", "SchedulerServerFiltering") + .Update("Update", "SchedulerServerFiltering") + .Destroy("Destroy", "SchedulerServerFiltering") + ) + ) +
+ + diff --git a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/appsettings.json b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/appsettings.json index 4153b50..af80f9e 100644 --- a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/appsettings.json +++ b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/appsettings.json @@ -11,9 +11,12 @@ }, "OpenAI": { "UseAzure": true, + //"ApiKey": "your-api-key", "ApiKey": "", - "Endpoint": "", - "DeploymentName": "" + //"Endpoint": "your-end-point", + "Endpoint": "your-end-point", + //"DeploymentName": "your-deployment-name", + "DeploymentName": "your-deployment-name" }, "AllowedHosts": "*" } diff --git a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/wwwroot/files/ExamplesEndpoints.txt b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/wwwroot/files/ExamplesEndpoints.txt index b29ca22..93b62d5 100644 --- a/Telerik.Examples.Mvc/Telerik.Examples.Mvc/wwwroot/files/ExamplesEndpoints.txt +++ b/Telerik.Examples.Mvc/Telerik.Examples.Mvc/wwwroot/files/ExamplesEndpoints.txt @@ -1 +1 @@ -[{"ComponentName":"TreeList","ActionName":"TreeListODataBinding","ControllerName":"TreeListODataBinding"},{"ComponentName":"StylesAndLayout","ActionName":"ClientThemeChange","ControllerName":"ClientThemeChange"},{"ComponentName":"Spreadsheet","ActionName":"Spreadsheet_Load_Xlsx_From_Server","ControllerName":"Spreadsheet_Load_Xlsx_From_Server"},{"ComponentName":"Scheduler","ActionName":"SchedulerCustomEdit","ControllerName":"SchedulerCustomEdit"},{"ComponentName":"Scheduler","ActionName":"SchedulerGoogleCalendar","ControllerName":"SchedulerGoogleCalendar"},{"ComponentName":"Scheduler","ActionName":"SchedulerServerFiltering","ControllerName":"SchedulerServerFiltering"},{"ComponentName":"Scheduler","ActionName":"SchedulerSignalR","ControllerName":"SchedulerSignalR"},{"ComponentName":"Scheduler","ActionName":"SchedulerSqlServerBinding","ControllerName":"SchedulerSqlServerBinding"},{"ComponentName":"MultiSelect","ActionName":"Cascading_MultiSelect","ControllerName":"Cascading_MultiSelect"},{"ComponentName":"MultiSelect","ActionName":"MultiSelectPost","ControllerName":"MultiSelectPost"},{"ComponentName":"MultiSelect","ActionName":"MultiSelectPost","ControllerName":"MultiSelectPost"},{"ComponentName":"Menu","ActionName":"SecurityTrimming","ControllerName":"SecurityTrimming"},{"ComponentName":"ListBox","ActionName":"RemoteBinding","ControllerName":"RemoteBinding"},{"ComponentName":"ImageEditor","ActionName":"ImageEditorSave","ControllerName":"ImageEditorSave"},{"ComponentName":"ImageEditor","ActionName":"ImageEditorSave","ControllerName":"ImageEditorSave"},{"ComponentName":"Grid","ActionName":"AjaxBinding","ControllerName":"AjaxBinding"},{"ComponentName":"Grid","ActionName":"AjaxEditing","ControllerName":"AjaxEditing"},{"ComponentName":"Grid","ActionName":"AlternatingRows","ControllerName":"AlternatingRows"},{"ComponentName":"Grid","ActionName":"AsynchronousBindingWithCancellationToken","ControllerName":"AsynchronousBindingWithCancellationToken"},{"ComponentName":"Grid","ActionName":"AudioColumn","ControllerName":"AudioColumn"},{"ComponentName":"Grid","ActionName":"AutocompleteEditorAllowSettingNewValues","ControllerName":"AutocompleteEditorAllowSettingNewValues"},{"ComponentName":"Grid","ActionName":"CustomDataSource","ControllerName":"CustomDataSource"},{"ComponentName":"Grid","ActionName":"CustomPopUpEditor","ControllerName":"CustomPopUpEditor"},{"ComponentName":"Grid","ActionName":"CustomPopUpEditorTagHelper","ControllerName":"CustomPopUpEditorTagHelper"},{"ComponentName":"Grid","ActionName":"DefiningColumnFormat","ControllerName":"DefiningColumnFormat"},{"ComponentName":"Grid","ActionName":"DragAndDropBetweenGrids","ControllerName":"DragAndDropBetweenGrids"},{"ComponentName":"Grid","ActionName":"DynamicBatchEditing","ControllerName":"DynamicBatchEditing"},{"ComponentName":"Grid","ActionName":"Dynamic","ControllerName":"Dynamic"},{"ComponentName":"Grid","ActionName":"DynamicPopupEditing","ControllerName":"DynamicPopupEditing"},{"ComponentName":"Grid","ActionName":"EditingWithCascadingDropDownLists","ControllerName":"EditingWithCascadingDropDownLists"},{"ComponentName":"Grid","ActionName":"EnableOperationsForObjectColumn","ControllerName":"EnableOperationsForObjectColumn"},{"ComponentName":"Grid","ActionName":"EncodedForeignKeyValues","ControllerName":"EncodedForeignKeyValues"},{"ComponentName":"Grid","ActionName":"GridInlineEditingWithNullableBoolean","ControllerName":"GridInlineEditingWithNullableBoolean"},{"ComponentName":"Grid","ActionName":"GridODataBinding","ControllerName":"GridODataBinding"},{"ComponentName":"Grid","ActionName":"Grid_SignalR","ControllerName":"Grid_SignalR"},{"ComponentName":"Grid","ActionName":"HierarchyCrud","ControllerName":"HierarchyCrud"},{"ComponentName":"Grid","ActionName":"HierarchySignalR","ControllerName":"HierarchySignalR"},{"ComponentName":"Grid","ActionName":"Hierarchy_Persist_Expanded_Children","ControllerName":"Hierarchy_Persist_Expanded_Children"},{"ComponentName":"Grid","ActionName":"ListBoxAsEditor","ControllerName":"ListBoxAsEditor"},{"ComponentName":"Grid","ActionName":"MinimalAPI","ControllerName":"MinimalAPI"},{"ComponentName":"Grid","ActionName":"MultiSelectAsEditor","ControllerName":"MultiSelectAsEditor"},{"ComponentName":"Grid","ActionName":"ToggleEditMode","ControllerName":"ToggleEditMode"},{"ComponentName":"Grid","ActionName":"ViewComponent","ControllerName":"ViewComponent"},{"ComponentName":"FormIndex","ActionName":"FormIndex","ControllerName":"FormIndex"},{"ComponentName":"Editor","ActionName":"EditorContent","ControllerName":"EditorContent"},{"ComponentName":"Editor","ActionName":"Editor_Header_And_Footer_Simulation","ControllerName":"Editor_Header_And_Footer_Simulation"},{"ComponentName":"DropDownList","ActionName":"AddItem","ControllerName":"AddItem"},{"ComponentName":"DateTimeOffset","ActionName":"DateTimeOffset","ControllerName":"DateTimeOffset"},{"ComponentName":"Chat","ActionName":"ChatAiIntegration","ControllerName":"ChatAiIntegration"},{"ComponentName":"Chat","ActionName":"ChatPeerToPeer","ControllerName":"ChatPeerToPeer"},{"ComponentName":"Captcha","ActionName":"CaptchaOverview","ControllerName":"CaptchaOverview"}] \ No newline at end of file +[{"ComponentName":"TreeList","ActionName":"TreeListODataBinding","ControllerName":"TreeListODataBinding"},{"ComponentName":"StylesAndLayout","ActionName":"ClientThemeChange","ControllerName":"ClientThemeChange"},{"ComponentName":"Spreadsheet","ActionName":"Spreadsheet_Load_Xlsx_From_Server","ControllerName":"Spreadsheet_Load_Xlsx_From_Server"},{"ComponentName":"Scheduler","ActionName":"SchedulerCustomEdit","ControllerName":"SchedulerCustomEdit"},{"ComponentName":"Scheduler","ActionName":"SchedulerGoogleCalendar","ControllerName":"SchedulerGoogleCalendar"},{"ComponentName":"Scheduler","ActionName":"SchedulerServerFiltering","ControllerName":"SchedulerServerFiltering"},{"ComponentName":"Scheduler","ActionName":"SchedulerSignalR","ControllerName":"SchedulerSignalR"},{"ComponentName":"Scheduler","ActionName":"SchedulerSqlServerBinding","ControllerName":"SchedulerSqlServerBinding"},{"ComponentName":"Scheduler","ActionName":"SmartScheduler","ControllerName":"SmartScheduler"},{"ComponentName":"MultiSelect","ActionName":"Cascading_MultiSelect","ControllerName":"Cascading_MultiSelect"},{"ComponentName":"MultiSelect","ActionName":"MultiSelectPost","ControllerName":"MultiSelectPost"},{"ComponentName":"MultiSelect","ActionName":"MultiSelectPost","ControllerName":"MultiSelectPost"},{"ComponentName":"Menu","ActionName":"SecurityTrimming","ControllerName":"SecurityTrimming"},{"ComponentName":"ListBox","ActionName":"RemoteBinding","ControllerName":"RemoteBinding"},{"ComponentName":"ImageEditor","ActionName":"ImageEditorSave","ControllerName":"ImageEditorSave"},{"ComponentName":"ImageEditor","ActionName":"ImageEditorSave","ControllerName":"ImageEditorSave"},{"ComponentName":"Grid","ActionName":"AjaxBinding","ControllerName":"AjaxBinding"},{"ComponentName":"Grid","ActionName":"AjaxEditing","ControllerName":"AjaxEditing"},{"ComponentName":"Grid","ActionName":"AlternatingRows","ControllerName":"AlternatingRows"},{"ComponentName":"Grid","ActionName":"AsynchronousBindingWithCancellationToken","ControllerName":"AsynchronousBindingWithCancellationToken"},{"ComponentName":"Grid","ActionName":"AudioColumn","ControllerName":"AudioColumn"},{"ComponentName":"Grid","ActionName":"AutocompleteEditorAllowSettingNewValues","ControllerName":"AutocompleteEditorAllowSettingNewValues"},{"ComponentName":"Grid","ActionName":"CustomDataSource","ControllerName":"CustomDataSource"},{"ComponentName":"Grid","ActionName":"CustomPopUpEditor","ControllerName":"CustomPopUpEditor"},{"ComponentName":"Grid","ActionName":"CustomPopUpEditorTagHelper","ControllerName":"CustomPopUpEditorTagHelper"},{"ComponentName":"Grid","ActionName":"DefiningColumnFormat","ControllerName":"DefiningColumnFormat"},{"ComponentName":"Grid","ActionName":"DragAndDropBetweenGrids","ControllerName":"DragAndDropBetweenGrids"},{"ComponentName":"Grid","ActionName":"DynamicBatchEditing","ControllerName":"DynamicBatchEditing"},{"ComponentName":"Grid","ActionName":"Dynamic","ControllerName":"Dynamic"},{"ComponentName":"Grid","ActionName":"DynamicPopupEditing","ControllerName":"DynamicPopupEditing"},{"ComponentName":"Grid","ActionName":"EditingWithCascadingDropDownLists","ControllerName":"EditingWithCascadingDropDownLists"},{"ComponentName":"Grid","ActionName":"EnableOperationsForObjectColumn","ControllerName":"EnableOperationsForObjectColumn"},{"ComponentName":"Grid","ActionName":"EncodedForeignKeyValues","ControllerName":"EncodedForeignKeyValues"},{"ComponentName":"Grid","ActionName":"GridInlineEditingWithNullableBoolean","ControllerName":"GridInlineEditingWithNullableBoolean"},{"ComponentName":"Grid","ActionName":"GridODataBinding","ControllerName":"GridODataBinding"},{"ComponentName":"Grid","ActionName":"Grid_SignalR","ControllerName":"Grid_SignalR"},{"ComponentName":"Grid","ActionName":"HierarchyCrud","ControllerName":"HierarchyCrud"},{"ComponentName":"Grid","ActionName":"HierarchySignalR","ControllerName":"HierarchySignalR"},{"ComponentName":"Grid","ActionName":"Hierarchy_Persist_Expanded_Children","ControllerName":"Hierarchy_Persist_Expanded_Children"},{"ComponentName":"Grid","ActionName":"ListBoxAsEditor","ControllerName":"ListBoxAsEditor"},{"ComponentName":"Grid","ActionName":"MinimalAPI","ControllerName":"MinimalAPI"},{"ComponentName":"Grid","ActionName":"MultiSelectAsEditor","ControllerName":"MultiSelectAsEditor"},{"ComponentName":"Grid","ActionName":"SmartGrid","ControllerName":"SmartGrid"},{"ComponentName":"Grid","ActionName":"ToggleEditMode","ControllerName":"ToggleEditMode"},{"ComponentName":"Grid","ActionName":"ViewComponent","ControllerName":"ViewComponent"},{"ComponentName":"FormIndex","ActionName":"FormIndex","ControllerName":"FormIndex"},{"ComponentName":"Editor","ActionName":"EditorContent","ControllerName":"EditorContent"},{"ComponentName":"Editor","ActionName":"Editor_Header_And_Footer_Simulation","ControllerName":"Editor_Header_And_Footer_Simulation"},{"ComponentName":"Editor","ActionName":"SmartEditor","ControllerName":"SmartEditor"},{"ComponentName":"DropDownList","ActionName":"AddItem","ControllerName":"AddItem"},{"ComponentName":"DateTimeOffset","ActionName":"DateTimeOffset","ControllerName":"DateTimeOffset"},{"ComponentName":"Chat","ActionName":"ChatAiIntegration","ControllerName":"ChatAiIntegration"},{"ComponentName":"Chat","ActionName":"ChatPeerToPeer","ControllerName":"ChatPeerToPeer"},{"ComponentName":"Chart","ActionName":"SmartChart","ControllerName":"SmartChart"},{"ComponentName":"Captcha","ActionName":"CaptchaOverview","ControllerName":"CaptchaOverview"}] \ No newline at end of file