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 6ed702b59547..1bc42524d04b 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 @@ -1,4 +1,4 @@ -import { Component, ElementRef, OnChanges, ViewChild, computed, inject, input, output, signal } from '@angular/core'; +import { Component, ElementRef, OnChanges, ViewChild, computed, inject, input, output, signal, viewChild } from '@angular/core'; import dayjs from 'dayjs/esm'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { faQuestionCircle, faTimes } from '@fortawesome/free-solid-svg-icons'; @@ -6,6 +6,7 @@ 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 { FormDateTimePickerComponent } from 'app/shared/date-time-picker/date-time-picker.component'; export interface AttachmentUnitFormData { formProperties: FormProperties; @@ -47,6 +48,8 @@ export class AttachmentUnitFormComponent implements OnChanges { hasCancelButton = input(false); onCancel = output(); + datePickerComponent = viewChild(FormDateTimePickerComponent); + // have to handle the file input as a special case at is not part of the reactive form @ViewChild('fileInput', { static: false }) fileInput: ElementRef; @@ -68,7 +71,7 @@ export class AttachmentUnitFormComponent implements OnChanges { private readonly statusChanges = toSignal(this.form.statusChanges ?? 'INVALID'); isFormValid = computed(() => { - return (this.statusChanges() === 'VALID' || this.fileName()) && !this.isFileTooBig(); + return (this.statusChanges() === 'VALID' || this.fileName()) && !this.isFileTooBig() && this.datePickerComponent()?.isValid(); }); ngOnChanges(): void { diff --git a/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/online-unit-form/online-unit-form.component.ts b/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/online-unit-form/online-unit-form.component.ts index 67adf4f2c8dc..241feda894e8 100644 --- a/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/online-unit-form/online-unit-form.component.ts +++ b/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/online-unit-form/online-unit-form.component.ts @@ -1,5 +1,5 @@ import dayjs from 'dayjs/esm'; -import { Component, OnChanges, computed, inject, input, output } from '@angular/core'; +import { Component, OnChanges, computed, inject, input, output, viewChild } from '@angular/core'; import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; import { faArrowLeft, faTimes } from '@fortawesome/free-solid-svg-icons'; import { map } from 'rxjs'; @@ -8,6 +8,7 @@ import { OnlineResourceDTO } from 'app/lecture/lecture-unit/lecture-unit-managem import { OnlineUnitService } from 'app/lecture/lecture-unit/lecture-unit-management/onlineUnit.service'; import { CompetencyLectureUnitLink } from 'app/entities/competency.model'; import { toSignal } from '@angular/core/rxjs-interop'; +import { FormDateTimePickerComponent } from 'app/shared/date-time-picker/date-time-picker.component'; export interface OnlineUnitFormData { name?: string; @@ -45,6 +46,8 @@ export class OnlineUnitFormComponent implements OnChanges { hasCancelButton = input(false); onCancel = output(); + datePickerComponent = viewChild(FormDateTimePickerComponent); + urlValidator = urlValidator; private readonly formBuilder = inject(FormBuilder); @@ -59,7 +62,7 @@ export class OnlineUnitFormComponent implements OnChanges { }); private readonly statusChanges = toSignal(this.form.statusChanges ?? 'INVALID'); - isFormValid = computed(() => this.statusChanges() === 'VALID'); + isFormValid = computed(() => this.statusChanges() === 'VALID' && this.datePickerComponent()?.isValid()); get nameControl() { return this.form.get('name'); diff --git a/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/text-unit-form/text-unit-form.component.ts b/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/text-unit-form/text-unit-form.component.ts index b6d7b31447b2..3ed05d37b8c1 100644 --- a/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/text-unit-form/text-unit-form.component.ts +++ b/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/text-unit-form/text-unit-form.component.ts @@ -1,4 +1,4 @@ -import { Component, OnChanges, OnDestroy, OnInit, computed, inject, input, output } from '@angular/core'; +import { Component, OnChanges, OnDestroy, OnInit, computed, inject, input, output, viewChild } from '@angular/core'; import dayjs from 'dayjs/esm'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { Router } from '@angular/router'; @@ -8,6 +8,7 @@ import { TranslateService } from '@ngx-translate/core'; import { faTimes } from '@fortawesome/free-solid-svg-icons'; import { CompetencyLectureUnitLink } from 'app/entities/competency.model'; import { toSignal } from '@angular/core/rxjs-interop'; +import { FormDateTimePickerComponent } from 'app/shared/date-time-picker/date-time-picker.component'; export interface TextUnitFormData { name?: string; @@ -32,6 +33,8 @@ export class TextUnitFormComponent implements OnInit, OnChanges, OnDestroy { hasCancelButton = input(false); onCancel = output(); + datePickerComponent = viewChild(FormDateTimePickerComponent); + // not included in reactive form content: string | undefined; contentLoadedFromCache = false; @@ -46,7 +49,7 @@ export class TextUnitFormComponent implements OnInit, OnChanges, OnDestroy { }); private readonly statusChanges = toSignal(this.form.statusChanges ?? 'INVALID'); - isFormValid = computed(() => this.statusChanges() === 'VALID'); + isFormValid = computed(() => this.statusChanges() === 'VALID' && this.datePickerComponent()?.isValid()); private markdownChanges = new Subject(); private markdownChangesSubscription: Subscription; diff --git a/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/video-unit-form/video-unit-form.component.ts b/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/video-unit-form/video-unit-form.component.ts index 543526c9491b..0ffea72952dc 100644 --- a/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/video-unit-form/video-unit-form.component.ts +++ b/src/main/webapp/app/lecture/lecture-unit/lecture-unit-management/video-unit-form/video-unit-form.component.ts @@ -1,10 +1,11 @@ import dayjs from 'dayjs/esm'; -import { Component, computed, effect, inject, input, output, untracked } from '@angular/core'; +import { Component, computed, effect, inject, input, output, untracked, viewChild } from '@angular/core'; import { AbstractControl, FormBuilder, FormGroup, ValidationErrors, Validators } from '@angular/forms'; import urlParser from 'js-video-url-parser'; import { faArrowLeft, faTimes } from '@fortawesome/free-solid-svg-icons'; import { CompetencyLectureUnitLink } from 'app/entities/competency.model'; import { toSignal } from '@angular/core/rxjs-interop'; +import { FormDateTimePickerComponent } from 'app/shared/date-time-picker/date-time-picker.component'; export interface VideoUnitFormData { name?: string; @@ -72,6 +73,8 @@ export class VideoUnitFormComponent { hasCancelButton = input(); onCancel = output(); + datePickerComponent = viewChild(FormDateTimePickerComponent); + videoSourceUrlValidator = videoSourceUrlValidator; videoSourceTransformUrlValidator = videoSourceTransformUrlValidator; @@ -84,7 +87,7 @@ export class VideoUnitFormComponent { competencyLinks: [undefined as CompetencyLectureUnitLink[] | undefined], }); private readonly statusChanges = toSignal(this.form.statusChanges ?? 'INVALID'); - isFormValid = computed(() => this.statusChanges() === 'VALID'); + isFormValid = computed(() => this.statusChanges() === 'VALID' && this.datePickerComponent()?.isValid()); constructor() { effect(() => { diff --git a/src/test/javascript/spec/component/lecture-unit/attachment-unit/attachment-unit-form.component.spec.ts b/src/test/javascript/spec/component/lecture-unit/attachment-unit/attachment-unit-form.component.spec.ts index 7235e4bba660..6de2fc97f18e 100644 --- a/src/test/javascript/spec/component/lecture-unit/attachment-unit/attachment-unit-form.component.spec.ts +++ b/src/test/javascript/spec/component/lecture-unit/attachment-unit/attachment-unit-form.component.spec.ts @@ -5,10 +5,11 @@ import { AttachmentUnitFormComponent, AttachmentUnitFormData } from 'app/lecture import { FormDateTimePickerComponent } from 'app/shared/date-time-picker/date-time-picker.component'; import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe'; import dayjs from 'dayjs/esm'; -import { MockComponent, MockDirective, MockPipe } from 'ng-mocks'; +import { MockComponent, MockDirective, MockModule, MockPipe } from 'ng-mocks'; import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'; import { CompetencySelectionComponent } from 'app/shared/competency-selection/competency-selection.component'; import { MAX_FILE_SIZE } from 'app/shared/constants/input.constants'; +import { OwlDateTimeModule, OwlNativeDateTimeModule } from '@danielmoncada/angular-datetime-picker'; describe('AttachmentUnitFormComponent', () => { let attachmentUnitFormComponentFixture: ComponentFixture; @@ -16,11 +17,11 @@ describe('AttachmentUnitFormComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, FormsModule, MockDirective(NgbTooltip)], + imports: [ReactiveFormsModule, FormsModule, MockDirective(NgbTooltip), MockModule(OwlDateTimeModule), MockModule(OwlNativeDateTimeModule)], declarations: [ AttachmentUnitFormComponent, + FormDateTimePickerComponent, MockPipe(ArtemisTranslatePipe), - MockComponent(FormDateTimePickerComponent), MockComponent(FaIconComponent), MockComponent(CompetencySelectionComponent), ], diff --git a/src/test/javascript/spec/component/lecture-unit/online-unit/online-unit-form.component.spec.ts b/src/test/javascript/spec/component/lecture-unit/online-unit/online-unit-form.component.spec.ts index 8f4411cd4f40..3032bb1cf7a0 100644 --- a/src/test/javascript/spec/component/lecture-unit/online-unit/online-unit-form.component.spec.ts +++ b/src/test/javascript/spec/component/lecture-unit/online-unit/online-unit-form.component.spec.ts @@ -3,7 +3,7 @@ import { OnlineUnitFormComponent, OnlineUnitFormData } from 'app/lecture/lecture import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe'; -import { MockComponent, MockPipe, MockProvider } from 'ng-mocks'; +import { MockComponent, MockModule, MockPipe, MockProvider } from 'ng-mocks'; import { FormDateTimePickerComponent } from 'app/shared/date-time-picker/date-time-picker.component'; import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { OnlineUnitService } from 'app/lecture/lecture-unit/lecture-unit-management/onlineUnit.service'; @@ -11,6 +11,9 @@ import { OnlineResourceDTO } from 'app/lecture/lecture-unit/lecture-unit-managem import { HttpResponse } from '@angular/common/http'; import { of } from 'rxjs'; import { CompetencySelectionComponent } from 'app/shared/competency-selection/competency-selection.component'; +import { OwlDateTimeModule, OwlNativeDateTimeModule } from '@danielmoncada/angular-datetime-picker'; +import { ArtemisTestModule } from '../../../test.module'; +import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; describe('OnlineUnitFormComponent', () => { let onlineUnitFormComponentFixture: ComponentFixture; @@ -18,11 +21,11 @@ describe('OnlineUnitFormComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, FormsModule], + imports: [ArtemisTestModule, ReactiveFormsModule, FormsModule, MockModule(NgbTooltipModule), MockModule(OwlDateTimeModule), MockModule(OwlNativeDateTimeModule)], declarations: [ OnlineUnitFormComponent, + FormDateTimePickerComponent, MockPipe(ArtemisTranslatePipe), - MockComponent(FormDateTimePickerComponent), MockComponent(FaIconComponent), MockComponent(CompetencySelectionComponent), ], diff --git a/src/test/javascript/spec/component/lecture-unit/text-unit/text-unit-form.component.spec.ts b/src/test/javascript/spec/component/lecture-unit/text-unit/text-unit-form.component.spec.ts index fae301e74331..e54974801b5f 100644 --- a/src/test/javascript/spec/component/lecture-unit/text-unit/text-unit-form.component.spec.ts +++ b/src/test/javascript/spec/component/lecture-unit/text-unit/text-unit-form.component.spec.ts @@ -8,9 +8,12 @@ import { TextUnitFormComponent, TextUnitFormData } from 'app/lecture/lecture-uni import { FormDateTimePickerComponent } from 'app/shared/date-time-picker/date-time-picker.component'; import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe'; import dayjs from 'dayjs/esm'; -import { MockComponent, MockPipe, MockProvider } from 'ng-mocks'; +import { MockComponent, MockModule, MockPipe, MockProvider } from 'ng-mocks'; import { MockRouter } from '../../../helpers/mocks/mock-router'; import { CompetencySelectionComponent } from 'app/shared/competency-selection/competency-selection.component'; +import { ArtemisTestModule } from '../../../test.module'; +import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; +import { OwlDateTimeModule, OwlNativeDateTimeModule } from '@danielmoncada/angular-datetime-picker'; @Component({ selector: 'jhi-markdown-editor-monaco', template: '' }) class MarkdownEditorStubComponent { @@ -43,11 +46,11 @@ describe('TextUnitFormComponent', () => { }); TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, FormsModule], + imports: [ArtemisTestModule, ReactiveFormsModule, FormsModule, MockModule(NgbTooltipModule), MockModule(OwlDateTimeModule), MockModule(OwlNativeDateTimeModule)], declarations: [ TextUnitFormComponent, MarkdownEditorStubComponent, - MockComponent(FormDateTimePickerComponent), + FormDateTimePickerComponent, MockPipe(ArtemisTranslatePipe), MockComponent(CompetencySelectionComponent), ], diff --git a/src/test/javascript/spec/component/lecture-unit/video-unit/video-unit-form.component.spec.ts b/src/test/javascript/spec/component/lecture-unit/video-unit/video-unit-form.component.spec.ts index 445163b967ff..84180448c005 100644 --- a/src/test/javascript/spec/component/lecture-unit/video-unit/video-unit-form.component.spec.ts +++ b/src/test/javascript/spec/component/lecture-unit/video-unit/video-unit-form.component.spec.ts @@ -3,10 +3,13 @@ import { VideoUnitFormComponent, VideoUnitFormData } from 'app/lecture/lecture-u import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { ArtemisTranslatePipe } from 'app/shared/pipes/artemis-translate.pipe'; -import { MockComponent, MockPipe } from 'ng-mocks'; +import { MockComponent, MockModule, MockPipe } from 'ng-mocks'; import { FormDateTimePickerComponent } from 'app/shared/date-time-picker/date-time-picker.component'; import { FaIconComponent } from '@fortawesome/angular-fontawesome'; import { CompetencySelectionComponent } from 'app/shared/competency-selection/competency-selection.component'; +import { OwlDateTimeModule, OwlNativeDateTimeModule } from '@danielmoncada/angular-datetime-picker'; +import { ArtemisTestModule } from '../../../test.module'; +import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; describe('VideoUnitFormComponent', () => { const validYouTubeUrl = 'https://www.youtube.com/watch?v=8iU8LPEa4o0'; @@ -16,11 +19,11 @@ describe('VideoUnitFormComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, FormsModule], + imports: [ArtemisTestModule, ReactiveFormsModule, FormsModule, MockModule(NgbTooltipModule), MockModule(OwlDateTimeModule), MockModule(OwlNativeDateTimeModule)], declarations: [ VideoUnitFormComponent, + FormDateTimePickerComponent, MockPipe(ArtemisTranslatePipe), - MockComponent(FormDateTimePickerComponent), MockComponent(FaIconComponent), MockComponent(CompetencySelectionComponent), ],