@firestitch/system 18.0.9 → 18.0.11

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.
@@ -17,18 +17,18 @@ import * as i10 from '@firestitch/common';
17
17
  import { FsCommonModule } from '@firestitch/common';
18
18
  import * as i4$2 from '@firestitch/date';
19
19
  import { FsDateModule, parse } from '@firestitch/date';
20
- import * as i9 from '@firestitch/dialog';
20
+ import * as i8 from '@firestitch/dialog';
21
21
  import { FsDialogModule } from '@firestitch/dialog';
22
22
  import * as i3 from '@firestitch/form';
23
23
  import { FsFormModule } from '@firestitch/form';
24
- import * as i8 from '@firestitch/label';
24
+ import * as i6 from '@firestitch/label';
25
25
  import { FsLabelModule } from '@firestitch/label';
26
26
  import * as i5 from '@firestitch/list';
27
27
  import { FsListComponent, FsListModule, PaginationStrategy } 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, takeUntil, switchMap, filter, takeWhile } from 'rxjs/operators';
31
+ import { map, tap, takeUntil, switchMap, filter, take, takeWhile } from 'rxjs/operators';
32
32
  import * as i7$2 from '@angular/material/expansion';
33
33
  import { MatExpansionModule } from '@angular/material/expansion';
34
34
  import * as i10$1 from '@angular/material/form-field';
@@ -37,7 +37,7 @@ import * as i3$1 from '@angular/material/icon';
37
37
  import { MatIconModule } from '@angular/material/icon';
38
38
  import * as i11 from '@angular/material/input';
39
39
  import { MatInputModule } from '@angular/material/input';
40
- import * as i6 from '@angular/material/progress-spinner';
40
+ import * as i6$1 from '@angular/material/progress-spinner';
41
41
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
42
42
  import * as i12 from '@angular/material/select';
43
43
  import { MatSelectModule } from '@angular/material/select';
@@ -50,7 +50,7 @@ import { FsDatePickerModule } from '@firestitch/datepicker';
50
50
  import * as i14 from '@firestitch/file';
51
51
  import { FsFileModule } from '@firestitch/file';
52
52
  import { FsFileManagerModule } from '@firestitch/file-manager';
53
- import * as i9$1 from '@firestitch/menu';
53
+ import * as i9 from '@firestitch/menu';
54
54
  import { FsMenuModule } from '@firestitch/menu';
55
55
  import * as i7$1 from '@firestitch/skeleton';
56
56
  import { FsSkeletonModule } from '@firestitch/skeleton';
@@ -75,7 +75,7 @@ class ExplainComponent {
75
75
  this.explain = _data.explain;
76
76
  }
