Spaces:
Paused
Paused
| 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; | |
| } | |
| ({ | |
| 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>, | |
| (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(); | |
| } | |
| } |