Hello @ismcagdas I have checked the devtools, thanks for the suggestion, some properties are not supported though, like i can not see the dependency tree but it will be okay i believe. I was doing some readings about angular patterns, i have read interesting articles about a different design pattern called scam (single component angular module).
https://dev.to/this-is-angular/emulating-tree-shakable-components-using-single-component-angular-modules-13do https://angular-training-guide.rangle.io/modules/module-scam-pattern
is there any future plans for switching to scam pattern for anz?
Also is there any specific documentation about angular structural design for anz project? it would be helpful to see a doc about how to design the code structure for your shared modules and feature modules, and what naming conventions should be used? When your codebase grows it is becoming difficult to seperate modules and shared modules and when to add a new module. So i believe it would be helpful for everyone to see a documentation, when and how to create a feature module and how to keep them when your code grows.
For ex in current anz project shared modules structure is little bit confusing since it has common.module (the module for singleton services, this one is referring to the core module in angular docs i believe), utilsmodule, appcommon module, appshared module,mainshared module, adminshared module. It is difficult to follow what module is doing what.
when you want to create a new feature module in anz app, what kind of pattern we should use? for ex in admin folder of anz there are some examples but they are so basic, it does not cover the things i am listing below,
some kind of folder structure guidance like in this article can be helpful i believe https://itnext.io/angular-patterns-1-modules-organisation-d3b2224ec4cf
Please answer the following questions before submitting an issue. YOU MAY DELETE THE PREREQUISITES SECTION.
Hello i have few questions about shared modules. So as an intro here are the modules that is shared for admin (for admin folder) and app(for app folder).
@NgModule({
declarations: [
RoleComboComponent,
PermissionTreeComponent,
PermissionTreeModalComponent,
PermissionComboComponent,
OrganizationUnitsTreeComponent,
FeatureTreeComponent,
EditionComboComponent,
],
imports: [
AppSharedModule,
ReactiveFormsModule,
TreeModule,
TooltipModule,
FormsModule,
CommonModule,
UtilsModule,
AppCommonModule,
TableModule,
TreeModule,
DragDropModule,
ContextMenuModule,
PaginatorModule,
AutoCompleteModule,
EditorModule,
InputMaskModule,
CountoModule,
TextMaskModule,
ImageCropperModule,
PerfectScrollbarModule,
DropdownModule,
AppBsModalModule,
FileUploadModule,
PrimeNgFileUploadModule,
SubheaderModule,
],
exports: [
RoleComboComponent,
PermissionTreeComponent,
PermissionTreeModalComponent,
PermissionComboComponent,
OrganizationUnitsTreeComponent,
FeatureTreeComponent,
EditionComboComponent,
UtilsModule,
AppCommonModule,
TableModule,
TreeModule,
DragDropModule,
ContextMenuModule,
PaginatorModule,
AutoCompleteModule,
EditorModule,
InputMaskModule,
CountoModule,
TextMaskModule,
ImageCropperModule,
PerfectScrollbarModule,
DropdownModule,
AppBsModalModule,
AppSharedModule,
ReactiveFormsModule,
TreeModule,
TooltipModule,
FormsModule,
CommonModule,
FileUploadModule,
PrimeNgFileUploadModule,
SubheaderModule,
],
})
export class AdminSharedModule {}
const imports = [
CommonModule,
FormsModule,
HttpClientModule,
HttpClientJsonpModule,
ModalModule,
TabsModule,
BsDropdownModule,
PopoverModule,
BsDatepickerModule,
AppCommonModule,
FileUploadModule,
AppRoutingModule,
UtilsModule,
ServiceProxyModule,
TableModule,
PaginatorModule,
ProgressBarModule,
PerfectScrollbarModule,
TextMaskModule,
ImageCropperModule,
AutoCompleteModule,
NgxSpinnerModule,
AppBsModalModule,
];
@NgModule({
imports: [...imports],
exports: [...imports],
declarations: [ThemesLayoutBaseComponent],
})
export class AppSharedModule {}
Thank you for the assistance, looking forward for your reply.
thank you @ismcagdas
Please answer the following questions before submitting an issue. YOU MAY DELETE THE PREREQUISITES SECTION.
Hello, I have upgraded my project to v11 from v9.3 so i can see that moment library has changed to luxon and there is datetimeservice which do the date manipulation and formatting. So while i was inspecting the code i have found sth.
createUtcDate(year: number, month: number, day: number): DateTime {
return DateTime.utc(year, month + 1, day);
}
toUtcDate(date: DateTime | Date): DateTime {
if (date instanceof Date) {
return this.createUtcDate(date.getFullYear(), date.getMonth(), date.getDate());
}
return this.createUtcDate(date.year, date.month, date.day);
}
here is the code block from DateTimeService, I have 2 questions about this code block
createUtcDate(year: number, month: number, day: number): DateTime {
return DateTime.utc(year, month, day);
}
//change the timezone to utc with same values from local, keep local time values
toUtcDate(date: DateTime | Date): DateTime {
if (date instanceof Date) {
return this.createUtcDate(date.getFullYear(), date.getMonth() + 1, date.getDate());
}
return this.createUtcDate(date.year, date.month, date.day);
}
date.setZone("utc", { keepLocalTime: true });
i think if you are manipulating datetime objects it is better to use this version? maybe for js instances you can not do that? https://moment.github.io/luxon/#/zones?id=keeplocaltimeLooking forward for your reply, thanks again.
Hello @ismcagdas here i created the issue on github you can find the link here. https://github.com/aspnetzero/aspnet-zero-core/issues/3933
Hello @musa.demir probably i couldn't explain it well. If you log in as tenant user, you can not see the change default language action button since there is
<li>
<a href="javascript:;" class="dropdown-item"
*ngIf="'Pages.Administration.Languages.Edit' | permission"
(click)="setAsDefaultLanguage(record)">{{'SetAsDefaultLanguage' | localize}}</a>
</li>
above code block. If you look at *ngIf condition since it is a multitenant application, there is no permission defined for the tenant with the permission 'Pages.Administration.Languages.Edit'.
https://github.com/aspnetzero/aspnet-zero-core/commit/f19577b88825dc983d433ca5fde4031344a1f14e
as i see it here, if it is multitenant application Pages.Administration.Languages.Edit is defined on host not on tenant. so this button will not appear. am i missing sth over here?
Please answer the following questions before submitting an issue. YOU MAY DELETE THE PREREQUISITES SECTION.
Hello, Is it possible to change the default language for specific tenants in the application. When we upgrade our project to v9.3.0 from v8.1.0 the menu option has disappeared from the action button list in languages. So when i looked into it, there is an if condition in angular html page.
<li>
<a href="javascript:;" class="dropdown-item"
*ngIf="'Pages.Administration.Languages.Edit' | permission"
(click)="setAsDefaultLanguage(record)">{{'SetAsDefaultLanguage' | localize}}</a>
</li>
and on the server side permissions has been stated if it is a multitenant application the permission is created for the host. in AppAuthorizationProvider.cs
var languages = administration.CreateChildPermission(AppPermissions.Pages_Administration_Languages, L("Languages"));
languages.CreateChildPermission(AppPermissions.Pages_Administration_Languages_Create, L("CreatingNewLanguage"), multiTenancySides: _isMultiTenancyEnabled ? MultiTenancySides.Host : MultiTenancySides.Tenant);
languages.CreateChildPermission(AppPermissions.Pages_Administration_Languages_Edit, L("EditingLanguage"), multiTenancySides: _isMultiTenancyEnabled ? MultiTenancySides.Host : MultiTenancySides.Tenant);
languages.CreateChildPermission(AppPermissions.Pages_Administration_Languages_Delete, L("DeletingLanguages"), multiTenancySides: _isMultiTenancyEnabled ? MultiTenancySides.Host : MultiTenancySides.Tenant);
languages.CreateChildPermission(AppPermissions.Pages_Administration_Languages_ChangeTexts, L("ChangingTexts"));
so the question is if this is by design with the new version? or is it a bug? and when i look at the application service for changing default language,
public async Task SetDefaultLanguage(SetDefaultLanguageInput input)
{
await _applicationLanguageManager.SetDefaultLanguageAsync(
AbpSession.TenantId,
CultureHelper.GetCultureInfoByChecking(input.Name).Name
);
}
there is no permission restriction with abpauthorize? can you clarify this? Thank you for the assistance
Now every thing is crystal clear, thank you super much. So what i did at the end is to create custom filter like AbpAuthorizationFilter and add it in startup.cs, and now i don't need to define my methods in appservice as virtual, and i can use my attribute on other methods also. I always thought that interception is always handled by Castle.Windsor. I can close this incident now. Thank you again.
Thank you for the reply, yes it works when i make the method virtual but can you explain why the method should be virtual for it to work? I wasn't expecting virtual, cause for AbpAuthorize we do not need to make it virtual. Can you elaborate on that?
Hello, here are the steps.
1) to reproduce the problem you can do a get call to https://localhost:44301/api/services/app/MobileOffer/GetOffers
Expected value is unAuthorizedRequest:true in json response since you are not passing any token in the header
What i get is
{ "result": null, "targetUrl": null, "success": false, "error": { "code": 0, "message": "Your request is not valid!", "details": "The following errors were detected during validation.\r\n - A non-empty request body is required.\r\n", "validationErrors": [ { "message": "A non-empty request body is required.", "members": [ "" ] } ] }, "unAuthorizedRequest": false, "__abp": true }
Also I am expecting the [DoohclickAuthorize] attribute should intercept the call and check for AssociateSession, this does not happen either. 2) You can uncomment the convention config from startup.cs in web.host module services.PostConfigure<MvcOptions>(mvcOptions => { mvcOptions.Conventions.RemoveType<AbpAppServiceConvention>(); mvcOptions.Conventions.Add(new DoohclickAppServiceConvention(services)); }); if you do that and do a get call to https://localhost:44301/api/services/app/MobileOffer/GetOffers
then it authorizes the request and returns the method response.
Expected behavior is [DoohclickAuthorize] attribute should intercept the call and check for AssociateSession which will be null and do not authorize the request