Skip to content
This repository was archived by the owner on May 14, 2025. It is now read-only.

Commit e338366

Browse files
oodamienghillert
authored andcommitted
Schedules
+ Add Schedule List + Add Schedule Details + Add support for multiple-schedules per each Task + Integrate Scheduling workflows in Task List Resolve #810, #811, #812, #813
1 parent 11b4a42 commit e338366

File tree

67 files changed

+4643
-525
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+4643
-525
lines changed

ui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"@angular/platform-browser": "5.2.9",
3232
"@angular/platform-browser-dynamic": "5.2.9",
3333
"@angular/router": "5.2.9",
34+
"angular-2-local-storage": "2.0.0",
3435
"core-js": "2.5.3",
3536
"rxjs": "5.5.7",
3637
"zone.js": "0.8.20",

ui/src/app/about/components/about-more/about-details.component.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ <h2>Enabled Features</h2>
4141
<span class="fa fa-close"></span>
4242
</strong>
4343
</div>
44+
<div class="line">
45+
<span>Schedules:</span>
46+
<strong *ngIf="dataflowVersionInfo.featureInfo.schedulerEnabled" id="schedulerEnabled">
47+
<span class="fa fa-check"></span>
48+
</strong>
49+
<strong *ngIf="!dataflowVersionInfo.featureInfo.schedulerEnabled" id="schedulerDisabled">
50+
<span class="fa fa-close"></span>
51+
</strong>
52+
</div>
4453
<div class="line">
4554
<span>Skipper Mode:</span>
4655
<strong *ngIf="dataflowVersionInfo.featureInfo.skipperEnabled" id="skipperEnabled">

