Skip to content

Commit de052f7

Browse files
jhonyeduardoalinelariguet
authored andcommitted
feat(page-job-scheduler): permite configuração da frequência
Permite configuração da frequência no componente PoPageJobScheduler. Fixes DTHFUI-5526
1 parent fc49645 commit de052f7

13 files changed

+635
-45
lines changed

projects/templates/src/lib/components/po-page-job-scheduler/interfaces/po-job-scheduler-internal.interface.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
export interface PoJobSchedulerInternal {
22
dayOfMonth?: number;
33

4+
frequency?: object;
5+
6+
rangeLimitHour?: string;
7+
8+
rangeLimitDay?: number;
9+
410
daysOfWeek?: Array<string>;
511

612
executionParameter?: object;

projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-base.component.spec.ts

+29
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,36 @@ describe('PoPageJobSchedulerBaseComponent:', () => {
3030
expect(component).toBeTruthy();
3131
});
3232

33+
describe('Properties:', () => {
34+
it('value: should set `model`', fakeAsync(() => {
35+
const returnValue: PoJobSchedulerInternal = {
36+
firstExecution: new Date('2019-02-04'),
37+
firstExecutionHour: '06:45',
38+
periodicity: 'single',
39+
recurrent: true
40+
};
41+
const jobSchedulerInternal = {
42+
firstExecution: new Date('2019-02-04'),
43+
periodicity: 'single',
44+
recurrent: true
45+
};
46+
47+
spyOn(component['poPageJobSchedulerService'], 'convertToJobSchedulerInternal').and.returnValue(returnValue);
48+
component.value = jobSchedulerInternal;
49+
50+
expect(component.model).toEqual(returnValue);
51+
}));
52+
});
53+
3354
describe('Methods:', () => {
55+
it('ngOnDestroy: should call unsubscribe', () => {
56+
const spyUnsubscribe = spyOn(component['_subscription'], 'unsubscribe');
57+
58+
component.ngOnDestroy();
59+
60+
expect(spyUnsubscribe).toHaveBeenCalled();
61+
});
62+
3463
it('loadData: should set `model` with `new PoPageJobSchedulerInternal()` and exit of method if `id` is invalid.', () => {
3564
const invalidId = 0;
3665
component.model = undefined;

projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-base.component.ts

+14-6
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export class PoPageJobSchedulerBaseComponent implements OnDestroy {
5959
* ```
6060
*
6161
* > Veja mais sobre paginação e filtros no [Guia de implementação de APIs](guides/api).
62+
* Caso seja informada a propriedade `p-parameters` não serão realizadas as requisições de processos e nem de parametros automaticamente.
6263
*
6364
* Também é possível fazer um agendamento de um processo específico, sem que seja necessário um endpoint para busca desses
6465
* 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 {
112113
* {
113114
* "firstExecution": "2018-12-07T00:00:01-00:00",
114115
* "recurrent": true,
115-
* "daily": { "hour": 10, "minute": 12 },
116-
* "processID": "ac0405"
116+
* "monthly": { "day": 1, "hour": 10, "minute": 0 },
117+
* "processID": "ac0405",
118+
* "rangeExecutions: { "frequency": { "type": "hour", "value": 2 }, "rangeLimit": { "hour": 18, "minute": 0, "day": 20 } }
117119
* }
118120
* ```
119121
*
@@ -147,9 +149,11 @@ export class PoPageJobSchedulerBaseComponent implements OnDestroy {
147149
* ```
148150
* {
149151
* "firstExecution": "2018-12-07T00:00:01-00:00",
150-
* "recurrent": false,
151-
* "daily": { "hour": 11, "minute": 30 },
152-
* "processID": "ac0405"
152+
* "recurrent": true,
153+
* "processID": "ac0405",
154+
* "monthly": { "day": 1, "hour": 10, "minute": 0 },
155+
* "processID": "ac0405",
156+
* "rangeExecutions: { "frequency": { "type": "hour", "value": 2 }, "rangeLimit": { "hour": 18, "minute": 0, "day": 20 } }
153157
* }
154158
* ```
155159
*/
@@ -166,6 +170,10 @@ export class PoPageJobSchedulerBaseComponent implements OnDestroy {
166170
*/
167171
@Input('p-parameters') parameters: Array<PoDynamicFormField> = [];
168172

173+
@Input('p-value') set value(value: any) {
174+
this.model = this.poPageJobSchedulerService.convertToJobSchedulerInternal(value);
175+
}
176+
169177
model: PoJobSchedulerInternal = new PoPageJobSchedulerInternal();
170178

171179
private _subscription = new Subscription();
@@ -178,7 +186,7 @@ export class PoPageJobSchedulerBaseComponent implements OnDestroy {
178186

179187
protected loadData(id: string | number) {
180188
if (!id) {
181-
this.model = new PoPageJobSchedulerInternal();
189+
this.model = this.model || new PoPageJobSchedulerInternal();
182190
return;
183191
}
184192

projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.html

+59-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
p-placeholder="HH:mm"
2828
p-required
2929
[p-disabled]="isEdit"
30-
[p-label]="literals.hour"
30+
[p-label]="literals.time"
3131
[p-pattern]="timePattern"
3232
>
3333
</po-input>
@@ -44,13 +44,41 @@
4444
p-required
4545
[p-label]="literals.periodicity"
4646
[p-options]="periodicityOptions"
47+
(p-change)="onChangePeriodicityOptions($event)"
4748
>
4849
</po-radio-group>
4950

5051
<ng-container *ngIf="value.periodicity !== 'single'">
51-
<po-divider class="po-md-12" [p-label]="literals.periodicityData"> </po-divider>
52+
<div class="po-row">
53+
<po-switch
54+
class="po-md-12"
55+
name="containsFrequency"
56+
[(ngModel)]="containsFrequency"
57+
[p-label]="literals.frequency"
58+
[p-label-off]="literals.no"
59+
[p-label-on]="literals.yes"
60+
(p-change)="onChangeContainsFrequency($event)"
61+
>
62+
</po-switch>
63+
<ng-container *ngIf="containsFrequency">
64+
<po-radio-group
65+
class="po-md-10"
66+
name="frequencyType"
67+
p-required
68+
[(ngModel)]="value.frequency.type"
69+
[p-columns]="3"
70+
[p-options]="frequencyOptions"
71+
(p-change)="onChangeFrequencyOptions()"
72+
>
73+
</po-radio-group>
74+
75+
<po-number class="po-md-2" name="frequencyValue" p-required [(ngModel)]="value.frequency.value"> </po-number>
76+
</ng-container>
77+
</div>
5278

5379
<div class="po-row">
80+
<po-divider class="po-md-12" [p-label]="literals.periodicityData"> </po-divider>
81+
5482
<ng-container *ngTemplateOutlet="periodicityTemplates[value.periodicity]"> </ng-container>
5583
</div>
5684

@@ -126,7 +154,20 @@
126154
[(ngModel)]="value.dayOfMonth"
127155
p-required
128156
[p-error-pattern]="'Dia inválido'"
129-
[p-label]="literals.day"
157+
[p-label]="dayLabel"
158+
[p-max]="31"
159+
[p-pattern]="dayPattern"
160+
>
161+
</po-number>
162+
163+
<po-number
164+
*ngIf="containsFrequency"
165+
class="po-md-3"
166+
name="rangeLimitDay"
167+
[(ngModel)]="value.rangeLimitDay"
168+
p-required
169+
[p-error-pattern]="'Dia inválido'"
170+
[p-label]="literals.endDay"
130171
[p-max]="31"
131172
[p-pattern]="dayPattern"
132173
>
@@ -144,7 +185,21 @@
144185
p-mask-format-model
145186
p-placeholder="HH:mm"
146187
p-required
147-
[p-label]="literals.hour"
188+
[p-label]="hourLabel"
189+
[p-pattern]="timePattern"
190+
>
191+
</po-input>
192+
193+
<po-input
194+
*ngIf="containsFrequency && value.frequency.type !== 'day'"
195+
class="po-md-2"
196+
name="rangeLimitHour"
197+
[(ngModel)]="value.rangeLimitHour"
198+
p-mask="99:99"
199+
p-mask-format-model
200+
p-placeholder="HH:mm"
201+
p-required
202+
[p-label]="literals.endTime"
148203
[p-pattern]="timePattern"
149204
>
150205
</po-input>

projects/templates/src/lib/components/po-page-job-scheduler/po-page-job-scheduler-execution/po-page-job-scheduler-execution.component.spec.ts

+133
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ describe('PoPageJobSchedulerExecutionComponent:', () => {
4949
expectPropertiesValues(component, 'value', validValues, validValues);
5050
});
5151

52+
it('value: should set `containsFrequency` with true if value.frequency.value', () => {
53+
component.value = { frequency: { value: 2 } };
54+
55+
expect(component.containsFrequency).toBeTrue();
56+
});
57+
58+
it('value: should set `containsFrequency` with false if value.frequency.value is undefined', () => {
59+
component.value = { frequency: undefined };
60+
61+
expect(component.containsFrequency).toBeFalse();
62+
});
63+
5264
it('startDateFirstExecution: should return `Date` if `isEdit` is false', () => {
5365
component.isEdit = false;
5466

@@ -61,6 +73,30 @@ describe('PoPageJobSchedulerExecutionComponent:', () => {
6173
expect(component.startDateFirstExecution instanceof Date).toBe(false);
6274
expect(component.startDateFirstExecution).toBeUndefined();
6375
});
76+
77+
it('hourLabel: should return `literals.startTime` if `containsFrequency`', () => {
78+
component.containsFrequency = true;
79+
const result = component.hourLabel;
80+
expect(result).toEqual(component.literals.startTime);
81+
});
82+
83+
it('hourLabel: should return `literals.time` if `containsFrequency` is false', () => {
84+
component.containsFrequency = false;
85+
const result = component.hourLabel;
86+
expect(result).toEqual(component.literals.time);
87+
});
88+
89+
it('dayLabel: should return `literals.startDay` if `containsFrequency`', () => {
90+
component.containsFrequency = true;
91+
const result = component.dayLabel;
92+
expect(result).toEqual(component.literals.startDay);
93+
});
94+
95+
it('dayLabel: should return `literals.day` if `containsFrequency` is false', () => {
96+
component.containsFrequency = false;
97+
const result = component.dayLabel;
98+
expect(result).toEqual(component.literals.day);
99+
});
64100
});
65101

66102
describe('Methods:', () => {
@@ -74,24 +110,58 @@ describe('PoPageJobSchedulerExecutionComponent:', () => {
74110
expect(component['subscribeProcessIdValueChanges']).toHaveBeenCalled();
75111
}));
76112

113+
it('ngAfterViewInit: should update `frequencyOption.disabled` if `frequencyOption.value` is equal to `day`', fakeAsync(() => {
114+
component.value.periodicity = 'daily';
115+
component.frequencyOptions = [
116+
{ label: 'Day', value: 'day' },
117+
{ label: 'Hour', value: 'hour' },
118+
{ label: 'minute', value: 'minute' }
119+
];
120+
const expectedValue = [
121+
{ label: 'Day', value: 'day', disabled: true },
122+
{ label: 'Hour', value: 'hour', disabled: false },
123+
{ label: 'minute', value: 'minute', disabled: false }
124+
];
125+
126+
component.ngAfterViewInit();
127+
128+
tick(50);
129+
130+
expect(component.frequencyOptions).toEqual(expectedValue);
131+
}));
132+
77133
it('ngOnInit: should call `checkExistsProcessesAPI` and set `periodicityTemplates`, `periodicityOptions` and `weekDays`', () => {
78134
component.periodicityTemplates = undefined;
79135
component.periodicityOptions = undefined;
136+
component.frequencyOptions = undefined;
80137
component.weekDays = undefined;
81138

82139
spyOn(component, <any>'checkExistsProcessesAPI');
83140
spyOn(component, <any>'getPeriodicityOptions').and.callThrough();
84141
spyOn(component, <any>'getWeekDays').and.callThrough();
142+
spyOn(component, <any>'getFrequencyOptions').and.callThrough();
85143

86144
component.ngOnInit();
87145

88146
expect(typeof component.periodicityTemplates === 'object').toBe(true);
89147
expect(component.periodicityOptions instanceof Array).toBe(true);
90148
expect(component.weekDays instanceof Array).toBe(true);
149+
expect(component.frequencyOptions instanceof Array).toBe(true);
91150

92151
expect(component['checkExistsProcessesAPI']).toHaveBeenCalled();
93152
expect(component['getPeriodicityOptions']).toHaveBeenCalled();
94153
expect(component['getWeekDays']).toHaveBeenCalled();
154+
expect(component['getFrequencyOptions']).toHaveBeenCalled();
155+
});
156+
157+
it('ngOnInit: shouldn`t call `checkExistsProcessesAPI` if `noParameters` is false', () => {
158+
component.noParameters = false;
159+
160+
spyOn(component, <any>'checkExistsProcessesAPI');
161+
162+
component.ngOnInit();
163+
164+
expect(component['checkExistsProcessesAPI']).not.toHaveBeenCalled();
95165
});
96166

97167
it('checkExistsProcessesAPI: should subscribe `getHeadProcesses` and on error set `existProcessAPI` to false', () => {
@@ -126,6 +196,15 @@ describe('PoPageJobSchedulerExecutionComponent:', () => {
126196
expect(weekDays.length).toBe(weekDaysLength);
127197
});
128198

199+
it('getFrequencyOptions: should return 3 options', () => {
200+
const frequencyOptionsLength = 3;
201+
202+
const frequencyOptions = component['getFrequencyOptions']();
203+
204+
expect(frequencyOptions instanceof Array).toBe(true);
205+
expect(frequencyOptions.length).toBe(frequencyOptionsLength);
206+
});
207+
129208
it('subscribeProcessIdValueChanges: should call `changeProcess.emit` when subscribe `processID.valueChanges`', () => {
130209
const processId = 1;
131210
component['form'] = <any>{
@@ -144,6 +223,60 @@ describe('PoPageJobSchedulerExecutionComponent:', () => {
144223
expect(component['form'].controls.processID.valueChanges.subscribe).toHaveBeenCalled();
145224
expect(component.changeProcess.emit).toHaveBeenCalledWith({ processId, existAPI: component.existProcessAPI });
146225
});
226+
227+
it('changeContainsFrequency: should update `value.frequency` if `containsfrequency`', () => {
228+
const containsFrequency = true;
229+
const expectedValue = { type: 'hour', value: null };
230+
231+
component.onChangeContainsFrequency(containsFrequency);
232+
233+
expect(component.value.frequency).toEqual(expectedValue);
234+
});
235+
236+
it('changeContainsFrequency: should update `value.frequency` with empty object if `containsfrequency` is false', () => {
237+
const containsFrequency = false;
238+
const expectedValue = {};
239+
240+
component.onChangeContainsFrequency(containsFrequency);
241+
242+
expect(component.value.frequency).toEqual(expectedValue);
243+
});
244+
245+
it('changeContainsFrequency: should update `value.rangeLimitHour`, `value.rangeLimitDay` and `value.dayOfMonth` with null', () => {
246+
const containsFrequency = false;
247+
248+
component.onChangeContainsFrequency(containsFrequency);
249+
250+
expect(component.value.rangeLimitHour).toBeNull();
251+
expect(component.value.rangeLimitDay).toBeNull();
252+
expect(component.value.dayOfMonth).toBeNull();
253+
});
254+
255+
it('onChangePeriodicityOptions: should update `frequencyOptions` and `value.frequency.type`', () => {
256+
const periodicity = 'daily';
257+
component.value.frequency = {};
258+
component.frequencyOptions = [
259+
{ label: 'Day', value: 'day' },
260+
{ label: 'Hour', value: 'hour' },
261+
{ label: 'minute', value: 'minute' }
262+
];
263+
const expectedValue = [
264+
{ label: 'Day', value: 'day', disabled: true },
265+
{ label: 'Hour', value: 'hour', disabled: false },
266+
{ label: 'minute', value: 'minute', disabled: false }
267+
];
268+
269+
component.onChangePeriodicityOptions(periodicity);
270+
271+
expect(component.frequencyOptions).toEqual(expectedValue);
272+
expect(component.value.frequency.type).toBeNull();
273+
});
274+
275+
it('onChangeFrequencyOptions: should update `value.rangeLimitHour` with `null`', () => {
276+
component.onChangeFrequencyOptions();
277+
278+
expect(component.value.rangeLimitHour).toBeNull();
279+
});
147280
});
148281

149282
describe('Templates:', () => {

0 commit comments

Comments
 (0)