Browse Source

Merge pull request #14561 from abpframework/issue/13946

Issue/13946
pull/14572/head
Mahmut Gundogdu 3 years ago
committed by GitHub
parent
commit
346a21d5c7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      npm/ng-packs/packages/core/src/lib/core.module.ts
  2. 8
      npm/ng-packs/packages/core/src/lib/providers/include-localization-resources.provider.ts
  3. 1
      npm/ng-packs/packages/core/src/lib/providers/index.ts
  4. 3798
      npm/ng-packs/packages/core/src/lib/proxy/generate-proxy.json
  5. 8
      npm/ng-packs/packages/core/src/lib/proxy/pages/abp/multi-tenancy/abp-tenant.service.ts
  6. 4
      npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/api-exploring/abp-api-definition.service.ts
  7. 11
      npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service.ts
  8. 20
      npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-localization.service.ts
  9. 1
      npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/index.ts
  10. 21
      npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/models.ts
  11. 9
      npm/ng-packs/packages/core/src/lib/proxy/volo/abp/http/modeling/models.ts
  12. 52
      npm/ng-packs/packages/core/src/lib/services/config-state.service.ts
  13. 60
      npm/ng-packs/packages/core/src/lib/services/localization.service.ts
  14. 3
      npm/ng-packs/packages/core/src/lib/tokens/include-localization-resources.token.ts
  15. 1
      npm/ng-packs/packages/core/src/lib/tokens/index.ts

2
npm/ng-packs/packages/core/src/lib/core.module.ts

@ -38,6 +38,7 @@ import { ShortDateTimePipe } from './pipes/short-date-time.pipe';
import { ShortTimePipe } from './pipes/short-time.pipe'; import { ShortTimePipe } from './pipes/short-time.pipe';
import { ShortDatePipe } from './pipes/short-date.pipe'; import { ShortDatePipe } from './pipes/short-date.pipe';
import { TimeoutLimitedOAuthService } from './services/timeout-limited-oauth.service'; import { TimeoutLimitedOAuthService } from './services/timeout-limited-oauth.service';
import { IncludeLocalizationResourcesProvider } from './providers/include-localization-resources.provider';
export function storageFactory(): OAuthStorage { export function storageFactory(): OAuthStorage {
return oAuthStorage; return oAuthStorage;
@ -193,6 +194,7 @@ export class CoreModule {
useValue: localizationContributor(options.localizations), useValue: localizationContributor(options.localizations),
deps: [LocalizationService], deps: [LocalizationService],
}, },
IncludeLocalizationResourcesProvider
], ],
}; };
} }

8
npm/ng-packs/packages/core/src/lib/providers/include-localization-resources.provider.ts

@ -0,0 +1,8 @@
import { Provider } from "@angular/core";
import { INCUDE_LOCALIZATION_RESOURCES_TOKEN } from "../tokens/include-localization-resources.token";
export const IncludeLocalizationResourcesProvider: Provider = {
provide: INCUDE_LOCALIZATION_RESOURCES_TOKEN,
useValue: false,
};

1
npm/ng-packs/packages/core/src/lib/providers/index.ts

@ -1,2 +1,3 @@
export * from './cookie-language.provider'; export * from './cookie-language.provider';
export * from './locale.provider'; export * from './locale.provider';
export * from './include-localization-resources.provider';

3798
npm/ng-packs/packages/core/src/lib/proxy/generate-proxy.json

File diff suppressed because it is too large

8
npm/ng-packs/packages/core/src/lib/proxy/pages/abp/multi-tenancy/abp-tenant.service.ts