ui/src/app/about/components/about-more/about-details.component.spec.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { MockActivatedRoute } from '../../../tests/mocks/activated-route';
55
import { ActivatedRoute } from '@angular/router';
66
import { MockAboutService } from '../../../tests/mocks/about';
77
import { AboutService } from '../../about.service';
8-
import { DebugElement } from '@angular/core';
98
import { By } from '@angular/platform-browser';
109
import { RouterTestingModule } from '@angular/router/testing';
1110
import { AboutDetailsComponent } from './about-details.component';
@@ -59,8 +58,8 @@ describe('AboutDetailsComponent', () => {
5958
expect(component).toBeTruthy();
6059

6160
// Verify Enabled Features
62-
validateColumnValues('enabledFeaturesTable', ['Analytics', 'Streams', 'Tasks', 'Skipper Mode'], 0);
63-
validateSpansExists(['analyticsEnabled', 'streamsEnabled', 'tasksEnabled', 'skipperEnabled']);
61+
validateColumnValues('enabledFeaturesTable', ['Analytics', 'Streams', 'Tasks', 'Schedules', 'Skipper Mode'], 0);
62+
validateSpansExists(['analyticsEnabled', 'streamsEnabled', 'tasksEnabled', 'schedulerEnabled', 'skipperEnabled']);
6463

6564
// Verify Security Information
6665
validateColumnValues('securityInformationTable', ['Authentication', 'Authorization',
@@ -106,8 +105,8 @@ describe('AboutDetailsComponent', () => {
106105
expect(component).toBeTruthy();
107106

108107
// Verify Enabled Features
109-
validateColumnValues('enabledFeaturesTable', ['Analytics', 'Streams', 'Tasks', 'Skipper Mode'], 0);
110-
validateSpansExists(['analyticsDisabled', 'streamsDisabled', 'tasksDisabled', 'skipperDisabled']);
108+
validateColumnValues('enabledFeaturesTable', ['Analytics', 'Streams', 'Tasks', 'Schedules', 'Skipper Mode'], 0);
109+
validateSpansExists(['analyticsDisabled', 'streamsDisabled', 'tasksDisabled', 'schedulerDisabled', 'skipperDisabled']);
111110

112111
// Verify Security Information
113112
validateColumnValues('securityInformationTable', ['Authentication', 'Authorization',

ui/src/app/apps/apps/apps.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ <h1>Apps</h1>
164164
</div>
165165
<div class="col-xs-12" *ngIf="appRegistrations && appRegistrations?.totalElements > 0">
166166
<app-pager [page]="params.page" [total]="appRegistrations.totalElements" [size]="params.size"
167-
(onSizeChange)="changeSize($event)">
167+
(sizeChange)="changeSize($event)">
168168
</app-pager>
169169
</div>
170170
</div>

ui/src/app/jobs/jobs/jobs.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ <h1>Batch Job Executions</h1>
7979
</div>
8080
<div class="col-xs-12" *ngIf="jobExecutions && jobExecutions?.totalElements > 0">
8181
<app-pager [page]="params.page" [total]="jobExecutions.totalElements" [size]="params.size"
82-
(onSizeChange)="changeSize($event)">
82+
(sizeChange)="changeSize($event)">
8383
</app-pager>
8484
</div>
8585
</div>

ui/src/app/runtime/runtime-apps/runtime-apps.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ <h1>Runtime applications</h1>
7272
</div>
7373
<div class="col-xs-12" *ngIf="runtimeApps && runtimeApps?.totalElements > 0">
7474
<app-pager [page]="pagination.page" [total]="runtimeApps.totalElements" [size]="pagination.size"
75-
(onSizeChange)="changeSize($event)">
75+
(sizeChange)="changeSize($event)">
7676
</app-pager>
7777
</div>
7878
</div>

ui/src/app/shared/components/pager/pager.component.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
</button>
2323
<ul class="dropdown-menu dropdown-menu-up" id="dropdown-basic" *dropdownMenu>
2424
<li *ngFor="let s of SIZE_LIST" [class.active]="s === size">
25-
<a (click)="sizeChange(s)" class="dropdown-item">{{ s }}</a>
25+
<a (click)="doSizeChange(s)" class="dropdown-item">{{ s }}</a>
2626
</li>
2727
</ul>
2828
</div>
@@ -44,7 +44,7 @@ export class PagerComponent implements OnChanges {
4444

4545
@Input() size: number;
4646

47-
@Output() onSizeChange = new EventEmitter<number>();
47+
@Output() sizeChange = new EventEmitter<number>();
4848

4949
values = {
5050
from: 0,
@@ -76,8 +76,8 @@ export class PagerComponent implements OnChanges {
7676
}
7777
}
7878

79-
sizeChange(size) {
80-
this.onSizeChange.emit(size);
79+
doSizeChange(size) {
80+
this.sizeChange.emit(size);
8181
}
8282

8383
}

ui/src/app/shared/components/timepicker/styles.scss

Whitespace-only changes.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { Component, forwardRef, ViewChild } from '@angular/core';
2+
import { NG_VALUE_ACCESSOR, FormControl } from '@angular/forms';
3+
import * as moment from 'moment';
4+
import { TimepickerValidator } from './timepicker.validator';
5+
6+
export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
7+
provide: NG_VALUE_ACCESSOR,
8+
useExisting: forwardRef(() => TimepickerComponent),
9+
multi: true
10+
};
11+
12+
@Component({
13+
selector: 'app-dataflow-timepicker',
14+
styleUrls: ['./styles.scss'],
15+
template: `
16+
<div class="form-control-timepicker">
17+
<input placeholder="HH:MM:SS" [(ngModel)]="value" [popover]="popTemplate" [outsideClick]="true" placement="bottom"
18+
containerClass="popover-timepicker" class="form-control input-sm input-time" #pop="bs-popover"
19+
(onShown)="onShown()">
20+
<span (click)="show()" class="timepicker-icon fa fa-clock-o"></span>
21+
<ng-template #popTemplate>
22+
<timepicker [(ngModel)]="currentValue" showSeconds="true" [showMeridian]="false" [hourStep]="1" [minuteStep]="1"
23+
[secondsStep]="1" (ngModelChange)="changedCurrentValue()"></timepicker>
24+
</ng-template>
25+
</div>
26+
`,
27+
providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
28+
})
29+
export class TimepickerComponent {
30+
31+
@ViewChild('pop') popover;
32+
33+
private valueProp: any = '';
34+
35+
private currentValue;
36+
37+
private isNull = true;
38+
39+
get value(): any {
40+
return this.valueProp;
41+
}
42+
43+
set value(val: any) {
44+
if (val !== this.valueProp) {
45+
this.valueProp = val;
46+
}
47+
}
48+
49+
show() {
50+
this.popover.show();
51+
}
52+
53+
onShown() {
54+
let setDefault = false;
55+
this.isNull = !(this.value && this.value.toString() !== '');
56+
if (!this.isNull) {
57+
if (TimepickerValidator.time(new FormControl(this.value))) {
58+
setDefault = true;
59+
this.isNull = true;
60+
} else {
61+
this.currentValue = moment(this.value, 'HH:mm:ss')
62+
.toDate();
63+
}
64+
} else {
65+
setDefault = true;
66+
}
67+
68+
if (setDefault) {
69+
this.currentValue = moment(new Date())
70+
.hours(12)
71+
.minutes(0)
72+
.seconds(0)
73+
.toDate();
74+
}
75+
}
76+
77+
writeValue(value: any) {
78+
this.valueProp = value;
79+
}
80+
81+
changedCurrentValue() {
82+
if (this.currentValue) {
83+
const date = moment(this.currentValue);
84+
const val = `${date.format('HH')}:${date.format('mm')}:${date.format('ss')}`;
85+
if (this.isNull && val === '12:00:00') {
86+
this.writeValue(null);
87+
} else {
88+
this.writeValue(val);
89+
}
90+
} else {
91+
this.writeValue(null);
92+
}
93+
}
94+
95+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { FormControl } from '@angular/forms';
2+
3+
/**
4+
* Validators for Timepicker Component
5+
* Static methods
6+
*
7+
* @author Damien Vitrac
8+
*/
9+
export class TimepickerValidator {
10+
11+
/**
12+
* Uri time
13+
*/
14+
static uriTimeRegex = /^(?:(?:([01]?\d|2[0-3]):)([0-5]?\d):)([0-5]?\d)$/;
15+
16+
17+
/**
18+
* Validate the name conditions: no space, 2 characters min, no specials characters
19+
*
20+
* @param {FormControl} formControl
21+
* @returns {any}
22+
*/
23+
static time(formControl: FormControl): any {
24+
if (!formControl.value) {
25+
return null;
26+
}
27+
if (!TimepickerValidator.uriTimeRegex.test(formControl.value)) {
28+
return { invalid: true };
29+
}
30+
return null;
31+
}
32+
33+
}

0 commit comments

Comments
 (0)