diff --git a/public/i18n/en.json b/public/i18n/en.json index f0f2329..84c8541 100644 --- a/public/i18n/en.json +++ b/public/i18n/en.json @@ -22,9 +22,13 @@ "portuguese": "portuguese" }, "chain": { + "chain": "chain", "chains": "chains", "new_chain": "new chain", "edit_chain": "edit chain" + }, + "establishment": { + "establishments":"establishments" } }, "common": { diff --git a/public/i18n/es.json b/public/i18n/es.json index 49ce30e..e3ae7db 100644 --- a/public/i18n/es.json +++ b/public/i18n/es.json @@ -22,9 +22,13 @@ "portuguese": "portugués" }, "chain": { + "chain": "cadena", "chains": "cadenas", "new_chain": "nueva cadena", "edit_chain": "editar cadena" + }, + "establishment": { + "establishments":"establecimientos" } }, "common": { diff --git a/public/i18n/pt.json b/public/i18n/pt.json index f0f2329..84c8541 100644 --- a/public/i18n/pt.json +++ b/public/i18n/pt.json @@ -22,9 +22,13 @@ "portuguese": "portuguese" }, "chain": { + "chain": "chain", "chains": "chains", "new_chain": "new chain", "edit_chain": "edit chain" + }, + "establishment": { + "establishments":"establishments" } }, "common": { diff --git a/src/app/components/chain-select/chain-select.html b/src/app/components/chain-select/chain-select.html new file mode 100644 index 0000000..406884d --- /dev/null +++ b/src/app/components/chain-select/chain-select.html @@ -0,0 +1,11 @@ + + {{'settings.chain.chain'|translate|upperfirst}} + + @for(chain of chains$|async; track chain.id) { + {{chain.name}} + } + + diff --git a/src/app/components/chain-select/chain-select.scss b/src/app/components/chain-select/chain-select.scss new file mode 100644 index 0000000..53a4bc5 --- /dev/null +++ b/src/app/components/chain-select/chain-select.scss @@ -0,0 +1,3 @@ +mat-form-field { + width: 100%; +} \ No newline at end of file diff --git a/src/app/components/chain-select/chain-select.spec.ts b/src/app/components/chain-select/chain-select.spec.ts new file mode 100644 index 0000000..1b6f028 --- /dev/null +++ b/src/app/components/chain-select/chain-select.spec.ts @@ -0,0 +1,65 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Component } from '@angular/core'; +import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms'; +import { By } from '@angular/platform-browser'; +import { MatSelect } from '@angular/material/select'; +import { provideTranslateService } from '@ngx-translate/core'; +import { Chain } from '../../models/Chain'; +import { ChainDAO } from '../../dao/ChainDAO'; +import { ChainSelect } from './chain-select'; + +@Component({ + selector: 'app-chain-select-mock', + imports: [ + ChainSelect, + ReactiveFormsModule + ], + template: ` +
+ + + + `, + styleUrl: './chain-select.scss', +}) +class ChainSelectTestbed { + form = new FormGroup({mock: new FormControl()}) +} + +describe('ChainSelect', () => { + let component: ChainSelectTestbed; + let fixture: ComponentFixture; + + let chainDAO: Partial; + let CHAINS_MOCK: Chain[]; + beforeEach(async () => { + CHAINS_MOCK = [new Chain('Mock 1', '', 1)]; + + chainDAO = { + findAll: vi.fn().mockResolvedValue(CHAINS_MOCK), + }; + + await TestBed.configureTestingModule({ + imports: [ChainSelectTestbed], + providers: [{ provide: ChainDAO, useValue: chainDAO }, provideTranslateService()], + }).compileComponents(); + + fixture = TestBed.createComponent(ChainSelectTestbed); + component = fixture.componentInstance; + + }); + + it('should create', async () => { + await fixture.whenStable(); + expect(component).toBeTruthy(); + }); + + it('should match form chain with chain option', async () => { + component.form = new FormGroup({mock: new FormControl(CHAINS_MOCK[0])}); + await fixture.whenStable(); + const matSelect: MatSelect = fixture.debugElement.query(By.css('mat-select')).componentInstance; + expect(matSelect.value).toEqual(CHAINS_MOCK[0]); + }); + +}); diff --git a/src/app/components/chain-select/chain-select.ts b/src/app/components/chain-select/chain-select.ts new file mode 100644 index 0000000..f1b5f0c --- /dev/null +++ b/src/app/components/chain-select/chain-select.ts @@ -0,0 +1,53 @@ +import { Component, inject, OnInit, Optional, Self } from '@angular/core'; +import { ChainDAO } from '../../dao/ChainDAO'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatSelectModule } from '@angular/material/select'; +import { AsyncPipe } from '@angular/common'; +import { ControlValueAccessor, FormControl, NgControl, ReactiveFormsModule } from '@angular/forms'; +import { Chain } from '../../models/Chain'; +import { TranslatePipe } from '@ngx-translate/core'; +import { UpperfirstPipe } from "../../pipes/upperfirst-pipe"; + +@Component({ + selector: 'app-chain-select', + imports: [ + AsyncPipe, + MatFormFieldModule, + MatInputModule, + MatSelectModule, + ReactiveFormsModule, + TranslatePipe, + UpperfirstPipe +], + templateUrl: './chain-select.html', + styleUrl: './chain-select.scss', +}) +export class ChainSelect implements ControlValueAccessor, OnInit { + private readonly chainDAO = inject(ChainDAO); + protected chains$ = this.chainDAO.findAll(); + protected control = new FormControl(); + + constructor(@Self() @Optional() public controlDir: NgControl) { + if (this.controlDir) { + this.controlDir.valueAccessor = this; + } + } + + ngOnInit() { + this.control = this.controlDir.control; + } + + writeValue(obj: any): void {} + + registerOnChange(onChange: any) {} + + registerOnTouched(fn: any): void {} + + setDisabledState?(isDisabled: boolean): void {} + + compareFn(c1: Chain, c2: Chain) { + if (!c1 || !c2) return false; + return c1.id === c2.id; + } +}