@ -7,20 +7,20 @@ import type { FindTenantResultDto } from '../../../volo/abp/asp-net-core/mvc/mul
}) })
export class AbpTenantService { export class AbpTenantService {
apiName = 'abp'; apiName = 'abp';
findTenantById = (id: string) => findTenantById = (id: string) =>
this.restService.request<any, FindTenantResultDto>({ this.restService.request<any, FindTenantResultDto>({
method: 'GET', method: 'GET',
url: `/api/abp/multi-tenancy/tenants/by-id/${id}`, url: `/api/abp/multi-tenancy/tenants/by-id/${id}`,
}, },
{ apiName: this.apiName }); { apiName: this.apiName });
findTenantByName = (name: string) => findTenantByName = (name: string) =>
this.restService.request<any, FindTenantResultDto>({ this.restService.request<any, FindTenantResultDto>({
method: 'GET', method: 'GET',
url: `/api/abp/multi-tenancy/tenants/by-name/${name}`, url: `/api/abp/multi-tenancy/tenants/by-name/${name}`,
}, },
{ apiName: this.apiName }); { apiName: this.apiName });
constructor(private restService: RestService) { } constructor(private restService: RestService) { }
} }

4
npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/api-exploring/abp-api-definition.service.ts

@ -7,14 +7,14 @@ import type { ApplicationApiDescriptionModel, ApplicationApiDescriptionModelRequ
}) })
export class AbpApiDefinitionService { export class AbpApiDefinitionService {
apiName = 'abp'; apiName = 'abp';
getByModel = (model: ApplicationApiDescriptionModelRequestDto) => getByModel = (model: ApplicationApiDescriptionModelRequestDto) =>
this.restService.request<any, ApplicationApiDescriptionModel>({ this.restService.request<any, ApplicationApiDescriptionModel>({
method: 'GET', method: 'GET',
url: '/api/abp/api-definition', url: '/api/abp/api-definition',
params: { includeTypes: model.includeTypes }, params: { includeTypes: model.includeTypes },
}, },
{ apiName: this.apiName }); { apiName: this.apiName });
constructor(private restService: RestService) { } constructor(private restService: RestService) { }
} }

11
npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service.ts

@ -1,4 +1,4 @@
import type { ApplicationConfigurationDto } from './models'; import type { ApplicationConfigurationDto, ApplicationConfigurationRequestOptions } from './models';
import { RestService } from '../../../../../../services/rest.service'; import { RestService } from '../../../../../../services/rest.service';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
@ -7,13 +7,14 @@ import { Injectable } from '@angular/core';
}) })
export class AbpApplicationConfigurationService { export class AbpApplicationConfigurationService {
apiName = 'abp'; apiName = 'abp';
get = () => get = (options: ApplicationConfigurationRequestOptions) =>
this.restService.request<any, ApplicationConfigurationDto>({ this.restService.request<any, ApplicationConfigurationDto>({
method: 'GET', method: 'GET',
url: '/api/abp/application-configuration', url: '/api/abp/application-configuration',
params: { includeLocalizationResources: options.includeLocalizationResources },
}, },
{ apiName: this.apiName }); { apiName: this.apiName });
constructor(private restService: RestService) { } constructor(private restService: RestService) {}
} }

20
npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-localization.service.ts

@ -0,0 +1,20 @@
import type { ApplicationLocalizationDto, ApplicationLocalizationRequestDto } from './models';
import { Injectable } from '@angular/core';
import { RestService } from '../../../../../../services/rest.service';
@Injectable({
providedIn: 'root',
})
export class AbpApplicationLocalizationService {
apiName = 'abp';
get = (input: ApplicationLocalizationRequestDto) =>
this.restService.request<any, ApplicationLocalizationDto>({
method: 'GET',
url: '/api/abp/application-localization',
params: { cultureName: input.cultureName, onlyDynamics: input.onlyDynamics },
},
{ apiName: this.apiName });
constructor(private restService: RestService) {}
}

1
npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/index.ts

@ -1,4 +1,5 @@
import * as ObjectExtending from './object-extending'; import * as ObjectExtending from './object-extending';
export * from './abp-application-configuration.service'; export * from './abp-application-configuration.service';
export * from './abp-application-localization.service';
export * from './models'; export * from './models';
export { ObjectExtending }; export { ObjectExtending };

21
npm/ng-packs/packages/core/src/lib/proxy/volo/abp/asp-net-core/mvc/application-configurations/models.ts

