Optimized the the Appmenu controller
This commit is contained in:
parent
7cfebd764c
commit
ff288448b0
@ -1,26 +1,20 @@
|
||||
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.Bson;
|
||||
using MongoDB.Driver;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Collections.Specialized.BitVector32;
|
||||
|
||||
namespace Marco.Pms.CacheHelper
|
||||
{
|
||||
public class SideBarMenu
|
||||
public class SidebarMenuHelper
|
||||
{
|
||||
private readonly IMongoCollection<MenuSection> _collection;
|
||||
private readonly ILogger<SideBarMenu> _logger;
|
||||
private readonly ILogger<SidebarMenuHelper> _logger;
|
||||
|
||||
public SideBarMenu(IConfiguration configuration, ILogger<SideBarMenu> logger)
|
||||
public SidebarMenuHelper(IConfiguration configuration, ILogger<SidebarMenuHelper> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
var connectionString = configuration["MongoDB:ConnectionMenu"];
|
||||
var connectionString = configuration["MongoDB:ModificationConnectionString"];
|
||||
var mongoUrl = new MongoUrl(connectionString);
|
||||
var client = new MongoClient(mongoUrl);
|
||||
var database = client.GetDatabase(mongoUrl.DatabaseName);
|
||||
@ -108,7 +102,7 @@ namespace Marco.Pms.CacheHelper
|
||||
.Set("Items.$.Icon", updatedItem.Icon)
|
||||
.Set("Items.$.Available", updatedItem.Available)
|
||||
.Set("Items.$.Link", updatedItem.Link)
|
||||
.Set("Items.$.PermissionKeys", updatedItem.PermissionKeys); // <-- updated
|
||||
.Set("Items.$.PermissionIds", updatedItem.PermissionIds);
|
||||
|
||||
var result = await _collection.UpdateOneAsync(filter, update);
|
||||
|
||||
@ -166,18 +160,18 @@ namespace Marco.Pms.CacheHelper
|
||||
var filter = Builders<MenuSection>.Filter.Eq(s => s.Id, sectionId);
|
||||
|
||||
var arrayFilters = new List<ArrayFilterDefinition>
|
||||
{
|
||||
new BsonDocumentArrayFilterDefinition<BsonDocument>(
|
||||
new BsonDocument("item._id", itemId.ToString())),
|
||||
new BsonDocumentArrayFilterDefinition<BsonDocument>(
|
||||
new BsonDocument("sub._id", subItemId.ToString()))
|
||||
};
|
||||
{
|
||||
new BsonDocumentArrayFilterDefinition<BsonDocument>(
|
||||
new BsonDocument("item._id", itemId.ToString())),
|
||||
new BsonDocumentArrayFilterDefinition<BsonDocument>(
|
||||
new BsonDocument("sub._id", subItemId.ToString()))
|
||||
};
|
||||
|
||||
var update = Builders<MenuSection>.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].PermissionKeys", updatedSub.PermissionKeys); // <-- updated
|
||||
.Set("Items.$[item].Submenu.$[sub].PermissionKeys", updatedSub.PermissionIds);
|
||||
|
||||
var options = new UpdateOptions { ArrayFilters = arrayFilters };
|
||||
|
||||
@ -204,9 +198,25 @@ namespace Marco.Pms.CacheHelper
|
||||
|
||||
|
||||
|
||||
public async Task<List<MenuSection>> GetAllMenuSectionsAsync()
|
||||
public async Task<List<MenuSection>> GetAllMenuSectionsAsync(Guid tenantId)
|
||||
{
|
||||
return await _collection.Find(_ => true).ToListAsync();
|
||||
var filter = Builders<MenuSection>.Filter.Eq(e => e.TenantId, tenantId);
|
||||
|
||||
var result = await _collection
|
||||
.Find(filter)
|
||||
.ToListAsync();
|
||||
if (result.Any())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
tenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26");
|
||||
filter = Builders<MenuSection>.Filter.Eq(e => e.TenantId, tenantId);
|
||||
|
||||
result = await _collection
|
||||
.Find(filter)
|
||||
.ToListAsync();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
23
Marco.Pms.Model/AppMenu/MenuItem.cs
Normal file
23
Marco.Pms.Model/AppMenu/MenuItem.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
|
||||
namespace Marco.Pms.Model.AppMenu
|
||||
{
|
||||
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; } = true;
|
||||
|
||||
public string? Link { get; set; }
|
||||
|
||||
// Changed from string → List<string>
|
||||
public List<string> PermissionIds { get; set; } = new List<string>();
|
||||
|
||||
public List<SubMenuItem> Submenu { get; set; } = new List<SubMenuItem>();
|
||||
}
|
||||
}
|
21
Marco.Pms.Model/AppMenu/MenuSection.cs
Normal file
21
Marco.Pms.Model/AppMenu/MenuSection.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
|
||||
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<MenuItem> Items { get; set; } = new List<MenuItem>();
|
||||
|
||||
[BsonRepresentation(BsonType.String)]
|
||||
public Guid TenantId { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,51 +0,0 @@
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
|
||||
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<MenuItem> Items { get; set; } = new List<MenuItem>();
|
||||
}
|
||||
|
||||
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; } = true;
|
||||
|
||||
public string? Link { get; set; }
|
||||
|
||||
// Changed from string → List<string>
|
||||
public List<string> PermissionKeys { get; set; } = new List<string>();
|
||||
|
||||
public List<SubMenuItem> Submenu { get; set; } = new List<SubMenuItem>();
|
||||
}
|
||||
|
||||
public class SubMenuItem
|
||||
{
|
||||
[BsonId]
|
||||
[BsonRepresentation(BsonType.String)]
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
public string? Text { get; set; }
|
||||
public bool Available { get; set; } = true;
|
||||
|
||||
public string Link { get; set; } = string.Empty;
|
||||
|
||||
// Changed from string → List<string>
|
||||
public List<string> PermissionKeys { get; set; } = new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
|
20
Marco.Pms.Model/AppMenu/SubMenuItem.cs
Normal file
20
Marco.Pms.Model/AppMenu/SubMenuItem.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
|
||||
namespace Marco.Pms.Model.AppMenu
|
||||
{
|
||||
public class SubMenuItem
|
||||
{
|
||||
[BsonId]
|
||||
[BsonRepresentation(BsonType.String)]
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
|
||||
public string? Text { get; set; }
|
||||
public bool Available { get; set; } = true;
|
||||
|
||||
public string Link { get; set; } = string.Empty;
|
||||
|
||||
// Changed from string → List<string>
|
||||
public List<string> PermissionIds { get; set; } = new List<string>();
|
||||
}
|
||||
}
|
16
Marco.Pms.Model/Dtos/AppMenu/CreateMenuItemDto.cs
Normal file
16
Marco.Pms.Model/Dtos/AppMenu/CreateMenuItemDto.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace Marco.Pms.Model.Dtos.AppMenu
|
||||
{
|
||||
public class CreateMenuItemDto
|
||||
{
|
||||
public required string Text { get; set; }
|
||||
public required string Icon { get; set; }
|
||||
public bool Available { get; set; } = true;
|
||||
|
||||
public required string Link { get; set; }
|
||||
|
||||
// Changed from string → List<string>
|
||||
public List<string> PermissionIds { get; set; } = new List<string>();
|
||||
|
||||
public List<CreateSubMenuItemDto> Submenu { get; set; } = new List<CreateSubMenuItemDto>();
|
||||
}
|
||||
}
|
9
Marco.Pms.Model/Dtos/AppMenu/CreateMenuSectionDto.cs
Normal file
9
Marco.Pms.Model/Dtos/AppMenu/CreateMenuSectionDto.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace Marco.Pms.Model.Dtos.AppMenu
|
||||
{
|
||||
public class CreateMenuSectionDto
|
||||
{
|
||||
public required string Header { get; set; }
|
||||
public required string Title { get; set; }
|
||||
public List<CreateMenuItemDto> Items { get; set; } = new List<CreateMenuItemDto>();
|
||||
}
|
||||
}
|
13
Marco.Pms.Model/Dtos/AppMenu/CreateSubMenuItemDto.cs
Normal file
13
Marco.Pms.Model/Dtos/AppMenu/CreateSubMenuItemDto.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace Marco.Pms.Model.Dtos.AppMenu
|
||||
{
|
||||
public class CreateSubMenuItemDto
|
||||
{
|
||||
public required string Text { get; set; }
|
||||
public bool Available { get; set; } = true;
|
||||
|
||||
public required string Link { get; set; } = string.Empty;
|
||||
|
||||
// Changed from string → List<string>
|
||||
public List<string> PermissionIds { get; set; } = new List<string>();
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
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<MenuItemDto> Items { get; set; } = new List<MenuItemDto>();
|
||||
}
|
||||
|
||||
public class MenuItemDto
|
||||
{
|
||||
public string? Text { get; set; }
|
||||
public string? Icon { get; set; }
|
||||
public bool Available { get; set; } = true;
|
||||
|
||||
public string? Link { get; set; }
|
||||
|
||||
// Changed from string → List<string>
|
||||
public List<string> PermissionKeys { get; set; } = new List<string>();
|
||||
|
||||
public List<SubMenuItemDto> Submenu { get; set; } = new List<SubMenuItemDto>();
|
||||
}
|
||||
|
||||
public class SubMenuItemDto
|
||||
{
|
||||
public string? Text { get; set; }
|
||||
public bool Available { get; set; } = true;
|
||||
|
||||
public string Link { get; set; } = string.Empty;
|
||||
|
||||
// Changed from string → List<string>
|
||||
public List<string> PermissionKeys { get; set; } = new List<string>();
|
||||
}
|
||||
}
|
16
Marco.Pms.Model/Dtos/AppMenu/UpdateMenuItemDto.cs
Normal file
16
Marco.Pms.Model/Dtos/AppMenu/UpdateMenuItemDto.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace Marco.Pms.Model.Dtos.AppMenu
|
||||
{
|
||||
public class UpdateMenuItemDto
|
||||
{
|
||||
public required Guid Id { get; set; }
|
||||
|
||||
public required string Text { get; set; }
|
||||
public required string Icon { get; set; }
|
||||
public bool Available { get; set; } = true;
|
||||
|
||||
public required string Link { get; set; }
|
||||
|
||||
// Changed from string → List<string>
|
||||
public List<string> PermissionIds { get; set; } = new List<string>();
|
||||
}
|
||||
}
|
9
Marco.Pms.Model/Dtos/AppMenu/UpdateMenuSectionDto.cs
Normal file
9
Marco.Pms.Model/Dtos/AppMenu/UpdateMenuSectionDto.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace Marco.Pms.Model.Dtos.AppMenu
|
||||
{
|
||||
public class UpdateMenuSectionDto
|
||||
{
|
||||
public required Guid Id { get; set; }
|
||||
public required string Header { get; set; }
|
||||
public required string Title { get; set; }
|
||||
}
|
||||
}
|
15
Marco.Pms.Model/Dtos/AppMenu/UpdateSubMenuItemDto.cs
Normal file
15
Marco.Pms.Model/Dtos/AppMenu/UpdateSubMenuItemDto.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace Marco.Pms.Model.Dtos.AppMenu
|
||||
{
|
||||
public class UpdateSubMenuItemDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public string? Text { get; set; }
|
||||
public bool Available { get; set; } = true;
|
||||
|
||||
public string Link { get; set; } = string.Empty;
|
||||
|
||||
// Changed from string → List<string>
|
||||
public List<string> PermissionIds { get; set; } = new List<string>();
|
||||
}
|
||||
}
|
@ -5,9 +5,11 @@
|
||||
public static readonly Guid ManageTenants = Guid.Parse("d032cb1a-3f30-462c-bef0-7ace73a71c0b");
|
||||
public static readonly Guid ModifyTenant = Guid.Parse("00e20637-ce8d-4417-bec4-9b31b5e65092");
|
||||
public static readonly Guid ViewTenant = Guid.Parse("647145c6-2108-4c98-aab4-178602236e55");
|
||||
|
||||
public static readonly Guid DirectoryAdmin = Guid.Parse("4286a13b-bb40-4879-8c6d-18e9e393beda");
|
||||
public static readonly Guid DirectoryManager = Guid.Parse("62668630-13ce-4f52-a0f0-db38af2230c5");
|
||||
public static readonly Guid DirectoryUser = Guid.Parse("0f919170-92d4-4337-abd3-49b66fc871bb");
|
||||
|
||||
public static readonly Guid ViewProject = Guid.Parse("6ea44136-987e-44ba-9e5d-1cf8f5837ebc");
|
||||
public static readonly Guid ManageProject = Guid.Parse("172fc9b6-755b-4f62-ab26-55c34a330614");
|
||||
public static readonly Guid ManageTeam = Guid.Parse("b94802ce-0689-4643-9e1d-11c86950c35b");
|
||||
@ -17,15 +19,19 @@
|
||||
public static readonly Guid AddAndEditTask = Guid.Parse("08752f33-3b29-4816-b76b-ea8a968ed3c5");
|
||||
public static readonly Guid AssignAndReportProgress = Guid.Parse("6a32379b-8b3f-49a6-8c48-4b7ac1b55dc2");
|
||||
public static readonly Guid ApproveTask = Guid.Parse("db4e40c5-2ba9-4b6d-b8a6-a16a250ff99c");
|
||||
|
||||
public static readonly Guid ViewAllEmployees = Guid.Parse("60611762-7f8a-4fb5-b53f-b1139918796b");
|
||||
public static readonly Guid ViewTeamMembers = Guid.Parse("b82d2b7e-0d52-45f3-997b-c008ea460e7f");
|
||||
public static readonly Guid AddAndEditEmployee = Guid.Parse("a97d366a-c2bb-448d-be93-402bd2324566");
|
||||
public static readonly Guid AssignRoles = Guid.Parse("fbd213e0-0250-46f1-9f5f-4b2a1e6e76a3");
|
||||
|
||||
public static readonly Guid TeamAttendance = Guid.Parse("915e6bff-65f6-4e3f-aea8-3fd217d3ea9e");
|
||||
public static readonly Guid RegularizeAttendance = Guid.Parse("57802c4a-00aa-4a1f-a048-fd2f70dd44b6");
|
||||
public static readonly Guid SelfAttendance = Guid.Parse("ccb0589f-712b-43de-92ed-5b6088e7dc4e");
|
||||
|
||||
public static readonly Guid ViewMasters = Guid.Parse("5ffbafe0-7ab0-48b1-bb50-c1bf76b65f9d");
|
||||
public static readonly Guid ManageMasters = Guid.Parse("588a8824-f924-4955-82d8-fc51956cf323");
|
||||
|
||||
public static readonly Guid ExpenseViewSelf = Guid.Parse("385be49f-8fde-440e-bdbc-3dffeb8dd116");
|
||||
public static readonly Guid ExpenseViewAll = Guid.Parse("01e06444-9ca7-4df4-b900-8c3fa051b92f");
|
||||
public static readonly Guid ExpenseUpload = Guid.Parse("0f57885d-bcb2-4711-ac95-d841ace6d5a7");
|
||||
|
@ -1,24 +1,13 @@
|
||||
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.Model.ViewModels.AppMenu;
|
||||
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 MongoDB.Driver;
|
||||
using Org.BouncyCastle.Asn1.Ocsp;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Collections.Specialized.BitVector32;
|
||||
|
||||
namespace Marco.Pms.Services.Controllers
|
||||
{
|
||||
@ -29,151 +18,290 @@ namespace Marco.Pms.Services.Controllers
|
||||
{
|
||||
|
||||
private readonly UserHelper _userHelper;
|
||||
private readonly EmployeeHelper _employeeHelper;
|
||||
private readonly RolesHelper _rolesHelper;
|
||||
private readonly SideBarMenu _sideBarMenuHelper;
|
||||
private readonly SidebarMenuHelper _sideBarMenuHelper;
|
||||
private readonly IMapper _mapper;
|
||||
private readonly ILoggingService _logger;
|
||||
private readonly PermissionServices _permissions;
|
||||
private readonly Guid tenantId;
|
||||
private static readonly Guid superTenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26");
|
||||
|
||||
public AppMenuController(EmployeeHelper employeeHelper, IProjectServices projectServices, UserHelper userHelper, RolesHelper rolesHelper, SideBarMenu sideBarMenuHelper, IMapper mapper, ILoggingService logger, PermissionServices permissions)
|
||||
public AppMenuController(UserHelper userHelper,
|
||||
SidebarMenuHelper sideBarMenuHelper,
|
||||
IMapper mapper,
|
||||
ILoggingService logger,
|
||||
PermissionServices permissions)
|
||||
{
|
||||
|
||||
_userHelper = userHelper;
|
||||
_employeeHelper = employeeHelper;
|
||||
_rolesHelper = rolesHelper;
|
||||
_sideBarMenuHelper = sideBarMenuHelper;
|
||||
_mapper = mapper;
|
||||
_logger = logger;
|
||||
_permissions = permissions;
|
||||
tenantId = userHelper.GetTenantId();
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("sidebar/menu-section")]
|
||||
public async Task<IActionResult> CreateAppSideBarMenu([FromBody] MenuSectionDto MenuSecetion)
|
||||
/// <summary>
|
||||
/// Creates a new sidebar menu section for the tenant.
|
||||
/// Only accessible by root users or for the super tenant.
|
||||
/// </summary>
|
||||
/// <param name="menuSectionDto">The data for the new menu section.</param>
|
||||
/// <returns>HTTP response with result of the operation.</returns>
|
||||
|
||||
[HttpPost("add/sidebar/menu-section")]
|
||||
public async Task<IActionResult> CreateAppSideBarMenu([FromBody] CreateMenuSectionDto menuSectionDto)
|
||||
{
|
||||
// Step 1: Fetch logged-in user
|
||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
var isRootUser = loggedInEmployee.ApplicationUser?.IsRootUser ?? false;
|
||||
|
||||
|
||||
var user = await _userHelper.GetCurrentEmployeeAsync();
|
||||
|
||||
if (!(user.ApplicationUser?.IsRootUser ?? false))
|
||||
// Step 2: Authorization check
|
||||
if (!isRootUser || tenantId != superTenantId)
|
||||
{
|
||||
_logger.LogWarning("Access Denied while creating side menu");
|
||||
return StatusCode(403, ApiResponse<object>.ErrorResponse("access denied", "User haven't permission", 403));
|
||||
_logger.LogWarning("Access denied: Employee {EmployeeId} attempted to create sidebar menu in Tenant {TenantId}", loggedInEmployee.Id, tenantId);
|
||||
return StatusCode(403, ApiResponse<object>.ErrorResponse("Access Denied", "User does not have permission.", 403));
|
||||
}
|
||||
|
||||
var sideMenuSection = _mapper.Map<MenuSection>(MenuSecetion);
|
||||
// Step 3: Map DTO to entity
|
||||
var sideMenuSection = _mapper.Map<MenuSection>(menuSectionDto);
|
||||
sideMenuSection.TenantId = tenantId;
|
||||
|
||||
try
|
||||
{
|
||||
// Step 4: Save entity using helper
|
||||
sideMenuSection = await _sideBarMenuHelper.CreateMenuSectionAsync(sideMenuSection);
|
||||
|
||||
if (sideMenuSection == null)
|
||||
{
|
||||
_logger.LogWarning("Failed to create sidebar menu section. Tenant: {TenantId}, Request: {@MenuSectionDto}", tenantId, menuSectionDto);
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid MenuSection", 400));
|
||||
}
|
||||
|
||||
// Step 5: Log success
|
||||
_logger.LogInfo("Sidebar menu created successfully. SectionId: {SectionId}, TenantId: {TenantId}, EmployeeId: {EmployeeId}",
|
||||
sideMenuSection.Id, tenantId, loggedInEmployee.Id);
|
||||
|
||||
return Ok(ApiResponse<object>.SuccessResponse(sideMenuSection, "Sidebar menu created successfully.", 201));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error Occurred while creating Menu");
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Server Error", ex, 500));
|
||||
}
|
||||
// Step 6: Handle and log unexpected server errors
|
||||
_logger.LogError(ex, "Unexpected error occurred while creating sidebar menu. Tenant: {TenantId}, EmployeeId: {EmployeeId}, Request: {@MenuSectionDto}",
|
||||
tenantId, loggedInEmployee.Id, menuSectionDto);
|
||||
|
||||
if (sideMenuSection == null) {
|
||||
_logger.LogWarning("Error Occurred while creating Menu");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid MenuSection", 400));
|
||||
}
|
||||
|
||||
_logger.LogInfo("Error Occurred while creating Menu");
|
||||
return Ok(ApiResponse<object>.SuccessResponse(sideMenuSection, "Sidebar menu created successfully.", 201));
|
||||
|
||||
}
|
||||
|
||||
[HttpPut("sidebar/menu-section/{sectionId}")]
|
||||
public async Task<IActionResult> UpdateMenuSection(Guid sectionId, [FromBody] MenuSection updatedSection)
|
||||
{
|
||||
if (sectionId == Guid.Empty || updatedSection == null)
|
||||
{
|
||||
_logger.LogWarning("Error Occurred while Updating Menu Item");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid section ID, item ID, or menu item payload.", 400));
|
||||
}
|
||||
var UpdatedMenuSection = _mapper.Map<MenuSection>(updatedSection);
|
||||
try
|
||||
{
|
||||
UpdatedMenuSection = await _sideBarMenuHelper.UpdateMenuSectionAsync(sectionId, UpdatedMenuSection);
|
||||
|
||||
if (UpdatedMenuSection == null)
|
||||
return NotFound(ApiResponse<object>.ErrorResponse("Menu section not found", 404));
|
||||
|
||||
return Ok(ApiResponse<object>.SuccessResponse(UpdatedMenuSection, "Menu section updated successfully"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to update menu section");
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Server error", ex, 500));
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Server Error", "An unexpected error occurred.", 500));
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("sidebar/menus/{sectionId}/items")]
|
||||
public async Task<IActionResult> AddMenuItem(Guid sectionId, [FromBody] MenuItemDto newItemDto)
|
||||
/// <summary>
|
||||
/// Updates an existing sidebar menu section for the tenant.
|
||||
/// Only accessible by root users or for the super tenant.
|
||||
/// </summary>
|
||||
/// <param name="sectionId">The unique identifier of the section to update.</param>
|
||||
/// <param name="updatedSection">The updated data for the sidebar menu section.</param>
|
||||
/// <returns>HTTP response with the result of the operation.</returns>
|
||||
|
||||
[HttpPut("edit/sidebar/menu-section/{sectionId}")]
|
||||
public async Task<IActionResult> UpdateMenuSection(Guid sectionId, [FromBody] UpdateMenuSectionDto updatedSection)
|
||||
{
|
||||
if (sectionId == Guid.Empty || newItemDto == null)
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid input", 400));
|
||||
// Step 1: Fetch logged-in user
|
||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
var isRootUser = loggedInEmployee.ApplicationUser?.IsRootUser ?? false;
|
||||
|
||||
// Step 2: Authorization check
|
||||
if (!isRootUser && tenantId != superTenantId)
|
||||
{
|
||||
_logger.LogWarning("Access denied: User {UserId} attempted to update sidebar menu section {SectionId} in Tenant {TenantId}",
|
||||
loggedInEmployee.Id, sectionId, tenantId);
|
||||
|
||||
return StatusCode(403, ApiResponse<object>.ErrorResponse("Access Denied", "User does not have permission.", 403));
|
||||
}
|
||||
|
||||
// Step 3: Validate request
|
||||
if (sectionId == Guid.Empty || sectionId != updatedSection.Id)
|
||||
{
|
||||
_logger.LogWarning("Invalid update request. Tenant: {TenantId}, SectionId: {SectionId}, PayloadId: {PayloadId}, UserId: {UserId}",
|
||||
tenantId, sectionId, updatedSection.Id, loggedInEmployee.Id);
|
||||
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid section ID or mismatched payload.", 400));
|
||||
}
|
||||
|
||||
// Step 4: Map DTO to entity
|
||||
var menuSectionEntity = _mapper.Map<MenuSection>(updatedSection);
|
||||
|
||||
try
|
||||
{
|
||||
var menuItem = _mapper.Map<MenuItem>(newItemDto);
|
||||
|
||||
var result = await _sideBarMenuHelper.AddMenuItemAsync(sectionId, menuItem);
|
||||
// Step 5: Perform update operation
|
||||
var result = await _sideBarMenuHelper.UpdateMenuSectionAsync(sectionId, menuSectionEntity);
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
_logger.LogWarning("Menu section not found for update. SectionId: {SectionId}, TenantId: {TenantId}, UserId: {UserId}",
|
||||
sectionId, tenantId, loggedInEmployee.Id);
|
||||
return NotFound(ApiResponse<object>.ErrorResponse("Menu section not found", 404));
|
||||
}
|
||||
|
||||
_logger.LogInfo("Added MenuItem in Section: {SectionId}");
|
||||
// Step 6: Successful update
|
||||
_logger.LogInfo("Menu section updated successfully. SectionId: {SectionId}, TenantId: {TenantId}, UserId: {UserId}",
|
||||
sectionId, tenantId, loggedInEmployee.Id);
|
||||
|
||||
return Ok(ApiResponse<object>.SuccessResponse(result, "Menu section updated successfully"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Step 7: Unexpected server error
|
||||
_logger.LogError(ex, "Failed to update menu section. SectionId: {SectionId}, TenantId: {TenantId}, UserId: {UserId}, Payload: {@UpdatedSection}",
|
||||
sectionId, tenantId, loggedInEmployee.Id, updatedSection);
|
||||
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Server error", "An unexpected error occurred while updating the menu section.", 500));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new menu item to an existing sidebar menu section.
|
||||
/// Only accessible by root users or for the super tenant.
|
||||
/// </summary>
|
||||
/// <param name="sectionId">The unique identifier of the section the item will be added to.</param>
|
||||
/// <param name="newItemDto">The details of the new menu item.</param>
|
||||
/// <returns>HTTP response with the result of the operation.</returns>
|
||||
|
||||
[HttpPost("add/sidebar/menus/{sectionId}/items")]
|
||||
public async Task<IActionResult> AddMenuItem(Guid sectionId, [FromBody] CreateMenuItemDto newItemDto)
|
||||
{
|
||||
// Step 1: Fetch logged-in user
|
||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
var isRootUser = loggedInEmployee.ApplicationUser?.IsRootUser ?? false;
|
||||
|
||||
// Step 2: Authorization check
|
||||
if (!isRootUser && tenantId != superTenantId)
|
||||
{
|
||||
_logger.LogWarning("Access denied: User {UserId} attempted to add menu item to section {SectionId} in Tenant {TenantId}",
|
||||
loggedInEmployee.Id, sectionId, tenantId);
|
||||
|
||||
return StatusCode(403, ApiResponse<object>.ErrorResponse("Access Denied", "User does not have permission.", 403));
|
||||
}
|
||||
|
||||
// Step 3: Input validation
|
||||
if (sectionId == Guid.Empty || newItemDto == null)
|
||||
{
|
||||
_logger.LogWarning("Invalid AddMenuItem request. Tenant: {TenantId}, SectionId: {SectionId}, UserId: {UserId}",
|
||||
tenantId, sectionId, loggedInEmployee.Id);
|
||||
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid section ID or menu item payload.", 400));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Step 4: Map DTO to entity
|
||||
var menuItemEntity = _mapper.Map<MenuItem>(newItemDto);
|
||||
|
||||
// Step 5: Perform Add operation
|
||||
var result = await _sideBarMenuHelper.AddMenuItemAsync(sectionId, menuItemEntity);
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
_logger.LogWarning("Menu section not found. Unable to add menu item. SectionId: {SectionId}, TenantId: {TenantId}, UserId: {UserId}",
|
||||
sectionId, tenantId, loggedInEmployee.Id);
|
||||
|
||||
return NotFound(ApiResponse<object>.ErrorResponse("Menu section not found", 404));
|
||||
}
|
||||
|
||||
// Step 6: Successful addition
|
||||
_logger.LogInfo("Menu item added successfully. SectionId: {SectionId}, MenuItemId: {MenuItemId}, TenantId: {TenantId}, UserId: {UserId}",
|
||||
sectionId, result.Id, tenantId, loggedInEmployee.Id);
|
||||
|
||||
return Ok(ApiResponse<object>.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<object>.ErrorResponse("Server error", ex, 500));
|
||||
// Step 7: Handle unexpected errors
|
||||
_logger.LogError(ex, "Error occurred while adding menu item. SectionId: {SectionId}, TenantId: {TenantId}, UserId: {UserId}, Payload: {@NewItemDto}",
|
||||
sectionId, tenantId, loggedInEmployee.Id, newItemDto);
|
||||
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Server error", "An unexpected error occurred while adding the menu item.", 500));
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut("sidebar/{sectionId}/items/{itemId}")]
|
||||
public async Task<IActionResult> UpdateMenuItem(Guid sectionId, Guid itemId, [FromBody] MenuItemDto updatedMenuItem)
|
||||
/// <summary>
|
||||
/// Updates an existing menu item inside a sidebar menu section.
|
||||
/// Only accessible by root users or within the super tenant.
|
||||
/// </summary>
|
||||
/// <param name="sectionId">The ID of the sidebar menu section.</param>
|
||||
/// <param name="itemId">The ID of the menu item to update.</param>
|
||||
/// <param name="updatedMenuItem">The updated menu item details.</param>
|
||||
/// <returns>HTTP response with the result of the update operation.</returns>
|
||||
|
||||
[HttpPut("edit/sidebar/{sectionId}/items/{itemId}")]
|
||||
public async Task<IActionResult> UpdateMenuItem(Guid sectionId, Guid itemId, [FromBody] UpdateMenuItemDto updatedMenuItem)
|
||||
{
|
||||
// Step 1: Fetch logged-in user
|
||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
var isRootUser = loggedInEmployee.ApplicationUser?.IsRootUser ?? false;
|
||||
|
||||
if (sectionId == Guid.Empty || itemId == Guid.Empty || updatedMenuItem == null)
|
||||
// Step 2: Authorization check
|
||||
if (!isRootUser && tenantId != superTenantId)
|
||||
{
|
||||
_logger.LogWarning("Error Occurred while Updating Menu Item");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid section ID, item ID, or menu item payload.", 400));
|
||||
_logger.LogWarning("Access denied: User {UserId} attempted to update menu item {ItemId} in Section {SectionId}, Tenant {TenantId}",
|
||||
loggedInEmployee.Id, itemId, sectionId, tenantId);
|
||||
|
||||
return StatusCode(403, ApiResponse<object>.ErrorResponse("Access Denied", "User does not have permission.", 403));
|
||||
}
|
||||
|
||||
var sideMenuItem = _mapper.Map<MenuItem>(updatedMenuItem);
|
||||
// Step 3: Input validation
|
||||
if (sectionId == Guid.Empty || itemId == Guid.Empty || updatedMenuItem == null || updatedMenuItem.Id != itemId)
|
||||
{
|
||||
_logger.LogWarning("Invalid UpdateMenuItem request. Tenant: {TenantId}, SectionId: {SectionId}, ItemId: {ItemId}, UserId: {UserId}",
|
||||
tenantId, sectionId, itemId, loggedInEmployee.Id);
|
||||
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid section ID, item ID, or menu item payload.", 400));
|
||||
}
|
||||
|
||||
// Step 4: Map DTO to entity
|
||||
var menuItemEntity = _mapper.Map<MenuItem>(updatedMenuItem);
|
||||
|
||||
try
|
||||
{
|
||||
// Step 5: Perform update operation
|
||||
var result = await _sideBarMenuHelper.UpdateMenuItemAsync(sectionId, itemId, menuItemEntity);
|
||||
|
||||
sideMenuItem = await _sideBarMenuHelper.UpdateMenuItemAsync(sectionId, itemId, sideMenuItem);
|
||||
|
||||
if (sideMenuItem == null)
|
||||
if (result == null)
|
||||
{
|
||||
_logger.LogWarning("Error Occurred while Updating SidBar Section:{SectionId} MenuItem:{itemId} ");
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Menu creation failed", 400));
|
||||
_logger.LogWarning("Menu item not found or update failed. Tenant: {TenantId}, SectionId: {SectionId}, ItemId: {ItemId}, UserId: {UserId}",
|
||||
tenantId, sectionId, itemId, loggedInEmployee.Id);
|
||||
return NotFound(ApiResponse<object>.ErrorResponse("Menu item not found or update failed.", 404));
|
||||
}
|
||||
|
||||
_logger.LogInfo("SidBar Section{SectionId} MenuItem {itemId} Updated ");
|
||||
return Ok(ApiResponse<object>.SuccessResponse(sideMenuItem, "Sidebar MenuItem Updated successfully.", 201));
|
||||
// Step 6: Success log
|
||||
_logger.LogInfo("Menu item updated successfully. Tenant: {TenantId}, SectionId: {SectionId}, ItemId: {ItemId}, UserId: {UserId}",
|
||||
tenantId, sectionId, itemId, loggedInEmployee.Id);
|
||||
|
||||
return Ok(ApiResponse<object>.SuccessResponse(result, "Sidebar menu item updated successfully."));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
_logger.LogError(ex, "Error Occurred while creating MenuItem");
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Server Error", ex, 500));
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ✅ Step 7: Handle server errors
|
||||
_logger.LogError(ex, "Error occurred while updating menu item. Tenant: {TenantId}, SectionId: {SectionId}, ItemId: {ItemId}, UserId: {UserId}, Payload: {@UpdatedMenuItem}",
|
||||
tenantId, sectionId, itemId, loggedInEmployee.Id, updatedMenuItem);
|
||||
|
||||
return StatusCode(
|
||||
500,
|
||||
ApiResponse<object>.ErrorResponse("Server Error", "An unexpected error occurred while updating the menu item.", 500)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
[HttpPost("sidebar/menus/{sectionId}/items/{itemId}/subitems")]
|
||||
public async Task<IActionResult> AddSubMenuItem(Guid sectionId, Guid itemId, [FromBody] SubMenuItemDto newSubItem)
|
||||
|
||||
[HttpPost("add/sidebar/menus/{sectionId}/items/{itemId}/subitems")]
|
||||
public async Task<IActionResult> AddSubMenuItem(Guid sectionId, Guid itemId, [FromBody] CreateSubMenuItemDto newSubItem)
|
||||
{
|
||||
if (sectionId == Guid.Empty || itemId == Guid.Empty || newSubItem == null)
|
||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
var isRootUser = loggedInEmployee.ApplicationUser?.IsRootUser ?? false;
|
||||
if (!isRootUser && tenantId != superTenantId)
|
||||
{
|
||||
_logger.LogWarning("Access Denied while adding sub menu item");
|
||||
return StatusCode(403, ApiResponse<object>.ErrorResponse("access denied", "User haven't permission", 403));
|
||||
}
|
||||
if (sectionId == Guid.Empty || itemId == Guid.Empty)
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid input", 400));
|
||||
|
||||
try
|
||||
@ -199,10 +327,17 @@ namespace Marco.Pms.Services.Controllers
|
||||
}
|
||||
|
||||
|
||||
[HttpPut("sidebar/{sectionId}/items/{itemId}/subitems/{subItemId}")]
|
||||
public async Task<IActionResult> UpdateSubmenuItem(Guid sectionId, Guid itemId, Guid subItemId, [FromBody] SubMenuItemDto updatedSubMenuItem)
|
||||
[HttpPut("edit/sidebar/{sectionId}/items/{itemId}/subitems/{subItemId}")]
|
||||
public async Task<IActionResult> UpdateSubmenuItem(Guid sectionId, Guid itemId, Guid subItemId, [FromBody] UpdateSubMenuItemDto updatedSubMenuItem)
|
||||
{
|
||||
if (sectionId == Guid.Empty || itemId == Guid.Empty || subItemId == Guid.Empty || updatedSubMenuItem == null)
|
||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
var isRootUser = loggedInEmployee.ApplicationUser?.IsRootUser ?? false;
|
||||
if (!isRootUser && tenantId != superTenantId)
|
||||
{
|
||||
_logger.LogWarning("Access Denied while updating sub menu item");
|
||||
return StatusCode(403, ApiResponse<object>.ErrorResponse("access denied", "User haven't permission", 403));
|
||||
}
|
||||
if (sectionId == Guid.Empty || itemId == Guid.Empty || subItemId == Guid.Empty || updatedSubMenuItem.Id != subItemId)
|
||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid input", 400));
|
||||
|
||||
try
|
||||
@ -223,16 +358,22 @@ namespace Marco.Pms.Services.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("sidebar/menu-section")]
|
||||
/// <summary>
|
||||
/// Fetches the sidebar menu for the current tenant and filters items based on employee permissions.
|
||||
/// </summary>
|
||||
/// <returns>The sidebar menu with only the items/sub-items the employee has access to.</returns>
|
||||
|
||||
[HttpGet("get/menu")]
|
||||
public async Task<IActionResult> GetAppSideBarMenu()
|
||||
{
|
||||
var loggedUser = await _userHelper.GetCurrentEmployeeAsync();
|
||||
var employeeId = loggedUser.Id;
|
||||
// Step 1: Get logged-in employee
|
||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||
var employeeId = loggedInEmployee.Id;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
var menus = await _sideBarMenuHelper.GetAllMenuSectionsAsync();
|
||||
// Step 2: Fetch all menu sections for the tenant
|
||||
var menus = await _sideBarMenuHelper.GetAllMenuSectionsAsync(tenantId);
|
||||
|
||||
foreach (var menu in menus)
|
||||
{
|
||||
@ -240,77 +381,78 @@ namespace Marco.Pms.Services.Controllers
|
||||
|
||||
foreach (var item in menu.Items)
|
||||
{
|
||||
bool isAllowed = false;
|
||||
|
||||
if (item.PermissionKeys == null || !item.PermissionKeys.Any())
|
||||
// --- Item permission check ---
|
||||
if (!item.PermissionIds.Any())
|
||||
{
|
||||
isAllowed = true;
|
||||
allowedItems.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var pk in item.PermissionKeys)
|
||||
{
|
||||
if (Guid.TryParse(pk, out var permissionId))
|
||||
{
|
||||
if (await _permissions.HasPermission(permissionId, employeeId))
|
||||
{
|
||||
isAllowed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Convert permission string IDs to GUIDs
|
||||
var menuPermissionIds = item.PermissionIds
|
||||
.Select(Guid.Parse)
|
||||
.ToList();
|
||||
|
||||
if (isAllowed)
|
||||
{
|
||||
bool isAllowed = await _permissions.HasPermissionAny(menuPermissionIds, employeeId);
|
||||
|
||||
if (item.Submenu != null && item.Submenu.Any())
|
||||
// If allowed, filter its submenus as well
|
||||
if (isAllowed)
|
||||
{
|
||||
var allowedSubmenus = new List<SubMenuItem>();
|
||||
foreach (var sm in item.Submenu)
|
||||
if (item.Submenu?.Any() == true)
|
||||
{
|
||||
if (sm.PermissionKeys == null || !sm.PermissionKeys.Any())
|
||||
var allowedSubmenus = new List<SubMenuItem>();
|
||||
|
||||
foreach (var subItem in item.Submenu)
|
||||
{
|
||||
allowedSubmenus.Add(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var pk in sm.PermissionKeys)
|
||||
if (!subItem.PermissionIds.Any())
|
||||
{
|
||||
if (Guid.TryParse(pk, out var permissionId))
|
||||
{
|
||||
if (await _permissions.HasPermission(permissionId, employeeId))
|
||||
{
|
||||
allowedSubmenus.Add(sm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
allowedSubmenus.Add(subItem);
|
||||
continue;
|
||||
}
|
||||
|
||||
var subMenuPermissionIds = subItem.PermissionIds
|
||||
.Select(Guid.Parse)
|
||||
.ToList();
|
||||
|
||||
bool isSubItemAllowed = await _permissions.HasPermissionAny(subMenuPermissionIds, employeeId);
|
||||
|
||||
if (isSubItemAllowed)
|
||||
{
|
||||
allowedSubmenus.Add(subItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
item.Submenu = allowedSubmenus;
|
||||
}
|
||||
|
||||
allowedItems.Add(item);
|
||||
// Replace with filtered submenus
|
||||
item.Submenu = allowedSubmenus;
|
||||
}
|
||||
|
||||
allowedItems.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace with filtered items
|
||||
menu.Items = allowedItems;
|
||||
}
|
||||
|
||||
_logger.LogInfo("Fetched Sidebar Menu");
|
||||
return Ok(ApiResponse<object>.SuccessResponse(menus, "SideBar Menu Fetched successfully"));
|
||||
// Step 3: Log success
|
||||
_logger.LogInfo("Fetched sidebar menu successfully. Tenant: {TenantId}, EmployeeId: {EmployeeId}, SectionsReturned: {Count}",
|
||||
tenantId, employeeId, menus.Count);
|
||||
|
||||
return Ok(ApiResponse<object>.SuccessResponse(menus, "Sidebar menu fetched successfully"));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Step 4: Handle unexpected errors
|
||||
_logger.LogError(ex, "Error occurred while fetching sidebar menu. Tenant: {TenantId}, EmployeeId: {EmployeeId}",
|
||||
tenantId, employeeId);
|
||||
|
||||
_logger.LogError(ex, "Error Occurred while Updating Fetching Menu");
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Server Error", ex, 500));
|
||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Server Error", "An unexpected error occurred while fetching the sidebar menu.", 500));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,12 +70,13 @@ namespace MarcoBMS.Services.Helpers
|
||||
|
||||
// --- Step 3: Execute the main query on the main thread using its original context ---
|
||||
// This is now safe because the background task is using a different DbContext instance.
|
||||
var permissions = await (
|
||||
from rpm in _context.RolePermissionMappings
|
||||
join fp in _context.FeaturePermissions.Include(f => f.Feature)
|
||||
on rpm.FeaturePermissionId equals fp.Id
|
||||
where employeeRoleIdsQuery.Contains(rpm.ApplicationRoleId) && fp.IsEnabled == true
|
||||
select fp)
|
||||
var roleIds = await employeeRoleIdsQuery.ToListAsync();
|
||||
|
||||
var permissionIds = await _context.RolePermissionMappings
|
||||
.Where(rp => roleIds.Contains(rp.ApplicationRoleId)).Select(rp => rp.FeaturePermissionId).ToListAsync();
|
||||
|
||||
var permissions = await _context.FeaturePermissions.Include(f => f.Feature)
|
||||
.Where(fp => permissionIds.Contains(fp.Id))
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
using AutoMapper;
|
||||
using Marco.Pms.Model.Dtos.Expenses;
|
||||
using Marco.Pms.Model.Dtos.Master;
|
||||
using Marco.Pms.Model.AppMenu;
|
||||
using Marco.Pms.Model.Dtos.AppMenu;
|
||||
using Marco.Pms.Model.Dtos.Expenses;
|
||||
using Marco.Pms.Model.Dtos.Master;
|
||||
using Marco.Pms.Model.Dtos.Project;
|
||||
using Marco.Pms.Model.Dtos.Tenant;
|
||||
using Marco.Pms.Model.Employees;
|
||||
@ -309,9 +309,14 @@ namespace Marco.Pms.Services.MappingProfiles
|
||||
#endregion
|
||||
|
||||
#region ======================================================= AppMenu =======================================================
|
||||
CreateMap<MenuSectionDto, MenuSection>();
|
||||
CreateMap<MenuItemDto, MenuItem>();
|
||||
CreateMap<SubMenuItemDto, SubMenuItem>();
|
||||
CreateMap<CreateMenuSectionDto, MenuSection>();
|
||||
CreateMap<UpdateMenuSectionDto, MenuSection>();
|
||||
|
||||
CreateMap<CreateMenuItemDto, MenuItem>();
|
||||
CreateMap<UpdateMenuItemDto, MenuItem>();
|
||||
|
||||
CreateMap<CreateSubMenuItemDto, SubMenuItem>();
|
||||
CreateMap<UpdateSubMenuItemDto, SubMenuItem>();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ builder.Services.AddScoped<ProjectCache>();
|
||||
builder.Services.AddScoped<EmployeeCache>();
|
||||
builder.Services.AddScoped<ReportCache>();
|
||||
builder.Services.AddScoped<ExpenseCache>();
|
||||
builder.Services.AddScoped<SideBarMenu>();
|
||||
builder.Services.AddScoped<SidebarMenuHelper>();
|
||||
#endregion
|
||||
|
||||
// Singleton services (one instance for the app's lifetime)
|
||||
|
@ -30,6 +30,18 @@ namespace Marco.Pms.Services.Service
|
||||
var hasPermission = featurePermissionIds.Contains(featurePermissionId);
|
||||
return hasPermission;
|
||||
}
|
||||
public async Task<bool> HasPermissionAny(List<Guid> featurePermissionIds, Guid employeeId)
|
||||
{
|
||||
var allFeaturePermissionIds = await _cache.GetPermissions(employeeId);
|
||||
if (allFeaturePermissionIds == null)
|
||||
{
|
||||
List<FeaturePermission> featurePermission = await _rolesHelper.GetFeaturePermissionByEmployeeId(employeeId);
|
||||
allFeaturePermissionIds = featurePermission.Select(fp => fp.Id).ToList();
|
||||
}
|
||||
var hasPermission = featurePermissionIds.Any(f => allFeaturePermissionIds.Contains(f));
|
||||
|
||||
return hasPermission;
|
||||
}
|
||||
public async Task<bool> HasProjectPermission(Employee LoggedInEmployee, Guid projectId)
|
||||
{
|
||||
var employeeId = LoggedInEmployee.Id;
|
||||
|
Loading…
x
Reference in New Issue
Block a user