Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,5 @@
"typescript.tsserver.watchOptions": "vscode",
"typescript.preferences.preferTypeOnlyAutoImports": true,
"chat.agent.enabled": true,
"chat.mcp.enabled": true
"chat.mcp.access": "all"
}
2 changes: 2 additions & 0 deletions apps/showcase/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
"@commitlint/types": "^19.0.0",
"@design-factory/design-factory": "~20.0.0",
"@formatjs/intl-numberformat": "~8.15.0",
"@jsverse/transloco": "~8.0.0",
"@jsverse/utils": "~1.0.0-beta.6",
"@ng-bootstrap/ng-bootstrap": "^19.0.0",
"@ng-select/ng-select": "~20.0.0",
"@ngrx/effects": "~20.0.0",
Expand Down
27 changes: 14 additions & 13 deletions apps/showcase/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import {
import {
BrowserAnimationsModule,
} from '@angular/platform-browser/animations';
import {
provideTransloco,
TranslocoModule,
} from '@jsverse/transloco';
import {
NgbOffcanvasModule,
} from '@ng-bootstrap/ng-bootstrap';
Expand All @@ -30,10 +34,6 @@ import {
import {
StoreDevtoolsModule,
} from '@ngrx/store-devtools';
import {
TranslateCompiler,
TranslateModule,
} from '@ngx-translate/core';
import {
ApplicationDevtoolsModule,
OTTER_APPLICATION_DEVTOOLS_OPTIONS,
Expand All @@ -56,7 +56,6 @@ import {
MESSAGE_FORMAT_CONFIG,
OTTER_LOCALIZATION_DEVTOOLS_OPTIONS,
translateLoaderProvider,
TranslateMessageFormatLazyCompiler,
} from '@o3r/localization';
import {
ConsoleLogger,
Expand Down Expand Up @@ -151,13 +150,7 @@ export function localizationConfigurationFactory(): Partial<LocalizationConfigur
EffectsModule.forRoot([]),
StoreModule.forRoot({}, { runtimeChecks }),
StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: !isDevMode() }),
TranslateModule.forRoot({
loader: translateLoaderProvider,
compiler: {
provide: TranslateCompiler,
useClass: TranslateMessageFormatLazyCompiler
}
}),
TranslocoModule,
LocalizationModule.forRoot(localizationConfigurationFactory),
RulesEngineRunnerModule.forRoot({ debug: true }),
AppRoutingModule,
Expand Down Expand Up @@ -199,7 +192,15 @@ export function localizationConfigurationFactory(): Partial<LocalizationConfigur
/* Templates are only internal, no need to sanitize */
sanitize: SecurityContext.NONE
}),
{ provide: NGX_MONACO_EDITOR_CONFIG, useValue: { baseUrl: `${location.origin}${location.pathname}assets/monaco/min/vs` } }
{ provide: NGX_MONACO_EDITOR_CONFIG, useValue: { baseUrl: `${location.origin}${location.pathname}assets/monaco/min/vs` } },
provideTransloco({
config: {
availableLangs: ['en', 'fr'],
interpolation: ['{', '}'],
reRenderOnLangChange: true
}
}),
translateLoaderProvider
],
bootstrap: [AppComponent]
})
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@
"@compodoc/compodoc": "^1.1.19",
"@design-factory/design-factory": "~20.0.0",
"@eslint-community/eslint-plugin-eslint-comments": "^4.4.0",
"@jsverse/transloco": "~8.0.0",
"@jsverse/utils": "~1.0.0-beta.6",
"@ng-bootstrap/ng-bootstrap": "^19.0.0",
"@ng-select/ng-select": "~20.0.0",
"@ngrx/effects": "~20.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ export class PlaceholderRulesEngineActionHandler implements RulesEngineActionHan
const translateService = inject(LocalizationService, { optional: true });

