Skip to content

Commit

Permalink
chore: remove dependency on ngx-translate
Browse files Browse the repository at this point in the history
  • Loading branch information
MrYuion committed Dec 21, 2024
1 parent 904f41e commit 2cbb75d
Show file tree
Hide file tree
Showing 27 changed files with 2,120 additions and 165 deletions.
4 changes: 1 addition & 3 deletions apps/backoffice/src/app/admin/admin.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';

import { ROUTES } from './admin.routes';
import { SharedContentModule } from 'apps/backoffice/src/app/ui/ui.module';

import { PlaceComponent } from './admin.component';
import { PlaceDatabaseDetailsComponent } from './database-details.component';
Expand Down Expand Up @@ -33,6 +31,7 @@ import { ViewUploadModalComponent } from './view-upload-modal.component';
import { ResourceImportsComponent } from './resource-imports.component';
import { EmailTemplatesComponent } from './mailing-lists/email-templates.component';
import { EmailTemplateFormComponent } from './mailing-lists/email-template-form.component';
import { SharedContentModule } from '../ui/ui.module';

@NgModule({
declarations: [
Expand Down Expand Up @@ -68,7 +67,6 @@ import { EmailTemplateFormComponent } from './mailing-lists/email-template-form.
ReactiveFormsModule,
RouterModule.forChild(ROUTES),
SharedContentModule,
TranslateModule.forChild(),
],
providers: [APIKeyService],
})
Expand Down
2 changes: 0 additions & 2 deletions apps/backoffice/src/app/alert-dashboard/dashboard.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { MatButtonModule } from '@angular/material/button';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { Route, RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';

import { SharedContentModule } from '../ui/ui.module';

Expand All @@ -27,7 +26,6 @@ const ROUTES: Route[] = [
MatSelectModule,
FormsModule,
SharedContentModule,
TranslateModule.forChild(),
],
})
export class MqttDashboardModule {}
13 changes: 6 additions & 7 deletions apps/backoffice/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { currentUser } from './common/user-state';
import { addDays, format, getUnixTime } from 'date-fns';

import { TranslateService } from '@ngx-translate/core';
import { setTranslationService } from './common/translate';
import { LocaleService } from './common/locale.service';

@Component({
selector: 'placeos-root',
Expand Down Expand Up @@ -100,7 +100,7 @@ export class AppComponent extends AsyncHandler implements OnInit {
private _snackbar: MatSnackBar,
private _router: Router,
private _route: ActivatedRoute,
@Optional() private _translate: TranslateService
@Optional() private _locale: LocaleService
) {
super();
}
Expand All @@ -114,15 +114,15 @@ export class AppComponent extends AsyncHandler implements OnInit {
this._route.queryParamMap.subscribe((params) => {
if (params.has('lang')) {
const locale = params.get('lang');
this._translate?.use(locale);
this._locale?.setLocale(locale);
localStorage.setItem('BACKOFFICE.locale', locale);
}
if (params.has('x-api-key')) {
setAPI_Key(params.get('x-api-key'));
}
});
setNotifyOutlet(this._snackbar);
setTranslationService(this._translate);
setTranslationService(this._locale);
this._loading.next(true);
/** Wait for settings to initialise */
await this._settings.initialised.pipe(first((_) => _)).toPromise();
Expand Down Expand Up @@ -197,17 +197,16 @@ export class AppComponent extends AsyncHandler implements OnInit {
const locales = this._settings.get('app.locales') || [
{ id: 'en', name: 'English' },
];
this._translate?.addLangs(locales.map((_) => _.id));
if (locale) {
this._translate?.use(locale);
this._locale?.setLocale(locale);
} else {
const list = navigator.languages;
for (const lang of list) {
locale = locales.find((_) => _.id === lang);
if (!locale)
locale = locales.find((_) => lang.includes(_.id));
if (locale) {
this._translate?.use(lang);
this._locale?.setLocale(lang);
localStorage.setItem('BACKOFFICE.locale', lang);
break;
}
Expand Down
29 changes: 7 additions & 22 deletions apps/backoffice/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule, ErrorHandler } from '@angular/core';
import {
HttpClient,
provideHttpClient,
withInterceptorsFromDi,
} from '@angular/common/http';
import { NgModule, ErrorHandler, LOCALE_ID } from '@angular/core';
import { ServiceWorkerModule } from '@angular/service-worker';
import { FormsModule } from '@angular/forms';

Expand All @@ -21,13 +16,7 @@ import { AuthorisedUserGuard } from './ui/guards/authorised-user.guard';
import { AuthorisedAdminGuard } from './ui/guards/authorised-admin.guard';

import './mocks';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';

// AoT requires an exported function for factories
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/locale/', '.json');
}
import { LocaleService } from './common/locale.service';

@NgModule({
declarations: [AppComponent],
Expand All @@ -48,20 +37,16 @@ export function HttpLoaderFactory(http: HttpClient) {
// or after 30 seconds (whichever comes first).
registrationStrategy: 'registerWhenStable:30000',
}),
TranslateModule.forRoot({
defaultLanguage: 'en',
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient],
},
}),
],
providers: [
{ provide: ErrorHandler, useClass: SentryService },
AuthorisedUserGuard,
AuthorisedAdminGuard,
provideHttpClient(withInterceptorsFromDi()),
{
provide: LOCALE_ID,
deps: [LocaleService],
useFactory: (localeService: LocaleService) => localeService.locale,
},
],
})
export class AppModule {}
117 changes: 117 additions & 0 deletions apps/backoffice/src/app/common/locale.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { Injectable } from '@angular/core';

