@firestitch/system 13.0.4 → 13.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/modules/system/components/cron-next-run/cron-next-run.component.d.ts +18 -0
- package/app/modules/system/components/cron-next-run/index.d.ts +1 -0
- package/app/modules/system/fs-system.module.d.ts +37 -36
- package/esm2020/app/modules/system/components/cron-next-run/cron-next-run.component.mjs +99 -0
- package/esm2020/app/modules/system/components/cron-next-run/index.mjs +2 -0
- package/esm2020/app/modules/system/components/crons/crons.component.mjs +5 -4
- package/esm2020/app/modules/system/fs-system.module.mjs +4 -1
- package/fesm2015/firestitch-system.mjs +99 -5
- package/fesm2015/firestitch-system.mjs.map +1 -1
- package/fesm2020/firestitch-system.mjs +99 -5
- package/fesm2020/firestitch-system.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -28,7 +28,7 @@ import { FsListComponent, FsListModule } from '@firestitch/list';
|
|
|
28
28
|
import * as i7 from '@firestitch/popover';
|
|
29
29
|
import { FsPopoverModule } from '@firestitch/popover';
|
|
30
30
|
import { ItemType } from '@firestitch/filter';
|
|
31
|
-
import { map, tap,
|
|
31
|
+
import { map, tap, takeUntil, switchMap } from 'rxjs/operators';
|
|
32
32
|
import * as i4$3 from '@angular/material/expansion';
|
|
33
33
|
import { MatExpansionModule } from '@angular/material/expansion';
|
|
34
34
|
import * as i7$1 from '@angular/material/form-field';
|
|
@@ -52,11 +52,11 @@ import * as i6 from '@firestitch/menu';
|
|
|
52
52
|
import { FsMenuModule } from '@firestitch/menu';
|
|
53
53
|
import * as i5 from '@firestitch/skeleton';
|
|
54
54
|
import { FsSkeletonModule } from '@firestitch/skeleton';
|
|
55
|
+
import { Subject, timer } from 'rxjs';
|
|
56
|
+
import { addMinutes, addHours, addDays, subSeconds, differenceInSeconds, getDaysInMonth, differenceInMinutes } from 'date-fns';
|
|
55
57
|
import * as i1$1 from '@firestitch/message';
|
|
56
58
|
import * as i3$3 from '@firestitch/prompt';
|
|
57
59
|
import { SelectionActionType } from '@firestitch/selection';
|
|
58
|
-
import { Subject } from 'rxjs';
|
|
59
|
-
import { differenceInSeconds, differenceInMinutes } from 'date-fns';
|
|
60
60
|
import * as i2$3 from '@firestitch/build';
|
|
61
61
|
import * as i9$1 from '@angular/material/core';
|
|
62
62
|
|
|
@@ -574,6 +574,98 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
574
574
|
args: [MAT_DIALOG_DATA]
|
|
575
575
|
}] }, { type: i1.MatDialog }, { type: i0.ChangeDetectorRef }]; } });
|
|
576
576
|
|
|
577
|
+
class CronNextRunComponent {
|
|
578
|
+
constructor(_cdRef) {
|
|
579
|
+
this._cdRef = _cdRef;
|
|
580
|
+
this._destroy$ = new Subject();
|
|
581
|
+
}
|
|
582
|
+
ngOnInit() {
|
|
583
|
+
this.update();
|
|
584
|
+
}
|
|
585
|
+
calculateDuration() {
|
|
586
|
+
const now = new Date();
|
|
587
|
+
const nextMinutes = this._getNextMinutes(now);
|
|
588
|
+
const nextHours = this._getNextHours(now);
|
|
589
|
+
const nextDays = this._getNextDays(now);
|
|
590
|
+
if (this.cron.cronSetting.minutes.length ||
|
|
591
|
+
this.cron.cronSetting.hours.length ||
|
|
592
|
+
this.cron.cronSetting.days.length) {
|
|
593
|
+
let next = new Date();
|
|
594
|
+
next = addMinutes(next, nextMinutes);
|
|
595
|
+
next = addHours(next, nextHours);
|
|
596
|
+
next = addDays(next, nextDays);
|
|
597
|
+
next = subSeconds(next, next.getSeconds());
|
|
598
|
+
this.duration = differenceInSeconds(next, now);
|
|
599
|
+
}
|
|
600
|
+
else {
|
|
601
|
+
this.duration = 60 - now.getSeconds();
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
update() {
|
|
605
|
+
this.calculateDuration();
|
|
606
|
+
timer(0, 1000)
|
|
607
|
+
.pipe(tap(() => {
|
|
608
|
+
this.duration -= 1;
|
|
609
|
+
if (this.duration % 60 === 0 || this.duration < (60 * 5)) {
|
|
610
|
+
this._cdRef.markForCheck();
|
|
611
|
+
}
|
|
612
|
+
if (this.duration <= 0) {
|
|
613
|
+
this.calculateDuration();
|
|
614
|
+
this._cdRef.markForCheck();
|
|
615
|
+
}
|
|
616
|
+
}), takeUntil(this._destroy$))
|
|
617
|
+
.subscribe();
|
|
618
|
+
}
|
|
619
|
+
ngOnDestroy() {
|
|
620
|
+
this._destroy$.next();
|
|
621
|
+
this._destroy$.complete();
|
|
622
|
+
}
|
|
623
|
+
_getNextMinutes(now) {
|
|
624
|
+
const minutes = this.cron.cronSetting.minutes;
|
|
625
|
+
if (minutes.length) {
|
|
626
|
+
for (let i = minutes.length - 1; i >= 0; i--) {
|
|
627
|
+
if (now.getUTCMinutes() >= minutes[i]) {
|
|
628
|
+
return (minutes[i + 1] ? minutes[i + 1] - now.getUTCMinutes() : (60 - now.getUTCMinutes() + minutes[i]));
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
return minutes[0] - now.getMinutes();
|
|
632
|
+
}
|
|
633
|
+
return 0;
|
|
634
|
+
}
|
|
635
|
+
_getNextHours(now) {
|
|
636
|
+
const hours = this.cron.cronSetting.hours;
|
|
637
|
+
if (hours.length) {
|
|
638
|
+
for (let i = hours.length - 1; i >= 0; i--) {
|
|
639
|
+
if (now.getUTCHours() >= hours[i]) {
|
|
640
|
+
return (hours[i + 1] ? hours[i + 1] - now.getUTCHours() : (24 - now.getUTCHours() + hours[i]));
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
return hours[0] - now.getUTCHours();
|
|
644
|
+
}
|
|
645
|
+
return 0;
|
|
646
|
+
}
|
|
647
|
+
_getNextDays(now) {
|
|
648
|
+
const days = this.cron.cronSetting.days;
|
|
649
|
+
if (days.length) {
|
|
650
|
+
for (let i = days.length - 1; i >= 0; i--) {
|
|
651
|
+
if (now.getDate() >= days[i]) {
|
|
652
|
+
return (days[i + 1] ? days[i + 1] : getDaysInMonth(now)) - now.getDate();
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
return days[0] - getDaysInMonth(now);
|
|
656
|
+
}
|
|
657
|
+
return 0;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
CronNextRunComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: CronNextRunComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
661
|
+
CronNextRunComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: CronNextRunComponent, selector: "app-next-run", inputs: { cron: "cron" }, ngImport: i0, template: "<ng-container *ngIf=\"duration > 60; else seconds\">\n {{duration | fsDateDuration: { hours: true, seconds: true, minutes: true, days: true} }}\n</ng-container>\n\n<ng-template #seconds>\n {{duration}}s\n</ng-template>\n\n", styles: [""], directives: [{ type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "fsDateDuration": i4$2.FsDateDurationPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
662
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: CronNextRunComponent, decorators: [{
|
|
663
|
+
type: Component,
|
|
664
|
+
args: [{ selector: 'app-next-run', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"duration > 60; else seconds\">\n {{duration | fsDateDuration: { hours: true, seconds: true, minutes: true, days: true} }}\n</ng-container>\n\n<ng-template #seconds>\n {{duration}}s\n</ng-template>\n\n", styles: [""] }]
|
|
665
|
+
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { cron: [{
|
|
666
|
+
type: Input
|
|
667
|
+
}] } });
|
|
668
|
+
|
|
577
669
|
class CronsComponent {
|
|
578
670
|
constructor(_message, _dialog, _prompt) {
|
|
579
671
|
this._message = _message;
|
|
@@ -759,10 +851,10 @@ class CronsComponent {
|
|
|
759
851
|
}
|
|
760
852
|
}
|
|
761
853
|
CronsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: CronsComponent, deps: [{ token: i1$1.FsMessage }, { token: i1.MatDialog }, { token: i3$3.FsPrompt }], target: i0.ɵɵFactoryTarget.Component });
|
|
762
|
-
CronsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: CronsComponent, selector: "fs-system-crons", inputs: { enable: "enable", disable: "disable", kill: "kill", queue: "queue", run: "run", loadCrons: "loadCrons", loadCron: "loadCron", loadCronLogs: "loadCronLogs", bulk: "bulk" }, viewQueries: [{ propertyName: "list", first: true, predicate: FsListComponent, descendants: true, static: true }], ngImport: i0, template: "<fs-list [config]=\"config\">\n <fs-list-column>\n <ng-template fs-list-header>Name</ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <a (click)=\"open(row)\">{{row.name}}</a>\n <div *ngIf=\"row.cronSetting\">\n <small>{{row.cronSetting.summary}}</small>\n </div>\n </ng-template>\n </fs-list-column>\n <fs-list-column align=\"center\">\n <ng-template fs-list-header>Status</ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <ng-container *ngIf=\"row.host || row.processId; else status\">\n <fs-popover \n [maxWidth]=\"null\"\n [template]=\"statusPopover\" \n size=\"small\">\n <ng-container *ngTemplateOutlet=\"status\"></ng-container>\n </fs-popover>\n <ng-template #statusPopover>\n <div *ngIf=\"row.host\">Host: {{row.host}}</div>\n <div *ngIf=\"row.processId\">Process ID: {{row.processId}}</div>\n <div *ngIf=\"row.processState\">Process State: {{CronProcessStates[row.processState]}}</div>\n </ng-template>\n </ng-container>\n <ng-template #status>\n {{CronStates[row.state]}}\n </ng-template>\n <ng-container *ngIf=\"row.state === CronState.Running\">\n <div class=\"small\">\n Duration: {{ row.runningDuration | fsDateDuration: { hours: true, minutes: true, seconds: true } }}\n </div>\n </ng-container> \n </ng-template>\n </fs-list-column>\n <fs-list-column>\n <ng-template fs-list-header>Last Ran</ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <ng-container *ngIf=\"row.duration===null; else lastRan\">\n Never\n </ng-container>\n <ng-template #lastRan>\n <fs-date-ago [date]=\"row.createDate\"></fs-date-ago>\n <div class=\"small\" *ngIf=\"row.duration\">\n Duration: {{ row.duration | fsDateDuration: { hours: true, minutes: true, seconds: true } }}\n </div>\n </ng-template>\n </ng-template>\n </fs-list-column>\n</fs-list>\n", styles: [""], components: [{ type: i2$2.FsListComponent, selector: "fs-list", inputs: ["config", "loaderLines"], outputs: ["filtersReady"] }, { type: i7.FsPopoverComponent, selector: "fs-popover" }, { type: i4$2.FsDateAgoComponent, selector: "fs-date-ago", inputs: ["date", "showTime", "format", "showTooltip", "tooltipDateFormat"] }], directives: [{ type: i2$2.FsListColumnDirective, selector: "fs-list-column", inputs: ["show", "title", "name", "customize", "sortable", "sortableDefault", "direction", "align", "width", "class"] }, { type: i2$2.FsListHeaderDirective, selector: "[fs-list-header]", inputs: ["colspan", "align", "class"] }, { type: i2$2.FsListCellDirective, selector: "[fs-list-cell]", inputs: ["colspan", "align", "class"] }, { type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "fsDateDuration": i4$2.FsDateDurationPipe } });
|
|
854
|
+
CronsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: CronsComponent, selector: "fs-system-crons", inputs: { enable: "enable", disable: "disable", kill: "kill", queue: "queue", run: "run", loadCrons: "loadCrons", loadCron: "loadCron", loadCronLogs: "loadCronLogs", bulk: "bulk" }, viewQueries: [{ propertyName: "list", first: true, predicate: FsListComponent, descendants: true, static: true }], ngImport: i0, template: "<fs-list [config]=\"config\">\n <fs-list-column>\n <ng-template fs-list-header>Name</ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <a (click)=\"open(row)\">{{row.name}}</a>\n <div *ngIf=\"row.cronSetting\">\n <small>{{row.cronSetting.summary}}</small>\n </div>\n </ng-template>\n </fs-list-column>\n <fs-list-column align=\"center\">\n <ng-template fs-list-header>Status</ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <ng-container *ngIf=\"row.host || row.processId; else status\">\n <fs-popover \n [maxWidth]=\"null\"\n [template]=\"statusPopover\" \n size=\"small\">\n <ng-container *ngTemplateOutlet=\"status\"></ng-container>\n </fs-popover>\n <ng-template #statusPopover>\n <div *ngIf=\"row.host\">Host: {{row.host}}</div>\n <div *ngIf=\"row.processId\">Process ID: {{row.processId}}</div>\n <div *ngIf=\"row.processState\">Process State: {{CronProcessStates[row.processState]}}</div>\n </ng-template>\n </ng-container>\n <ng-template #status>\n {{CronStates[row.state]}}\n </ng-template>\n <ng-container *ngIf=\"row.state === CronState.Running\">\n <div class=\"small\">\n Duration: {{ row.runningDuration | fsDateDuration: { hours: true, minutes: true, seconds: true } }}\n </div>\n </ng-container> \n </ng-template>\n </fs-list-column>\n <fs-list-column>\n <ng-template fs-list-header>Last Ran</ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <ng-container *ngIf=\"row.duration===null; else lastRan\">\n Never\n </ng-container>\n <ng-template #lastRan>\n <fs-date-ago [date]=\"row.createDate\"></fs-date-ago>\n <div class=\"small\" *ngIf=\"row.duration\">\n Duration: {{ row.duration | fsDateDuration: { hours: true, minutes: true, seconds: true } }}\n </div>\n </ng-template>\n </ng-template>\n </fs-list-column>\n <fs-list-column>\n <ng-template fs-list-header>Next Run</ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <ng-container *ngIf=\"row.state !== CronState.Disabled\">\n <app-next-run [cron]=\"row\"></app-next-run>\n </ng-container>\n </ng-template>\n </fs-list-column>\n</fs-list>\n", styles: [""], components: [{ type: i2$2.FsListComponent, selector: "fs-list", inputs: ["config", "loaderLines"], outputs: ["filtersReady"] }, { type: i7.FsPopoverComponent, selector: "fs-popover" }, { type: i4$2.FsDateAgoComponent, selector: "fs-date-ago", inputs: ["date", "showTime", "format", "showTooltip", "tooltipDateFormat"] }, { type: CronNextRunComponent, selector: "app-next-run", inputs: ["cron"] }], directives: [{ type: i2$2.FsListColumnDirective, selector: "fs-list-column", inputs: ["show", "title", "name", "customize", "sortable", "sortableDefault", "direction", "align", "width", "class"] }, { type: i2$2.FsListHeaderDirective, selector: "[fs-list-header]", inputs: ["colspan", "align", "class"] }, { type: i2$2.FsListCellDirective, selector: "[fs-list-cell]", inputs: ["colspan", "align", "class"] }, { type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "fsDateDuration": i4$2.FsDateDurationPipe } });
|
|
763
855
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: CronsComponent, decorators: [{
|
|
764
856
|
type: Component,
|
|
765
|
-
args: [{ selector: 'fs-system-crons', template: "<fs-list [config]=\"config\">\n <fs-list-column>\n <ng-template fs-list-header>Name</ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <a (click)=\"open(row)\">{{row.name}}</a>\n <div *ngIf=\"row.cronSetting\">\n <small>{{row.cronSetting.summary}}</small>\n </div>\n </ng-template>\n </fs-list-column>\n <fs-list-column align=\"center\">\n <ng-template fs-list-header>Status</ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <ng-container *ngIf=\"row.host || row.processId; else status\">\n <fs-popover \n [maxWidth]=\"null\"\n [template]=\"statusPopover\" \n size=\"small\">\n <ng-container *ngTemplateOutlet=\"status\"></ng-container>\n </fs-popover>\n <ng-template #statusPopover>\n <div *ngIf=\"row.host\">Host: {{row.host}}</div>\n <div *ngIf=\"row.processId\">Process ID: {{row.processId}}</div>\n <div *ngIf=\"row.processState\">Process State: {{CronProcessStates[row.processState]}}</div>\n </ng-template>\n </ng-container>\n <ng-template #status>\n {{CronStates[row.state]}}\n </ng-template>\n <ng-container *ngIf=\"row.state === CronState.Running\">\n <div class=\"small\">\n Duration: {{ row.runningDuration | fsDateDuration: { hours: true, minutes: true, seconds: true } }}\n </div>\n </ng-container> \n </ng-template>\n </fs-list-column>\n <fs-list-column>\n <ng-template fs-list-header>Last Ran</ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <ng-container *ngIf=\"row.duration===null; else lastRan\">\n Never\n </ng-container>\n <ng-template #lastRan>\n <fs-date-ago [date]=\"row.createDate\"></fs-date-ago>\n <div class=\"small\" *ngIf=\"row.duration\">\n Duration: {{ row.duration | fsDateDuration: { hours: true, minutes: true, seconds: true } }}\n </div>\n </ng-template>\n </ng-template>\n </fs-list-column>\n</fs-list>\n", styles: [""] }]
|
|
857
|
+
args: [{ selector: 'fs-system-crons', template: "<fs-list [config]=\"config\">\n <fs-list-column>\n <ng-template fs-list-header>Name</ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <a (click)=\"open(row)\">{{row.name}}</a>\n <div *ngIf=\"row.cronSetting\">\n <small>{{row.cronSetting.summary}}</small>\n </div>\n </ng-template>\n </fs-list-column>\n <fs-list-column align=\"center\">\n <ng-template fs-list-header>Status</ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <ng-container *ngIf=\"row.host || row.processId; else status\">\n <fs-popover \n [maxWidth]=\"null\"\n [template]=\"statusPopover\" \n size=\"small\">\n <ng-container *ngTemplateOutlet=\"status\"></ng-container>\n </fs-popover>\n <ng-template #statusPopover>\n <div *ngIf=\"row.host\">Host: {{row.host}}</div>\n <div *ngIf=\"row.processId\">Process ID: {{row.processId}}</div>\n <div *ngIf=\"row.processState\">Process State: {{CronProcessStates[row.processState]}}</div>\n </ng-template>\n </ng-container>\n <ng-template #status>\n {{CronStates[row.state]}}\n </ng-template>\n <ng-container *ngIf=\"row.state === CronState.Running\">\n <div class=\"small\">\n Duration: {{ row.runningDuration | fsDateDuration: { hours: true, minutes: true, seconds: true } }}\n </div>\n </ng-container> \n </ng-template>\n </fs-list-column>\n <fs-list-column>\n <ng-template fs-list-header>Last Ran</ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <ng-container *ngIf=\"row.duration===null; else lastRan\">\n Never\n </ng-container>\n <ng-template #lastRan>\n <fs-date-ago [date]=\"row.createDate\"></fs-date-ago>\n <div class=\"small\" *ngIf=\"row.duration\">\n Duration: {{ row.duration | fsDateDuration: { hours: true, minutes: true, seconds: true } }}\n </div>\n </ng-template>\n </ng-template>\n </fs-list-column>\n <fs-list-column>\n <ng-template fs-list-header>Next Run</ng-template>\n <ng-template fs-list-cell let-row=\"row\">\n <ng-container *ngIf=\"row.state !== CronState.Disabled\">\n <app-next-run [cron]=\"row\"></app-next-run>\n </ng-container>\n </ng-template>\n </fs-list-column>\n</fs-list>\n", styles: [""] }]
|
|
766
858
|
}], ctorParameters: function () { return [{ type: i1$1.FsMessage }, { type: i1.MatDialog }, { type: i3$3.FsPrompt }]; }, propDecorators: { list: [{
|
|
767
859
|
type: ViewChild,
|
|
768
860
|
args: [FsListComponent, { static: true }]
|
|
@@ -1341,6 +1433,7 @@ class FsSystemModule {
|
|
|
1341
1433
|
}
|
|
1342
1434
|
FsSystemModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: FsSystemModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1343
1435
|
FsSystemModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: FsSystemModule, declarations: [DashboardComponent,
|
|
1436
|
+
CronNextRunComponent,
|
|
1344
1437
|
CronsComponent,
|
|
1345
1438
|
SettingsComponent,
|
|
1346
1439
|
KeyNameValuePipe,
|
|
@@ -1445,6 +1538,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
1445
1538
|
],
|
|
1446
1539
|
declarations: [
|
|
1447
1540
|
DashboardComponent,
|
|
1541
|
+
CronNextRunComponent,
|
|
1448
1542
|
CronsComponent,
|
|
1449
1543
|
SettingsComponent,
|
|
1450
1544
|
KeyNameValuePipe,
|