diff --git a/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.html b/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.html index 7a4e788..ebfe195 100644 --- a/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.html +++ b/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.html @@ -3,16 +3,7 @@ TRIGGER DETAILS - - - - - - - - +
@@ -82,7 +73,7 @@ diff --git a/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.spec.ts b/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.spec.ts new file mode 100644 index 0000000..d25ff65 --- /dev/null +++ b/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.spec.ts @@ -0,0 +1,80 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; +import {MatCardModule} from '@angular/material/card'; +import {SimpleTriggerConfigComponent} from './simple-trigger-config.component'; +import {ApiService, ConfigService, SchedulerService} from '../../services'; +import {HttpClient} from '@angular/common/http'; +import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; +import {DebugElement, NO_ERRORS_SCHEMA} from '@angular/core'; +import {By} from '@angular/platform-browser'; +import {RouterTestingModule} from '@angular/router/testing'; +import {MatIconModule} from '@angular/material/icon'; +import {FormsModule} from '@angular/forms'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {MatNativeDateModule} from '@angular/material/core'; +import {MatDatepickerModule} from '@angular/material/datepicker'; +import {MatInputModule} from '@angular/material/input'; +import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; +import {TriggerKey} from '../../model/triggerKey.model'; +import {Trigger} from '../../model/trigger.model'; +import {NgxMatDatetimePickerModule} from '@angular-material-components/datetime-picker'; +import { NgxMatMomentModule } from '@angular-material-components/moment-adapter'; + +describe('SimpleTriggerConfig', () => { + + let component: SimpleTriggerConfigComponent; + let fixture: ComponentFixture; + + let httpClient: HttpClient; + let httpTestingController: HttpTestingController; + + beforeEach(async( () => { + TestBed.configureTestingModule({ + imports: [FormsModule, MatFormFieldModule, MatFormFieldModule, MatInputModule, BrowserAnimationsModule, + MatNativeDateModule, + MatCardModule, MatIconModule, HttpClientTestingModule, RouterTestingModule], + declarations: [SimpleTriggerConfigComponent], + providers: [SchedulerService, ApiService, ConfigService], + schemas: [NO_ERRORS_SCHEMA] + }).compileComponents(); + + httpClient = TestBed.inject(HttpClient); + httpTestingController = TestBed.inject(HttpTestingController); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SimpleTriggerConfigComponent); + component = fixture.componentInstance; + }); + + it('should fetch no triggers at the init', () => { + expect(component).toBeTruthy(); + httpTestingController.expectNone('/quartz-manager/simple-triggers/my-simple-trigger'); + }); + + it('should fetch and display the trigger when the triggerKey is passed as input', () => { + const mockTriggerKey = new TriggerKey('my-simple-trigger', null); + component.triggerKey = mockTriggerKey; + fixture.detectChanges(); + + const mockTrigger = new Trigger(); + mockTrigger.triggerKeyDTO = mockTriggerKey; + const getSimpleTriggerReq = httpTestingController.expectOne('/quartz-manager/simple-triggers/my-simple-trigger'); + getSimpleTriggerReq.flush(mockTrigger); + + const componentDe: DebugElement = fixture.debugElement; + const submitButton = componentDe.query(By.css('form > button')); + expect(submitButton.nativeElement.textContent.trim()).toEqual('Reschedule'); + }); + + it('should get display the form if the openTriggerForm method is called', () => { + component.openTriggerForm(); + fixture.detectChanges(); + + const componentDe: DebugElement = fixture.debugElement; + const submitButton = componentDe.query(By.css('form > button[color="primary"]')); + expect(submitButton.nativeElement.textContent.trim()).toEqual('Submit'); + }); + + + +}); diff --git a/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.ts b/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.ts index 8efd796..3888801 100644 --- a/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.ts +++ b/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.ts @@ -1,10 +1,11 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; import {SchedulerService} from '../../services'; import {Scheduler} from '../../model/scheduler.model'; import {SimpleTriggerCommand} from '../../model/simple-trigger.command'; import {SimpleTrigger} from '../../model/simple-trigger.model'; import {SimpleTriggerForm} from '../../model/simple-trigger.form'; import * as moment from 'moment'; +import {TriggerKey} from '../../model/triggerKey.model'; @Component({ selector: 'qrzmng-simple-trigger-config', @@ -20,31 +21,53 @@ export class SimpleTriggerConfigComponent implements OnInit { scheduler: Scheduler; triggerLoading = true; - enabledTriggerForm = false; + private fetchedTriggers = false; private triggerInProgress = false; + private selectedTriggerKey: TriggerKey; + + enabledTriggerForm = false; + + @Output() + onNewTrigger = new EventEmitter(); + constructor( private schedulerService: SchedulerService ) { } ngOnInit() { - this.triggerLoading = true; - this.retrieveConfiguredTriggerIfExists(); } - retrieveConfiguredTriggerIfExists = () => { - this.schedulerService.getSimpleTriggerConfig() + openTriggerForm() { + this.enabledTriggerForm = true; + } + + private closeTriggerForm() { + this.enabledTriggerForm = false; + } + + @Input() + set triggerKey(triggerKey: TriggerKey){ + this.selectedTriggerKey = {...triggerKey} as TriggerKey; + this.fetchSelectedTrigger(); + } + + + fetchSelectedTrigger = () => { + this.triggerLoading = true; + this.schedulerService.getSimpleTriggerConfig(this.selectedTriggerKey.name) .subscribe((retTrigger: SimpleTrigger) => { this.trigger = retTrigger; this.formBackup = this.simpleTriggerForm; this.simpleTriggerForm = this._fromTriggerToForm(retTrigger); - this.triggerLoading = false; this.triggerInProgress = this.trigger.mayFireAgain; }) } + shouldShowTheTriggerCardContent = (): boolean => this.trigger !== null || this.enabledTriggerForm; + existsATriggerInProgress = (): boolean => this.trigger && this.triggerInProgress; cancelConfigForm = () => this.enabledTriggerForm = false; @@ -59,25 +82,16 @@ export class SimpleTriggerConfigComponent implements OnInit { this.trigger = retTrigger; this.formBackup = this.simpleTriggerForm; this.simpleTriggerForm = this._fromTriggerToForm(retTrigger); - this.enabledTriggerForm = false; this.fetchedTriggers = true; this.triggerInProgress = this.trigger.mayFireAgain; + + this.onNewTrigger.emit(retTrigger); + this.closeTriggerForm(); }, error => { this.simpleTriggerForm = this.formBackup; }); }; - enableTriggerForm = () => this.enabledTriggerForm = true; - - private _fromTriggerToCommand = (simpleTrigger: SimpleTrigger) => { - const command = new SimpleTriggerCommand(); - command.repeatCount = simpleTrigger.repeatCount; - command.repeatInterval = simpleTrigger.repeatInterval; - command.startDate = simpleTrigger.startTime; - command.endDate = simpleTrigger.endTime; - return command; - } - private _fromTriggerToForm = (simpleTrigger: SimpleTrigger): SimpleTriggerForm => { const command = new SimpleTriggerForm(); command.repeatCount = simpleTrigger.repeatCount; diff --git a/quartz-manager-frontend/src/app/components/trigger-list/trigger-list.component.html b/quartz-manager-frontend/src/app/components/trigger-list/trigger-list.component.html index 36e76a9..0c722c8 100644 --- a/quartz-manager-frontend/src/app/components/trigger-list/trigger-list.component.html +++ b/quartz-manager-frontend/src/app/components/trigger-list/trigger-list.component.html @@ -1,14 +1,14 @@ TRIGGERS - - + {{ triggerKey.name }} diff --git a/quartz-manager-frontend/src/app/components/trigger-list/trigger-list.component.spec.ts b/quartz-manager-frontend/src/app/components/trigger-list/trigger-list.component.spec.ts new file mode 100644 index 0000000..2f61fd0 --- /dev/null +++ b/quartz-manager-frontend/src/app/components/trigger-list/trigger-list.component.spec.ts @@ -0,0 +1,84 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; +import {ApiService, ConfigService, TriggerService} from '../../services'; +import {HttpClient} from '@angular/common/http'; +import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; +import {RouterTestingModule} from '@angular/router/testing'; +import {DebugElement} from '@angular/core'; +import {By} from '@angular/platform-browser'; +import {MatCardModule} from '@angular/material/card'; +import {MatIconModule} from '@angular/material/icon'; +import {MatDividerModule} from '@angular/material/divider'; +import {TriggerListComponent} from './trigger-list.component'; +import {MatListModule} from '@angular/material/list'; +import {TriggerKey} from '../../model/triggerKey.model'; + +describe('TriggerListComponent', () => { + + let component: TriggerListComponent; + let fixture: ComponentFixture; + + let httpClient: HttpClient; + let httpTestingController: HttpTestingController; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [MatCardModule, MatDividerModule, MatIconModule, MatListModule, HttpClientTestingModule, RouterTestingModule], + declarations: [TriggerListComponent], + providers: [TriggerService, ApiService, ConfigService] + }).compileComponents(); + + httpClient = TestBed.inject(HttpClient); + httpTestingController = TestBed.inject(HttpTestingController); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TriggerListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should select the first trigger of the list', () => { + expect(component).toBeDefined(); + + let actualSelectedTrigger: TriggerKey; + component.onSelectedTrigger.subscribe(selectedTrigger => actualSelectedTrigger = selectedTrigger); + + const getTriggerListReq = httpTestingController.expectOne('quartz-manager/triggers'); + const mockExistingTriggers = new Array(); + const firstTriggerKey = new TriggerKey('trigger1', 'group1'); + mockExistingTriggers.push(firstTriggerKey); + const secondTriggerKey = new TriggerKey('trigger2', 'group2'); + mockExistingTriggers.push(secondTriggerKey); + getTriggerListReq.flush(mockExistingTriggers); + fixture.detectChanges(); + + const triggerListComponentDe: DebugElement = fixture.debugElement; + const triggerItemList = triggerListComponentDe.queryAll(By.css('.triggerItemList')); + expect(triggerItemList.length).toEqual(2); + + expect(actualSelectedTrigger).toEqual(firstTriggerKey); + + }); + + it('should open the trigger form if the trigger list is empty', () => { + expect(component).toBeDefined(); + + let actualSelectedTrigger: TriggerKey; + component.onSelectedTrigger.subscribe(selectedTrigger => actualSelectedTrigger = selectedTrigger); + + let expectedOpenedNewTriggerFormEvent: boolean; + component.onNewTriggerClicked.subscribe(() => expectedOpenedNewTriggerFormEvent = true); + + const getTriggerListReq = httpTestingController.expectOne('quartz-manager/triggers'); + getTriggerListReq.flush(new Array()); + fixture.detectChanges(); + + const triggerListComponentDe: DebugElement = fixture.debugElement; + const triggerItemList = triggerListComponentDe.queryAll(By.css('.triggerItemList')); + expect(triggerItemList.length).toEqual(0); + + expect(expectedOpenedNewTriggerFormEvent).toBeTruthy(); + expect(actualSelectedTrigger).toBeUndefined(); + }); + +}); diff --git a/quartz-manager-frontend/src/app/components/trigger-list/trigger-list.component.ts b/quartz-manager-frontend/src/app/components/trigger-list/trigger-list.component.ts index 490f68b..b6428ae 100644 --- a/quartz-manager-frontend/src/app/components/trigger-list/trigger-list.component.ts +++ b/quartz-manager-frontend/src/app/components/trigger-list/trigger-list.component.ts @@ -1,6 +1,7 @@ -import {Component, EventEmitter, OnInit, Output} from '@angular/core'; +import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; import {TriggerService} from '../../services/trigger.service'; import {TriggerKey} from '../../model/triggerKey.model'; +import {SimpleTrigger} from '../../model/simple-trigger.model'; @Component({ selector: 'qrzmng-trigger-list', @@ -9,10 +10,18 @@ import {TriggerKey} from '../../model/triggerKey.model'; }) export class TriggerListComponent implements OnInit { - loading = true; - triggerKeys: Array = []; + @Input() + newTriggers: Array = new Array(); - @Output() openedNewTriggerFormEvent = new EventEmitter(); + loading = true; + + triggerKeys: Array = new Array(); + + @Output() onNewTriggerClicked = new EventEmitter(); + triggerFormIsOpen = false; + + selectedTrigger: TriggerKey; + @Output() onSelectedTrigger = new EventEmitter(); constructor( private triggerService: TriggerService @@ -23,14 +32,35 @@ export class TriggerListComponent implements OnInit { this.fetchTriggers(); } + @Input() + set openedNewTriggerForm(triggerFormIsOpen: boolean){ + this.triggerFormIsOpen = triggerFormIsOpen; + } + + getTriggerKeyList = () => { + const newTriggerKeys = this.newTriggers.map(simpleTrigger => simpleTrigger.triggerKeyDTO); + return newTriggerKeys.concat(this.triggerKeys); + } + private fetchTriggers() { this.triggerService.fetchTriggers() .subscribe((triggerKeys: Array) => { this.triggerKeys = triggerKeys; + if (!triggerKeys || triggerKeys.length === 0) { + this.onNewTriggerBtnClicked(); + } + else { + this.selectTrigger(this.triggerKeys[0]); + } }) } - openNewTriggerForm() { - this.openedNewTriggerFormEvent.emit(true); + selectTrigger(triggerKey: TriggerKey) { + this.selectedTrigger = triggerKey; + this.onSelectedTrigger.emit(triggerKey); + } + + onNewTriggerBtnClicked() { + this.onNewTriggerClicked.emit(); } } diff --git a/quartz-manager-frontend/src/app/services/scheduler.service.ts b/quartz-manager-frontend/src/app/services/scheduler.service.ts index afc94ec..9a26d1b 100644 --- a/quartz-manager-frontend/src/app/services/scheduler.service.ts +++ b/quartz-manager-frontend/src/app/services/scheduler.service.ts @@ -43,8 +43,8 @@ export class SchedulerService { return this.apiService.get(getBaseUrl() + '/quartz-manager/scheduler/config') } - getSimpleTriggerConfig = (): Observable => { - return this.apiService.get(getBaseUrl() + '/quartz-manager/simple-triggers/my-simple-trigger'); + getSimpleTriggerConfig = (triggerName: string): Observable => { + return this.apiService.get(getBaseUrl() + `/quartz-manager/simple-triggers/${triggerName}`); } // deprecated diff --git a/quartz-manager-frontend/src/app/views/manager/manager.component.html b/quartz-manager-frontend/src/app/views/manager/manager.component.html index df44e6d..6131d71 100644 --- a/quartz-manager-frontend/src/app/views/manager/manager.component.html +++ b/quartz-manager-frontend/src/app/views/manager/manager.component.html @@ -1,6 +1,6 @@ -
+
-
+
@@ -8,13 +8,21 @@
- +
- + +
diff --git a/quartz-manager-frontend/src/app/views/manager/manager.component.ts b/quartz-manager-frontend/src/app/views/manager/manager.component.ts index 839c3e7..f8c51fd 100644 --- a/quartz-manager-frontend/src/app/views/manager/manager.component.ts +++ b/quartz-manager-frontend/src/app/views/manager/manager.component.ts @@ -1,8 +1,11 @@ -import { Component, OnInit } from '@angular/core'; +import {Component, OnInit, ViewChild} from '@angular/core'; import { ConfigService, UserService } from '../../services'; +import {SimpleTrigger} from '../../model/simple-trigger.model'; +import {TriggerKey} from '../../model/triggerKey.model'; +import {SimpleTriggerConfigComponent} from '../../components/simple-trigger-config'; @Component({ selector: 'manager', @@ -11,8 +14,14 @@ import { }) export class ManagerComponent implements OnInit { + @ViewChild(SimpleTriggerConfigComponent) + private triggerConfigComponent!: SimpleTriggerConfigComponent; + newTriggerFormOpened = false; + newTriggers = new Array(); + selectedTriggerKey: TriggerKey; + constructor( private config: ConfigService, private userService: UserService @@ -21,8 +30,19 @@ export class ManagerComponent implements OnInit { ngOnInit() { } - setnewTriggerFormOpened(opened: boolean){ - this.newTriggerFormOpened = opened; + onNewTriggerRequested() { + this.triggerConfigComponent.openTriggerForm(); } + onNewTrigger(newTrigger: SimpleTrigger) { + this.newTriggers.push(newTrigger); + } + + setSelectedTrigger(triggerKey: TriggerKey) { + this.selectedTriggerKey = triggerKey; + } + + onTriggerFormToggled(formOpened: boolean) { + this.newTriggerFormOpened = formOpened; + } }