You've already forked pigallery2
mirror of
https://github.com/bpatrik/pigallery2.git
synced 2025-07-05 00:48:51 +02:00
291 lines
8.0 KiB
TypeScript
291 lines
8.0 KiB
TypeScript
import {Component, OnDestroy, OnInit, QueryList, ViewChildren} from '@angular/core';
|
|
import {forwardRef} from '../../../../../../node_modules/@angular/core';
|
|
import {ModalDirective} from 'ngx-bootstrap/modal';
|
|
import {
|
|
AfterJobTrigger,
|
|
JobScheduleDTO,
|
|
JobScheduleDTOUtils,
|
|
JobTriggerType,
|
|
ScheduledJobTrigger
|
|
} from '../../../../../common/entities/job/JobScheduleDTO';
|
|
import {ScheduledJobsService} from '../scheduled-jobs.service';
|
|
import {BackendtextService} from '../../../model/backendtext.service';
|
|
import {SettingsService} from '../settings.service';
|
|
import {ConfigTemplateEntry} from '../../../../../common/entities/job/JobDTO';
|
|
import {JobProgressDTO, JobProgressStates} from '../../../../../common/entities/job/JobProgressDTO';
|
|
import {
|
|
AfterJobTriggerConfig,
|
|
JobScheduleConfig,
|
|
NeverJobTriggerConfig,
|
|
PeriodicJobTriggerConfig,
|
|
ScheduledJobTriggerConfig
|
|
} from '../../../../../common/config/private/PrivateConfig';
|
|
import {
|
|
ControlValueAccessor,
|
|
NG_VALIDATORS,
|
|
NG_VALUE_ACCESSOR,
|
|
ValidationErrors,
|
|
Validator
|
|
} from '../../../../../../node_modules/@angular/forms';
|
|
|
|
@Component({
|
|
selector: 'app-settings-workflow',
|
|
templateUrl: './workflow.component.html',
|
|
styleUrls: ['./workflow.component.css'],
|
|
providers: [
|
|
{
|
|
provide: NG_VALUE_ACCESSOR,
|
|
useExisting: forwardRef(() => WorkflowComponent),
|
|
multi: true,
|
|
},
|
|
|
|
{
|
|
provide: NG_VALIDATORS,
|
|
useExisting: forwardRef(() => WorkflowComponent),
|
|
multi: true,
|
|
},
|
|
],
|
|
})
|
|
export class WorkflowComponent implements ControlValueAccessor, Validator, OnInit, OnDestroy {
|
|
|
|
|
|
public schedules: JobScheduleConfig[] = [];
|
|
|
|
@ViewChildren('jobModal') public jobModalQL: QueryList<ModalDirective>;
|
|
|
|
public disableButtons = false;
|
|
public JobTriggerTypeMap: { key: number; value: string }[];
|
|
public JobTriggerType = JobTriggerType;
|
|
public periods: string[] = [];
|
|
public showDetails: { [key: string]: boolean } = {};
|
|
public JobProgressStates = JobProgressStates;
|
|
public newSchedule: JobScheduleDTO = {
|
|
name: '',
|
|
config: null,
|
|
jobName: '',
|
|
trigger: {
|
|
type: JobTriggerType.never,
|
|
},
|
|
allowParallelRun: false,
|
|
};
|
|
|
|
error: string;
|
|
|
|
constructor(
|
|
public settingsService: SettingsService,
|
|
public jobsService: ScheduledJobsService,
|
|
public backendTextService: BackendtextService,
|
|
) {
|
|
this.JobTriggerTypeMap = [
|
|
{key: JobTriggerType.after, value: $localize`after`},
|
|
{key: JobTriggerType.never, value: $localize`never`},
|
|
{key: JobTriggerType.periodic, value: $localize`periodic`},
|
|
{key: JobTriggerType.scheduled, value: $localize`scheduled`},
|
|
];
|
|
this.periods = [
|
|
$localize`Monday`, // 0
|
|
$localize`Tuesday`, // 1
|
|
$localize`Wednesday`, // 2
|
|
$localize`Thursday`,
|
|
$localize`Friday`,
|
|
$localize`Saturday`,
|
|
$localize`Sunday`,
|
|
$localize`day`,
|
|
]; // 7
|
|
}
|
|
|
|
atTimeLocal(atTime: number): Date {
|
|
if (!atTime) {
|
|
return null;
|
|
}
|
|
const d = new Date();
|
|
d.setUTCHours(Math.floor(atTime / 60));
|
|
d.setUTCMinutes(Math.floor(atTime % 60));
|
|
return d;
|
|
}
|
|
|
|
|
|
|
|
ngOnInit(): void {
|
|
this.jobsService.subscribeToProgress();
|
|
this.jobsService.getAvailableJobs().catch(console.error);
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
this.jobsService.unsubscribeFromProgress();
|
|
}
|
|
|
|
remove(schedule: JobScheduleDTO): void {
|
|
this.schedules.splice(
|
|
this.schedules.indexOf(schedule),
|
|
1
|
|
);
|
|
}
|
|
|
|
jobTypeChanged(schedule: JobScheduleDTO): void {
|
|
const job = this.jobsService.availableJobs.value.find(
|
|
(t) => t.Name === schedule.jobName
|
|
);
|
|
schedule.config = schedule.config || {};
|
|
if (job.ConfigTemplate) {
|
|
job.ConfigTemplate.forEach(
|
|
(ct) => (schedule.config[ct.id] = ct.defaultValue)
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
jobTriggerTypeChanged(
|
|
triggerType: JobTriggerType,
|
|
schedule: JobScheduleDTO
|
|
): void {
|
|
switch (triggerType) {
|
|
case JobTriggerType.never:
|
|
schedule.trigger = new NeverJobTriggerConfig();
|
|
break;
|
|
case JobTriggerType.scheduled:
|
|
schedule.trigger = new ScheduledJobTriggerConfig();
|
|
(schedule.trigger as unknown as ScheduledJobTrigger).time = Date.now();
|
|
break;
|
|
|
|
case JobTriggerType.periodic:
|
|
schedule.trigger = new PeriodicJobTriggerConfig();
|
|
schedule.trigger.periodicity = 7;
|
|
schedule.trigger.atTime = 0;
|
|
break;
|
|
|
|
case JobTriggerType.after:
|
|
schedule.trigger = new AfterJobTriggerConfig();
|
|
if (!(schedule.trigger as unknown as AfterJobTrigger).afterScheduleName && this.schedules.length > 1) {
|
|
(schedule.trigger as unknown as AfterJobTrigger).afterScheduleName = this.schedules.find(s => s.name !== schedule.name).name;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
setNumberArray(configElement: any, id: string, value: string): void {
|
|
value = value.replace(new RegExp(',', 'g'), ';');
|
|
value = value.replace(new RegExp(' ', 'g'), ';');
|
|
configElement[id] = value
|
|
.split(';')
|
|
.map((s: string) => parseInt(s, 10))
|
|
.filter((i: number) => !isNaN(i) && i > 0);
|
|
}
|
|
|
|
getNumberArray(configElement: Record<string, number[]>, id: string): string {
|
|
return configElement[id] ? configElement[id].join('; ') : '';
|
|
}
|
|
|
|
public shouldIdent(curr: JobScheduleDTO, prev: JobScheduleDTO): boolean {
|
|
return (
|
|
curr &&
|
|
curr.trigger.type === JobTriggerType.after &&
|
|
prev &&
|
|
prev.name === curr.trigger.afterScheduleName
|
|
);
|
|
}
|
|
|
|
public sortedSchedules(): JobScheduleDTO[] {
|
|
return (this.schedules || [])
|
|
.slice()
|
|
.sort((a: JobScheduleDTO, b: JobScheduleDTO) => {
|
|
return (
|
|
this.getNextRunningDate(a, this.schedules) -
|
|
this.getNextRunningDate(b, this.schedules)
|
|
);
|
|
});
|
|
}
|
|
|
|
prepareNewJob(): void {
|
|
const jobName = this.jobsService.availableJobs.value[0].Name;
|
|
this.newSchedule = new JobScheduleConfig('new job',
|
|
jobName,
|
|
new NeverJobTriggerConfig());
|
|
|
|
// setup job specific config
|
|
const job = this.jobsService.availableJobs.value.find(
|
|
(t) => t.Name === jobName
|
|
);
|
|
this.newSchedule.config = this.newSchedule.config || {};
|
|
if (job.ConfigTemplate) {
|
|
job.ConfigTemplate.forEach(
|
|
(ct) => (this.newSchedule.config[ct.id] = ct.defaultValue)
|
|
);
|
|
}
|
|
this.jobModalQL.first.show();
|
|
}
|
|
|
|
addNewJob(): void {
|
|
// make unique job name
|
|
const jobName = this.newSchedule.jobName;
|
|
const count = this.schedules.filter(
|
|
(s: JobScheduleDTO) => s.jobName === jobName
|
|
).length;
|
|
this.newSchedule.name =
|
|
count === 0
|
|
? jobName
|
|
: this.backendTextService.getJobName(jobName) + ' ' + (count + 1);
|
|
this.schedules.push(this.newSchedule);
|
|
|
|
this.jobModalQL.first.hide();
|
|
this.onChange(null); // trigger change detection after adding new job
|
|
}
|
|
|
|
getProgress(schedule: JobScheduleDTO): JobProgressDTO {
|
|
return this.jobsService.getProgress(schedule);
|
|
}
|
|
|
|
private getNextRunningDate(
|
|
sch: JobScheduleDTO,
|
|
list: JobScheduleDTO[],
|
|
depth = 0
|
|
): number {
|
|
if (depth > list.length) {
|
|
return 0;
|
|
}
|
|
if (sch.trigger.type === JobTriggerType.never) {
|
|
return (
|
|
list
|
|
.map((s) => s.name)
|
|
.sort()
|
|
.indexOf(sch.name) * -1
|
|
);
|
|
}
|
|
if (sch.trigger.type === JobTriggerType.after) {
|
|
const parent = list.find(
|
|
(s) => s.name === (sch.trigger as AfterJobTrigger).afterScheduleName
|
|
);
|
|
if (parent) {
|
|
return this.getNextRunningDate(parent, list, depth + 1) + 0.001;
|
|
}
|
|
}
|
|
const d = JobScheduleDTOUtils.getNextRunningDate(new Date(), sch);
|
|
return d !== null ? d.getTime() : 0;
|
|
}
|
|
|
|
validate(): ValidationErrors {
|
|
return null;
|
|
}
|
|
|
|
public onChange = (value: unknown): void => {
|
|
// empty
|
|
};
|
|
|
|
public onTouched = (): void => {
|
|
// empty
|
|
};
|
|
|
|
public writeValue(obj: JobScheduleConfig[]): void {
|
|
this.schedules = obj;
|
|
}
|
|
|
|
public registerOnChange(fn: (v: JobScheduleConfig[]) => void): void {
|
|
this.onChange = () => fn(this.schedules);
|
|
}
|
|
|
|
public registerOnTouched(fn: () => void): void {
|
|
this.onTouched = fn;
|
|
}
|
|
|
|
}
|