mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
adding job last run status
This commit is contained in:
parent
509a398639
commit
8b6a367257
@ -102,4 +102,15 @@ export class AdminMWs {
|
||||
return next(new ErrorDTO(ErrorCodes.JOB_ERROR, 'Job error: ' + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
public static getJobLastRuns(req: Request, res: Response, next: NextFunction) {
|
||||
try {
|
||||
req.resultPipe = ObjectManagers.getInstance().JobManager.getJobLastRuns();
|
||||
return next();
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
return next(new ErrorDTO(ErrorCodes.JOB_ERROR, 'Job error: ' + err.toString(), err));
|
||||
}
|
||||
return next(new ErrorDTO(ErrorCodes.JOB_ERROR, 'Job error: ' + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import {JobProgressDTO} from '../../../../common/entities/settings/JobProgressDTO';
|
||||
import {JobProgressDTO} from '../../../../common/entities/job/JobProgressDTO';
|
||||
import {JobDTO} from '../../../../common/entities/job/JobDTO';
|
||||
import {JobLastRunDTO} from '../../../../common/entities/job/JobLastRunDTO';
|
||||
|
||||
export interface IJobManager {
|
||||
|
||||
@ -15,4 +16,6 @@ export interface IJobManager {
|
||||
stopSchedules(): void;
|
||||
|
||||
runSchedules(): void;
|
||||
|
||||
getJobLastRuns(): { [key: string]: { [key: string]: JobLastRunDTO } };
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
import {IJobManager} from '../database/interfaces/IJobManager';
|
||||
import {JobProgressDTO} from '../../../common/entities/settings/JobProgressDTO';
|
||||
import {JobProgressDTO} from '../../../common/entities/job/JobProgressDTO';
|
||||
import {IJob} from './jobs/IJob';
|
||||
import {JobRepository} from './JobRepository';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {AfterJobTrigger, JobScheduleDTO, JobTriggerType} from '../../../common/entities/job/JobScheduleDTO';
|
||||
import {Logger} from '../../Logger';
|
||||
import {NotificationManager} from '../NotifocationManager';
|
||||
import {JobLastRunDTO} from '../../../common/entities/job/JobLastRunDTO';
|
||||
|
||||
declare var global: NodeJS.Global;
|
||||
|
||||
@ -30,6 +31,14 @@ export class JobManager implements IJobManager {
|
||||
return m;
|
||||
}
|
||||
|
||||
getJobLastRuns(): { [key: string]: { [key: string]: JobLastRunDTO } } {
|
||||
const m: { [id: string]: { [id: string]: JobLastRunDTO } } = {};
|
||||
JobRepository.Instance.getAvailableJobs().forEach(t => {
|
||||
m[t.Name] = t.LastRuns;
|
||||
});
|
||||
return m;
|
||||
}
|
||||
|
||||
async run<T>(jobName: string, config: T): Promise<void> {
|
||||
const t = this.findJob(jobName);
|
||||
if (t) {
|
||||
@ -54,9 +63,10 @@ export class JobManager implements IJobManager {
|
||||
}
|
||||
|
||||
async onJobFinished(job: IJob<any>): Promise<void> {
|
||||
console.log('onFinished' + job.Name);
|
||||
const sch = Config.Server.Jobs.scheduled.find(s => s.jobName === job.Name);
|
||||
if (sch) {
|
||||
console.log('found parent');
|
||||
console.log('parent found' + sch.jobName);
|
||||
const children = Config.Server.Jobs.scheduled.filter(s => s.trigger.type === JobTriggerType.after &&
|
||||
(<AfterJobTrigger>s.trigger).afterScheduleName === sch.name);
|
||||
for (let i = 0; i < children.length; ++i) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {JobProgressDTO} from '../../../../common/entities/settings/JobProgressDTO';
|
||||
import {JobProgressDTO} from '../../../../common/entities/job/JobProgressDTO';
|
||||
import {ObjectManagers} from '../../ObjectManagers';
|
||||
import {Config} from '../../../../common/config/private/Config';
|
||||
import {ConfigTemplateEntry, DefaultsJobs} from '../../../../common/entities/job/JobDTO';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {JobProgressDTO} from '../../../../common/entities/settings/JobProgressDTO';
|
||||
import {JobProgressDTO} from '../../../../common/entities/job/JobProgressDTO';
|
||||
import {ConfigTemplateEntry} from '../../../../common/entities/job/JobDTO';
|
||||
import {Job} from './Job';
|
||||
import * as path from 'path';
|
||||
|
@ -1,12 +1,14 @@
|
||||
import {JobProgressDTO} from '../../../../common/entities/settings/JobProgressDTO';
|
||||
import {JobProgressDTO} from '../../../../common/entities/job/JobProgressDTO';
|
||||
import {JobDTO} from '../../../../common/entities/job/JobDTO';
|
||||
import {JobLastRunDTO} from '../../../../common/entities/job/JobLastRunDTO';
|
||||
|
||||
export interface IJob<T> extends JobDTO {
|
||||
Name: string;
|
||||
Supported: boolean;
|
||||
Progress: JobProgressDTO;
|
||||
LastRuns: { [key: string]: JobLastRunDTO };
|
||||
|
||||
start(config: T, onFinishCB?: () => void): Promise<void>;
|
||||
start(config: T, OnFinishCB: () => void): Promise<void>;
|
||||
|
||||
stop(): void;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {JobProgressDTO, JobState} from '../../../../common/entities/settings/JobProgressDTO';
|
||||
import {JobProgressDTO, JobState} from '../../../../common/entities/job/JobProgressDTO';
|
||||
import {ObjectManagers} from '../../ObjectManagers';
|
||||
import * as path from 'path';
|
||||
import {Config} from '../../../../common/config/private/Config';
|
||||
|
@ -1,9 +1,11 @@
|
||||
import {JobProgressDTO, JobState} from '../../../../common/entities/settings/JobProgressDTO';
|
||||
import {JobProgressDTO, JobState} from '../../../../common/entities/job/JobProgressDTO';
|
||||
import {Logger} from '../../../Logger';
|
||||
import {IJob} from './IJob';
|
||||
import {ConfigTemplateEntry, JobDTO} from '../../../../common/entities/job/JobDTO';
|
||||
import {JobLastRunDTO, JobLastRunState} from '../../../../common/entities/job/JobLastRunDTO';
|
||||
|
||||
declare const process: any;
|
||||
declare const global: any;
|
||||
|
||||
const LOG_TAG = '[JOB]';
|
||||
|
||||
@ -14,6 +16,7 @@ export abstract class Job<T = void> implements IJob<T> {
|
||||
protected config: T;
|
||||
protected prResolve: () => void;
|
||||
protected IsInstant = false;
|
||||
protected lastRuns: { [key: string]: JobLastRunDTO } = {};
|
||||
|
||||
public abstract get Supported(): boolean;
|
||||
|
||||
@ -21,12 +24,15 @@ export abstract class Job<T = void> implements IJob<T> {
|
||||
|
||||
public abstract get ConfigTemplate(): ConfigTemplateEntry[];
|
||||
|
||||
public get LastRuns(): { [key: string]: JobLastRunDTO } {
|
||||
return this.lastRuns;
|
||||
}
|
||||
|
||||
public get Progress(): JobProgressDTO {
|
||||
return this.progress;
|
||||
}
|
||||
|
||||
public start(config: T, onFinishCB = () => {
|
||||
}): Promise<void> {
|
||||
public start(config: T, onFinishCB: () => void): Promise<void> {
|
||||
this.OnFinishCB = onFinishCB;
|
||||
if (this.state === JobState.idle && this.Supported) {
|
||||
Logger.info(LOG_TAG, 'Running job: ' + this.Name);
|
||||
@ -78,6 +84,17 @@ export abstract class Job<T = void> implements IJob<T> {
|
||||
protected abstract async init(): Promise<void>;
|
||||
|
||||
private onFinish(): void {
|
||||
this.lastRuns[JSON.stringify(this.config)] = {
|
||||
all: this.progress.left + this.progress.progress,
|
||||
done: this.progress.progress,
|
||||
comment: '',
|
||||
config: this.config,
|
||||
state: this.progress.state === JobState.stopping ? JobLastRunState.canceled : JobLastRunState.finished,
|
||||
time: {
|
||||
start: this.progress.time.start,
|
||||
end: Date.now()
|
||||
}
|
||||
};
|
||||
this.progress = null;
|
||||
if (global.gc) {
|
||||
global.gc();
|
||||
@ -95,16 +112,16 @@ export abstract class Job<T = void> implements IJob<T> {
|
||||
if (this.state === JobState.idle) {
|
||||
return;
|
||||
}
|
||||
let prg = null;
|
||||
if (this.state === JobState.running) {
|
||||
this.progress = await this.step();
|
||||
} else {
|
||||
this.progress = null;
|
||||
prg = await this.step();
|
||||
}
|
||||
if (this.progress == null) { // finished
|
||||
if (prg == null) { // finished
|
||||
this.state = JobState.idle;
|
||||
this.onFinish();
|
||||
return;
|
||||
}
|
||||
this.progress = prg;
|
||||
this.run();
|
||||
} catch (e) {
|
||||
Logger.error(LOG_TAG, e);
|
||||
|
@ -3,7 +3,7 @@ import * as path from 'path';
|
||||
import * as util from 'util';
|
||||
import {promises as fsp} from 'fs';
|
||||
import {Job} from './Job';
|
||||
import {JobProgressDTO} from '../../../../common/entities/settings/JobProgressDTO';
|
||||
import {JobProgressDTO} from '../../../../common/entities/job/JobProgressDTO';
|
||||
import {ProjectPath} from '../../../ProjectPath';
|
||||
import {PhotoProcessing} from '../../fileprocessing/PhotoProcessing';
|
||||
import {VideoProcessing} from '../../fileprocessing/VideoProcessing';
|
||||
|
@ -28,14 +28,14 @@ export class ThumbnailGenerationJob extends FileJob<MediaDTO, { sizes: number[]
|
||||
return true;
|
||||
}
|
||||
|
||||
start(config: { sizes: number[] }): Promise<void> {
|
||||
start(config: { sizes: number[] }, OnFinishCB: () => void): Promise<void> {
|
||||
for (let i = 0; i < config.sizes.length; ++i) {
|
||||
if (Config.Client.Media.Thumbnail.thumbnailSizes.indexOf(config.sizes[i]) === -1) {
|
||||
throw new Error('unknown thumbnails size: ' + config.sizes[i] + '. Add it to the possible thumbnail sizes.');
|
||||
}
|
||||
}
|
||||
|
||||
return super.start(config);
|
||||
return super.start(config, OnFinishCB);
|
||||
}
|
||||
|
||||
protected async processDirectory(directory: DirectoryDTO): Promise<MediaDTO[]> {
|
||||
|
@ -43,6 +43,12 @@ export class AdminRouter {
|
||||
AdminMWs.getJobProgresses,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
app.get('/api/admin/jobs/scheduled/lastRun',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.getJobLastRuns,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
app.post('/api/admin/jobs/scheduled/:id/start',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
|
@ -75,17 +75,50 @@ export class PrivateConfigDefaultsClass extends PublicConfigClass implements IPr
|
||||
listingLimit: 1000
|
||||
},
|
||||
Jobs: {
|
||||
scheduled: [{
|
||||
name: DefaultsJobs[DefaultsJobs['Database Reset']],
|
||||
jobName: DefaultsJobs[DefaultsJobs['Database Reset']],
|
||||
config: {},
|
||||
trigger: {type: JobTriggerType.never}
|
||||
}, {
|
||||
scheduled: [
|
||||
{
|
||||
name: DefaultsJobs[DefaultsJobs.Indexing],
|
||||
jobName: DefaultsJobs[DefaultsJobs.Indexing],
|
||||
config: {},
|
||||
trigger: {type: JobTriggerType.never}
|
||||
}]
|
||||
},
|
||||
{
|
||||
name: DefaultsJobs[DefaultsJobs['Thumbnail Generation']],
|
||||
jobName: DefaultsJobs[DefaultsJobs['Thumbnail Generation']],
|
||||
config: {sizes: [160]},
|
||||
trigger: {
|
||||
type: JobTriggerType.after,
|
||||
afterScheduleName: DefaultsJobs[DefaultsJobs.Indexing]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: DefaultsJobs[DefaultsJobs['Photo Converting']],
|
||||
jobName: DefaultsJobs[DefaultsJobs['Photo Converting']],
|
||||
config: {},
|
||||
trigger: {
|
||||
type: JobTriggerType.after,
|
||||
afterScheduleName: DefaultsJobs[DefaultsJobs['Thumbnail Generation']]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: DefaultsJobs[DefaultsJobs['Video Converting']],
|
||||
jobName: DefaultsJobs[DefaultsJobs['Video Converting']],
|
||||
config: {},
|
||||
trigger: {
|
||||
type: JobTriggerType.after,
|
||||
afterScheduleName: DefaultsJobs[DefaultsJobs['Photo Converting']]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: DefaultsJobs[DefaultsJobs['Temp Folder Cleaning']],
|
||||
jobName: DefaultsJobs[DefaultsJobs['Temp Folder Cleaning']],
|
||||
config: {},
|
||||
trigger: {
|
||||
type: JobTriggerType.after,
|
||||
afterScheduleName: DefaultsJobs[DefaultsJobs['Video Converting']]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
15
src/common/entities/job/JobLastRunDTO.ts
Normal file
15
src/common/entities/job/JobLastRunDTO.ts
Normal file
@ -0,0 +1,15 @@
|
||||
export enum JobLastRunState {
|
||||
finished = 1, canceled = 2
|
||||
}
|
||||
|
||||
export interface JobLastRunDTO {
|
||||
config: any;
|
||||
done: number;
|
||||
all: number;
|
||||
state: JobLastRunState;
|
||||
comment: string;
|
||||
time: {
|
||||
start: number,
|
||||
end: number
|
||||
};
|
||||
}
|
@ -64,47 +64,47 @@
|
||||
</nav>
|
||||
</div>
|
||||
<div class="col-md-10">
|
||||
<!-- <app-settings-basic #setting #basic-->
|
||||
<!-- [simplifiedMode]="simplifiedMode"-->
|
||||
<!-- [hidden]="!basic.HasAvailableSettings"></app-settings-basic>-->
|
||||
<!-- <app-settings-usermanager #setting #userManager-->
|
||||
<!-- [hidden]="!userManager.HasAvailableSettings"></app-settings-usermanager>-->
|
||||
<!-- <app-settings-database #setting #database-->
|
||||
<!-- [simplifiedMode]="simplifiedMode"-->
|
||||
<!-- [hidden]="!database.HasAvailableSettings"></app-settings-database>-->
|
||||
<!-- <app-settings-photo #setting #photo-->
|
||||
<!-- [hidden]="!photo.HasAvailableSettings"-->
|
||||
<!-- [simplifiedMode]="simplifiedMode"></app-settings-photo>-->
|
||||
<!-- <app-settings-video #setting #video-->
|
||||
<!-- [hidden]="!video.HasAvailableSettings"-->
|
||||
<!-- [simplifiedMode]="simplifiedMode"></app-settings-video>-->
|
||||
<!-- <app-settings-thumbnail #setting #thumbnail-->
|
||||
<!-- [hidden]="!thumbnail.HasAvailableSettings"-->
|
||||
<!-- [simplifiedMode]="simplifiedMode"></app-settings-thumbnail>-->
|
||||
<!-- <app-settings-search #setting #search-->
|
||||
<!-- [hidden]="!search.HasAvailableSettings"-->
|
||||
<!-- [simplifiedMode]="simplifiedMode"></app-settings-search>-->
|
||||
<!-- <app-settings-share #setting #share-->
|
||||
<!-- [hidden]="!share.HasAvailableSettings"-->
|
||||
<!-- [simplifiedMode]="simplifiedMode"></app-settings-share>-->
|
||||
<!-- <app-settings-map #setting #map-->
|
||||
<!-- [hidden]="!map.HasAvailableSettings"-->
|
||||
<!-- [simplifiedMode]="simplifiedMode"></app-settings-map>-->
|
||||
<!-- <app-settings-meta-file #setting #metaFile-->
|
||||
<!-- [hidden]="!metaFile.HasAvailableSettings"-->
|
||||
<!-- [simplifiedMode]="simplifiedMode"></app-settings-meta-file>-->
|
||||
<!-- <app-settings-other #setting #other-->
|
||||
<!-- [hidden]="!other.HasAvailableSettings"-->
|
||||
<!-- [simplifiedMode]="simplifiedMode"></app-settings-other>-->
|
||||
<!-- <app-settings-random-photo #setting #random-->
|
||||
<!-- [hidden]="!random.HasAvailableSettings"-->
|
||||
<!-- [simplifiedMode]="simplifiedMode"></app-settings-random-photo>-->
|
||||
<!-- <app-settings-faces #setting #faces-->
|
||||
<!-- [hidden]="!faces.HasAvailableSettings"-->
|
||||
<!-- [simplifiedMode]="simplifiedMode"></app-settings-faces>-->
|
||||
<!-- <app-settings-indexing #setting #indexing-->
|
||||
<!-- [hidden]="!indexing.HasAvailableSettings"-->
|
||||
<!-- [simplifiedMode]="simplifiedMode"></app-settings-indexing>-->
|
||||
<app-settings-basic #setting #basic
|
||||
[simplifiedMode]="simplifiedMode"
|
||||
[hidden]="!basic.HasAvailableSettings"></app-settings-basic>
|
||||
<app-settings-usermanager #setting #userManager
|
||||
[hidden]="!userManager.HasAvailableSettings"></app-settings-usermanager>
|
||||
<app-settings-database #setting #database
|
||||
[simplifiedMode]="simplifiedMode"
|
||||
[hidden]="!database.HasAvailableSettings"></app-settings-database>
|
||||
<app-settings-photo #setting #photo
|
||||
[hidden]="!photo.HasAvailableSettings"
|
||||
[simplifiedMode]="simplifiedMode"></app-settings-photo>
|
||||
<app-settings-video #setting #video
|
||||
[hidden]="!video.HasAvailableSettings"
|
||||
[simplifiedMode]="simplifiedMode"></app-settings-video>
|
||||
<app-settings-thumbnail #setting #thumbnail
|
||||
[hidden]="!thumbnail.HasAvailableSettings"
|
||||
[simplifiedMode]="simplifiedMode"></app-settings-thumbnail>
|
||||
<app-settings-search #setting #search
|
||||
[hidden]="!search.HasAvailableSettings"
|
||||
[simplifiedMode]="simplifiedMode"></app-settings-search>
|
||||
<app-settings-share #setting #share
|
||||
[hidden]="!share.HasAvailableSettings"
|
||||
[simplifiedMode]="simplifiedMode"></app-settings-share>
|
||||
<app-settings-map #setting #map
|
||||
[hidden]="!map.HasAvailableSettings"
|
||||
[simplifiedMode]="simplifiedMode"></app-settings-map>
|
||||
<app-settings-meta-file #setting #metaFile
|
||||
[hidden]="!metaFile.HasAvailableSettings"
|
||||
[simplifiedMode]="simplifiedMode"></app-settings-meta-file>
|
||||
<app-settings-other #setting #other
|
||||
[hidden]="!other.HasAvailableSettings"
|
||||
[simplifiedMode]="simplifiedMode"></app-settings-other>
|
||||
<app-settings-random-photo #setting #random
|
||||
[hidden]="!random.HasAvailableSettings"
|
||||
[simplifiedMode]="simplifiedMode"></app-settings-random-photo>
|
||||
<app-settings-faces #setting #faces
|
||||
[hidden]="!faces.HasAvailableSettings"
|
||||
[simplifiedMode]="simplifiedMode"></app-settings-faces>
|
||||
<app-settings-indexing #setting #indexing
|
||||
[hidden]="!indexing.HasAvailableSettings"
|
||||
[simplifiedMode]="simplifiedMode"></app-settings-indexing>
|
||||
<app-settings-jobs #setting #jobs
|
||||
[hidden]="!jobs.HasAvailableSettings"
|
||||
[simplifiedMode]="simplifiedMode"></app-settings-jobs>
|
||||
|
@ -10,7 +10,7 @@ import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
import {ScheduledJobsService} from '../scheduled-jobs.service';
|
||||
import {DefaultsJobs} from '../../../../../common/entities/job/JobDTO';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {JobState} from '../../../../../common/entities/settings/JobProgressDTO';
|
||||
import {JobState} from '../../../../../common/entities/job/JobProgressDTO';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-indexing',
|
||||
|
@ -189,9 +189,11 @@
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<app-settings-job-progress
|
||||
class="card-footer bg-transparent"
|
||||
[progress]="jobsService.progress.value[schedule.jobName]">
|
||||
[progress]="jobsService.progress.value[schedule.jobName]"
|
||||
[lastRun]="(jobsService.lastRuns.value[schedule.jobName] || {})[getConfigHash(schedule)]">
|
||||
</app-settings-job-progress>
|
||||
|
||||
</div>
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import {ConfigTemplateEntry} from '../../../../../common/entities/job/JobDTO';
|
||||
import {JobState} from '../../../../../common/entities/settings/JobProgressDTO';
|
||||
import {JobState} from '../../../../../common/entities/job/JobProgressDTO';
|
||||
import {Job} from '../../../../../backend/model/jobs/jobs/Job';
|
||||
import {ModalDirective} from 'ngx-bootstrap/modal';
|
||||
|
||||
@ -211,6 +211,10 @@ export class JobsSettingsComponent extends SettingsComponent<ServerConfig.JobCon
|
||||
this.settings.scheduled.push(this.newSchedule);
|
||||
}
|
||||
|
||||
getConfigHash(schedule: JobScheduleDTO): string {
|
||||
return JSON.stringify(schedule.config);
|
||||
}
|
||||
|
||||
private getNextRunningDate(sch: JobScheduleDTO, list: JobScheduleDTO[], depth: number = 0): number {
|
||||
if (depth > list.length) {
|
||||
return 0;
|
||||
|
@ -1,3 +1,20 @@
|
||||
<div class="row" *ngIf="!progress && lastRun">
|
||||
<div class="col-md-2 col-12" i18n>
|
||||
Last run:
|
||||
</div>
|
||||
<div class="col-md-4 col-12">
|
||||
<span class="oi oi-clock" title="Run between" i18n-title aria-hidden="true"></span>
|
||||
{{lastRun.time.start | date:'medium'}} - {{lastRun.time.end | date:'mediumTime'}}
|
||||
</div>
|
||||
<div class="col-md-3 col-6">
|
||||
<span class="oi oi-check" title="done/all" i18n-title aria-hidden="true"></span>
|
||||
{{lastRun.all}}/{{lastRun.done}}
|
||||
</div>
|
||||
<div class="col-md-3 col-6">
|
||||
<span class="oi oi-pulse" title="Status" i18n-title aria-hidden="true"></span>
|
||||
{{JobLastRunState[lastRun.state]}}
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="progress">
|
||||
|
||||
<div class="form-group row">
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {Component, Input, OnChanges, OnDestroy} from '@angular/core';
|
||||
import {JobProgressDTO, JobState} from '../../../../../../common/entities/settings/JobProgressDTO';
|
||||
import {JobProgressDTO, JobState} from '../../../../../../common/entities/job/JobProgressDTO';
|
||||
import {Subscription, timer} from 'rxjs';
|
||||
import {JobLastRunDTO, JobLastRunState} from '../../../../../../common/entities/job/JobLastRunDTO';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-job-progress',
|
||||
@ -10,8 +11,10 @@ import {Subscription, timer} from 'rxjs';
|
||||
export class JobProgressComponent implements OnDestroy, OnChanges {
|
||||
|
||||
@Input() progress: JobProgressDTO;
|
||||
@Input() lastRun: JobLastRunDTO;
|
||||
JobState = JobState;
|
||||
timeCurrentCopy: number;
|
||||
JobLastRunState = JobLastRunState;
|
||||
private timerSub: Subscription;
|
||||
|
||||
constructor() {
|
||||
|
@ -11,7 +11,7 @@ import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig'
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {DefaultsJobs} from '../../../../../common/entities/job/JobDTO';
|
||||
import {ErrorDTO} from '../../../../../common/entities/Error';
|
||||
import {JobState} from '../../../../../common/entities/settings/JobProgressDTO';
|
||||
import {JobState} from '../../../../../common/entities/job/JobProgressDTO';
|
||||
|
||||
|
||||
@Component({
|
||||
|
@ -1,19 +1,22 @@
|
||||
import {EventEmitter, Injectable} from '@angular/core';
|
||||
import {BehaviorSubject} from 'rxjs';
|
||||
import {JobProgressDTO} from '../../../../common/entities/settings/JobProgressDTO';
|
||||
import {JobProgressDTO} from '../../../../common/entities/job/JobProgressDTO';
|
||||
import {NetworkService} from '../../model/network/network.service';
|
||||
import {JobLastRunDTO} from '../../../../common/entities/job/JobLastRunDTO';
|
||||
|
||||
@Injectable()
|
||||
export class ScheduledJobsService {
|
||||
|
||||
|
||||
public progress: BehaviorSubject<{ [key: string]: JobProgressDTO }>;
|
||||
public lastRuns: BehaviorSubject<{ [key: string]: { [key: string]: JobLastRunDTO } }>;
|
||||
public onJobFinish: EventEmitter<string> = new EventEmitter<string>();
|
||||
timer: number = null;
|
||||
private subscribers = 0;
|
||||
|
||||
constructor(private _networkService: NetworkService) {
|
||||
this.progress = new BehaviorSubject({});
|
||||
this.lastRuns = new BehaviorSubject({});
|
||||
}
|
||||
|
||||
public calcTimeElapsed(progress: JobProgressDTO) {
|
||||
@ -53,6 +56,7 @@ export class ScheduledJobsService {
|
||||
protected async getProgress(): Promise<void> {
|
||||
const prevPrg = this.progress.value;
|
||||
this.progress.next(await this._networkService.getJson<{ [key: string]: JobProgressDTO }>('/admin/jobs/scheduled/progress'));
|
||||
this.lastRuns.next(await this._networkService.getJson<{ [key: string]: { [key: string]: JobLastRunDTO } }>('/admin/jobs/scheduled/lastRun'));
|
||||
for (const prg in prevPrg) {
|
||||
if (!this.progress.value.hasOwnProperty(prg)) {
|
||||
this.onJobFinish.emit(prg);
|
||||
|
@ -10,7 +10,7 @@ import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig'
|
||||
import {DefaultsJobs} from '../../../../../common/entities/job/JobDTO';
|
||||
import {ErrorDTO} from '../../../../../common/entities/Error';
|
||||
import {ScheduledJobsService} from '../scheduled-jobs.service';
|
||||
import {JobState} from '../../../../../common/entities/settings/JobProgressDTO';
|
||||
import {JobState} from '../../../../../common/entities/job/JobProgressDTO';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-thumbnail',
|
||||
|
@ -10,7 +10,7 @@ import {ScheduledJobsService} from '../scheduled-jobs.service';
|
||||
import {DefaultsJobs} from '../../../../../common/entities/job/JobDTO';
|
||||
import {ErrorDTO} from '../../../../../common/entities/Error';
|
||||
import {ServerConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||
import { JobState } from '../../../../../common/entities/settings/JobProgressDTO';
|
||||
import { JobState } from '../../../../../common/entities/job/JobProgressDTO';
|
||||
|
||||
|
||||
@Component({
|
||||
|
Loading…
x
Reference in New Issue
Block a user