diff --git a/.gitignore b/.gitignore index d8cb675af..bbb61b064 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,4 @@ local-serve.sh .claude/ CLAUDE.md TRANSLATIONS_SCRATCH.md +docs/ diff --git a/src/app/components/shared/project-name-dialog/project-name-dialog.component.html b/src/app/components/shared/project-name-dialog/project-name-dialog.component.html index 2f278b3b3..ad685235b 100644 --- a/src/app/components/shared/project-name-dialog/project-name-dialog.component.html +++ b/src/app/components/shared/project-name-dialog/project-name-dialog.component.html @@ -16,25 +16,52 @@

- - {{ 'PROJECT_NAME' | translate }} - - {{ projectName()?.length || 0 }}/100 - @if (!projectName()?.trim()) { - {{ 'PROJECT_NAME_REQUIRED' | translate }} - } @else if (projectName()?.length >= 100) { - {{ 'PROJECT_NAME_MAX_LENGTH' | translate }} - } - + + + @if (jobCount <= 1) { + {{ 'RENAME_JOB_TO' | translate }} + } @else { + {{ 'RENAME_JOBS_TO' | translate: { count: jobCount } }} + } + + + + {{ 'PROJECT_NAME' | translate }} + + {{ projectName()?.length || 0 }}/100 + @if (!projectName()?.trim()) { + {{ 'PROJECT_NAME_REQUIRED' | translate }} + } @else if (projectName()?.length >= 100) { + {{ 'PROJECT_NAME_MAX_LENGTH' | translate }} + } + + + + @if (projectCount <= 1) { + {{ 'REMOVE_PROJECT_NAME' | translate }} + } @else { + {{ 'REMOVE_PROJECT_NAMES' | translate: { count: projectCount } }} + } + + @if (dataSource.data.length > 0) {

@@ -86,18 +113,32 @@

[(ngModel)]="confirmationChecked" name="confirmationChecked" > - {{ - (projectCount === 1 - ? 'CONFIRM_RENAME_SINGLE' - : 'CONFIRM_RENAME_MULTIPLE' - ) - | translate - : { - projectCount: projectCount, - jobCount: jobCount, - newName: projectName()?.trim(), - } - }} + @if (isEditMode()) { + {{ + (projectCount === 1 + ? 'CONFIRM_RENAME_SINGLE' + : 'CONFIRM_RENAME_MULTIPLE' + ) + | translate + : { + projectCount: projectCount, + jobCount: jobCount, + newName: projectName()?.trim(), + } + }} + } @else { + {{ + (projectCount === 1 + ? 'CONFIRM_REMOVE_SINGLE' + : 'CONFIRM_REMOVE_MULTIPLE' + ) + | translate + : { + projectCount: projectCount, + jobCount: jobCount, + } + }} + } } } diff --git a/src/app/components/shared/project-name-dialog/project-name-dialog.component.scss b/src/app/components/shared/project-name-dialog/project-name-dialog.component.scss index 946a24eb5..fa95893eb 100644 --- a/src/app/components/shared/project-name-dialog/project-name-dialog.component.scss +++ b/src/app/components/shared/project-name-dialog/project-name-dialog.component.scss @@ -26,12 +26,34 @@ app-project-name-dialog { } } + // Radio group layout for edit/remove toggle + .project-edit-radio-group { + display: flex; + flex-direction: column; + gap: 8px; + margin-bottom: 16px; + } + .project-name-field { - width: 100%; + margin-left: 32px; + width: calc(100% - 32px); .mat-mdc-text-field-wrapper { padding-top: 0; } + + // Subtle disabled state when "Remove" is selected + &.disabled { + opacity: 0.5; + pointer-events: none; + } + } + + // Radio button label sizing + .mat-mdc-radio-button { + .mdc-label { + font-size: 14px; + } } .projects-label { diff --git a/src/app/components/shared/project-name-dialog/project-name-dialog.component.ts b/src/app/components/shared/project-name-dialog/project-name-dialog.component.ts index f0fd90c57..d5b5e5a10 100644 --- a/src/app/components/shared/project-name-dialog/project-name-dialog.component.ts +++ b/src/app/components/shared/project-name-dialog/project-name-dialog.component.ts @@ -37,6 +37,7 @@ import { MatRowDef, MatRow, } from '@angular/material/table'; +import { MatRadioModule } from '@angular/material/radio'; import { MatSort, MatSortModule } from '@angular/material/sort'; import { TranslateModule, TranslateService } from '@ngx-translate/core'; import { SubSink } from 'subsink'; @@ -92,6 +93,7 @@ export interface ProjectNameDialogResult { MatRowDef, MatRow, TranslateModule, + MatRadioModule, ], }) export class ProjectNameDialogComponent @@ -125,9 +127,14 @@ export class ProjectNameDialogComponent public successCount = 0; public failedCount = 0; public failedProjectNames: string[] = []; + public projectEditType = signal<'edit' | 'remove'>('edit'); // Computed values (only recalculate when dependencies change) - public isValid = computed(() => this.projectName().trim().length > 0); + public isEditMode = computed(() => this.projectEditType() === 'edit'); + public isRemoveMode = computed(() => this.projectEditType() === 'remove'); + public isValid = computed( + () => this.projectName().trim().length > 0 || this.isRemoveMode(), + ); public formattedTimeRemaining = computed(() => { // Only show estimated time for operations of 5+ jobs @@ -157,7 +164,7 @@ export class ProjectNameDialogComponent } const products = this.data?.products; - this.jobCount = products?.length; + this.jobCount = products?.length ?? 1; if (products) { const unnamedLabel = this.translateService.instant( @@ -204,7 +211,7 @@ export class ProjectNameDialogComponent return; } - const trimmedName = this.projectName().trim(); + const trimmedName = this.isEditMode() ? this.projectName().trim() : null; // If no products, just return the name (single-file rename flow) if (!this.data.products || this.data.products.length === 0) { diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json index 710f679de..2849fc25a 100644 --- a/src/assets/i18n/de.json +++ b/src/assets/i18n/de.json @@ -597,6 +597,8 @@ "REMOVE_FILE_FROM_DOWNLOADS": "Datei aus Downloads entfernen", "REMOVE_FILE_FROM_QUEUE": "Datei aus der Warteschlange entfernen", "REMOVE_JOB": "Job entfernen", + "REMOVE_PROJECT_NAME": "Projektname entfernen", + "REMOVE_PROJECT_NAMES": "{{count}} Projektnamen entfernen", "REMOVE_RED_EYE": "remove_red_eye", "REMOVE_SCENE_FILES_FROM_DOWNLOADS": "Entfernen von Szenendateien aus Downloads", "RESAMPLED_DEM_SRTM_OR_NED_USED_FOR_RTC_PROCESSING": "Resampled DEM (SRTM oder NED), das für die RTC-Verarbeitung verwendet wird.", @@ -609,6 +611,8 @@ "RENAME_ALL_FAILED": "{{count}} Auftrag/Aufträge konnten nicht umbenannt werden.", "RENAME_COMPLETE": "Umbenennung abgeschlossen", "RENAME_ERROR": "Beim Umbenennen der Aufträge ist ein Fehler aufgetreten.", + "RENAME_JOB_TO": "Job umbenennen zu:", + "RENAME_JOBS_TO": "{{count}} Jobs umbenennen zu:", "RENAME_PARTIAL_SUCCESS": "{{success}} Auftrag/Aufträge umbenannt. {{failed}} fehlgeschlagen.", "RENAME_SUCCESS": "{{count}} Auftrag/Aufträge erfolgreich umbenannt.", "RENAMING_JOBS": "Aufträge werden umbenannt...", diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index b88ab00a2..8e5f2fa6a 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -126,6 +126,8 @@ "CANNOT_RENAME_PROJECTS_FOR": "You cannot rename projects for", "CONFIRM_RENAME_MULTIPLE": "Yes! I really want to rename these {{projectCount}} projects ({{jobCount}} jobs) to \"{{newName}}\".", "CONFIRM_RENAME_SINGLE": "Yes! I really want to rename this 1 project ({{jobCount}} jobs) to \"{{newName}}\".", + "CONFIRM_REMOVE_MULTIPLE": "Yes! I really want to remove the names from these {{projectCount}} projects ({{jobCount}} jobs).", + "CONFIRM_REMOVE_SINGLE": "Yes! I really want to remove the project name from this project ({{jobCount}} jobs).", "CENTER_COLUMN_AND_FILES_COLUMN_RIGHT_WILL_POPULATE": "(center column) and Files column (right) will populate.", "CHARACTERS": "characters", "CHART": "Chart", @@ -713,6 +715,8 @@ "REMOVE_FILE_FROM_DOWNLOADS": "Remove file from downloads", "REMOVE_FILE_FROM_QUEUE": "Remove file from queue", "REMOVE_JOB": "Remove job", + "REMOVE_PROJECT_NAME": "Remove project name", + "REMOVE_PROJECT_NAMES": "Remove {{count}} project names", "REMOVE_RED_EYE": "remove_red_eye", "REMOVE_SCENE_FILES_FROM_DOWNLOADS": "Remove scene files from downloads", "REMOVE_SERIES": "Remove Series", @@ -728,6 +732,8 @@ "RENAME_ALL_FAILED": "Failed to rename {{count}} job(s).", "RENAME_COMPLETE": "Rename Complete", "RENAME_ERROR": "An error occurred while renaming jobs.", + "RENAME_JOB_TO": "Rename job to:", + "RENAME_JOBS_TO": "Rename {{count}} jobs to:", "RENAME_PARTIAL_SUCCESS": "Renamed {{success}} job(s). {{failed}} failed.", "RENAME_SUCCESS": "Successfully renamed {{count}} job(s).", "RENAMING_JOBS": "Renaming jobs...", @@ -1050,4 +1056,4 @@ "ZOOM_TO_FIT": "Zoom To Fit", "ZOOM_TO_RESULTS": "Zoom to results", "ZOOM_TO_SCENE": "Zoom to scene" -} \ No newline at end of file +} diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index ba4d9b069..2f32c1015 100644 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -126,6 +126,8 @@ "CANNOT_RENAME_PROJECTS_FOR": "No puede cambiar el nombre de los proyectos de", "CONFIRM_RENAME_MULTIPLE": "¡Sí! Realmente quiero renombrar estos {{projectCount}} proyectos ({{jobCount}} trabajos) a \"{{newName}}\".", "CONFIRM_RENAME_SINGLE": "¡Sí! Realmente quiero renombrar este 1 proyecto ({{jobCount}} trabajos) a \"{{newName}}\".", + "CONFIRM_REMOVE_MULTIPLE": "¡Sí! Realmente quiero eliminar estos {{projectCount}} proyectos ({{jobCount}} trabajos).", + "CONFIRM_REMOVE_SINGLE": "¡Sí! Realmente quiero eliminar este 1 proyecto ({{jobCount}} trabajos).", "CENTER_COLUMN_AND_FILES_COLUMN_RIGHT_WILL_POPULATE": "(columna central) y la columna Archivos (derecha) se completarán.", "CHARACTERS": "caracteres", "CHART": "Gráfico", @@ -714,6 +716,8 @@ "REMOVE_FILE_FROM_DOWNLOADS": "Eliminar archivo de las descargas", "REMOVE_FILE_FROM_QUEUE": "Eliminar archivo de la lista", "REMOVE_JOB": "Quitar trabajo", + "REMOVE_PROJECT_NAME": "Eliminar nombre del proyecto", + "REMOVE_PROJECT_NAMES": "Eliminar {{count}} nombres de proyecto", "REMOVE_RED_EYE": "quitar_ojo_rojo", "REMOVE_SCENE_FILES_FROM_DOWNLOADS": "Eliminar archivos de escena de las descargas", "REMOVE_SERIES": "Eliminar serie", @@ -729,6 +733,8 @@ "RENAME_ALL_FAILED": "Error al renombrar {{count}} trabajo(s).", "RENAME_COMPLETE": "Cambio de nombre completado", "RENAME_ERROR": "Ocurrió un error al renombrar los trabajos.", + "RENAME_JOB_TO": "Renombrar trabajo a:", + "RENAME_JOBS_TO": "Renombrar {{count}} trabajos a:", "RENAME_PARTIAL_SUCCESS": "Se renombraron {{success}} trabajo(s). {{failed}} fallaron.", "RENAME_SUCCESS": "Se renombraron {{count}} trabajo(s) exitosamente.", "RENAMING_JOBS": "Renombrando trabajos...", @@ -1051,4 +1057,4 @@ "ZOOM_TO_FIT": "Acercar para ajustar", "ZOOM_TO_RESULTS": "Acercar a los resultados", "ZOOM_TO_SCENE": "Acercar a la escena" -} \ No newline at end of file +}