const lang$ = translateService
? translateService.getTranslateService().onLangChange.pipe(
map(({ lang }) => lang),
? translateService.getTranslateService().langChanges$.pipe(
startWith(translateService.getCurrentLanguage()),
distinctUntilChanged()
)
Expand Down
3 changes: 3 additions & 0 deletions packages/@o3r/localization/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"@angular/core": "^20.0.0",
"@angular/platform-browser-dynamic": "^20.0.0",
"@formatjs/intl-numberformat": "^8.0.2",
"@jsverse/transloco": "^8.0.0",
"@ngrx/store": "^20.0.0",
"@ngx-translate/core": "^15.0.0 || ~16.0.4",
"@o3r/core": "workspace:^",
Expand Down Expand Up @@ -137,6 +138,8 @@
"@babel/preset-typescript": "~7.27.0",
"@compodoc/compodoc": "^1.1.19",
"@eslint-community/eslint-plugin-eslint-comments": "^4.4.0",
"@jsverse/transloco": "~8.0.0",
"@jsverse/utils": "~1.0.0-beta.6",
"@ngrx/store": "~20.0.0",
"@ngx-translate/core": "~16.0.4",
"@nx/eslint": "~21.5.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
LoggerService,
} from '@o3r/logger';
import {
firstValueFrom,
fromEvent,
} from 'rxjs';
import {
Expand Down Expand Up @@ -79,7 +78,7 @@ export class LocalizationDevtoolsMessageService {
* Function to trigger a re-send a requested messages to the Otter Chrome DevTools extension
* @param only restricted list of messages to re-send
*/
private async handleReEmitRequest(only?: LocalizationMessageDataTypes[]) {
private handleReEmitRequest(only?: LocalizationMessageDataTypes[]) {
if (!only || only.includes('localizations')) {
void this.sendLocalizationsMetadata();
}
Expand All @@ -91,7 +90,7 @@ export class LocalizationDevtoolsMessageService {
}
if (!only || only.includes('getTranslationValuesContentMessage')) {
this.sendMessage('getTranslationValuesContentMessage', {
translations: await firstValueFrom(this.localizationService.getTranslateService().getTranslation(this.localizationService.getCurrentLanguage()))
translations: this.localizationService.getTranslateService().getTranslation(this.localizationService.getCurrentLanguage())
});
}
if (!only || only.includes('isTranslationDeactivationEnabled')) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,18 @@
import {
ApplicationRef,
inject,
Injectable,
} from '@angular/core';
import {
TranslateCompiler,
} from '@ngx-translate/core';
import {
lastValueFrom,
Subscription,
} from 'rxjs';
import type {
TranslateMessageFormatLazyCompiler,
} from '../core';
import {
LocalizationService,
} from '../tools';

@Injectable()
export class OtterLocalizationDevtools {
private readonly localizationService = inject(LocalizationService);
private readonly translateCompiler = inject(TranslateCompiler);
private readonly appRef = inject(ApplicationRef);

/**
* Is the translation deactivation enabled
Expand All @@ -36,7 +27,6 @@ export class OtterLocalizationDevtools {
*/
public showLocalizationKeys(value?: boolean): void {
this.localizationService.toggleShowKeys(value);
this.appRef.tick();
}

/**
Expand All @@ -53,8 +43,8 @@ export class OtterLocalizationDevtools {
public onLanguageChange(fn: (language: string) => any): Subscription {
return this.localizationService
.getTranslateService()
.onLangChange
.subscribe(({ lang }) => {
.langChanges$
.subscribe((lang) => {
fn(lang);
});
}
Expand All @@ -68,7 +58,6 @@ export class OtterLocalizationDevtools {
return;
}
await lastValueFrom(this.localizationService.useLanguage(language));
this.appRef.tick();
}

/**
Expand All @@ -81,10 +70,7 @@ export class OtterLocalizationDevtools {
public updateLocalizationKeys(keyValues: { [key: string]: string }, language?: string): void | Promise<void> {
const lang = language || this.getCurrentLanguage();
const translateService = this.localizationService.getTranslateService();
Object.entries(keyValues).forEach(([key, value]) => {
translateService.set(key, value, lang);
});
this.appRef.tick();
translateService.setTranslation(keyValues, lang);
}

/**
Expand All @@ -94,18 +80,8 @@ export class OtterLocalizationDevtools {
*/
public async reloadLocalizationKeys(language?: string) {
const lang = language || this.getCurrentLanguage();
if ((this.translateCompiler as TranslateMessageFormatLazyCompiler).clearCache) {
(this.translateCompiler as TranslateMessageFormatLazyCompiler).clearCache();
}
const initialLocs = await lastValueFrom(
this.localizationService
.getTranslateService()
.reloadLang(lang)
);
this.localizationService.getTranslateService().setTranslation(
language || this.getCurrentLanguage(),
initialLocs
);
this.appRef.tick();
const translateService = this.localizationService.getTranslateService();
const translations = await lastValueFrom(translateService.load(lang));
translateService.setTranslation(translations, lang, { merge: false });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import {
PipeTransform,
} from '@angular/core';
import {
TranslatePipe,
TranslateService,
} from '@ngx-translate/core';
TRANSLOCO_LANG,
TRANSLOCO_SCOPE,
TranslocoPipe,
TranslocoService,
} from '@jsverse/transloco';
import {
Subscription,
} from 'rxjs';
Expand All @@ -30,7 +32,7 @@ import {
pure: false,
standalone: false
})
export class O3rLocalizationTranslatePipe extends TranslatePipe implements PipeTransform, OnDestroy {
export class O3rLocalizationTranslatePipe extends TranslocoPipe implements PipeTransform, OnDestroy {
/** Localization service instance */
protected readonly localizationService = inject(LocalizationService);
/** Change detector service instance */
Expand Down Expand Up @@ -59,21 +61,34 @@ export class O3rLocalizationTranslatePipe extends TranslatePipe implements PipeT
protected lastResolvedKey?: string;

constructor() {
super(inject(TranslateService), inject(ChangeDetectorRef));
super(
inject(TranslocoService),
inject(TRANSLOCO_SCOPE, { optional: true }) || undefined,
inject(TRANSLOCO_LANG, { optional: true }) || undefined,
inject(ChangeDetectorRef)
);
if (this.localizationConfig.enableTranslationDeactivation) {
this.onShowKeysChange = this.localizationService.showKeys$.subscribe((showKeys) => {
this.showKeys = showKeys;
this.changeDetector.markForCheck();
});
}
// const translateService = this.localizationService.getTranslateService();
// translateService.events$.pipe(
// takeUntilDestroyed()
// ).subscribe(() => {
// // HACK to force re-evaluation of the pipe when translations change
// (this as any).lastKey = undefined;
// this.changeDetector.markForCheck();
// });
}

/**
* Calls original transform method and eventually outputs the key if debugMode (in LocalizationConfiguration) is enabled
* @inheritdoc
*/
public transform(query: string, ...args: any[]): any {
if (this.showKeys) {
if (!query || this.showKeys) {
return query;
}

Expand All @@ -88,17 +103,13 @@ export class O3rLocalizationTranslatePipe extends TranslatePipe implements PipeT
});
}

if (this.lastResolvedKey) {
const value = super.transform(this.lastResolvedKey, ...args);
const value = super.transform(this.lastResolvedKey, ...args);

if (this.localizationConfig.debugMode) {
return `${this.lastResolvedKey} - ${value as string}`;
}

return value;
if (this.localizationConfig.debugMode) {
return `${this.lastResolvedKey} - ${value}`;
}

return this.value;
return value;
}

public ngOnDestroy() {
Expand Down
8 changes: 4 additions & 4 deletions packages/@o3r/localization/src/tools/localization.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import {
Optional,
} from '@angular/core';
import {
TranslateModule,
} from '@ngx-translate/core';
TranslocoModule,
} from '@jsverse/transloco';
import {
DynamicContentModule,
} from '@o3r/dynamic-content';
Expand Down Expand Up @@ -77,8 +77,8 @@ export const CUSTOM_LOCALIZATION_CONFIGURATION_TOKEN = new InjectionToken<Partia

@NgModule({
declarations: [O3rLocalizationTranslatePipe, LocalizationTranslateDirective, LocalizedDatePipe, LocalizedDecimalPipe, LocalizedCurrencyPipe],
imports: [TranslateModule, BidiModule, DynamicContentModule, CommonModule],
exports: [TranslateModule, O3rLocalizationTranslatePipe, LocalizationTranslateDirective, LocalizedDatePipe, LocalizedDecimalPipe, LocalizedCurrencyPipe],
imports: [TranslocoModule, BidiModule, DynamicContentModule, CommonModule],
exports: [TranslocoModule, O3rLocalizationTranslatePipe, LocalizationTranslateDirective, LocalizedDatePipe, LocalizedDecimalPipe, LocalizedCurrencyPipe],
providers: [
{ provide: LOCALIZATION_CONFIGURATION_TOKEN, useFactory: createLocalizationConfiguration, deps: [[new Optional(), CUSTOM_LOCALIZATION_CONFIGURATION_TOKEN]] },
{ provide: LOCALE_ID, useFactory: localeIdNgBridge, deps: [LocalizationService] },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {
Optional,
} from '@angular/core';
import {
TranslateLoader,
} from '@ngx-translate/core';
TRANSLOCO_LOADER,
} from '@jsverse/transloco';
import {
DynamicContentService,
} from '@o3r/dynamic-content';
Expand Down Expand Up @@ -48,7 +48,7 @@ export function createTranslateLoader(localizationConfiguration: LocalizationCon
* TranslateLoader provider, using framework's TranslationsLoader class
*/
export const translateLoaderProvider: Readonly<FactoryProvider> = {
provide: TranslateLoader,
provide: TRANSLOCO_LOADER,
useFactory: createTranslateLoader,
deps: [LOCALIZATION_CONFIGURATION_TOKEN, [new Optional(), LoggerService], [new Optional(), DynamicContentService]]
} as const;
Loading