Skip to content

Commit b4f84ea

Browse files
authored
HTM-1751: Add time to search-index schedule configuration (#1048)
1 parent 8faff95 commit b4f84ea

File tree

10 files changed

+189
-61
lines changed

10 files changed

+189
-61
lines changed

projects/admin-core/assets/locale/messages.admin-core.de.xlf

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2114,6 +2114,10 @@
21142114
<source>There is no schedule for this search index yet.</source>
21152115
<target>Für diesen Suchindex gibt es noch keinen Zeitplan.</target>
21162116
</trans-unit>
2117+
<trans-unit id="admin-core.search-index.pick-time" datatype="html">
2118+
<source>Pick a time</source>
2119+
<target>Wähle eine Uhrzeit</target>
2120+
</trans-unit>
21172121
<trans-unit id="admin-core.search-index.priority" datatype="html">
21182122
<source>Priority</source>
21192123
<target>Priorität</target>
@@ -2135,20 +2139,20 @@
21352139
<target>Zeitplan</target>
21362140
</trans-unit>
21372141
<trans-unit id="admin-core.search-index.schedule.every-day" datatype="html">
2138-
<source>Every day at 18:00</source>
2139-
<target>Jeden Tag um 18:00 Uhr</target>
2142+
<source>Every day</source>
2143+
<target>Jeden Tag</target>
21402144
</trans-unit>
21412145
<trans-unit id="admin-core.search-index.schedule.every-hour" datatype="html">
21422146
<source>Every hour</source>
21432147
<target>Stündlich</target>
21442148
</trans-unit>
21452149
<trans-unit id="admin-core.search-index.schedule.every-month" datatype="html">
2146-
<source>Every first day of the month at 18:00</source>
2147-
<target>Jeden ersten Tag im Monat um 18:00 Uhr</target>
2150+
<source>Every first day of the month</source>
2151+
<target>Jeden ersten Tag im Monat</target>
21482152
</trans-unit>
21492153
<trans-unit id="admin-core.search-index.schedule.every-week" datatype="html">
2150-
<source>Every week Monday at 18:00</source>
2151-
<target>Jede Woche Montag um 18:00 Uhr</target>
2154+
<source>Every week on monday</source>
2155+
<target>Jede Woche im Montag</target>
21522156
</trans-unit>
21532157
<trans-unit id="admin-core.search-index.schedule.no-schedule" datatype="html">
21542158
<source>No schedule</source>
@@ -2273,10 +2277,6 @@
22732277
<source>last execution succesful</source>
22742278
<target>letzte Ausführung erfolgreich</target>
22752279
</trans-unit>
2276-
<trans-unit id="admin-core.tasks.task-details.cron-expression" datatype="html">
2277-
<source>Cron expression</source>
2278-
<target>Planung (Cron expression)</target>
2279-
</trans-unit>
22802280
<trans-unit id="admin-core.tasks.task-details.description" datatype="html">
22812281
<source>Description</source>
22822282
<target>Beschreibung</target>
@@ -2309,6 +2309,10 @@
23092309
<source>Progress</source>
23102310
<target>Fortschritt</target>
23112311
</trans-unit>
2312+
<trans-unit id="admin-core.tasks.task-details.schedule" datatype="html">
2313+
<source>Schedule</source>
2314+
<target>Zeitplan</target>
2315+
</trans-unit>
23122316
<trans-unit id="admin-core.tasks.task-details.scheduling-state" datatype="html">
23132317
<source>Scheduling state</source>
23142318
<target>Planungsstatus</target>
@@ -2373,6 +2377,10 @@
23732377
<source>Tasks</source>
23742378
<target>Aufgaben</target>
23752379
</trans-unit>
2380+
<trans-unit id="admin-core.tasks.time" datatype="html">
2381+
<source><x id="PH" equiv-text="schedule.viewValue"/> at <x id="PH_1" equiv-text="timeString"/></source>
2382+
<target><x id="PH" equiv-text="schedule.viewValue"/> um <x id="PH_1" equiv-text="timeString"/> Uhr</target>
2383+
</trans-unit>
23762384
<trans-unit id="admin-core.upload-select.delete-file" datatype="html">
23772385
<source>Delete file?</source>
23782386
<target>Datei löschen?</target>

projects/admin-core/assets/locale/messages.admin-core.en.xlf

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,6 +1550,9 @@
15501550
<trans-unit id="admin-core.search-index.no-schedule" datatype="html">
15511551
<source>There is no schedule for this search index yet.</source>
15521552
</trans-unit>
1553+
<trans-unit id="admin-core.search-index.pick-time" datatype="html">
1554+
<source>Pick a time</source>
1555+
</trans-unit>
15531556
<trans-unit id="admin-core.search-index.priority" datatype="html">
15541557
<source>Priority</source>
15551558
</trans-unit>
@@ -1566,16 +1569,16 @@
15661569
<source>Schedule</source>
15671570
</trans-unit>
15681571
<trans-unit id="admin-core.search-index.schedule.every-day" datatype="html">
1569-
<source>Every day at 18:00</source>
1572+
<source>Every day</source>
15701573
</trans-unit>
15711574
<trans-unit id="admin-core.search-index.schedule.every-hour" datatype="html">
15721575
<source>Every hour</source>
15731576
</trans-unit>
15741577
<trans-unit id="admin-core.search-index.schedule.every-month" datatype="html">
1575-
<source>Every first day of the month at 18:00</source>
1578+
<source>Every first day of the month</source>
15761579
</trans-unit>
15771580
<trans-unit id="admin-core.search-index.schedule.every-week" datatype="html">
1578-
<source>Every week Monday at 18:00</source>
1581+
<source>Every week on monday</source>
15791582
</trans-unit>
15801583
<trans-unit id="admin-core.search-index.schedule.no-schedule" datatype="html">
15811584
<source>No schedule</source>
@@ -1670,9 +1673,6 @@
16701673
<trans-unit id="admin-core.tasks.last-execution-successful" datatype="html">
16711674
<source>last execution succesful</source>
16721675
</trans-unit>
1673-
<trans-unit id="admin-core.tasks.task-details.cron-expression" datatype="html">
1674-
<source>Cron expression</source>
1675-
</trans-unit>
16761676
<trans-unit id="admin-core.tasks.task-details.description" datatype="html">
16771677
<source>Description</source>
16781678
</trans-unit>
@@ -1697,6 +1697,9 @@
16971697
<trans-unit id="admin-core.tasks.task-details.progress" datatype="html">
16981698
<source>Progress</source>
16991699
</trans-unit>
1700+
<trans-unit id="admin-core.tasks.task-details.schedule" datatype="html">
1701+
<source>Schedule</source>
1702+
</trans-unit>
17001703
<trans-unit id="admin-core.tasks.task-details.scheduling-state" datatype="html">
17011704
<source>Scheduling state</source>
17021705
</trans-unit>
@@ -1745,6 +1748,9 @@
17451748
<trans-unit id="admin-core.tasks.tasks" datatype="html">
17461749
<source>Tasks</source>
17471750
</trans-unit>
1751+
<trans-unit id="admin-core.tasks.time" datatype="html">
1752+
<source><x id="PH" equiv-text="schedule.viewValue"/> at <x id="PH_1" equiv-text="timeString"/></source>
1753+
</trans-unit>
17481754
<trans-unit id="admin-core.upload-select.delete-file" datatype="html">
17491755
<source>Delete file?</source>
17501756
</trans-unit>

projects/admin-core/assets/locale/messages.admin-core.nl.xlf

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,6 +2097,10 @@
20972097
<source>There is no schedule for this search index yet.</source>
20982098
<target>Er is nog geen planning voor deze zoekindex.</target>
20992099
</trans-unit>
2100+
<trans-unit id="admin-core.search-index.pick-time" datatype="html">
2101+
<source>Pick a time</source>
2102+
<target>Kies een tijd</target>
2103+
</trans-unit>
21002104
<trans-unit id="admin-core.search-index.priority" datatype="html">
21012105
<source>Priority</source>
21022106
<target>Prioriteit</target>
@@ -2118,20 +2122,20 @@
21182122
<target>Planning</target>
21192123
</trans-unit>
21202124
<trans-unit id="admin-core.search-index.schedule.every-day" datatype="html">
2121-
<source>Every day at 18:00</source>
2122-
<target>Elke dag om 18:00</target>
2125+
<source>Every day</source>
2126+
<target>Elke dag</target>
21232127
</trans-unit>
21242128
<trans-unit id="admin-core.search-index.schedule.every-hour" datatype="html">
21252129
<source>Every hour</source>
21262130
<target>Elk uur</target>
21272131
</trans-unit>
21282132
<trans-unit id="admin-core.search-index.schedule.every-month" datatype="html">
2129-
<source>Every first day of the month at 18:00</source>
2130-
<target>Elke eerste dag van de maand om 18:00</target>
2133+
<source>Every first day of the month</source>
2134+
<target>Elke eerste dag van de maand</target>
21312135
</trans-unit>
21322136
<trans-unit id="admin-core.search-index.schedule.every-week" datatype="html">
2133-
<source>Every week Monday at 18:00</source>
2134-
<target>Elke week maandag om 18:00</target>
2137+
<source>Every week on monday</source>
2138+
<target>Elke week op maandag</target>
21352139
</trans-unit>
21362140
<trans-unit id="admin-core.search-index.schedule.no-schedule" datatype="html">
21372141
<source>No schedule</source>
@@ -2257,10 +2261,6 @@
22572261
<source>last execution succesful</source>
22582262
<target>laatste uitvoering succesvol</target>
22592263
</trans-unit>
2260-
<trans-unit id="admin-core.tasks.task-details.cron-expression" datatype="html">
2261-
<source>Cron expression</source>
2262-
<target>Planning (Cron expression)</target>
2263-
</trans-unit>
22642264
<trans-unit id="admin-core.tasks.task-details.description" datatype="html">
22652265
<source>Description</source>
22662266
<target>Beschrijving</target>
@@ -2293,6 +2293,10 @@
22932293
<source>Progress</source>
22942294
<target>Voortgang</target>
22952295
</trans-unit>
2296+
<trans-unit id="admin-core.tasks.task-details.schedule" datatype="html">
2297+
<source>Schedule</source>
2298+
<target>Planning</target>
2299+
</trans-unit>
22962300
<trans-unit id="admin-core.tasks.task-details.scheduling-state" datatype="html">
22972301
<source>Scheduling state</source>
22982302
<target>Planning staat</target>
@@ -2357,6 +2361,10 @@
23572361
<source>Tasks</source>
23582362
<target>Taken</target>
23592363
</trans-unit>
2364+
<trans-unit id="admin-core.tasks.time" datatype="html">
2365+
<source><x id="PH" equiv-text="schedule.viewValue"/> at <x id="PH_1" equiv-text="timeString"/></source>
2366+
<target><x id="PH" equiv-text="schedule.viewValue"/> om <x id="PH_1" equiv-text="timeString"/> uur</target>
2367+
</trans-unit>
23602368
<trans-unit id="admin-core.upload-select.delete-file" datatype="html">
23612369
<source>Delete file?</source>
23622370
<target>Bestand verwijderen?</target>

projects/admin-core/src/lib/search-index/search-index-scheduling/search-index-scheduling.component.css

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
.form-control {
2-
margin-top: 16px;
3-
}
4-
51
.schedule-title {
62
margin-bottom: 16px;
73
}
@@ -37,3 +33,20 @@
3733
margin-top: 16px;
3834
margin-bottom: 3px;
3935
}
36+
37+
.schedule-frequency-and-time {
38+
display: flex;
39+
gap: 16px;
40+
flex-direction: row;
41+
margin-bottom: 16px;
42+
}
43+
44+
.schedule-frequency-field {
45+
flex: 1;
46+
}
47+
48+
.time-picker-field {
49+
margin-top: 0;
50+
flex: 0 0 150px;
51+
}
52+