77
77
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ExplainComponent, deps: [{ token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
78
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: ExplainComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog>\n <h1 mat-dialog-title>Explain</h1>\n <mat-dialog-content>\n <div class=\"explain-popover\">{{explain | json}}</div>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"undefined\">\n Done\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: [".explain-popover{white-space:pre}\n"], dependencies: [{ kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i3.FsButtonDirective, selector: "[mat-raised-button]:not([fsFormButtonStandalone]),[mat-button]:not([fsFormButtonStandalone]),[mat-flat-button]:not([fsFormButtonStandalone]),[mat-stroked-button]:not([fsFormButtonStandalone])", inputs: ["name", "dirtySubmit", "form"] }, { kind: "component", type: i9.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
78
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: ExplainComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog>\n <h1 mat-dialog-title>Explain</h1>\n <mat-dialog-content>\n <div class=\"explain-popover\">{{explain | json}}</div>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"undefined\">\n Done\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: [".explain-popover{white-space:pre}\n"], dependencies: [{ kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i3.FsButtonDirective, selector: "[mat-raised-button]:not([fsFormButtonStandalone]),[mat-button]:not([fsFormButtonStandalone]),[mat-flat-button]:not([fsFormButtonStandalone]),[mat-stroked-button]:not([fsFormButtonStandalone])", inputs: ["name", "dirtySubmit", "form"] }, { kind: "component", type: i8.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
79
79
  }
80
80
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ExplainComponent, decorators: [{
81
81
  type: Component,
@@ -122,7 +122,7 @@ class QueryLogComponent {
122
122
  return this.queryBlock?.orderingOperation;
123
123
  }
124
124
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: QueryLogComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
125
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: QueryLogComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog>\n <h1 mat-dialog-title>Query Log</h1>\n <mat-dialog-content>\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <fs-label-field>\n <fs-label>Duration</fs-label>\n {{queryLog.duration}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Optimized</fs-label>\n {{queryLog.optimized ? 'Yes' : 'No'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Query Cost</fs-label>\n {{queryLog.queryCost}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Raw Explain</fs-label>\n <a (click)=\"openExplain()\">View</a>\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>URL</fs-label>\n {{queryLog.path | fsFormatTruncate: 50}}\n </fs-label-field>\n </div>\n\n <mat-tab-group>\n <mat-tab label=\"Query\">\n <fs-clipboard-button\n [content]=\"queryLog.prettyQuery\">\n </fs-clipboard-button>\n <div [innerHTML]=\"queryLog.prettyQuery\" class=\"query\"></div>\n </mat-tab>\n \n <mat-tab label=\"Explain\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock, selectId: queryBlock.selectId, costInfo: queryBlock.costInfo }\"></ng-container>\n </mat-tab>\n </mat-tab-group>\n\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"undefined\">\n Done\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n\n<ng-template #nestedLoop let-queryBlock=\"queryBlock\" let-selectId=\"selectId\" let-costInfo=\"costInfo\">\n <ng-container *ngIf=\"selectId\">\n <h1>Select {{selectId}}</h1>\n </ng-container>\n \n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <ng-container *ngIf=\"costInfo?.queryCost\">\n <fs-label-field>\n <fs-label>Query Cost</fs-label>\n {{costInfo.queryCost}}\n </fs-label-field>\n </ng-container>\n <ng-container *ngIf=\"queryBlock.orderingOperation\">\n <fs-label-field>\n <fs-label>Ordering Operation</fs-label>\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.orderingOperation }\"></ng-container>\n </fs-label-field>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.groupingOperation\">\n <fs-label-field>\n <fs-label>Grouping Operation</fs-label>\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.groupingOperation }\"></ng-container>\n </fs-label-field>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.duplicatesRemoval\">\n <fs-label-field>\n <fs-label>Duplicates Removal</fs-label>\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.duplicatesRemoval }\"></ng-container>\n </fs-label-field>\n </ng-container>\n </div>\n\n <ng-container *ngIf=\"queryBlock.orderingOperation\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.orderingOperation }\"></ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.groupingOperation\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.groupingOperation }\"></ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.duplicatesRemoval\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.duplicatesRemoval }\"></ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.table\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: { nestedLoop: [ queryBlock ]} }\"></ng-container>\n \n <ng-container *ngIf=\"queryBlock.table.attachedSubqueries\"> \n <fs-label>Attached Subqueries</fs-label>\n <ng-container *ngFor=\"let subquery of queryBlock.table.attachedSubqueries\">\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container> \n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock, selectId: subquery.queryBlock.selectId, costInfo: subquery.queryBlock.costInfo }\"></ng-container>\n </ng-container>\n </ng-container> \n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.nestedLoop\">\n <table class=\"fs-list-table style-line\">\n <thead>\n <tr>\n <th>Table</th>\n <th>Type</th>\n <th>Keys</th>\n <th>Ref</th>\n <th>Rows</th>\n <th>Filtered</th>\n <th>Extra</th>\n <th>Cost</th>\n </tr>\n </thead>\n <tbody>\n <ng-container *ngFor=\"let item of queryBlock.nestedLoop; let index = index\">\n <tr>\n <td>\n {{item.table.tableName}}\n </td>\n <td>\n <fs-popover [template]=\"accessTypePopover\" [data]=\"item.table.accessType\">\n <span class=\"access-type\" [ngClass]=\"item.table.accessType\">{{item.table.accessType}}</span>\n </fs-popover> \n </td>\n <td>\n <fs-popover \n [template]=\"keysPopover\"\n [maxWidth]=\"null\"\n [data]=\"{ possibleKeys: item.table.possibleKeys, key: item.table.key }\">\n {{item.table.key}}\n </fs-popover>\n </td>\n <td>\n <div class=\"fs-delimit\">\n <ng-container *ngFor=\"let ref of item.table.ref\">\n <span>{{ref}}</span>\n </ng-container>\n </div>\n </td>\n <td>\n {{item.table.rowsExaminedPerScan}}\n </td>\n <td>\n {{item.table.filtered}}\n </td>\n <td>\n <div class=\"fs-delimit\">\n <ng-container *ngIf=\"item.table.indexCondition\">\n <span>\n <fs-popover \n [template]=\"usingIndexCondition\" \n [maxWidth]=\"null\"\n [data]=\"item.table.indexCondition\">\n Using Index Condition\n </fs-popover>\n </span>\n </ng-container>\n <ng-container *ngIf=\"item.table.attachedCondition\">\n <span>\n <fs-popover \n [template]=\"usingWhere\" \n [maxWidth]=\"null\"\n [data]=\"item.table.attachedCondition\">\n Using Where\n </fs-popover>\n </span>\n </ng-container>\n <ng-container *ngIf=\"item.usingIndex\">\n <span>Using Index</span>\n </ng-container> \n <ng-container *ngIf=\"item.usingFilesort\">\n <span class=\"critical\">Using File Sort</span>\n </ng-container>\n \n <ng-container *ngIf=\"item.usingTemporaryTable\">\n <span class=\"critical\">Temporary Table</span>\n </ng-container>\n </div>\n </td>\n <td> \n <fs-popover [template]=\"tableCostPopover\" [data]=\"item.table?.costInfo\">\n {{item.table?.costInfo.prefixCost}}\n </fs-popover>\n <ng-template #tableCostPopover let-data=\"data\">\n <div>Eval Cost: {{data.evalCost}}</div>\n <div>Read Cost: {{data.readCost}}</div>\n <div>Prefix Cost: {{data.prefixCost}}</div>\n <div>Data Read Per Join: {{data.dataReadPerJoin}}</div>\n </ng-template>\n </td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n <br>\n </ng-container> \n \n <ng-container *ngIf=\"queryBlock.selectListSubqueries\">\n <br>\n <fs-label>Select List Subqueries</fs-label>\n <ng-container *ngFor=\"let subquery of queryBlock.selectListSubqueries\">\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container> \n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock, selectId: subquery.queryBlock.selectId, costInfo: subquery.queryBlock.costInfo }\"></ng-container>\n </ng-container>\n </ng-container>\n<!-- \n <ng-container *ngIf=\"queryBlock.queryBlockattachedSubqueries\">\n <br>\n <fs-label>Attached Subqueries</fs-label>\n <ng-container *ngFor=\"let subquery of queryBlock.attachedSubqueries\">\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container>\n </ng-container>\n </ng-container> -->\n</ng-template>\n\n<ng-template #keysPopover let-data=\"data\">\n <div class=\"fs-delimit\">\n <ng-container *ngFor=\"let possibleKey of data.possibleKeys\">\n <span [ngClass]=\"{ 'query-log-used-key': possibleKey === data.key }\">{{possibleKey}}</span>\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #usingWhere let-data=\"data\">\n {{data}}\n</ng-template>\n\n<ng-template #usingIndexCondition let-data=\"data\">\n {{data}}\n</ng-template>\n\n<ng-template #accessTypePopover let-data=\"data\">\n {{accessTypes[data]}}\n</ng-template>\n\n\n<ng-template #queryBlockCritical let-queryBlock=\"queryBlock\">\n <div class=\"fs-delimit\">\n <ng-container *ngIf=\"queryBlock.usingFilesort\">\n <span class=\"critical\">Using File Sort</span>\n </ng-container>\n \n <ng-container *ngIf=\"queryBlock.usingTemporaryTable\">\n <span class=\"critical\">Temporary Table</span>\n </ng-container>\n </div>\n</ng-template>", styles: ["::ng-deep .query-log-used-key{font-weight:700}::ng-deep .explain-popover{white-space:pre}.critical{color:red}fs-clipboard-button{float:right}.query{white-space:break-spaces}.access-type{color:green}.access-type.fulltext,.access-type.index,.access-type.range{color:orange}.access-type.ALL{color:red}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i4$1.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i4$1.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i3.FsButtonDirective, selector: "[mat-raised-button]:not([fsFormButtonStandalone]),[mat-button]:not([fsFormButtonStandalone]),[mat-flat-button]:not([fsFormButtonStandalone]),[mat-stroked-button]:not([fsFormButtonStandalone])", inputs: ["name", "dirtySubmit", "form"] }, { kind: "component", type: i8.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i8.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i7.FsPopoverComponent, selector: "fs-popover" }, { kind: "component", type: i9.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "component", type: i2.FsClipboardButtonComponent, selector: "fs-clipboard-button", inputs: ["content", "tooltip"] }, { kind: "pipe", type: i10.FsFormatTruncatePipe, name: "fsFormatTruncate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
125
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: QueryLogComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog>\n <h1 mat-dialog-title>Query Log</h1>\n <mat-dialog-content>\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <fs-label-field>\n <fs-label>Duration</fs-label>\n {{queryLog.duration}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Optimized</fs-label>\n {{queryLog.optimized ? 'Yes' : 'No'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Query Cost</fs-label>\n {{queryLog.queryCost}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Raw Explain</fs-label>\n <a (click)=\"openExplain()\">View</a>\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>URL</fs-label>\n {{queryLog.path | fsFormatTruncate: 50}}\n </fs-label-field>\n </div>\n\n <mat-tab-group>\n <mat-tab label=\"Query\">\n <fs-clipboard-button\n [content]=\"queryLog.prettyQuery\">\n </fs-clipboard-button>\n <div [innerHTML]=\"queryLog.prettyQuery\" class=\"query\"></div>\n </mat-tab>\n \n <mat-tab label=\"Explain\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock, selectId: queryBlock.selectId, costInfo: queryBlock.costInfo }\"></ng-container>\n </mat-tab>\n </mat-tab-group>\n\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"undefined\">\n Done\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n\n<ng-template #nestedLoop let-queryBlock=\"queryBlock\" let-selectId=\"selectId\" let-costInfo=\"costInfo\">\n <ng-container *ngIf=\"selectId\">\n <h1>Select {{selectId}}</h1>\n </ng-container>\n \n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <ng-container *ngIf=\"costInfo?.queryCost\">\n <fs-label-field>\n <fs-label>Query Cost</fs-label>\n {{costInfo.queryCost}}\n </fs-label-field>\n </ng-container>\n <ng-container *ngIf=\"queryBlock.orderingOperation\">\n <fs-label-field>\n <fs-label>Ordering Operation</fs-label>\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.orderingOperation }\"></ng-container>\n </fs-label-field>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.groupingOperation\">\n <fs-label-field>\n <fs-label>Grouping Operation</fs-label>\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.groupingOperation }\"></ng-container>\n </fs-label-field>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.duplicatesRemoval\">\n <fs-label-field>\n <fs-label>Duplicates Removal</fs-label>\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.duplicatesRemoval }\"></ng-container>\n </fs-label-field>\n </ng-container>\n </div>\n\n <ng-container *ngIf=\"queryBlock.orderingOperation\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.orderingOperation }\"></ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.groupingOperation\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.groupingOperation }\"></ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.duplicatesRemoval\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: queryBlock.duplicatesRemoval }\"></ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.table\">\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: { nestedLoop: [ queryBlock ]} }\"></ng-container>\n \n <ng-container *ngIf=\"queryBlock.table.attachedSubqueries\"> \n <fs-label>Attached Subqueries</fs-label>\n <ng-container *ngFor=\"let subquery of queryBlock.table.attachedSubqueries\">\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container> \n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock, selectId: subquery.queryBlock.selectId, costInfo: subquery.queryBlock.costInfo }\"></ng-container>\n </ng-container>\n </ng-container> \n </ng-container>\n\n <ng-container *ngIf=\"queryBlock.nestedLoop\">\n <table class=\"fs-list-table style-line\">\n <thead>\n <tr>\n <th>Table</th>\n <th>Type</th>\n <th>Keys</th>\n <th>Ref</th>\n <th>Rows</th>\n <th>Filtered</th>\n <th>Extra</th>\n <th>Cost</th>\n </tr>\n </thead>\n <tbody>\n <ng-container *ngFor=\"let item of queryBlock.nestedLoop; let index = index\">\n <tr>\n <td>\n {{item.table.tableName}}\n </td>\n <td>\n <fs-popover [template]=\"accessTypePopover\" [data]=\"item.table.accessType\">\n <span class=\"access-type\" [ngClass]=\"item.table.accessType\">{{item.table.accessType}}</span>\n </fs-popover> \n </td>\n <td>\n <fs-popover \n [template]=\"keysPopover\"\n [maxWidth]=\"null\"\n [data]=\"{ possibleKeys: item.table.possibleKeys, key: item.table.key }\">\n {{item.table.key}}\n </fs-popover>\n </td>\n <td>\n <div class=\"fs-delimit\">\n <ng-container *ngFor=\"let ref of item.table.ref\">\n <span>{{ref}}</span>\n </ng-container>\n </div>\n </td>\n <td>\n {{item.table.rowsExaminedPerScan}}\n </td>\n <td>\n {{item.table.filtered}}\n </td>\n <td>\n <div class=\"fs-delimit\">\n <ng-container *ngIf=\"item.table.indexCondition\">\n <span>\n <fs-popover \n [template]=\"usingIndexCondition\" \n [maxWidth]=\"null\"\n [data]=\"item.table.indexCondition\">\n Using Index Condition\n </fs-popover>\n </span>\n </ng-container>\n <ng-container *ngIf=\"item.table.attachedCondition\">\n <span>\n <fs-popover \n [template]=\"usingWhere\" \n [maxWidth]=\"null\"\n [data]=\"item.table.attachedCondition\">\n Using Where\n </fs-popover>\n </span>\n </ng-container>\n <ng-container *ngIf=\"item.usingIndex\">\n <span>Using Index</span>\n </ng-container> \n <ng-container *ngIf=\"item.usingFilesort\">\n <span class=\"critical\">Using File Sort</span>\n </ng-container>\n \n <ng-container *ngIf=\"item.usingTemporaryTable\">\n <span class=\"critical\">Temporary Table</span>\n </ng-container>\n </div>\n </td>\n <td> \n <fs-popover [template]=\"tableCostPopover\" [data]=\"item.table?.costInfo\">\n {{item.table?.costInfo.prefixCost}}\n </fs-popover>\n <ng-template #tableCostPopover let-data=\"data\">\n <div>Eval Cost: {{data.evalCost}}</div>\n <div>Read Cost: {{data.readCost}}</div>\n <div>Prefix Cost: {{data.prefixCost}}</div>\n <div>Data Read Per Join: {{data.dataReadPerJoin}}</div>\n </ng-template>\n </td>\n </tr>\n </ng-container>\n </tbody>\n </table>\n <br>\n </ng-container> \n \n <ng-container *ngIf=\"queryBlock.selectListSubqueries\">\n <br>\n <fs-label>Select List Subqueries</fs-label>\n <ng-container *ngFor=\"let subquery of queryBlock.selectListSubqueries\">\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container> \n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock, selectId: subquery.queryBlock.selectId, costInfo: subquery.queryBlock.costInfo }\"></ng-container>\n </ng-container>\n </ng-container>\n<!-- \n <ng-container *ngIf=\"queryBlock.queryBlockattachedSubqueries\">\n <br>\n <fs-label>Attached Subqueries</fs-label>\n <ng-container *ngFor=\"let subquery of queryBlock.attachedSubqueries\">\n <ng-container [ngTemplateOutlet]=\"queryBlockCritical\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"nestedLoop\" [ngTemplateOutletContext]=\"{ queryBlock: subquery.queryBlock }\"></ng-container>\n </ng-container>\n </ng-container> -->\n</ng-template>\n\n<ng-template #keysPopover let-data=\"data\">\n <div class=\"fs-delimit\">\n <ng-container *ngFor=\"let possibleKey of data.possibleKeys\">\n <span [ngClass]=\"{ 'query-log-used-key': possibleKey === data.key }\">{{possibleKey}}</span>\n </ng-container>\n </div>\n</ng-template>\n\n<ng-template #usingWhere let-data=\"data\">\n {{data}}\n</ng-template>\n\n<ng-template #usingIndexCondition let-data=\"data\">\n {{data}}\n</ng-template>\n\n<ng-template #accessTypePopover let-data=\"data\">\n {{accessTypes[data]}}\n</ng-template>\n\n\n<ng-template #queryBlockCritical let-queryBlock=\"queryBlock\">\n <div class=\"fs-delimit\">\n <ng-container *ngIf=\"queryBlock.usingFilesort\">\n <span class=\"critical\">Using File Sort</span>\n </ng-container>\n \n <ng-container *ngIf=\"queryBlock.usingTemporaryTable\">\n <span class=\"critical\">Temporary Table</span>\n </ng-container>\n </div>\n</ng-template>", styles: ["::ng-deep .query-log-used-key{font-weight:700}::ng-deep .explain-popover{white-space:pre}.critical{color:red}fs-clipboard-button{float:right}.query{white-space:break-spaces}.access-type{color:green}.access-type.fulltext,.access-type.index,.access-type.range{color:orange}.access-type.ALL{color:red}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i4$1.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i4$1.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i3.FsButtonDirective, selector: "[mat-raised-button]:not([fsFormButtonStandalone]),[mat-button]:not([fsFormButtonStandalone]),[mat-flat-button]:not([fsFormButtonStandalone]),[mat-stroked-button]:not([fsFormButtonStandalone])", inputs: ["name", "dirtySubmit", "form"] }, { kind: "component", type: i6.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i6.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i7.FsPopoverComponent, selector: "fs-popover" }, { kind: "component", type: i8.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "component", type: i2.FsClipboardButtonComponent, selector: "fs-clipboard-button", inputs: ["content", "tooltip"] }, { kind: "pipe", type: i10.FsFormatTruncatePipe, name: "fsFormatTruncate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
126
126
  }
127
127
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: QueryLogComponent, decorators: [{
128
128
  type: Component,
@@ -423,7 +423,7 @@ class ApiLogComponent {
423
423
  }
424
424
  }
425
425
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ApiLogComponent, deps: [{ token: i1.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
426
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: ApiLogComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"apiLog\">\n\n <div mat-dialog-title>API Log</div>\n\n <mat-dialog-content>\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Type\n </fs-label>\n {{apiLog.type}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>\n Status\n </fs-label>\n {{apiLogStates[apiLog.state]}}\n </fs-label-field>\n\n <fs-label-field *ngIf=\"apiLog.code\">\n <fs-label>\n Code\n </fs-label>\n {{apiLog.code}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{apiLog.createDate|fsDateFormat: 'full-date-time'}}\n </fs-label-field>\n\n <fs-label-field *ngIf=\"apiLog.direction\">\n <fs-label>\n Direction\n </fs-label>\n {{apiLog.direction}}\n </fs-label-field>\n\n <fs-label-field *ngIf=\"apiLog.length\">\n <fs-label>\n Duration\n </fs-label>\n {{ apiLog.length | fsDateDuration }}\n </fs-label-field>\n\n <ng-container *ngIf=\"apiLog.method\">\n <fs-label-field *ngIf=\"apiLog.method\">\n <fs-label>\n Method\n </fs-label>\n {{apiLog.method}}\n </fs-label-field>\n </ng-container>\n \n <fs-label-field *ngIf=\"apiLog.url\">\n <fs-label>\n URL\n </fs-label>\n {{apiLog.url}}\n </fs-label-field>\n </div>\n\n <fs-label-field *ngIf=\"apiLog.message\">\n <fs-label>\n Message\n </fs-label>\n {{apiLog.message}}\n </fs-label-field>\n\n <div>\n <fs-label-field *ngIf=\"apiLog.request\">\n <fs-label>\n Request\n </fs-label>\n <pre>{{apiLog.request|json}}</pre>\n </fs-label-field>\n\n <fs-label-field *ngIf=\"apiLog.response\">\n <fs-label>\n Response\n </fs-label>\n <pre>{{apiLog.response|json}}</pre>\n </fs-label-field>\n </div>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button \n mat-button \n [mat-dialog-close]=\"true\" \n color=\"primary\">\n Done\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i7$1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: i8.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i8.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i9.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }, { kind: "pipe", type: i4$2.FsDateDurationPipe, name: "fsDateDuration" }, { kind: "pipe", type: i4$2.FsDateFormatPipe, name: "fsDateFormat" }] });
426
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: ApiLogComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"apiLog\">\n\n <div mat-dialog-title>API Log</div>\n\n <mat-dialog-content>\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Type\n </fs-label>\n {{apiLog.type}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>\n Status\n </fs-label>\n {{apiLogStates[apiLog.state]}}\n </fs-label-field>\n\n <fs-label-field *ngIf=\"apiLog.code\">\n <fs-label>\n Code\n </fs-label>\n {{apiLog.code}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{apiLog.createDate|fsDateFormat: 'full-date-time'}}\n </fs-label-field>\n\n <fs-label-field *ngIf=\"apiLog.direction\">\n <fs-label>\n Direction\n </fs-label>\n {{apiLog.direction}}\n </fs-label-field>\n\n <fs-label-field *ngIf=\"apiLog.length\">\n <fs-label>\n Duration\n </fs-label>\n {{ apiLog.length | fsDateDuration }}\n </fs-label-field>\n\n <ng-container *ngIf=\"apiLog.method\">\n <fs-label-field *ngIf=\"apiLog.method\">\n <fs-label>\n Method\n </fs-label>\n {{apiLog.method}}\n </fs-label-field>\n </ng-container>\n \n <fs-label-field *ngIf=\"apiLog.url\">\n <fs-label>\n URL\n </fs-label>\n {{apiLog.url}}\n </fs-label-field>\n </div>\n\n <fs-label-field *ngIf=\"apiLog.message\">\n <fs-label>\n Message\n </fs-label>\n {{apiLog.message}}\n </fs-label-field>\n\n <div>\n <fs-label-field *ngIf=\"apiLog.request\">\n <fs-label>\n Request\n </fs-label>\n <pre>{{apiLog.request|json}}</pre>\n </fs-label-field>\n\n <fs-label-field *ngIf=\"apiLog.response\">\n <fs-label>\n Response\n </fs-label>\n <pre>{{apiLog.response|json}}</pre>\n </fs-label-field>\n </div>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button \n mat-button \n [mat-dialog-close]=\"true\" \n color=\"primary\">\n Done\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i7$1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: i6.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i6.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i8.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }, { kind: "pipe", type: i4$2.FsDateDurationPipe, name: "fsDateDuration" }, { kind: "pipe", type: i4$2.FsDateFormatPipe, name: "fsDateFormat" }] });
427
427
  }
428
428
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ApiLogComponent, decorators: [{
429
429
  type: Component,
@@ -559,7 +559,7 @@ class CronLogComponent {
559
559
  }, {});
560
560
  }
561
561
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CronLogComponent, deps: [{ token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
562
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: CronLogComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"cronLog\">\n <div mat-dialog-title>\n Cron Log\n </div>\n <mat-dialog-content>\n <div class=\"row\">\n <fs-label-field>\n <fs-label>\n Status\n </fs-label>\n <div [ngStyle]=\"{ color: CronLogStateColors[cronLog.state]}\">\n {{ CronLogStates[cronLog.state] || cronLog.state }}\n </div>\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n <fs-date-ago [date]=\"cronLog.createDate\"></fs-date-ago>\n </fs-label-field>\n </div>\n <fs-label-field *ngIf=\"cronLog.message\">\n <fs-label>\n Message\n </fs-label>\n <div class=\"message\">\n {{ cronLog.message }}\n </div>\n </fs-label-field>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n </mat-dialog-actions>\n</fs-dialog>", styles: [".message{white-space:pre-line}.row{display:flex;flex-wrap:wrap}.row fs-label-field:not(:last-child){margin-right:40px}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i4$2.FsDateAgoComponent, selector: "fs-date-ago", inputs: ["date", "showTime", "format", "showTooltip", "tooltipDateFormat"] }, { kind: "directive", type: i7$1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: i8.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i8.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i9.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
562
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: CronLogComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"cronLog\">\n <div mat-dialog-title>\n Cron Log\n </div>\n <mat-dialog-content>\n <div class=\"row\">\n <fs-label-field>\n <fs-label>\n Status\n </fs-label>\n <div [ngStyle]=\"{ color: CronLogStateColors[cronLog.state]}\">\n {{ CronLogStates[cronLog.state] || cronLog.state }}\n </div>\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n <fs-date-ago [date]=\"cronLog.createDate\"></fs-date-ago>\n </fs-label-field>\n </div>\n <fs-label-field *ngIf=\"cronLog.message\">\n <fs-label>\n Message\n </fs-label>\n <div class=\"message\">\n {{ cronLog.message }}\n </div>\n </fs-label-field>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n </mat-dialog-actions>\n</fs-dialog>", styles: [".message{white-space:pre-line}.row{display:flex;flex-wrap:wrap}.row fs-label-field:not(:last-child){margin-right:40px}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i4$2.FsDateAgoComponent, selector: "fs-date-ago", inputs: ["date", "showTime", "format", "showTooltip", "tooltipDateFormat"] }, { kind: "directive", type: i7$1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: i6.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i6.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i8.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
563
563
  }
564
564
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CronLogComponent, decorators: [{
565
565
  type: Component,
@@ -569,20 +569,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImpor
569
569
  args: [MAT_DIALOG_DATA]
570
570
  }] }] });
571
571
 
572
- class CronComponent {
572
+ class CronLogsComponent {
573
573
  cron;
574
- tabIndex = 0;
575
- CronStates = indexNameValue(CronStates);
576
- CronProcessStates = indexNameValue(CronProcessStates);
577
- CronLogStates = indexNameValue(CronLogStates);
578
574
  CronLogStateColors = {};
579
575
  config;
576
+ CronLogStates = indexNameValue(CronLogStates);
580
577
  cronActions;
581
578
  _cronData = inject(CronData);
582
579
  _dialog = inject(MatDialog);
583
- _cdRef = inject(ChangeDetectorRef);
584
580
  _data = inject(MAT_DIALOG_DATA);
585
581
  ngOnInit() {
582
+ this.cron = this._data.cron;
586
583
  this.load();
587
584
  this.CronLogStateColors = CronLogStates
588
585
  .reduce((accum, cronLogState) => {
@@ -598,6 +595,60 @@ class CronComponent {
598
595
  width: '85%',
599
596
  });
600
597
  }
598
+ load() {
599
+ this.config = {
600
+ filters: [
601
+ {
602
+ type: ItemType.Select,
603
+ name: 'state',
604
+ label: 'Status',
605
+ values: [
606
+ { name: 'All', value: null },
607
+ ...CronLogStates,
608
+ ],
609
+ },
610
+ {
611
+ type: ItemType.DateRange,
612
+ name: 'date',
613
+ label: ['From Date', 'To Date'],
614
+ },
615
+ ],
616
+ fetch: (query) => {
617
+ query = {
618
+ ...query,
619
+ cronId: this.cron.id,
620
+ };
621
+ return this._cronData.cronLogGets(query);
622
+ },
623
+ };
624
+ }
625
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CronLogsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
626
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: CronLogsComponent, isStandalone: true, selector: "app-cron-logs", inputs: { cron: "cron" }, ngImport: i0, template: "<fs-list [config]=\"config\">\n <fs-list-column\n name=\"state\"\n title=\"Status\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <a\n (click)=\"cronLogOpen(row)\"\n [ngStyle]=\"{ color: CronLogStateColors[row.state] }\">\n {{ CronLogStates[row.state] || row.state }}\n </a>\n </ng-template>\n </fs-list-column>\n <fs-list-column\n title=\"Message\"\n class=\"col-message\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <div class=\"message\">\n {{ row.message }}\n </div>\n </ng-template>\n </fs-list-column>\n <fs-list-column\n title=\"Duration\"\n class=\"col-message\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <ng-container *ngIf=\"row.duration\">\n {{ row.duration | fsDateDuration: 'hour-minute-second' }}\n </ng-container>\n </ng-template>\n </fs-list-column>\n <fs-list-column\n name=\"create_date\"\n title=\"Date\"\n class=\"col-date\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <fs-date-ago [date]=\"row.createDate\"></fs-date-ago>\n </ng-template>\n </fs-list-column>\n</fs-list>", styles: [":host ::ng-deep .col-message .message{white-space:break-spaces;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}:host ::ng-deep .col-date{white-space:nowrap}h1 .small{line-height:normal}.row{display:flex;flex-wrap:wrap}.row fs-label-field:not(:last-child){margin-right:40px}.message{white-space:pre-line}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FsListModule }, { kind: "component", type: i5.FsListComponent, selector: "fs-list", inputs: ["config", "loaderLines"], outputs: ["filtersReady"] }, { kind: "directive", type: i5.FsListColumnDirective, selector: "fs-list-column", inputs: ["show", "title", "name", "customizable", "sortable", "sortableDefault", "sortableDirection", "direction", "align", "width", "class"] }, { kind: "directive", type: i5.FsListCellDirective, selector: "[fs-list-cell]", inputs: ["colspan", "align", "class"] }, { kind: "ngmodule", type: FsDateModule }, { kind: "pipe", type: i4$2.FsDateDurationPipe, name: "fsDateDuration" }, { kind: "component", type: i4$2.FsDateAgoComponent, selector: "fs-date-ago", inputs: ["date", "showTime", "format", "showTooltip", "tooltipDateFormat"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
627
+ }
628
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CronLogsComponent, decorators: [{
629
+ type: Component,
630
+ args: [{ selector: 'app-cron-logs', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
631
+ CommonModule,
632
+ FsListModule,
633
+ FsDateModule,
634
+ ], template: "<fs-list [config]=\"config\">\n <fs-list-column\n name=\"state\"\n title=\"Status\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <a\n (click)=\"cronLogOpen(row)\"\n [ngStyle]=\"{ color: CronLogStateColors[row.state] }\">\n {{ CronLogStates[row.state] || row.state }}\n </a>\n </ng-template>\n </fs-list-column>\n <fs-list-column\n title=\"Message\"\n class=\"col-message\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <div class=\"message\">\n {{ row.message }}\n </div>\n </ng-template>\n </fs-list-column>\n <fs-list-column\n title=\"Duration\"\n class=\"col-message\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <ng-container *ngIf=\"row.duration\">\n {{ row.duration | fsDateDuration: 'hour-minute-second' }}\n </ng-container>\n </ng-template>\n </fs-list-column>\n <fs-list-column\n name=\"create_date\"\n title=\"Date\"\n class=\"col-date\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <fs-date-ago [date]=\"row.createDate\"></fs-date-ago>\n </ng-template>\n </fs-list-column>\n</fs-list>", styles: [":host ::ng-deep .col-message .message{white-space:break-spaces;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}:host ::ng-deep .col-date{white-space:nowrap}h1 .small{line-height:normal}.row{display:flex;flex-wrap:wrap}.row fs-label-field:not(:last-child){margin-right:40px}.message{white-space:pre-line}\n"] }]
635
+ }], propDecorators: { cron: [{
636
+ type: Input
637
+ }] } });
638
+
639
+ class CronComponent {
640
+ cron;
641
+ tabIndex = 0;
642
+ CronStates = indexNameValue(CronStates);
643
+ CronProcessStates = indexNameValue(CronProcessStates);
644
+ config;
645
+ cronActions;
646
+ _cronData = inject(CronData);
647
+ _cdRef = inject(ChangeDetectorRef);
648
+ _data = inject(MAT_DIALOG_DATA);
649
+ ngOnInit() {
650
+ this.load();
651
+ }
601
652
  cronActionClick(cronAction) {
602
653
  cronAction
603
654
  .action(this.cron)
@@ -609,42 +660,15 @@ class CronComponent {
609
660
  this.tabIndex = index;
610
661
  }
611
662
  load() {
612
- const query = {
663
+ this._cronData
664
+ .get(this._data.cron.id, {
613
665
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
614
- };
615
- this._cronData.get(this._data.cron.id, query)
666
+ })
616
667
  .subscribe((cron) => {
617
668
  this.cron = {
618
669
  ...this._data.cron,
619
670
  ...cron,
620
671
  };
621
- if (this._data.loadCronLogs) {
622
- this.config = {
623
- filters: [
624
- {
625
- type: ItemType.Select,
626
- name: 'state',
627
- label: 'Status',
628
- values: [
629
- { name: 'All', value: null },
630
- ...CronLogStates,
631
- ],
632
- },
633
- {
634
- type: ItemType.DateRange,
635
- name: 'date',
636
- label: ['From Date', 'To Date'],
637
- },
638
- ],
639
- fetch: (query) => {
640
- query = {
641
- ...query,
642
- cronId: this.cron.id,
643
- };
644
- return this._data.loadCronLogs(query);
645
- },
646
- };
647
- }
648
672
  this.cronActions = this._data.cronActions
649
673
  .filter((cronLogAction) => {
650
674
  return cronLogAction.show(this.cron);
@@ -653,11 +677,11 @@ class CronComponent {
653
677
  });
654
678
  }
655
679
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CronComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
656
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: CronComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"cron\">\n <h1 mat-dialog-title>\n Cron\n <div class=\"small\">\n {{ cron.name }}\n </div>\n </h1>\n <mat-dialog-content>\n <mat-tab-group (selectedIndexChange)=\"selectedIndexChange($event)\">\n <mat-tab label=\"Overview\">\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Status\n </fs-label>\n {{ CronStates[cron.state] }}\n </fs-label-field>\n <fs-label-field *ngIf=\"cron.cronSetting\">\n <fs-label>\n Run Frequency\n </fs-label>\n {{ cron.cronSetting.summary }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Process ID\n </fs-label>\n {{ cron.processId || 'None' }}\n <ng-container *ngIf=\"cron.processId\">\n <div class=\"small\">\n {{ CronProcessStates[cron.processState] || 'Unknown' }}\n </div>\n </ng-container>\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Last Ran\n </fs-label>\n <ng-container *ngIf=\"cron.duration===null; else lastRan\">\n Never\n </ng-container>\n <ng-template #lastRan>\n <fs-date-ago [date]=\"cron.createDate\"></fs-date-ago>\n <div>\n <small *ngIf=\"cron.duration\">\n Duration: {{ cron.duration | fsDateDuration }}\n </small>\n </div>\n </ng-template>\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Timeout hours\n </fs-label>\n {{ cron.cronSetting?.timeout || 'N/A' }}\n </fs-label-field>\n </div>\n <fs-label-field *ngIf=\"cron.message\">\n <fs-label>\n Last Message\n </fs-label>\n <div class=\"message\">\n {{ cron.message }}\n </div>\n </fs-label-field>\n </mat-tab>\n <mat-tab\n label=\"Logs\"\n *ngIf=\"config\">\n <ng-template matTabContent>\n <fs-list [config]=\"config\">\n <fs-list-column\n name=\"state\"\n title=\"Status\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <a\n (click)=\"cronLogOpen(row)\"\n [ngStyle]=\"{ color: CronLogStateColors[row.state] }\">\n {{ CronLogStates[row.state] || row.state }}\n </a>\n </ng-template>\n </fs-list-column>\n <fs-list-column\n title=\"Message\"\n class=\"col-message\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <div class=\"message\">\n {{ row.message }}\n </div>\n </ng-template>\n </fs-list-column>\n <fs-list-column\n title=\"Duration\"\n class=\"col-message\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <ng-container *ngIf=\"row.duration\">\n {{ row.duration | fsDateDuration: 'hour-minute-second' }}\n </ng-container>\n </ng-template>\n </fs-list-column>\n <fs-list-column\n name=\"create_date\"\n title=\"Date\"\n class=\"col-date\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <fs-date-ago [date]=\"row.createDate\"></fs-date-ago>\n </ng-template>\n </fs-list-column>\n </fs-list>\n </ng-template>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <ng-container *ngIf=\"tabIndex === 0\">\n <button\n *ngFor=\"let cronAction of cronActions\"\n mat-button\n (click)=\"cronActionClick(cronAction)\">\n {{ cronAction.label }}\n </button>\n </ng-container>\n </mat-dialog-actions>\n</fs-dialog>", styles: [":host ::ng-deep .col-message .message{white-space:break-spaces;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}:host ::ng-deep .col-date{white-space:nowrap}h1 .small{line-height:normal}.row{display:flex;flex-wrap:wrap}.row fs-label-field:not(:last-child){margin-right:40px}.message{white-space:pre-line}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i4$1.MatTabContent, selector: "[matTabContent]" }, { kind: "component", type: i4$1.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i4$1.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "component", type: i4$2.FsDateAgoComponent, selector: "fs-date-ago", inputs: ["date", "showTime", "format", "showTooltip", "tooltipDateFormat"] }, { kind: "directive", type: i7$1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: i5.FsListComponent, selector: "fs-list", inputs: ["config", "loaderLines"], outputs: ["filtersReady"] }, { kind: "directive", type: i5.FsListColumnDirective, selector: "fs-list-column", inputs: ["show", "title", "name", "customizable", "sortable", "sortableDefault", "sortableDirection", "direction", "align", "width", "class"] }, { kind: "directive", type: i5.FsListCellDirective, selector: "[fs-list-cell]", inputs: ["colspan", "align", "class"] }, { kind: "component", type: i8.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i8.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i9.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "pipe", type: i4$2.FsDateDurationPipe, name: "fsDateDuration" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
680
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: CronComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"cron\">\n <h1 mat-dialog-title>\n Cron\n <div class=\"small\">\n {{ cron.name }}\n </div>\n </h1>\n <mat-dialog-content>\n <mat-tab-group (selectedIndexChange)=\"selectedIndexChange($event)\">\n <mat-tab label=\"Overview\">\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Status\n </fs-label>\n {{ CronStates[cron.state] }}\n </fs-label-field>\n <fs-label-field *ngIf=\"cron.cronSetting\">\n <fs-label>\n Run Frequency\n </fs-label>\n {{ cron.cronSetting.summary }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Process ID\n </fs-label>\n {{ cron.processId || 'None' }}\n <ng-container *ngIf=\"cron.processId\">\n <div class=\"small\">\n {{ CronProcessStates[cron.processState] || 'Unknown' }}\n </div>\n </ng-container>\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Last Ran\n </fs-label>\n <ng-container *ngIf=\"cron.duration===null; else lastRan\">\n Never\n </ng-container>\n <ng-template #lastRan>\n <fs-date-ago [date]=\"cron.createDate\"></fs-date-ago>\n <div>\n <small *ngIf=\"cron.duration\">\n Duration: {{ cron.duration | fsDateDuration }}\n </small>\n </div>\n </ng-template>\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Timeout hours\n </fs-label>\n {{ cron.cronSetting?.timeout || 'N/A' }}\n </fs-label-field>\n </div>\n <fs-label-field *ngIf=\"cron.message\">\n <fs-label>\n Last Message\n </fs-label>\n <div class=\"message\">\n {{ cron.message }}\n </div>\n </fs-label-field>\n </mat-tab>\n <mat-tab\n label=\"Logs\"\n *ngIf=\"config\">\n <ng-template matTabContent>\n <app-cron-logs [cron]=\"cron\"></app-cron-logs>\n </ng-template>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <ng-container *ngIf=\"tabIndex === 0\">\n <button\n *ngFor=\"let cronAction of cronActions\"\n mat-button\n (click)=\"cronActionClick(cronAction)\">\n {{ cronAction.label }}\n </button>\n </ng-container>\n </mat-dialog-actions>\n</fs-dialog>", styles: [":host ::ng-deep .col-message .message{white-space:break-spaces;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}:host ::ng-deep .col-date{white-space:nowrap}h1 .small{line-height:normal}.row{display:flex;flex-wrap:wrap}.row fs-label-field:not(:last-child){margin-right:40px}.message{white-space:pre-line}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i4$1.MatTabContent, selector: "[matTabContent]" }, { kind: "component", type: i4$1.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i4$1.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "component", type: i4$2.FsDateAgoComponent, selector: "fs-date-ago", inputs: ["date", "showTime", "format", "showTooltip", "tooltipDateFormat"] }, { kind: "directive", type: i7$1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: i6.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i6.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i8.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "component", type: CronLogsComponent, selector: "app-cron-logs", inputs: ["cron"] }, { kind: "pipe", type: i4$2.FsDateDurationPipe, name: "fsDateDuration" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
657
681
  }
658
682
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CronComponent, decorators: [{
659
683
  type: Component,
660
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, template: "<fs-dialog *fsSkeleton=\"cron\">\n <h1 mat-dialog-title>\n Cron\n <div class=\"small\">\n {{ cron.name }}\n </div>\n </h1>\n <mat-dialog-content>\n <mat-tab-group (selectedIndexChange)=\"selectedIndexChange($event)\">\n <mat-tab label=\"Overview\">\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Status\n </fs-label>\n {{ CronStates[cron.state] }}\n </fs-label-field>\n <fs-label-field *ngIf=\"cron.cronSetting\">\n <fs-label>\n Run Frequency\n </fs-label>\n {{ cron.cronSetting.summary }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Process ID\n </fs-label>\n {{ cron.processId || 'None' }}\n <ng-container *ngIf=\"cron.processId\">\n <div class=\"small\">\n {{ CronProcessStates[cron.processState] || 'Unknown' }}\n </div>\n </ng-container>\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Last Ran\n </fs-label>\n <ng-container *ngIf=\"cron.duration===null; else lastRan\">\n Never\n </ng-container>\n <ng-template #lastRan>\n <fs-date-ago [date]=\"cron.createDate\"></fs-date-ago>\n <div>\n <small *ngIf=\"cron.duration\">\n Duration: {{ cron.duration | fsDateDuration }}\n </small>\n </div>\n </ng-template>\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Timeout hours\n </fs-label>\n {{ cron.cronSetting?.timeout || 'N/A' }}\n </fs-label-field>\n </div>\n <fs-label-field *ngIf=\"cron.message\">\n <fs-label>\n Last Message\n </fs-label>\n <div class=\"message\">\n {{ cron.message }}\n </div>\n </fs-label-field>\n </mat-tab>\n <mat-tab\n label=\"Logs\"\n *ngIf=\"config\">\n <ng-template matTabContent>\n <fs-list [config]=\"config\">\n <fs-list-column\n name=\"state\"\n title=\"Status\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <a\n (click)=\"cronLogOpen(row)\"\n [ngStyle]=\"{ color: CronLogStateColors[row.state] }\">\n {{ CronLogStates[row.state] || row.state }}\n </a>\n </ng-template>\n </fs-list-column>\n <fs-list-column\n title=\"Message\"\n class=\"col-message\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <div class=\"message\">\n {{ row.message }}\n </div>\n </ng-template>\n </fs-list-column>\n <fs-list-column\n title=\"Duration\"\n class=\"col-message\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <ng-container *ngIf=\"row.duration\">\n {{ row.duration | fsDateDuration: 'hour-minute-second' }}\n </ng-container>\n </ng-template>\n </fs-list-column>\n <fs-list-column\n name=\"create_date\"\n title=\"Date\"\n class=\"col-date\">\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <fs-date-ago [date]=\"row.createDate\"></fs-date-ago>\n </ng-template>\n </fs-list-column>\n </fs-list>\n </ng-template>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <ng-container *ngIf=\"tabIndex === 0\">\n <button\n *ngFor=\"let cronAction of cronActions\"\n mat-button\n (click)=\"cronActionClick(cronAction)\">\n {{ cronAction.label }}\n </button>\n </ng-container>\n </mat-dialog-actions>\n</fs-dialog>", styles: [":host ::ng-deep .col-message .message{white-space:break-spaces;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}:host ::ng-deep .col-date{white-space:nowrap}h1 .small{line-height:normal}.row{display:flex;flex-wrap:wrap}.row fs-label-field:not(:last-child){margin-right:40px}.message{white-space:pre-line}\n"] }]
684
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, template: "<fs-dialog *fsSkeleton=\"cron\">\n <h1 mat-dialog-title>\n Cron\n <div class=\"small\">\n {{ cron.name }}\n </div>\n </h1>\n <mat-dialog-content>\n <mat-tab-group (selectedIndexChange)=\"selectedIndexChange($event)\">\n <mat-tab label=\"Overview\">\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Status\n </fs-label>\n {{ CronStates[cron.state] }}\n </fs-label-field>\n <fs-label-field *ngIf=\"cron.cronSetting\">\n <fs-label>\n Run Frequency\n </fs-label>\n {{ cron.cronSetting.summary }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Process ID\n </fs-label>\n {{ cron.processId || 'None' }}\n <ng-container *ngIf=\"cron.processId\">\n <div class=\"small\">\n {{ CronProcessStates[cron.processState] || 'Unknown' }}\n </div>\n </ng-container>\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Last Ran\n </fs-label>\n <ng-container *ngIf=\"cron.duration===null; else lastRan\">\n Never\n </ng-container>\n <ng-template #lastRan>\n <fs-date-ago [date]=\"cron.createDate\"></fs-date-ago>\n <div>\n <small *ngIf=\"cron.duration\">\n Duration: {{ cron.duration | fsDateDuration }}\n </small>\n </div>\n </ng-template>\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Timeout hours\n </fs-label>\n {{ cron.cronSetting?.timeout || 'N/A' }}\n </fs-label-field>\n </div>\n <fs-label-field *ngIf=\"cron.message\">\n <fs-label>\n Last Message\n </fs-label>\n <div class=\"message\">\n {{ cron.message }}\n </div>\n </fs-label-field>\n </mat-tab>\n <mat-tab\n label=\"Logs\"\n *ngIf=\"config\">\n <ng-template matTabContent>\n <app-cron-logs [cron]=\"cron\"></app-cron-logs>\n </ng-template>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Done\n </button>\n <ng-container *ngIf=\"tabIndex === 0\">\n <button\n *ngFor=\"let cronAction of cronActions\"\n mat-button\n (click)=\"cronActionClick(cronAction)\">\n {{ cronAction.label }}\n </button>\n </ng-container>\n </mat-dialog-actions>\n</fs-dialog>", styles: [":host ::ng-deep .col-message .message{white-space:break-spaces;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}:host ::ng-deep .col-date{white-space:nowrap}h1 .small{line-height:normal}.row{display:flex;flex-wrap:wrap}.row fs-label-field:not(:last-child){margin-right:40px}.message{white-space:pre-line}\n"] }]
661
685
  }] });
662
686
 
663
687
  class CronNextRunComponent {
@@ -896,7 +920,7 @@ class CronsComponent {
896
920
  .pipe(filter((event) => event instanceof StreamEventData), map((event) => {
897
921
  return event?.data;
898
922
  }), filter((data) => !!data)));
899
- timer(100, 5000)
923
+ timer(1000, 5000)
900
924
  .pipe(takeUntil(this._destroy$))
901
925
  .subscribe(() => {
902
926
  observer.next(null);
@@ -953,8 +977,12 @@ class CronsComponent {
953
977
  return {
954
978
  ...rowAction,
955
979
  click: (cron) => {
956
- rowAction.action(cron)
957
- .subscribe();
980
+ rowAction
981
+ .action(cron)
982
+ .pipe(take(1))
983
+ .subscribe(() => {
984
+ this.list.reload();
985
+ });
958
986
  },
959
987
  };
960
988
  }),
@@ -1075,7 +1103,7 @@ class DashboardComponent {
1075
1103
  });
1076
1104
  }
1077
1105
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: DashboardComponent, deps: [{ token: i1$3.FsMessage }, { token: i0.ChangeDetectorRef }, { token: i2$1.FsBuildService }], target: i0.ɵɵFactoryTarget.Component });
1078
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: DashboardComponent, selector: "fs-system-dashboard", inputs: { init: "init", upgrade: "upgrade", load: "load", actions: "actions" }, ngImport: i0, template: "<div *fsSkeleton=\"dashboard\">\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <div>\n <h2>Server</h2>\n\n <fs-label-field>\n <fs-label>Date/Time</fs-label>\n {{dashboard.serverTime | fsDateFormat: 'date-time'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Timezone</fs-label>\n {{dashboard.serverTimezone}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Hostname</fs-label>\n {{dashboard.serverHostname}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Directory</fs-label>\n {{dashboard.appDirectory}}\n </fs-label-field>\n </div>\n\n <div>\n <h2>System</h2>\n <fs-label-field>\n <fs-label>Mode</fs-label>\n {{dashboard.appMode}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Notification Recipients</fs-label>\n {{dashboard.notifyRecipients.join(', ')}}\n </fs-label-field>\n </div>\n\n <div>\n <h2>Database</h2>\n\n <fs-label-field>\n <fs-label>Name</fs-label>\n {{dashboard.databaseName}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Date/Time</fs-label>\n {{dashboard.databaseTime | fsDateFormat: 'date-time'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Timezone</fs-label>\n {{dashboard.databaseTimezone}}\n </fs-label-field>\n </div>\n\n <div *ngIf=\"build || dashboard.upgrades.length\">\n <ng-container *ngIf=\"build\">\n <h2>Build</h2>\n <fs-label-field>\n <fs-label>Version</fs-label>\n {{build.version || 'Unknown'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Date</fs-label>\n {{ (build.date | fsDateFormat: 'date-time') || 'Unknown' }}\n </fs-label-field>\n </ng-container>\n\n <fs-label-field *ngIf=\"dashboard.upgrades.length\">\n <fs-label>Pending Upgrades</fs-label>\n <span class=\"attention\" [ngClass]=\"{ 'needs-attention': !!dashboard.upgrades.length }\">\n {{dashboard.upgrades.length}}\n <mat-icon\n [matTooltip]=\"dashboard.upgrades.join('\\n')\"\n matTooltipClass=\"tooltip-pending-upgrades\"\n >\n warning\n </mat-icon>\n </span>\n </fs-label-field>\n </div>\n\n <div>\n <h2>Cron</h2>\n\n <fs-label-field>\n <fs-label>Last Ran</fs-label>\n <span class=\"attention\" [ngClass]=\"{ 'needs-attention': dashboard.cronRanAttention }\">\n <span *ngIf=\"!dashboard.cronRan\">Never</span>\n <span *ngIf=\"dashboard.cronRan\">{{dashboard.cronRan | fsDateFormat: 'date-time'}}</span>\n <mat-icon>warning</mat-icon>\n </span>\n </fs-label-field>\n </div>\n </div>\n \n\n <div>\n <div class=\"actions\">\n <button mat-raised-button (click)=\"upgradeClick()\">Run Upgrades</button>\n <button mat-raised-button (click)=\"initClick()\">Init System</button>\n <button\n *ngFor=\"let action of buttonActions\"\n mat-raised-button\n (click)=\"actionClick(action)\">\n {{action.label}}\n </button>\n\n <ng-container *ngIf=\"menuActions.length\">\n <fs-menu buttonClass=\"mat-raised-button menu-button\">\n <ng-template\n *ngFor=\"let action of menuActions\"\n fs-menu-item\n (click)=\"actionClick(action)\">\n {{action.label}}\n </ng-template>\n </fs-menu>\n </ng-container>\n </div>\n </div>\n</div>\n", styles: [":host ::ng-deep .menu-button{box-shadow:none}h2{margin-top:0}.actions{display:flex;align-items:center;flex-wrap:wrap}.actions button,.actions fs-menu{margin-bottom:10px;margin-right:5px}table td{padding:3px}.attention{display:flex;align-items:center}.attention mat-icon{display:none;margin-left:2px}.attention.needs-attention{color:#c00}.attention.needs-attention mat-icon{display:inline}::ng-deep .tooltip-pending-upgrades{white-space:pre-line}@media (max-width: 1000px){:host ::ng-deep .menu-button{width:100%;border-radius:4px}}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7$1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: i8.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i8.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i9$1.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i9$1.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "pipe", type: i4$2.FsDateFormatPipe, name: "fsDateFormat" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1106
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: DashboardComponent, selector: "fs-system-dashboard", inputs: { init: "init", upgrade: "upgrade", load: "load", actions: "actions" }, ngImport: i0, template: "<div *fsSkeleton=\"dashboard\">\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <div>\n <h2>Server</h2>\n\n <fs-label-field>\n <fs-label>Date/Time</fs-label>\n {{dashboard.serverTime | fsDateFormat: 'date-time'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Timezone</fs-label>\n {{dashboard.serverTimezone}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Hostname</fs-label>\n {{dashboard.serverHostname}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Directory</fs-label>\n {{dashboard.appDirectory}}\n </fs-label-field>\n </div>\n\n <div>\n <h2>System</h2>\n <fs-label-field>\n <fs-label>Mode</fs-label>\n {{dashboard.appMode}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Notification Recipients</fs-label>\n {{dashboard.notifyRecipients.join(', ')}}\n </fs-label-field>\n </div>\n\n <div>\n <h2>Database</h2>\n\n <fs-label-field>\n <fs-label>Name</fs-label>\n {{dashboard.databaseName}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Date/Time</fs-label>\n {{dashboard.databaseTime | fsDateFormat: 'date-time'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Timezone</fs-label>\n {{dashboard.databaseTimezone}}\n </fs-label-field>\n </div>\n\n <div *ngIf=\"build || dashboard.upgrades.length\">\n <ng-container *ngIf=\"build\">\n <h2>Build</h2>\n <fs-label-field>\n <fs-label>Version</fs-label>\n {{build.version || 'Unknown'}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>Date</fs-label>\n {{ (build.date | fsDateFormat: 'date-time') || 'Unknown' }}\n </fs-label-field>\n </ng-container>\n\n <fs-label-field *ngIf=\"dashboard.upgrades.length\">\n <fs-label>Pending Upgrades</fs-label>\n <span class=\"attention\" [ngClass]=\"{ 'needs-attention': !!dashboard.upgrades.length }\">\n {{dashboard.upgrades.length}}\n <mat-icon\n [matTooltip]=\"dashboard.upgrades.join('\\n')\"\n matTooltipClass=\"tooltip-pending-upgrades\"\n >\n warning\n </mat-icon>\n </span>\n </fs-label-field>\n </div>\n\n <div>\n <h2>Cron</h2>\n\n <fs-label-field>\n <fs-label>Last Ran</fs-label>\n <span class=\"attention\" [ngClass]=\"{ 'needs-attention': dashboard.cronRanAttention }\">\n <span *ngIf=\"!dashboard.cronRan\">Never</span>\n <span *ngIf=\"dashboard.cronRan\">{{dashboard.cronRan | fsDateFormat: 'date-time'}}</span>\n <mat-icon>warning</mat-icon>\n </span>\n </fs-label-field>\n </div>\n </div>\n \n\n <div>\n <div class=\"actions\">\n <button mat-raised-button (click)=\"upgradeClick()\">Run Upgrades</button>\n <button mat-raised-button (click)=\"initClick()\">Init System</button>\n <button\n *ngFor=\"let action of buttonActions\"\n mat-raised-button\n (click)=\"actionClick(action)\">\n {{action.label}}\n </button>\n\n <ng-container *ngIf=\"menuActions.length\">\n <fs-menu buttonClass=\"mat-raised-button menu-button\">\n <ng-template\n *ngFor=\"let action of menuActions\"\n fs-menu-item\n (click)=\"actionClick(action)\">\n {{action.label}}\n </ng-template>\n </fs-menu>\n </ng-container>\n </div>\n </div>\n</div>\n", styles: [":host ::ng-deep .menu-button{box-shadow:none}h2{margin-top:0}.actions{display:flex;align-items:center;flex-wrap:wrap}.actions button,.actions fs-menu{margin-bottom:10px;margin-right:5px}table td{padding:3px}.attention{display:flex;align-items:center}.attention mat-icon{display:none;margin-left:2px}.attention.needs-attention{color:#c00}.attention.needs-attention mat-icon{display:inline}::ng-deep .tooltip-pending-upgrades{white-space:pre-line}@media (max-width: 1000px){:host ::ng-deep .menu-button{width:100%;border-radius:4px}}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i5$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7$1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: i6.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i6.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i9.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i9.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "pipe", type: i4$2.FsDateFormatPipe, name: "fsDateFormat" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1079
1107
  }
1080
1108
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: DashboardComponent, decorators: [{
1081
1109
  type: Component,
@@ -1229,7 +1257,7 @@ class ProcessComponent {
1229
1257
  this._destroy$.complete();
1230
1258
  }
1231
1259
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ProcessComponent, deps: [{ token: MAT_DIALOG_DATA }, { token: i1$3.FsMessage }, { token: i0.ChangeDetectorRef }, { token: i2$2.FsPrompt }], target: i0.ɵɵFactoryTarget.Component });
1232
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: ProcessComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"process\">\n <div mat-dialog-title>\n Process\n </div>\n <mat-dialog-content>\n <div class=\"column\">\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Name\n </fs-label>\n {{ process.prettyName }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Status\n </fs-label>\n <div\n class=\"status\"\n [ngClass]=\"{ 'running': process.state === ProcessState.Running }\">\n {{ ProcessStates[process.state] }}\n <ng-container *ngIf=\"process.state === ProcessState.Running\">\n <mat-progress-spinner\n [diameter]=\"20\"\n [mode]=\"'indeterminate'\">\n </mat-progress-spinner>\n </ng-container>\n </div>\n </fs-label-field>\n <fs-label-field *ngIf=\"process.notify\">\n <fs-label>\n Notification Email\n </fs-label>\n {{ process.notify }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Process ID\n </fs-label>\n {{ process.pid || 'None' }}\n <ng-container *ngIf=\"process.pid\">\n <div class=\"small\">\n {{ ProcessProcessStates[process.processState] || 'Unknown' }}\n </div>\n </ng-container>\n </fs-label-field>\n <fs-label-field *ngIf=\"process.createDate\">\n <fs-label>\n Create Date\n </fs-label>\n {{ process.createDate | fsDateFormat: 'date-time' }}\n </fs-label-field>\n <fs-label-field *ngIf=\"process.startDate\">\n <fs-label>\n Start Date\n </fs-label>\n {{ process.startDate | fsDateFormat: 'date-time' }}\n </fs-label-field>\n <fs-label-field *ngIf=\"process.endDate\">\n <fs-label>\n Complete Date\n </fs-label>\n {{ process.endDate | fsDateFormat: 'date-time' }}\n </fs-label-field>\n <fs-label-field *ngIf=\"process.duration\">\n <fs-label>\n Duration\n </fs-label>\n {{ process.duration | fsDateDuration: {hours: true, minutes: true, seconds: true} }}\n </fs-label-field>\n </div>\n <fs-label-field *ngIf=\"process.message\">\n <fs-label>\n Message\n </fs-label>\n {{ process.message }}\n </fs-label-field>\n <fs-label-field *ngIf=\"process.log\">\n <fs-label>\n Log\n </fs-label>\n <div class=\"log\">\n {{ process.log }}\n </div>\n </fs-label-field>\n </div>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Close\n </button>\n <button\n *ngIf=\"process.state === ProcessState.Running\"\n mat-button\n (click)=\"kill()\">\n Kill\n </button>\n <button\n *ngIf=\"process.state !== ProcessState.Running\"\n mat-button\n (click)=\"run()\">\n Run\n </button>\n <button\n *ngIf=\"(\n process.state !== ProcessState.Running && \n process.state !== ProcessState.Queued\n )\"\n mat-button\n (click)=\"queue()\">\n Queue\n </button>\n <button\n *ngIf=\"process.filename\"\n mat-button\n (click)=\"download()\">\n Download\n </button>\n </mat-dialog-actions>\n</fs-dialog>", styles: [".log{white-space:pre-line;font-family:monospace;font-size:95%;line-height:130%}.status{display:flex}.status.running{margin-right:28px}.status.running mat-progress-spinner{position:absolute;right:0}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i6.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i7$1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: i8.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i8.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i9.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "pipe", type: i4$2.FsDateDurationPipe, name: "fsDateDuration" }, { kind: "pipe", type: i4$2.FsDateFormatPipe, name: "fsDateFormat" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1260
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: ProcessComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"process\">\n <div mat-dialog-title>\n Process\n </div>\n <mat-dialog-content>\n <div class=\"column\">\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Name\n </fs-label>\n {{ process.prettyName }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Status\n </fs-label>\n <div\n class=\"status\"\n [ngClass]=\"{ 'running': process.state === ProcessState.Running }\">\n {{ ProcessStates[process.state] }}\n <ng-container *ngIf=\"process.state === ProcessState.Running\">\n <mat-progress-spinner\n [diameter]=\"20\"\n [mode]=\"'indeterminate'\">\n </mat-progress-spinner>\n </ng-container>\n </div>\n </fs-label-field>\n <fs-label-field *ngIf=\"process.notify\">\n <fs-label>\n Notification Email\n </fs-label>\n {{ process.notify }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Process ID\n </fs-label>\n {{ process.pid || 'None' }}\n <ng-container *ngIf=\"process.pid\">\n <div class=\"small\">\n {{ ProcessProcessStates[process.processState] || 'Unknown' }}\n </div>\n </ng-container>\n </fs-label-field>\n <fs-label-field *ngIf=\"process.createDate\">\n <fs-label>\n Create Date\n </fs-label>\n {{ process.createDate | fsDateFormat: 'date-time' }}\n </fs-label-field>\n <fs-label-field *ngIf=\"process.startDate\">\n <fs-label>\n Start Date\n </fs-label>\n {{ process.startDate | fsDateFormat: 'date-time' }}\n </fs-label-field>\n <fs-label-field *ngIf=\"process.endDate\">\n <fs-label>\n Complete Date\n </fs-label>\n {{ process.endDate | fsDateFormat: 'date-time' }}\n </fs-label-field>\n <fs-label-field *ngIf=\"process.duration\">\n <fs-label>\n Duration\n </fs-label>\n {{ process.duration | fsDateDuration: {hours: true, minutes: true, seconds: true} }}\n </fs-label-field>\n </div>\n <fs-label-field *ngIf=\"process.message\">\n <fs-label>\n Message\n </fs-label>\n {{ process.message }}\n </fs-label-field>\n <fs-label-field *ngIf=\"process.log\">\n <fs-label>\n Log\n </fs-label>\n <div class=\"log\">\n {{ process.log }}\n </div>\n </fs-label-field>\n </div>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n mat-button\n [mat-dialog-close]=\"true\"\n color=\"primary\">\n Close\n </button>\n <button\n *ngIf=\"process.state === ProcessState.Running\"\n mat-button\n (click)=\"kill()\">\n Kill\n </button>\n <button\n *ngIf=\"process.state !== ProcessState.Running\"\n mat-button\n (click)=\"run()\">\n Run\n </button>\n <button\n *ngIf=\"(\n process.state !== ProcessState.Running && \n process.state !== ProcessState.Queued\n )\"\n mat-button\n (click)=\"queue()\">\n Queue\n </button>\n <button\n *ngIf=\"process.filename\"\n mat-button\n (click)=\"download()\">\n Download\n </button>\n </mat-dialog-actions>\n</fs-dialog>", styles: [".log{white-space:pre-line;font-family:monospace;font-size:95%;line-height:130%}.status{display:flex}.status.running{margin-right:28px}.status.running mat-progress-spinner{position:absolute;right:0}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i6$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "directive", type: i7$1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: i6.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i6.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i8.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "pipe", type: i4$2.FsDateDurationPipe, name: "fsDateDuration" }, { kind: "pipe", type: i4$2.FsDateFormatPipe, name: "fsDateFormat" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1233
1261
  }
1234
1262
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ProcessComponent, decorators: [{
1235
1263
  type: Component,
@@ -1415,7 +1443,7 @@ class ServerLogComponent {
1415
1443
  }
1416
1444
  }
1417
1445
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ServerLogComponent, deps: [{ token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
1418
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: ServerLogComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>Log</div>\n <mat-dialog-content>\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{log.type}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{log.message}}\n </fs-label-field>\n\n <fs-label-field *ngIf=\"log.url\">\n <fs-label>\n URL\n </fs-label>\n {{log.url}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{log.createDate|fsDateFormat: 'full-date-time'}}\n </fs-label-field>\n \n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{log.file}} &#64; {{log.line}}\n </fs-label-field>\n </div>\n <fs-label-field>\n <fs-label>\n $_SERVER\n </fs-label>\n <pre>{{log.server|json}}</pre>\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>\n Backtrace\n </fs-label>\n <pre>{{log.backtrace|json}}</pre>\n </fs-label-field>\n\n\n </mat-dialog-content>\n <mat-dialog-actions>\n <button mat-button [mat-dialog-close]=\"true\" color=\"primary\">Done</button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i7$1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: i8.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i8.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i9.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }, { kind: "pipe", type: i4$2.FsDateFormatPipe, name: "fsDateFormat" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1446
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: ServerLogComponent, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>Log</div>\n <mat-dialog-content>\n <div class=\"fs-row.gap-lg.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{log.type}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{log.message}}\n </fs-label-field>\n\n <fs-label-field *ngIf=\"log.url\">\n <fs-label>\n URL\n </fs-label>\n {{log.url}}\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>\n Date\n </fs-label>\n {{log.createDate|fsDateFormat: 'full-date-time'}}\n </fs-label-field>\n \n <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{log.file}} &#64; {{log.line}}\n </fs-label-field>\n </div>\n <fs-label-field>\n <fs-label>\n $_SERVER\n </fs-label>\n <pre>{{log.server|json}}</pre>\n </fs-label-field>\n\n <fs-label-field>\n <fs-label>\n Backtrace\n </fs-label>\n <pre>{{log.backtrace|json}}</pre>\n </fs-label-field>\n\n\n </mat-dialog-content>\n <mat-dialog-actions>\n <button mat-button [mat-dialog-close]=\"true\" color=\"primary\">Done</button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: i1.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i7$1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "component", type: i6.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i6.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i8.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }, { kind: "pipe", type: i4$2.FsDateFormatPipe, name: "fsDateFormat" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1419
1447
  }
1420
1448
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ServerLogComponent, decorators: [{
1421
1449
  type: Component,
@@ -1698,7 +1726,8 @@ class FsSystemModule {
1698
1726
  FsDatePickerModule,
1699
1727
  FsMenuModule,
1700
1728
  FsPopoverModule,
1701
- FsColorPickerModule], exports: [DashboardComponent,
1729
+ FsColorPickerModule,
1730
+ CronLogsComponent], exports: [DashboardComponent,
1702
1731
  CronsComponent,
1703
1732
  SettingsComponent,
1704
1733
  ProcessesComponent,
@@ -1728,7 +1757,8 @@ class FsSystemModule {
1728
1757
  FsDatePickerModule,
1729
1758
  FsMenuModule,
1730
1759
  FsPopoverModule,
1731
- FsColorPickerModule] });
1760
+ FsColorPickerModule,
1761
+ CronLogsComponent] });
1732
1762
  }
1733
1763
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsSystemModule, decorators: [{
1734
1764
  type: NgModule,
@@ -1757,6 +1787,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImpor
1757
1787
  FsMenuModule,
1758
1788
  FsPopoverModule,
1759
1789
  FsColorPickerModule,
1790
+ CronLogsComponent,
1760
1791
  ],
1761
1792
  exports: [
1762
1793
  DashboardComponent,