Hi, can somebody please let me know why the functions and business logic for User (and Role) has been divided into 2 different places (UserManager and UserAppService)? I can see that the UserAppService sometimes using the functions within the UserManager. I am trying to understand the reason behind it so I could fallow the same principle with my own entities. In all demo and sample projects I have seen so far, all the business logic is supposed to be within the AppServices classes.
Thanks,
Hi Alper, After spending some time over the issue I have finally found out that the issue is in the side-bar-menu.component.html file. I made some changes and have got it worked. The Accordion menu item works fine now but if in the "Visual Settings" page the Submenu toggle mode changes to Dropdown from Accordion, there wont be any pop up for the nested submenu item. How can I report the issue and my half way solution to your team to have it fully fixed?
Hey Apler, Perhaps my bad explanation. I am trying to load nested menu items in Angular solution. The code sample you have shared however was for MVC. Here is my Angular manu structure:
getMenu(): AppMenu {
return new AppMenu('MainMenu', 'MainMenu', [
new AppMenuItem('Dashboard', 'Pages.Administration.Host.Dashboard', 'flaticon-line-graph', '/app/admin/hostDashboard'),
new AppMenuItem('Administration', '', 'flaticon-interface-8', '', [
new AppMenuItem('Jobs', 'Pages.Administration.Jobs', 'fa fa-tachometer', '', [
new AppMenuItem('JobLocations', 'Pages.Administration.Jobs.Locations', 'fa fa-map-marker', '/app/admin/job-locations'),
new AppMenuItem('JobClassifications', 'Pages.Administration.Jobs.Classifications', 'fa fa-object-group', '/app/admin/job-classifications'),
]),
new AppMenuItem('OrganizationUnits', 'Pages.Administration.OrganizationUnits', 'flaticon-map', '/app/admin/organization-units'),
])
]);
}
The JobLocation and JobClassification appear under the Job menu item but without indention and the Job menu item does not collapse like its own parent (Administration) menu item.
<cite>alper: </cite> I've added some sub menu items to the Metronic theme. It seems to be supporting many sub levels.
Hey alper, Would you please share the code you have used to generate the nested menu items? I can't see any specific issue in my own code that shared earlier!
Cheers,
Hi, How many nested level we can have within an AppMenuItem? I have got a side menu and trying to have 2 nested sub-menus but seems not more than one nested sub-menu is supported. Right?
new AppMenuItem('Administration', '', 'flaticon-interface-8', '', [
new AppMenuItem('Jobs', 'Pages.Administration.Jobs', 'fa fa-tachometer', '', [
new AppMenuItem('JobLocations', 'Pages.Administration.Jobs.Locations', 'fa fa-map-marker', '/app/admin/job-locations'),
new AppMenuItem('JobClassifications', 'Pages.Administration.Jobs.Classifications', 'fa fa-object-group', '/app/admin/job-classifications'),
]),
new AppMenuItem('OrganizationUnits', 'Pages.Administration.OrganizationUnits', 'flaticon-map', '/app/admin/organization-units'),
])
Here is a code I have got:
[AbpAuthorize(AppPermissions.Pages_Administration_JobLocations_Manage)]
public async Task<JobLocationDto> UpdateJobLocation(UpdateJobLocationInput input)
{
var jobLocation = await _jobLocationRepository.GetAsync(input.Id);
jobLocation.DisplayName = input.DisplayName;
await _jobLocationRepository.UpdateAsync(jobLocation);
//await EntityFrameworkCore.Repositories.RepositoryExtensions.UpdateOwnAsync(_jobLocationRepository, jobLocation);
return ObjectMapper.Map<JobLocationDto>(jobLocation);
}
The commented section works fine when uncommented but I wonder if there is any way of having the UpdateOwnAsync method instead of the UpdateAsync method on the _jobLocationRepository?
Is there any method to check if a request is coming from an Auhenticated user? Something such as IsUserAuthenticated....?
- Use the AbpAuthorize attribute
I know about the attribute but I have got a method which is available to both authenticated and unauthenticated users with 1 different behavior for each scenario:
public async Task<ListResultDto<JobLocationDto>> GetJobLocationList(GetJobLocationListInput input)
{
if (await _userManager.IsGrantedAsync(GetCurrentUser().Id, AppPermissions.Pages_Administration_JobLocations_Manage))
{
var jobLocations = await _jobLocationRepository.GetAll().Where(jobLocation => input.State == Common.VisibilityState.All ? (jobLocation.IsActive || !jobLocation.IsActive) :
input.State == Common.VisibilityState.Active ? jobLocation.IsActive : !jobLocation.IsActive).ToListAsync();
return new ListResultDto<JobLocationDto>(ObjectMapper.Map<List<JobLocationDto>>(jobLocations));
}
else
{
var jobLocations = await _jobLocationRepository.GetAll().Where(jobLocation => jobLocation.IsActive).ToListAsync();
return new ListResultDto<JobLocationDto>(ObjectMapper.Map<List<JobLocationDto>>(jobLocations));
}
}
The problem is that the IsGrantedAsync() fails and throws exception when no logged in user. So first I need to check if the request is coming from a logged in user or not
A new question: Is there any method to check if a request is coming from an Auhenticated user? Something such as IsUserAuthenticated....?
Thanks Aaron,
<cite>aaron: </cite> A helper like this can be implemented as an extension:
namespace AbpCompanyName.AbpProjectName.Domain.Repositories { public static class RepositoryExtensions { public static Task<TEntity> UpdateOwnAsync<TEntity, TPrimaryKey>(this IRepository<TEntity, TPrimaryKey> repository, TEntity entity) where TEntity : class, IEntity<TPrimaryKey>, ICreationAudited { var currentUserId = SingletonDependency<IAbpSession>.Instance.UserId; if (currentUserId != entity.CreatorUserId) { return null; // Or throw exception } return repository.UpdateAsync(entity); } } }
Usage:
// using AbpCompanyName.AbpProjectName.Domain.Repositories _repository.UpdateOwnAsync(entity);
That should be sufficient for you to modify it yourself if you want to:
- pass in "Own" as a parameter instead of the method name, or
- use it with updateAction.
Thanks Aaron, Just a couple of quick questions: Where should I place this RepositoryExtension? I put it in the RepositoryBase.cs file in the EntityFrameworkCore project. I didn't get what the _repository is in your usage sample! I doubt it'd be the RepositoryExtension class as you have defined it static. Here is how I am trying to use it:
public async Task<JobLocationDto> UpdateJobLocation(UpdateJobLocationInput input)
{
var jobLocation = await _jobLocationRepository.GetAsync(input.Id);
jobLocation.DisplayName = input.DisplayName;
await EntityFrameworkCore.Repositories.RepositoryExtensions.UpdateOwnAsync(_jobLocationRepository, jobLocation);
return ObjectMapper.Map<JobLocationDto>(jobLocation);
}
Is it right? Anyway that I could have the UpdateOwnAsync method in the normal repository list of methods rather than in another extension? Can I have a sample of how to use it with the upateAction parameter?
thanks a lot in advanced :)
Hi, I have just noticed the second parameter of the UpdateAsync method:
Task<TEntity> UpdateAsync(TPrimaryKey id, Func<TEntity, Task> updateAction);
Just wonder if there is any way of limiting users to Delete\Update their own entities by providing the second parameter of the method to check if entity is not for the user then cancel the entire updating process followed by a message that "you can't modify this entity!". I am literally looking for a generic way to limit users to their own entities rather than every time checking if the selected entity is for the user taking an action or not!
Any comment and a sample code would be much appreciated :)