import * as DEFAULT_LOCALE from 'apps/backoffice/src/assets/locale/en.json';

import { log } from './general';

interface LocaleStore {
expiry: number;
locale: string;
mappings: Record<string, string>;
}

function removeNesting(value: any, path = ''): Record<string, string> {
let out_object: Record<string, string> = {};
for (const key in value) {
const out_key = path ? [path, key].join('.') : key;
if (value[key] instanceof Object) {
out_object = {
...out_object,
...removeNesting(value[key], out_key),
};
} else {
out_object[out_key] = `${value[key]}`;
}
}
return out_object;
}

const STORE_KEY = 'BACKOFFICE.locale';

@Injectable({
providedIn: 'root',
})
export class LocaleService {
private _default_locale = 'en-AU';
private _current_locale = this._default_locale;
private _current_locale_short = this._current_locale.split('-')[0];
private _cache_time = 7 * 24 * 60 * 60 * 1000;
private _load_promises: Record<string, Promise<void>> = {};

private _default_mappings: Record<string, string> =
removeNesting(DEFAULT_LOCALE);
private _locale_mappings: Record<string, Record<string, string>> = {};

public locale_folder = 'assets/locale';

constructor() {
this.setLocale(
localStorage.getItem(`${STORE_KEY}`) || this._default_locale
);
}

public get(key: string, args: Record<string, any> = {}) {
let value =
(this._locale_mappings[this._current_locale] || {})[key] ||
(this._locale_mappings[this._current_locale_short] || {})[key] ||
this._default_mappings[key] ||
key;
for (const id in args) {
value = value.replace(`{{ ${id} }}`, args[id]);
}
return value;
}

public get default_locale() {
return this._default_locale;
}

public get locale(): string {
return this._current_locale;
}

public getLocaleShort(): string {
return this._current_locale_short;
}

public setLocale(locale: string) {
this._current_locale = locale;
this._current_locale_short = this._current_locale.split('-')[0];
if (!this._locale_mappings[locale] && !this._load_promises[locale]) {
this._load_promises[locale] = this._loadLocale(locale);
}
localStorage.setItem(`${STORE_KEY}`, locale);
log('LOCALE', `Locale set to "${locale}"`);
}

private async _loadLocale(locale: string) {
const existing: LocaleStore = JSON.parse(
localStorage.getItem(`${STORE_KEY}.${locale}`) || '{}'
);
if (!existing.expiry || existing.expiry < Date.now()) {
localStorage.removeItem(`${STORE_KEY}.${locale}`);
const resp = await fetch(`${this.locale_folder}/${locale}.json`);
if (!resp.ok) {
delete this._load_promises[locale];
return console.error(
`Failed to loaded locale file for "${locale}".`,
resp
);
}
const locale_data = await resp.json();
this._locale_mappings[locale] = removeNesting(locale_data);
const store = {
expiry: Date.now() + this._cache_time,
locale,
mappings: this._locale_mappings[locale],
};
localStorage.setItem(
`${STORE_KEY}.${locale}`,
JSON.stringify(store)
);
} else {
this._locale_mappings[locale] = existing.mappings;
}
delete this._load_promises[locale];
}
}
10 changes: 5 additions & 5 deletions apps/backoffice/src/app/common/translate.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { TranslateService } from '@ngx-translate/core';
import { LocaleService } from './locale.service';