projects/admin-core/src/lib/search-index/search-index-scheduling/search-index-scheduling.component.html

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,30 @@ <h2 class="schedule-title" i18n="@@admin-core.search-index.schedule">Schedule</h
1414
</div>
1515

1616
<form [formGroup]="scheduleForm">
17-
<mat-form-field>
18-
<mat-label>Schedule</mat-label>
19-
<mat-select formControlName="cronExpression">
20-
@for (option of scheduleOptions; track $index) {
21-
<mat-option
22-
[value]="option.cronExpression"
23-
[disabled]="option.cronExpression === '' && taskSchedule?.uuid">
24-
{{ option.viewValue }}
25-
</mat-option>
26-
}
27-
</mat-select>
28-
</mat-form-field>
29-
@if (scheduleForm.value.cronExpression) {
17+
<div class="schedule-frequency-and-time">
18+
<mat-form-field class="schedule-frequency-field">
19+
<mat-label i18n="@@admin-core.search-index.schedule">Schedule</mat-label>
20+
<mat-select formControlName="partialCronExpression">
21+
@for (option of scheduleOptions; track $index) {
22+
<mat-option
23+
[value]="option.cronExpression"
24+
[disabled]="option.cronExpression === '' && taskSchedule?.uuid">
25+
{{ option.viewValue }}
26+
</mat-option>
27+
}
28+
</mat-select>
29+
</mat-form-field>
30+
@if (!(scheduleForm.get('partialCronExpression')?.value === hourlyCronExpression
31+
|| scheduleForm.get('partialCronExpression')?.value === '')) {
32+
<mat-form-field class="time-picker-field">
33+
<mat-label i18n="@@admin-core.search-index.pick-time">Pick a time</mat-label>
34+
<input matInput formControlName="time" [matTimepicker]="picker">
35+
<mat-timepicker-toggle matIconSuffix [for]="picker"/>
36+
<mat-timepicker #picker/>
37+
</mat-form-field>
38+
}
39+
</div>
40+
@if (scheduleForm.value.partialCronExpression) {
3041
<mat-form-field>
3142
<mat-label i18n="@@admin-core.common.description">Description</mat-label>
3243
<input matInput

projects/admin-core/src/lib/search-index/search-index-scheduling/search-index-scheduling.component.ts

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import { Component, OnInit, ChangeDetectionStrategy, Output, EventEmitter, DestroyRef, Input, inject } from '@angular/core';
1+
import { Component, OnInit, ChangeDetectionStrategy, Output, EventEmitter, DestroyRef, Input, inject, LOCALE_ID } from '@angular/core';
22
import { FormControl, FormGroup, Validators } from '@angular/forms';
33
import { SearchIndexModel, TaskSchedule } from '@tailormap-admin/admin-api';
44
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
55
import { debounceTime, distinctUntilChanged, filter, map } from 'rxjs';
66
import { FormHelper } from '../../helpers/form.helper';
7+
import { DateAdapter } from '@angular/material/core';
8+
import { CronExpressionHelper } from '../../tasks/helpers/cron-expression.helper';
79

810
@Component({
911
selector: 'tm-admin-search-index-scheduling',
@@ -14,8 +16,10 @@ import { FormHelper } from '../../helpers/form.helper';
1416
})
1517
export class SearchIndexSchedulingComponent implements OnInit {
1618
private destroyRef = inject(DestroyRef);
19+
private locale = inject(LOCALE_ID);
1720

1821

22+
private readonly _adapter = inject<DateAdapter<unknown, unknown>>(DateAdapter);
1923
public taskSchedule: TaskSchedule | undefined = undefined;
2024

2125
@Input({ required: true })
@@ -30,16 +34,12 @@ export class SearchIndexSchedulingComponent implements OnInit {
3034
@Output()
3135
public formChanged = new EventEmitter<boolean>();
3236

33-
public scheduleOptions = [
34-
{ cronExpression: '', viewValue: $localize `:@@admin-core.search-index.schedule.no-schedule:No schedule` },
35-
{ cronExpression: '0 0 0/1 1/1 * ? *', viewValue: $localize `:@@admin-core.search-index.schedule.every-hour:Every hour` },
36-
{ cronExpression: '0 0 18 1/1 * ? *', viewValue: $localize `:@@admin-core.search-index.schedule.every-day:Every day at 18:00` },
37-
{ cronExpression: '0 0 18 ? * MON *', viewValue: $localize `:@@admin-core.search-index.schedule.every-week:Every week Monday at 18:00` },
38-
{ cronExpression: '0 0 18 1 * ? *', viewValue: $localize `:@@admin-core.search-index.schedule.every-month:Every first day of the month at 18:00` },
39-
];
37+
public hourlyCronExpression = CronExpressionHelper.HOURLY_CRON_EXPRESSION;
38+
public scheduleOptions = CronExpressionHelper.SCHEDULE_OPTIONS;
4039

4140
public scheduleForm = new FormGroup({
42-
cronExpression: new FormControl('', { nonNullable: true }),
41+
partialCronExpression: new FormControl('', { nonNullable: true }),
42+
time: new FormControl<Date | null>(null, { nonNullable: true }),
4343
description: new FormControl('', {
4444
nonNullable: true,
4545
validators: [Validators.required],
@@ -48,6 +48,7 @@ export class SearchIndexSchedulingComponent implements OnInit {
4848
});
4949

5050
public ngOnInit(): void {
51+
this._adapter.setLocale(this.locale);
5152
const scheduleFormChanges$ = this.scheduleForm.valueChanges.pipe(
5253
takeUntilDestroyed(this.destroyRef),
5354
debounceTime(250),
@@ -66,10 +67,14 @@ export class SearchIndexSchedulingComponent implements OnInit {
6667
)
6768
.subscribe(value => {
6869
let schedule: TaskSchedule | undefined = undefined;
69-
if (value.cronExpression) {
70+
if (value.partialCronExpression) {
71+
const timePart = value.time ? this.timeToPartialCronExpression(value.time) : '0 0 6 ';
72+
const cronExpression = value.partialCronExpression === CronExpressionHelper.HOURLY_CRON_EXPRESSION
73+
? value.partialCronExpression
74+
: timePart + value.partialCronExpression;
7075
schedule = {
7176
...this.taskSchedule,
72-
cronExpression: value.cronExpression,
77+
cronExpression: cronExpression,
7378
description: value.description,
7479
priority: value.priority,
7580
};
@@ -84,13 +89,22 @@ export class SearchIndexSchedulingComponent implements OnInit {
8489
private initForm(schedule: TaskSchedule | undefined, searchIndexName?: string) {
8590
const preFillDescription: string = $localize `:@@admin-core.search-index.schedule.prefill-description:Update ${searchIndexName}`;
8691
if (!schedule) {
87-
this.scheduleForm.patchValue({ cronExpression: '', description: preFillDescription, priority: undefined }, { emitEvent: false });
92+
const time = new Date();
93+
time.setHours(6, 0, 0);
94+
this.scheduleForm.patchValue({
95+
partialCronExpression: '',
96+
time: time,
97+
description: preFillDescription,
98+
priority: undefined,
99+
}, { emitEvent: false });
88100
} else {
89-
if (!this.scheduleOptions.some(option => option.cronExpression === schedule.cronExpression)) {
101+
const { time, partialCronExpression } = CronExpressionHelper.splitCronExpression(schedule.cronExpression);
102+
if (!this.scheduleOptions.some(option => option.cronExpression === partialCronExpression)) {
90103
this.scheduleOptions.push({ cronExpression: schedule.cronExpression, viewValue: schedule.cronExpression });
91104
}
92105
this.scheduleForm.patchValue({
93-
cronExpression: schedule.cronExpression,
106+
partialCronExpression: partialCronExpression,
107+
time: time,
94108
description: schedule.description || preFillDescription,
95109
priority: schedule.priority,
96110
}, { emitEvent: false });
@@ -104,4 +118,11 @@ export class SearchIndexSchedulingComponent implements OnInit {
104118
&& this.scheduleForm.valid;
105119
}
106120

121+
private timeToPartialCronExpression(time: Date): string {
122+
const timeDateObject = new Date(time);
123+
const minutes = isNaN(timeDateObject.getMinutes()) ? 0 : timeDateObject.getMinutes();
124+
const hours = isNaN(timeDateObject.getHours()) ? 6 : timeDateObject.getHours();
125+
return `0 ${minutes} ${hours} `;
126+
}
127+
107128
}

0 commit comments

Comments
 (0)