From 56d3b754d99b20a95b23612c3c56932e3b438c85 Mon Sep 17 00:00:00 2001 From: pramod mahajan Date: Fri, 1 Aug 2025 14:50:00 +0530 Subject: [PATCH 01/11] side bar Menu Model define --- Marco.Pms.CacheHelper/SidebarMenu.cs | 14 ++++ Marco.Pms.Model/AppMenu/SideBarMenu.cs | 46 ++++++++++++ .../Controllers/AppMenuController.cs | 72 +++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 Marco.Pms.CacheHelper/SidebarMenu.cs create mode 100644 Marco.Pms.Model/AppMenu/SideBarMenu.cs create mode 100644 Marco.Pms.Services/Controllers/AppMenuController.cs diff --git a/Marco.Pms.CacheHelper/SidebarMenu.cs b/Marco.Pms.CacheHelper/SidebarMenu.cs new file mode 100644 index 0000000..31196b4 --- /dev/null +++ b/Marco.Pms.CacheHelper/SidebarMenu.cs @@ -0,0 +1,14 @@ +using Marco.Pms.Model.AppMenu; +using MongoDB.Driver; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Marco.Pms.CacheHelper +{ + + private readonly IMongoCollection? _collection; + +} diff --git a/Marco.Pms.Model/AppMenu/SideBarMenu.cs b/Marco.Pms.Model/AppMenu/SideBarMenu.cs new file mode 100644 index 0000000..8228cba --- /dev/null +++ b/Marco.Pms.Model/AppMenu/SideBarMenu.cs @@ -0,0 +1,46 @@ + +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Marco.Pms.Model.AppMenu +{ + public class MenuSection + { + [BsonId] + [BsonRepresentation(BsonType.String)] + public Guid Id { get; set; } = Guid.NewGuid(); + public string? Header { get; set; } + public string? Title { get; set; } + public List Items { get; set; } = new List(); + } + + public class MenuItem + { + [BsonId] + [BsonRepresentation(BsonType.String)] + public Guid Id { get; set; } = Guid.NewGuid(); + public string? Text { get; set; } + public string? Icon { get; set; } + public bool? Available { get; set; } + public string? Link { get; set; } + public List Submenu { get; set; } + } + + public class SubMenuItem + { + + [BsonId] + [BsonRepresentation(BsonType.String)] + public Guid Id { get; set; } = Guid.NewGuid(); + public string Text { get; set; } + public bool Available { get; set; } + public string Link { get; set; } + public string permissionKey { get; set; } + + } +} diff --git a/Marco.Pms.Services/Controllers/AppMenuController.cs b/Marco.Pms.Services/Controllers/AppMenuController.cs new file mode 100644 index 0000000..f84762a --- /dev/null +++ b/Marco.Pms.Services/Controllers/AppMenuController.cs @@ -0,0 +1,72 @@ +using Marco.Pms.Model.AppMenu; +using Marco.Pms.Model.Employees; +using Marco.Pms.Model.Entitlements; +using Marco.Pms.Services.Service; +using Marco.Pms.Services.Service.ServiceInterfaces; +using MarcoBMS.Services.Helpers; +using Microsoft.AspNetCore.Http.HttpResults; +using Microsoft.AspNetCore.Mvc; +using System.Threading.Tasks; + +namespace Marco.Pms.Services.Controllers +{ + public class AppMenuController + { + + private readonly UserHelper _userHelper; + private readonly EmployeeHelper _employeeHelper; + private readonly RolesHelper _rolesHelper; + + public AppMenuController(EmployeeHelper employeeHelper, IProjectServices projectServices, UserHelper userHelper, RolesHelper rolesHelper) { + + _userHelper = userHelper; + _employeeHelper = employeeHelper; + _rolesHelper = rolesHelper; + } + + + [HttpGet("/appMenu")] + + public async Task getAppSideBarMenu() + { + return Ok(); + } + + + [HttpPost("/create/appsidebar")] + public async Task PostAppSideBarMenu([FromForm] MenuSection sidebarmenu) + { + var user = await _userHelper.GetCurrentEmployeeAsync(); + Employee? loginUser = null; + + if (user != null) + { + loginUser = await _employeeHelper.GetEmployeeByApplicationUserID(user.Id.ToString()); + + + List featurePermission = await _rolesHelper.GetFeaturePermissionByEmployeeId(loginUser.Id); + string[] projectsId = []; + + + + + return Ok(loginUser); + } + + } + + + + + + + + + + + + + } + + +} From cc5badeb0f0813e9c84258bc06eb77e40a117c48 Mon Sep 17 00:00:00 2001 From: pramod mahajan Date: Sat, 2 Aug 2025 14:45:38 +0530 Subject: [PATCH 02/11] create menu api created --- Marco.Pms.CacheHelper/SidebarMenu.cs | 43 +++++++- Marco.Pms.Model/AppMenu/SideBarMenu.cs | 25 +++-- .../Dtos/AppMenu/SideBarMenuDtco.cs | 42 +++++++ .../Controllers/AppMenuController.cs | 85 +++++++++----- .../MappingProfiles/MappingProfile.cs | 8 ++ Marco.Pms.Services/Program.cs | 1 + .../appsettings.Development.json | 104 +++++++++--------- 7 files changed, 209 insertions(+), 99 deletions(-) create mode 100644 Marco.Pms.Model/Dtos/AppMenu/SideBarMenuDtco.cs diff --git a/Marco.Pms.CacheHelper/SidebarMenu.cs b/Marco.Pms.CacheHelper/SidebarMenu.cs index 31196b4..734d47a 100644 --- a/Marco.Pms.CacheHelper/SidebarMenu.cs +++ b/Marco.Pms.CacheHelper/SidebarMenu.cs @@ -1,14 +1,45 @@ -using Marco.Pms.Model.AppMenu; + +using Marco.Pms.Model.AppMenu; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; using MongoDB.Driver; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading.Tasks; namespace Marco.Pms.CacheHelper { - private readonly IMongoCollection? _collection; + public class SideBarMenu + { + private readonly IMongoCollection _collection; + private readonly ILogger _logger; -} + public SideBarMenu(IConfiguration configuration, ILogger logger) + { + _logger = logger; + var connectionString = configuration["MongoDB:ConnectionMenu"]; + var mongoUrl = new MongoUrl(connectionString); + var client = new MongoClient(mongoUrl); + var database = client.GetDatabase(mongoUrl.DatabaseName); + _collection = database.GetCollection("Menus"); + } + + public async Task CreateMenuSectionAsync(MenuSection section) + { + try + { + await _collection.InsertOneAsync(section); + return section; + } + catch(Exception ex) + { + _logger.LogError(ex, "Error occured while added in mongo"); + return null; + } + + } + + // You can add Get, Update, Delete later here + } + +} \ No newline at end of file diff --git a/Marco.Pms.Model/AppMenu/SideBarMenu.cs b/Marco.Pms.Model/AppMenu/SideBarMenu.cs index 8228cba..2d38fb4 100644 --- a/Marco.Pms.Model/AppMenu/SideBarMenu.cs +++ b/Marco.Pms.Model/AppMenu/SideBarMenu.cs @@ -1,11 +1,6 @@  using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Marco.Pms.Model.AppMenu { @@ -14,6 +9,7 @@ namespace Marco.Pms.Model.AppMenu [BsonId] [BsonRepresentation(BsonType.String)] public Guid Id { get; set; } = Guid.NewGuid(); + public string? Header { get; set; } public string? Title { get; set; } public List Items { get; set; } = new List(); @@ -24,23 +20,28 @@ namespace Marco.Pms.Model.AppMenu [BsonId] [BsonRepresentation(BsonType.String)] public Guid Id { get; set; } = Guid.NewGuid(); + public string? Text { get; set; } public string? Icon { get; set; } - public bool? Available { get; set; } + public bool Available { get; set; } = true; + public string? Link { get; set; } - public List Submenu { get; set; } + + public List Submenu { get; set; } = new List (); } public class SubMenuItem { - [BsonId] [BsonRepresentation(BsonType.String)] public Guid Id { get; set; } = Guid.NewGuid(); - public string Text { get; set; } - public bool Available { get; set; } - public string Link { get; set; } - public string permissionKey { get; set; } + public string? Text { get; set; } + public bool Available { get; set; } = true; + + public string Link { get; set; } = string.Empty; + + public string PermissionKey { get; set; } = string.Empty; } } + diff --git a/Marco.Pms.Model/Dtos/AppMenu/SideBarMenuDtco.cs b/Marco.Pms.Model/Dtos/AppMenu/SideBarMenuDtco.cs new file mode 100644 index 0000000..10b3495 --- /dev/null +++ b/Marco.Pms.Model/Dtos/AppMenu/SideBarMenuDtco.cs @@ -0,0 +1,42 @@ +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Marco.Pms.Model.Dtos.AppMenu +{ + public class MenuSectionDto + { + + public string? Header { get; set; } + public string? Title { get; set; } + public List Items { get; set; } = new List(); + } + + public class MenuItemDto + { + + public string? Text { get; set; } + public string? Icon { get; set; } + public bool Available { get; set; } = true; + + public string? Link { get; set; } + + public List Submenu { get; set; } = new List(); + } + + public class SubMenuItemDto + { + + + public string? Text { get; set; } + public bool Available { get; set; } = true; + + public string Link { get; set; } = string.Empty; + + public string PermissionKey { get; set; } = string.Empty; + } +} diff --git a/Marco.Pms.Services/Controllers/AppMenuController.cs b/Marco.Pms.Services/Controllers/AppMenuController.cs index f84762a..73dedd7 100644 --- a/Marco.Pms.Services/Controllers/AppMenuController.cs +++ b/Marco.Pms.Services/Controllers/AppMenuController.cs @@ -1,72 +1,97 @@ -using Marco.Pms.Model.AppMenu; +using AutoMapper; +using Azure; +using Marco.Pms.CacheHelper; +using Marco.Pms.Model.AppMenu; +using Marco.Pms.Model.Dtos.AppMenu; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Entitlements; +using Marco.Pms.Model.Utilities; using Marco.Pms.Services.Service; using Marco.Pms.Services.Service.ServiceInterfaces; using MarcoBMS.Services.Helpers; +using MarcoBMS.Services.Service; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; +using Org.BouncyCastle.Asn1.Ocsp; using System.Threading.Tasks; +using static System.Collections.Specialized.BitVector32; namespace Marco.Pms.Services.Controllers { - public class AppMenuController + [Authorize] + [ApiController] + [Route("api/[controller]")] + public class AppMenuController : ControllerBase { private readonly UserHelper _userHelper; private readonly EmployeeHelper _employeeHelper; private readonly RolesHelper _rolesHelper; + private readonly SideBarMenu _sideBarMenuHelper; + private readonly IMapper _mapper; + private readonly ILoggingService _logger; - public AppMenuController(EmployeeHelper employeeHelper, IProjectServices projectServices, UserHelper userHelper, RolesHelper rolesHelper) { + public AppMenuController(EmployeeHelper employeeHelper, IProjectServices projectServices, UserHelper userHelper, RolesHelper rolesHelper, SideBarMenu sideBarMenuHelper, IMapper mapper, ILoggingService logger) { _userHelper = userHelper; _employeeHelper = employeeHelper; _rolesHelper = rolesHelper; + _sideBarMenuHelper = sideBarMenuHelper; + _mapper = mapper; + _logger = logger; } - [HttpGet("/appMenu")] + //[HttpGet("/appMenu")] - public async Task getAppSideBarMenu() + //public async Task getAppSideBarMenu() + //{ + // return Ok(); + //} + + + [HttpPost("create/appsidebar")] + public async Task PostAppSideBarMenu([FromBody] MenuSectionDto sidebarMenu) { - return Ok(); - } - [HttpPost("/create/appsidebar")] - public async Task PostAppSideBarMenu([FromForm] MenuSection sidebarmenu) - { var user = await _userHelper.GetCurrentEmployeeAsync(); - Employee? loginUser = null; - if (user != null) + if (!(user.ApplicationUser?.IsRootUser ?? false)) { - loginUser = await _employeeHelper.GetEmployeeByApplicationUserID(user.Id.ToString()); - - - List featurePermission = await _rolesHelper.GetFeaturePermissionByEmployeeId(loginUser.Id); - string[] projectsId = []; - - - - - return Ok(loginUser); + _logger.LogWarning("Access Denied while creating side menu"); + return StatusCode(403, ApiResponse.ErrorResponse("access denied", "User haven't permission", 403)); } + var sideMenu = _mapper.Map(sidebarMenu); + try + { + sideMenu = await _sideBarMenuHelper.CreateMenuSectionAsync(sideMenu); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error Occurred while creating Menu"); + return StatusCode(500, ApiResponse.ErrorResponse("Server Error", ex, 500)); + } + + if (sideMenu == null) { + _logger.LogWarning("Error Occurred while creating Menu"); + return BadRequest(ApiResponse.ErrorResponse("Menu creation failed", 400)); + } + + _logger.LogInfo("Error Occurred while creating Menu"); + return Ok(ApiResponse.SuccessResponse(sideMenu, "Sidebar menu created successfully.", 201)); + + } + } - - - - - - + } - -} diff --git a/Marco.Pms.Services/MappingProfiles/MappingProfile.cs b/Marco.Pms.Services/MappingProfiles/MappingProfile.cs index bf3777c..f7705b6 100644 --- a/Marco.Pms.Services/MappingProfiles/MappingProfile.cs +++ b/Marco.Pms.Services/MappingProfiles/MappingProfile.cs @@ -1,4 +1,6 @@ using AutoMapper; +using Marco.Pms.Model.AppMenu; +using Marco.Pms.Model.Dtos.AppMenu; using Marco.Pms.Model.Dtos.Project; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Master; @@ -63,6 +65,12 @@ namespace Marco.Pms.Services.MappingProfiles #region ======================================================= Projects ======================================================= CreateMap(); #endregion + + #region ======================================================= AppMenu ======================================================= + CreateMap(); + CreateMap(); + CreateMap(); + #endregion } } } diff --git a/Marco.Pms.Services/Program.cs b/Marco.Pms.Services/Program.cs index 5549702..cb19a54 100644 --- a/Marco.Pms.Services/Program.cs +++ b/Marco.Pms.Services/Program.cs @@ -189,6 +189,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); #endregion // Singleton services (one instance for the app's lifetime) diff --git a/Marco.Pms.Services/appsettings.Development.json b/Marco.Pms.Services/appsettings.Development.json index 030c450..964fa26 100644 --- a/Marco.Pms.Services/appsettings.Development.json +++ b/Marco.Pms.Services/appsettings.Development.json @@ -1,53 +1,55 @@ { - "Cors": { - "AllowedOrigins": "*", - "AllowedMethods": "*", - "AllowedHeaders": "*" - }, - "Environment": { - "Name": "Development", - "Title": "Dev" - }, - "ConnectionStrings": { - "DefaultConnectionString": "Server=147.93.98.152;User ID=devuser;Password=AppUser@123$;Database=MarcoBMS1" - }, - "SmtpSettings": { - "SmtpServer": "smtp.gmail.com", - "Port": 587, - "SenderName": "MarcoAIOT", - "SenderEmail": "marcoioitsoft@gmail.com", - "Password": "qrtq wfuj hwpp fhqr" - }, - //"SmtpSettings": { - // "SmtpServer": "mail.marcoaiot.com", - // "Port": 587, - // "SenderName": "MarcoAIOT", - // "SenderEmail": "ashutosh.nehete@marcoaiot.com", - // "Password": "Reset@123" - //}, - "AppSettings": { - "WebFrontendUrl": "http://localhost:5173", - "ImagesBaseUrl": "http://localhost:5173" - }, - "Jwt": { - "Issuer": "http://localhost:5246", - "Audience": "http://localhost:5246", - "Key": "sworffishhkjfa9dnfdndfu33infnajfj", - "ExpiresInMinutes": 60, - "RefreshTokenExpiresInDays": 7 - }, - "MailingList": { - "RequestDemoReceivers": "ashutosh.nehete@marcoaiot.com;vikas@marcoaiot.com;umesh@marcoait.com" - //"ProjectStatisticsReceivers": "ashutosh.nehete@marcoaiot.com;vikas@marcoaiot.com;umesh@marcoait.com" - }, - "AWS": { - "AccessKey": "AKIARZDBH3VDMSUUY2FX", - "SecretKey": "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", - "Region": "us-east-1", - "BucketName": "testenv-marco-pms-documents" - }, - "MongoDB": { - "SerilogDatabaseUrl": "mongodb://localhost:27017/DotNetLogs", - "ConnectionString": "mongodb://localhost:27017/MarcoBMS_Caches?socketTimeoutMS=500&serverSelectionTimeoutMS=500&connectTimeoutMS=500" - } + "Cors": { + "AllowedOrigins": "*", + "AllowedMethods": "*", + "AllowedHeaders": "*" + }, + "Environment": { + "Name": "Development", + "Title": "Dev" + }, + "ConnectionStrings": { + "DefaultConnectionString": "Server=147.93.98.152;User ID=devuser;Password=AppUser@123$;Database=MarcoBMS1" + }, + "SmtpSettings": { + "SmtpServer": "smtp.gmail.com", + "Port": 587, + "SenderName": "MarcoAIOT", + "SenderEmail": "marcoioitsoft@gmail.com", + "Password": "qrtq wfuj hwpp fhqr" + }, + //"SmtpSettings": { + // "SmtpServer": "mail.marcoaiot.com", + // "Port": 587, + // "SenderName": "MarcoAIOT", + // "SenderEmail": "ashutosh.nehete@marcoaiot.com", + // "Password": "Reset@123" + //}, + "AppSettings": { + "WebFrontendUrl": "http://localhost:5173", + "ImagesBaseUrl": "http://localhost:5173" + }, + "Jwt": { + "Issuer": "http://localhost:5246", + "Audience": "http://localhost:5246", + "Key": "sworffishhkjfa9dnfdndfu33infnajfj", + "ExpiresInMinutes": 60, + "RefreshTokenExpiresInDays": 7 + }, + "MailingList": { + "RequestDemoReceivers": "ashutosh.nehete@marcoaiot.com;vikas@marcoaiot.com;umesh@marcoait.com" + //"ProjectStatisticsReceivers": "ashutosh.nehete@marcoaiot.com;vikas@marcoaiot.com;umesh@marcoait.com" + }, + "AWS": { + "AccessKey": "AKIARZDBH3VDMSUUY2FX", + "SecretKey": "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", + "Region": "us-east-1", + "BucketName": "testenv-marco-pms-documents" + }, + "MongoDB": { + "SerilogDatabaseUrl": "mongodb://devuser:DevPass123@147.93.98.152:27017/DotNetLogs?authSource=admin", + "ConnectionString": "mongodb://devuser:DevPass123@147.93.98.152:27017/DevelopmentCache?authSource=admin&socketTimeoutMS=500&serverSelectionTimeoutMS=500&connectTimeoutMS=500", + "ConnectionMenu": "mongodb://devuser:DevPass123@147.93.98.152:27017/UpdateLogs?authSource=admin&socketTimeoutMS=500&serverSelectionTimeoutMS=500&connectTimeoutMS=500", + + } } From 5988a980164db5ea713b0dbac16fd4a0b04cd0e8 Mon Sep 17 00:00:00 2001 From: pramod mahajan Date: Sun, 3 Aug 2025 02:20:51 +0530 Subject: [PATCH 03/11] created edit MenuItem and subMenuItem end -points --- Marco.Pms.CacheHelper/SidebarMenu.cs | 91 +++++++++++++++++-- .../Controllers/AppMenuController.cs | 81 +++++++++++++++-- 2 files changed, 155 insertions(+), 17 deletions(-) diff --git a/Marco.Pms.CacheHelper/SidebarMenu.cs b/Marco.Pms.CacheHelper/SidebarMenu.cs index 734d47a..8e5403c 100644 --- a/Marco.Pms.CacheHelper/SidebarMenu.cs +++ b/Marco.Pms.CacheHelper/SidebarMenu.cs @@ -1,14 +1,14 @@ - -using Marco.Pms.Model.AppMenu; +using Marco.Pms.Model.AppMenu; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using MongoDB.Driver; +using MongoDB.Bson; using System; +using System.Collections.Generic; using System.Threading.Tasks; namespace Marco.Pms.CacheHelper { - public class SideBarMenu { private readonly IMongoCollection _collection; @@ -31,15 +31,88 @@ namespace Marco.Pms.CacheHelper await _collection.InsertOneAsync(section); return section; } - catch(Exception ex) + catch (Exception ex) { - _logger.LogError(ex, "Error occured while added in mongo"); + _logger.LogError(ex, "Error occurred while adding MenuSection."); return null; } - } - // You can add Get, Update, Delete later here - } + public async Task UpdateMenuItemAsync(Guid sectionId, Guid itemId, MenuItem updatedItem) + { + try + { + var filter = Builders.Filter.And( + Builders.Filter.Eq(s => s.Id, sectionId), + Builders.Filter.ElemMatch(s => s.Items, i => i.Id == itemId) + ); -} \ No newline at end of file + var update = Builders.Update + .Set("Items.$.Text", updatedItem.Text) + .Set("Items.$.Icon", updatedItem.Icon) + .Set("Items.$.Available", updatedItem.Available) + .Set("Items.$.Link", updatedItem.Link); + + var result = await _collection.UpdateOneAsync(filter, update); + if (result.ModifiedCount > 0) + { + // Re-fetch section and return the updated item + var section = await _collection.Find(s => s.Id == sectionId).FirstOrDefaultAsync(); + return section?.Items.FirstOrDefault(i => i.Id == itemId); + } + + return null; + } + catch (Exception ex) + { + _logger.LogError(ex, "Error updating MenuItem."); + return null; + } + } + + + public async Task UpdateSubmenuItemAsync(Guid sectionId, Guid itemId, Guid subItemId, SubMenuItem updatedSub) + { + try + { + var filter = Builders.Filter.Eq(s => s.Id, sectionId); + + var arrayFilters = new List + { + new BsonDocumentArrayFilterDefinition( + new BsonDocument("item._id", itemId.ToString())), + new BsonDocumentArrayFilterDefinition( + new BsonDocument("sub._id", subItemId.ToString())) + }; + + var update = Builders.Update + .Set("Items.$[item].Submenu.$[sub].Text", updatedSub.Text) + .Set("Items.$[item].Submenu.$[sub].Available", updatedSub.Available) + .Set("Items.$[item].Submenu.$[sub].Link", updatedSub.Link) + .Set("Items.$[item].Submenu.$[sub].PermissionKey", updatedSub.PermissionKey); + + var options = new UpdateOptions { ArrayFilters = arrayFilters }; + + var result = await _collection.UpdateOneAsync(filter, update, options); + + if (result.ModifiedCount == 0) + return null; + + var updatedSection = await _collection.Find(x => x.Id == sectionId).FirstOrDefaultAsync(); + + var subItem = updatedSection?.Items + .FirstOrDefault(i => i.Id.ToString() == itemId.ToString())? + .Submenu + .FirstOrDefault(s => s.Id.ToString() == subItemId.ToString()); + + return subItem; + } + catch (Exception ex) + { + _logger.LogError(ex, "Error updating SubMenuItem."); + return null; + } + } + + } +} diff --git a/Marco.Pms.Services/Controllers/AppMenuController.cs b/Marco.Pms.Services/Controllers/AppMenuController.cs index 73dedd7..70591e1 100644 --- a/Marco.Pms.Services/Controllers/AppMenuController.cs +++ b/Marco.Pms.Services/Controllers/AppMenuController.cs @@ -13,6 +13,7 @@ using MarcoBMS.Services.Service; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; +using MongoDB.Driver; using Org.BouncyCastle.Asn1.Ocsp; using System.Threading.Tasks; using static System.Collections.Specialized.BitVector32; @@ -51,8 +52,8 @@ namespace Marco.Pms.Services.Controllers //} - [HttpPost("create/appsidebar")] - public async Task PostAppSideBarMenu([FromBody] MenuSectionDto sidebarMenu) + [HttpPost("sidebar/menusection")] + public async Task CreateAppSideBarMenu([FromBody] MenuSectionDto MenuSecetion) { @@ -64,10 +65,10 @@ namespace Marco.Pms.Services.Controllers return StatusCode(403, ApiResponse.ErrorResponse("access denied", "User haven't permission", 403)); } - var sideMenu = _mapper.Map(sidebarMenu); + var sideMenuSection = _mapper.Map(MenuSecetion); try { - sideMenu = await _sideBarMenuHelper.CreateMenuSectionAsync(sideMenu); + sideMenuSection = await _sideBarMenuHelper.CreateMenuSectionAsync(sideMenuSection); } catch (Exception ex) { @@ -75,23 +76,87 @@ namespace Marco.Pms.Services.Controllers return StatusCode(500, ApiResponse.ErrorResponse("Server Error", ex, 500)); } - if (sideMenu == null) { + if (sideMenuSection == null) { _logger.LogWarning("Error Occurred while creating Menu"); - return BadRequest(ApiResponse.ErrorResponse("Menu creation failed", 400)); + return BadRequest(ApiResponse.ErrorResponse("Invalid MenuSection", 400)); } _logger.LogInfo("Error Occurred while creating Menu"); - return Ok(ApiResponse.SuccessResponse(sideMenu, "Sidebar menu created successfully.", 201)); + return Ok(ApiResponse.SuccessResponse(sideMenuSection, "Sidebar menu created successfully.", 201)); } + [HttpPut("sidebar/{sectionId}/items/{itemId}")] + public async Task UpdateMenuItem(Guid sectionId, Guid itemId, [FromBody] MenuItemDto updatedMenuItem) + { + + if (sectionId == Guid.Empty || itemId == Guid.Empty || updatedMenuItem == null) + { + _logger.LogWarning("Error Occurred while creating Menu"); + return BadRequest(ApiResponse.ErrorResponse("Invalid section ID, item ID, or menu item payload.", 400)); + + } + + var sideMenuItem = _mapper.Map(updatedMenuItem); + + try + { + + sideMenuItem = await _sideBarMenuHelper.UpdateMenuItemAsync(sectionId, itemId, sideMenuItem); + + if (sideMenuItem == null) + { + _logger.LogWarning("Error Occurred while Updating SidBar Section:{SectionId} MenuItem:{itemId} "); + return BadRequest(ApiResponse.ErrorResponse("Menu creation failed", 400)); + } + + _logger.LogInfo("SidBar Section{SectionId} MenuItem {itemId} Updated "); + return Ok(ApiResponse.SuccessResponse(sideMenuItem, "Sidebar MenuItem Updated successfully.", 201)); + + } + catch (Exception ex) { + _logger.LogError(ex, "Error Occurred while creating MenuItem"); + return StatusCode(500, ApiResponse.ErrorResponse("Server Error", ex, 500)); + } + + } + [HttpPut("sidebar/{sectionId}/items/{itemId}/subitems/{subItemId}")] + public async Task UpdateSubmenuItem(Guid sectionId,Guid itemId,Guid subItemId,[FromBody] SubMenuItemDto updatedSubMenuItem) + { + if (sectionId == Guid.Empty || itemId == Guid.Empty || subItemId == Guid.Empty || updatedSubMenuItem == null) + return BadRequest(ApiResponse.ErrorResponse("Invalid input", 400)); + try + { + var SubMenuItem = _mapper.Map(updatedSubMenuItem); + SubMenuItem = await _sideBarMenuHelper.UpdateSubmenuItemAsync(sectionId, itemId, subItemId, SubMenuItem); - + if (SubMenuItem == null) + return NotFound(ApiResponse.ErrorResponse("Submenu item not found", 404)); + + _logger.LogInfo("SidBar Section{SectionId} MenuItem {itemId} SubMenuItem {subItemId} Updated"); + return Ok(ApiResponse.SuccessResponse(SubMenuItem, "Submenu item updated successfully")); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error Occurred while Updating Sub-MenuItem"); + return StatusCode(500, ApiResponse.ErrorResponse("Server Error", ex, 500)); + } + } } + + + + + + + + +} + From ee4e3f713ede390cd37db575182eba89205e5037 Mon Sep 17 00:00:00 2001 From: pramod mahajan Date: Sun, 3 Aug 2025 11:33:08 +0530 Subject: [PATCH 04/11] added two more end-point for Add Item and SubItem --- Marco.Pms.CacheHelper/SidebarMenu.cs | 82 ++++++++++++++++++ .../Controllers/AppMenuController.cs | 86 ++++++++++++++++++- 2 files changed, 166 insertions(+), 2 deletions(-) diff --git a/Marco.Pms.CacheHelper/SidebarMenu.cs b/Marco.Pms.CacheHelper/SidebarMenu.cs index 8e5403c..c1a3a27 100644 --- a/Marco.Pms.CacheHelper/SidebarMenu.cs +++ b/Marco.Pms.CacheHelper/SidebarMenu.cs @@ -37,6 +37,58 @@ namespace Marco.Pms.CacheHelper return null; } } + + public async Task UpdateMenuSectionAsync(Guid sectionId, MenuSection updatedSection) + { + try + { + var filter = Builders.Filter.Eq(s => s.Id, sectionId); + + var update = Builders.Update + .Set(s => s.Header, updatedSection.Header) + .Set(s => s.Title, updatedSection.Title); + + var result = await _collection.UpdateOneAsync(filter, update); + + if (result.ModifiedCount > 0) + { + return await _collection.Find(s => s.Id == sectionId).FirstOrDefaultAsync(); + } + + return null; + } + catch (Exception ex) + { + _logger.LogError(ex, "Error updating MenuSection."); + return null; + } + } + + public async Task AddMenuItemAsync(Guid sectionId, MenuItem newItem) + { + try + { + newItem.Id = Guid.NewGuid(); + + var filter = Builders.Filter.Eq(s => s.Id, sectionId); + + var update = Builders.Update.Push(s => s.Items, newItem); + + var result = await _collection.UpdateOneAsync(filter, update); + + if (result.ModifiedCount > 0) + { + return await _collection.Find(s => s.Id == sectionId).FirstOrDefaultAsync(); + } + + return null; + } + catch (Exception ex) + { + _logger.LogError(ex, "Error adding menu item."); + return null; + } + } public async Task UpdateMenuItemAsync(Guid sectionId, Guid itemId, MenuItem updatedItem) { @@ -70,6 +122,36 @@ namespace Marco.Pms.CacheHelper } } + public async Task AddSubMenuItemAsync(Guid sectionId, Guid itemId, SubMenuItem newSubItem) + { + try + { + newSubItem.Id = Guid.NewGuid(); + + // Match the MenuSection and the specific MenuItem inside it + var filter = Builders.Filter.And( + Builders.Filter.Eq(s => s.Id, sectionId), + Builders.Filter.ElemMatch(s => s.Items, i => i.Id == itemId) + ); + + // Use positional operator `$` to target matched MenuItem and push into its Submenu + var update = Builders.Update.Push("Items.$.Submenu", newSubItem); + + var result = await _collection.UpdateOneAsync(filter, update); + + if (result.ModifiedCount > 0) + { + return await _collection.Find(s => s.Id == sectionId).FirstOrDefaultAsync(); + } + + return null; + } + catch (Exception ex) + { + _logger.LogError(ex, "Error adding submenu item."); + return null; + } + } public async Task UpdateSubmenuItemAsync(Guid sectionId, Guid itemId, Guid subItemId, SubMenuItem updatedSub) { diff --git a/Marco.Pms.Services/Controllers/AppMenuController.cs b/Marco.Pms.Services/Controllers/AppMenuController.cs index 70591e1..13c5d7d 100644 --- a/Marco.Pms.Services/Controllers/AppMenuController.cs +++ b/Marco.Pms.Services/Controllers/AppMenuController.cs @@ -52,7 +52,7 @@ namespace Marco.Pms.Services.Controllers //} - [HttpPost("sidebar/menusection")] + [HttpPost("sidebar/menu-section")] public async Task CreateAppSideBarMenu([FromBody] MenuSectionDto MenuSecetion) { @@ -86,13 +86,66 @@ namespace Marco.Pms.Services.Controllers } + [HttpPut("sidebar/menu-section/{sectionId}")] + public async Task UpdateMenuSection(Guid sectionId,[FromBody] MenuSection updatedSection) + { + if (sectionId == Guid.Empty || updatedSection == null) + { + _logger.LogWarning("Error Occurred while Updating Menu Item"); + return BadRequest(ApiResponse.ErrorResponse("Invalid section ID, item ID, or menu item payload.", 400)); + } + var UpdatedMenuSection = _mapper.Map(updatedSection); + try + { + UpdatedMenuSection = await _sideBarMenuHelper.UpdateMenuSectionAsync(sectionId, UpdatedMenuSection); + + if (UpdatedMenuSection == null) + return NotFound(ApiResponse.ErrorResponse("Menu section not found", 404)); + + return Ok(ApiResponse.SuccessResponse(UpdatedMenuSection, "Menu section updated successfully")); + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to update menu section"); + return StatusCode(500, ApiResponse.ErrorResponse("Server error", ex, 500)); + } + } + + [HttpPost("sidebar/menus/{sectionId}/items")] + public async Task AddMenuItem(Guid sectionId, [FromBody] MenuItemDto newItemDto) + { + if (sectionId == Guid.Empty || newItemDto == null) + return BadRequest(ApiResponse.ErrorResponse("Invalid input", 400)); + + try + { + var menuItem = _mapper.Map(newItemDto); + + var result = await _sideBarMenuHelper.AddMenuItemAsync(sectionId, menuItem); + + if (result == null) + return NotFound(ApiResponse.ErrorResponse("Menu section not found", 404)); + + _logger.LogInfo("Added MenuItem in Section: {SectionId}"); + + return Ok(ApiResponse.SuccessResponse(result, "Menu item added successfully")); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error occurred while adding MenuItem inside MenuSection: {SectionId}", sectionId); + return StatusCode(500, ApiResponse.ErrorResponse("Server error", ex, 500)); + } + } + + + [HttpPut("sidebar/{sectionId}/items/{itemId}")] public async Task UpdateMenuItem(Guid sectionId, Guid itemId, [FromBody] MenuItemDto updatedMenuItem) { if (sectionId == Guid.Empty || itemId == Guid.Empty || updatedMenuItem == null) { - _logger.LogWarning("Error Occurred while creating Menu"); + _logger.LogWarning("Error Occurred while Updating Menu Item"); return BadRequest(ApiResponse.ErrorResponse("Invalid section ID, item ID, or menu item payload.", 400)); } @@ -122,6 +175,35 @@ namespace Marco.Pms.Services.Controllers } + [HttpPost("sidebar/menus/{sectionId}/items/{itemId}/subitems")] + public async Task AddSubMenuItem(Guid sectionId, Guid itemId, [FromBody] SubMenuItemDto newSubItem) + { + if (sectionId == Guid.Empty || itemId == Guid.Empty || newSubItem == null) + return BadRequest(ApiResponse.ErrorResponse("Invalid input", 400)); + + try + { + var subMenuItem = _mapper.Map(newSubItem); + + var result = await _sideBarMenuHelper.AddSubMenuItemAsync(sectionId, itemId, subMenuItem); + + if (result == null) + { + return NotFound(ApiResponse.ErrorResponse("Menu item not found", 404)); + + } + + _logger.LogInfo("Added SubMenuItem in Section: {SectionId}, MenuItem: {ItemId}"); + return Ok(ApiResponse.SuccessResponse(result, "Submenu item added successfully")); + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to add submenu item"); + return StatusCode(500, ApiResponse.ErrorResponse("Server error", ex, 500)); + } + } + + [HttpPut("sidebar/{sectionId}/items/{itemId}/subitems/{subItemId}")] public async Task UpdateSubmenuItem(Guid sectionId,Guid itemId,Guid subItemId,[FromBody] SubMenuItemDto updatedSubMenuItem) { From 6c394f40ad355dfac1e6c8f0c4ed65604337cb47 Mon Sep 17 00:00:00 2001 From: pramod mahajan Date: Mon, 4 Aug 2025 09:46:40 +0530 Subject: [PATCH 05/11] added PermissionKey inside MenuItem and start to making get api --- Marco.Pms.CacheHelper/SidebarMenu.cs | 3 ++- Marco.Pms.Model/AppMenu/SideBarMenu.cs | 2 ++ .../Dtos/AppMenu/SideBarMenuDtco.cs | 1 + .../Controllers/AppMenuController.cs | 21 ++++++++++++------- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Marco.Pms.CacheHelper/SidebarMenu.cs b/Marco.Pms.CacheHelper/SidebarMenu.cs index c1a3a27..5d0b02d 100644 --- a/Marco.Pms.CacheHelper/SidebarMenu.cs +++ b/Marco.Pms.CacheHelper/SidebarMenu.cs @@ -103,7 +103,8 @@ namespace Marco.Pms.CacheHelper .Set("Items.$.Text", updatedItem.Text) .Set("Items.$.Icon", updatedItem.Icon) .Set("Items.$.Available", updatedItem.Available) - .Set("Items.$.Link", updatedItem.Link); + .Set("Items.$.Link", updatedItem.Link) + .Set("Items.$.PermissionKey",updatedItem.PermissionKey); var result = await _collection.UpdateOneAsync(filter, update); if (result.ModifiedCount > 0) diff --git a/Marco.Pms.Model/AppMenu/SideBarMenu.cs b/Marco.Pms.Model/AppMenu/SideBarMenu.cs index 2d38fb4..a7c96db 100644 --- a/Marco.Pms.Model/AppMenu/SideBarMenu.cs +++ b/Marco.Pms.Model/AppMenu/SideBarMenu.cs @@ -27,6 +27,8 @@ namespace Marco.Pms.Model.AppMenu public string? Link { get; set; } + public string PermissionKey { get; set; } = string.Empty; + public List Submenu { get; set; } = new List (); } diff --git a/Marco.Pms.Model/Dtos/AppMenu/SideBarMenuDtco.cs b/Marco.Pms.Model/Dtos/AppMenu/SideBarMenuDtco.cs index 10b3495..a9d1bbe 100644 --- a/Marco.Pms.Model/Dtos/AppMenu/SideBarMenuDtco.cs +++ b/Marco.Pms.Model/Dtos/AppMenu/SideBarMenuDtco.cs @@ -25,6 +25,7 @@ namespace Marco.Pms.Model.Dtos.AppMenu public string? Link { get; set; } + public string PermissionKey { get; set; } = string.Empty; public List Submenu { get; set; } = new List(); } diff --git a/Marco.Pms.Services/Controllers/AppMenuController.cs b/Marco.Pms.Services/Controllers/AppMenuController.cs index 13c5d7d..d46640d 100644 --- a/Marco.Pms.Services/Controllers/AppMenuController.cs +++ b/Marco.Pms.Services/Controllers/AppMenuController.cs @@ -44,14 +44,6 @@ namespace Marco.Pms.Services.Controllers } - //[HttpGet("/appMenu")] - - //public async Task getAppSideBarMenu() - //{ - // return Ok(); - //} - - [HttpPost("sidebar/menu-section")] public async Task CreateAppSideBarMenu([FromBody] MenuSectionDto MenuSecetion) { @@ -228,7 +220,20 @@ namespace Marco.Pms.Services.Controllers } } + [HttpGet("sidebar/menu-section")] + public async Task GetAppSideBarMenu() + { + var LoggedUser = await _userHelper.GetCurrentUserAsync(); + + + + + + + return Ok(LoggedUser); + + } } From ff5f6734754e6a5af2085b6e5a320d9bf76ba255 Mon Sep 17 00:00:00 2001 From: pramod mahajan Date: Sun, 17 Aug 2025 12:55:53 +0530 Subject: [PATCH 06/11] initially added fetch menu api --- Marco.Pms.CacheHelper/SidebarMenu.cs | 25 +++++++++++++---- Marco.Pms.Model/AppMenu/SideBarMenu.cs | 14 ++++++---- .../Dtos/AppMenu/SideBarMenuDtco.cs | 13 ++++----- .../ViewModels/AppMenu/AppMenuVM.cs | 28 +++++++++++++++++++ .../Controllers/AppMenuController.cs | 9 ++++-- 5 files changed, 67 insertions(+), 22 deletions(-) create mode 100644 Marco.Pms.Model/ViewModels/AppMenu/AppMenuVM.cs diff --git a/Marco.Pms.CacheHelper/SidebarMenu.cs b/Marco.Pms.CacheHelper/SidebarMenu.cs index 5d0b02d..8ee9ed4 100644 --- a/Marco.Pms.CacheHelper/SidebarMenu.cs +++ b/Marco.Pms.CacheHelper/SidebarMenu.cs @@ -1,11 +1,14 @@ using Marco.Pms.Model.AppMenu; +using Marco.Pms.Model.Dtos.AppMenu; +using Marco.Pms.Model.ViewModels.AppMenu; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -using MongoDB.Driver; using MongoDB.Bson; +using MongoDB.Driver; using System; using System.Collections.Generic; using System.Threading.Tasks; +using static System.Collections.Specialized.BitVector32; namespace Marco.Pms.CacheHelper { @@ -46,7 +49,8 @@ namespace Marco.Pms.CacheHelper var update = Builders.Update .Set(s => s.Header, updatedSection.Header) - .Set(s => s.Title, updatedSection.Title); + .Set(s => s.Title, updatedSection.Title) + .Set(s => s.Items, updatedSection.Items); var result = await _collection.UpdateOneAsync(filter, update); @@ -104,9 +108,10 @@ namespace Marco.Pms.CacheHelper .Set("Items.$.Icon", updatedItem.Icon) .Set("Items.$.Available", updatedItem.Available) .Set("Items.$.Link", updatedItem.Link) - .Set("Items.$.PermissionKey",updatedItem.PermissionKey); + .Set("Items.$.PermissionKeys", updatedItem.PermissionKeys); // <-- updated var result = await _collection.UpdateOneAsync(filter, update); + if (result.ModifiedCount > 0) { // Re-fetch section and return the updated item @@ -172,7 +177,7 @@ namespace Marco.Pms.CacheHelper .Set("Items.$[item].Submenu.$[sub].Text", updatedSub.Text) .Set("Items.$[item].Submenu.$[sub].Available", updatedSub.Available) .Set("Items.$[item].Submenu.$[sub].Link", updatedSub.Link) - .Set("Items.$[item].Submenu.$[sub].PermissionKey", updatedSub.PermissionKey); + .Set("Items.$[item].Submenu.$[sub].PermissionKeys", updatedSub.PermissionKeys); // <-- updated var options = new UpdateOptions { ArrayFilters = arrayFilters }; @@ -184,9 +189,9 @@ namespace Marco.Pms.CacheHelper var updatedSection = await _collection.Find(x => x.Id == sectionId).FirstOrDefaultAsync(); var subItem = updatedSection?.Items - .FirstOrDefault(i => i.Id.ToString() == itemId.ToString())? + .FirstOrDefault(i => i.Id == itemId)? .Submenu - .FirstOrDefault(s => s.Id.ToString() == subItemId.ToString()); + .FirstOrDefault(s => s.Id == subItemId); return subItem; } @@ -197,5 +202,13 @@ namespace Marco.Pms.CacheHelper } } + + + public async Task> GetAllMenuSectionsAsync() + { + return await _collection.Find(_ => true).ToListAsync(); + } + + } } diff --git a/Marco.Pms.Model/AppMenu/SideBarMenu.cs b/Marco.Pms.Model/AppMenu/SideBarMenu.cs index a7c96db..cd826f0 100644 --- a/Marco.Pms.Model/AppMenu/SideBarMenu.cs +++ b/Marco.Pms.Model/AppMenu/SideBarMenu.cs @@ -1,5 +1,4 @@ - -using MongoDB.Bson; +using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; namespace Marco.Pms.Model.AppMenu @@ -27,9 +26,10 @@ namespace Marco.Pms.Model.AppMenu public string? Link { get; set; } - public string PermissionKey { get; set; } = string.Empty; + // Changed from string → List + public List PermissionKeys { get; set; } = new List(); - public List Submenu { get; set; } = new List (); + public List Submenu { get; set; } = new List(); } public class SubMenuItem @@ -38,12 +38,14 @@ namespace Marco.Pms.Model.AppMenu [BsonRepresentation(BsonType.String)] public Guid Id { get; set; } = Guid.NewGuid(); - public string? Text { get; set; } + public string? Text { get; set; } public bool Available { get; set; } = true; public string Link { get; set; } = string.Empty; - public string PermissionKey { get; set; } = string.Empty; + // Changed from string → List + public List PermissionKeys { get; set; } = new List(); } } + diff --git a/Marco.Pms.Model/Dtos/AppMenu/SideBarMenuDtco.cs b/Marco.Pms.Model/Dtos/AppMenu/SideBarMenuDtco.cs index a9d1bbe..e31759a 100644 --- a/Marco.Pms.Model/Dtos/AppMenu/SideBarMenuDtco.cs +++ b/Marco.Pms.Model/Dtos/AppMenu/SideBarMenuDtco.cs @@ -10,7 +10,6 @@ namespace Marco.Pms.Model.Dtos.AppMenu { public class MenuSectionDto { - public string? Header { get; set; } public string? Title { get; set; } public List Items { get; set; } = new List(); @@ -18,26 +17,26 @@ namespace Marco.Pms.Model.Dtos.AppMenu public class MenuItemDto { - public string? Text { get; set; } public string? Icon { get; set; } public bool Available { get; set; } = true; public string? Link { get; set; } - public string PermissionKey { get; set; } = string.Empty; + // Changed from string → List + public List PermissionKeys { get; set; } = new List(); + public List Submenu { get; set; } = new List(); } public class SubMenuItemDto { - - public string? Text { get; set; } public bool Available { get; set; } = true; public string Link { get; set; } = string.Empty; - public string PermissionKey { get; set; } = string.Empty; + // Changed from string → List + public List PermissionKeys { get; set; } = new List(); } -} +} \ No newline at end of file diff --git a/Marco.Pms.Model/ViewModels/AppMenu/AppMenuVM.cs b/Marco.Pms.Model/ViewModels/AppMenu/AppMenuVM.cs new file mode 100644 index 0000000..43d85c7 --- /dev/null +++ b/Marco.Pms.Model/ViewModels/AppMenu/AppMenuVM.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; + +namespace Marco.Pms.Model.ViewModels.AppMenu +{ + public class MenuSectionVm + { + public string? Header { get; set; } + public string? Title { get; set; } + public List Items { get; set; } = new(); + } + + public class MenuItemVm + { + public string? Text { get; set; } + public string? Icon { get; set; } + public bool Available { get; set; } = true; + public string? Link { get; set; } + public List Submenu { get; set; } = new(); + } + + public class SubMenuItemVm + { + public string? Text { get; set; } + public bool Available { get; set; } = true; + public string Link { get; set; } = string.Empty; + } +} diff --git a/Marco.Pms.Services/Controllers/AppMenuController.cs b/Marco.Pms.Services/Controllers/AppMenuController.cs index d46640d..f9c6633 100644 --- a/Marco.Pms.Services/Controllers/AppMenuController.cs +++ b/Marco.Pms.Services/Controllers/AppMenuController.cs @@ -32,8 +32,10 @@ namespace Marco.Pms.Services.Controllers private readonly SideBarMenu _sideBarMenuHelper; private readonly IMapper _mapper; private readonly ILoggingService _logger; + private readonly PermissionServices _permissions; - public AppMenuController(EmployeeHelper employeeHelper, IProjectServices projectServices, UserHelper userHelper, RolesHelper rolesHelper, SideBarMenu sideBarMenuHelper, IMapper mapper, ILoggingService logger) { + public AppMenuController(EmployeeHelper employeeHelper, IProjectServices projectServices, UserHelper userHelper, RolesHelper rolesHelper, SideBarMenu sideBarMenuHelper, IMapper mapper, ILoggingService logger, PermissionServices permissions = null) + { _userHelper = userHelper; _employeeHelper = employeeHelper; @@ -41,6 +43,7 @@ namespace Marco.Pms.Services.Controllers _sideBarMenuHelper = sideBarMenuHelper; _mapper = mapper; _logger = logger; + _permissions = permissions; } @@ -227,11 +230,11 @@ namespace Marco.Pms.Services.Controllers - + var menus = await _sideBarMenuHelper.GetAllMenuSectionsAsync(); - return Ok(LoggedUser); + return Ok(menus); } From 732cfbef3e208f04769e9d3ff710883748a28530 Mon Sep 17 00:00:00 2001 From: pramod mahajan Date: Mon, 18 Aug 2025 09:37:16 +0530 Subject: [PATCH 07/11] added permission for fetch menu according feature permission --- .../Controllers/AppMenuController.cs | 90 ++++++++++++++++--- 1 file changed, 79 insertions(+), 11 deletions(-) diff --git a/Marco.Pms.Services/Controllers/AppMenuController.cs b/Marco.Pms.Services/Controllers/AppMenuController.cs index f9c6633..9c5d557 100644 --- a/Marco.Pms.Services/Controllers/AppMenuController.cs +++ b/Marco.Pms.Services/Controllers/AppMenuController.cs @@ -6,6 +6,7 @@ using Marco.Pms.Model.Dtos.AppMenu; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Utilities; +using Marco.Pms.Model.ViewModels.AppMenu; using Marco.Pms.Services.Service; using Marco.Pms.Services.Service.ServiceInterfaces; using MarcoBMS.Services.Helpers; @@ -15,6 +16,7 @@ using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; using MongoDB.Driver; using Org.BouncyCastle.Asn1.Ocsp; +using System.Linq; using System.Threading.Tasks; using static System.Collections.Specialized.BitVector32; @@ -34,7 +36,7 @@ namespace Marco.Pms.Services.Controllers private readonly ILoggingService _logger; private readonly PermissionServices _permissions; - public AppMenuController(EmployeeHelper employeeHelper, IProjectServices projectServices, UserHelper userHelper, RolesHelper rolesHelper, SideBarMenu sideBarMenuHelper, IMapper mapper, ILoggingService logger, PermissionServices permissions = null) + public AppMenuController(EmployeeHelper employeeHelper, IProjectServices projectServices, UserHelper userHelper, RolesHelper rolesHelper, SideBarMenu sideBarMenuHelper, IMapper mapper, ILoggingService logger, PermissionServices permissions) { _userHelper = userHelper; @@ -71,7 +73,7 @@ namespace Marco.Pms.Services.Controllers return StatusCode(500, ApiResponse.ErrorResponse("Server Error", ex, 500)); } - if (sideMenuSection == null) { + if (sideMenuSection == null) { _logger.LogWarning("Error Occurred while creating Menu"); return BadRequest(ApiResponse.ErrorResponse("Invalid MenuSection", 400)); } @@ -82,7 +84,7 @@ namespace Marco.Pms.Services.Controllers } [HttpPut("sidebar/menu-section/{sectionId}")] - public async Task UpdateMenuSection(Guid sectionId,[FromBody] MenuSection updatedSection) + public async Task UpdateMenuSection(Guid sectionId, [FromBody] MenuSection updatedSection) { if (sectionId == Guid.Empty || updatedSection == null) { @@ -92,7 +94,7 @@ namespace Marco.Pms.Services.Controllers var UpdatedMenuSection = _mapper.Map(updatedSection); try { - UpdatedMenuSection = await _sideBarMenuHelper.UpdateMenuSectionAsync(sectionId, UpdatedMenuSection); + UpdatedMenuSection = await _sideBarMenuHelper.UpdateMenuSectionAsync(sectionId, UpdatedMenuSection); if (UpdatedMenuSection == null) return NotFound(ApiResponse.ErrorResponse("Menu section not found", 404)); @@ -142,7 +144,7 @@ namespace Marco.Pms.Services.Controllers { _logger.LogWarning("Error Occurred while Updating Menu Item"); return BadRequest(ApiResponse.ErrorResponse("Invalid section ID, item ID, or menu item payload.", 400)); - + } var sideMenuItem = _mapper.Map(updatedMenuItem); @@ -200,7 +202,7 @@ namespace Marco.Pms.Services.Controllers [HttpPut("sidebar/{sectionId}/items/{itemId}/subitems/{subItemId}")] - public async Task UpdateSubmenuItem(Guid sectionId,Guid itemId,Guid subItemId,[FromBody] SubMenuItemDto updatedSubMenuItem) + public async Task UpdateSubmenuItem(Guid sectionId, Guid itemId, Guid subItemId, [FromBody] SubMenuItemDto updatedSubMenuItem) { if (sectionId == Guid.Empty || itemId == Guid.Empty || subItemId == Guid.Empty || updatedSubMenuItem == null) return BadRequest(ApiResponse.ErrorResponse("Invalid input", 400)); @@ -226,18 +228,84 @@ namespace Marco.Pms.Services.Controllers [HttpGet("sidebar/menu-section")] public async Task GetAppSideBarMenu() { - var LoggedUser = await _userHelper.GetCurrentUserAsync(); - - + var loggedUser = await _userHelper.GetCurrentUserAsync(); + var employeeId = Guid.Parse(loggedUser.Id); var menus = await _sideBarMenuHelper.GetAllMenuSectionsAsync(); - + foreach (var menu in menus) + { + var allowedItems = new List(); - return Ok(menus); + foreach (var item in menu.Items) + { + bool isAllowed = false; + if (item.PermissionKeys == null || !item.PermissionKeys.Any()) + { + isAllowed = true; + } + else + { + foreach (var pk in item.PermissionKeys) + { + if (Guid.TryParse(pk, out var permissionId)) + { + if (await _permissions.HasPermission(employeeId, permissionId)) + { + isAllowed = true; + break; + } + } + } + } + + if (isAllowed) + { + + if (item.Submenu != null && item.Submenu.Any()) + { + var allowedSubmenus = new List(); + foreach (var sm in item.Submenu) + { + bool smAllowed = false; + if (sm.PermissionKeys == null || !sm.PermissionKeys.Any()) + { + smAllowed = true; + } + else + { + foreach (var pk in sm.PermissionKeys) + { + if (Guid.TryParse(pk, out var permissionId)) + { + if (await _permissions.HasPermission(employeeId, permissionId)) + { + smAllowed = true; + break; + } + } + } + } + + if (smAllowed) + allowedSubmenus.Add(sm); + } + item.Submenu = allowedSubmenus; + } + + allowedItems.Add(item); + } + } + + menu.Items = allowedItems; + } + + return Ok(menus); } + + } From 374e023cde4d56375c8f024f5f07f85b84bb7414 Mon Sep 17 00:00:00 2001 From: pramod mahajan Date: Mon, 18 Aug 2025 10:29:53 +0530 Subject: [PATCH 08/11] added perfectly permssion checking coondition and fixed previous mistake --- Marco.Pms.Services/Controllers/AppMenuController.cs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/Marco.Pms.Services/Controllers/AppMenuController.cs b/Marco.Pms.Services/Controllers/AppMenuController.cs index 9c5d557..cc48d16 100644 --- a/Marco.Pms.Services/Controllers/AppMenuController.cs +++ b/Marco.Pms.Services/Controllers/AppMenuController.cs @@ -228,8 +228,8 @@ namespace Marco.Pms.Services.Controllers [HttpGet("sidebar/menu-section")] public async Task GetAppSideBarMenu() { - var loggedUser = await _userHelper.GetCurrentUserAsync(); - var employeeId = Guid.Parse(loggedUser.Id); + var loggedUser = await _userHelper.GetCurrentEmployeeAsync(); + var employeeId = loggedUser.Id; var menus = await _sideBarMenuHelper.GetAllMenuSectionsAsync(); @@ -268,10 +268,9 @@ namespace Marco.Pms.Services.Controllers var allowedSubmenus = new List(); foreach (var sm in item.Submenu) { - bool smAllowed = false; if (sm.PermissionKeys == null || !sm.PermissionKeys.Any()) { - smAllowed = true; + allowedSubmenus.Add(sm); } else { @@ -281,15 +280,12 @@ namespace Marco.Pms.Services.Controllers { if (await _permissions.HasPermission(employeeId, permissionId)) { - smAllowed = true; + allowedSubmenus.Add(sm); break; } } } } - - if (smAllowed) - allowedSubmenus.Add(sm); } item.Submenu = allowedSubmenus; } @@ -305,7 +301,6 @@ namespace Marco.Pms.Services.Controllers } - } From 3ba954ac82f91d5ac45316d6f54617b0d9bac1e4 Mon Sep 17 00:00:00 2001 From: pramod mahajan Date: Mon, 18 Aug 2025 18:22:50 +0530 Subject: [PATCH 09/11] correct the order of haspermission method parameters --- Marco.Pms.Services/Controllers/AppMenuController.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Marco.Pms.Services/Controllers/AppMenuController.cs b/Marco.Pms.Services/Controllers/AppMenuController.cs index cc48d16..c0238a7 100644 --- a/Marco.Pms.Services/Controllers/AppMenuController.cs +++ b/Marco.Pms.Services/Controllers/AppMenuController.cs @@ -251,7 +251,7 @@ namespace Marco.Pms.Services.Controllers { if (Guid.TryParse(pk, out var permissionId)) { - if (await _permissions.HasPermission(employeeId, permissionId)) + if (await _permissions.HasPermission(permissionId,employeeId)) { isAllowed = true; break; @@ -278,7 +278,7 @@ namespace Marco.Pms.Services.Controllers { if (Guid.TryParse(pk, out var permissionId)) { - if (await _permissions.HasPermission(employeeId, permissionId)) + if (await _permissions.HasPermission(permissionId,employeeId)) { allowedSubmenus.Add(sm); break; From e8c8c92120e5d582798b24fcb89d8c91f5977ee6 Mon Sep 17 00:00:00 2001 From: pramod mahajan Date: Mon, 18 Aug 2025 23:31:18 +0530 Subject: [PATCH 10/11] handle error --- .../Controllers/AppMenuController.cs | 90 ++++++++++--------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/Marco.Pms.Services/Controllers/AppMenuController.cs b/Marco.Pms.Services/Controllers/AppMenuController.cs index c0238a7..12dc7ec 100644 --- a/Marco.Pms.Services/Controllers/AppMenuController.cs +++ b/Marco.Pms.Services/Controllers/AppMenuController.cs @@ -134,8 +134,6 @@ namespace Marco.Pms.Services.Controllers } } - - [HttpPut("sidebar/{sectionId}/items/{itemId}")] public async Task UpdateMenuItem(Guid sectionId, Guid itemId, [FromBody] MenuItemDto updatedMenuItem) { @@ -231,73 +229,85 @@ namespace Marco.Pms.Services.Controllers var loggedUser = await _userHelper.GetCurrentEmployeeAsync(); var employeeId = loggedUser.Id; - var menus = await _sideBarMenuHelper.GetAllMenuSectionsAsync(); - - foreach (var menu in menus) + try { - var allowedItems = new List(); - foreach (var item in menu.Items) + var menus = await _sideBarMenuHelper.GetAllMenuSectionsAsync(); + + foreach (var menu in menus) { - bool isAllowed = false; + var allowedItems = new List(); - if (item.PermissionKeys == null || !item.PermissionKeys.Any()) + foreach (var item in menu.Items) { - isAllowed = true; - } - else - { - foreach (var pk in item.PermissionKeys) + bool isAllowed = false; + + if (item.PermissionKeys == null || !item.PermissionKeys.Any()) { - if (Guid.TryParse(pk, out var permissionId)) + isAllowed = true; + } + else + { + foreach (var pk in item.PermissionKeys) { - if (await _permissions.HasPermission(permissionId,employeeId)) + if (Guid.TryParse(pk, out var permissionId)) { - isAllowed = true; - break; + if (await _permissions.HasPermission(permissionId, employeeId)) + { + isAllowed = true; + break; + } } } } - } - if (isAllowed) - { - - if (item.Submenu != null && item.Submenu.Any()) + if (isAllowed) { - var allowedSubmenus = new List(); - foreach (var sm in item.Submenu) + + if (item.Submenu != null && item.Submenu.Any()) { - if (sm.PermissionKeys == null || !sm.PermissionKeys.Any()) + var allowedSubmenus = new List(); + foreach (var sm in item.Submenu) { - allowedSubmenus.Add(sm); - } - else - { - foreach (var pk in sm.PermissionKeys) + if (sm.PermissionKeys == null || !sm.PermissionKeys.Any()) { - if (Guid.TryParse(pk, out var permissionId)) + allowedSubmenus.Add(sm); + } + else + { + foreach (var pk in sm.PermissionKeys) { - if (await _permissions.HasPermission(permissionId,employeeId)) + if (Guid.TryParse(pk, out var permissionId)) { - allowedSubmenus.Add(sm); - break; + if (await _permissions.HasPermission(permissionId, employeeId)) + { + allowedSubmenus.Add(sm); + break; + } } } } } + item.Submenu = allowedSubmenus; } - item.Submenu = allowedSubmenus; - } - allowedItems.Add(item); + allowedItems.Add(item); + } } + + menu.Items = allowedItems; } - menu.Items = allowedItems; + _logger.LogInfo("Fetched Sidebar Menu"); + return Ok(ApiResponse.SuccessResponse(menus, "SideBar Menu Fetched successfully")); + } + catch (Exception ex) { + + _logger.LogError(ex, "Error Occurred while Updating Fetching Menu"); + return StatusCode(500, ApiResponse.ErrorResponse("Server Error", ex, 500)); } - return Ok(menus); + } From ea1e172c656964fe7aa3f05e7abebbda976e1483 Mon Sep 17 00:00:00 2001 From: pramod mahajan Date: Sat, 23 Aug 2025 12:45:20 +0530 Subject: [PATCH 11/11] resolved conflicts --- Marco.Pms.Services/appsettings.Development.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Marco.Pms.Services/appsettings.Development.json b/Marco.Pms.Services/appsettings.Development.json index 964fa26..98347b0 100644 --- a/Marco.Pms.Services/appsettings.Development.json +++ b/Marco.Pms.Services/appsettings.Development.json @@ -9,7 +9,7 @@ "Title": "Dev" }, "ConnectionStrings": { - "DefaultConnectionString": "Server=147.93.98.152;User ID=devuser;Password=AppUser@123$;Database=MarcoBMS1" + "DefaultConnectionString": "Server=147.93.98.152;User ID=devuser;Password=AppUser@123$;Database=MarcoBMSDev" }, "SmtpSettings": { "SmtpServer": "smtp.gmail.com",