@firestitch/system 18.0.37 → 18.0.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/modules/system/components/server-logs/components/server-log/server-log.component.d.ts +8 -0
- package/esm2022/app/modules/system/components/server-logs/components/server-log/server-log.component.mjs +36 -24
- package/fesm2022/firestitch-system.mjs +32 -20
- package/fesm2022/firestitch-system.mjs.map +1 -1
- package/package.json +1 -1
package/app/modules/system/components/server-logs/components/server-log/server-log.component.d.ts
CHANGED
|
@@ -2,8 +2,16 @@ import { OnInit } from '@angular/core';
|
|
|
2
2
|
import * as i0 from "@angular/core";
|
|
3
3
|
export declare class ServerLogComponent implements OnInit {
|
|
4
4
|
data: any;
|
|
5
|
+
private _clipboard;
|
|
6
|
+
private _message;
|
|
5
7
|
log: any;
|
|
8
|
+
backtrace: string;
|
|
9
|
+
logData: string;
|
|
10
|
+
server: string;
|
|
11
|
+
LogTypes: Record<string, string>;
|
|
6
12
|
ngOnInit(): void;
|
|
13
|
+
copy(): void;
|
|
14
|
+
private _prettify;
|
|
7
15
|
static ɵfac: i0.ɵɵFactoryDeclaration<ServerLogComponent, never>;
|
|
8
16
|
static ɵcmp: i0.ɵɵComponentDeclaration<ServerLogComponent, "ng-component", never, {}, {}, never, never, true, never>;
|
|
9
17
|
}
|
|
@@ -1,60 +1,72 @@
|
|
|
1
|
-
import { CommonModule, JsonPipe } from '@angular/common';
|
|
2
1
|
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
|
3
2
|
import { MatButtonModule } from '@angular/material/button';
|
|
4
3
|
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
4
|
+
import { MatTabsModule } from '@angular/material/tabs';
|
|
5
|
+
import { FsClipboard } from '@firestitch/clipboard';
|
|
6
|
+
import { index } from '@firestitch/common';
|
|
8
7
|
import { FsDateModule } from '@firestitch/date';
|
|
9
8
|
import { FsDialogModule } from '@firestitch/dialog';
|
|
10
9
|
import { FsLabelModule } from '@firestitch/label';
|
|
10
|
+
import { FsMessage } from '@firestitch/message';
|
|
11
11
|
import { FsSkeletonModule } from '@firestitch/skeleton';
|
|
12
|
+
import { LogTypes } from '../../../../../../consts';
|
|
12
13
|
import * as i0 from "@angular/core";
|
|
13
|
-
import * as i1 from "@angular/
|
|
14
|
-
import * as i2 from "@angular/material/
|
|
15
|
-
import * as i3 from "@angular/material/
|
|
14
|
+
import * as i1 from "@angular/material/dialog";
|
|
15
|
+
import * as i2 from "@angular/material/button";
|
|
16
|
+
import * as i3 from "@angular/material/tabs";
|
|
16
17
|
import * as i4 from "@firestitch/label";
|
|
17
18
|
import * as i5 from "@firestitch/date";
|
|
18
19
|
import * as i6 from "@firestitch/skeleton";
|
|
19
20
|
import * as i7 from "@firestitch/dialog";
|
|
20
21
|
export class ServerLogComponent {
|
|
21
22
|
data = inject(MAT_DIALOG_DATA);
|
|
23
|
+
_clipboard = inject(FsClipboard);
|
|
24
|
+
_message = inject(FsMessage);
|
|
22
25
|
log;
|
|
26
|
+
backtrace;
|
|
27
|
+
logData;
|
|
28
|
+
server;
|
|
29
|
+
LogTypes = index(LogTypes, 'value', 'name');
|
|
23
30
|
ngOnInit() {
|
|
24
31
|
if (this.data.log) {
|
|
25
32
|
this.log = this.data.log;
|
|
33
|
+
this.backtrace = this._prettify(this.log.backtrace);
|
|
34
|
+
this.logData = this._prettify(this.log.data);
|
|
35
|
+
this.server = this._prettify(this.log.server);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
copy() {
|
|
39
|
+
this._clipboard.copy(JSON.stringify(this.log, null, 2));
|
|
40
|
+
this._message.success('Copied to clipboard');
|
|
41
|
+
}
|
|
42
|
+
_prettify(value) {
|
|
43
|
+
if (typeof value === 'string') {
|
|
44
|
+
value = value.trim();
|
|
26
45
|
try {
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
catch (e) {
|
|
30
|
-
//
|
|
31
|
-
}
|
|
32
|
-
try {
|
|
33
|
-
this.log.server = JSON.parse(this.log.server);
|
|
46
|
+
value = JSON.parse(value);
|
|
34
47
|
}
|
|
35
48
|
catch (e) {
|
|
36
|
-
|
|
49
|
+
return value;
|
|
37
50
|
}
|
|
38
51
|
}
|
|
52
|
+
if (!value || (typeof value === 'object' && Object.keys(value).length === 0)) {
|
|
53
|
+
return '';
|
|
54
|
+
}
|
|
55
|
+
return JSON.stringify(value, null, 2);
|
|
39
56
|
}
|
|
40
57
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ServerLogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
41
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: ServerLogComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\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 <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} @ {{ log.line }}\n </fs-label-field>\n </div>\n @if (
|
|
58
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: ServerLogComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log.type] || log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\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 <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} @ {{ log.line }}\n </fs-label-field>\n </div>\n @if (backtrace || logData || server) {\n <mat-tab-group>\n @if (backtrace) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace }}</pre>\n </mat-tab>\n }\n @if (logData) {\n <mat-tab label=\"Data\">\n <pre>{{ logData }}</pre>\n </mat-tab>\n }\n @if (server) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\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 <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { 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: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i3.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: "ngmodule", type: FsLabelModule }, { kind: "component", type: i4.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i4.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "ngmodule", type: FsDateModule }, { kind: "pipe", type: i5.FsDateFormatPipe, name: "fsDateFormat" }, { kind: "ngmodule", type: FsSkeletonModule }, { kind: "directive", type: i6.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i7.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
42
59
|
}
|
|
43
60
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ServerLogComponent, decorators: [{
|
|
44
61
|
type: Component,
|
|
45
62
|
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
46
|
-
CommonModule,
|
|
47
63
|
MatDialogModule,
|
|
48
64
|
MatButtonModule,
|
|
49
|
-
|
|
50
|
-
MatTooltipModule,
|
|
51
|
-
FsLabelModule,
|
|
65
|
+
MatTabsModule,
|
|
52
66
|
FsLabelModule,
|
|
53
|
-
FsBadgeModule,
|
|
54
|
-
JsonPipe,
|
|
55
67
|
FsDateModule,
|
|
56
68
|
FsSkeletonModule,
|
|
57
69
|
FsDialogModule,
|
|
58
|
-
], template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\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 <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} @ {{ log.line }}\n </fs-label-field>\n </div>\n @if (
|
|
70
|
+
], template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log.type] || log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\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 <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} @ {{ log.line }}\n </fs-label-field>\n </div>\n @if (backtrace || logData || server) {\n <mat-tab-group>\n @if (backtrace) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace }}</pre>\n </mat-tab>\n }\n @if (logData) {\n <mat-tab label=\"Data\">\n <pre>{{ logData }}</pre>\n </mat-tab>\n }\n @if (server) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\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 <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"] }]
|
|
59
71
|
}] });
|
|
60
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
72
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLWxvZy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL21vZHVsZXMvc3lzdGVtL2NvbXBvbmVudHMvc2VydmVyLWxvZ3MvY29tcG9uZW50cy9zZXJ2ZXItbG9nL3NlcnZlci1sb2cuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9tb2R1bGVzL3N5c3RlbS9jb21wb25lbnRzL3NlcnZlci1sb2dzL2NvbXBvbmVudHMvc2VydmVyLWxvZy9zZXJ2ZXItbG9nLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQVUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRW5GLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsZUFBZSxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzVFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV2RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDcEQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV4RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7Ozs7Ozs7OztBQWtCcEQsTUFBTSxPQUFPLGtCQUFrQjtJQUM3QixJQUFJLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBRXZCLFVBQVUsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDakMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUU5QixHQUFHLENBQUM7SUFDSixTQUFTLENBQVM7SUFDbEIsT0FBTyxDQUFTO0lBQ2hCLE1BQU0sQ0FBUztJQUNmLFFBQVEsR0FBMkIsS0FBSyxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFFcEUsUUFBUTtRQUNiLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1lBQ3pCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3BELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzdDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2hELENBQUM7SUFDSCxDQUFDO0lBRU0sSUFBSTtRQUNULElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4RCxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFTyxTQUFTLENBQUMsS0FBSztRQUNyQixJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzlCLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7WUFFckIsSUFBSSxDQUFDO2dCQUNILEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzVCLENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNYLE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDN0UsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDeEMsQ0FBQzt1R0ExQ1Usa0JBQWtCOzJGQUFsQixrQkFBa0Isd0VDaEMvQiwwd0RBMEVBLGdLRG5ESSxlQUFlLCtuQkFDZixlQUFlLDJOQUNmLGFBQWEsNG9CQUNiLGFBQWEsK1FBQ2IsWUFBWSxpR0FDWixnQkFBZ0IsaUtBQ2hCLGNBQWM7OzJGQUdMLGtCQUFrQjtrQkFmOUIsU0FBUztzQ0FHUyx1QkFBdUIsQ0FBQyxNQUFNLGNBQ25DLElBQUksV0FDUDt3QkFDUCxlQUFlO3dCQUNmLGVBQWU7d0JBQ2YsYUFBYTt3QkFDYixhQUFhO3dCQUNiLFlBQVk7d0JBQ1osZ0JBQWdCO3dCQUNoQixjQUFjO3FCQUNmIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgT25Jbml0LCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgTWF0QnV0dG9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcbmltcG9ydCB7IE1BVF9ESUFMT0dfREFUQSwgTWF0RGlhbG9nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IE1hdFRhYnNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90YWJzJztcblxuaW1wb3J0IHsgRnNDbGlwYm9hcmQgfSBmcm9tICdAZmlyZXN0aXRjaC9jbGlwYm9hcmQnO1xuaW1wb3J0IHsgaW5kZXggfSBmcm9tICdAZmlyZXN0aXRjaC9jb21tb24nO1xuaW1wb3J0IHsgRnNEYXRlTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvZGF0ZSc7XG5pbXBvcnQgeyBGc0RpYWxvZ01vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2RpYWxvZyc7XG5pbXBvcnQgeyBGc0xhYmVsTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbGFiZWwnO1xuaW1wb3J0IHsgRnNNZXNzYWdlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWVzc2FnZSc7XG5pbXBvcnQgeyBGc1NrZWxldG9uTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvc2tlbGV0b24nO1xuXG5pbXBvcnQgeyBMb2dUeXBlcyB9IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL2NvbnN0cyc7XG5cblxuQENvbXBvbmVudCh7XG4gIHRlbXBsYXRlVXJsOiAnLi9zZXJ2ZXItbG9nLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc2VydmVyLWxvZy5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIE1hdERpYWxvZ01vZHVsZSxcbiAgICBNYXRCdXR0b25Nb2R1bGUsXG4gICAgTWF0VGFic01vZHVsZSxcbiAgICBGc0xhYmVsTW9kdWxlLFxuICAgIEZzRGF0ZU1vZHVsZSxcbiAgICBGc1NrZWxldG9uTW9kdWxlLFxuICAgIEZzRGlhbG9nTW9kdWxlLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBTZXJ2ZXJMb2dDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBkYXRhID0gaW5qZWN0KE1BVF9ESUFMT0dfREFUQSk7XG5cbiAgcHJpdmF0ZSBfY2xpcGJvYXJkID0gaW5qZWN0KEZzQ2xpcGJvYXJkKTtcbiAgcHJpdmF0ZSBfbWVzc2FnZSA9IGluamVjdChGc01lc3NhZ2UpO1xuXG4gIHB1YmxpYyBsb2c7XG4gIHB1YmxpYyBiYWNrdHJhY2U6IHN0cmluZztcbiAgcHVibGljIGxvZ0RhdGE6IHN0cmluZztcbiAgcHVibGljIHNlcnZlcjogc3RyaW5nO1xuICBwdWJsaWMgTG9nVHlwZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSBpbmRleChMb2dUeXBlcywgJ3ZhbHVlJywgJ25hbWUnKTtcblxuICBwdWJsaWMgbmdPbkluaXQoKSB7XG4gICAgaWYgKHRoaXMuZGF0YS5sb2cpIHtcbiAgICAgIHRoaXMubG9nID0gdGhpcy5kYXRhLmxvZztcbiAgICAgIHRoaXMuYmFja3RyYWNlID0gdGhpcy5fcHJldHRpZnkodGhpcy5sb2cuYmFja3RyYWNlKTtcbiAgICAgIHRoaXMubG9nRGF0YSA9IHRoaXMuX3ByZXR0aWZ5KHRoaXMubG9nLmRhdGEpO1xuICAgICAgdGhpcy5zZXJ2ZXIgPSB0aGlzLl9wcmV0dGlmeSh0aGlzLmxvZy5zZXJ2ZXIpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjb3B5KCkge1xuICAgIHRoaXMuX2NsaXBib2FyZC5jb3B5KEpTT04uc3RyaW5naWZ5KHRoaXMubG9nLCBudWxsLCAyKSk7XG4gICAgdGhpcy5fbWVzc2FnZS5zdWNjZXNzKCdDb3BpZWQgdG8gY2xpcGJvYXJkJyk7XG4gIH1cblxuICBwcml2YXRlIF9wcmV0dGlmeSh2YWx1ZSk6IHN0cmluZyB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHZhbHVlID0gdmFsdWUudHJpbSgpO1xuXG4gICAgICB0cnkge1xuICAgICAgICB2YWx1ZSA9IEpTT04ucGFyc2UodmFsdWUpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCF2YWx1ZSB8fCAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoID09PSAwKSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSwgbnVsbCwgMik7XG4gIH1cbn1cbiIsIjxmcy1kaWFsb2cgKmZzU2tlbGV0b249XCJsb2dcIj5cbiAgPGRpdiBtYXQtZGlhbG9nLXRpdGxlPlxuICAgIExvZ1xuICA8L2Rpdj5cbiAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICA8ZGl2IGNsYXNzPVwiZnMtcm93LmNvbHVtbi1nYXAtbGcucm93LWdhcC1zbS53cmFwLmFsaWduLXN0YXJ0XCI+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBFcnJvciBUeXBlXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IExvZ1R5cGVzW2xvZy50eXBlXSB8fCBsb2cudHlwZSB9fVxuICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgIE1lc3NhZ2VcbiAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAge3sgbG9nLm1lc3NhZ2UgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICBAaWYgKGxvZy51cmwpIHtcbiAgICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICAgIFVSTFxuICAgICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgICAge3sgbG9nLnVybCB9fVxuICAgICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgICAgfVxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+XG4gICAgICAgICAgRGF0ZVxuICAgICAgICA8L2ZzLWxhYmVsPlxuICAgICAgICB7eyBsb2cuY3JlYXRlRGF0ZXxmc0RhdGVGb3JtYXQ6ICdmdWxsLWRhdGUtdGltZScgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBGaWxlXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IGxvZy5maWxlIH19ICYjNjQ7IHt7IGxvZy5saW5lIH19XG4gICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgIDwvZGl2PlxuICAgIEBpZiAoYmFja3RyYWNlIHx8IGxvZ0RhdGEgfHwgc2VydmVyKSB7XG4gICAgICA8bWF0LXRhYi1ncm91cD5cbiAgICAgICAgQGlmIChiYWNrdHJhY2UpIHtcbiAgICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIkJhY2t0cmFjZVwiPlxuICAgICAgICAgICAgPHByZT57eyBiYWNrdHJhY2UgfX08L3ByZT5cbiAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIH1cbiAgICAgICAgQGlmIChsb2dEYXRhKSB7XG4gICAgICAgICAgPG1hdC10YWIgbGFiZWw9XCJEYXRhXCI+XG4gICAgICAgICAgICA8cHJlPnt7IGxvZ0RhdGEgfX08L3ByZT5cbiAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIH1cbiAgICAgICAgQGlmIChzZXJ2ZXIpIHtcbiAgICAgICAgICA8bWF0LXRhYiBsYWJlbD1cIiRfU0VSVkVSXCI+XG4gICAgICAgICAgICA8cHJlPnt7IHNlcnZlciB9fTwvcHJlPlxuICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgfVxuICAgICAgPC9tYXQtdGFiLWdyb3VwPlxuICAgIH1cbiAgPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XG4gIDxtYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgPGJ1dHRvblxuICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgIFttYXQtZGlhbG9nLWNsb3NlXT1cInRydWVcIlxuICAgICAgICBjb2xvcj1cInByaW1hcnlcIj5cbiAgICAgIERvbmVcbiAgICA8L2J1dHRvbj5cbiAgICA8YnV0dG9uXG4gICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIChjbGljayk9XCJjb3B5KClcIj5cbiAgICAgIENvcHlcbiAgICA8L2J1dHRvbj5cbiAgPC9tYXQtZGlhbG9nLWFjdGlvbnM+XG48L2ZzLWRpYWxvZz5cbiJdfQ==
|
|
@@ -2,11 +2,11 @@ import * as i1$2 from '@angular/common';
|
|
|
2
2
|
import { JsonPipe, NgClass, NgStyle, CommonModule, NgTemplateOutlet } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
4
|
import { inject, Component, ChangeDetectionStrategy, ViewChild, Input, Injectable, ChangeDetectorRef, EventEmitter, Output, Pipe, InjectionToken, NgModule } from '@angular/core';
|
|
5
|
-
import * as i1$
|
|
5
|
+
import * as i1$4 from '@angular/forms';
|
|
6
6
|
import { FormsModule } from '@angular/forms';
|
|
7
|
-
import * as
|
|
7
|
+
import * as i2$2 from '@angular/material/button';
|
|
8
8
|
import { MatButton, MatButtonModule, MatIconButton } from '@angular/material/button';
|
|
9
|
-
import * as
|
|
9
|
+
import * as i1$3 from '@angular/material/dialog';
|
|
10
10
|
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogTitle, MatDialogContent, MatDialogActions, MatDialogClose, MatDialog, MatDialogModule } from '@angular/material/dialog';
|
|
11
11
|
import { MatAccordion, MatExpansionPanel, MatExpansionPanelHeader, MatExpansionPanelTitle, MatExpansionModule } from '@angular/material/expansion';
|
|
12
12
|
import { MatFormField, MatLabel, MatHint, MatFormFieldModule } from '@angular/material/form-field';
|
|
@@ -14,6 +14,7 @@ import { MatIcon, MatIconModule } from '@angular/material/icon';
|
|
|
14
14
|
import { MatInput, MatInputModule } from '@angular/material/input';
|
|
15
15
|
import { MatProgressSpinner, MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
16
16
|
import { MatSelect, MatSelectModule } from '@angular/material/select';
|
|
17
|
+
import * as i3$2 from '@angular/material/tabs';
|
|
17
18
|
import { MatTabGroup, MatTab, MatTabContent, MatTabsModule } from '@angular/material/tabs';
|
|
18
19
|
import { MatTooltip, MatTooltipModule } from '@angular/material/tooltip';
|
|
19
20
|
import * as i2$3 from '@firestitch/badge';
|
|
@@ -1266,43 +1267,54 @@ const LogTypes = [
|
|
|
1266
1267
|
|
|
1267
1268
|
class ServerLogComponent {
|
|
1268
1269
|
data = inject(MAT_DIALOG_DATA);
|
|
1270
|
+
_clipboard = inject(FsClipboard);
|
|
1271
|
+
_message = inject(FsMessage);
|
|
1269
1272
|
log;
|
|
1273
|
+
backtrace;
|
|
1274
|
+
logData;
|
|
1275
|
+
server;
|
|
1276
|
+
LogTypes = index(LogTypes, 'value', 'name');
|
|
1270
1277
|
ngOnInit() {
|
|
1271
1278
|
if (this.data.log) {
|
|
1272
1279
|
this.log = this.data.log;
|
|
1280
|
+
this.backtrace = this._prettify(this.log.backtrace);
|
|
1281
|
+
this.logData = this._prettify(this.log.data);
|
|
1282
|
+
this.server = this._prettify(this.log.server);
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
copy() {
|
|
1286
|
+
this._clipboard.copy(JSON.stringify(this.log, null, 2));
|
|
1287
|
+
this._message.success('Copied to clipboard');
|
|
1288
|
+
}
|
|
1289
|
+
_prettify(value) {
|
|
1290
|
+
if (typeof value === 'string') {
|
|
1291
|
+
value = value.trim();
|
|
1273
1292
|
try {
|
|
1274
|
-
|
|
1275
|
-
}
|
|
1276
|
-
catch (e) {
|
|
1277
|
-
//
|
|
1278
|
-
}
|
|
1279
|
-
try {
|
|
1280
|
-
this.log.server = JSON.parse(this.log.server);
|
|
1293
|
+
value = JSON.parse(value);
|
|
1281
1294
|
}
|
|
1282
1295
|
catch (e) {
|
|
1283
|
-
|
|
1296
|
+
return value;
|
|
1284
1297
|
}
|
|
1285
1298
|
}
|
|
1299
|
+
if (!value || (typeof value === 'object' && Object.keys(value).length === 0)) {
|
|
1300
|
+
return '';
|
|
1301
|
+
}
|
|
1302
|
+
return JSON.stringify(value, null, 2);
|
|
1286
1303
|
}
|
|
1287
1304
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ServerLogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1288
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: ServerLogComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\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 <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} @ {{ log.line }}\n </fs-label-field>\n </div>\n @if (
|
|
1305
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: ServerLogComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log.type] || log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\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 <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} @ {{ log.line }}\n </fs-label-field>\n </div>\n @if (backtrace || logData || server) {\n <mat-tab-group>\n @if (backtrace) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace }}</pre>\n </mat-tab>\n }\n @if (logData) {\n <mat-tab label=\"Data\">\n <pre>{{ logData }}</pre>\n </mat-tab>\n }\n @if (server) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\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 <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$3.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "directive", type: i1$3.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$3.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$3.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$2.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i3$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i3$2.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: "ngmodule", type: FsLabelModule }, { kind: "component", type: i3.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i3.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "ngmodule", type: FsDateModule }, { kind: "pipe", type: i4.FsDateFormatPipe, name: "fsDateFormat" }, { kind: "ngmodule", type: FsSkeletonModule }, { kind: "directive", type: i1.FsSkeletonContentDirective, selector: "[fsSkeleton]", inputs: ["fsSkeleton", "fsSkeletonPattern"] }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i2.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1289
1306
|
}
|
|
1290
1307
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ServerLogComponent, decorators: [{
|
|
1291
1308
|
type: Component,
|
|
1292
1309
|
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
1293
|
-
CommonModule,
|
|
1294
1310
|
MatDialogModule,
|
|
1295
1311
|
MatButtonModule,
|
|
1296
|
-
|
|
1297
|
-
MatTooltipModule,
|
|
1298
|
-
FsLabelModule,
|
|
1312
|
+
MatTabsModule,
|
|
1299
1313
|
FsLabelModule,
|
|
1300
|
-
FsBadgeModule,
|
|
1301
|
-
JsonPipe,
|
|
1302
1314
|
FsDateModule,
|
|
1303
1315
|
FsSkeletonModule,
|
|
1304
1316
|
FsDialogModule,
|
|
1305
|
-
], template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\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 <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} @ {{ log.line }}\n </fs-label-field>\n </div>\n @if (
|
|
1317
|
+
], template: "<fs-dialog *fsSkeleton=\"log\">\n <div mat-dialog-title>\n Log\n </div>\n <mat-dialog-content>\n <div class=\"fs-row.column-gap-lg.row-gap-sm.wrap.align-start\">\n <fs-label-field>\n <fs-label>\n Error Type\n </fs-label>\n {{ LogTypes[log.type] || log.type }}\n </fs-label-field>\n <fs-label-field>\n <fs-label>\n Message\n </fs-label>\n {{ log.message }}\n </fs-label-field>\n @if (log.url) {\n <fs-label-field>\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 <fs-label-field>\n <fs-label>\n File\n </fs-label>\n {{ log.file }} @ {{ log.line }}\n </fs-label-field>\n </div>\n @if (backtrace || logData || server) {\n <mat-tab-group>\n @if (backtrace) {\n <mat-tab label=\"Backtrace\">\n <pre>{{ backtrace }}</pre>\n </mat-tab>\n }\n @if (logData) {\n <mat-tab label=\"Data\">\n <pre>{{ logData }}</pre>\n </mat-tab>\n }\n @if (server) {\n <mat-tab label=\"$_SERVER\">\n <pre>{{ server }}</pre>\n </mat-tab>\n }\n </mat-tab-group>\n }\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 <button\n mat-button\n type=\"button\"\n (click)=\"copy()\">\n Copy\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n", styles: ["mat-tab-group{margin-top:16px}pre{margin:0;padding:16px 0;white-space:pre-wrap;word-break:break-word}\n"] }]
|
|
1306
1318
|
}] });
|
|
1307
1319
|
|
|
1308
1320
|
class ServerLogsComponent {
|
|
@@ -1528,7 +1540,7 @@ class SettingsComponent {
|
|
|
1528
1540
|
});
|
|
1529
1541
|
}
|
|
1530
1542
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: SettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1531
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: SettingsComponent, isStandalone: true, selector: "fs-system-settings", inputs: { loadSettings: "loadSettings", save: "save" }, outputs: { fileRemove: "fileRemove", fileSelect: "fileSelect" }, ngImport: i0, template: "<mat-accordion>\n @for (group of groups; track group) {\n <mat-expansion-panel\n hideToggle\n >\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"title-row\">\n <div class=\"title\">\n {{ group || 'General' }}\n </div>\n <div class=\"actions\">\n <button\n type=\"button\"\n [matTooltip]=\"'Export ' + (group || 'General') + ' Settings'\"\n mat-icon-button\n (click)=\"export($event, groupedSettings[group])\">\n <mat-icon>\n cloud_download\n </mat-icon>\n </button>\n <button\n type=\"button\"\n [matTooltip]=\"'Import ' + (group || 'General') + ' Settings'\"\n mat-icon-button\n (click)=\"import($event, group)\">\n <mat-icon>\n cloud_upload\n </mat-icon>\n </button>\n </div>\n </div>\n </mat-panel-title>\n </mat-expansion-panel-header>\n @for (setting of groupedSettings[group]; track setting) {\n <div\n hideToggle\n class=\"setting\"\n [ngClass]=\"{ 'has-instruction': !! setting.instruction }\">\n @if (setting.interfaceType===SettingInterfaceType.InputBox) {\n <mat-form-field\n class=\"full-width form-field-multiline-subscript\"\n >\n <mat-label>\n {{ setting.label }}\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"setting.value\"\n [name]=\"'setting' + setting.id\">\n <mat-hint>\n {{ setting.instruction }}\n </mat-hint>\n </mat-form-field>\n }\n @if (setting.interfaceType===SettingInterfaceType.Textarea) {\n <mat-form-field\n class=\"full-width form-field-multiline-subscript\"\n >\n <mat-label>\n {{ setting.label }}\n </mat-label>\n <textarea\n matInput\n [(ngModel)]=\"setting.value\"\n [name]=\"'setting' + setting.id\">\n </textarea>\n <mat-hint>\n {{ setting.instruction }}\n </mat-hint>\n </mat-form-field>\n }\n @if (setting.interfaceType===SettingInterfaceType.Select || setting.interfaceType===SettingInterfaceType.SelectMultiple) {\n <mat-form-field\n class=\"full-width form-field-multiline-subscript\"\n >\n <mat-label>\n {{ setting.label }}\n </mat-label>\n <mat-select\n [(ngModel)]=\"setting.value\"\n [multiple]=\"setting.interfaceType===SettingInterfaceType.SelectMultiple\"\n [name]=\"'setting' + setting.id\">\n @for (item of setting.values | keyNameValue; track item) {\n <mat-option\n [value]=\"item.value\">\n {{ item.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n {{ setting.instruction }}\n </mat-hint>\n </mat-form-field>\n }\n @if (setting.interfaceType===SettingInterfaceType.Date) {\n <mat-form-field\n class=\"full-width form-field-multiline-subscript\"\n >\n <mat-label>\n {{ setting.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"setting.value\"\n [name]=\"'setting' + setting.id\">\n <mat-hint>\n {{ setting.instruction }}\n </mat-hint>\n </mat-form-field>\n }\n @if (setting.interfaceType===SettingInterfaceType.Color) {\n <mat-form-field\n class=\"full-width form-field-multiline-subscript\"\n >\n <mat-label>\n {{ setting.label }}\n </mat-label>\n <input\n matInput\n fsColorPicker\n [(ngModel)]=\"setting.value\"\n [name]=\"'setting' + setting.id\">\n <mat-hint>\n {{ setting.instruction }}\n </mat-hint>\n </mat-form-field>\n }\n @if (setting.interfaceType===SettingInterfaceType.Time) {\n <mat-form-field\n class=\"full-width form-field-multiline-subscript\"\n >\n <mat-label>\n {{ setting.label }}\n </mat-label>\n <input\n matInput\n fsTimePicker\n [(ngModel)]=\"setting.value\"\n [name]=\"'setting' + setting.id\">\n <mat-hint>\n {{ setting.instruction }}\n </mat-hint>\n </mat-form-field>\n }\n @if (setting.interfaceType===SettingInterfaceType.File) {\n <fs-file-picker\n [allowRemove]=\"true\"\n [allowDownload]=\"true\"\n (select)=\"fileSelect.emit({ setting: setting, file: $event.file })\"\n (remove)=\"fileRemove.emit(setting)\"\n [url]=\"setting.value\">\n <div fsFileLabel>\n {{ setting.label }}\n </div>\n <div fsFileHint>\n {{ setting.instruction }}\n </div>\n </fs-file-picker>\n }\n </div>\n }\n <button\n mat-stroked-button\n color=\"primary\"\n type=\"button\"\n (click)=\"saveGroup(group)\">\n Save\n </button>\n </mat-expansion-panel>\n }\n</mat-accordion>", styles: [".mat-expansion-panel-header{font-size:19px}.full-width{width:100%}.title-row{flex-direction:row;box-sizing:border-box;display:flex;place-content:center flex-start;align-items:center;width:100%}.title-row .title{display:flex;flex:1}:host ::ng-deep .mat-expansion-panel-header-title{margin:0}:host ::ng-deep .mat-expansion-panel .actions{display:none}:host ::ng-deep .mat-expansion-panel.mat-expanded .actions{display:block}:host ::ng-deep .setting.has-instruction fs-file-picker fs-label-message{display:block;padding-bottom:1em}\n"], dependencies: [{ kind: "directive", type: MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: FsDatePickerModule }, { kind: "component", type: i2$4.FsDatePickerComponent, selector: "[fsDatePicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "startOfDay", "view", "format", "minutes"], outputs: ["change"] }, { kind: "component", type: i2$4.FsTimePickerComponent, selector: "[fsTimePicker]", inputs: ["view"] }, { kind: "ngmodule", type: FsColorPickerModule }, { kind: "component", type: i3$3.FsColorPickerComponent, selector: "[fsColorPicker]", inputs: ["showClear"] }, { kind: "ngmodule", type: FsFileModule }, { kind: "component", type: i4$1.FsFilePickerComponent, selector: "fs-file-picker", inputs: ["minWidth", "minHeight", "imageWidth", "imageHeight", "imageQuality", "label", "showFilename", "allowDownload", "allowReupload", "multiple", "allowRemove", "url", "file", "accept", "disabled", "previewWidth", "previewHeight"], outputs: ["select", "remove", "download"] }, { kind: "directive", type: i4$1.FsFileLabelDirective, selector: "[fsFileLabel]" }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "pipe", type: KeyNameValuePipe, name: "keyNameValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1543
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: SettingsComponent, isStandalone: true, selector: "fs-system-settings", inputs: { loadSettings: "loadSettings", save: "save" }, outputs: { fileRemove: "fileRemove", fileSelect: "fileSelect" }, ngImport: i0, template: "<mat-accordion>\n @for (group of groups; track group) {\n <mat-expansion-panel\n hideToggle\n >\n <mat-expansion-panel-header>\n <mat-panel-title>\n <div class=\"title-row\">\n <div class=\"title\">\n {{ group || 'General' }}\n </div>\n <div class=\"actions\">\n <button\n type=\"button\"\n [matTooltip]=\"'Export ' + (group || 'General') + ' Settings'\"\n mat-icon-button\n (click)=\"export($event, groupedSettings[group])\">\n <mat-icon>\n cloud_download\n </mat-icon>\n </button>\n <button\n type=\"button\"\n [matTooltip]=\"'Import ' + (group || 'General') + ' Settings'\"\n mat-icon-button\n (click)=\"import($event, group)\">\n <mat-icon>\n cloud_upload\n </mat-icon>\n </button>\n </div>\n </div>\n </mat-panel-title>\n </mat-expansion-panel-header>\n @for (setting of groupedSettings[group]; track setting) {\n <div\n hideToggle\n class=\"setting\"\n [ngClass]=\"{ 'has-instruction': !! setting.instruction }\">\n @if (setting.interfaceType===SettingInterfaceType.InputBox) {\n <mat-form-field\n class=\"full-width form-field-multiline-subscript\"\n >\n <mat-label>\n {{ setting.label }}\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"setting.value\"\n [name]=\"'setting' + setting.id\">\n <mat-hint>\n {{ setting.instruction }}\n </mat-hint>\n </mat-form-field>\n }\n @if (setting.interfaceType===SettingInterfaceType.Textarea) {\n <mat-form-field\n class=\"full-width form-field-multiline-subscript\"\n >\n <mat-label>\n {{ setting.label }}\n </mat-label>\n <textarea\n matInput\n [(ngModel)]=\"setting.value\"\n [name]=\"'setting' + setting.id\">\n </textarea>\n <mat-hint>\n {{ setting.instruction }}\n </mat-hint>\n </mat-form-field>\n }\n @if (setting.interfaceType===SettingInterfaceType.Select || setting.interfaceType===SettingInterfaceType.SelectMultiple) {\n <mat-form-field\n class=\"full-width form-field-multiline-subscript\"\n >\n <mat-label>\n {{ setting.label }}\n </mat-label>\n <mat-select\n [(ngModel)]=\"setting.value\"\n [multiple]=\"setting.interfaceType===SettingInterfaceType.SelectMultiple\"\n [name]=\"'setting' + setting.id\">\n @for (item of setting.values | keyNameValue; track item) {\n <mat-option\n [value]=\"item.value\">\n {{ item.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n {{ setting.instruction }}\n </mat-hint>\n </mat-form-field>\n }\n @if (setting.interfaceType===SettingInterfaceType.Date) {\n <mat-form-field\n class=\"full-width form-field-multiline-subscript\"\n >\n <mat-label>\n {{ setting.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"setting.value\"\n [name]=\"'setting' + setting.id\">\n <mat-hint>\n {{ setting.instruction }}\n </mat-hint>\n </mat-form-field>\n }\n @if (setting.interfaceType===SettingInterfaceType.Color) {\n <mat-form-field\n class=\"full-width form-field-multiline-subscript\"\n >\n <mat-label>\n {{ setting.label }}\n </mat-label>\n <input\n matInput\n fsColorPicker\n [(ngModel)]=\"setting.value\"\n [name]=\"'setting' + setting.id\">\n <mat-hint>\n {{ setting.instruction }}\n </mat-hint>\n </mat-form-field>\n }\n @if (setting.interfaceType===SettingInterfaceType.Time) {\n <mat-form-field\n class=\"full-width form-field-multiline-subscript\"\n >\n <mat-label>\n {{ setting.label }}\n </mat-label>\n <input\n matInput\n fsTimePicker\n [(ngModel)]=\"setting.value\"\n [name]=\"'setting' + setting.id\">\n <mat-hint>\n {{ setting.instruction }}\n </mat-hint>\n </mat-form-field>\n }\n @if (setting.interfaceType===SettingInterfaceType.File) {\n <fs-file-picker\n [allowRemove]=\"true\"\n [allowDownload]=\"true\"\n (select)=\"fileSelect.emit({ setting: setting, file: $event.file })\"\n (remove)=\"fileRemove.emit(setting)\"\n [url]=\"setting.value\">\n <div fsFileLabel>\n {{ setting.label }}\n </div>\n <div fsFileHint>\n {{ setting.instruction }}\n </div>\n </fs-file-picker>\n }\n </div>\n }\n <button\n mat-stroked-button\n color=\"primary\"\n type=\"button\"\n (click)=\"saveGroup(group)\">\n Save\n </button>\n </mat-expansion-panel>\n }\n</mat-accordion>", styles: [".mat-expansion-panel-header{font-size:19px}.full-width{width:100%}.title-row{flex-direction:row;box-sizing:border-box;display:flex;place-content:center flex-start;align-items:center;width:100%}.title-row .title{display:flex;flex:1}:host ::ng-deep .mat-expansion-panel-header-title{margin:0}:host ::ng-deep .mat-expansion-panel .actions{display:none}:host ::ng-deep .mat-expansion-panel.mat-expanded .actions{display:block}:host ::ng-deep .setting.has-instruction fs-file-picker fs-label-message{display:block;padding-bottom:1em}\n"], dependencies: [{ kind: "directive", type: MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: FsDatePickerModule }, { kind: "component", type: i2$4.FsDatePickerComponent, selector: "[fsDatePicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "startOfDay", "view", "format", "minutes"], outputs: ["change"] }, { kind: "component", type: i2$4.FsTimePickerComponent, selector: "[fsTimePicker]", inputs: ["view"] }, { kind: "ngmodule", type: FsColorPickerModule }, { kind: "component", type: i3$3.FsColorPickerComponent, selector: "[fsColorPicker]", inputs: ["showClear"] }, { kind: "ngmodule", type: FsFileModule }, { kind: "component", type: i4$1.FsFilePickerComponent, selector: "fs-file-picker", inputs: ["minWidth", "minHeight", "imageWidth", "imageHeight", "imageQuality", "label", "showFilename", "allowDownload", "allowReupload", "multiple", "allowRemove", "url", "file", "accept", "disabled", "previewWidth", "previewHeight"], outputs: ["select", "remove", "download"] }, { kind: "directive", type: i4$1.FsFileLabelDirective, selector: "[fsFileLabel]" }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "pipe", type: KeyNameValuePipe, name: "keyNameValue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1532
1544
|
}
|
|
1533
1545
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: SettingsComponent, decorators: [{
|
|
1534
1546
|
type: Component,
|