diff --git a/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/attachment-unit-form/attachment-unit-form.component.html b/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/attachment-unit-form/attachment-unit-form.component.html index 7c8434dc9023..f658308506ef 100644 --- a/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/attachment-unit-form/attachment-unit-form.component.html +++ b/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/attachment-unit-form/attachment-unit-form.component.html @@ -2,7 +2,7 @@
- + {{ 'artemisApp.attachmentUnit.createAttachmentUnit.fileTooBig' | artemisTranslate }} - {{ 'artemisApp.attachmentUnit.createAttachmentUnit.fileLimitation' | artemisTranslate }}
} @if (!fileName() && fileInputTouched) { @@ -105,14 +104,16 @@
- - @if (hasCancelButton()) { - - } + @if (hasCancelButton()) { + + } +
diff --git a/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/attachment-unit-form/attachment-unit-form.component.ts b/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/attachment-unit-form/attachment-unit-form.component.ts index 1bc42524d04b..92f071e8a537 100644 --- a/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/attachment-unit-form/attachment-unit-form.component.ts +++ b/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/attachment-unit-form/attachment-unit-form.component.ts @@ -6,7 +6,9 @@ import { ACCEPTED_FILE_EXTENSIONS_FILE_BROWSER, ALLOWED_FILE_EXTENSIONS_HUMAN_RE import { CompetencyLectureUnitLink } from 'app/entities/competency.model'; import { MAX_FILE_SIZE } from 'app/shared/constants/input.constants'; import { toSignal } from '@angular/core/rxjs-interop'; +import { map, of } from 'rxjs'; import { FormDateTimePickerComponent } from 'app/shared/date-time-picker/date-time-picker.component'; +import { TranslateService } from '@ngx-translate/core'; export interface AttachmentUnitFormData { formProperties: FormProperties; @@ -50,7 +52,7 @@ export class AttachmentUnitFormComponent implements OnChanges { datePickerComponent = viewChild(FormDateTimePickerComponent); - // have to handle the file input as a special case at is not part of the reactive form + // have to handle the file input as a special case, as it is not part of the reactive form @ViewChild('fileInput', { static: false }) fileInput: ElementRef; file: File; @@ -59,6 +61,7 @@ export class AttachmentUnitFormComponent implements OnChanges { fileName = signal(undefined); isFileTooBig = signal(false); + private readonly translateService = inject(TranslateService); private readonly formBuilder = inject(FormBuilder); form: FormGroup = this.formBuilder.group({ name: [undefined as string | undefined, [Validators.required, Validators.maxLength(255)]], @@ -69,9 +72,9 @@ export class AttachmentUnitFormComponent implements OnChanges { competencyLinks: [undefined as CompetencyLectureUnitLink[] | undefined], }); private readonly statusChanges = toSignal(this.form.statusChanges ?? 'INVALID'); - + private readonly name = toSignal(this.nameControl?.valueChanges ?? of('')); isFormValid = computed(() => { - return (this.statusChanges() === 'VALID' || this.fileName()) && !this.isFileTooBig() && this.datePickerComponent()?.isValid(); + return this.statusChanges() === 'VALID' && !this.isFileTooBig() && this.name() && this.fileName(); }); ngOnChanges(): void { @@ -80,6 +83,8 @@ export class AttachmentUnitFormComponent implements OnChanges { } } + private readonly currentLanguage = toSignal(this.translateService.onLangChange.pipe(map((event) => event.lang))); + onFileChange(event: Event): void { const input = event.target as HTMLInputElement; if (!input.files?.length) { @@ -88,7 +93,7 @@ export class AttachmentUnitFormComponent implements OnChanges { this.file = input.files[0]; this.fileName.set(this.file.name); // automatically set the name in case it is not yet specified - if (this.form && (this.nameControl?.value == undefined || this.nameControl?.value == '')) { + if (this.form && !this.name()) { this.form.patchValue({ // without extension name: this.file.name.replace(/\.[^/.]+$/, ''), @@ -97,6 +102,20 @@ export class AttachmentUnitFormComponent implements OnChanges { this.isFileTooBig.set(this.file.size > MAX_FILE_SIZE); } + tooltipText = computed(() => { + this.currentLanguage(); + if (!this.fileName() && !this.name()) { + return this.translateService.instant('artemisApp.attachmentUnit.createAttachmentUnit.nameAndFileRequiredValidationError'); + } + if (!this.fileName()) { + return this.translateService.instant('artemisApp.attachmentUnit.createAttachmentUnit.fileRequiredValidationError'); + } + if (!this.name()) { + return this.translateService.instant('artemisApp.attachmentUnit.createAttachmentUnit.nameRequiredValidationError'); + } + return undefined; + }); + get nameControl() { return this.form.get('name'); } diff --git a/src/main/webapp/i18n/de/lectureUnit.json b/src/main/webapp/i18n/de/lectureUnit.json index 2ed9397e04ff..4e8d8efa8002 100644 --- a/src/main/webapp/i18n/de/lectureUnit.json +++ b/src/main/webapp/i18n/de/lectureUnit.json @@ -173,6 +173,7 @@ "file": "Datei", "version": "Version", "fileRequiredValidationError": "Du musst eine Datei zum Uploaden auswählen.", + "nameAndFileRequiredValidationError": "Der Name ist ein Pflichtfeld. Du musst eine Datei zum Uploaden auswählen.", "chooseFile": "Datei auswählen", "fileTooBig": "Die Datei ist zu groß! Die maximale Dateigröße beträgt 20 MB.", "fileLimitation": "(max. Größe 20 MB)", diff --git a/src/main/webapp/i18n/en/lectureUnit.json b/src/main/webapp/i18n/en/lectureUnit.json index d54a06f188b1..8513f82b8306 100644 --- a/src/main/webapp/i18n/en/lectureUnit.json +++ b/src/main/webapp/i18n/en/lectureUnit.json @@ -173,6 +173,7 @@ "file": "File", "version": "Version", "fileRequiredValidationError": "You must select a file to upload.", + "nameAndFileRequiredValidationError": "Name is required. You must select a file to upload.", "chooseFile": "Choose File", "fileTooBig": "File is too big! The maximum file size is 20 MB.", "fileLimitation": "(max. size 20 MB)",