@ -4,7 +4,6 @@ import type { LanguageInfo } from '../../../localization/models';
import type { NameValue } from '../../../models'; import type { NameValue } from '../../../models';
export interface ApplicationAuthConfigurationDto { export interface ApplicationAuthConfigurationDto {
policies: Record<string, boolean>;
grantedPolicies: Record<string, boolean>; grantedPolicies: Record<string, boolean>;
} }
@ -20,6 +19,11 @@ export interface ApplicationConfigurationDto {
timing: TimingDto; timing: TimingDto;
clock: ClockDto; clock: ClockDto;
objectExtensions: ObjectExtensionsDto; objectExtensions: ObjectExtensionsDto;
extraProperties: Record<string, object>;
}
export interface ApplicationConfigurationRequestOptions {
includeLocalizationResources: boolean;
} }
export interface ApplicationFeatureConfigurationDto { export interface ApplicationFeatureConfigurationDto {
@ -32,6 +36,7 @@ export interface ApplicationGlobalFeatureConfigurationDto {
export interface ApplicationLocalizationConfigurationDto { export interface ApplicationLocalizationConfigurationDto {
values: Record<string, Record<string, string>>; values: Record<string, Record<string, string>>;
resources: Record<string, ApplicationLocalizationResourceDto>;
languages: LanguageInfo[]; languages: LanguageInfo[];
currentCulture: CurrentCultureDto; currentCulture: CurrentCultureDto;
defaultResourceName?: string; defaultResourceName?: string;
@ -39,6 +44,20 @@ export interface ApplicationLocalizationConfigurationDto {
languageFilesMap: Record<string, NameValue[]>; languageFilesMap: Record<string, NameValue[]>;
} }
export interface ApplicationLocalizationDto {
resources: Record<string, ApplicationLocalizationResourceDto>;
}
export interface ApplicationLocalizationRequestDto {
cultureName: string;
onlyDynamics: boolean;
}
export interface ApplicationLocalizationResourceDto {
texts: Record<string, string>;
baseResources: string[];
}
export interface ApplicationSettingConfigurationDto { export interface ApplicationSettingConfigurationDto {
values: Record<string, string>; values: Record<string, string>;
} }

9
npm/ng-packs/packages/core/src/lib/proxy/volo/abp/http/modeling/models.ts

@ -25,6 +25,7 @@ export interface ControllerApiDescriptionModel {
controllerName?: string; controllerName?: string;
controllerGroupName?: string; controllerGroupName?: string;
isRemoteService: boolean; isRemoteService: boolean;
integrationService: boolean;
apiVersion?: string; apiVersion?: string;
type?: string; type?: string;
interfaces: ControllerInterfaceApiDescriptionModel[]; interfaces: ControllerInterfaceApiDescriptionModel[];
@ -33,6 +34,14 @@ export interface ControllerApiDescriptionModel {
export interface ControllerInterfaceApiDescriptionModel { export interface ControllerInterfaceApiDescriptionModel {
type?: string; type?: string;
name?: string;
methods: InterfaceMethodApiDescriptionModel[];
}
export interface InterfaceMethodApiDescriptionModel {
name?: string;
parametersOnMethod: MethodParameterApiDescriptionModel[];
returnValue: ReturnValueApiDescriptionModel;
} }
export interface MethodParameterApiDescriptionModel { export interface MethodParameterApiDescriptionModel {

52
npm/ng-packs/packages/core/src/lib/services/config-state.service.ts

@ -1,11 +1,13 @@
import { Injectable } from '@angular/core'; import { Inject, Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs'; import { Observable, Subject, of } from 'rxjs';
import { map, switchMap, take } from 'rxjs/operators'; import { map, switchMap, take, tap } from 'rxjs/operators';
import { AbpApplicationConfigurationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service'; import { AbpApplicationConfigurationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service';
import { AbpApplicationLocalizationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-localization.service';
import { import {
ApplicationConfigurationDto, ApplicationConfigurationDto,
ApplicationGlobalFeatureConfigurationDto, ApplicationGlobalFeatureConfigurationDto,
} from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/models'; } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/models';
import { INCUDE_LOCALIZATION_RESOURCES_TOKEN } from '../tokens/include-localization-resources.token';
import { InternalStore } from '../utils/internal-store-utils'; import { InternalStore } from '../utils/internal-store-utils';
@Injectable({ @Injectable({
@ -20,21 +22,61 @@ export class ConfigStateService {
private updateSubject = new Subject<void>(); private updateSubject = new Subject<void>();
constructor(private abpConfigService: AbpApplicationConfigurationService) { constructor(
private abpConfigService: AbpApplicationConfigurationService,
private abpApplicationLocalizationService: AbpApplicationLocalizationService,
@Inject(INCUDE_LOCALIZATION_RESOURCES_TOKEN)
private readonly includeLocalizationResources: boolean,
) {
this.initUpdateStream(); this.initUpdateStream();
} }
private initUpdateStream() { private initUpdateStream() {
this.updateSubject this.updateSubject
.pipe(switchMap(() => this.abpConfigService.get())) .pipe(
switchMap(() =>
this.abpConfigService.get({
includeLocalizationResources: this.includeLocalizationResources,
}),
),
)
.pipe(switchMap(appState => this.getLocalizationAndCombineWithAppState(appState)))
.subscribe(res => this.store.set(res)); .subscribe(res => this.store.set(res));
} }
private getLocalizationAndCombineWithAppState(
appState: ApplicationConfigurationDto,
): Observable<ApplicationConfigurationDto> {
return this.getlocalizationResource(appState.localization.currentCulture.cultureName).pipe(
map(result => ({ ...appState, localization: { ...appState.localization, ...result } })),
);
}
private getlocalizationResource(cultureName: string) {
return this.abpApplicationLocalizationService.get({
cultureName: cultureName,
onlyDynamics: false,
});
}
refreshAppState() { refreshAppState() {
this.updateSubject.next(); this.updateSubject.next();
return this.createOnUpdateStream(state => state).pipe(take(1)); return this.createOnUpdateStream(state => state).pipe(take(1));
} }
refreshLocalization(lang: string): Observable<null> {
if (this.includeLocalizationResources) {
return this.refreshAppState().pipe(map(() => null));
} else {
return this.getlocalizationResource(lang)
.pipe(
tap(result =>
this.store.patch({ localization: { ...this.store.state.localization, ...result } }),
),
)
.pipe(map(() => null));
}
}
getOne$(key: string) { getOne$(key: string) {
return this.store.sliceState(state => state[key]); return this.store.sliceState(state => state[key]);
} }

60
npm/ng-packs/packages/core/src/lib/services/localization.service.ts

@ -1,10 +1,13 @@
import { registerLocaleData } from '@angular/common'; import { registerLocaleData } from '@angular/common';
import { Injectable, Injector, isDevMode, Optional, SkipSelf } from '@angular/core'; import { Injectable, Injector, isDevMode, Optional, SkipSelf } from '@angular/core';
import { BehaviorSubject, combineLatest, from, Observable, Subject } from 'rxjs'; import { BehaviorSubject, combineLatest, from, Observable, of, Subject } from 'rxjs';
import { filter, map, mapTo, switchMap } from 'rxjs/operators'; import { filter, map, mapTo, switchMap } from 'rxjs/operators';
import { ABP } from '../models/common'; import { ABP } from '../models/common';
import { LocalizationWithDefault } from '../models/localization'; import { LocalizationWithDefault } from '../models/localization';
import { ApplicationConfigurationDto } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/models'; import {
ApplicationConfigurationDto,
ApplicationLocalizationResourceDto,
} from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/models';
import { localizations$ } from '../tokens/localization.token'; import { localizations$ } from '../tokens/localization.token';
import { CORE_OPTIONS } from '../tokens/options.token'; import { CORE_OPTIONS } from '../tokens/options.token';
import { createLocalizer, createLocalizerWithFallback } from '../utils/localization-utils'; import { createLocalizer, createLocalizerWithFallback } from '../utils/localization-utils';
@ -58,18 +61,27 @@ export class LocalizationService {
private initLocalizationValues() { private initLocalizationValues() {
localizations$.subscribe(val => this.addLocalization(val)); localizations$.subscribe(val => this.addLocalization(val));
const remoteLocalizations$ = this.configState.getDeep$('localization.values') as Observable< const legacyResources$ = this.configState.getDeep$('localization.values') as Observable<
Record<string, Record<string, string>> Record<string, Record<string, string>>
>; >;
const remoteLocalizations$ = this.configState.getDeep$('localization.resources') as Observable<
Record<string, ApplicationLocalizationResourceDto>
>;
const currentLanguage$ = this.sessionState.getLanguage$(); const currentLanguage$ = this.sessionState.getLanguage$();
const uiLocalizations$ = combineLatest([currentLanguage$, this.uiLocalizations$]).pipe( const uiLocalizations$ = combineLatest([currentLanguage$, this.uiLocalizations$]).pipe(
map(([currentLang, localizations]) => localizations.get(currentLang)), map(([currentLang, localizations]) => localizations.get(currentLang)),
); );
combineLatest([remoteLocalizations$, uiLocalizations$]) combineLatest([legacyResources$, remoteLocalizations$, uiLocalizations$])
.pipe( .pipe(
map(([remote, local]) => { map(([legacy, resource, local]) => {
if (!resource) {
return;
}
const remote = combineLegacyandNewResources(legacy || {}, resource);
if (remote) { if (remote) {
if (!local) { if (!local) {
local = new Map(); local = new Map();
@ -121,7 +133,7 @@ export class LocalizationService {
filter( filter(
lang => this.configState.getDeep('localization.currentCulture.cultureName') !== lang, lang => this.configState.getDeep('localization.currentCulture.cultureName') !== lang,
), ),
switchMap(lang => this.configState.refreshAppState().pipe(mapTo(lang))), switchMap(lang => this.configState.refreshLocalization(lang).pipe(map(()=> lang))),
switchMap(lang => from(this.registerLocale(lang).then(() => lang))), switchMap(lang => from(this.registerLocale(lang).then(() => lang))),
) )
.subscribe(lang => this._languageChange$.next(lang)); .subscribe(lang => this._languageChange$.next(lang));
@ -250,3 +262,39 @@ export class LocalizationService {
return localization || defaultValue || (key as string); return localization || defaultValue || (key as string);
} }
} }
function recursivelyMergeBaseResources(baseResourceName: string, source: ResourceDto) {
const item = source[baseResourceName];
if (item.baseResources.length === 0) {
return item;
}
return item.baseResources.reduce((acc, baseResource) => {
const baseItem = recursivelyMergeBaseResources(baseResource, source);
const texts = { ...baseItem.texts, ...item.texts };
return { ...acc, texts };
}, item);
}
function mergeResourcesWithBaseResource(resource: ResourceDto): ResourceDto {
const entities = Object.keys(resource).map(key => {
const newValue = recursivelyMergeBaseResources(key, resource);
return [key, newValue];
});
return entities.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {});
}
function combineLegacyandNewResources(
legacy: LegacyLanguageDto,
resource: ResourceDto,
): LegacyLanguageDto {
const mergedResource = mergeResourcesWithBaseResource(resource);
return Object.entries(mergedResource).reduce((acc, [key, value]) => {
return { ...acc, [key]: value.texts };
}, legacy);
}
type LegacyLanguageDto = Record<string, Record<string, string>>;
type ResourceDto = Record<string, ApplicationLocalizationResourceDto>;

3
npm/ng-packs/packages/core/src/lib/tokens/include-localization-resources.token.ts

@ -0,0 +1,3 @@
import { InjectionToken } from "@angular/core";
export const INCUDE_LOCALIZATION_RESOURCES_TOKEN = new InjectionToken<boolean>('INCUDE_LOCALIZATION_RESOURCES_TOKEN');

1
npm/ng-packs/packages/core/src/lib/tokens/index.ts

@ -6,3 +6,4 @@ export * from './lodaer-delay.token';
export * from './manage-profile.token'; export * from './manage-profile.token';
export * from './options.token'; export * from './options.token';
export * from './tenant-key.token'; export * from './tenant-key.token';
export * from './include-localization-resources.token';
Loading…
Cancel
Save