diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/App_Data/NORTHWND.MDF b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/App_Data/NORTHWND.MDF deleted file mode 100644 index 85013d4..0000000 Binary files a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/App_Data/NORTHWND.MDF and /dev/null differ diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/App_Data/NORTHWND_log.ldf b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/App_Data/NORTHWND_log.ldf deleted file mode 100644 index eb3c1e4..0000000 Binary files a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/App_Data/NORTHWND_log.ldf and /dev/null differ diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Controllers/GridController.cs b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Controllers/GridController.cs deleted file mode 100644 index 07c9f96..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Controllers/GridController.cs +++ /dev/null @@ -1,268 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using System.ComponentModel.DataAnnotations; -using System.Data; -using Syncfusion.EJ2.Base; -using Microsoft.Data.SqlClient; // Use the new package - -namespace Grid_MSSQL.Server.Controllers -{ - [ApiController] - public class GridController : ControllerBase - { - string ConnectionString = @""; - - /// - /// Processes the DataManager request to perform searching, filtering, sorting, and paging operations. - /// - /// Contains the details of the data operation requested. - /// Returns a JSON object with the filtered, sorted, and paginated data along with the total record count. - [HttpPost] - [Route("api/[controller]")] - public object Post([FromBody] DataManagerRequest DataManagerRequest) - { - // Retrieve data from the data source (e.g., database). - IQueryable DataSource = GetOrderData().AsQueryable(); - - // Initialize QueryableOperation instance. - QueryableOperation queryableOperation = new QueryableOperation(); - - // Handling searching operation. - if (DataManagerRequest.Search != null && DataManagerRequest.Search.Count > 0) - { - DataSource = queryableOperation.PerformSearching(DataSource, DataManagerRequest.Search); - //Add custom logic here if needed and remove above method. - } - - // Handling filtering operation. - if (DataManagerRequest.Where != null && DataManagerRequest.Where.Count > 0) - { - foreach (WhereFilter condition in DataManagerRequest.Where) - { - foreach (WhereFilter predicate in condition.predicates) - { - DataSource = queryableOperation.PerformFiltering(DataSource, DataManagerRequest.Where, predicate.Operator); - //Add custom logic here if needed and remove above method. - } - } - } - - // Handling sorting operation. - if (DataManagerRequest.Sorted != null && DataManagerRequest.Sorted.Count > 0) - { - DataSource = queryableOperation.PerformSorting(DataSource, DataManagerRequest.Sorted); - //Add custom logic here if needed and remove above method. - } - - // Get the total count of records. - int totalRecordsCount = DataSource.Count(); - - // Handling paging operation. - if (DataManagerRequest.Skip != 0) - { - DataSource = queryableOperation.PerformSkip(DataSource, DataManagerRequest.Skip); - //Add custom logic here if needed and remove above method. - } - if (DataManagerRequest.Take != 0) - { - DataSource = queryableOperation.PerformTake(DataSource, DataManagerRequest.Take); - //Add custom logic here if needed and remove above method. - } - - // Return data based on the request. - return new { result = DataSource, count = totalRecordsCount }; - } - - /// - /// Retrieves the order data from the database. - /// - /// Returns a list of orders fetched from the database. - [HttpGet] - [Route("api/[controller]")] - public List GetOrderData() - { - string queryStr = "SELECT * FROM dbo.Orders ORDER BY OrderID;"; - SqlConnection sqlConnection = new(ConnectionString); - sqlConnection.Open(); - SqlCommand sqlCommand = new(queryStr, sqlConnection); - SqlDataAdapter DataAdapter = new(sqlCommand); - DataTable DataTable = new(); - DataAdapter.Fill(DataTable); - sqlConnection.Close(); - - // Map data to a list. - List dataSource = (from DataRow Data in DataTable.Rows - select new Orders() - { - OrderID = Convert.ToInt32(Data["OrderID"]), - CustomerID = Data["CustomerID"].ToString(), - EmployeeID = Convert.IsDBNull(Data["EmployeeID"]) ? 0 : Convert.ToUInt16(Data["EmployeeID"]), - ShipCity = Data["ShipCity"].ToString(), - Freight = Convert.ToDecimal(Data["Freight"]) - }).ToList(); - return dataSource; - } - - /// - /// Inserts a new data item into the data collection. - /// - /// It contains the new record detail which is need to be inserted. - /// Returns void. - [HttpPost] - [Route("api/[controller]/Insert")] - public void Insert([FromBody] CRUDModel value) - { - //Create query to insert the specific into the database by accessing its properties. - string queryStr = $"Insert into Orders(CustomerID,Freight,ShipCity,EmployeeID) values('{value.value.CustomerID}','{value.value.Freight}','{value.value.ShipCity}','{value.value.EmployeeID}')"; - SqlConnection SqlConnection = new SqlConnection(ConnectionString); - SqlConnection.Open(); - - //Execute the SQL command. - SqlCommand SqlCommand = new SqlCommand(queryStr, SqlConnection); - - //Execute this code to reflect the changes into the database. - SqlCommand.ExecuteNonQuery(); - SqlConnection.Close(); - - //Add custom logic here if needed and remove above method. - } - - /// - /// Update a existing data item from the data collection. - /// - /// It contains the updated record detail which is need to be updated. - /// Returns void. - [HttpPost] - [Route("api/[controller]/Update")] - public void Update([FromBody] CRUDModel value) - { - //Create query to update the changes into the database by accessing its properties. - string queryStr = $"Update Orders set CustomerID='{value.value.CustomerID}', Freight='{value.value.Freight}',EmployeeID='{value.value.EmployeeID}',ShipCity='{value.value.ShipCity}' where OrderID='{value.value.OrderID}'"; - SqlConnection SqlConnection = new SqlConnection(ConnectionString); - SqlConnection.Open(); - - //Execute the SQL command. - SqlCommand SqlCommand = new SqlCommand(queryStr, SqlConnection); - - //Execute this code to reflect the changes into the database. - SqlCommand.ExecuteNonQuery(); - SqlConnection.Close(); - - //Add custom logic here if needed and remove above method. - } - - /// - /// Remove a specific data item from the data collection. - /// - /// It contains the specific record detail which is need to be removed. - /// Returns void. - [HttpPost] - [Route("api/[controller]/Remove")] - public void Remove([FromBody] CRUDModel value) - { - //Create query to remove the specific from database by passing the primary key column value. - string queryStr = $"Delete from Orders where OrderID={value.key}"; - SqlConnection SqlConnection = new SqlConnection(ConnectionString); - SqlConnection.Open(); - - //Execute the SQL command. - SqlCommand SqlCommand = new SqlCommand(queryStr, SqlConnection); - - //Execute this code to reflect the changes into the database. - SqlCommand.ExecuteNonQuery(); - SqlConnection.Close(); - - //Add custom logic here if needed and remove above method. - } - - /// - /// Batch update (Insert, Update, and Delete) a collection of data items from the data collection. - /// - /// The set of information along with details about the CRUD actions to be executed from the database. - /// Returns void. - [HttpPost] - [Route("api/[controller]/BatchUpdate")] - public IActionResult BatchUpdate([FromBody] CRUDModel value) - { - if (value.changed != null && value.changed.Count > 0) - { - foreach (Orders Record in (IEnumerable)value.changed) - { - //Create query to update the changes into the database by accessing its properties. - string queryStr = $"Update Orders set CustomerID='{Record.CustomerID}', Freight='{Record.Freight}',EmployeeID='{Record.EmployeeID}',ShipCity='{Record.ShipCity}' where OrderID='{Record.OrderID}'"; - SqlConnection SqlConnection = new SqlConnection(ConnectionString); - SqlConnection.Open(); - - //Execute the SQL command. - SqlCommand SqlCommand = new SqlCommand(queryStr, SqlConnection); - - //Execute this code to reflect the changes into the database. - SqlCommand.ExecuteNonQuery(); - SqlConnection.Close(); - - //Add custom logic here if needed and remove above method. - } - } - if (value.added != null && value.added.Count > 0) - { - foreach (Orders Record in (IEnumerable)value.added) - { - //Create query to insert the specific into the database by accessing its properties. - string queryStr = $"Insert into Orders(CustomerID,Freight,ShipCity,EmployeeID) values('{Record.CustomerID}','{Record.Freight}','{Record.ShipCity}','{Record.EmployeeID}')"; - SqlConnection SqlConnection = new SqlConnection(ConnectionString); - SqlConnection.Open(); - - //Execute the SQL command. - SqlCommand SqlCommand = new SqlCommand(queryStr, SqlConnection); - - //Execute this code to reflect the changes into the database. - SqlCommand.ExecuteNonQuery(); - SqlConnection.Close(); - - //Add custom logic here if needed and remove above method. - } - } - if (value.deleted != null && value.deleted.Count > 0) - { - foreach (Orders Record in (IEnumerable)value.deleted) - { - //Create query to remove the specific from database by passing the primary key column value. - string queryStr = $"Delete from Orders where OrderID={Record.OrderID}"; - SqlConnection SqlConnection = new SqlConnection(ConnectionString); - SqlConnection.Open(); - - //Execute the SQL command. - SqlCommand SqlCommand = new SqlCommand(queryStr, SqlConnection); - - //Execute this code to reflect the changes into the database. - SqlCommand.ExecuteNonQuery(); - SqlConnection.Close(); - - //Add custom logic here if needed and remove above method. - } - } - return new JsonResult(value); - } - public class CRUDModel where T : class - { - public string? action { get; set; } - public string? keyColumn { get; set; } - public object? key { get; set; } - public T? value { get; set; } - public List? added { get; set; } - public List? changed { get; set; } - public List? deleted { get; set; } - public IDictionary? @params { get; set; } - } - - public class Orders - { - [Key] - public int? OrderID { get; set; } - public string? CustomerID { get; set; } - public int? EmployeeID { get; set; } - public decimal? Freight { get; set; } - public string? ShipCity { get; set; } - } - } -} - diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Controllers/WeatherForecastController.cs b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Controllers/WeatherForecastController.cs deleted file mode 100644 index 358c374..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Controllers/WeatherForecastController.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace Grid_MSSQL.Server.Controllers -{ - [ApiController] - [Route("[controller]")] - public class WeatherForecastController : ControllerBase - { - private static readonly string[] Summaries = new[] - { - "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" - }; - - private readonly ILogger _logger; - - public WeatherForecastController(ILogger logger) - { - _logger = logger; - } - - [HttpGet(Name = "GetWeatherForecast")] - public IEnumerable Get() - { - return Enumerable.Range(1, 5).Select(index => new WeatherForecast - { - Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), - TemperatureC = Random.Shared.Next(-20, 55), - Summary = Summaries[Random.Shared.Next(Summaries.Length)] - }) - .ToArray(); - } - } -} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Grid_MSSQL.Server.http b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Grid_MSSQL.Server.http deleted file mode 100644 index 47b7fca..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Grid_MSSQL.Server.http +++ /dev/null @@ -1,6 +0,0 @@ -@Grid_MSSQL.Server_HostAddress = http://localhost:5108 - -GET {{Grid_MSSQL.Server_HostAddress}}/weatherforecast/ -Accept: application/json - -### diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Program.cs b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Program.cs deleted file mode 100644 index 45174d0..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Program.cs +++ /dev/null @@ -1,42 +0,0 @@ -var builder = WebApplication.CreateBuilder(args); - -// Add services to the container. - -builder.Services.AddControllers().AddJsonOptions(options => -{ - options.JsonSerializerOptions.PropertyNamingPolicy = null; // Use PascalCase -}); -builder.Services.AddControllers(); -// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle -builder.Services.AddEndpointsApiExplorer(); -builder.Services.AddSwaggerGen(); - -builder.Services.AddCors(options => -{ - options.AddDefaultPolicy(builder => - { - builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader(); - }); -}); -var app = builder.Build(); -app.UseCors(); - -app.UseDefaultFiles(); -app.UseStaticFiles(); - -// Configure the HTTP request pipeline. -if (app.Environment.IsDevelopment()) -{ - app.UseSwagger(); - app.UseSwaggerUI(); -} - -app.UseHttpsRedirection(); - -app.UseAuthorization(); - -app.MapControllers(); - -app.MapFallbackToFile("/index.html"); - -app.Run(); diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Properties/launchSettings.json b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Properties/launchSettings.json deleted file mode 100644 index 538277e..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Properties/launchSettings.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:7159", - "sslPort": 44366 - } - }, - "profiles": { - "http": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "http://localhost:5108", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development", - "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy" - } - }, - "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "https://localhost:7150;http://localhost:5108", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development", - "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development", - "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy" - } - } - } -} - diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/WeatherForecast.cs b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/WeatherForecast.cs deleted file mode 100644 index 26e5067..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/WeatherForecast.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Grid_MSSQL.Server -{ - public class WeatherForecast - { - public DateOnly Date { get; set; } - - public int TemperatureC { get; set; } - - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); - - public string? Summary { get; set; } - } -} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/appsettings.json b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/appsettings.json deleted file mode 100644 index 10f68b8..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*" -} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.sln b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.sln deleted file mode 100644 index 3665b11..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.sln +++ /dev/null @@ -1,33 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.10.35027.167 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grid_MSSQL.Server", "Grid_MSSQL.Server\Grid_MSSQL.Server.csproj", "{1877CE58-6BBD-4F9F-988A-4022D8429E65}" -EndProject -Project("{54A90642-561A-4BB1-A94E-469ADEE60C69}") = "grid_mssql.client", "grid_mssql.client\grid_mssql.client.esproj", "{1D9FFEE9-CAD2-4D54-B4A3-A1042305C9A4}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1877CE58-6BBD-4F9F-988A-4022D8429E65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1877CE58-6BBD-4F9F-988A-4022D8429E65}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1877CE58-6BBD-4F9F-988A-4022D8429E65}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1877CE58-6BBD-4F9F-988A-4022D8429E65}.Release|Any CPU.Build.0 = Release|Any CPU - {1D9FFEE9-CAD2-4D54-B4A3-A1042305C9A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1D9FFEE9-CAD2-4D54-B4A3-A1042305C9A4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1D9FFEE9-CAD2-4D54-B4A3-A1042305C9A4}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {1D9FFEE9-CAD2-4D54-B4A3-A1042305C9A4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1D9FFEE9-CAD2-4D54-B4A3-A1042305C9A4}.Release|Any CPU.Build.0 = Release|Any CPU - {1D9FFEE9-CAD2-4D54-B4A3-A1042305C9A4}.Release|Any CPU.Deploy.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {097A8824-C47C-4DD7-A11F-55EE7DB796C4} - EndGlobalSection -EndGlobal diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/CHANGELOG.md b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/CHANGELOG.md similarity index 100% rename from Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/CHANGELOG.md rename to Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/CHANGELOG.md index 139854d..03c2619 100644 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/CHANGELOG.md +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/CHANGELOG.md @@ -2,7 +2,7 @@ This file explains how Visual Studio created the project. The following steps were used to generate this project: - Create new ASP\.NET Core Web API project. -- Update `launchSettings.json` to register the SPA proxy as a startup assembly. - Update project file to add a reference to the frontend project and set SPA properties. +- Update `launchSettings.json` to register the SPA proxy as a startup assembly. - Add project to the startup projects list. - Write this file. diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/Controllers/TicketsController.cs b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/Controllers/TicketsController.cs new file mode 100644 index 0000000..8f3b85d --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/Controllers/TicketsController.cs @@ -0,0 +1,128 @@ +using Microsoft.AspNetCore.Mvc; +using Syncfusion.EJ2.Base; +using TicketManagement.Server.Data; + +namespace TicketManagement.Server.Controllers +{ + [ApiController] + [Route("api/[controller]")] + public class TicketsController : ControllerBase + { + private readonly TicketRepository _repo; + private readonly DataOperations _dataOps = new DataOperations(); + + public TicketsController(TicketRepository repo) + { + _repo = repo; + } + + // READ (DataManager + UrlAdaptor expects POST) + // POST api/tickets + [HttpPost] + public async Task List([FromBody] DataManagerRequest dm) + { + IEnumerable data = await _repo.GetTicketsAsync(); + + // Searching + if (dm.Search != null && dm.Search.Count > 0) + { + data = _dataOps.PerformSearching(data, dm.Search); + } + + // Filtering + if (dm.Where != null && dm.Where.Count > 0) + { + data = _dataOps.PerformFiltering(data, dm.Where, dm.Where[0].Operator); + } + + // Sorting + if (dm.Sorted != null && dm.Sorted.Count > 0) + { + data = _dataOps.PerformSorting(data, dm.Sorted); + } + + // Count BEFORE paging + int count = data.Count(); + + // Paging + if (dm.Skip != 0) + data = _dataOps.PerformSkip(data, dm.Skip); + if (dm.Take != 0) + data = _dataOps.PerformTake(data, dm.Take); + + // Final shape required by UrlAdaptor + return Ok(dm.RequiresCounts ? new { result = data, count } : data); + } + + [HttpGet("ping")] + public IActionResult Ping() => Ok(new { ok = true, time = DateTime.UtcNow }); + + // INSERT + // POST api/tickets/insert + [HttpPost("insert")] + public async Task Insert([FromBody] CRUDModel args) + { + if (args?.Value == null) + return BadRequest("Invalid payload."); + var created = await _repo.InsertAsync(args.Value); + return Ok(created); + } + + // UPDATE + // POST api/tickets/update + [HttpPost("update")] + public async Task Update([FromBody] CRUDModel args) + { + if (args?.Value == null) + return BadRequest("Invalid payload."); + if (args.Value.TicketId <= 0) + return BadRequest("TicketId is required for update."); + var updated = await _repo.UpdateAsync(args.Value); + return Ok(updated); + } + + // REMOVE + // POST api/tickets/remove + // UrlAdaptor sends { key: , keyColumn: "TicketId", action: "remove" } + [HttpPost("remove")] + public async Task Remove([FromBody] CRUDModel args) + { + if (args == null || args.Key == null) + return BadRequest("Key is required."); + if (!int.TryParse(args.Key.ToString(), out var id)) + return BadRequest("Invalid key format."); + + await _repo.DeleteAsync(id); + return Ok(new { TicketId = id }); + } + + // BATCH + // POST api/tickets/batch + [HttpPost("batch")] + public async Task Batch([FromBody] CRUDModel args) + { + if (args == null) + return BadRequest("Invalid payload."); + + if (args.Changed != null) + { + foreach (var t in args.Changed) + await _repo.UpdateAsync(t); + } + + if (args.Added != null) + { + for (int i = 0; i < args.Added.Count; i++) + args.Added[i] = await _repo.InsertAsync(args.Added[i]); + } + + if (args.Deleted != null) + { + foreach (var t in args.Deleted) + await _repo.DeleteAsync(t.TicketId); + } + + return Ok(new { status = "ok" }); + } + } +} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/Data/TicketRepository.cs b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/Data/TicketRepository.cs new file mode 100644 index 0000000..e1d2ed5 --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/Data/TicketRepository.cs @@ -0,0 +1,221 @@ +using Microsoft.Data.SqlClient; + +namespace TicketManagement.Server.Data +{ + public class TicketRepository + { + private readonly string _connectionString; + + // Public Ticket ID Configuration + private const string PublicTicketIdPrefix = "NET"; + private const string PublicTicketIdSeparator = "-"; + private const int PublicTicketIdStartNumber = 1001; + + /// + /// Initializes the repository with a connection string from configuration. + /// + public TicketRepository(IConfiguration configuration) + { + _connectionString = configuration.GetConnectionString("TicketDb")!; + } + + /// + /// Creates a new SQL connection using the configured connection string. + /// + private SqlConnection GetConnection() => new SqlConnection(_connectionString); + + /// + /// Returns all tickets ordered by TicketId. + /// + public async Task> GetTicketsAsync() + { + var list = new List(); + const string sql = + @"SELECT TicketId, PublicTicketId, Title, Description, Category, Department, Assignee, + CreatedBy, Status, Priority, ResponseDue, DueDate, CreatedAt, UpdatedAt + FROM dbo.Tickets ORDER BY TicketId"; + + await using var conn = GetConnection(); + await conn.OpenAsync(); + await using var cmd = new SqlCommand(sql, conn); + await using var reader = await cmd.ExecuteReaderAsync(); + + while (await reader.ReadAsync()) + { + list.Add( + new Tickets + { + TicketId = reader.GetInt32(reader.GetOrdinal("TicketId")), + PublicTicketId = reader["PublicTicketId"] as string, + Title = reader["Title"] as string, + Description = reader["Description"] as string, + Category = reader["Category"] as string, + Department = reader["Department"] as string, + Assignee = reader["Assignee"] as string, + CreatedBy = reader["CreatedBy"] as string, + Status = reader["Status"] as string, + Priority = reader["Priority"] as string, + ResponseDue = + reader["ResponseDue"] == DBNull.Value + ? null + : Convert.ToDateTime(reader["ResponseDue"]), + DueDate = + reader["DueDate"] == DBNull.Value + ? null + : Convert.ToDateTime(reader["DueDate"]), + CreatedAt = + reader["CreatedAt"] == DBNull.Value + ? null + : Convert.ToDateTime(reader["CreatedAt"]), + UpdatedAt = + reader["UpdatedAt"] == DBNull.Value + ? null + : Convert.ToDateTime(reader["UpdatedAt"]), + } + ); + } + return list; + } + + /// + /// Generates the next public ticket ID (e.g., NET-1002) by reading the current max numeric suffix. + /// + private async Task GeneratePublicTicketIdAsync() + { + // Efficiently get max numeric suffix with SQL + string like = $"{PublicTicketIdPrefix}{PublicTicketIdSeparator}%"; + const string sql = + @" + SELECT MAX(TRY_CAST(SUBSTRING(PublicTicketId, LEN(@prefix) + LEN(@sep) + 1, 50) AS INT)) + FROM dbo.Tickets + WHERE PublicTicketId LIKE @like"; + int? maxNumber = null; + + await using var conn = GetConnection(); + await conn.OpenAsync(); + await using var cmd = new SqlCommand(sql, conn); + cmd.Parameters.AddWithValue("@prefix", PublicTicketIdPrefix); + cmd.Parameters.AddWithValue("@sep", PublicTicketIdSeparator); + cmd.Parameters.AddWithValue("@like", like); + + var result = await cmd.ExecuteScalarAsync(); + if (result != DBNull.Value && result != null) + { + maxNumber = Convert.ToInt32(result); + } + + int next = (maxNumber ?? (PublicTicketIdStartNumber - 1)) + 1; + return $"{PublicTicketIdPrefix}{PublicTicketIdSeparator}{next}"; + } + + /// + /// Inserts a new ticket and returns the created entity with its TicketId. + /// + public async Task InsertAsync(Tickets value) + { + // Auto-generate PublicTicketId if empty + if (string.IsNullOrWhiteSpace(value.PublicTicketId)) + { + value.PublicTicketId = await GeneratePublicTicketIdAsync(); + } + + // Default timestamps + value.CreatedAt ??= DateTime.UtcNow; + value.UpdatedAt ??= DateTime.UtcNow; + + const string sql = + @" + INSERT INTO dbo.Tickets + (PublicTicketId, Title, Description, Category, Department, Assignee, CreatedBy, Status, Priority, + ResponseDue, DueDate, CreatedAt, UpdatedAt) + OUTPUT INSERTED.TicketId + VALUES + (@PublicTicketId, @Title, @Description, @Category, @Department, @Assignee, @CreatedBy, @Status, @Priority, + @ResponseDue, @DueDate, @CreatedAt, @UpdatedAt);"; + + await using var conn = GetConnection(); + await conn.OpenAsync(); + await using var cmd = new SqlCommand(sql, conn); + cmd.Parameters.AddWithValue( + "@PublicTicketId", + (object?)value.PublicTicketId ?? DBNull.Value + ); + cmd.Parameters.AddWithValue("@Title", (object?)value.Title ?? DBNull.Value); + cmd.Parameters.AddWithValue("@Description", (object?)value.Description ?? DBNull.Value); + cmd.Parameters.AddWithValue("@Category", (object?)value.Category ?? DBNull.Value); + cmd.Parameters.AddWithValue("@Department", (object?)value.Department ?? DBNull.Value); + cmd.Parameters.AddWithValue("@Assignee", (object?)value.Assignee ?? DBNull.Value); + cmd.Parameters.AddWithValue("@CreatedBy", (object?)value.CreatedBy ?? DBNull.Value); + cmd.Parameters.AddWithValue("@Status", (object?)value.Status ?? DBNull.Value); + cmd.Parameters.AddWithValue("@Priority", (object?)value.Priority ?? DBNull.Value); + cmd.Parameters.AddWithValue("@ResponseDue", (object?)value.ResponseDue ?? DBNull.Value); + cmd.Parameters.AddWithValue("@DueDate", (object?)value.DueDate ?? DBNull.Value); + cmd.Parameters.AddWithValue("@CreatedAt", (object?)value.CreatedAt ?? DBNull.Value); + cmd.Parameters.AddWithValue("@UpdatedAt", (object?)value.UpdatedAt ?? DBNull.Value); + + value.TicketId = Convert.ToInt32(await cmd.ExecuteScalarAsync()); + return value; + } + + /// + /// Updates an existing ticket by TicketId and returns the updated entity. + /// + public async Task UpdateAsync(Tickets value) + { + value.UpdatedAt ??= DateTime.UtcNow; + + const string sql = + @" + UPDATE dbo.Tickets + SET PublicTicketId = @PublicTicketId, + Title = @Title, + Description = @Description, + Category = @Category, + Department = @Department, + Assignee = @Assignee, + CreatedBy = @CreatedBy, + Status = @Status, + Priority = @Priority, + ResponseDue = @ResponseDue, + DueDate = @DueDate, + UpdatedAt = @UpdatedAt + WHERE TicketId = @TicketId;"; + + await using var conn = GetConnection(); + await conn.OpenAsync(); + await using var cmd = new SqlCommand(sql, conn); + cmd.Parameters.AddWithValue("@TicketId", value.TicketId); + cmd.Parameters.AddWithValue( + "@PublicTicketId", + (object?)value.PublicTicketId ?? DBNull.Value + ); + cmd.Parameters.AddWithValue("@Title", (object?)value.Title ?? DBNull.Value); + cmd.Parameters.AddWithValue("@Description", (object?)value.Description ?? DBNull.Value); + cmd.Parameters.AddWithValue("@Category", (object?)value.Category ?? DBNull.Value); + cmd.Parameters.AddWithValue("@Department", (object?)value.Department ?? DBNull.Value); + cmd.Parameters.AddWithValue("@Assignee", (object?)value.Assignee ?? DBNull.Value); + cmd.Parameters.AddWithValue("@CreatedBy", (object?)value.CreatedBy ?? DBNull.Value); + cmd.Parameters.AddWithValue("@Status", (object?)value.Status ?? DBNull.Value); + cmd.Parameters.AddWithValue("@Priority", (object?)value.Priority ?? DBNull.Value); + cmd.Parameters.AddWithValue("@ResponseDue", (object?)value.ResponseDue ?? DBNull.Value); + cmd.Parameters.AddWithValue("@DueDate", (object?)value.DueDate ?? DBNull.Value); + cmd.Parameters.AddWithValue("@UpdatedAt", (object?)value.UpdatedAt ?? DBNull.Value); + + await cmd.ExecuteNonQueryAsync(); + return value; + } + + /// + /// Deletes a ticket by TicketId. Returns affected rows (0 or 1). + /// + public async Task DeleteAsync(int ticketId) + { + const string sql = @"DELETE FROM dbo.Tickets WHERE TicketId = @TicketId;"; + await using var conn = GetConnection(); + await conn.OpenAsync(); + await using var cmd = new SqlCommand(sql, conn); + cmd.Parameters.AddWithValue("@TicketId", ticketId); + return await cmd.ExecuteNonQueryAsync(); + } + } +} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/Data/Tickets.cs b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/Data/Tickets.cs new file mode 100644 index 0000000..fb4bb2e --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/Data/Tickets.cs @@ -0,0 +1,82 @@ +using System.ComponentModel.DataAnnotations; + +namespace TicketManagement.Server.Data +{ + /// + /// Represents a ticket record mapped to the 'Tickets' table in the database. + /// This model defines the structure of ticket-related data used throughout the application. + /// + public class Tickets + { + /// + /// Gets or sets the unique identifier for the ticket record. + /// + [Key] + public int TicketId { get; set; } + + /// + /// Gets or sets the public-facing ticket identifier (e.g., NET-1001). + /// + public string? PublicTicketId { get; set; } + + /// + /// Gets or sets the ticket title or subject. + /// + public string? Title { get; set; } + + /// + /// Gets or sets a detailed description of the ticket. + /// + public string? Description { get; set; } + + /// + /// Gets or sets the category of the issue (e.g., Network, Hardware, Software). + /// + public string? Category { get; set; } + + /// + /// Gets or sets the department responsible for handling the ticket. + /// + public string? Department { get; set; } + + /// + /// Gets or sets the name of the agent assigned to the ticket. + /// + public string? Assignee { get; set; } + + /// + /// Gets or sets the name of the person who created the ticket. + /// + public string? CreatedBy { get; set; } + + /// + /// Gets or sets the current status of the ticket (e.g., Open, In Progress, Resolved, Closed). + /// + public string? Status { get; set; } + + /// + /// Gets or sets the priority level of the ticket (e.g., Critical, High, Medium, Low). + /// + public string? Priority { get; set; } + + /// + /// Gets or sets the deadline for responding to the ticket. + /// + public DateTime? ResponseDue { get; set; } + + /// + /// Gets or sets the deadline for resolving the ticket. + /// + public DateTime? DueDate { get; set; } + + /// + /// Gets or sets the timestamp indicating when the ticket was created. + /// + public DateTime? CreatedAt { get; set; } + + /// + /// Gets or sets the timestamp indicating when the ticket was last updated. + /// + public DateTime? UpdatedAt { get; set; } + } +} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/Program.cs b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/Program.cs new file mode 100644 index 0000000..cbb5a83 --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/Program.cs @@ -0,0 +1,41 @@ +using TicketManagement.Server.Data; + +var builder = WebApplication.CreateBuilder(args); + +// Add MVC controllers and keep JSON property names as-is (PascalCase) +builder + .Services.AddControllers() + .AddJsonOptions(options => + { + options.JsonSerializerOptions.PropertyNamingPolicy = null; + options.JsonSerializerOptions.DictionaryKeyPolicy = null; + options.JsonSerializerOptions.ReferenceHandler = null; + }); + +// (Optional) Swagger for API exploration in Development +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +// CORS: allow all (simple for local dev / separate frontend) +builder.Services.AddCors(options => +{ + options.AddDefaultPolicy(policy => policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()); +}); + +// Register repository for DI +builder.Services.AddScoped(); + +var app = builder.Build(); + +// Swagger only in Development +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +// Enable CORS and map controllers +app.UseCors(); +app.MapControllers(); + +app.Run(); diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/Properties/launchSettings.json b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/Properties/launchSettings.json new file mode 100644 index 0000000..8f30495 --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/Properties/launchSettings.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "https://localhost:7000;http://localhost:5275", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy" + } + } + } +} + diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Grid_MSSQL.Server.csproj b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/TicketManagement.Server.csproj similarity index 57% rename from Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Grid_MSSQL.Server.csproj rename to Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/TicketManagement.Server.csproj index c819d60..60d477a 100644 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Grid_MSSQL.Server.csproj +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/TicketManagement.Server.csproj @@ -1,27 +1,32 @@ - net8.0 + net10.0 enable enable - ..\grid_mssql.client + ..\ticketmanagement.client npm start - https://localhost:4200 + https://localhost:53605 + - 8.*-* + 10.*-* - - - + + + - + false + + + + diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Grid_MSSQL.Server.csproj.user b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/TicketManagement.Server.csproj.user similarity index 100% rename from Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/Grid_MSSQL.Server.csproj.user rename to Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/TicketManagement.Server.csproj.user diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/TicketManagement.Server.http b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/TicketManagement.Server.http new file mode 100644 index 0000000..c584066 --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/TicketManagement.Server.http @@ -0,0 +1,6 @@ +@TicketManagement.Server_HostAddress = http://localhost:5275 + +GET {{TicketManagement.Server_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/appsettings.Development.json b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/appsettings.Development.json similarity index 100% rename from Binding MS SQL database using UrlAdaptor/Grid_MSSQL/Grid_MSSQL.Server/appsettings.Development.json rename to Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/appsettings.Development.json diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/appsettings.json b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/appsettings.json new file mode 100644 index 0000000..ff161a4 --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.Server/appsettings.json @@ -0,0 +1,12 @@ +{ + "ConnectionStrings": { + "TicketDb": "Data Source=localhost;Initial Catalog=NetworkSupportDB;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} \ No newline at end of file diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.slnx b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.slnx new file mode 100644 index 0000000..20344c8 --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/TicketManagement.slnx @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/.editorconfig b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/.editorconfig deleted file mode 100644 index 59d9a3a..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/.editorconfig +++ /dev/null @@ -1,16 +0,0 @@ -# Editor configuration, see https://editorconfig.org -root = true - -[*] -charset = utf-8 -indent_style = space -indent_size = 2 -insert_final_newline = true -trim_trailing_whitespace = true - -[*.ts] -quote_type = single - -[*.md] -max_line_length = off -trim_trailing_whitespace = false diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/.gitignore b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/.gitignore deleted file mode 100644 index 0711527..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/.gitignore +++ /dev/null @@ -1,42 +0,0 @@ -# See http://help.github.com/ignore-files/ for more about ignoring files. - -# Compiled output -/dist -/tmp -/out-tsc -/bazel-out - -# Node -/node_modules -npm-debug.log -yarn-error.log - -# IDEs and editors -.idea/ -.project -.classpath -.c9/ -*.launch -.settings/ -*.sublime-workspace - -# Visual Studio Code -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json -.history/* - -# Miscellaneous -/.angular/cache -.sass-cache/ -/connect.lock -/coverage -/libpeerconnection.log -testem.log -/typings - -# System files -.DS_Store -Thumbs.db diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/.vscode/extensions.json b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/.vscode/extensions.json deleted file mode 100644 index 77b3745..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/.vscode/extensions.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 - "recommendations": ["angular.ng-template"] -} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/.vscode/launch.json b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/.vscode/launch.json deleted file mode 100644 index 3eb15cd..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/.vscode/launch.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "type": "edge", - "request": "launch", - "name": "localhost (Edge)", - "url": "https://localhost:4200", - "webRoot": "${workspaceFolder}" - }, - { - "type": "chrome", - "request": "launch", - "name": "localhost (Chrome)", - "url": "https://localhost:4200", - "webRoot": "${workspaceFolder}" - } - ] -} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/.vscode/tasks.json b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/.vscode/tasks.json deleted file mode 100644 index a298b5b..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/.vscode/tasks.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "start", - "isBackground": true, - "problemMatcher": { - "owner": "typescript", - "pattern": "$tsc", - "background": { - "activeOnStart": true, - "beginsPattern": { - "regexp": "(.*?)" - }, - "endsPattern": { - "regexp": "bundle generation complete" - } - } - } - }, - { - "type": "npm", - "script": "test", - "isBackground": true, - "problemMatcher": { - "owner": "typescript", - "pattern": "$tsc", - "background": { - "activeOnStart": true, - "beginsPattern": { - "regexp": "(.*?)" - }, - "endsPattern": { - "regexp": "bundle generation complete" - } - } - } - } - ] -} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/nuget.config b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/nuget.config deleted file mode 100644 index 6548586..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/nuget.config +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app-routing.module.ts b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app-routing.module.ts deleted file mode 100644 index 0297262..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app-routing.module.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; - -const routes: Routes = []; - -@NgModule({ - imports: [RouterModule.forRoot(routes)], - exports: [RouterModule] -}) -export class AppRoutingModule { } diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app.component.css b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app.component.css deleted file mode 100644 index 43fba20..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app.component.css +++ /dev/null @@ -1,14 +0,0 @@ -:host { - max-width: 1280px; - padding: 2rem; - text-align: center; -} - -th, td { - padding-left: 1rem; - padding-right: 1rem; -} - -table { - margin: 0 auto; -} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app.component.html b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app.component.html deleted file mode 100644 index e754707..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app.component.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app.component.spec.ts b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app.component.spec.ts deleted file mode 100644 index 64dc497..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app.component.spec.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { AppComponent } from './app.component'; - -describe('AppComponent', () => { - let component: AppComponent; - let fixture: ComponentFixture; - let httpMock: HttpTestingController; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [AppComponent], - imports: [HttpClientTestingModule] - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(AppComponent); - component = fixture.componentInstance; - httpMock = TestBed.inject(HttpTestingController); - }); - - afterEach(() => { - httpMock.verify(); - }); - - it('should create the app', () => { - expect(component).toBeTruthy(); - }); - - it('should retrieve weather forecasts from the server', () => { - const mockForecasts = [ - { date: '2021-10-01', temperatureC: 20, temperatureF: 68, summary: 'Mild' }, - { date: '2021-10-02', temperatureC: 25, temperatureF: 77, summary: 'Warm' } - ]; - - component.ngOnInit(); - - const req = httpMock.expectOne('/weatherforecast'); - expect(req.request.method).toEqual('GET'); - req.flush(mockForecasts); - - expect(component.forecasts).toEqual(mockForecasts); - }); -}); \ No newline at end of file diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app.component.ts b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app.component.ts deleted file mode 100644 index 09f32e1..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Component, ViewChild } from '@angular/core'; -import { DataManager, UrlAdaptor } from '@syncfusion/ej2-data'; -import { GridComponent, EditSettingsModel, ToolbarItems } from '@syncfusion/ej2-angular-grids'; -import { EditService, FilterService, GridModule, PageService, GroupService, AggregateService, SortService, ToolbarService } from '@syncfusion/ej2-angular-grids'; - -@Component({ - selector: 'app-root', - templateUrl: './app.component.html', - standalone: true, - providers: [EditService, ToolbarService, AggregateService, GroupService, FilterService, SortService, PageService], - imports: [GridModule], -}) -export class AppComponent { - @ViewChild('grid') public grid?: GridComponent; - public data?: DataManager; - public editSettings?: EditSettingsModel; - public toolbar?: ToolbarItems[]; - public employeeIDRules?: Object; - public customerIDRules?: Object; - public freightRules?: Object; - public shipCityRules?: Object; - - public ngOnInit(): void { - this.data = new DataManager({ - url: 'https://localhost:7150/api/Grid', // Replace your hosted link. - insertUrl: 'https://localhost:7150/api/Grid/Insert', - updateUrl: 'https://localhost:7150/api/Grid/Update', - removeUrl: 'https://localhost:7150/api/Grid/Remove', - // Enable batch URL when batch editing is enabled. - //batchUrl: 'https://localhost:7150/api/Grid/BatchUpdate', - adaptor: new UrlAdaptor() - }); - this.employeeIDRules = { required: true, number: true }; - this.customerIDRules = { required: true }; - this.freightRules = { required: true, min: 1, max: 1000 }; - this.shipCityRules = { required: true }; - this.toolbar = ['Add', 'Update', 'Delete', 'Cancel', 'Search']; - this.editSettings = { allowAdding: true, allowDeleting: true, allowEditing: true, mode: 'Normal' }; - } -} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app.module.ts b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app.module.ts deleted file mode 100644 index 9ece5fb..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/app/app.module.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { HttpClientModule } from '@angular/common/http'; -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; -import { EditService, FilterService, GridModule, PageService ,GroupService, AggregateService, SortService, ToolbarService } from '@syncfusion/ej2-angular-grids'; -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; - -@NgModule({ - declarations: [ - AppComponent - ], - imports: [ - BrowserModule, HttpClientModule, - AppRoutingModule, GridModule - ], - providers: [EditService, ToolbarService, AggregateService, GroupService, FilterService, SortService, PageService], - bootstrap: [AppComponent] -}) -export class AppModule { } diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/assets/.gitkeep b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/assets/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/index.html b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/index.html deleted file mode 100644 index 290c8ee..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - GridMssqlClient - - - - - - - - diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/main.ts b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/main.ts deleted file mode 100644 index 04cb008..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { AppComponent } from './app/app.component'; -import 'zone.js'; -bootstrapApplication(AppComponent).catch((err) => console.error(err)); diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/styles.css b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/styles.css deleted file mode 100644 index 8a6c039..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/styles.css +++ /dev/null @@ -1,11 +0,0 @@ -/* You can add global styles to this file, and also import other style files */ -/* You can add global styles to this file, and also import other style files */ -@import '../node_modules/@syncfusion/ej2-base/styles/material.css'; -@import '../node_modules/@syncfusion/ej2-buttons/styles/material.css'; -@import '../node_modules/@syncfusion/ej2-calendars/styles/material.css'; -@import '../node_modules/@syncfusion/ej2-dropdowns/styles/material.css'; -@import '../node_modules/@syncfusion/ej2-inputs/styles/material.css'; -@import '../node_modules/@syncfusion/ej2-navigations/styles/material.css'; -@import '../node_modules/@syncfusion/ej2-popups/styles/material.css'; -@import '../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css'; -@import '../node_modules/@syncfusion/ej2-angular-grids/styles/material.css'; diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/tsconfig.app.json b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/tsconfig.app.json deleted file mode 100644 index 374cc9d..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/tsconfig.app.json +++ /dev/null @@ -1,14 +0,0 @@ -/* To learn more about this file see: https://angular.io/config/tsconfig. */ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "./out-tsc/app", - "types": [] - }, - "files": [ - "src/main.ts" - ], - "include": [ - "src/**/*.d.ts" - ] -} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/tsconfig.spec.json b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/tsconfig.spec.json deleted file mode 100644 index be7e9da..0000000 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/tsconfig.spec.json +++ /dev/null @@ -1,14 +0,0 @@ -/* To learn more about this file see: https://angular.io/config/tsconfig. */ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "./out-tsc/spec", - "types": [ - "jasmine" - ] - }, - "include": [ - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] -} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/CHANGELOG.md b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/CHANGELOG.md similarity index 62% rename from Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/CHANGELOG.md rename to Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/CHANGELOG.md index 5d20269..1a6d95c 100644 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/CHANGELOG.md +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/CHANGELOG.md @@ -4,17 +4,16 @@ The following tools were used to generate this project: - Angular CLI (ng) The following steps were used to generate this project: -- Create Angular project with ng: `ng new grid_mssql.client --defaults --skip-install --skip-git --no-standalone `. +- Create Angular project with ng: `ng new ticketmanagement.client --defaults --skip-install --skip-git --no-standalone `. - Add `proxy.conf.js` to proxy calls to the backend ASP.NET server. - Add `aspnetcore-https.js` script to install https certs. - Update `package.json` to call `aspnetcore-https.js` and serve with https. - Update `angular.json` to point to `proxy.conf.js`. -- Update `app.component.ts` component to fetch and display weather information. -- Modify `app.component.spec.ts` with updated tests. -- Update `app.module.ts` to import the HttpClientModule. -- Create project file (`grid_mssql.client.esproj`). +- Update app.component.ts component to fetch and display weather information. +- Modify app.component.spec.ts with updated tests. +- Update app.module.ts to import the HttpClientModule. +- Create project file (`ticketmanagement.client.esproj`). - Create `launch.json` to enable debugging. -- Create `nuget.config` to specify location of the JavaScript Project System SDK (which is used in the first line in `grid_mssql.client.esproj`). - Update package.json to add `jest-editor-support`. - Update package.json to add `run-script-os`. - Add `karma.conf.js` for unit tests. diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/README.md b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/README.md similarity index 91% rename from Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/README.md rename to Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/README.md index b54fd23..9655042 100644 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/README.md +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/README.md @@ -1,6 +1,6 @@ -# GridMssqlClient +# TicketmanagementClient -This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.0.3. +This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.2.21. ## Development server @@ -24,4 +24,4 @@ Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To u ## Further help -To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/angular.json b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/angular.json similarity index 77% rename from Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/angular.json rename to Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/angular.json index e215a58..dbba6ce 100644 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/angular.json +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/angular.json @@ -3,7 +3,7 @@ "version": 1, "newProjectRoot": "projects", "projects": { - "grid_mssql.client": { + "ticketmanagement.client": { "projectType": "application", "schematics": { "@schematics/angular:component": { @@ -23,7 +23,7 @@ "build": { "builder": "@angular-devkit/build-angular:application", "options": { - "outputPath": "dist/grid_mssql.client", + "outputPath": "dist/ticketmanagement.client", "index": "src/index.html", "browser": "src/main.ts", "polyfills": [ @@ -31,8 +31,10 @@ ], "tsConfig": "tsconfig.app.json", "assets": [ - "src/favicon.ico", - "src/assets" + { + "glob": "**/*", + "input": "public" + } ], "styles": [ "src/styles.css" @@ -44,13 +46,13 @@ "budgets": [ { "type": "initial", - "maximumWarning": "500kb", - "maximumError": "1mb" + "maximumWarning": "500kB", + "maximumError": "1MB" }, { "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" + "maximumWarning": "2kB", + "maximumError": "4kB" } ], "outputHashing": "all" @@ -67,22 +69,20 @@ "builder": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { - "buildTarget": "grid_mssql.client:build:production" + "buildTarget": "ticketmanagement.client:build:production" }, "development": { - "buildTarget": "grid_mssql.client:build:development" + "buildTarget": "ticketmanagement.client:build:development" } }, "defaultConfiguration": "development", "options": { - "proxyConfig": "src/proxy.conf.js" + "proxyConfig": "src/proxy.conf.js", + "port": 53605 } }, "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "buildTarget": "grid_mssql.client:build" - } + "builder": "@angular-devkit/build-angular:extract-i18n" }, "test": { "builder": "@angular-devkit/build-angular:karma", @@ -93,8 +93,10 @@ ], "tsConfig": "tsconfig.spec.json", "assets": [ - "src/favicon.ico", - "src/assets" + { + "glob": "**/*", + "input": "public" + } ], "styles": [ "src/styles.css" @@ -105,8 +107,5 @@ } } } - }, - "cli": { - "analytics": "4250ac6d-a397-4c26-813d-3aa19d7aac63" } } \ No newline at end of file diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/aspnetcore-https.js b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/aspnetcore-https.js similarity index 92% rename from Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/aspnetcore-https.js rename to Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/aspnetcore-https.js index 764331a..cab03ec 100644 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/aspnetcore-https.js +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/aspnetcore-https.js @@ -19,6 +19,10 @@ if (!certificateName) { const certFilePath = path.join(baseFolder, `${certificateName}.pem`); const keyFilePath = path.join(baseFolder, `${certificateName}.key`); +if (!fs.existsSync(baseFolder)) { + fs.mkdirSync(baseFolder, { recursive: true }); +} + if (!fs.existsSync(certFilePath) || !fs.existsSync(keyFilePath)) { spawn('dotnet', [ 'dev-certs', diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/karma.conf.js b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/karma.conf.js similarity index 100% rename from Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/karma.conf.js rename to Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/karma.conf.js diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/package.json b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/package.json similarity index 62% rename from Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/package.json rename to Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/package.json index 8690e2e..f44682b 100644 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/package.json +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/package.json @@ -1,5 +1,5 @@ { - "name": "grid-mssql.client", + "name": "ticketmanagement.client", "version": "0.0.0", "scripts": { "ng": "ng", @@ -13,33 +13,30 @@ }, "private": true, "dependencies": { - "@angular/animations": "^17.0.0", - "@angular/common": "^17.0.0", - "@angular/compiler": "^17.0.0", - "@angular/core": "^17.0.0", - "@angular/forms": "^17.0.0", - "@angular/platform-browser": "^17.0.0", - "@angular/platform-browser-dynamic": "^17.0.0", + "@angular/common": "^20.0.0", + "@angular/compiler": "^20.0.0", + "@angular/core": "^20.0.0", + "@angular/forms": "^20.0.0", + "@angular/platform-browser": "^20.0.0", "@syncfusion/ej2-angular-grids": "*", "@syncfusion/ej2-data": "*", - "@angular/router": "^17.0.0", + "run-script-os": "*", "rxjs": "~7.8.0", "tslib": "^2.3.0", - "zone.js": "~0.14.2", - "jest-editor-support": "*", - "run-script-os": "*" + "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^17.0.3", - "@angular/cli": "^17.0.3", - "@angular/compiler-cli": "^17.0.0", + "@angular-devkit/build-angular": "^20.0.0", + "@angular/build": "^20.0.0", + "@angular/cli": "^20.0.0", + "@angular/compiler-cli": "^20.0.0", "@types/jasmine": "~5.1.0", - "jasmine-core": "~5.1.0", + "jasmine-core": "~5.7.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.2.0", "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.1.0", - "typescript": "~5.2.2" + "typescript": "~5.8.2" } -} +} \ No newline at end of file diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/favicon.ico b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/public/favicon.ico similarity index 100% rename from Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/favicon.ico rename to Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/public/favicon.ico diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/app/app.component.css b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/app/app.component.css new file mode 100644 index 0000000..ffe15f7 --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/app/app.component.css @@ -0,0 +1,191 @@ +:host { + display: block; + padding: 1rem; +} + +/* STATUS */ +.status-text { + font-weight: 600; + font-size: 0.92rem; +} + +.status-open { + color: #0d6efd; +} + +.status-inprogress { + color: #d97706; +} + +.status-waiting-customer { + color: #7c3aed; +} + +.status-waiting-agent { + color: #9333ea; +} + +.status-resolved { + color: #059669; +} + +.status-closed { + color: #047857; +} + +.status-ticket-id { + color: #4097ee; + position: relative; + text-decoration: none; + transition: color 0.3s ease-in-out; +} + +.status-ticket-id::before { + content: ""; + position: absolute; + top: 100%; + width: 100%; + height: 3px; + background-color: #94a8e1; + transform: scaleX(0); + transition: transform 0.3s ease-in-out; +} + +.status-ticket-id:hover { + color: #2d26c6; + cursor: pointer; +} + +.status-ticket-id:hover::before { + transform: scaleX(1); +} + +/* PRIORITY */ +.priority-pill { + display: inline-flex; + align-items: center; + gap: 0.45rem; + font-weight: 600; + font-size: 0.92rem; +} + +.priority-pill .priority-icon { + display: inline-block; +} + +.priority-pill.priority-critical { + color: #b91c1c; +} + +.priority-pill.priority-critical .priority-icon { + width: 0; + height: 0; + border-left: 0.35rem solid transparent; + border-right: 0.35rem solid transparent; + border-bottom: 0.65rem solid #b91c1c; +} + +.priority-pill.priority-high { + color: #dc2626; +} + +.priority-pill.priority-high .priority-icon { + width: 0; + height: 0; + border-left: 0.34rem solid transparent; + border-right: 0.34rem solid transparent; + border-bottom: 0.6rem solid #dc2626; +} + +.priority-pill.priority-medium { + color: #15803d; +} + +.priority-pill.priority-medium .priority-icon { + width: 0.6rem; + height: 0.6rem; + border-radius: 0.2rem; + background-color: #22c55e; +} + +.priority-pill.priority-low { + color: #4b5563; +} + +.priority-pill.priority-low .priority-icon { + width: 0; + height: 0; + border-left: 0.32rem solid transparent; + border-right: 0.32rem solid transparent; + border-top: 0.55rem solid #4b5563; +} + +/* CATEGORY CHIP */ +.chip { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.2rem 1rem; + min-height: 1.8rem; + border-radius: 999px; + font-size: 0.82rem; + font-weight: 600; + color: #fff; + line-height: 1; + white-space: nowrap; + background-color: var(--chip-color, #4b5563); +} + +.chip.category-network { + --chip-color: #4a7c59; +} + +.chip.category-performance { + --chip-color: #68b0ab; +} + +.chip.category-vpn { + --chip-color: #56638a; +} + +.chip.category-hardware { + --chip-color: #8e443d; +} + +.chip.category-server { + --chip-color: #25a18e; +} + +.chip.category-security { + --chip-color: #320a28; +} + +.chip.category-connectivity { + --chip-color: #3c6997; +} + +.chip.category-software { + --chip-color: #ae76a6; +} + +.chip.category-email { + --chip-color: #003554; +} + +.chip.category-access { + --chip-color: #0582ca; +} + +.chip.category-backup { + --chip-color: #093a3e; +} + +.chip.category-database { + --chip-color: #92374d; +} + +/* RESPONSE DUE */ +.response-due { + color: #c05621; + font-weight: 600; +} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/app/app.component.html b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/app/app.component.html new file mode 100644 index 0000000..c158c19 --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/app/app.component.html @@ -0,0 +1,145 @@ + + + + + + + + + + {{ data.PublicTicketId }} + + + + + + + + + + + {{ data.Status }} + + + + + + + + + {{ data.Priority }} + + + + + + + + {{ data.Category }} + + + + + + + + + + + + + + + + + + + + {{ data.ResponseDue ? (data.ResponseDue | date:'MMM d, yyyy, h:mm a') : '' }} + + + + + + + + + + + diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/app/app.component.ts b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/app/app.component.ts new file mode 100644 index 0000000..a98b545 --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/app/app.component.ts @@ -0,0 +1,89 @@ +import { Component } from "@angular/core"; +import { CommonModule, DatePipe } from "@angular/common"; +import { + GridModule, + FilterService, + SortService, + EditService, + ToolbarService, + PageService, + ToolbarItems, + EditSettingsModel, + FilterSettingsModel, +} from "@syncfusion/ej2-angular-grids"; +import { TicketRow } from "./app.types"; +import { DataManager, UrlAdaptor } from "@syncfusion/ej2-data"; + +const BASE_URL = "https://localhost:7000/api/tickets"; // ASP.NET Core server API URL + +@Component({ + selector: "app-root", + standalone: true, + imports: [CommonModule, DatePipe, GridModule], + templateUrl: "app.component.html", + styleUrls: ["app.component.css"], + providers: [PageService, FilterService, SortService, EditService, ToolbarService], +}) +export class AppComponent { + public dataManager: DataManager = new DataManager({ + url: `${BASE_URL}`, + insertUrl: `${BASE_URL}/insert`, + updateUrl: `${BASE_URL}/update`, + removeUrl: `${BASE_URL}/remove`, + batchUrl: `${BASE_URL}/batch`, + adaptor: new UrlAdaptor(), + }); + + public toolbar: ToolbarItems[] = [ + "Add", + "Edit", + "Delete", + "Update", + "Cancel", + "Search", + ]; + + public editSettings: EditSettingsModel = { + allowEditing: true, + allowAdding: true, + allowDeleting: true, + mode: "Batch", + }; + + public filterSettings: FilterSettingsModel = { type: "Excel" }; + + getStatusClass(row: TicketRow): string { + const map: Record = { + Open: "status-open", + Closed: "status-closed", + Pending: "status-pending", + }; + return map[row.Status] ?? ""; + } + + getStatusDescription(row: TicketRow): string { + return `Status: ${row.Status}`; + } + + getPriorityClass(row: TicketRow): string { + const map: Record = { + High: "priority-high", + Medium: "priority-medium", + Low: "priority-low", + }; + return map[row.Priority] ?? ""; + } + + getPriorityDescription(row: TicketRow): string { + return `Priority: ${row.Priority}`; + } + + getCategoryClass(row: TicketRow): string { + const map: Record = { + Bug: "chip-bug", + Feature: "chip-feature", + Task: "chip-task", + }; + return map[row.Category] ?? ""; + } +} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/app/app.types.ts b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/app/app.types.ts new file mode 100644 index 0000000..2519a19 --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/app/app.types.ts @@ -0,0 +1,15 @@ +export interface TicketRow { + TicketId: number; + PublicTicketId: string; + Title: string; + Status: string; + Priority: string; + Category: string; + Department: string; + CreatedBy: string; + Assignee: string; + DueDate: Date; + ResponseDue: Date | null; + UpdatedAt: Date; + CreatedAt: Date; +} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/index.html b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/index.html new file mode 100644 index 0000000..a2feea5 --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/index.html @@ -0,0 +1,28 @@ + + + + + Client + + + + + + + + + + + diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/main.ts b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/main.ts new file mode 100644 index 0000000..c191868 --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/main.ts @@ -0,0 +1,10 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { provideAnimations } from '@angular/platform-browser/animations'; +// import { registerLicense } from '@syncfusion/ej2-base'; + +import { AppComponent } from './app/app.component'; + +// TODO: replace with your Syncfusion license key. +// registerLicense('YOUR SYNCFUSION LICENSE KEY'); + +bootstrapApplication(AppComponent).catch(err => console.error(err)); \ No newline at end of file diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/proxy.conf.js b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/proxy.conf.js similarity index 75% rename from Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/proxy.conf.js rename to Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/proxy.conf.js index 888c70e..c6233ad 100644 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/src/proxy.conf.js +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/proxy.conf.js @@ -1,7 +1,7 @@ const { env } = require('process'); const target = env.ASPNETCORE_HTTPS_PORT ? `https://localhost:${env.ASPNETCORE_HTTPS_PORT}` : - env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(';')[0] : 'https://localhost:7150'; + env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(';')[0] : 'https://localhost:7073'; const PROXY_CONFIG = [ { diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/styles.css b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/styles.css new file mode 100644 index 0000000..6f2edcc --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/src/styles.css @@ -0,0 +1,10 @@ +@import '../node_modules/@syncfusion/ej2-base/styles/bootstrap5.3.css'; +@import '../node_modules/@syncfusion/ej2-buttons/styles/bootstrap5.3.css'; +@import '../node_modules/@syncfusion/ej2-calendars/styles/bootstrap5.3.css'; +@import '../node_modules/@syncfusion/ej2-dropdowns/styles/bootstrap5.3.css'; +@import '../node_modules/@syncfusion/ej2-inputs/styles/bootstrap5.3.css'; +@import '../node_modules/@syncfusion/ej2-navigations/styles/bootstrap5.3.css'; +@import '../node_modules/@syncfusion/ej2-popups/styles/bootstrap5.3.css'; +@import '../node_modules/@syncfusion/ej2-splitbuttons/styles/bootstrap5.3.css'; +@import '../node_modules/@syncfusion/ej2-notifications/styles/bootstrap5.3.css'; +@import '../node_modules/@syncfusion/ej2-angular-grids/styles/bootstrap5.3.css'; \ No newline at end of file diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/grid_mssql.client.esproj b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/ticketmanagement.client.esproj similarity index 67% rename from Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/grid_mssql.client.esproj rename to Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/ticketmanagement.client.esproj index 11bd509..43394ca 100644 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/grid_mssql.client.esproj +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/ticketmanagement.client.esproj @@ -1,10 +1,10 @@ - + npm start Jasmine false - $(MSBuildProjectDirectory)\dist\grid_mssql.client\browser\ + $(MSBuildProjectDirectory)\dist\ticketmanagement.client\browser\ \ No newline at end of file diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/tsconfig.app.json b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/tsconfig.app.json new file mode 100644 index 0000000..3775b37 --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/tsconfig.json b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/tsconfig.json similarity index 67% rename from Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/tsconfig.json rename to Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/tsconfig.json index 678336b..a8bb65b 100644 --- a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/grid_mssql.client/tsconfig.json +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/tsconfig.json @@ -1,23 +1,24 @@ -/* To learn more about this file see: https://angular.io/config/tsconfig. */ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, "compilerOptions": { "outDir": "./dist/out-tsc", - "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "isolatedModules": true, "esModuleInterop": true, "sourceMap": true, "declaration": false, "experimentalDecorators": true, - "moduleResolution": "node", + "moduleResolution": "bundler", "importHelpers": true, "target": "ES2022", "module": "ES2022", - "useDefineForClassFields": false, "lib": [ "ES2022", "dom" diff --git a/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/tsconfig.spec.json b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/tsconfig.spec.json new file mode 100644 index 0000000..5fb748d --- /dev/null +++ b/Binding MS SQL database using UrlAdaptor/Grid_MSSQL/ticketmanagement.client/tsconfig.spec.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/Binding MS SQL database using UrlAdaptor/README.md b/Binding MS SQL database using UrlAdaptor/README.md index 13bc71c..04a43a7 100644 --- a/Binding MS SQL database using UrlAdaptor/README.md +++ b/Binding MS SQL database using UrlAdaptor/README.md @@ -1,22 +1,118 @@ -## Angular Grid Microsoft SQL Server connectivity using URLAdaptor +# Syncfusion Angular Grid with ASP.NET Core Web API and Microsoft SQL Server -A project that enables data binding and CRUD action handling in the Syncfusion Angular Grid to a Microsoft SQL Server using URLAdaptor feature of the Grid. +A minimal, high‑level user guide for binding **Microsoft SQL Server** data to a **Syncfusion Angular Grid** using an **ASP.NET Core Web API**. This document focuses on concepts, flow, and run commands only, without implementation details. -## Steps to Run the Sample +--- -1. Download or unzip the project and open the project in **Visual Studio 2022**. +## Key Features -2. Add the `NORTHWIND.MDF` database located in the `App_Data` folder of the backend project to the application. +- SQL Server → ASP.NET Core Web API → Angular architecture +- Syncfusion Angular Grid with paging, sorting, filtering, and searching +- DataManager + UrlAdaptor for remote data binding +- Full CRUD and batch operations +- Server‑side data processing -3. Replace the connected database's connection string in the `GridController.cs` file. +--- -4. In the Angular client project, open `app.component.ts` and replace the port number in the API URL where it says `xxxx` with the actual backend server port. +## Prerequisites -5. Navigate to the client project folder and run the following command: +- Node.js 18+ and Angular 16+ +- .NET SDK 8.0+ +- Microsoft SQL Server 2019+ +- Syncfusion Angular Grid and DataManager packages - ```bash - npm install - ``` -6. Build the project to restore dependencies and compile it. +--- -7. Run the project. \ No newline at end of file +## Architecture Overview + +The solution follows a simple three‑tier pattern: + +- **Database Layer**: SQL Server stores ticket data +- **Service Layer**: ASP.NET Core Web API exposes REST endpoints and processes Grid requests +- **UI Layer**: Angular application renders data using Syncfusion Grid + +This separation ensures scalability and maintainability. + +--- + +## Database Setup + +SQL Server hosts the application data in a `Tickets` table. The schema includes identifiers, status, priority, assignment details, and date fields required for Grid operations such as filtering, sorting, and paging. + +--- + +## Backend (ASP.NET Core Web API) + +The Web API connects Angular and SQL Server. + +### Responsibilities + +- Manage SQL Server connectivity +- Accept DataManager requests from the Grid +- Apply server‑side searching, filtering, sorting, and paging +- Handle CRUD and batch updates + +Configuration such as the connection string and CORS policy is managed through `appsettings.json` and `Program.cs`. + +--- + +## Angular Grid Integration + +The Syncfusion Angular Grid acts as the presentation layer. + +- Uses **DataManager** with **UrlAdaptor** to communicate with the API +- Sends Grid actions (read, search, filter, sort, page, CRUD) as HTTP requests +- Expects responses in `{ result, count }` format for paging + +Enabled Grid features include paging, sorting, filtering, searching, editing, and toolbar actions. + +--- + +## CRUD Operation Flow + +1. User performs an action in the Grid +2. DataManager sends the request to the Web API +3. API processes the request and interacts with SQL Server +4. API returns the result +5. Grid updates the UI + +This flow is consistent for insert, update, delete, and batch operations. + +--- + +## Running the Application + +**Step 1: Build and run the ASP.NET Core Server** + +1. Configure the `TicketDb` connection string in `appsettings.json`. +2. From the server project folder, run below command it terminal: + +```bash + dotnet build + dotnet run +``` + +**Explanation:** +- The API exposes endpoints at a base similar to `https://localhost:7000/api/tickets` (adjust ports as necessary). +- This endpoint is configured to DataManager url. + +**Step 2: Run the Angular Client** + +1. From the client folder install dependencies and start the Angular dev server: + +```bash + npm install + ng serve --open +``` + +**Step 3: Access the Application** + +1. Open a web browser. +2. Navigate to `http://localhost:53605` (or the port shown in the terminal). +3. The Network Support Ticket System is now running and ready to use. + +--- + +## Summary + +This minimal guide outlines how to integrate **Syncfusion Angular Grid** with **Microsoft SQL Server** through an **ASP.NET Core Web API**. The approach supports server‑side data operations and provides a clean foundation for enterprise‑ready Angular applications.