From e6a59fb6a272f53897d40fe1d104b46cdf3c24fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 17 Aug 2021 12:12:51 +0300 Subject: [PATCH 1/4] Added abp commercial 4.4 version note. --- .../2021-05-24-Removing-EfCore-Migrations/POST.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Community-Articles/2021-05-24-Removing-EfCore-Migrations/POST.md b/docs/en/Community-Articles/2021-05-24-Removing-EfCore-Migrations/POST.md index 15fbbc4678..d8fa243c3b 100644 --- a/docs/en/Community-Articles/2021-05-24-Removing-EfCore-Migrations/POST.md +++ b/docs/en/Community-Articles/2021-05-24-Removing-EfCore-Migrations/POST.md @@ -30,7 +30,7 @@ If you want to make it in your solution with today, follow the steps in this art > There is one **drawback** with the new design (everything in software development is a trade-off). We need to remove the `AppUser` entity, because EF Core can't map two classes to single table without an inheritance relation. I will cover this later in this article and provide suggestions to deal with it. -> If you are using **ABP Commercial**, ABP Suite code generation won't work correctly with the new design. In this case, we suggest to wait for the next version. +> If you are using **ABP Commercial**, ABP Suite code generation won't work correctly before the version 4.4. Please upgrade to v4.4 if you are using a previous version. ## The Steps From f01333ccb28ba23e69613070fd804d0a3e27575c Mon Sep 17 00:00:00 2001 From: bnymncoskuner Date: Tue, 17 Aug 2021 13:51:46 +0300 Subject: [PATCH 2/4] fix: use refreshAppState when updating config state --- .../src/lib/services/config-state.service.ts | 23 +++++++++-- .../src/lib/services/localization.service.ts | 11 +----- .../core/src/lib/states/config.state.ts | 38 +++++++++---------- .../src/lib/strategies/auth-flow.strategy.ts | 23 ++++------- .../packages/core/src/lib/utils/auth-utils.ts | 7 +--- .../core/src/lib/utils/initial-utils.ts | 7 +--- .../feature-management.component.ts | 17 +++------ .../permission-management.component.ts | 23 ++++------- 8 files changed, 62 insertions(+), 87 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts b/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts index eb2a0d30b6..69cf23e8a4 100644 --- a/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; -import { map, tap } from 'rxjs/operators'; +import { Observable, Subject } from 'rxjs'; +import { map, take, switchMap } from 'rxjs/operators'; import { ApplicationConfigurationDto } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/models'; import { InternalStore } from '../utils/internal-store-utils'; import { AbpApplicationConfigurationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service'; @@ -15,14 +15,29 @@ export class ConfigStateService { return this.store.sliceUpdate; } - constructor(private abpConfigService: AbpApplicationConfigurationService) {} + private updateSubject = new Subject(); + constructor(private abpConfigService: AbpApplicationConfigurationService) { + this.initUpdateStream(); + } + + private initUpdateStream() { + this.updateSubject + .pipe(switchMap(() => this.abpConfigService.get())) + .subscribe(res => this.setState(res)); + } + + /** + * @deprecated do not use this method directly, instead call refreshAppState + * This method will be private in v5.0 + */ setState(state: ApplicationConfigurationDto) { this.store.set(state); } refreshAppState() { - return this.abpConfigService.get().pipe(tap(res => this.setState(res))); + this.updateSubject.next(); + return this.createOnUpdateStream(state => state).pipe(take(1)); } getOne$(key: string) { diff --git a/npm/ng-packs/packages/core/src/lib/services/localization.service.ts b/npm/ng-packs/packages/core/src/lib/services/localization.service.ts index dc229a4c22..fe6e410f24 100644 --- a/npm/ng-packs/packages/core/src/lib/services/localization.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/localization.service.ts @@ -1,10 +1,9 @@ import { registerLocaleData } from '@angular/common'; import { Injectable, Injector, isDevMode, Optional, SkipSelf } from '@angular/core'; import { from, Observable, Subject } from 'rxjs'; -import { filter, map, mapTo, switchMap, tap } from 'rxjs/operators'; +import { filter, map, mapTo, switchMap } from 'rxjs/operators'; import { ABP } from '../models/common'; import { Config } from '../models/config'; -import { AbpApplicationConfigurationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service'; import { ApplicationConfigurationDto } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/models'; import { CORE_OPTIONS } from '../tokens/options.token'; import { createLocalizer, createLocalizerWithFallback } from '../utils/localization-utils'; @@ -35,7 +34,6 @@ export class LocalizationService { @SkipSelf() otherInstance: LocalizationService, private configState: ConfigStateService, - private appConfigService: AbpApplicationConfigurationService, ) { if (otherInstance) throw new Error('LocalizationService should have only one instance.'); @@ -49,12 +47,7 @@ export class LocalizationService { filter( lang => this.configState.getDeep('localization.currentCulture.cultureName') !== lang, ), - switchMap(lang => - this.appConfigService - .get() - .pipe(tap(res => this.configState.setState(res))) - .pipe(mapTo(lang)), - ), + switchMap(lang => this.configState.refreshAppState().pipe(mapTo(lang))), switchMap(lang => from(this.registerLocale(lang).then(() => lang))), ) .subscribe(lang => this._languageChange$.next(lang)); diff --git a/npm/ng-packs/packages/core/src/lib/states/config.state.ts b/npm/ng-packs/packages/core/src/lib/states/config.state.ts index 4cc2dc741d..455014e895 100644 --- a/npm/ng-packs/packages/core/src/lib/states/config.state.ts +++ b/npm/ng-packs/packages/core/src/lib/states/config.state.ts @@ -1,19 +1,17 @@ import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Action, createSelector, Selector, State, StateContext, Store } from '@ngxs/store'; -import { of, throwError } from 'rxjs'; -import { catchError, distinctUntilChanged, switchMap, tap } from 'rxjs/operators'; +import { throwError } from 'rxjs'; +import { catchError, distinctUntilChanged } from 'rxjs/operators'; import snq from 'snq'; import { GetAppConfiguration, PatchConfigState, SetEnvironment } from '../actions/config.actions'; import { RestOccurError } from '../actions/rest.actions'; -import { ApplicationConfiguration } from '../models/application-configuration'; import { Config } from '../models/config'; import { ConfigStateService } from '../services/config-state.service'; import { EnvironmentService } from '../services/environment.service'; import { SessionStateService } from '../services/session-state.service'; import { interpolate } from '../utils/string-utils'; import compare from 'just-compare'; -import { ApplicationConfigurationDto } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/models'; /** * @deprecated Use ConfigStateService instead. To be deleted in v5.0. @@ -143,11 +141,16 @@ export class ConfigState { } static getLocalizationResource(resourceName: string) { - const selector = createSelector([ConfigState], (state: Config.State): { - [key: string]: string; - } => { - return state.localization.values[resourceName]; - }); + const selector = createSelector( + [ConfigState], + ( + state: Config.State, + ): { + [key: string]: string; + } => { + return state.localization.values[resourceName]; + }, + ); return selector; } @@ -217,9 +220,7 @@ export class ConfigState { } constructor( - private http: HttpClient, private store: Store, - private sessionState: SessionStateService, private environmentService: EnvironmentService, private configState: ConfigStateService, ) { @@ -245,15 +246,12 @@ export class ConfigState { addData({ patchState, dispatch }: StateContext) { const apiName = 'default'; const api = this.store.selectSnapshot(ConfigState.getApiUrl(apiName)); - return this.http - .get(`${api}/api/abp/application-configuration`) - .pipe( - tap(configuration => this.configState.setState(configuration)), - catchError((err: HttpErrorResponse) => { - dispatch(new RestOccurError(err)); - return throwError(err); - }), - ); + return this.configState.refreshAppState().pipe( + catchError((err: HttpErrorResponse) => { + dispatch(new RestOccurError(err)); + return throwError(err); + }), + ); } @Action(SetEnvironment) diff --git a/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts b/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts index 4cb959ac45..001d0e8842 100644 --- a/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts +++ b/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts @@ -13,7 +13,6 @@ import { from, Observable, of, pipe } from 'rxjs'; import { filter, switchMap, tap } from 'rxjs/operators'; import { RestOccurError } from '../actions/rest.actions'; import { LoginParams } from '../models/auth'; -import { AbpApplicationConfigurationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service'; import { ConfigStateService } from '../services/config-state.service'; import { EnvironmentService } from '../services/environment.service'; import { SessionStateService } from '../services/session-state.service'; @@ -32,7 +31,6 @@ export abstract class AuthFlowStrategy { protected oAuthService: OAuthService; protected oAuthConfig: AuthConfig; protected sessionState: SessionStateService; - protected appConfigService: AbpApplicationConfigurationService; protected tenantKey: string; abstract checkIfInternalAuth(queryParams?: Params): boolean; @@ -47,7 +45,6 @@ export abstract class AuthFlowStrategy { this.environment = injector.get(EnvironmentService); this.configState = injector.get(ConfigStateService); this.oAuthService = injector.get(OAuthService); - this.appConfigService = injector.get(AbpApplicationConfigurationService); this.sessionState = injector.get(SessionStateService); this.oAuthConfig = this.environment.getEnvironment().oAuthConfig; this.tenantKey = injector.get(TENANT_KEY); @@ -84,11 +81,9 @@ export abstract class AuthFlowStrategy { .pipe( filter(event => event instanceof OAuthErrorEvent), tap(() => clearOAuthStorage()), - switchMap(() => this.appConfigService.get()), + switchMap(() => this.configState.refreshAppState()), ) - .subscribe(res => { - this.configState.setState(res); - }); + .subscribe(); } } @@ -148,9 +143,7 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { } else { this.oAuthService.logOut(); removeRememberMe(); - this.appConfigService.get().subscribe(res => { - this.configState.setState(res); - }); + this.configState.refreshAppState().subscribe(); } }); } @@ -188,9 +181,8 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { const router = this.injector.get(Router); return pipe( - switchMap(() => this.appConfigService.get()), - tap(res => { - this.configState.setState(res); + switchMap(() => this.configState.refreshAppState()), + tap(() => { setRememberMe(params.rememberMe); if (params.redirectUrl) router.navigate([params.redirectUrl]); }), @@ -201,9 +193,8 @@ export class AuthPasswordFlowStrategy extends AuthFlowStrategy { const router = this.injector.get(Router); return from(this.oAuthService.revokeTokenAndLogout(queryParams)).pipe( - switchMap(() => this.appConfigService.get()), - tap(res => { - this.configState.setState(res); + switchMap(() => this.configState.refreshAppState()), + tap(() => { router.navigateByUrl('/'); removeRememberMe(); }), diff --git a/npm/ng-packs/packages/core/src/lib/utils/auth-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/auth-utils.ts index 44da3f7c4a..10fe1e1177 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/auth-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/auth-utils.ts @@ -4,7 +4,6 @@ import { OAuthStorage, TokenResponse } from 'angular-oauth2-oidc'; import { pipe } from 'rxjs'; import { switchMap, tap } from 'rxjs/operators'; import { LoginParams } from '../models/auth'; -import { AbpApplicationConfigurationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service'; import { ConfigStateService } from '../services/config-state.service'; const cookieKey = 'rememberMe'; @@ -15,13 +14,11 @@ export function pipeToLogin( injector: Injector, ) { const configState = injector.get(ConfigStateService); - const appConfigService = injector.get(AbpApplicationConfigurationService); const router = injector.get(Router); return pipe( - switchMap(() => appConfigService.get()), - tap(res => { - configState.setState(res); + switchMap(() => configState.refreshAppState()), + tap(() => { setRememberMe(params.rememberMe); if (params.redirectUrl) router.navigate([params.redirectUrl]); }), diff --git a/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts index 87982d8bd0..9c14d14b6d 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts @@ -5,7 +5,6 @@ import { tap, catchError } from 'rxjs/operators'; import { throwError } from 'rxjs'; import { ABP } from '../models/common'; import { Environment } from '../models/environment'; -import { AbpApplicationConfigurationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service'; import { CurrentTenantDto } from '../proxy/volo/abp/asp-net-core/mvc/multi-tenancy/models'; import { AuthService } from '../services/auth.service'; import { ConfigStateService } from '../services/config-state.service'; @@ -21,7 +20,6 @@ export function getInitialData(injector: Injector) { const fn = async () => { const environmentService = injector.get(EnvironmentService); const configState = injector.get(ConfigStateService); - const appConfigService = injector.get(AbpApplicationConfigurationService); const options = injector.get(CORE_OPTIONS) as ABP.Root; environmentService.setState(options.environment as Environment); @@ -31,10 +29,9 @@ export function getInitialData(injector: Injector) { if (options.skipGetAppConfiguration) return; - return appConfigService - .get() + return configState + .refreshAppState() .pipe( - tap(res => configState.setState(res)), tap(() => checkAccessToken(injector)), tap(() => { const currentTenant = configState.getOne('currentTenant') as CurrentTenantDto; diff --git a/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts b/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts index 4bda77b4fb..e40779eba4 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts +++ b/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts @@ -1,12 +1,8 @@ -import { - AbpApplicationConfigurationService, - ConfigStateService, - TrackByService, -} from '@abp/ng.core'; +import { ConfigStateService, TrackByService } from '@abp/ng.core'; import { LocaleDirection } from '@abp/ng.theme.shared'; import { Component, EventEmitter, Input, Output } from '@angular/core'; import { Store } from '@ngxs/store'; -import { finalize, tap } from 'rxjs/operators'; +import { finalize } from 'rxjs/operators'; import { FeatureManagement } from '../../models/feature-management'; import { FeaturesService } from '../../proxy/feature-management/features.service'; import { @@ -29,7 +25,8 @@ enum ValueTypes { export class FeatureManagementComponent implements FeatureManagement.FeatureManagementComponentInputs, - FeatureManagement.FeatureManagementComponentOutputs { + FeatureManagement.FeatureManagementComponentOutputs +{ @Input() providerKey: string; @@ -70,7 +67,6 @@ export class FeatureManagementComponent protected service: FeaturesService, protected store: Store, protected configState: ConfigStateService, - protected appConfigService: AbpApplicationConfigurationService, ) {} openModal() { @@ -122,10 +118,7 @@ export class FeatureManagementComponent if (!this.providerKey) { // to refresh host's features - this.appConfigService - .get() - .pipe(tap(res => this.configState.setState(res))) - .subscribe(); + this.configState.refreshAppState().subscribe(); } }); } diff --git a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts index 67a48cb507..2fe9a1f294 100644 --- a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts +++ b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts @@ -1,8 +1,4 @@ -import { - AbpApplicationConfigurationService, - ConfigStateService, - CurrentUserDto, -} from '@abp/ng.core'; +import { ConfigStateService, CurrentUserDto } from '@abp/ng.core'; import { LocaleDirection } from '@abp/ng.theme.shared'; import { Component, EventEmitter, Input, Output, TrackByFunction } from '@angular/core'; import { Select, Store } from '@ngxs/store'; @@ -39,7 +35,8 @@ type PermissionWithStyle = PermissionGrantInfoDto & { export class PermissionManagementComponent implements PermissionManagement.PermissionManagementComponentInputs, - PermissionManagement.PermissionManagementComponentOutputs { + PermissionManagement.PermissionManagementComponentOutputs +{ @Input() readonly providerName: string; @@ -105,21 +102,17 @@ export class PermissionManagementComponent map(permissions => permissions.map( permission => - (({ + ({ ...permission, style: { [margin]: findMargin(permissions, permission) }, isGranted: this.permissions.find(per => per.name === permission.name).isGranted, - } as any) as PermissionWithStyle), + } as any as PermissionWithStyle), ), ), ); } - constructor( - protected store: Store, - protected configState: ConfigStateService, - protected appConfigService: AbpApplicationConfigurationService, - ) {} + constructor(protected store: Store, protected configState: ConfigStateService) {} getChecked(name: string) { return (this.permissions.find(per => per.name === name) || { isGranted: false }).isGranted; @@ -253,9 +246,7 @@ export class PermissionManagementComponent ) .pipe( switchMap(() => - this.shouldFetchAppConfig() - ? this.appConfigService.get().pipe(tap(res => this.configState.setState(res))) - : of(null), + this.shouldFetchAppConfig() ? this.configState.refreshAppState() : of(null), ), finalize(() => (this.modalBusy = false)), ) From 851cfd69bac9b6a385d5058307a0143ecdce6574 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 18 Aug 2021 11:17:45 +0800 Subject: [PATCH 3/4] Enhancement IQueryStringCultureReplacement. --- .../AbpAspNetCoreMvcQueryStringCultureReplacement.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpAspNetCoreMvcQueryStringCultureReplacement.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpAspNetCoreMvcQueryStringCultureReplacement.cs index 900d1c5de7..8e173a2e26 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpAspNetCoreMvcQueryStringCultureReplacement.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpAspNetCoreMvcQueryStringCultureReplacement.cs @@ -16,12 +16,13 @@ namespace Volo.Abp.AspNetCore.Mvc.Localization { context.ReturnUrl = Regex.Replace( context.ReturnUrl, - "culture=[A-Za-z-]+?&", - $"culture={context.RequestCulture.Culture}&", + "culture=[A-Za-z-]+", + $"culture={context.RequestCulture.Culture}", RegexOptions.Compiled | RegexOptions.IgnoreCase); context.ReturnUrl = Regex.Replace( - context.ReturnUrl, "ui-culture=[A-Za-z-]+?$", + context.ReturnUrl, + "ui-culture=[A-Za-z-]+", $"ui-culture={context.RequestCulture.UICulture}", RegexOptions.Compiled | RegexOptions.IgnoreCase); } From 054afbbd961ca34b9ae183f884266baeab493b42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 18 Aug 2021 11:52:51 +0300 Subject: [PATCH 4/4] Update localization --- .../AbpIoLocalization/Commercial/Localization/Resources/en.json | 2 +- .../AbpIoLocalization/Commercial/Localization/Resources/fi.json | 2 +- .../AbpIoLocalization/Commercial/Localization/Resources/fr.json | 2 +- .../AbpIoLocalization/Commercial/Localization/Resources/hi.json | 2 +- .../AbpIoLocalization/Commercial/Localization/Resources/it.json | 2 +- .../Commercial/Localization/Resources/ro-RO.json | 2 +- .../AbpIoLocalization/Commercial/Localization/Resources/sk.json | 2 +- .../Commercial/Localization/Resources/zh-Hans.json | 2 +- .../Commercial/Localization/Resources/zh-Hant.json | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 1e87f281bc..d8f0befd48 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -106,7 +106,7 @@ "DarkBlueTheme": "Dark Blue Theme", "LightTheme": "Light Theme", "ProudToWorkWith": "Proud to Work With", - "OurConsumers": "Hundreds of enterprises and developers over 50 countries worldwide rely on ABP Commercial.", + "OurConsumers": "Thousands of enterprises and developers over 70 countries worldwide rely on ABP Commercial.", "JoinOurConsumers": "Join them and build amazing products fast.", "AdditionalServicesExplanation": "Do you need additional or custom services? We and our partners can provide;", "CustomProjectDevelopment": "Custom Project Development", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json index 8de4891e99..8a0e6f22c1 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json @@ -106,7 +106,7 @@ "DarkBlueTheme": "Tummansininen teema", "LightTheme": "Kevyt teema", "ProudToWorkWith": "Ylpeä työskennellä", - "OurConsumers": "Sadat yritykset ja kehittäjät yli 50 maassa ympäri maailmaa luottavat ABP Commercialiin.", + "OurConsumers": "Sadat yritykset ja kehittäjät yli 70 maassa ympäri maailmaa luottavat ABP Commercialiin.", "JoinOurConsumers": "Liity heihin ja rakenna upeita tuotteita nopeasti.", "AdditionalServicesExplanation": "Tarvitsetko lisä- tai mukautettuja palveluita? Me ja kumppanimme voimme tarjota; ", "CustomProjectDevelopment": "Mukautettu projektikehitys", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json index e8f4165971..4db09019ed 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json @@ -106,7 +106,7 @@ "DarkBlueTheme": "Thème bleu foncé", "LightTheme": "Thème clair", "ProudToWorkWith": "Fier de travailler avec", - "OurConsumers": "Des centaines d'entreprises et de développeurs dans plus de 50 pays dans le monde font confiance à ABP Commercial.", + "OurConsumers": "Des centaines d'entreprises et de développeurs dans plus de 70 pays dans le monde font confiance à ABP Commercial.", "JoinOurConsumers": "Rejoignez-les et créez rapidement des produits incroyables.", "AdditionalServicesExplanation": "Avez-vous besoin de services supplémentaires ou personnalisés? Nous et nos partenaires pouvons fournir; ", "CustomProjectDevelopment": "Développement de projets personnalisés", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json index 4af2f31246..91158973d8 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json @@ -106,7 +106,7 @@ "DarkBlueTheme": "डार्क ब्लू थीम", "LightTheme": "प्रकाश थीम", "ProudToWorkWith": "गर्व के साथ काम करने के लिए", - "OurConsumers": "दुनिया भर में 50 से अधिक देशों के सैकड़ों उद्यम और डेवलपर्स एबीपी कमर्शियल पर निर्भर हैं।", + "OurConsumers": "दुनिया भर में 70 से अधिक देशों के सैकड़ों उद्यम और डेवलपर्स एबीपी कमर्शियल पर निर्भर हैं।", "JoinOurConsumers": "उनके साथ जुड़ें और तेजी से अद्भुत उत्पादों का निर्माण करें।", "AdditionalServicesExplanation": "क्या आपको अतिरिक्त या कस्टम सेवाओं की आवश्यकता है? हम और हमारे साथी प्रदान कर सकते हैं; ", "CustomProjectDevelopment": "कस्टम परियोजना विकास", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json index 722c10275f..2031279d6d 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json @@ -106,7 +106,7 @@ "DarkBlueTheme": "Tema blu scuro", "LightTheme": "Tema chiaro", "ProudToWorkWith": "Orgoglioso di lavorare con", - "OurConsumers": "Centinaia di aziende e sviluppatori in oltre 50 paesi in tutto il mondo si affidano a ABP Commercial.", + "OurConsumers": "Centinaia di aziende e sviluppatori in oltre 70 paesi in tutto il mondo si affidano a ABP Commercial.", "JoinOurConsumers": "Unisciti a loro e crea prodotti sorprendenti velocemente.", "AdditionalServicesExplanation": "Hai bisogno di servizi aggiuntivi o personalizzati? Noi e i nostri partner possiamo fornire; ", "CustomProjectDevelopment": "Sviluppo di progetti personalizzati", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json index d5dcbfa751..a88d581d36 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json @@ -106,7 +106,7 @@ "DarkBlueTheme": "Tema Dark Blue", "LightTheme": "Tema Light", "ProudToWorkWith": "Mândru să lucrez cu", - "OurConsumers": "Sute de întreprinderi şi dezvoltatori din peste 50 de ţări din jurul lumii se bazează pe ABP Commercial.", + "OurConsumers": "Sute de întreprinderi şi dezvoltatori din peste 70 de ţări din jurul lumii se bazează pe ABP Commercial.", "JoinOurConsumers": "Alăturaţi-va lor şi construiţi produse uimitoare rapid.", "AdditionalServicesExplanation": "Aveţi nevoie de servicii suplimentare sau personalizate? Noi şi partenerii noştri vi le putem oferi;", "CustomProjectDevelopment": "Custom Project Development", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json index 7e2143a9af..4b160bdb70 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json @@ -106,7 +106,7 @@ "DarkBlueTheme": "Tmavomodrá téma", "LightTheme": "Téma Light", "ProudToWorkWith": "Hrdo spolupracujeme s", - "OurConsumers": "Na ABP Commercial sa spoliehajú stovky podnikov a vývojárov vo viac ako 50 krajinách sveta.", + "OurConsumers": "Na ABP Commercial sa spoliehajú stovky podnikov a vývojárov vo viac ako 70 krajinách sveta.", "JoinOurConsumers": "Pridajte sa k nim a jednoducho vytvorte úžasné produkty.", "AdditionalServicesExplanation": "Potrebujete ďalšie alebo vlastné služby? My a naši partneri vám ich môžeme poskytnúť;", "CustomProjectDevelopment": "Vývoj projektu na mieru", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json index 5f99be6ba8..ac5e247264 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json @@ -106,7 +106,7 @@ "DarkBlueTheme": "深蓝主题", "LightTheme": "浅色主题", "ProudToWorkWith": "荣幸与你合作", - "OurConsumers": "全球50多个国家的数百家企业和开发商使用ABP商业版.", + "OurConsumers": "全球70多个国家的数百家企业和开发商使用ABP商业版.", "JoinOurConsumers": "加它他们并快速构建令人惊叹的产品.", "AdditionalServicesExplanation": "你是否需要额外或自定义的服务? 我们和我们的合作伙伴可以提供;", "CustomProjectDevelopment": "自定义项目开发", diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json index a676aa9124..80fed13066 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json @@ -104,7 +104,7 @@ "DarkBlueTheme": "深藍主題", "LightTheme": "淺色主題", "ProudToWorkWith": "榮幸與你合作", - "OurConsumers": "全球50多個國家的數百家企業和開發商使用ABP商業版.", + "OurConsumers": "全球70多個國家的數百家企業和開發商使用ABP商業版.", "JoinOurConsumers": "加它他們並快速構建令人驚嘆的產品.", "AdditionalServicesExplanation": "你是否需要額外或自定義的服務? 我們和我們的合作夥伴可以提供;", "CustomProjectDevelopment": "自定義項目開發",