flare / flare-ui /src /app /dialogs /caption-dialog /caption-dialog.component.ts
ciyidogan's picture
Upload caption-dialog.component.ts
23aadc9 verified
import { Component, Inject, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormBuilder, FormGroup, FormArray, Validators, ReactiveFormsModule } from '@angular/forms';
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatListModule } from '@angular/material/list';
import { MatChipsModule } from '@angular/material/chips';
interface LocalizedCaption {
locale_code: string;
caption: string;
}
@Component({
selector: 'app-caption-dialog',
standalone: true,
imports: [
CommonModule,
ReactiveFormsModule,
MatDialogModule,
MatFormFieldModule,
MatInputModule,
MatButtonModule,
MatIconModule,
MatListModule,
MatChipsModule
],
template: `
<h2 mat-dialog-title>Manage Captions</h2>
<mat-dialog-content>
<p class="hint">Add captions for different languages. The default locale ({{ getLocaleName(data.defaultLocale) }}) is required.</p>
<form [formGroup]="form">
<div formArrayName="captions" class="captions-list">
<div *ngFor="let caption of captions.controls; let i = index"
[formGroupName]="i"
class="caption-row">
<mat-chip-listbox class="locale-chip" [disabled]="true">
<mat-chip-option [selected]="true">
{{ getLocaleName(caption.get('locale_code')?.value) }}
</mat-chip-option>
</mat-chip-listbox>
<mat-form-field appearance="outline" class="caption-field">
<mat-label>Caption</mat-label>
<input matInput formControlName="caption"
[placeholder]="'Caption in ' + getLocaleName(caption.get('locale_code')?.value)">
<mat-error *ngIf="caption.get('caption')?.hasError('required')">
Caption is required
</mat-error>
</mat-form-field>
<button mat-icon-button color="warn"
(click)="removeCaption(i)"
[disabled]="caption.get('locale_code')?.value === data.defaultLocale && captions.length === 1"
class="remove-button">
<mat-icon>delete</mat-icon>
</button>
</div>
</div>
<div class="add-section" *ngIf="availableLocales.length > 0">
<button mat-stroked-button (click)="addCaption()">
<mat-icon>add</mat-icon>
Add Caption for Another Language
</button>
<mat-chip-listbox class="available-locales">
<mat-chip-option *ngFor="let locale of availableLocales"
[value]="locale"
(click)="addCaptionForLocale(locale)">
{{ getLocaleName(locale) }}
</mat-chip-option>
</mat-chip-listbox>
</div>
</form>
</mat-dialog-content>
<mat-dialog-actions align="end">
<button mat-button (click)="cancel()">Cancel</button>
<button mat-raised-button color="primary"
(click)="save()"
[disabled]="!form.valid">
Save
</button>
</mat-dialog-actions>
`,
styles: [`
mat-dialog-content {
min-width: 500px;
max-width: 600px;
}
.hint {
color: rgba(0, 0, 0, 0.6);
font-size: 14px;
margin-bottom: 16px;
}
.captions-list {
margin-bottom: 24px;
}
.caption-row {
display: flex;
align-items: flex-start;
gap: 16px;
margin-bottom: 16px;
}
.locale-chip {
flex: 0 0 120px;
margin-top: 8px;
}
.caption-field {
flex: 1;
}
.remove-button {
margin-top: 8px;
}
.add-section {
border-top: 1px solid #e0e0e0;
padding-top: 16px;
}
.available-locales {
margin-top: 16px;
}
`]
})
export default class CaptionDialogComponent implements OnInit {
form!: FormGroup;
availableLocales: string[] = [];
constructor(
private fb: FormBuilder,
public dialogRef: MatDialogRef<CaptionDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: {
captions: LocalizedCaption[];
supportedLocales: string[];
defaultLocale: string;
}
) {}
ngOnInit() {
this.initializeForm();
this.updateAvailableLocales();
}
initializeForm() {
this.form = this.fb.group({
captions: this.fb.array([])
});
// Add existing captions
if (this.data.captions && this.data.captions.length > 0) {
this.data.captions.forEach(caption => {
this.addCaptionFormGroup(caption);
});
} else {
// Add default locale caption if no captions exist
this.addCaptionFormGroup({
locale_code: this.data.defaultLocale,
caption: ''
});
}
}
get captions() {
return this.form.get('captions') as FormArray;
}
addCaptionFormGroup(caption: LocalizedCaption) {
const group = this.fb.group({
locale_code: [caption.locale_code, Validators.required],
caption: [caption.caption, Validators.required]
});
this.captions.push(group);
}
addCaption() {
if (this.availableLocales.length > 0) {
this.addCaptionForLocale(this.availableLocales[0]);
}
}
addCaptionForLocale(locale: string) {
this.addCaptionFormGroup({
locale_code: locale,
caption: ''
});
this.updateAvailableLocales();
}
removeCaption(index: number) {
this.captions.removeAt(index);
this.updateAvailableLocales();
}
updateAvailableLocales() {
const usedLocales = this.captions.controls.map(c => c.get('locale_code')?.value);
this.availableLocales = this.data.supportedLocales.filter(
locale => !usedLocales.includes(locale)
);
}
getLocaleName(localeCode: string): string {
const localeNames: { [key: string]: string } = {
'tr': 'Türkçe',
'en': 'English',
'de': 'Deutsch',
'fr': 'Français',
'es': 'Español',
'ar': 'العربية',
'ru': 'Русский',
'zh': '中文',
'ja': '日本語',
'ko': '한국어'
};
return localeNames[localeCode] || localeCode;
}
save() {
if (this.form.valid) {
this.dialogRef.close(this.form.value.captions);
}
}
cancel() {
this.dialogRef.close();
}
}