let _service: TranslateService;
let _service: LocaleService;

export function setTranslationService(pipe: TranslateService) {
_service = pipe;
export function setTranslationService(service: LocaleService) {
_service = service;
}

export function i18n(key: string, args: Record<string, any> = {}) {
if (!_service) return key;
return _service.instant(key, args);
return _service.get(key, args);
}
4 changes: 1 addition & 3 deletions apps/backoffice/src/app/domains/domains.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';

import { ROUTES } from './domains.routes';

Expand All @@ -11,8 +10,8 @@ import { DomainAuthenticationComponent } from './domain-authentication.component
import { DomainUsersComponent } from './domain-users.component';
import { DomainAboutComponent } from './domain-about.component';

import { SharedContentModule } from 'apps/backoffice/src/app/ui/ui.module';
import { DomainsComponent } from './domains.component';
import { SharedContentModule } from '../ui/ui.module';

@NgModule({
declarations: [
Expand All @@ -28,7 +27,6 @@ import { DomainsComponent } from './domains.component';
ReactiveFormsModule,
RouterModule.forChild(ROUTES),
SharedContentModule,
TranslateModule.forChild(),
],
})
export class AppDomainsModule {}
5 changes: 2 additions & 3 deletions apps/backoffice/src/app/drivers/drivers.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';

import { ROUTES } from './drivers.routes';

import { DriverAboutComponent } from './driver-about.component';
import { DriverModulesComponent } from './driver-devices.component';
import { SharedContentModule } from 'apps/backoffice/src/app/ui/ui.module';

import { DriversComponent } from './drivers.component';
import { DriverUpdateListModalComponent } from './driver-update-list-modal.component';
import { SharedContentModule } from '../ui/ui.module';

@NgModule({
declarations: [
Expand All @@ -24,7 +24,6 @@ import { DriverUpdateListModalComponent } from './driver-update-list-modal.compo
FormsModule,
RouterModule.forChild(ROUTES),
SharedContentModule,
TranslateModule.forChild(),
],
})
export class AppDriversModule {}
5 changes: 2 additions & 3 deletions apps/backoffice/src/app/metrics/metrics.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';

import { ROUTES } from './metrics.routes';

import { MetricsComponent } from './metrics.component';
import { SharedContentModule } from 'apps/backoffice/src/app/ui/ui.module';

import { ClockComponent } from './clock.component';
import { SharedContentModule } from '../ui/ui.module';

@NgModule({
declarations: [MetricsComponent, ClockComponent],
Expand All @@ -17,7 +17,6 @@ import { ClockComponent } from './clock.component';
FormsModule,
RouterModule.forChild(ROUTES),
SharedContentModule,
TranslateModule.forChild(),
],
})
export class AppMetricsModule {}
5 changes: 2 additions & 3 deletions apps/backoffice/src/app/modules/modules.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';

import { ROUTES } from './modules.routes';

import { ModuleAboutComponent } from './module-about.component';
import { ModuleSystemsComponent } from './module-systems.component';
import { SharedContentModule } from 'apps/backoffice/src/app/ui/ui.module';

import { ModulesComponent } from './modules.component';
import { SharedContentModule } from '../ui/ui.module';

@NgModule({
declarations: [
Expand All @@ -22,7 +22,6 @@ import { ModulesComponent } from './modules.component';
FormsModule,
RouterModule.forChild(ROUTES),
SharedContentModule,
TranslateModule.forChild(),
],
})
export class AppModulesModule {}
Loading

0 comments on commit 2cbb75d

Please sign in to comment.