From b93a0e3ba46662d3d51a7f6d3a31a5f986f07a17 Mon Sep 17 00:00:00 2001 From: Andrii Kostenko Date: Sun, 16 Nov 2025 21:50:06 +0000 Subject: [PATCH 1/2] language widget --- .../language/language.component.css | 49 +++++ .../language/language.component.html | 22 ++ .../language/language.component.spec.ts | 50 +++++ .../language/language.component.ts | 116 ++++++++++ .../markdown/markdown.component.css | 13 +- .../language/language.component.css | 4 + .../language/language.component.html | 4 + .../language/language.component.spec.ts | 38 ++++ .../language/language.component.ts | 51 +++++ .../markdown/markdown.component.css | 58 ++++- .../language/language.component.css | 27 +++ .../language/language.component.html | 14 ++ .../language/language.component.spec.ts | 46 ++++ .../language/language.component.ts | 54 +++++ .../markdown/markdown.component.css | 13 +- frontend/src/app/consts/languages.ts | 201 ++++++++++++++++++ frontend/src/app/consts/record-edit-types.ts | 2 + frontend/src/app/consts/record-view-types.ts | 2 + .../src/app/consts/table-display-types.ts | 2 + 19 files changed, 758 insertions(+), 8 deletions(-) create mode 100644 frontend/src/app/components/ui-components/record-edit-fields/language/language.component.css create mode 100644 frontend/src/app/components/ui-components/record-edit-fields/language/language.component.html create mode 100644 frontend/src/app/components/ui-components/record-edit-fields/language/language.component.spec.ts create mode 100644 frontend/src/app/components/ui-components/record-edit-fields/language/language.component.ts create mode 100644 frontend/src/app/components/ui-components/record-view-fields/language/language.component.css create mode 100644 frontend/src/app/components/ui-components/record-view-fields/language/language.component.html create mode 100644 frontend/src/app/components/ui-components/record-view-fields/language/language.component.spec.ts create mode 100644 frontend/src/app/components/ui-components/record-view-fields/language/language.component.ts create mode 100644 frontend/src/app/components/ui-components/table-display-fields/language/language.component.css create mode 100644 frontend/src/app/components/ui-components/table-display-fields/language/language.component.html create mode 100644 frontend/src/app/components/ui-components/table-display-fields/language/language.component.spec.ts create mode 100644 frontend/src/app/components/ui-components/table-display-fields/language/language.component.ts create mode 100644 frontend/src/app/consts/languages.ts diff --git a/frontend/src/app/components/ui-components/record-edit-fields/language/language.component.css b/frontend/src/app/components/ui-components/record-edit-fields/language/language.component.css new file mode 100644 index 000000000..d37c35d34 --- /dev/null +++ b/frontend/src/app/components/ui-components/record-edit-fields/language/language.component.css @@ -0,0 +1,49 @@ +.language-form-field { + width: 100%; +} + +.language-input-container { + display: flex; + align-items: center; + width: 100%; +} + +.language-flag-prefix { + font-size: 20px; + margin-right: 8px; + line-height: 1; +} + +.language-input { + flex: 1; + border: none !important; + outline: none !important; + background: transparent !important; +} + +.language-flag { + margin-right: 8px; + font-size: 16px; +} + +.language-name { + flex: 1; +} + +.language-native { + margin-left: 8px; + opacity: 0.8; + font-size: 13px; + font-style: italic; +} + +.language-code { + margin-left: 8px; + opacity: 0.7; + font-size: 12px; +} + +mat-option { + display: flex; + align-items: center; +} diff --git a/frontend/src/app/components/ui-components/record-edit-fields/language/language.component.html b/frontend/src/app/components/ui-components/record-edit-fields/language/language.component.html new file mode 100644 index 000000000..7a6570ebb --- /dev/null +++ b/frontend/src/app/components/ui-components/record-edit-fields/language/language.component.html @@ -0,0 +1,22 @@ + + {{normalizedLabel}} +
+ {{selectedLanguageFlag}} + +
+ + + {{language.flag}} + {{language.label}} + {{language.nativeName}} + ({{language.value}}) + + +
diff --git a/frontend/src/app/components/ui-components/record-edit-fields/language/language.component.spec.ts b/frontend/src/app/components/ui-components/record-edit-fields/language/language.component.spec.ts new file mode 100644 index 000000000..649add210 --- /dev/null +++ b/frontend/src/app/components/ui-components/record-edit-fields/language/language.component.spec.ts @@ -0,0 +1,50 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LanguageEditComponent } from './language.component'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { provideHttpClient } from '@angular/common/http'; + +describe('LanguageEditComponent', () => { + let component: LanguageEditComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ + LanguageEditComponent, + BrowserAnimationsModule + ], + providers: [provideHttpClient()] + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(LanguageEditComponent); + component = fixture.componentInstance; + component.widgetStructure = { widget_params: {} } as any; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should load languages on init', () => { + component.ngOnInit(); + expect(component.languages.length).toBeGreaterThan(0); + }); + + it('should set initial value when value is provided', () => { + component.value = 'en'; + component.ngOnInit(); + expect(component.selectedLanguageFlag).toBeTruthy(); + }); + + it('should parse widget params for show_flag', () => { + component.widgetStructure = { + widget_params: { show_flag: false } + } as any; + component.ngOnInit(); + expect(component.showFlag).toBe(false); + }); +}); diff --git a/frontend/src/app/components/ui-components/record-edit-fields/language/language.component.ts b/frontend/src/app/components/ui-components/record-edit-fields/language/language.component.ts new file mode 100644 index 000000000..c5835378a --- /dev/null +++ b/frontend/src/app/components/ui-components/record-edit-fields/language/language.component.ts @@ -0,0 +1,116 @@ +import { LANGUAGES, getLanguageFlag, Language } from '../../../../consts/languages'; +import { CUSTOM_ELEMENTS_SCHEMA, Component, Input } from '@angular/core'; +import { map, startWith } from 'rxjs/operators'; + +import { BaseEditFieldComponent } from '../base-row-field/base-row-field.component'; +import { CommonModule } from '@angular/common'; +import { FormControl } from '@angular/forms'; +import { FormsModule } from '@angular/forms'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { Observable } from 'rxjs'; +import { ReactiveFormsModule } from '@angular/forms'; + +@Component({ + selector: 'app-edit-language', + imports: [CommonModule, FormsModule, ReactiveFormsModule, MatFormFieldModule, MatAutocompleteModule, MatInputModule], + templateUrl: './language.component.html', + styleUrls: ['./language.component.css'], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) +export class LanguageEditComponent extends BaseEditFieldComponent { + @Input() value: string; + + public languages: {value: string | null, label: string, flag: string, nativeName?: string}[] = []; + public languageControl = new FormControl<{value: string | null, label: string, flag: string, nativeName?: string} | string>(''); + public filteredLanguages: Observable<{value: string | null, label: string, flag: string, nativeName?: string}[]>; + public showFlag: boolean = true; + public selectedLanguageFlag: string = ''; + + originalOrder = () => { return 0; } + + ngOnInit(): void { + super.ngOnInit(); + this.parseWidgetParams(); + this.loadLanguages(); + this.setupAutocomplete(); + this.setInitialValue(); + } + + private parseWidgetParams(): void { + if (this.widgetStructure?.widget_params) { + try { + const params = typeof this.widgetStructure.widget_params === 'string' + ? JSON.parse(this.widgetStructure.widget_params) + : this.widgetStructure.widget_params; + + if (params.show_flag !== undefined) { + this.showFlag = params.show_flag; + } + } catch (e) { + console.error('Error parsing language widget params:', e); + } + } + } + + private setupAutocomplete(): void { + this.filteredLanguages = this.languageControl.valueChanges.pipe( + startWith(''), + map(value => { + // Update flag when value changes + if (typeof value === 'object' && value !== null) { + this.selectedLanguageFlag = value.flag; + } else if (typeof value === 'string') { + // Clear flag if user is typing + this.selectedLanguageFlag = ''; + } + return this._filter(typeof value === 'string' ? value : (value?.label || '')); + }) + ); + } + + private setInitialValue(): void { + if (this.value) { + const language = this.languages.find(l => l.value && l.value.toLowerCase() === this.value.toLowerCase()); + if (language) { + this.languageControl.setValue(language); + this.selectedLanguageFlag = language.flag; + } + } + } + + private _filter(value: string): {value: string | null, label: string, flag: string, nativeName?: string}[] { + const filterValue = value.toLowerCase(); + return this.languages.filter(language => + language.label?.toLowerCase().includes(filterValue) || + (language.value && language.value.toLowerCase().includes(filterValue)) || + (language.nativeName && language.nativeName.toLowerCase().includes(filterValue)) + ); + } + + onLanguageSelected(selectedLanguage: {value: string | null, label: string, flag: string, nativeName?: string}): void { + this.value = selectedLanguage.value; + this.selectedLanguageFlag = selectedLanguage.flag; + this.onFieldChange.emit(this.value); + } + + displayFn(language: any): string { + if (!language) return ''; + // Only return the language label, flag is shown separately + return typeof language === 'string' ? language : language.label; + } + + private loadLanguages(): void { + this.languages = LANGUAGES.map(language => ({ + value: language.code, + label: language.name, + flag: getLanguageFlag(language), + nativeName: language.nativeName + })).toSorted((a, b) => a.label.localeCompare(b.label)); + + if (this.widgetStructure?.widget_params?.allow_null || this.structure?.allow_null) { + this.languages = [{ value: null, label: '', flag: '' }, ...this.languages]; + } + } +} diff --git a/frontend/src/app/components/ui-components/record-edit-fields/markdown/markdown.component.css b/frontend/src/app/components/ui-components/record-edit-fields/markdown/markdown.component.css index d5062f6f0..7e6b36f97 100644 --- a/frontend/src/app/components/ui-components/record-edit-fields/markdown/markdown.component.css +++ b/frontend/src/app/components/ui-components/record-edit-fields/markdown/markdown.component.css @@ -1,6 +1,17 @@ .code-editor-box { min-height: 200px; - border: 1px solid #ccc; border-radius: 4px; overflow: hidden; } + +@media (prefers-color-scheme: light) { + .code-editor-box { + border: 1px solid #ccc; + } +} + +@media (prefers-color-scheme: dark) { + .code-editor-box { + border: 1px solid #404040; + } +} diff --git a/frontend/src/app/components/ui-components/record-view-fields/language/language.component.css b/frontend/src/app/components/ui-components/record-view-fields/language/language.component.css new file mode 100644 index 000000000..17911d54f --- /dev/null +++ b/frontend/src/app/components/ui-components/record-view-fields/language/language.component.css @@ -0,0 +1,4 @@ +.language-flag { + margin-right: 6px; + font-size: 1.2em; +} diff --git a/frontend/src/app/components/ui-components/record-view-fields/language/language.component.html b/frontend/src/app/components/ui-components/record-view-fields/language/language.component.html new file mode 100644 index 000000000..0615634dd --- /dev/null +++ b/frontend/src/app/components/ui-components/record-view-fields/language/language.component.html @@ -0,0 +1,4 @@ + + {{ languageFlag }} + {{ languageName }} + diff --git a/frontend/src/app/components/ui-components/record-view-fields/language/language.component.spec.ts b/frontend/src/app/components/ui-components/record-view-fields/language/language.component.spec.ts new file mode 100644 index 000000000..08ef242f0 --- /dev/null +++ b/frontend/src/app/components/ui-components/record-view-fields/language/language.component.spec.ts @@ -0,0 +1,38 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LanguageRecordViewComponent } from './language.component'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { provideHttpClient } from '@angular/common/http'; + +describe('LanguageRecordViewComponent', () => { + let component: LanguageRecordViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [LanguageRecordViewComponent, BrowserAnimationsModule], + providers: [provideHttpClient()] + }).compileComponents(); + + fixture = TestBed.createComponent(LanguageRecordViewComponent); + component = fixture.componentInstance; + component.value = 'en'; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should display language name from code', () => { + component.value = 'en'; + component.ngOnInit(); + expect(component.languageName).toBe('English'); + }); + + it('should display em dash when value is empty', () => { + component.value = null; + component.ngOnInit(); + expect(component.languageName).toBe('—'); + }); +}); diff --git a/frontend/src/app/components/ui-components/record-view-fields/language/language.component.ts b/frontend/src/app/components/ui-components/record-view-fields/language/language.component.ts new file mode 100644 index 000000000..656ae30cc --- /dev/null +++ b/frontend/src/app/components/ui-components/record-view-fields/language/language.component.ts @@ -0,0 +1,51 @@ +import { LANGUAGES, getLanguageFlag } from '../../../../consts/languages'; +import { Component, Injectable, OnInit } from '@angular/core'; + +import { BaseRecordViewFieldComponent } from '../base-record-view-field/base-record-view-field.component'; +import { CommonModule } from '@angular/common'; + +@Injectable() +@Component({ + selector: 'app-language-record-view', + templateUrl: './language.component.html', + styleUrls: ['../base-record-view-field/base-record-view-field.component.css', './language.component.css'], + imports: [CommonModule] +}) +export class LanguageRecordViewComponent extends BaseRecordViewFieldComponent implements OnInit { + static type = 'language'; + + public languageName: string = ''; + public languageFlag: string = ''; + public showFlag: boolean = true; + + ngOnInit(): void { + this.parseWidgetParams(); + + if (this.value) { + const language = LANGUAGES.find(l => l.code.toLowerCase() === this.value.toLowerCase()); + this.languageName = language ? language.name : this.value; + if (language) { + this.languageFlag = getLanguageFlag(language); + } + } else { + this.languageName = '—'; + this.languageFlag = ''; + } + } + + private parseWidgetParams(): void { + if (this.widgetStructure?.widget_params) { + try { + const params = typeof this.widgetStructure.widget_params === 'string' + ? JSON.parse(this.widgetStructure.widget_params) + : this.widgetStructure.widget_params; + + if (params.show_flag !== undefined) { + this.showFlag = params.show_flag; + } + } catch (e) { + console.error('Error parsing language widget params:', e); + } + } + } +} diff --git a/frontend/src/app/components/ui-components/record-view-fields/markdown/markdown.component.css b/frontend/src/app/components/ui-components/record-view-fields/markdown/markdown.component.css index 27736edaf..df572a3d4 100644 --- a/frontend/src/app/components/ui-components/record-view-fields/markdown/markdown.component.css +++ b/frontend/src/app/components/ui-components/record-view-fields/markdown/markdown.component.css @@ -1,11 +1,23 @@ .markdown-container { padding: 16px; - background: #f9f9f9; border-radius: 4px; - border: 1px solid #e0e0e0; min-height: 100px; } +@media (prefers-color-scheme: light) { + .markdown-container { + background: #f9f9f9; + border: 1px solid #e0e0e0; + } +} + +@media (prefers-color-scheme: dark) { + .markdown-container { + background: #2a2a2a; + border: 1px solid #404040; + } +} + .markdown-container ::ng-deep h1, .markdown-container ::ng-deep h2, .markdown-container ::ng-deep h3, @@ -27,22 +39,56 @@ } .markdown-container ::ng-deep code { - background: #f5f5f5; padding: 2px 4px; border-radius: 3px; font-family: monospace; } +@media (prefers-color-scheme: light) { + .markdown-container ::ng-deep code { + background: #f5f5f5; + } +} + +@media (prefers-color-scheme: dark) { + .markdown-container ::ng-deep code { + background: #3a3a3a; + } +} + .markdown-container ::ng-deep pre { - background: #f5f5f5; padding: 12px; border-radius: 4px; overflow-x: auto; } +@media (prefers-color-scheme: light) { + .markdown-container ::ng-deep pre { + background: #f5f5f5; + } +} + +@media (prefers-color-scheme: dark) { + .markdown-container ::ng-deep pre { + background: #3a3a3a; + } +} + .markdown-container ::ng-deep blockquote { - border-left: 4px solid #ddd; padding-left: 16px; margin-left: 0; - color: #666; +} + +@media (prefers-color-scheme: light) { + .markdown-container ::ng-deep blockquote { + border-left: 4px solid #ddd; + color: #666; + } +} + +@media (prefers-color-scheme: dark) { + .markdown-container ::ng-deep blockquote { + border-left: 4px solid #555; + color: #aaa; + } } diff --git a/frontend/src/app/components/ui-components/table-display-fields/language/language.component.css b/frontend/src/app/components/ui-components/table-display-fields/language/language.component.css new file mode 100644 index 000000000..02b00a9c4 --- /dev/null +++ b/frontend/src/app/components/ui-components/table-display-fields/language/language.component.css @@ -0,0 +1,27 @@ +.field-wrapper { + display: flex; + align-items: center; +} + +.value-wrapper { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 300px; + display: flex; + align-items: center; +} + +.language-flag { + margin-right: 6px; + font-size: 1.2em; +} + +.copy-button { + visibility: hidden; + margin-left: 4px; +} + +.field-wrapper:hover .copy-button { + visibility: visible; +} diff --git a/frontend/src/app/components/ui-components/table-display-fields/language/language.component.html b/frontend/src/app/components/ui-components/table-display-fields/language/language.component.html new file mode 100644 index 000000000..85f344d1e --- /dev/null +++ b/frontend/src/app/components/ui-components/table-display-fields/language/language.component.html @@ -0,0 +1,14 @@ +
+ + {{ languageFlag }} + {{ languageName }} + + +
diff --git a/frontend/src/app/components/ui-components/table-display-fields/language/language.component.spec.ts b/frontend/src/app/components/ui-components/table-display-fields/language/language.component.spec.ts new file mode 100644 index 000000000..f6d5f0e89 --- /dev/null +++ b/frontend/src/app/components/ui-components/table-display-fields/language/language.component.spec.ts @@ -0,0 +1,46 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LanguageDisplayComponent } from './language.component'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { provideHttpClient } from '@angular/common/http'; + +describe('LanguageDisplayComponent', () => { + let component: LanguageDisplayComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [LanguageDisplayComponent, BrowserAnimationsModule], + providers: [provideHttpClient()] + }).compileComponents(); + + fixture = TestBed.createComponent(LanguageDisplayComponent); + component = fixture.componentInstance; + component.value = 'en'; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should display language name from code', () => { + component.value = 'fr'; + component.ngOnInit(); + expect(component.languageName).toBe('French'); + }); + + it('should display em dash when value is empty', () => { + component.value = null; + component.ngOnInit(); + expect(component.languageName).toBe('—'); + }); + + it('should respect show_flag widget parameter', () => { + component.widgetStructure = { + widget_params: { show_flag: false } + } as any; + component.ngOnInit(); + expect(component.showFlag).toBe(false); + }); +}); diff --git a/frontend/src/app/components/ui-components/table-display-fields/language/language.component.ts b/frontend/src/app/components/ui-components/table-display-fields/language/language.component.ts new file mode 100644 index 000000000..ae7d5e2cf --- /dev/null +++ b/frontend/src/app/components/ui-components/table-display-fields/language/language.component.ts @@ -0,0 +1,54 @@ +import { LANGUAGES, getLanguageFlag } from '../../../../consts/languages'; +import { Component, OnInit } from '@angular/core'; + +import { BaseTableDisplayFieldComponent } from '../base-table-display-field/base-table-display-field.component'; +import { ClipboardModule } from '@angular/cdk/clipboard'; +import { CommonModule } from '@angular/common'; +import { MatButtonModule } from '@angular/material/button'; +import { MatIconModule } from '@angular/material/icon'; +import { MatTooltipModule } from '@angular/material/tooltip'; + +@Component({ + selector: 'app-language-display', + templateUrl: './language.component.html', + styleUrls: ['../base-table-display-field/base-table-display-field.component.css', './language.component.css'], + imports: [ClipboardModule, MatIconModule, MatButtonModule, MatTooltipModule, CommonModule] +}) +export class LanguageDisplayComponent extends BaseTableDisplayFieldComponent implements OnInit { + static type = 'language'; + + public languageName: string = ''; + public languageFlag: string = ''; + public showFlag: boolean = true; + + ngOnInit(): void { + this.parseWidgetParams(); + + if (this.value) { + const language = LANGUAGES.find(l => l.code.toLowerCase() === this.value.toLowerCase()); + this.languageName = language ? language.name : this.value; + if (language) { + this.languageFlag = getLanguageFlag(language); + } + } else { + this.languageName = '—'; + this.languageFlag = ''; + } + } + + private parseWidgetParams(): void { + if (this.widgetStructure?.widget_params) { + try { + const params = typeof this.widgetStructure.widget_params === 'string' + ? JSON.parse(this.widgetStructure.widget_params) + : this.widgetStructure.widget_params; + + if (params.show_flag !== undefined) { + this.showFlag = params.show_flag; + } + } catch (e) { + console.error('Error parsing language widget params:', e); + } + } + } +} diff --git a/frontend/src/app/components/ui-components/table-display-fields/markdown/markdown.component.css b/frontend/src/app/components/ui-components/table-display-fields/markdown/markdown.component.css index 6c6f41777..03a09e89e 100644 --- a/frontend/src/app/components/ui-components/table-display-fields/markdown/markdown.component.css +++ b/frontend/src/app/components/ui-components/table-display-fields/markdown/markdown.component.css @@ -32,9 +32,20 @@ } .markdown-preview ::ng-deep code { - background: #f5f5f5; padding: 1px 3px; border-radius: 2px; font-family: monospace; font-size: 0.9em; } + +@media (prefers-color-scheme: light) { + .markdown-preview ::ng-deep code { + background: #f5f5f5; + } +} + +@media (prefers-color-scheme: dark) { + .markdown-preview ::ng-deep code { + background: #3a3a3a; + } +} diff --git a/frontend/src/app/consts/languages.ts b/frontend/src/app/consts/languages.ts new file mode 100644 index 000000000..a198a147f --- /dev/null +++ b/frontend/src/app/consts/languages.ts @@ -0,0 +1,201 @@ +export interface Language { + code: string; + name: string; + nativeName?: string; + flagCountryCode?: string; // ISO 3166-1 alpha-2 country code for flag emoji +} + +export function getLanguageFlag(language: Language): string { + if (!language.flagCountryCode || language.flagCountryCode.length !== 2) return ''; + const codePoints = language.flagCountryCode + .toUpperCase() + .split('') + .map(char => 127397 + char.charCodeAt(0)); + return String.fromCodePoint(...codePoints); +} + +export const LANGUAGES: Language[] = [ + { code: 'aa', name: 'Afar', nativeName: 'Afaraf', flagCountryCode: 'ET' }, + { code: 'ab', name: 'Abkhazian', nativeName: 'аҧсуа бызшәа', flagCountryCode: 'GE' }, + { code: 'af', name: 'Afrikaans', nativeName: 'Afrikaans', flagCountryCode: 'ZA' }, + { code: 'ak', name: 'Akan', nativeName: 'Akan', flagCountryCode: 'GH' }, + { code: 'am', name: 'Amharic', nativeName: 'አማርኛ', flagCountryCode: 'ET' }, + { code: 'an', name: 'Aragonese', nativeName: 'aragonés', flagCountryCode: 'ES' }, + { code: 'ar', name: 'Arabic', nativeName: 'العربية', flagCountryCode: 'SA' }, + { code: 'as', name: 'Assamese', nativeName: 'অসমীয়া', flagCountryCode: 'IN' }, + { code: 'av', name: 'Avaric', nativeName: 'авар мацӀ', flagCountryCode: 'RU' }, + { code: 'ay', name: 'Aymara', nativeName: 'aymar aru', flagCountryCode: 'BO' }, + { code: 'az', name: 'Azerbaijani', nativeName: 'azərbaycan dili', flagCountryCode: 'AZ' }, + { code: 'ba', name: 'Bashkir', nativeName: 'башҡорт теле', flagCountryCode: 'RU' }, + { code: 'be', name: 'Belarusian', nativeName: 'беларуская мова', flagCountryCode: 'BY' }, + { code: 'bg', name: 'Bulgarian', nativeName: 'български език', flagCountryCode: 'BG' }, + { code: 'bh', name: 'Bihari languages', nativeName: 'भोजपुरी', flagCountryCode: 'IN' }, + { code: 'bi', name: 'Bislama', nativeName: 'Bislama', flagCountryCode: 'VU' }, + { code: 'bm', name: 'Bambara', nativeName: 'bamanankan', flagCountryCode: 'ML' }, + { code: 'bn', name: 'Bengali', nativeName: 'বাংলা', flagCountryCode: 'BD' }, + { code: 'bo', name: 'Tibetan', nativeName: 'བོད་ཡིག', flagCountryCode: 'CN' }, + { code: 'br', name: 'Breton', nativeName: 'brezhoneg', flagCountryCode: 'FR' }, + { code: 'bs', name: 'Bosnian', nativeName: 'bosanski jezik', flagCountryCode: 'BA' }, + { code: 'ca', name: 'Catalan', nativeName: 'català', flagCountryCode: 'ES' }, + { code: 'ce', name: 'Chechen', nativeName: 'нохчийн мott', flagCountryCode: 'RU' }, + { code: 'ch', name: 'Chamorro', nativeName: 'Chamoru', flagCountryCode: 'GU' }, + { code: 'co', name: 'Corsican', nativeName: 'corsu', flagCountryCode: 'FR' }, + { code: 'cr', name: 'Cree', nativeName: 'ᓀᐦᐃᔭᐍᐏᐣ', flagCountryCode: 'CA' }, + { code: 'cs', name: 'Czech', nativeName: 'čeština', flagCountryCode: 'CZ' }, + { code: 'cu', name: 'Church Slavonic', nativeName: 'ѩзыкъ словѣньскъ', flagCountryCode: 'BG' }, + { code: 'cv', name: 'Chuvash', nativeName: 'чӑваш чӗлхи', flagCountryCode: 'RU' }, + { code: 'cy', name: 'Welsh', nativeName: 'Cymraeg', flagCountryCode: 'GB' }, + { code: 'da', name: 'Danish', nativeName: 'dansk', flagCountryCode: 'DK' }, + { code: 'de', name: 'German', nativeName: 'Deutsch', flagCountryCode: 'DE' }, + { code: 'dv', name: 'Divehi', nativeName: 'ދިވެހި', flagCountryCode: 'MV' }, + { code: 'dz', name: 'Dzongkha', nativeName: 'རྫོང་ཁ', flagCountryCode: 'BT' }, + { code: 'ee', name: 'Ewe', nativeName: 'Eʋegbe', flagCountryCode: 'GH' }, + { code: 'el', name: 'Greek', nativeName: 'Ελληνικά', flagCountryCode: 'GR' }, + { code: 'en', name: 'English', nativeName: 'English', flagCountryCode: 'GB' }, + { code: 'eo', name: 'Esperanto', nativeName: 'Esperanto', flagCountryCode: 'EU' }, + { code: 'es', name: 'Spanish', nativeName: 'español', flagCountryCode: 'ES' }, + { code: 'et', name: 'Estonian', nativeName: 'eesti', flagCountryCode: 'EE' }, + { code: 'eu', name: 'Basque', nativeName: 'euskara', flagCountryCode: 'ES' }, + { code: 'fa', name: 'Persian', nativeName: 'فارسی', flagCountryCode: 'IR' }, + { code: 'ff', name: 'Fulah', nativeName: 'Fulfulde', flagCountryCode: 'SN' }, + { code: 'fi', name: 'Finnish', nativeName: 'suomi', flagCountryCode: 'FI' }, + { code: 'fj', name: 'Fijian', nativeName: 'vosa Vakaviti', flagCountryCode: 'FJ' }, + { code: 'fo', name: 'Faroese', nativeName: 'føroyskt', flagCountryCode: 'FO' }, + { code: 'fr', name: 'French', nativeName: 'français', flagCountryCode: 'FR' }, + { code: 'fy', name: 'Western Frisian', nativeName: 'Frysk', flagCountryCode: 'NL' }, + { code: 'ga', name: 'Irish', nativeName: 'Gaeilge', flagCountryCode: 'IE' }, + { code: 'gd', name: 'Scottish Gaelic', nativeName: 'Gàidhlig', flagCountryCode: 'GB' }, + { code: 'gl', name: 'Galician', nativeName: 'galego', flagCountryCode: 'ES' }, + { code: 'gn', name: 'Guarani', nativeName: "Avañe'ẽ", flagCountryCode: 'PY' }, + { code: 'gu', name: 'Gujarati', nativeName: 'ગુજરાતી', flagCountryCode: 'IN' }, + { code: 'gv', name: 'Manx', nativeName: 'Gaelg', flagCountryCode: 'IM' }, + { code: 'ha', name: 'Hausa', nativeName: 'هَوُسَ', flagCountryCode: 'NG' }, + { code: 'he', name: 'Hebrew', nativeName: 'עברית', flagCountryCode: 'IL' }, + { code: 'hi', name: 'Hindi', nativeName: 'हिन्दी', flagCountryCode: 'IN' }, + { code: 'ho', name: 'Hiri Motu', nativeName: 'Hiri Motu', flagCountryCode: 'PG' }, + { code: 'hr', name: 'Croatian', nativeName: 'hrvatski jezik', flagCountryCode: 'HR' }, + { code: 'ht', name: 'Haitian', nativeName: 'Kreyòl ayisyen', flagCountryCode: 'HT' }, + { code: 'hu', name: 'Hungarian', nativeName: 'magyar', flagCountryCode: 'HU' }, + { code: 'hy', name: 'Armenian', nativeName: 'Հայերեն', flagCountryCode: 'AM' }, + { code: 'hz', name: 'Herero', nativeName: 'Otjiherero', flagCountryCode: 'NA' }, + { code: 'ia', name: 'Interlingua', nativeName: 'Interlingua', flagCountryCode: 'EU' }, + { code: 'id', name: 'Indonesian', nativeName: 'Bahasa Indonesia', flagCountryCode: 'ID' }, + { code: 'ie', name: 'Interlingue', nativeName: 'Interlingue', flagCountryCode: 'EU' }, + { code: 'ig', name: 'Igbo', nativeName: 'Asụsụ Igbo', flagCountryCode: 'NG' }, + { code: 'ii', name: 'Sichuan Yi', nativeName: 'ꆈꌠ꒿', flagCountryCode: 'CN' }, + { code: 'ik', name: 'Inupiaq', nativeName: 'Iñupiaq', flagCountryCode: 'US' }, + { code: 'io', name: 'Ido', nativeName: 'Ido', flagCountryCode: 'EU' }, + { code: 'is', name: 'Icelandic', nativeName: 'Íslenska', flagCountryCode: 'IS' }, + { code: 'it', name: 'Italian', nativeName: 'italiano', flagCountryCode: 'IT' }, + { code: 'iu', name: 'Inuktitut', nativeName: 'ᐃᓄᒃᑎᑐᑦ', flagCountryCode: 'CA' }, + { code: 'ja', name: 'Japanese', nativeName: '日本語', flagCountryCode: 'JP' }, + { code: 'jv', name: 'Javanese', nativeName: 'ꦧꦱꦗꦮ', flagCountryCode: 'ID' }, + { code: 'ka', name: 'Georgian', nativeName: 'ქართული', flagCountryCode: 'GE' }, + { code: 'kg', name: 'Kongo', nativeName: 'Kikongo', flagCountryCode: 'CD' }, + { code: 'ki', name: 'Kikuyu', nativeName: 'Gĩkũyũ', flagCountryCode: 'KE' }, + { code: 'kj', name: 'Kuanyama', nativeName: 'Kuanyama', flagCountryCode: 'AO' }, + { code: 'kk', name: 'Kazakh', nativeName: 'қазақ тілі', flagCountryCode: 'KZ' }, + { code: 'kl', name: 'Kalaallisut', nativeName: 'kalaallisut', flagCountryCode: 'GL' }, + { code: 'km', name: 'Central Khmer', nativeName: 'ខេមរភាសា', flagCountryCode: 'KH' }, + { code: 'kn', name: 'Kannada', nativeName: 'ಕನ್ನಡ', flagCountryCode: 'IN' }, + { code: 'ko', name: 'Korean', nativeName: '한국어', flagCountryCode: 'KR' }, + { code: 'kr', name: 'Kanuri', nativeName: 'Kanuri', flagCountryCode: 'NG' }, + { code: 'ks', name: 'Kashmiri', nativeName: 'कश्मीरी', flagCountryCode: 'IN' }, + { code: 'ku', name: 'Kurdish', nativeName: 'Kurdî', flagCountryCode: 'IQ' }, + { code: 'kv', name: 'Komi', nativeName: 'коми кыв', flagCountryCode: 'RU' }, + { code: 'kw', name: 'Cornish', nativeName: 'Kernewek', flagCountryCode: 'GB' }, + { code: 'ky', name: 'Kirghiz', nativeName: 'Кыргызча', flagCountryCode: 'KG' }, + { code: 'la', name: 'Latin', nativeName: 'latine', flagCountryCode: 'VA' }, + { code: 'lb', name: 'Luxembourgish', nativeName: 'Lëtzebuergesch', flagCountryCode: 'LU' }, + { code: 'lg', name: 'Ganda', nativeName: 'Luganda', flagCountryCode: 'UG' }, + { code: 'li', name: 'Limburgan', nativeName: 'Limburgs', flagCountryCode: 'NL' }, + { code: 'ln', name: 'Lingala', nativeName: 'Lingála', flagCountryCode: 'CD' }, + { code: 'lo', name: 'Lao', nativeName: 'ພາສາລາວ', flagCountryCode: 'LA' }, + { code: 'lt', name: 'Lithuanian', nativeName: 'lietuvių kalba', flagCountryCode: 'LT' }, + { code: 'lu', name: 'Luba-Katanga', nativeName: 'Tshiluba', flagCountryCode: 'CD' }, + { code: 'lv', name: 'Latvian', nativeName: 'latviešu valoda', flagCountryCode: 'LV' }, + { code: 'mg', name: 'Malagasy', nativeName: 'fiteny malagasy', flagCountryCode: 'MG' }, + { code: 'mh', name: 'Marshallese', nativeName: 'Kajin M̧ajeļ', flagCountryCode: 'MH' }, + { code: 'mi', name: 'Maori', nativeName: 'te reo Māori', flagCountryCode: 'NZ' }, + { code: 'mk', name: 'Macedonian', nativeName: 'македонски јазик', flagCountryCode: 'MK' }, + { code: 'ml', name: 'Malayalam', nativeName: 'മലയാളം', flagCountryCode: 'IN' }, + { code: 'mn', name: 'Mongolian', nativeName: 'Монгол хэл', flagCountryCode: 'MN' }, + { code: 'mr', name: 'Marathi', nativeName: 'मराठी', flagCountryCode: 'IN' }, + { code: 'ms', name: 'Malay', nativeName: 'Bahasa Melayu', flagCountryCode: 'MY' }, + { code: 'mt', name: 'Maltese', nativeName: 'Malti', flagCountryCode: 'MT' }, + { code: 'my', name: 'Burmese', nativeName: 'ဗမာစာ', flagCountryCode: 'MM' }, + { code: 'na', name: 'Nauru', nativeName: 'Dorerin Naoero', flagCountryCode: 'NR' }, + { code: 'nb', name: 'Norwegian Bokmål', nativeName: 'Norsk bokmål', flagCountryCode: 'NO' }, + { code: 'nd', name: 'North Ndebele', nativeName: 'isiNdebele', flagCountryCode: 'ZW' }, + { code: 'ne', name: 'Nepali', nativeName: 'नेपाली', flagCountryCode: 'NP' }, + { code: 'ng', name: 'Ndonga', nativeName: 'Owambo', flagCountryCode: 'NA' }, + { code: 'nl', name: 'Dutch', nativeName: 'Nederlands', flagCountryCode: 'NL' }, + { code: 'nn', name: 'Norwegian Nynorsk', nativeName: 'Norsk nynorsk', flagCountryCode: 'NO' }, + { code: 'no', name: 'Norwegian', nativeName: 'Norsk', flagCountryCode: 'NO' }, + { code: 'nr', name: 'South Ndebele', nativeName: 'isiNdebele', flagCountryCode: 'ZA' }, + { code: 'nv', name: 'Navajo', nativeName: 'Diné bizaad', flagCountryCode: 'US' }, + { code: 'ny', name: 'Chichewa', nativeName: 'chiCheŵa', flagCountryCode: 'MW' }, + { code: 'oc', name: 'Occitan', nativeName: 'occitan', flagCountryCode: 'FR' }, + { code: 'oj', name: 'Ojibwa', nativeName: 'ᐊᓂᔑᓈᐯᒧᐎᓐ', flagCountryCode: 'CA' }, + { code: 'om', name: 'Oromo', nativeName: 'Afaan Oromoo', flagCountryCode: 'ET' }, + { code: 'or', name: 'Oriya', nativeName: 'ଓଡ଼ିଆ', flagCountryCode: 'IN' }, + { code: 'os', name: 'Ossetian', nativeName: 'ирон æвзаг', flagCountryCode: 'GE' }, + { code: 'pa', name: 'Punjabi', nativeName: 'ਪੰਜਾਬੀ', flagCountryCode: 'IN' }, + { code: 'pi', name: 'Pali', nativeName: 'पाऴि', flagCountryCode: 'IN' }, + { code: 'pl', name: 'Polish', nativeName: 'polski', flagCountryCode: 'PL' }, + { code: 'ps', name: 'Pashto', nativeName: 'پښتو', flagCountryCode: 'AF' }, + { code: 'pt', name: 'Portuguese', nativeName: 'português', flagCountryCode: 'PT' }, + { code: 'qu', name: 'Quechua', nativeName: 'Runa Simi', flagCountryCode: 'PE' }, + { code: 'rm', name: 'Romansh', nativeName: 'rumantsch grischun', flagCountryCode: 'CH' }, + { code: 'rn', name: 'Rundi', nativeName: 'Ikirundi', flagCountryCode: 'BI' }, + { code: 'ro', name: 'Romanian', nativeName: 'română', flagCountryCode: 'RO' }, + { code: 'ru', name: 'Russian', nativeName: 'русский', flagCountryCode: 'RU' }, + { code: 'rw', name: 'Kinyarwanda', nativeName: 'Ikinyarwanda', flagCountryCode: 'RW' }, + { code: 'sa', name: 'Sanskrit', nativeName: 'संस्कृतम्', flagCountryCode: 'IN' }, + { code: 'sc', name: 'Sardinian', nativeName: 'sardu', flagCountryCode: 'IT' }, + { code: 'sd', name: 'Sindhi', nativeName: 'सिन्धी', flagCountryCode: 'PK' }, + { code: 'se', name: 'Northern Sami', nativeName: 'Davvisámegiella', flagCountryCode: 'NO' }, + { code: 'sg', name: 'Sango', nativeName: 'yângâ tî sängö', flagCountryCode: 'CF' }, + { code: 'si', name: 'Sinhala', nativeName: 'සිංහල', flagCountryCode: 'LK' }, + { code: 'sk', name: 'Slovak', nativeName: 'slovenčina', flagCountryCode: 'SK' }, + { code: 'sl', name: 'Slovenian', nativeName: 'slovenski jezik', flagCountryCode: 'SI' }, + { code: 'sm', name: 'Samoan', nativeName: 'gagana fa\'a Samoa', flagCountryCode: 'WS' }, + { code: 'sn', name: 'Shona', nativeName: 'chiShona', flagCountryCode: 'ZW' }, + { code: 'so', name: 'Somali', nativeName: 'Soomaaliga', flagCountryCode: 'SO' }, + { code: 'sq', name: 'Albanian', nativeName: 'Shqip', flagCountryCode: 'AL' }, + { code: 'sr', name: 'Serbian', nativeName: 'српски језик', flagCountryCode: 'RS' }, + { code: 'ss', name: 'Swati', nativeName: 'SiSwati', flagCountryCode: 'SZ' }, + { code: 'st', name: 'Southern Sotho', nativeName: 'Sesotho', flagCountryCode: 'LS' }, + { code: 'su', name: 'Sundanese', nativeName: 'Basa Sunda', flagCountryCode: 'ID' }, + { code: 'sv', name: 'Swedish', nativeName: 'svenska', flagCountryCode: 'SE' }, + { code: 'sw', name: 'Swahili', nativeName: 'Kiswahili', flagCountryCode: 'TZ' }, + { code: 'ta', name: 'Tamil', nativeName: 'தமிழ்', flagCountryCode: 'IN' }, + { code: 'te', name: 'Telugu', nativeName: 'తెలుగు', flagCountryCode: 'IN' }, + { code: 'tg', name: 'Tajik', nativeName: 'тоҷикӣ', flagCountryCode: 'TJ' }, + { code: 'th', name: 'Thai', nativeName: 'ไทย', flagCountryCode: 'TH' }, + { code: 'ti', name: 'Tigrinya', nativeName: 'ትግርኛ', flagCountryCode: 'ER' }, + { code: 'tk', name: 'Turkmen', nativeName: 'Türkmen', flagCountryCode: 'TM' }, + { code: 'tl', name: 'Tagalog', nativeName: 'Wikang Tagalog', flagCountryCode: 'PH' }, + { code: 'tn', name: 'Tswana', nativeName: 'Setswana', flagCountryCode: 'BW' }, + { code: 'to', name: 'Tonga', nativeName: 'faka Tonga', flagCountryCode: 'TO' }, + { code: 'tr', name: 'Turkish', nativeName: 'Türkçe', flagCountryCode: 'TR' }, + { code: 'ts', name: 'Tsonga', nativeName: 'Xitsonga', flagCountryCode: 'ZA' }, + { code: 'tt', name: 'Tatar', nativeName: 'татар теле', flagCountryCode: 'RU' }, + { code: 'tw', name: 'Twi', nativeName: 'Twi', flagCountryCode: 'GH' }, + { code: 'ty', name: 'Tahitian', nativeName: 'Reo Tahiti', flagCountryCode: 'PF' }, + { code: 'ug', name: 'Uighur', nativeName: 'ئۇيغۇرچە', flagCountryCode: 'CN' }, + { code: 'uk', name: 'Ukrainian', nativeName: 'Українська', flagCountryCode: 'UA' }, + { code: 'ur', name: 'Urdu', nativeName: 'اردو', flagCountryCode: 'PK' }, + { code: 'uz', name: 'Uzbek', nativeName: 'Oʻzbek', flagCountryCode: 'UZ' }, + { code: 've', name: 'Venda', nativeName: 'Tshivenḓa', flagCountryCode: 'ZA' }, + { code: 'vi', name: 'Vietnamese', nativeName: 'Tiếng Việt', flagCountryCode: 'VN' }, + { code: 'vo', name: 'Volapük', nativeName: 'Volapük', flagCountryCode: 'EU' }, + { code: 'wa', name: 'Walloon', nativeName: 'walon', flagCountryCode: 'BE' }, + { code: 'wo', name: 'Wolof', nativeName: 'Wollof', flagCountryCode: 'SN' }, + { code: 'xh', name: 'Xhosa', nativeName: 'isiXhosa', flagCountryCode: 'ZA' }, + { code: 'yi', name: 'Yiddish', nativeName: 'ייִדיש', flagCountryCode: 'IL' }, + { code: 'yo', name: 'Yoruba', nativeName: 'Yorùbá', flagCountryCode: 'NG' }, + { code: 'za', name: 'Zhuang', nativeName: 'Saɯ cueŋƅ', flagCountryCode: 'CN' }, + { code: 'zh', name: 'Chinese', nativeName: '中文', flagCountryCode: 'CN' }, + { code: 'zu', name: 'Zulu', nativeName: 'isiZulu', flagCountryCode: 'ZA' } +]; diff --git a/frontend/src/app/consts/record-edit-types.ts b/frontend/src/app/consts/record-edit-types.ts index ba6fabe41..7c3bb3d15 100644 --- a/frontend/src/app/consts/record-edit-types.ts +++ b/frontend/src/app/consts/record-edit-types.ts @@ -10,6 +10,7 @@ import { ForeignKeyEditComponent } from '../components/ui-components/record-edit import { IdEditComponent } from '../components/ui-components/record-edit-fields/id/id.component'; import { ImageEditComponent } from '../components/ui-components/record-edit-fields/image/image.component'; import { JsonEditorEditComponent } from '../components/ui-components/record-edit-fields/json-editor/json-editor.component'; +import { LanguageEditComponent } from '../components/ui-components/record-edit-fields/language/language.component'; import { LongTextEditComponent } from 'src/app/components/ui-components/record-edit-fields/long-text/long-text.component' import { MarkdownEditComponent } from '../components/ui-components/record-edit-fields/markdown/markdown.component'; import { MoneyEditComponent } from '../components/ui-components/record-edit-fields/money/money.component'; @@ -45,6 +46,7 @@ export const UIwidgets = { Foreign_key: ForeignKeyEditComponent, Image: ImageEditComponent, JSON: JsonEditorEditComponent, + Language: LanguageEditComponent, Markdown: MarkdownEditComponent, Money: MoneyEditComponent, Number: NumberEditComponent, diff --git a/frontend/src/app/consts/record-view-types.ts b/frontend/src/app/consts/record-view-types.ts index 13553a5b9..efeff01a0 100644 --- a/frontend/src/app/consts/record-view-types.ts +++ b/frontend/src/app/consts/record-view-types.ts @@ -9,6 +9,7 @@ import { ForeignKeyRecordViewComponent } from '../components/ui-components/recor import { IdRecordViewComponent } from '../components/ui-components/record-view-fields/id/id.component'; import { ImageRecordViewComponent } from '../components/ui-components/record-view-fields/image/image.component'; import { JsonEditorRecordViewComponent } from '../components/ui-components/record-view-fields/json-editor/json-editor.component'; +import { LanguageRecordViewComponent } from '../components/ui-components/record-view-fields/language/language.component'; import { LongTextRecordViewComponent } from 'src/app/components/ui-components/record-view-fields/long-text/long-text.component'; import { MarkdownRecordViewComponent } from '../components/ui-components/record-view-fields/markdown/markdown.component'; import { MoneyRecordViewComponent } from '../components/ui-components/record-view-fields/money/money.component'; @@ -33,6 +34,7 @@ export const UIwidgets = { Time: TimeRecordViewComponent, DateTime: DateTimeRecordViewComponent, JSON: JsonEditorRecordViewComponent, + Language: LanguageRecordViewComponent, Markdown: MarkdownRecordViewComponent, Textarea: LongTextRecordViewComponent, String: TextRecordViewComponent, diff --git a/frontend/src/app/consts/table-display-types.ts b/frontend/src/app/consts/table-display-types.ts index e640d660a..ff434f6bc 100644 --- a/frontend/src/app/consts/table-display-types.ts +++ b/frontend/src/app/consts/table-display-types.ts @@ -9,6 +9,7 @@ import { ForeignKeyDisplayComponent } from '../components/ui-components/table-di import { IdDisplayComponent } from '../components/ui-components/table-display-fields/id/id.component'; import { ImageDisplayComponent } from '../components/ui-components/table-display-fields/image/image.component'; import { JsonEditorDisplayComponent } from '../components/ui-components/table-display-fields/json-editor/json-editor.component'; +import { LanguageDisplayComponent } from '../components/ui-components/table-display-fields/language/language.component'; import { LongTextDisplayComponent } from 'src/app/components/ui-components/table-display-fields/long-text/long-text.component'; import { MarkdownDisplayComponent } from '../components/ui-components/table-display-fields/markdown/markdown.component'; import { MoneyDisplayComponent } from '../components/ui-components/table-display-fields/money/money.component'; @@ -38,6 +39,7 @@ export const UIwidgets = { Foreign_key: ForeignKeyDisplayComponent, Image: ImageDisplayComponent, JSON: JsonEditorDisplayComponent, + Language: LanguageDisplayComponent, Markdown: MarkdownDisplayComponent, Money: MoneyDisplayComponent, Number: NumberDisplayComponent, From b4c8d4cad9729cf0d07b78c44591070275082bce Mon Sep 17 00:00:00 2001 From: Andrii Kostenko Date: Sat, 22 Nov 2025 19:44:19 +0000 Subject: [PATCH 2/2] color and flag --- .../db-table-widgets/db-table-widgets.component.ts | 6 ++++++ .../record-view-fields/markdown/markdown.component.css | 2 ++ 2 files changed, 8 insertions(+) diff --git a/frontend/src/app/components/dashboard/db-table-view/db-table-widgets/db-table-widgets.component.ts b/frontend/src/app/components/dashboard/db-table-view/db-table-widgets/db-table-widgets.component.ts index 1138124d0..fc56d5f59 100644 --- a/frontend/src/app/components/dashboard/db-table-view/db-table-widgets/db-table-widgets.component.ts +++ b/frontend/src/app/components/dashboard/db-table-view/db-table-widgets/db-table-widgets.component.ts @@ -162,6 +162,12 @@ export class DbTableWidgetsComponent implements OnInit { } `, JSON: `// No settings required`, + Language: `// Configure language display options +// show_flag: Display country flag emoji next to language name +// Example: +{ + "show_flag": true +}`, Markdown: `// No settings required`, Money: `// Configure money widget settings // example: diff --git a/frontend/src/app/components/ui-components/record-view-fields/markdown/markdown.component.css b/frontend/src/app/components/ui-components/record-view-fields/markdown/markdown.component.css index df572a3d4..5b2ca4ec5 100644 --- a/frontend/src/app/components/ui-components/record-view-fields/markdown/markdown.component.css +++ b/frontend/src/app/components/ui-components/record-view-fields/markdown/markdown.component.css @@ -8,6 +8,7 @@ .markdown-container { background: #f9f9f9; border: 1px solid #e0e0e0; + color: rgba(0, 0, 0, 0.64); } } @@ -15,6 +16,7 @@ .markdown-container { background: #2a2a2a; border: 1px solid #404040; + color: rgba(255, 255, 255, 0.64); } }