feat; add multi language support
This commit is contained in:
@@ -5,20 +5,20 @@
|
|||||||
<app-form-field
|
<app-form-field
|
||||||
[errorsDictionary]="companyAndNameErrorsDictionary"
|
[errorsDictionary]="companyAndNameErrorsDictionary"
|
||||||
formControlName="name"
|
formControlName="name"
|
||||||
[label]="(strings.name|upperfirst) + ':'"
|
[label]="(languageManager.strings.name|upperfirst) + ':'"
|
||||||
[placeholder]="strings.contactsName|upperfirst"
|
[placeholder]="languageManager.strings.contactsName|upperfirst"
|
||||||
/>
|
/>
|
||||||
<app-form-field
|
<app-form-field
|
||||||
[errorsDictionary]="companyAndNameErrorsDictionary"
|
[errorsDictionary]="companyAndNameErrorsDictionary"
|
||||||
formControlName="company"
|
formControlName="company"
|
||||||
[label]="(strings.company|upperfirst) + ':'"
|
[label]="(languageManager.strings.company|upperfirst) + ':'"
|
||||||
[placeholder]="strings.contactsCompany|upperfirst"
|
[placeholder]="languageManager.strings.contactsCompany|upperfirst"
|
||||||
/>
|
/>
|
||||||
<app-form-field
|
<app-form-field
|
||||||
[errorsDictionary]="phoneErrorsDictionary"
|
[errorsDictionary]="phoneErrorsDictionary"
|
||||||
formControlName="phone"
|
formControlName="phone"
|
||||||
[label]="(strings.phone|upperfirst) +':'"
|
[label]="(languageManager.strings.phone|upperfirst) +':'"
|
||||||
[placeholder]="strings.contactsPhone|upperfirst"
|
[placeholder]="languageManager.strings.contactsPhone|upperfirst"
|
||||||
type="tel"
|
type="tel"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Component, inject, input, output } from '@angular/core';
|
import { Component, inject, input, output } from '@angular/core';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
import { FormField } from '../form-field/form-field';
|
import { FormField } from '../form-field/form-field';
|
||||||
import { STRINGS_INJECTOR } from '../../app.config';
|
|
||||||
import { SquaredBtn } from '../squared-btn/squared-btn';
|
import { SquaredBtn } from '../squared-btn/squared-btn';
|
||||||
import { NameAndCompanyFieldsErrorsDictionary } from '../../errors-dictionaries/name-and-company-field';
|
import { NameAndCompanyFieldsErrorsDictionary } from '../../errors-dictionaries/name-and-company-field';
|
||||||
import { PhoneFieldErroresDictionary } from '../../errors-dictionaries/phone-field';
|
import { PhoneFieldErroresDictionary } from '../../errors-dictionaries/phone-field';
|
||||||
@@ -9,6 +8,7 @@ import { UpperfirstPipe } from '../../pipes/upperfirst-pipe';
|
|||||||
import { ContactDTO } from '../../models/ContactDTO';
|
import { ContactDTO } from '../../models/ContactDTO';
|
||||||
import { ContactFormValue } from '../../types/ContactFormValue.type';
|
import { ContactFormValue } from '../../types/ContactFormValue.type';
|
||||||
import { FormGroupContact } from '../../utils/form-group-contact';
|
import { FormGroupContact } from '../../utils/form-group-contact';
|
||||||
|
import { LanguageManager } from '../../services/language-manager';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-contact-form',
|
selector: 'app-contact-form',
|
||||||
@@ -20,7 +20,7 @@ export class ContactForm {
|
|||||||
contact = output<ContactDTO>();
|
contact = output<ContactDTO>();
|
||||||
form = input(new FormGroupContact());
|
form = input(new FormGroupContact());
|
||||||
submitText = input('');
|
submitText = input('');
|
||||||
protected strings = inject(STRINGS_INJECTOR);
|
protected languageManager = inject(LanguageManager);
|
||||||
protected companyAndNameErrorsDictionary =
|
protected companyAndNameErrorsDictionary =
|
||||||
new NameAndCompanyFieldsErrorsDictionary().getDictionary();
|
new NameAndCompanyFieldsErrorsDictionary().getDictionary();
|
||||||
protected phoneErrorsDictionary = new PhoneFieldErroresDictionary().getDictionary();
|
protected phoneErrorsDictionary = new PhoneFieldErroresDictionary().getDictionary();
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
<table class="contact-list">
|
<table class="contact-list">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{strings.name}}</th>
|
<th>{{languageManager.strings.name}}</th>
|
||||||
<th>{{strings.company}}</th>
|
<th>{{languageManager.strings.company}}</th>
|
||||||
<th>{{strings.phone}}</th>
|
<th>{{languageManager.strings.phone}}</th>
|
||||||
<th>{{strings.actions}}</th>
|
<th>{{languageManager.strings.actions}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Component, inject, input } from '@angular/core';
|
import { Component, inject, input } from '@angular/core';
|
||||||
import { STRINGS_INJECTOR } from '../../app.config';
|
|
||||||
import { ContactDTO } from '../../models/ContactDTO';
|
import { ContactDTO } from '../../models/ContactDTO';
|
||||||
import { ContactActionsBar } from '../contact-actions-bar/contact-actions-bar';
|
import { ContactActionsBar } from '../contact-actions-bar/contact-actions-bar';
|
||||||
import { ContactService } from '../../services/contact.service';
|
import { ContactService } from '../../services/contact.service';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
import { LanguageManager } from '../../services/language-manager';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-contact-list-table',
|
selector: 'app-contact-list-table',
|
||||||
@@ -13,7 +13,7 @@ import { Router } from '@angular/router';
|
|||||||
})
|
})
|
||||||
export class ContactListTable {
|
export class ContactListTable {
|
||||||
contactList = input<ContactDTO[]>([]);
|
contactList = input<ContactDTO[]>([]);
|
||||||
protected readonly strings = inject(STRINGS_INJECTOR);
|
protected readonly languageManager = inject(LanguageManager);
|
||||||
private readonly contactService = inject(ContactService);
|
private readonly contactService = inject(ContactService);
|
||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<div class="contact-list">
|
<div class="contact-list">
|
||||||
<div class="contact-list__container">
|
<div class="contact-list__container">
|
||||||
<h2>{{strings.contacts|upperfirst}}</h2>
|
<h2>{{languageManager.strings.contacts|upperfirst}}</h2>
|
||||||
<app-contact-search-bar (contactSearch)="filter=$event"/>
|
<app-contact-search-bar (contactSearch)="filter=$event"/>
|
||||||
<app-counter
|
<app-counter
|
||||||
[count]="(this.contacts$|async)?.length ?? 0"
|
[count]="(this.contacts$|async)?.length ?? 0"
|
||||||
item="{{strings.contacts}}"
|
item="{{languageManager.strings.contacts}}"
|
||||||
/>
|
/>
|
||||||
<app-contact-list-table [contactList]="(this.contacts$|async)|contactsFilter:filter"/>
|
<app-contact-list-table [contactList]="(this.contacts$|async)|contactsFilter:filter"/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Component, inject, OnInit } from '@angular/core';
|
import { Component, inject, OnInit } from '@angular/core';
|
||||||
import { STRINGS_INJECTOR } from '../../app.config';
|
|
||||||
import { UpperfirstPipe } from '../../pipes/upperfirst-pipe';
|
import { UpperfirstPipe } from '../../pipes/upperfirst-pipe';
|
||||||
import { ContactSearchBar } from '../contact-search-bar/contact-search-bar';
|
import { ContactSearchBar } from '../contact-search-bar/contact-search-bar';
|
||||||
import { ContactListTable } from '../contact-list-table/contact-list-table';
|
import { ContactListTable } from '../contact-list-table/contact-list-table';
|
||||||
@@ -7,6 +6,7 @@ import { ContactService } from '../../services/contact.service';
|
|||||||
import { AsyncPipe } from '@angular/common';
|
import { AsyncPipe } from '@angular/common';
|
||||||
import { Counter } from '../counter/counter';
|
import { Counter } from '../counter/counter';
|
||||||
import { ContactsFilterPipe } from '../../pipes/contacts-filter-pipe';
|
import { ContactsFilterPipe } from '../../pipes/contacts-filter-pipe';
|
||||||
|
import { LanguageManager } from '../../services/language-manager';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-contact-list',
|
selector: 'app-contact-list',
|
||||||
@@ -23,7 +23,7 @@ import { ContactsFilterPipe } from '../../pipes/contacts-filter-pipe';
|
|||||||
})
|
})
|
||||||
export class ContactList implements OnInit {
|
export class ContactList implements OnInit {
|
||||||
private readonly contactService = inject(ContactService);
|
private readonly contactService = inject(ContactService);
|
||||||
protected readonly strings = inject(STRINGS_INJECTOR);
|
protected readonly languageManager = inject(LanguageManager);
|
||||||
protected contacts$ = this.contactService.contacts$;
|
protected contacts$ = this.contactService.contacts$;
|
||||||
protected filter = '';
|
protected filter = '';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<input
|
<input
|
||||||
(input)="contactSearch.emit($event.target.value)"
|
(input)="contactSearch.emit($event.target.value)"
|
||||||
class="search-bar shadow"
|
class="search-bar shadow"
|
||||||
placeholder="{{strings.searchContactPlaceholder}}"
|
placeholder="{{languageManager.strings.searchContactPlaceholder|upperfirst}}"
|
||||||
type="text">
|
type="text">
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
import { Component, inject, output } from '@angular/core';
|
import { Component, inject, output } from '@angular/core';
|
||||||
import { STRINGS_INJECTOR } from '../../app.config';
|
import { LanguageManager } from '../../services/language-manager';
|
||||||
|
import { UpperfirstPipe } from '../../pipes/upperfirst-pipe';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-contact-search-bar',
|
selector: 'app-contact-search-bar',
|
||||||
imports: [],
|
imports: [UpperfirstPipe],
|
||||||
templateUrl: './contact-search-bar.html',
|
templateUrl: './contact-search-bar.html',
|
||||||
styleUrl: './contact-search-bar.scss',
|
styleUrl: './contact-search-bar.scss',
|
||||||
})
|
})
|
||||||
export class ContactSearchBar {
|
export class ContactSearchBar {
|
||||||
contactSearch = output<string>()
|
contactSearch = output<string>();
|
||||||
protected readonly strings = inject(STRINGS_INJECTOR);
|
protected readonly languageManager = inject(LanguageManager);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
@if(notification$(); as notification) {
|
@if(notification$(); as notification) {
|
||||||
<div class="notification notification--{{notification.type}} notification--fade-in-out">
|
<div class="notification notification--{{notification.type}} notification--fade-in-out">
|
||||||
<p>{{ notification.message }}</p>
|
<p>{{ notification.message|upperfirst }}</p>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { Notifier } from '../../services/notifier';
|
import { Notifier } from '../../services/notifier';
|
||||||
|
import { UpperfirstPipe } from '../../pipes/upperfirst-pipe';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-notification',
|
selector: 'app-notification',
|
||||||
imports: [],
|
imports: [UpperfirstPipe],
|
||||||
templateUrl: './notification.html',
|
templateUrl: './notification.html',
|
||||||
styleUrl: './notification.scss',
|
styleUrl: './notification.scss',
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { inject } from '@angular/core';
|
import { inject } from '@angular/core';
|
||||||
import { Dictionary } from '../interfaces/dictionary.interface';
|
import { Dictionary } from '../interfaces/dictionary.interface';
|
||||||
import { STRINGS_INJECTOR } from '../app.config';
|
import { LanguageManager } from '../services/language-manager';
|
||||||
|
|
||||||
export class NameAndCompanyFieldsErrorsDictionary implements Dictionary {
|
export class NameAndCompanyFieldsErrorsDictionary implements Dictionary {
|
||||||
private readonly strings = inject(STRINGS_INJECTOR);
|
private readonly languageManager = inject(LanguageManager);
|
||||||
private readonly maxlen: string;
|
private readonly maxlen: string;
|
||||||
private readonly required = this.strings.errorMessageRequired;
|
private readonly required = this.languageManager.strings.errorMessageRequired;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.maxlen = this.strings.errorMessageMaxLength(120);
|
this.maxlen = this.languageManager.strings.errorMessageMaxLength(120);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDictionary(): { [key: string]: string } {
|
getDictionary(): { [key: string]: string } {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { inject } from '@angular/core';
|
import { inject } from '@angular/core';
|
||||||
import { Dictionary } from '../interfaces/dictionary.interface';
|
import { Dictionary } from '../interfaces/dictionary.interface';
|
||||||
import { STRINGS_INJECTOR } from '../app.config';
|
import { LanguageManager } from '../services/language-manager';
|
||||||
|
|
||||||
export class PhoneFieldErroresDictionary implements Dictionary {
|
export class PhoneFieldErroresDictionary implements Dictionary {
|
||||||
strings = inject(STRINGS_INJECTOR);
|
languageManager = inject(LanguageManager);
|
||||||
pattern = this.strings.errorMessagePhonePattern;
|
pattern = this.languageManager.strings.errorMessagePhonePattern;
|
||||||
required = this.strings.errorMessageRequired;
|
required = this.languageManager.strings.errorMessageRequired;
|
||||||
|
|
||||||
getDictionary(): { [key: string]: string } {
|
getDictionary(): { [key: string]: string } {
|
||||||
const { required, pattern } = this;
|
const { required, pattern } = this;
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import { ContactDTO } from '../../models/ContactDTO';
|
|||||||
import { provideHttpClient } from '@angular/common/http';
|
import { provideHttpClient } from '@angular/common/http';
|
||||||
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
|
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
|
||||||
import { environment } from '../../../environments/environment';
|
import { environment } from '../../../environments/environment';
|
||||||
|
import { STRINGS_INJECTOR } from '../../app.config';
|
||||||
|
import { strings } from '../../strings';
|
||||||
|
|
||||||
describe('contactResolver', () => {
|
describe('contactResolver', () => {
|
||||||
let httpTestingController: HttpTestingController;
|
let httpTestingController: HttpTestingController;
|
||||||
@@ -31,6 +33,7 @@ describe('contactResolver', () => {
|
|||||||
provideHttpClient(),
|
provideHttpClient(),
|
||||||
provideHttpClientTesting(),
|
provideHttpClientTesting(),
|
||||||
{ provide: Router, useValue: router },
|
{ provide: Router, useValue: router },
|
||||||
|
{ provide: STRINGS_INJECTOR, useValue: strings },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
httpTestingController = TestBed.inject(HttpTestingController);
|
httpTestingController = TestBed.inject(HttpTestingController);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<app-main-header
|
<app-main-header
|
||||||
[title]="strings.editContact"
|
[title]="languageManager.strings.editContact"
|
||||||
>
|
>
|
||||||
<app-rounded-btn
|
<app-rounded-btn
|
||||||
(keydown)="goBack()"
|
(keydown)="goBack()"
|
||||||
(click)="goBack()"
|
(click)="goBack()"
|
||||||
slot="action-button"
|
slot="action-button"
|
||||||
text="Go back"
|
text={{languageManager.strings.goBack|upperfirst}}
|
||||||
/>
|
/>
|
||||||
</app-main-header>
|
</app-main-header>
|
||||||
<app-card bgColor="var(--secondary)">
|
<app-card bgColor="var(--secondary)">
|
||||||
@@ -14,9 +14,9 @@
|
|||||||
class="form"
|
class="form"
|
||||||
(contact)="edit(form.value)"
|
(contact)="edit(form.value)"
|
||||||
[form]="form"
|
[form]="form"
|
||||||
[submitText]="strings.save"
|
[submitText]="languageManager.strings.save"
|
||||||
><app-form-header
|
><app-form-header
|
||||||
[title]="strings.editTheContact|upperfirst"
|
[title]="languageManager.strings.editTheContact|upperfirst"
|
||||||
slot="header"
|
slot="header"
|
||||||
/>
|
/>
|
||||||
</app-contact-form>
|
</app-contact-form>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { MainHeader } from '../../components/main-header/main-header';
|
import { MainHeader } from '../../components/main-header/main-header';
|
||||||
import { STRINGS_INJECTOR } from '../../app.config';
|
|
||||||
import { RoundedBtn } from '../../components/rounded-btn/rounded-btn';
|
import { RoundedBtn } from '../../components/rounded-btn/rounded-btn';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { Card } from '../../components/card/card';
|
import { Card } from '../../components/card/card';
|
||||||
@@ -13,6 +12,7 @@ import { FormGroupContact } from '../../utils/form-group-contact';
|
|||||||
import { AsyncPipe } from '@angular/common';
|
import { AsyncPipe } from '@angular/common';
|
||||||
import { ContactService } from '../../services/contact.service';
|
import { ContactService } from '../../services/contact.service';
|
||||||
import { ContactFormValue } from '../../types/ContactFormValue.type';
|
import { ContactFormValue } from '../../types/ContactFormValue.type';
|
||||||
|
import { LanguageManager } from '../../services/language-manager';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-edit',
|
selector: 'app-edit',
|
||||||
@@ -21,7 +21,7 @@ import { ContactFormValue } from '../../types/ContactFormValue.type';
|
|||||||
styleUrl: './edit.scss',
|
styleUrl: './edit.scss',
|
||||||
})
|
})
|
||||||
export class Edit {
|
export class Edit {
|
||||||
protected readonly strings = inject(STRINGS_INJECTOR);
|
protected readonly languageManager = inject(LanguageManager);
|
||||||
private readonly activatedRoute = inject(ActivatedRoute);
|
private readonly activatedRoute = inject(ActivatedRoute);
|
||||||
private readonly contactService = inject(ContactService);
|
private readonly contactService = inject(ContactService);
|
||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<app-main-header [title]="strings.contactList"/>
|
<app-main-header [title]="languageManager.strings.contactAgenda"/>
|
||||||
<app-card bgColor="var(--secondary)">
|
<app-card bgColor="var(--secondary)">
|
||||||
<app-contact-form
|
<app-contact-form
|
||||||
(contact)="save($event)"
|
(contact)="save($event)"
|
||||||
[form]="form"
|
[form]="form"
|
||||||
[submitText]="strings.add"
|
[submitText]="languageManager.strings.add"
|
||||||
class="form"
|
class="form"
|
||||||
><app-form-header
|
><app-form-header
|
||||||
[subtitle]="strings.allFieldRequired|upperfirst"
|
[subtitle]="languageManager.strings.allFieldRequired|upperfirst"
|
||||||
[title]="strings.addContact|upperfirst"
|
[title]="languageManager.strings.addContact|upperfirst"
|
||||||
slot="header"
|
slot="header"
|
||||||
/>
|
/>
|
||||||
</app-contact-form>
|
</app-contact-form>
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import { ContactList } from '../../components/contact-list/contact-list';
|
|||||||
import { ContactService } from '../../services/contact.service';
|
import { ContactService } from '../../services/contact.service';
|
||||||
import { ContactDTO } from '../../models/ContactDTO';
|
import { ContactDTO } from '../../models/ContactDTO';
|
||||||
import { FormHeader } from '../../components/form-header/form-header';
|
import { FormHeader } from '../../components/form-header/form-header';
|
||||||
import { STRINGS_INJECTOR } from '../../app.config';
|
|
||||||
import { UpperfirstPipe } from '../../pipes/upperfirst-pipe';
|
import { UpperfirstPipe } from '../../pipes/upperfirst-pipe';
|
||||||
import { MainHeader } from '../../components/main-header/main-header';
|
import { MainHeader } from '../../components/main-header/main-header';
|
||||||
import { FormGroupContact } from '../../utils/form-group-contact';
|
import { FormGroupContact } from '../../utils/form-group-contact';
|
||||||
|
import { LanguageManager } from '../../services/language-manager';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-main',
|
selector: 'app-main',
|
||||||
@@ -18,7 +18,7 @@ import { FormGroupContact } from '../../utils/form-group-contact';
|
|||||||
})
|
})
|
||||||
export class Main {
|
export class Main {
|
||||||
protected readonly form = new FormGroupContact();
|
protected readonly form = new FormGroupContact();
|
||||||
protected readonly strings = inject(STRINGS_INJECTOR);
|
protected readonly languageManager = inject(LanguageManager);
|
||||||
private readonly contactService = inject(ContactService);
|
private readonly contactService = inject(ContactService);
|
||||||
|
|
||||||
save(contactDTO: ContactDTO) {
|
save(contactDTO: ContactDTO) {
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import { provideHttpClient } from '@angular/common/http';
|
|||||||
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
|
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
|
||||||
import { environment } from '../../environments/environment';
|
import { environment } from '../../environments/environment';
|
||||||
import { ContactDTO } from '../models/ContactDTO';
|
import { ContactDTO } from '../models/ContactDTO';
|
||||||
|
import { STRINGS_INJECTOR } from '../app.config';
|
||||||
|
import { strings } from '../strings';
|
||||||
|
|
||||||
describe('ContactService', () => {
|
describe('ContactService', () => {
|
||||||
let service: ContactService;
|
let service: ContactService;
|
||||||
@@ -16,7 +18,11 @@ describe('ContactService', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [],
|
imports: [],
|
||||||
providers: [provideHttpClient(), provideHttpClientTesting()],
|
providers: [
|
||||||
|
provideHttpClient(),
|
||||||
|
provideHttpClientTesting(),
|
||||||
|
{ provide: STRINGS_INJECTOR, useValue: strings },
|
||||||
|
],
|
||||||
});
|
});
|
||||||
service = TestBed.inject(ContactService);
|
service = TestBed.inject(ContactService);
|
||||||
httpTestingController = TestBed.inject(HttpTestingController);
|
httpTestingController = TestBed.inject(HttpTestingController);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { ContactDTO } from '../models/ContactDTO';
|
|||||||
import { Response } from '../models/Response';
|
import { Response } from '../models/Response';
|
||||||
import { BehaviorSubject, map, switchMap, tap } from 'rxjs';
|
import { BehaviorSubject, map, switchMap, tap } from 'rxjs';
|
||||||
import { ResponseStateNotification } from './ResponseStateNotificatio';
|
import { ResponseStateNotification } from './ResponseStateNotificatio';
|
||||||
import { strings } from '../strings';
|
import { LanguageManager } from './language-manager';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@@ -14,7 +14,7 @@ export class ContactService {
|
|||||||
private readonly httpClient = inject(HttpClient);
|
private readonly httpClient = inject(HttpClient);
|
||||||
private readonly responseStateNotification = inject(ResponseStateNotification);
|
private readonly responseStateNotification = inject(ResponseStateNotification);
|
||||||
private readonly contacts = new BehaviorSubject<ContactDTO[]>([]);
|
private readonly contacts = new BehaviorSubject<ContactDTO[]>([]);
|
||||||
|
private readonly languageManager = inject(LanguageManager);
|
||||||
readonly contacts$ = this.contacts.asObservable();
|
readonly contacts$ = this.contacts.asObservable();
|
||||||
|
|
||||||
delete(id: number) {
|
delete(id: number) {
|
||||||
@@ -22,8 +22,8 @@ export class ContactService {
|
|||||||
(r) =>
|
(r) =>
|
||||||
this.responseStateNotification.handleResponse(
|
this.responseStateNotification.handleResponse(
|
||||||
r,
|
r,
|
||||||
strings.deleteContactSuccessNotification,
|
this.languageManager.strings.deleteContactSuccessNotification,
|
||||||
strings.errorNotification
|
this.languageManager.strings.errorNotification
|
||||||
),
|
),
|
||||||
switchMap(() => this.getAll())
|
switchMap(() => this.getAll())
|
||||||
);
|
);
|
||||||
@@ -47,8 +47,8 @@ export class ContactService {
|
|||||||
(r) =>
|
(r) =>
|
||||||
this.responseStateNotification.handleResponse(
|
this.responseStateNotification.handleResponse(
|
||||||
r,
|
r,
|
||||||
strings.createContactSuccessNotification,
|
this.languageManager.strings.createContactSuccessNotification,
|
||||||
strings.errorNotification
|
this.languageManager.strings.errorNotification
|
||||||
),
|
),
|
||||||
|
|
||||||
switchMap(() => this.getAll())
|
switchMap(() => this.getAll())
|
||||||
@@ -61,8 +61,8 @@ export class ContactService {
|
|||||||
.pipe((r) =>
|
.pipe((r) =>
|
||||||
this.responseStateNotification.handleResponse(
|
this.responseStateNotification.handleResponse(
|
||||||
r,
|
r,
|
||||||
strings.editContactSuccessNotification,
|
this.languageManager.strings.editContactSuccessNotification,
|
||||||
strings.errorNotification
|
this.languageManager.strings.errorNotification
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/app/services/language-manager.spec.ts
Normal file
27
src/app/services/language-manager.spec.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { LanguageManager } from './language-manager';
|
||||||
|
import { strings } from '../strings';
|
||||||
|
import { STRINGS_INJECTOR } from '../app.config';
|
||||||
|
import { Language } from '../types/Language.type';
|
||||||
|
|
||||||
|
describe('LanguageManager', () => {
|
||||||
|
let service: LanguageManager;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [{ provide: STRINGS_INJECTOR, useValue: strings }],
|
||||||
|
});
|
||||||
|
service = TestBed.inject(LanguageManager);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should switch language', () => {
|
||||||
|
const SELECTED_LANGUAGE_MOCK: Language = 'es';
|
||||||
|
service.setLanguage(SELECTED_LANGUAGE_MOCK);
|
||||||
|
expect(service.strings).toEqual(strings[SELECTED_LANGUAGE_MOCK]);
|
||||||
|
});
|
||||||
|
});
|
||||||
16
src/app/services/language-manager.ts
Normal file
16
src/app/services/language-manager.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { inject, Injectable } from '@angular/core';
|
||||||
|
import { STRINGS_INJECTOR } from '../app.config';
|
||||||
|
import { Language } from '../types/Language.type';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class LanguageManager {
|
||||||
|
private readonly stringsDictionary = inject(STRINGS_INJECTOR);
|
||||||
|
|
||||||
|
strings = this.stringsDictionary.en;
|
||||||
|
|
||||||
|
setLanguage(language: Language) {
|
||||||
|
this.strings = this.stringsDictionary[language];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,25 +1,54 @@
|
|||||||
export const strings = Object.freeze({
|
export const strings = Object.freeze({
|
||||||
|
en: {
|
||||||
actions: 'actions',
|
actions: 'actions',
|
||||||
add: 'add',
|
add: 'add',
|
||||||
addContact: 'add a contact',
|
addContact: 'add a contact',
|
||||||
allFieldRequired: 'all fields are required',
|
allFieldRequired: 'all fields are required',
|
||||||
company: 'company',
|
company: 'company',
|
||||||
|
contactAgenda: 'contact agenda',
|
||||||
contacts: 'contacts',
|
contacts: 'contacts',
|
||||||
contactsName: "Contact's name",
|
contactsName: "contact's name",
|
||||||
contactsCompany: "Contact's company",
|
contactsCompany: "contact's company",
|
||||||
contactsPhone: "Contact's phone",
|
contactsPhone: "contact's phone",
|
||||||
contactList: 'contact list',
|
createContactSuccessNotification: 'contact created successfully',
|
||||||
createContactSuccessNotification: 'Contact created successfully',
|
deleteContactSuccessNotification: 'contact deleted successfully',
|
||||||
deleteContactSuccessNotification: 'Contact deleted successfully',
|
|
||||||
editContact: 'edit contact',
|
editContact: 'edit contact',
|
||||||
editContactSuccessNotification: 'Contact edited successfully',
|
editContactSuccessNotification: 'contact edited successfully',
|
||||||
editTheContact: 'edit the contact',
|
editTheContact: 'edit the contact',
|
||||||
errorMessageMaxLength: (maxLen: number) => `Must be ${maxLen} characters or fewer.`,
|
errorMessageMaxLength: (maxLen: number) => `Must be ${maxLen} characters or fewer.`,
|
||||||
errorMessagePhonePattern: `Valid format: + (optional) plus 12 to 15 digits`,
|
errorMessagePhonePattern: `Valid format: + (optional) plus 12 to 15 digits`,
|
||||||
errorMessageRequired: 'This field is required.',
|
errorMessageRequired: 'This field is required.',
|
||||||
errorNotification: 'Oops, there was an error',
|
errorNotification: 'Oops, there was an error',
|
||||||
|
goBack: 'go back',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
phone: 'phone',
|
phone: 'phone',
|
||||||
save: 'save',
|
save: 'save',
|
||||||
searchContactPlaceholder: 'Search contact...',
|
searchContactPlaceholder: 'Search contact...',
|
||||||
|
},
|
||||||
|
es: {
|
||||||
|
actions: 'acciones',
|
||||||
|
add: 'añadir',
|
||||||
|
addContact: 'añada un contacto',
|
||||||
|
allFieldRequired: 'todos los campos son obligatorios',
|
||||||
|
company: 'empresa',
|
||||||
|
contactAgenda: 'agenda de contactos',
|
||||||
|
contacts: 'contactos',
|
||||||
|
contactsName: 'nombre contacto',
|
||||||
|
contactsCompany: 'empresa contacto',
|
||||||
|
contactsPhone: 'teléfono contacto',
|
||||||
|
createContactSuccessNotification: 'contacto creado correctamente',
|
||||||
|
deleteContactSuccessNotification: 'contacto eliminado',
|
||||||
|
editContact: 'editar contacto',
|
||||||
|
editContactSuccessNotification: 'contacto editado correctamente',
|
||||||
|
editTheContact: 'edite el contacto. ',
|
||||||
|
errorMessageMaxLength: (maxLen: number) => `Debe contener ${maxLen} caracteres or menos.`,
|
||||||
|
errorMessagePhonePattern: `Formato: + (opcional) y 12 a 15 digitos`,
|
||||||
|
errorMessageRequired: 'este campo es requerido.',
|
||||||
|
errorNotification: 'hubo un error',
|
||||||
|
goBack: 'volver',
|
||||||
|
name: 'nombre',
|
||||||
|
phone: 'teléfono',
|
||||||
|
save: 'guardar',
|
||||||
|
searchContactPlaceholder: 'buscar contactos...',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
3
src/app/types/Language.type.ts
Normal file
3
src/app/types/Language.type.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { strings } from '../strings';
|
||||||
|
|
||||||
|
export type Language = keyof typeof strings;
|
||||||
Reference in New Issue
Block a user