Hello, sure we will consider adding these exports to the relative indexes. Until then, you can reach the source code using suite as explained here: https://abp.io/docs/latest/suite/source-code
You can also get the source code to your project using abp add-package @volo/abp.ng.identity --with-source-code command.
Thank you for your cooperation.
Yes, you are right the proxy generation creates such functions by just checking the backend implementation. For your case, everything should be clear other than the generated uploadSchema function.
I can recommend you to have such approach:
Sending FormData input in such a way
public readonly proxyService = inject(FirstEntityService);
// ...
protected createFileRequest(file) {
formData.append('File', file);
formData.append('itemId', '21902787');
formData.append('tenantId', '7872091221902787');
return this.proxyService.uploadFile(formData);
}
Modifying the uploadFile function in the proxy as follows:
export class FirstEntityService {
// ...
uploadFile = (input: FormData, config?: Partial<Rest.Config>) =>
this.restService.request<any, AppFileDescriptorDto>(
{
method: 'POST',
url: '/api/app/first-entities/upload-file',
body: input,
},
{ apiName: this.apiName, ...config }
);
}
I can share a sample project if you would like to. You can also let us know if you need further assistance. Thank you for your cooperation.
Hello,
As my colleague has mentioned, you can pass the __tenant parameter for the authService.navigateToLogin() function.
https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/oauth/src/lib/strategies/auth-code-flow-strategy.ts#L78-L86
Here is how you could achieve that:
import { SessionStateService } from '@abp/ng.core';
// ...
export class HomeComponent {
// ...
sessionStateService = inject(SessionStateService);
login(){
const tenantId = this.sessionStateService.getTenant().id || null;
if(tenantId){
this.authService.navigateToLogin({
__tenant: `${tenantId}`
});
} else {
this.authService.navigateToLogin();
}
}
}
Hello,
After adding this registerLocale function to your module file
let localeMap = {} as { [key: string]: string };
export function registerLocale(
{
cultureNameLocaleFileMap = {},
errorHandlerFn = defaultLocalErrorHandlerFn,
} = {} as RegisterLocaleData
) {
return (locale: string): Promise<any> => {
localeMap = { ...differentLocales, ...cultureNameLocaleFileMap };
const localePath = `/locales/${localeMap[locale] || locale}`;
return new Promise((resolve, reject) => {
return import(
/* webpackMode: "lazy-once" */
/* webpackChunkName: "locales"*/
/* webpackInclude: /[/\\](ar|cs|en|en-GB|es|de|fi|fr|hi|hu|is|it|pt|tr|ru|ro|sk|sl|zh-Hans|zh-Hant)\.(mjs|js)$/ */
/* webpackExclude: /[/\\]global|extra/ */
/* @vite-ignore */
`@angular/common${localePath}`
)
.then(val => {
let module = val;
while (module.default) {
module = module.default;
}
resolve({ default: module });
})
.catch(error => {
errorHandlerFn({
resolve,
reject,
error,
locale,
});
});
});
};
}
Checking these points may be helpful:
Verify the webpack include pattern in the function
*/* webpackInclude: /[/\\](ar|cs|en|en-GB|es|de|fi|fr|hi|hu|is|it|pt|tr|ru|ro|sk|sl|zh-Hans|zh-Hant)\.(mjs|js)$/ */*
The pattern includes en but might not be matching the actual file structure.
Check if en.mjs exists in @angular/common/locales/
`ls angular/node_modules/@angular/common/locales/en*`
The core issue is that the locale files are not being found by the dynamic import, likely due to a path or webpack configuration mismatch.
This might be due to me unintentionally misleading you about importing IdentityModule for MyIdentityModule.
If removing that import doesn’t conflict with your requirements, things should work as expected.
//my-identity.module.ts
import { MyIdentityRoutingModule } from './my-identity-routing.module';
import { SharedModule } from './shared/shared.module';
import { NgModule } from '@angular/core';
@NgModule({
declarations: [],
imports: [SharedModule, MyIdentityRoutingModule],
exports: [MyIdentityRoutingModule],
})
export class MyIdentityModule {}
I see your point now. By this means, you may not even need to replace the UsersComponent Here is how you could achieve this:
//my-identity-routing.module.ts
import { RouterOutletComponent, authGuard, permissionGuard } from '@abp/ng.core';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { identityExtensionsResolver } from '@volo/abp.ng.identity';
import { UserDetailComponent } from './user-detail/user-detail.component';
import { UserResolver } from './my-users/users.resolver';
const routes: Routes = [
{ path: '', redirectTo: 'roles', pathMatch: 'full' },
{
path: '',
component: RouterOutletComponent,
canActivate: [authGuard, permissionGuard],
resolve: [identityExtensionsResolver],
children: [
{
path: 'users/:id',
component: UserDetailComponent,
title: 'AbpIdentity::Users',
resolve: { user: UserResolver },
},
],
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class MyIdentityRoutingModule {}
//my-identity.module.ts
import { IdentityModule } from '@volo/abp.ng.identity';
import { MyIdentityRoutingModule } from './my-identity-routing.module';
import { SharedModule } from './shared/shared.module';
import { NgModule } from '@angular/core';
@NgModule({
declarations: [],
imports: [IdentityModule, SharedModule, MyIdentityRoutingModule],
exports: [MyIdentityRoutingModule],
})
export class MyIdentityModule {}
Then in your app-routing.module.ts
{
path: 'identity',
loadChildren: () => import('./my-identity.module').then(m => m.MyIdentityModule),
},
// {
// path: 'identity',
// loadChildren: () => import('@volo/abp.ng.identity').then(m => m.IdentityModule.forLazy()),
// },
Hello,
Thank you for providing such detailed information. After reviewing the section where you appended values to the FormData while modifying the proxy, I noticed that you are trying to work with an object on the backend. You can still achieve this functionality without altering the current proxy setup.
These resources might be helpful:
How to Upload and Download Files in ABP: https://abp.io/community/articles/how-to-upload-and-download-files-in-the-abp-framework-using-angular-que8cdr8#gsc.tab=0
Using append() with FormData (MDN): https://developer.mozilla.org/en-US/docs/Web/API/FormData/append
Feel free to reach out if you need further assistance.
Hello,
If your goal is simply to display a detail page based on the user ID, there’s no need to override the IdentityRoutingModule. Instead, you can create a UserResolver as shown below:
@Injectable({ providedIn: 'root' })
export class UserResolver implements Resolve<IdentityUserDto> {
private userService = inject(IdentityUserService);
resolve(route: ActivatedRouteSnapshot): Observable<IdentityUserDto> {
const id = route.paramMap.get('id');
if (!id) {
throw new Error('User ID is required');
}
return this.userService.get(id);
}
}
You can then use this resolver in your routing configuration like so:
const routes: Routes = [
{
path: 'identity',
children: [
{
path: 'users/detail/:id',
component: UserDetailComponent,
resolve: { user: UserResolver },
},
{
path: '',
loadChildren: () =>
import('@volo/abp.ng.identity').then(m => m.IdentityModule.forLazy()),
},
],
},
// Alternative approach [#1](https://abp.io/QA/Questions/1):
// {
// path: 'identity',
// loadChildren: () => import('@volo/abp.ng.identity').then(m => m.IdentityModule.forLazy()),
// },
// {
// path: 'identity/users/detail/:id',
// component: UserDetailComponent,
// resolve: { user: UserResolver },
// },
// Alternative approach [#2](https://abp.io/QA/Questions/2):
// {
// path: 'users/:id',
// component: UserDetailComponent,
// title: 'New Users',
// resolve: { user: UserResolver },
// },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}
Feel free to reach out if you need any further clarification or assistance.
Hello,
Both templates are designed to support a modular structure.
I would like to know if it's possible to generate an Angular frontend in a microservice-based ABP project. If yes, could you please guide me on how to achieve this?
Yes, it is possible to generate an Angular frontend within a microservice-based ABP project. If you're unsure which template best fits your needs, I recommend reviewing the relevant documentation below:
Solution Template Guide: https://abp.io/docs/latest/solution-templates/guide
Microservice Tutorial: https://abp.io/docs/latest/tutorials/microservice?UI=NG&DB=EF
DDD Tutorial: https://abp.io/docs/latest/tutorials/modular-crm
Please feel free to reach out if you need further assistance.
Hello again,
I assume you're using the old CLI for this task. If that's the case, I'm encountering the same issues on my end, and we'll be looking into them. In the meantime, I recommend switching to the new CLI. You can find more information about the differences between the old and new versions here: https://abp.io/docs/latest/cli/differences-between-old-and-new-cli
Additionally, if you'd like to use the Lepton theme, make sure you have the following packages installed:
"@volo/abp.ng.theme.lepton": "~9.2.2",
"@volosoft/abp.ng.theme.lepton-x": "~4.2.1",
For more information on configuring themes, check out this guide: https://abp.io/docs/latest/framework/ui/angular/theme-configurations