|
1 | | -import { LANGUAGES, getLanguageFlag, } from '../../../../consts/languages'; |
2 | | -import { CUSTOM_ELEMENTS_SCHEMA, Component, Input } from '@angular/core'; |
3 | | -import { map, startWith } from 'rxjs/operators'; |
4 | | - |
5 | | -import { BaseEditFieldComponent } from '../base-row-field/base-row-field.component'; |
6 | 1 | import { CommonModule } from '@angular/common'; |
7 | | -import { FormControl } from '@angular/forms'; |
8 | | -import { FormsModule } from '@angular/forms'; |
| 2 | +import { Component, CUSTOM_ELEMENTS_SCHEMA, computed, input, OnInit, output, signal } from '@angular/core'; |
| 3 | +import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; |
9 | 4 | import { MatAutocompleteModule } from '@angular/material/autocomplete'; |
10 | 5 | import { MatFormFieldModule } from '@angular/material/form-field'; |
11 | 6 | import { MatInputModule } from '@angular/material/input'; |
12 | 7 | import { Observable } from 'rxjs'; |
13 | | -import { ReactiveFormsModule } from '@angular/forms'; |
| 8 | +import { map, startWith } from 'rxjs/operators'; |
| 9 | +import { TableField, TableForeignKey, WidgetStructure } from 'src/app/models/table'; |
| 10 | +import { getLanguageFlag, LANGUAGES } from '../../../../consts/languages'; |
| 11 | +import { normalizeFieldName } from '../../../../lib/normalize'; |
| 12 | + |
| 13 | +interface LanguageOption { |
| 14 | + value: string | null; |
| 15 | + label: string; |
| 16 | + flag: string; |
| 17 | + nativeName?: string; |
| 18 | +} |
14 | 19 |
|
15 | 20 | @Component({ |
16 | | - selector: 'app-edit-language', |
17 | | - imports: [CommonModule, FormsModule, ReactiveFormsModule, MatFormFieldModule, MatAutocompleteModule, MatInputModule], |
18 | | - templateUrl: './language.component.html', |
19 | | - styleUrls: ['./language.component.css'], |
20 | | - schemas: [CUSTOM_ELEMENTS_SCHEMA] |
| 21 | + selector: 'app-edit-language', |
| 22 | + imports: [CommonModule, FormsModule, ReactiveFormsModule, MatFormFieldModule, MatAutocompleteModule, MatInputModule], |
| 23 | + templateUrl: './language.component.html', |
| 24 | + styleUrls: ['./language.component.css'], |
| 25 | + schemas: [CUSTOM_ELEMENTS_SCHEMA], |
21 | 26 | }) |
22 | | -export class LanguageEditComponent extends BaseEditFieldComponent { |
23 | | - @Input() value: string; |
| 27 | +export class LanguageEditComponent implements OnInit { |
| 28 | + readonly key = input<string>(); |
| 29 | + readonly label = input<string>(); |
| 30 | + readonly required = input<boolean>(false); |
| 31 | + readonly readonly = input<boolean>(false); |
| 32 | + readonly structure = input<TableField>(); |
| 33 | + readonly disabled = input<boolean>(false); |
| 34 | + readonly widgetStructure = input<WidgetStructure>(); |
| 35 | + readonly relations = input<TableForeignKey>(); |
| 36 | + readonly value = input<string>(); |
| 37 | + |
| 38 | + readonly onFieldChange = output<any>(); |
24 | 39 |
|
25 | | - public languages: {value: string | null, label: string, flag: string, nativeName?: string}[] = []; |
26 | | - public languageControl = new FormControl<{value: string | null, label: string, flag: string, nativeName?: string} | string>(''); |
27 | | - public filteredLanguages: Observable<{value: string | null, label: string, flag: string, nativeName?: string}[]>; |
28 | | - public showFlag: boolean = true; |
29 | | - public selectedLanguageFlag: string = ''; |
| 40 | + readonly normalizedLabel = computed(() => normalizeFieldName(this.label() || '')); |
30 | 41 |
|
31 | | - originalOrder = () => { return 0; } |
| 42 | + readonly showFlag = computed(() => { |
| 43 | + const ws = this.widgetStructure(); |
| 44 | + if (!ws?.widget_params) return true; |
| 45 | + try { |
| 46 | + const params = typeof ws.widget_params === 'string' ? JSON.parse(ws.widget_params) : ws.widget_params; |
| 47 | + return params.show_flag !== undefined ? params.show_flag : true; |
| 48 | + } catch { |
| 49 | + return true; |
| 50 | + } |
| 51 | + }); |
32 | 52 |
|
33 | | - ngOnInit(): void { |
34 | | - super.ngOnInit(); |
35 | | - this.parseWidgetParams(); |
36 | | - this.loadLanguages(); |
37 | | - this.setupAutocomplete(); |
38 | | - this.setInitialValue(); |
39 | | - } |
| 53 | + public languages: LanguageOption[] = []; |
| 54 | + public languageControl = new FormControl<LanguageOption | string>(''); |
| 55 | + public filteredLanguages: Observable<LanguageOption[]>; |
| 56 | + public selectedLanguageFlag = signal(''); |
40 | 57 |
|
41 | | - private parseWidgetParams(): void { |
42 | | - if (this.widgetStructure?.widget_params) { |
43 | | - try { |
44 | | - const params = typeof this.widgetStructure.widget_params === 'string' |
45 | | - ? JSON.parse(this.widgetStructure.widget_params) |
46 | | - : this.widgetStructure.widget_params; |
| 58 | + originalOrder = () => { |
| 59 | + return 0; |
| 60 | + }; |
47 | 61 |
|
48 | | - if (params.show_flag !== undefined) { |
49 | | - this.showFlag = params.show_flag; |
50 | | - } |
51 | | - } catch (e) { |
52 | | - console.error('Error parsing language widget params:', e); |
53 | | - } |
54 | | - } |
55 | | - } |
| 62 | + ngOnInit(): void { |
| 63 | + this.loadLanguages(); |
| 64 | + this.setupAutocomplete(); |
| 65 | + this.setInitialValue(); |
| 66 | + } |
56 | 67 |
|
57 | | - private setupAutocomplete(): void { |
58 | | - this.filteredLanguages = this.languageControl.valueChanges.pipe( |
59 | | - startWith(''), |
60 | | - map(value => { |
61 | | - // Update flag when value changes |
62 | | - if (typeof value === 'object' && value !== null) { |
63 | | - this.selectedLanguageFlag = value.flag; |
64 | | - } else if (typeof value === 'string') { |
65 | | - // Clear flag if user is typing |
66 | | - this.selectedLanguageFlag = ''; |
67 | | - } |
68 | | - return this._filter(typeof value === 'string' ? value : (value?.label || '')); |
69 | | - }) |
70 | | - ); |
71 | | - } |
| 68 | + displayFn(language: any): string { |
| 69 | + if (!language) return ''; |
| 70 | + return typeof language === 'string' ? language : language.label; |
| 71 | + } |
72 | 72 |
|
73 | | - private setInitialValue(): void { |
74 | | - if (this.value) { |
75 | | - const language = this.languages.find(l => l.value && l.value.toLowerCase() === this.value.toLowerCase()); |
76 | | - if (language) { |
77 | | - this.languageControl.setValue(language); |
78 | | - this.selectedLanguageFlag = language.flag; |
79 | | - } |
80 | | - } |
81 | | - } |
| 73 | + onLanguageSelected(selectedLanguage: LanguageOption): void { |
| 74 | + this.selectedLanguageFlag.set(selectedLanguage.flag); |
| 75 | + this.onFieldChange.emit(selectedLanguage.value); |
| 76 | + } |
82 | 77 |
|
83 | | - private _filter(value: string): {value: string | null, label: string, flag: string, nativeName?: string}[] { |
84 | | - const filterValue = value.toLowerCase(); |
85 | | - return this.languages.filter(language => |
86 | | - language.label?.toLowerCase().includes(filterValue) || |
87 | | - (language.value?.toLowerCase().includes(filterValue)) || |
88 | | - (language.nativeName?.toLowerCase().includes(filterValue)) |
89 | | - ); |
90 | | - } |
| 78 | + private setupAutocomplete(): void { |
| 79 | + this.filteredLanguages = this.languageControl.valueChanges.pipe( |
| 80 | + startWith(''), |
| 81 | + map((value) => { |
| 82 | + if (typeof value === 'object' && value !== null) { |
| 83 | + this.selectedLanguageFlag.set(value.flag); |
| 84 | + } else if (typeof value === 'string') { |
| 85 | + this.selectedLanguageFlag.set(''); |
| 86 | + } |
| 87 | + return this._filter(typeof value === 'string' ? value : value?.label || ''); |
| 88 | + }), |
| 89 | + ); |
| 90 | + } |
91 | 91 |
|
92 | | - onLanguageSelected(selectedLanguage: {value: string | null, label: string, flag: string, nativeName?: string}): void { |
93 | | - this.value = selectedLanguage.value; |
94 | | - this.selectedLanguageFlag = selectedLanguage.flag; |
95 | | - this.onFieldChange.emit(this.value); |
96 | | - } |
| 92 | + private setInitialValue(): void { |
| 93 | + const val = this.value(); |
| 94 | + if (val) { |
| 95 | + const language = this.languages.find((l) => l.value && l.value.toLowerCase() === val.toLowerCase()); |
| 96 | + if (language) { |
| 97 | + this.languageControl.setValue(language); |
| 98 | + this.selectedLanguageFlag.set(language.flag); |
| 99 | + } |
| 100 | + } |
| 101 | + } |
97 | 102 |
|
98 | | - displayFn(language: any): string { |
99 | | - if (!language) return ''; |
100 | | - // Only return the language label, flag is shown separately |
101 | | - return typeof language === 'string' ? language : language.label; |
102 | | - } |
| 103 | + private _filter(value: string): LanguageOption[] { |
| 104 | + const filterValue = value.toLowerCase(); |
| 105 | + return this.languages.filter( |
| 106 | + (language) => |
| 107 | + language.label?.toLowerCase().includes(filterValue) || |
| 108 | + language.value?.toLowerCase().includes(filterValue) || |
| 109 | + language.nativeName?.toLowerCase().includes(filterValue), |
| 110 | + ); |
| 111 | + } |
103 | 112 |
|
104 | | - private loadLanguages(): void { |
105 | | - this.languages = LANGUAGES.map(language => ({ |
106 | | - value: language.code, |
107 | | - label: language.name, |
108 | | - flag: getLanguageFlag(language), |
109 | | - nativeName: language.nativeName |
110 | | - })).toSorted((a, b) => a.label.localeCompare(b.label)); |
| 113 | + private loadLanguages(): void { |
| 114 | + this.languages = LANGUAGES.map((language) => ({ |
| 115 | + value: language.code, |
| 116 | + label: language.name, |
| 117 | + flag: getLanguageFlag(language), |
| 118 | + nativeName: language.nativeName, |
| 119 | + })).toSorted((a, b) => a.label.localeCompare(b.label)); |
111 | 120 |
|
112 | | - if (this.widgetStructure?.widget_params?.allow_null || this.structure?.allow_null) { |
113 | | - this.languages = [{ value: null, label: '', flag: '' }, ...this.languages]; |
114 | | - } |
115 | | - } |
| 121 | + const ws = this.widgetStructure(); |
| 122 | + if (ws?.widget_params?.allow_null || this.structure()?.allow_null) { |
| 123 | + this.languages = [{ value: null, label: '', flag: '' }, ...this.languages]; |
| 124 | + } |
| 125 | + } |
116 | 126 | } |
0 commit comments