diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/interfaces/po-job-scheduler-internal.interface.ts b/projects/templates/src/lib/components/po-page-job-scheduler/interfaces/po-job-scheduler-internal.interface.ts index 7b1032133a..65d0dd9b01 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/interfaces/po-job-scheduler-internal.interface.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/interfaces/po-job-scheduler-internal.interface.ts @@ -1,6 +1,12 @@ export interface PoJobSchedulerInternal { dayOfMonth?: number; + frequency?: object; + + rangeLimitHour?: string; + + rangeLimitDay?: number; + daysOfWeek?: Array; executionParameter?: object; diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-base.component.spec.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-base.component.spec.ts index cc6e29feeb..9f4b359bd4 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-base.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-base.component.spec.ts @@ -30,7 +30,36 @@ describe('PoPageJobSchedulerBaseComponent:', () => { expect(component).toBeTruthy(); }); + describe('Properties:', () => { + it('value: should set `model`', fakeAsync(() => { + const returnValue: PoJobSchedulerInternal = { + firstExecution: new Date('2019-02-04'), + firstExecutionHour: '06:45', + periodicity: 'single', + recurrent: true + }; + const jobSchedulerInternal = { + firstExecution: new Date('2019-02-04'), + periodicity: 'single', + recurrent: true + }; + + spyOn(component['poPageJobSchedulerService'], 'convertToJobSchedulerInternal').and.returnValue(returnValue); + component.value = jobSchedulerInternal; + + expect(component.model).toEqual(returnValue); + })); + }); + describe('Methods:', () => { + it('ngOnDestroy: should call unsubscribe', () => { + const spyUnsubscribe = spyOn(component['_subscription'], 'unsubscribe'); + + component.ngOnDestroy(); + + expect(spyUnsubscribe).toHaveBeenCalled(); + }); + it('loadData: should set `model` with `new PoPageJobSchedulerInternal()` and exit of method if `id` is invalid.', () => { const invalidId = 0; component.model = undefined; diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-base.component.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-base.component.ts index 301a20a9aa..c29d111e5f 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-base.component.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-base.component.ts @@ -59,6 +59,7 @@ export class PoPageJobSchedulerBaseComponent implements OnDestroy { * ``` * * > Veja mais sobre paginação e filtros no [Guia de implementação de APIs](guides/api). + * Caso seja informada a propriedade `p-parameters` não serão realizadas as requisições de processos e nem de parametros automaticamente. * * Também é possível fazer um agendamento de um processo específico, sem que seja necessário um endpoint para busca desses * processos. Então, caso o endpoint `{service-api}/processes` não seja válido, será apresentado um campo de entrada de @@ -112,8 +113,9 @@ export class PoPageJobSchedulerBaseComponent implements OnDestroy { * { * "firstExecution": "2018-12-07T00:00:01-00:00", * "recurrent": true, - * "daily": { "hour": 10, "minute": 12 }, - * "processID": "ac0405" + * "monthly": { "day": 1, "hour": 10, "minute": 0 }, + * "processID": "ac0405", + * "rangeExecutions: { "frequency": { "type": "hour", "value": 2 }, "rangeLimit": { "hour": 18, "minute": 0, "day": 20 } } * } * ``` * @@ -147,9 +149,11 @@ export class PoPageJobSchedulerBaseComponent implements OnDestroy { * ``` * { * "firstExecution": "2018-12-07T00:00:01-00:00", - * "recurrent": false, - * "daily": { "hour": 11, "minute": 30 }, - * "processID": "ac0405" + * "recurrent": true, + * "processID": "ac0405", + * "monthly": { "day": 1, "hour": 10, "minute": 0 }, + * "processID": "ac0405", + * "rangeExecutions: { "frequency": { "type": "hour", "value": 2 }, "rangeLimit": { "hour": 18, "minute": 0, "day": 20 } } * } * ``` */ @@ -166,6 +170,10 @@ export class PoPageJobSchedulerBaseComponent implements OnDestroy { */ @Input('p-parameters') parameters: Array = []; + @Input('p-value') set value(value: any) { + this.model = this.poPageJobSchedulerService.convertToJobSchedulerInternal(value); + } + model: PoJobSchedulerInternal = new PoPageJobSchedulerInternal(); private _subscription = new Subscription(); @@ -178,7 +186,7 @@ export class PoPageJobSchedulerBaseComponent implements OnDestroy { protected loadData(id: string | number) { if (!id) { - this.model = new PoPageJobSchedulerInternal(); + this.model = this.model || new PoPageJobSchedulerInternal(); return; } diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.html b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.html index b872460ccb..9e8f5cc94d 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.html +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.html @@ -27,7 +27,7 @@ p-placeholder="HH:mm" p-required [p-disabled]="isEdit" - [p-label]="literals.hour" + [p-label]="literals.time" [p-pattern]="timePattern" > @@ -44,13 +44,41 @@ p-required [p-label]="literals.periodicity" [p-options]="periodicityOptions" + (p-change)="onChangePeriodicityOptions($event)" > - +
+ + + + + + + + +
+ +
@@ -126,7 +154,20 @@ [(ngModel)]="value.dayOfMonth" p-required [p-error-pattern]="'Dia inválido'" - [p-label]="literals.day" + [p-label]="dayLabel" + [p-max]="31" + [p-pattern]="dayPattern" + > + + + @@ -144,7 +185,21 @@ p-mask-format-model p-placeholder="HH:mm" p-required - [p-label]="literals.hour" + [p-label]="hourLabel" + [p-pattern]="timePattern" + > + + + diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.spec.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.spec.ts index 53eb5b612e..074047bba3 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.spec.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.spec.ts @@ -49,6 +49,18 @@ describe('PoPageJobSchedulerExecutionComponent:', () => { expectPropertiesValues(component, 'value', validValues, validValues); }); + it('value: should set `containsFrequency` with true if value.frequency.value', () => { + component.value = { frequency: { value: 2 } }; + + expect(component.containsFrequency).toBeTrue(); + }); + + it('value: should set `containsFrequency` with false if value.frequency.value is undefined', () => { + component.value = { frequency: undefined }; + + expect(component.containsFrequency).toBeFalse(); + }); + it('startDateFirstExecution: should return `Date` if `isEdit` is false', () => { component.isEdit = false; @@ -61,6 +73,30 @@ describe('PoPageJobSchedulerExecutionComponent:', () => { expect(component.startDateFirstExecution instanceof Date).toBe(false); expect(component.startDateFirstExecution).toBeUndefined(); }); + + it('hourLabel: should return `literals.startTime` if `containsFrequency`', () => { + component.containsFrequency = true; + const result = component.hourLabel; + expect(result).toEqual(component.literals.startTime); + }); + + it('hourLabel: should return `literals.time` if `containsFrequency` is false', () => { + component.containsFrequency = false; + const result = component.hourLabel; + expect(result).toEqual(component.literals.time); + }); + + it('dayLabel: should return `literals.startDay` if `containsFrequency`', () => { + component.containsFrequency = true; + const result = component.dayLabel; + expect(result).toEqual(component.literals.startDay); + }); + + it('dayLabel: should return `literals.day` if `containsFrequency` is false', () => { + component.containsFrequency = false; + const result = component.dayLabel; + expect(result).toEqual(component.literals.day); + }); }); describe('Methods:', () => { @@ -74,24 +110,58 @@ describe('PoPageJobSchedulerExecutionComponent:', () => { expect(component['subscribeProcessIdValueChanges']).toHaveBeenCalled(); })); + it('ngAfterViewInit: should update `frequencyOption.disabled` if `frequencyOption.value` is equal to `day`', fakeAsync(() => { + component.value.periodicity = 'daily'; + component.frequencyOptions = [ + { label: 'Day', value: 'day' }, + { label: 'Hour', value: 'hour' }, + { label: 'minute', value: 'minute' } + ]; + const expectedValue = [ + { label: 'Day', value: 'day', disabled: true }, + { label: 'Hour', value: 'hour', disabled: false }, + { label: 'minute', value: 'minute', disabled: false } + ]; + + component.ngAfterViewInit(); + + tick(50); + + expect(component.frequencyOptions).toEqual(expectedValue); + })); + it('ngOnInit: should call `checkExistsProcessesAPI` and set `periodicityTemplates`, `periodicityOptions` and `weekDays`', () => { component.periodicityTemplates = undefined; component.periodicityOptions = undefined; + component.frequencyOptions = undefined; component.weekDays = undefined; spyOn(component, 'checkExistsProcessesAPI'); spyOn(component, 'getPeriodicityOptions').and.callThrough(); spyOn(component, 'getWeekDays').and.callThrough(); + spyOn(component, 'getFrequencyOptions').and.callThrough(); component.ngOnInit(); expect(typeof component.periodicityTemplates === 'object').toBe(true); expect(component.periodicityOptions instanceof Array).toBe(true); expect(component.weekDays instanceof Array).toBe(true); + expect(component.frequencyOptions instanceof Array).toBe(true); expect(component['checkExistsProcessesAPI']).toHaveBeenCalled(); expect(component['getPeriodicityOptions']).toHaveBeenCalled(); expect(component['getWeekDays']).toHaveBeenCalled(); + expect(component['getFrequencyOptions']).toHaveBeenCalled(); + }); + + it('ngOnInit: shouldn`t call `checkExistsProcessesAPI` if `noParameters` is false', () => { + component.noParameters = false; + + spyOn(component, 'checkExistsProcessesAPI'); + + component.ngOnInit(); + + expect(component['checkExistsProcessesAPI']).not.toHaveBeenCalled(); }); it('checkExistsProcessesAPI: should subscribe `getHeadProcesses` and on error set `existProcessAPI` to false', () => { @@ -126,6 +196,15 @@ describe('PoPageJobSchedulerExecutionComponent:', () => { expect(weekDays.length).toBe(weekDaysLength); }); + it('getFrequencyOptions: should return 3 options', () => { + const frequencyOptionsLength = 3; + + const frequencyOptions = component['getFrequencyOptions'](); + + expect(frequencyOptions instanceof Array).toBe(true); + expect(frequencyOptions.length).toBe(frequencyOptionsLength); + }); + it('subscribeProcessIdValueChanges: should call `changeProcess.emit` when subscribe `processID.valueChanges`', () => { const processId = 1; component['form'] = { @@ -144,6 +223,60 @@ describe('PoPageJobSchedulerExecutionComponent:', () => { expect(component['form'].controls.processID.valueChanges.subscribe).toHaveBeenCalled(); expect(component.changeProcess.emit).toHaveBeenCalledWith({ processId, existAPI: component.existProcessAPI }); }); + + it('changeContainsFrequency: should update `value.frequency` if `containsfrequency`', () => { + const containsFrequency = true; + const expectedValue = { type: 'hour', value: null }; + + component.onChangeContainsFrequency(containsFrequency); + + expect(component.value.frequency).toEqual(expectedValue); + }); + + it('changeContainsFrequency: should update `value.frequency` with empty object if `containsfrequency` is false', () => { + const containsFrequency = false; + const expectedValue = {}; + + component.onChangeContainsFrequency(containsFrequency); + + expect(component.value.frequency).toEqual(expectedValue); + }); + + it('changeContainsFrequency: should update `value.rangeLimitHour`, `value.rangeLimitDay` and `value.dayOfMonth` with null', () => { + const containsFrequency = false; + + component.onChangeContainsFrequency(containsFrequency); + + expect(component.value.rangeLimitHour).toBeNull(); + expect(component.value.rangeLimitDay).toBeNull(); + expect(component.value.dayOfMonth).toBeNull(); + }); + + it('onChangePeriodicityOptions: should update `frequencyOptions` and `value.frequency.type`', () => { + const periodicity = 'daily'; + component.value.frequency = {}; + component.frequencyOptions = [ + { label: 'Day', value: 'day' }, + { label: 'Hour', value: 'hour' }, + { label: 'minute', value: 'minute' } + ]; + const expectedValue = [ + { label: 'Day', value: 'day', disabled: true }, + { label: 'Hour', value: 'hour', disabled: false }, + { label: 'minute', value: 'minute', disabled: false } + ]; + + component.onChangePeriodicityOptions(periodicity); + + expect(component.frequencyOptions).toEqual(expectedValue); + expect(component.value.frequency.type).toBeNull(); + }); + + it('onChangeFrequencyOptions: should update `value.rangeLimitHour` with `null`', () => { + component.onChangeFrequencyOptions(); + + expect(component.value.rangeLimitHour).toBeNull(); + }); }); describe('Templates:', () => { diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.ts index d5505284b9..32dde94c66 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.ts @@ -35,11 +35,17 @@ export class PoPageJobSchedulerExecutionComponent implements OnInit, AfterViewIn periodicityTemplates: { daily: TemplateRef; weekly: TemplateRef; monthly: TemplateRef }; timePattern = '^(2[0-3]|[01][0-9]):?([0-5][0-9])$'; weekDays: Array = []; + frequencyOptions: Array = []; + containsFrequency = false; + frequency: string = 'hour'; + rangeLimitHour: string; private _value: any = {}; @Input('p-value') set value(value: any) { this._value = value && isTypeof(value, 'object') ? value : {}; + + this.containsFrequency = this._value.frequency && this._value.frequency.value ? true : false; } get value() { @@ -55,9 +61,24 @@ export class PoPageJobSchedulerExecutionComponent implements OnInit, AfterViewIn return this.isEdit ? undefined : this.minDateFirstExecution; } + get hourLabel() { + return this.containsFrequency ? this.literals.startTime : this.literals.time; + } + + get dayLabel() { + return this.containsFrequency ? this.literals.startDay : this.literals.day; + } + ngAfterViewInit() { setTimeout(() => { this.subscribeProcessIdValueChanges(); + + if (this.value.periodicity) { + this.frequencyOptions = this.frequencyOptions.map(frequencyOption => ({ + ...frequencyOption, + disabled: frequencyOption.value === 'day' && this.value.periodicity !== 'monthly' + })); + } }); } @@ -68,10 +89,38 @@ export class PoPageJobSchedulerExecutionComponent implements OnInit, AfterViewIn weekly: this.weeklyTempalte }; - this.checkExistsProcessesAPI(); + if (this.noParameters) { + this.checkExistsProcessesAPI(); + } this.periodicityOptions = this.getPeriodicityOptions(); this.weekDays = this.getWeekDays(); + this.frequencyOptions = this.getFrequencyOptions(); + } + + onChangeContainsFrequency(containsFrequency) { + if (containsFrequency) { + this.value.frequency = { type: 'hour', value: null }; + } else { + this.value.frequency = {}; + } + + this.value.rangeLimitHour = null; + this.value.rangeLimitDay = null; + this.value.dayOfMonth = null; + } + + onChangePeriodicityOptions(periodicity) { + this.frequencyOptions = this.frequencyOptions.map(frequencyOption => ({ + ...frequencyOption, + disabled: frequencyOption.value === 'day' && periodicity !== 'monthly' + })); + + this.value.frequency.type = null; + } + + onChangeFrequencyOptions() { + this.value.rangeLimitHour = null; } private checkExistsProcessesAPI() { @@ -89,6 +138,14 @@ export class PoPageJobSchedulerExecutionComponent implements OnInit, AfterViewIn ]; } + private getFrequencyOptions() { + return [ + { label: this.literals.day, value: 'day' }, + { label: this.literals.hour, value: 'hour' }, + { label: this.literals.minute, value: 'minute' } + ]; + } + private getWeekDays() { return [ { label: this.literals.sunday, value: 'Sunday' }, diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-internal.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-internal.ts index d2d9c8db95..da9fa16f78 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-internal.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-internal.ts @@ -5,6 +5,7 @@ export class PoPageJobSchedulerInternal implements PoJobSchedulerInternal { firstExecution = new Date(); firstExecutionHour = this.getCurrentHour(this.firstExecution); recurrent = true; + frequency = {}; private getCurrentHour(date: Date): string { const hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-literals.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-literals.ts index baf18784fa..29e2daf7de 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-literals.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-literals.ts @@ -16,8 +16,14 @@ export const poPageJobSchedulerLiteralsDefault = { parameterization: 'Parameterization', conclude: 'Conclude', firstExecution: 'First Execution', + startTime: 'Start time', + endTime: 'End time', + time: 'Time', hour: 'Hour', + minute: 'Minute', day: 'Day', + endDay: 'End day', + startDay: 'Start day', weekDays: 'Week days', sunday: 'Sunday', monday: 'Monday', @@ -36,7 +42,10 @@ export const poPageJobSchedulerLiteralsDefault = { confirmUpdateMessage: 'Are you sure you want to update this schedule?', saveNotificationSuccessUpdate: 'Successfully updated scheduling', saveNotificationSuccessSave: 'Successfully saved scheduling', - parametersNotFound: 'Parameters not found.' + parametersNotFound: 'Parameters not found.', + frequency: 'Frequency', + to: 'to', + from: 'from' }, es: { at: 'a las', @@ -55,8 +64,14 @@ export const poPageJobSchedulerLiteralsDefault = { parameterization: 'Parametrización', conclude: 'Completar', firstExecution: 'Primera ejecución', - hour: 'Horario', + startTime: 'Hora de inicio', + endTime: 'Hora de finalización', + time: 'Horário', + hour: 'Hora', + minute: 'Minute', day: 'Día', + endDay: 'Último Día', + startDay: 'Día de inicio', weekDays: 'Dias de la semana', sunday: 'Domingo', monday: 'Lunes', @@ -75,7 +90,10 @@ export const poPageJobSchedulerLiteralsDefault = { confirmUpdateMessage: '¿Está seguro de que desea cambiar esta programación de proceso?', saveNotificationSuccessUpdate: 'Programación de proceso actualizada con éxito.', saveNotificationSuccessSave: 'Programación de proceso salvo con éxito.', - parametersNotFound: 'No se encontraron parámetros.' + parametersNotFound: 'No se encontraron parámetros.', + frequency: 'Frecuencia', + to: 'de', + from: 'a' }, pt: { at: 'às', @@ -94,8 +112,14 @@ export const poPageJobSchedulerLiteralsDefault = { parameterization: 'Parametrização', conclude: 'Concluir', firstExecution: 'Primeira execução', - hour: 'Horário', + startTime: 'Horário inicial', + endTime: 'Horário final', + time: 'Horário', + hour: 'Hora', + minute: 'Minuto', day: 'Dia', + endDay: 'Dia final', + startDay: 'Dia inicial', weekDays: 'Dias de semana', sunday: 'Domingo', monday: 'Segunda-feira', @@ -114,7 +138,10 @@ export const poPageJobSchedulerLiteralsDefault = { confirmUpdateMessage: 'Tem certeza que deseja alterar este agendamento de processo?', saveNotificationSuccessUpdate: 'Agendamento de processo atualizado com sucesso.', saveNotificationSuccessSave: 'Agendamento de processo salvo com sucesso.', - parametersNotFound: 'Parâmetros não foram encontrados.' + parametersNotFound: 'Parâmetros não foram encontrados.', + frequency: 'Frequência', + to: 'das', + from: 'até' }, ru: { at: 'в', @@ -133,8 +160,14 @@ export const poPageJobSchedulerLiteralsDefault = { parameterization: 'Параметризация', conclude: 'Завершить', firstExecution: 'Первичное выполнение', + startTime: 'начальное время', + endTime: 'время окончания', + time: 'расписание', hour: 'Час', day: 'День', + minute: 'минута', + endDay: 'последний день', + startDay: 'день начала', weekDays: 'Рабочие дни', sunday: 'Воскресенье', monday: 'Понедельник', @@ -153,6 +186,9 @@ export const poPageJobSchedulerLiteralsDefault = { confirmUpdateMessage: 'Вы уверены, что хотите обновить это расписание?', saveNotificationSuccessUpdate: 'Расписание успешно обновлено', saveNotificationSuccessSave: 'Расписание успешно сохранено ', - parametersNotFound: 'Параметры не найдены' + parametersNotFound: 'Параметры не найдены', + frequency: 'Частота', + to: 'с', + from: 'до' } }; diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.html b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.html index fb437c0841..35c1bd7cdd 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.html +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.html @@ -9,6 +9,14 @@ + + + { component.executionValue = undefined; component.firstExecutionValue = undefined; component.recurrentValue = undefined; + component.frequencyValue = undefined; component.value = { periodicity: 'single', processID: 'ab03', firstExecution: new Date(), firstExecutionHour: '11:30', - recurrent: false + recurrent: false, + frequency: { type: 'day', value: 2 } }; spyOn(component, 'getPeriodicityLabel').and.callThrough(); spyOn(component, 'getExecutionValue').and.callThrough(); spyOn(component, 'getFirstExecutionLabel').and.callThrough(); spyOn(component, 'getRecurrentValue').and.callThrough(); + spyOn(component, 'getFrequencyValue').and.callThrough(); component.ngOnInit(); @@ -67,11 +70,33 @@ describe('PoPageJobSchedulerSummaryComponent:', () => { expect(component['getExecutionValue']).toHaveBeenCalled(); expect(component['getFirstExecutionLabel']).toHaveBeenCalled(); expect(component['getRecurrentValue']).toHaveBeenCalled(); + expect(component['getFrequencyValue']).toHaveBeenCalled(); expect(component.periodicityValue).toBeDefined(); expect(component.executionValue).toBeDefined(); expect(component.firstExecutionValue).toBeDefined(); expect(component.recurrentValue).toBeDefined(); + expect(component.frequencyValue).toBeDefined(); + }); + + it('getFrequencyValue: should return `frequency[value] - frequency[type]`', () => { + const periodicity = 'daily'; + const frequency = { type: 'day', value: 2 }; + const expectedValue = '2 - day'; + + const result = component['getFrequencyValue'](frequency, periodicity); + + expect(result).toBe(expectedValue); + }); + + it('getFrequencyValue: should return a empty string if `periodicity` is `single`', () => { + const periodicity = 'single'; + const frequency = { type: 'day', value: 2 }; + const expectedValue = ''; + + const result = component['getFrequencyValue'](frequency, periodicity); + + expect(result).toBe(expectedValue); }); it('getExecutionValue: should return `literals.notReported` if periodicity is `single`', () => { @@ -109,10 +134,13 @@ describe('PoPageJobSchedulerSummaryComponent:', () => { const periodicity = 'weekly'; const hour = '11:20'; const daysOfWeek = ['Saturday']; + const rangeLimitHour = '18:00'; + const dayOfMonth = null; + component.value = { firstExecution: new Date(), firstExecutionHour: '', recurrent: false, periodicity: 'single' }; spyOn(component, 'getWeeklyLabelExecution').and.callThrough(); - const executionValue = component['getExecutionValue'](periodicity, hour, daysOfWeek); + const executionValue = component['getExecutionValue'](periodicity, hour, daysOfWeek, dayOfMonth, rangeLimitHour); expect(typeof executionValue === 'string').toBe(true); expect(component['getWeeklyLabelExecution']).toHaveBeenCalled(); @@ -151,14 +179,14 @@ describe('PoPageJobSchedulerSummaryComponent:', () => { }); it('getHourLabel: should return formatted string value with 00:00h if `hour`is undefined', () => { - const expectedValue = `${component.literals.at} 00:00h`; + const expectedValue = `${component.literals.at} 00:00 `; expect(component['getHourLabel'](undefined)).toBe(expectedValue); }); it('getHourLabel: should return formatted string value with 12:00h if `hour` is 12:00', () => { const hour = '12:00'; - const expectedValue = `${component.literals.at} ${hour}h`; + const expectedValue = `${component.literals.at} ${hour} `; expect(component['getHourLabel'](hour)).toBe(expectedValue); }); @@ -166,15 +194,24 @@ describe('PoPageJobSchedulerSummaryComponent:', () => { it('getMonthlyLabelExecution: should return formatted string value with 12:00h if `hour` is 12:00', () => { const hour = '12:00'; const dayOfMonth = 10; + const rangeLimitHour = '18:00'; + const rangeLimitDay = 20; - const expectedValue = `${component.literals.day} ${dayOfMonth} ${component['getHourLabel'](hour)}`; + const expectedValue = `${component.literals.from} ${dayOfMonth} ${ + component.literals.to + } ${rangeLimitDay} ${component['getHourLabel'](hour, rangeLimitHour)}`; spyOn(component, 'getHourLabel').and.callThrough(); - const monthlyLabelExecution = component['getMonthlyLabelExecution'](dayOfMonth, hour); + const monthlyLabelExecution = component['getMonthlyLabelExecution']( + dayOfMonth, + hour, + rangeLimitHour, + rangeLimitDay + ); expect(monthlyLabelExecution).toBe(expectedValue); - expect(component['getHourLabel']).toHaveBeenCalledWith(hour); + expect(component['getHourLabel']).toHaveBeenCalledWith(hour, rangeLimitHour); }); it('getPeriodicityLabel: should return `literals.single`', () => { diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.ts index 64f57b4cd6..09ff892cb3 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-summary/po-page-job-scheduler-summary.component.ts @@ -22,27 +22,64 @@ export class PoPageJobSchedulerSummaryComponent implements OnInit { firstExecutionValue = ''; infoOrientation = PoInfoOrientation.Horizontal; periodicityValue = ''; + frequencyValue = ''; + rangeLimitHour = ''; + rangeLimitDay = ''; recurrentValue = ''; constructor(private datePipe: DatePipe) {} ngOnInit() { - const { periodicity, hour, dayOfMonth, daysOfWeek, recurrent, firstExecution, firstExecutionHour } = this.value; + const { + periodicity, + hour, + dayOfMonth, + daysOfWeek, + recurrent, + firstExecution, + firstExecutionHour, + frequency, + rangeLimitHour, + rangeLimitDay + } = this.value; this.periodicityValue = this.getPeriodicityLabel(periodicity); - this.executionValue = this.getExecutionValue(periodicity, hour, daysOfWeek, dayOfMonth); + if (frequency) { + this.frequencyValue = this.getFrequencyValue(frequency, periodicity); + } + this.executionValue = this.getExecutionValue( + periodicity, + hour, + daysOfWeek, + dayOfMonth, + rangeLimitHour, + rangeLimitDay + ); this.firstExecutionValue = this.getFirstExecutionLabel(firstExecution, firstExecutionHour); this.recurrentValue = this.getRecurrentValue(recurrent); } - private getExecutionValue(periodicity: string, hour?: string, daysOfWeek?: Array, dayOfMonth?: number) { + private getFrequencyValue(frequency, periodicity) { + return frequency['value'] && frequency['type'] && periodicity !== 'single' + ? `${frequency['value']} - ${frequency['type']}` + : ''; + } + + private getExecutionValue( + periodicity: string, + hour?: string, + daysOfWeek?: Array, + dayOfMonth?: number, + rangeLimitHour?: string, + rangeLimitDay?: number + ) { switch (periodicity) { case 'daily': - return this.getHourLabel(hour); + return this.getHourLabel(hour, rangeLimitHour); case 'monthly': - return this.getMonthlyLabelExecution(dayOfMonth, hour); + return this.getMonthlyLabelExecution(dayOfMonth, hour, rangeLimitHour, rangeLimitDay); case 'weekly': - return this.getWeeklyLabelExecution(daysOfWeek, hour); + return this.getWeeklyLabelExecution(daysOfWeek, hour, rangeLimitHour); default: return this.literals.notReported; } @@ -58,14 +95,18 @@ export class PoPageJobSchedulerSummaryComponent implements OnInit { } } - private getHourLabel(hour: string) { - return `${this.literals.at} ${hour || '00:00'}h`; + private getHourLabel(hour: string, rangeLimitHour?) { + return `${rangeLimitHour ? this.literals.from : this.literals.at} ${hour || '00:00'} ${ + rangeLimitHour ? this.literals.to + ' ' + rangeLimitHour : '' + }`; } - private getMonthlyLabelExecution(dayOfMonth: number, hour: string) { - const hourLabel = this.getHourLabel(hour); + private getMonthlyLabelExecution(dayOfMonth: number, hour: string, rangeLimitHour?: string, rangeLimitDay?: number) { + const hourLabel = this.getHourLabel(hour, rangeLimitHour); - return `${this.literals.day} ${dayOfMonth} ${hourLabel}`; + return `${rangeLimitDay ? this.literals.from : ''} ${dayOfMonth} ${rangeLimitDay ? this.literals.to : ''} ${ + rangeLimitDay ? rangeLimitDay : '' + } ${hourLabel}`; } private getPeriodicityLabel(periodicity) { @@ -117,9 +158,9 @@ export class PoPageJobSchedulerSummaryComponent implements OnInit { return weekDaysSorted.map(day => this.getTranslateWeekDay(day)).join(', '); } - private getWeeklyLabelExecution(daysOfWeek: Array, hour: string) { + private getWeeklyLabelExecution(daysOfWeek: Array, hour: string, rangeLimitHour?: string) { if (daysOfWeek && Array.isArray(daysOfWeek)) { - return `${this.getWeekDaysLabel(daysOfWeek)} ${this.getHourLabel(hour)}`; + return `${this.getWeekDaysLabel(daysOfWeek)} ${this.getHourLabel(hour, rangeLimitHour)}`; } else { return this.literals.notReported; } diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.service.spec.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.service.spec.ts index fa6ad2e6cd..f2db1972a0 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.service.spec.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.service.spec.ts @@ -253,6 +253,61 @@ describe('PoPageJobSchedulerService:', () => { ); }); + it(`convertToJobScheduler: should set 'rangeExecutions' with 'frequency'`, () => { + const jobSchedulerInternal = { + frequency: { type: 'day', value: 2 }, + processID: 'id' + }; + + const expectedValue = { + processID: 'id', + rangeExecutions: { + frequency: { type: 'day', value: 2 } + } + }; + + const result = poPageJobSchedulerService['convertToJobScheduler'](jobSchedulerInternal); + expect(result).toEqual(expectedValue); + }); + + it(`convertToJobScheduler: should set 'rangeLimitHour'`, () => { + const jobSchedulerInternal = { + frequency: { type: 'day', value: 2 }, + rangeLimitHour: '18:00', + processID: 'id' + }; + + const expectedValue = { + processID: 'id', + rangeExecutions: { + frequency: { type: 'day', value: 2 }, + rangeLimit: { hour: 18, minute: 0 } + } + }; + + const result = poPageJobSchedulerService['convertToJobScheduler'](jobSchedulerInternal); + expect(result).toEqual(expectedValue); + }); + + it(`convertToJobScheduler: should set 'rangeLimitDay'`, () => { + const jobSchedulerInternal = { + frequency: { type: 'day', value: 2 }, + rangeLimitDay: 2, + processID: 'id' + }; + + const expectedValue = { + processID: 'id', + rangeExecutions: { + frequency: { type: 'day', value: 2 }, + rangeLimit: { day: 2 } + } + }; + + const result = poPageJobSchedulerService['convertToJobScheduler'](jobSchedulerInternal); + expect(result).toEqual(expectedValue); + }); + it(`convertToJobScheduler: should not call 'replaceHourFirstExecution' if 'firstExecutionHour' is undefined`, () => { const jobSchedulerInternal = { firstExecutionHour: undefined @@ -382,6 +437,51 @@ describe('PoPageJobSchedulerService:', () => { expect(result).toEqual({}); }); + it(`convertToJobSchedulerInternal: should set 'rangeExecutions'`, () => { + const jobScheduler = { + processID: '20', + rangeExecutions: { frequency: { type: 'hour', value: 2 }, rangeLimit: { hour: 18, minute: 0, day: 20 } } + }; + + const jobSchedulerInternalExpected = { + processID: '20', + rangeExecutions: { frequency: { type: 'hour', value: 2 }, rangeLimit: { hour: 18, minute: 0, day: 20 } }, + rangeLimitHour: '18:00', + rangeLimitDay: 20, + frequency: { type: 'hour', value: 2 } + }; + + spyOn(poPageJobSchedulerService, 'removeInvalidKeys'); + spyOn(poPageJobSchedulerService, 'convertToPeriodicityInternal'); + spyOn(poPageJobSchedulerService, 'getHourFirstExecution').and.returnValue('06:45'); + + const result = poPageJobSchedulerService['convertToJobSchedulerInternal'](jobScheduler); + + expect(result).toEqual(jobSchedulerInternalExpected); + }); + + it(`convertToJobSchedulerInternal: should set 'rangeExecutions' with 'rangeLimit`, () => { + const jobScheduler = { + processID: '20', + rangeExecutions: { frequency: { type: 'hour', value: 2 }, rangeLimit: { hour: 8, minute: 10, day: 20 } } + }; + + const jobSchedulerInternalExpected = { + processID: '20', + rangeExecutions: { frequency: { type: 'hour', value: 2 }, rangeLimit: { hour: 8, minute: 10, day: 20 } }, + rangeLimitHour: '08:10', + rangeLimitDay: 20, + frequency: { type: 'hour', value: 2 } + }; + + spyOn(poPageJobSchedulerService, 'removeInvalidKeys'); + spyOn(poPageJobSchedulerService, 'convertToPeriodicityInternal'); + spyOn(poPageJobSchedulerService, 'getHourFirstExecution').and.returnValue('06:45'); + + const result = poPageJobSchedulerService['convertToJobSchedulerInternal'](jobScheduler); + + expect(result).toEqual(jobSchedulerInternalExpected); + }); it(`convertToJobSchedulerInternal: should return the merge between 'jobSchedulerInternal' and the return from 'convertToPeriodicityInternal'`, () => { const jobSchedulerInternal = { @@ -631,6 +731,42 @@ describe('PoPageJobSchedulerService:', () => { expect(value).toEqual(valueExpected); }); + it('removeInvalidKeys: should set periodicity if periodicity is `single`', () => { + const value: any = { + keyB: 'A', + periodicity: 'single' + }; + + const valueExpected = { + keyB: 'A', + periodicity: 'single' + }; + + const invalidKeys = ['invalidKeyA']; + + poPageJobSchedulerService['removeInvalidKeys'](value, invalidKeys); + + expect(value).toEqual(valueExpected); + }); + + it('removeInvalidKeys: should remove invalid keys if keys is `rangeExecutions` and periodicity is `single`', () => { + const value: any = { + invalidKeyA: 'A', + rangeExecutions: {}, + periodicity: 'single' + }; + + const valueExpected = { + periodicity: 'single' + }; + + const invalidKeys = ['invalidKeyA']; + + poPageJobSchedulerService['removeInvalidKeys'](value, invalidKeys); + + expect(value).toEqual(valueExpected); + }); + it(`replaceHourFirstExecution: should call 'convertDateToIsoExtended'`, () => { spyOn(utilsFunctions, 'convertDateToISOExtended'); diff --git a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.service.ts b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.service.ts index d374bbe814..3ad85f8d63 100644 --- a/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.service.ts +++ b/projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler.service.ts @@ -26,9 +26,9 @@ export class PoPageJobSchedulerService { // Cria um recurso createResource(resource): Observable { - const jobScheduler = this.convertToJobScheduler(resource); + const newResouce = this.convertToJobScheduler(resource); - return this.http.post(`${this.endpoint}`, jobScheduler, { headers: this.headers }); + return this.http.post(`${this.endpoint}`, newResouce, { headers: this.headers }); } getHeadProcesses() { @@ -63,12 +63,11 @@ export class PoPageJobSchedulerService { // Atualiza um recurso updateResource(id, resource): Observable { - const jobScheduler = this.convertToJobScheduler(resource); - - return this.http.put(`${this.endpoint}/${id}`, jobScheduler, { headers: this.headers }); + const newResouce = this.convertToJobScheduler(resource); + return this.http.put(`${this.endpoint}/${id}`, newResouce, { headers: this.headers }); } - private convertToJobScheduler(jobSchedulerInternal): PoJobScheduler { + convertToJobScheduler(jobSchedulerInternal): PoJobScheduler { const jobScheduler = { ...jobSchedulerInternal }; if (jobSchedulerInternal.periodicity) { @@ -86,6 +85,28 @@ export class PoPageJobSchedulerService { ); } + if (jobSchedulerInternal.frequency && jobSchedulerInternal.frequency.type) { + jobScheduler.rangeExecutions = { + frequency: { ...jobSchedulerInternal.frequency } + }; + + if (jobSchedulerInternal.rangeLimitHour) { + const splitRangeLimitHour = jobSchedulerInternal.rangeLimitHour.split(':'); + + jobScheduler.rangeExecutions.rangeLimit = { + hour: parseInt(splitRangeLimitHour[0], 10), + minute: parseInt(splitRangeLimitHour[1], 10) + }; + } + + if (jobSchedulerInternal.rangeLimitDay) { + jobScheduler.rangeExecutions.rangeLimit = { + ...jobScheduler.rangeExecutions.rangeLimit, + day: jobSchedulerInternal.rangeLimitDay + }; + } + } + if (!Object.keys(this.returnValidExecutionParameter(jobScheduler.executionParameter)).length) { delete jobScheduler.executionParameter; } @@ -95,7 +116,7 @@ export class PoPageJobSchedulerService { return jobScheduler; } - private convertToJobSchedulerInternal(jobScheduler = {}): PoJobSchedulerInternal { + convertToJobSchedulerInternal(jobScheduler = {}): PoJobSchedulerInternal { const jobSchedulerInternal = { ...jobScheduler }; if (jobScheduler.firstExecution) { @@ -104,6 +125,23 @@ export class PoPageJobSchedulerService { Object.assign(jobSchedulerInternal, this.convertToPeriodicityInternal(jobScheduler)); + if (jobScheduler.rangeExecutions) { + jobSchedulerInternal.rangeLimitHour = `${ + jobScheduler.rangeExecutions.rangeLimit.hour < 10 + ? '0' + jobScheduler.rangeExecutions.rangeLimit.hour + : jobScheduler.rangeExecutions.rangeLimit.hour + }:${ + jobScheduler.rangeExecutions.rangeLimit.minute < 10 + ? '0' + jobScheduler.rangeExecutions.rangeLimit.minute + : jobScheduler.rangeExecutions.rangeLimit.minute + }`; + jobSchedulerInternal.rangeLimitDay = jobScheduler.rangeExecutions.rangeLimit.day; + jobSchedulerInternal.frequency = { + type: jobScheduler.rangeExecutions.frequency.type, + value: jobScheduler.rangeExecutions.frequency.value + }; + } + this.removeInvalidKeys(jobSchedulerInternal, ['weekly', 'monthly', 'daily']); return jobSchedulerInternal; @@ -178,12 +216,17 @@ export class PoPageJobSchedulerService { 'day', 'daysOfWeek', 'dayOfMonth', - 'firstExecutionHour' + 'firstExecutionHour', + 'frequency', + 'rangeLimitHour', + 'rangeLimitDay' ]; Object.keys(value).forEach(key => { if (invalidKeys.includes(key)) { delete value[key]; + } else if (key === 'rangeExecutions' && value['periodicity'] === 'single') { + delete value[key]; } }); }