@mintplayer/ng-spark 22.33.0 → 22.35.0
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/fesm2022/mintplayer-ng-spark-auth-account.mjs +576 -2
- package/fesm2022/mintplayer-ng-spark-auth-account.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-auth-core.mjs +24 -0
- package/fesm2022/mintplayer-ng-spark-auth-core.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-auth-models.mjs +4 -1
- package/fesm2022/mintplayer-ng-spark-auth-models.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-auth-register.mjs +18 -5
- package/fesm2022/mintplayer-ng-spark-auth-register.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-auth-routes.mjs +22 -1
- package/fesm2022/mintplayer-ng-spark-auth-routes.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-dashboards.mjs +726 -0
- package/fesm2022/mintplayer-ng-spark-dashboards.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-panels.mjs +9 -1
- package/fesm2022/mintplayer-ng-spark-panels.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-detail.mjs +10 -3
- package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
- package/package.json +5 -1
- package/types/mintplayer-ng-spark-auth-account.d.ts +56 -1
- package/types/mintplayer-ng-spark-auth-core.d.ts +11 -1
- package/types/mintplayer-ng-spark-auth-models.d.ts +96 -1
- package/types/mintplayer-ng-spark-auth-register.d.ts +13 -0
- package/types/mintplayer-ng-spark-auth-routes.d.ts +15 -0
- package/types/mintplayer-ng-spark-dashboards.d.ts +226 -0
- package/types/mintplayer-ng-spark-panels.d.ts +16 -0
- package/types/mintplayer-ng-spark-po-detail.d.ts +3 -0
|
@@ -0,0 +1,726 @@
|
|
|
1
|
+
import { NgComponentOutlet, formatNumber } from "@angular/common";
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
import { ChangeDetectionStrategy, Component, LOCALE_ID, computed, inject, input } from "@angular/core";
|
|
4
|
+
import { Color } from "@mintplayer/ng-bootstrap";
|
|
5
|
+
import { BsProgressBarComponent, BsProgressComponent } from "@mintplayer/ng-bootstrap/progress-bar";
|
|
6
|
+
import { BsTableComponent } from "@mintplayer/ng-bootstrap/table";
|
|
7
|
+
import { SparkIconComponent } from "@mintplayer/ng-spark/icon";
|
|
8
|
+
import { SparkLanguageService } from "@mintplayer/ng-spark/services";
|
|
9
|
+
import { BsCardBodyComponent, BsCardComponent } from "@mintplayer/ng-bootstrap/card";
|
|
10
|
+
import { ShowedOn, hasShowedOnFlag } from "@mintplayer/ng-spark/models";
|
|
11
|
+
import { ResolveTranslationPipe, TranslateKeyPipe } from "@mintplayer/ng-spark/pipes";
|
|
12
|
+
import { SPARK_ATTRIBUTE_RENDERERS, rendererValue, withDeclaredInputs } from "@mintplayer/ng-spark/renderers";
|
|
13
|
+
import { provideSparkDetailLayouts } from "@mintplayer/ng-spark/panels";
|
|
14
|
+
function toSparkNumber(value) {
|
|
15
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
16
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
17
|
+
const parsed = Number(value);
|
|
18
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
function formatSparkBytes(bytes, locale = "en") {
|
|
23
|
+
if (bytes == null || !Number.isFinite(bytes)) return "—";
|
|
24
|
+
const units = [
|
|
25
|
+
"B",
|
|
26
|
+
"KB",
|
|
27
|
+
"MB",
|
|
28
|
+
"GB",
|
|
29
|
+
"TB",
|
|
30
|
+
"PB"
|
|
31
|
+
];
|
|
32
|
+
let value = bytes;
|
|
33
|
+
let unit = 0;
|
|
34
|
+
while (Math.abs(value) >= 1024 && unit < units.length - 1) {
|
|
35
|
+
value /= 1024;
|
|
36
|
+
unit++;
|
|
37
|
+
}
|
|
38
|
+
return unit === 0 ? `${formatNumber(value, locale, "1.0-0")} B` : `${formatNumber(value, locale, "1.1-1")} ${units[unit]}`;
|
|
39
|
+
}
|
|
40
|
+
function formatSparkDashboardValue(value, format, locale = "en", decimals) {
|
|
41
|
+
if (value === null || value === void 0 || value === "") return "—";
|
|
42
|
+
switch (format) {
|
|
43
|
+
case "bytes": return formatSparkBytes(toSparkNumber(value), locale);
|
|
44
|
+
case "percent": {
|
|
45
|
+
const n = toSparkNumber(value);
|
|
46
|
+
const d = decimals ?? 1;
|
|
47
|
+
return n === null ? "—" : `${formatNumber(n, locale, `1.${d}-${d}`)}%`;
|
|
48
|
+
}
|
|
49
|
+
case "date":
|
|
50
|
+
case "datetime": {
|
|
51
|
+
const date = new Date(String(value));
|
|
52
|
+
if (Number.isNaN(date.getTime())) return String(value);
|
|
53
|
+
return format === "date" ? date.toLocaleDateString(locale) : date.toLocaleString(locale);
|
|
54
|
+
}
|
|
55
|
+
case "text": return String(value);
|
|
56
|
+
default: {
|
|
57
|
+
const n = typeof value === "boolean" ? null : toSparkNumber(value);
|
|
58
|
+
if (n === null) return String(value);
|
|
59
|
+
const d = decimals ?? 0;
|
|
60
|
+
return formatNumber(n, locale, `1.${d}-${d}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function sparkThresholdColor(value, thresholds) {
|
|
65
|
+
if (value === null) return null;
|
|
66
|
+
const past = (limit) => typeof limit === "number" && (thresholds.direction === "below" ? value <= limit : value >= limit);
|
|
67
|
+
if (past(thresholds.danger)) return "danger";
|
|
68
|
+
if (past(thresholds.warning)) return "warning";
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
var SparkStatComponent = class SparkStatComponent {
|
|
72
|
+
locale = inject(LOCALE_ID);
|
|
73
|
+
value = input(...ngDevMode ? [void 0, { debugName: "value" }] : /* istanbul ignore next */ []);
|
|
74
|
+
options = input(...ngDevMode ? [void 0, { debugName: "options" }] : /* istanbul ignore next */ []);
|
|
75
|
+
settings = computed(() => this.options() ?? {}, ...ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []);
|
|
76
|
+
text = computed(() => {
|
|
77
|
+
const s = this.settings();
|
|
78
|
+
const text = formatSparkDashboardValue(this.value(), s.format, this.locale, typeof s.decimals === "number" ? s.decimals : void 0);
|
|
79
|
+
return text === "—" || typeof s.suffix !== "string" ? text : text + s.suffix;
|
|
80
|
+
}, ...ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []);
|
|
81
|
+
color = computed(() => sparkThresholdColor(toSparkNumber(this.value()), this.settings()), ...ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []);
|
|
82
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
83
|
+
minVersion: "12.0.0",
|
|
84
|
+
version: "22.2.2",
|
|
85
|
+
ngImport: i0,
|
|
86
|
+
type: SparkStatComponent,
|
|
87
|
+
deps: [],
|
|
88
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
89
|
+
});
|
|
90
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
91
|
+
minVersion: "17.1.0",
|
|
92
|
+
version: "22.2.2",
|
|
93
|
+
type: SparkStatComponent,
|
|
94
|
+
isStandalone: true,
|
|
95
|
+
selector: "spark-stat",
|
|
96
|
+
inputs: {
|
|
97
|
+
value: {
|
|
98
|
+
classPropertyName: "value",
|
|
99
|
+
publicName: "value",
|
|
100
|
+
isSignal: true,
|
|
101
|
+
isRequired: false,
|
|
102
|
+
transformFunction: null
|
|
103
|
+
},
|
|
104
|
+
options: {
|
|
105
|
+
classPropertyName: "options",
|
|
106
|
+
publicName: "options",
|
|
107
|
+
isSignal: true,
|
|
108
|
+
isRequired: false,
|
|
109
|
+
transformFunction: null
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
ngImport: i0,
|
|
113
|
+
template: `
|
|
114
|
+
<span class="spark-stat" [class.text-warning-emphasis]="color() === 'warning'" [class.text-danger]="color() === 'danger'"
|
|
115
|
+
[class.text-body-secondary]="text() === '—'" [attr.data-threshold]="color()">{{ text() }}</span>
|
|
116
|
+
`,
|
|
117
|
+
isInline: true,
|
|
118
|
+
styles: [":host{display:inline-block}.spark-stat{font-size:var(--spark-stat-font-size, 1.75rem);font-weight:600;line-height:1.2;font-variant-numeric:tabular-nums}\n"],
|
|
119
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
123
|
+
minVersion: "12.0.0",
|
|
124
|
+
version: "22.2.2",
|
|
125
|
+
ngImport: i0,
|
|
126
|
+
type: SparkStatComponent,
|
|
127
|
+
decorators: [{
|
|
128
|
+
type: Component,
|
|
129
|
+
args: [{
|
|
130
|
+
selector: "spark-stat",
|
|
131
|
+
template: `
|
|
132
|
+
<span class="spark-stat" [class.text-warning-emphasis]="color() === 'warning'" [class.text-danger]="color() === 'danger'"
|
|
133
|
+
[class.text-body-secondary]="text() === '—'" [attr.data-threshold]="color()">{{ text() }}</span>
|
|
134
|
+
`,
|
|
135
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
136
|
+
styles: [":host{display:inline-block}.spark-stat{font-size:var(--spark-stat-font-size, 1.75rem);font-weight:600;line-height:1.2;font-variant-numeric:tabular-nums}\n"]
|
|
137
|
+
}]
|
|
138
|
+
}],
|
|
139
|
+
propDecorators: {
|
|
140
|
+
value: [{
|
|
141
|
+
type: i0.Input,
|
|
142
|
+
args: [{
|
|
143
|
+
isSignal: true,
|
|
144
|
+
alias: "value",
|
|
145
|
+
required: false
|
|
146
|
+
}]
|
|
147
|
+
}],
|
|
148
|
+
options: [{
|
|
149
|
+
type: i0.Input,
|
|
150
|
+
args: [{
|
|
151
|
+
isSignal: true,
|
|
152
|
+
alias: "options",
|
|
153
|
+
required: false
|
|
154
|
+
}]
|
|
155
|
+
}]
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
var SparkMeterComponent = class SparkMeterComponent {
|
|
159
|
+
locale = inject(LOCALE_ID);
|
|
160
|
+
value = input(...ngDevMode ? [void 0, { debugName: "value" }] : /* istanbul ignore next */ []);
|
|
161
|
+
options = input(...ngDevMode ? [void 0, { debugName: "options" }] : /* istanbul ignore next */ []);
|
|
162
|
+
settings = computed(() => this.options() ?? {}, ...ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []);
|
|
163
|
+
label = computed(() => typeof this.settings().label === "string" ? this.settings().label : "Usage", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
|
|
164
|
+
view = computed(() => {
|
|
165
|
+
const raw = this.value();
|
|
166
|
+
const s = this.settings();
|
|
167
|
+
const isPair = raw !== null && typeof raw === "object" && "value" in raw;
|
|
168
|
+
const value = toSparkNumber(isPair ? raw.value : raw);
|
|
169
|
+
const max = toSparkNumber(isPair ? raw.max : void 0) ?? toSparkNumber(s.max) ?? (isPair ? null : 100);
|
|
170
|
+
if (value === null || max === null || max <= 0) return null;
|
|
171
|
+
const share = Math.round(Math.min(100, Math.max(0, value / max * 100)) * 10) / 10;
|
|
172
|
+
const threshold = sparkThresholdColor(share, {
|
|
173
|
+
warning: typeof s.warning === "number" ? s.warning : 75,
|
|
174
|
+
danger: typeof s.danger === "number" ? s.danger : 90
|
|
175
|
+
});
|
|
176
|
+
const format = s.format ?? "number";
|
|
177
|
+
return {
|
|
178
|
+
value,
|
|
179
|
+
max,
|
|
180
|
+
share,
|
|
181
|
+
color: threshold === "danger" ? Color.danger : threshold === "warning" ? Color.warning : Color.success,
|
|
182
|
+
text: `${formatSparkDashboardValue(value, format, this.locale)} / ${formatSparkDashboardValue(max, format, this.locale)} (${formatNumber(share, this.locale, "1.0-1")}%)`
|
|
183
|
+
};
|
|
184
|
+
}, ...ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []);
|
|
185
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
186
|
+
minVersion: "12.0.0",
|
|
187
|
+
version: "22.2.2",
|
|
188
|
+
ngImport: i0,
|
|
189
|
+
type: SparkMeterComponent,
|
|
190
|
+
deps: [],
|
|
191
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
192
|
+
});
|
|
193
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
194
|
+
minVersion: "17.0.0",
|
|
195
|
+
version: "22.2.2",
|
|
196
|
+
type: SparkMeterComponent,
|
|
197
|
+
isStandalone: true,
|
|
198
|
+
selector: "spark-meter",
|
|
199
|
+
inputs: {
|
|
200
|
+
value: {
|
|
201
|
+
classPropertyName: "value",
|
|
202
|
+
publicName: "value",
|
|
203
|
+
isSignal: true,
|
|
204
|
+
isRequired: false,
|
|
205
|
+
transformFunction: null
|
|
206
|
+
},
|
|
207
|
+
options: {
|
|
208
|
+
classPropertyName: "options",
|
|
209
|
+
publicName: "options",
|
|
210
|
+
isSignal: true,
|
|
211
|
+
isRequired: false,
|
|
212
|
+
transformFunction: null
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
ngImport: i0,
|
|
216
|
+
template: `
|
|
217
|
+
@if (view(); as v) {
|
|
218
|
+
<div class="d-flex flex-column gap-1 spark-meter">
|
|
219
|
+
<bs-progress [style.height]="'.75rem'">
|
|
220
|
+
<bs-progress-bar [value]="v.share" [minimum]="0" [maximum]="100" [color]="v.color"
|
|
221
|
+
[ariaLabel]="label()" [valueText]="v.text" />
|
|
222
|
+
</bs-progress>
|
|
223
|
+
<span class="small text-nowrap" data-meter-text>{{ v.text }}</span>
|
|
224
|
+
</div>
|
|
225
|
+
} @else {
|
|
226
|
+
<span class="text-muted small">—</span>
|
|
227
|
+
}
|
|
228
|
+
`,
|
|
229
|
+
isInline: true,
|
|
230
|
+
styles: [":host{display:block;min-width:8rem}\n"],
|
|
231
|
+
dependencies: [{
|
|
232
|
+
kind: "component",
|
|
233
|
+
type: BsProgressComponent,
|
|
234
|
+
selector: "bs-progress",
|
|
235
|
+
inputs: [
|
|
236
|
+
"height",
|
|
237
|
+
"isIndeterminate",
|
|
238
|
+
"ariaLabel"
|
|
239
|
+
]
|
|
240
|
+
}, {
|
|
241
|
+
kind: "component",
|
|
242
|
+
type: BsProgressBarComponent,
|
|
243
|
+
selector: "bs-progress-bar",
|
|
244
|
+
inputs: [
|
|
245
|
+
"minimum",
|
|
246
|
+
"maximum",
|
|
247
|
+
"value",
|
|
248
|
+
"color",
|
|
249
|
+
"striped",
|
|
250
|
+
"animated",
|
|
251
|
+
"ariaLabel",
|
|
252
|
+
"valueText"
|
|
253
|
+
]
|
|
254
|
+
}],
|
|
255
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
256
|
+
});
|
|
257
|
+
};
|
|
258
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
259
|
+
minVersion: "12.0.0",
|
|
260
|
+
version: "22.2.2",
|
|
261
|
+
ngImport: i0,
|
|
262
|
+
type: SparkMeterComponent,
|
|
263
|
+
decorators: [{
|
|
264
|
+
type: Component,
|
|
265
|
+
args: [{
|
|
266
|
+
selector: "spark-meter",
|
|
267
|
+
imports: [BsProgressComponent, BsProgressBarComponent],
|
|
268
|
+
template: `
|
|
269
|
+
@if (view(); as v) {
|
|
270
|
+
<div class="d-flex flex-column gap-1 spark-meter">
|
|
271
|
+
<bs-progress [style.height]="'.75rem'">
|
|
272
|
+
<bs-progress-bar [value]="v.share" [minimum]="0" [maximum]="100" [color]="v.color"
|
|
273
|
+
[ariaLabel]="label()" [valueText]="v.text" />
|
|
274
|
+
</bs-progress>
|
|
275
|
+
<span class="small text-nowrap" data-meter-text>{{ v.text }}</span>
|
|
276
|
+
</div>
|
|
277
|
+
} @else {
|
|
278
|
+
<span class="text-muted small">—</span>
|
|
279
|
+
}
|
|
280
|
+
`,
|
|
281
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
282
|
+
styles: [":host{display:block;min-width:8rem}\n"]
|
|
283
|
+
}]
|
|
284
|
+
}],
|
|
285
|
+
propDecorators: {
|
|
286
|
+
value: [{
|
|
287
|
+
type: i0.Input,
|
|
288
|
+
args: [{
|
|
289
|
+
isSignal: true,
|
|
290
|
+
alias: "value",
|
|
291
|
+
required: false
|
|
292
|
+
}]
|
|
293
|
+
}],
|
|
294
|
+
options: [{
|
|
295
|
+
type: i0.Input,
|
|
296
|
+
args: [{
|
|
297
|
+
isSignal: true,
|
|
298
|
+
alias: "options",
|
|
299
|
+
required: false
|
|
300
|
+
}]
|
|
301
|
+
}]
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
var SparkDashboardTableComponent = class SparkDashboardTableComponent {
|
|
305
|
+
locale = inject(LOCALE_ID);
|
|
306
|
+
lang = inject(SparkLanguageService);
|
|
307
|
+
value = input(...ngDevMode ? [void 0, { debugName: "value" }] : /* istanbul ignore next */ []);
|
|
308
|
+
options = input(...ngDevMode ? [void 0, { debugName: "options" }] : /* istanbul ignore next */ []);
|
|
309
|
+
settings = computed(() => this.options() ?? {}, ...ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []);
|
|
310
|
+
rows = computed(() => toSparkTableRows(this.value()), ...ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []);
|
|
311
|
+
columns = computed(() => {
|
|
312
|
+
const declared = this.settings().columns;
|
|
313
|
+
if (Array.isArray(declared) && declared.length > 0) return declared.filter((c) => typeof c?.key === "string");
|
|
314
|
+
const first = this.rows()[0];
|
|
315
|
+
return first ? Object.keys(first).map((key) => ({ key })) : [];
|
|
316
|
+
}, ...ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []);
|
|
317
|
+
cells = computed(() => {
|
|
318
|
+
const columns = this.columns();
|
|
319
|
+
return this.rows().map((row) => columns.map((column) => this.cell(row[column.key], column)));
|
|
320
|
+
}, ...ngDevMode ? [{ debugName: "cells" }] : /* istanbul ignore next */ []);
|
|
321
|
+
header(column) {
|
|
322
|
+
return column.label ? this.lang.t(column.label, column.label) : column.key;
|
|
323
|
+
}
|
|
324
|
+
isNumeric(column) {
|
|
325
|
+
return column?.format === "number" || column?.format === "bytes" || column?.format === "percent";
|
|
326
|
+
}
|
|
327
|
+
cell(value, column) {
|
|
328
|
+
if (column.format === "boolean") return {
|
|
329
|
+
text: value === true ? this.lang.t("dashboards.yes", "yes") : "",
|
|
330
|
+
check: value === true
|
|
331
|
+
};
|
|
332
|
+
if (column.translate && value !== null && value !== void 0 && value !== "") return {
|
|
333
|
+
text: this.lang.t(column.translate + String(value), String(value)),
|
|
334
|
+
check: false
|
|
335
|
+
};
|
|
336
|
+
return {
|
|
337
|
+
text: formatSparkDashboardValue(value, column.format, this.locale),
|
|
338
|
+
check: false
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
342
|
+
minVersion: "12.0.0",
|
|
343
|
+
version: "22.2.2",
|
|
344
|
+
ngImport: i0,
|
|
345
|
+
type: SparkDashboardTableComponent,
|
|
346
|
+
deps: [],
|
|
347
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
348
|
+
});
|
|
349
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
350
|
+
minVersion: "17.0.0",
|
|
351
|
+
version: "22.2.2",
|
|
352
|
+
type: SparkDashboardTableComponent,
|
|
353
|
+
isStandalone: true,
|
|
354
|
+
selector: "spark-dashboard-table",
|
|
355
|
+
inputs: {
|
|
356
|
+
value: {
|
|
357
|
+
classPropertyName: "value",
|
|
358
|
+
publicName: "value",
|
|
359
|
+
isSignal: true,
|
|
360
|
+
isRequired: false,
|
|
361
|
+
transformFunction: null
|
|
362
|
+
},
|
|
363
|
+
options: {
|
|
364
|
+
classPropertyName: "options",
|
|
365
|
+
publicName: "options",
|
|
366
|
+
isSignal: true,
|
|
367
|
+
isRequired: false,
|
|
368
|
+
transformFunction: null
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
ngImport: i0,
|
|
372
|
+
template: `
|
|
373
|
+
@if (rows().length > 0) {
|
|
374
|
+
<bs-table [isResponsive]="true" class="d-block mb-0">
|
|
375
|
+
<thead>
|
|
376
|
+
<tr>
|
|
377
|
+
@for (column of columns(); track column.key) {
|
|
378
|
+
<th [class.text-end]="isNumeric(column)">{{ header(column) }}</th>
|
|
379
|
+
}
|
|
380
|
+
</tr>
|
|
381
|
+
</thead>
|
|
382
|
+
<tbody>
|
|
383
|
+
@for (row of cells(); track $index) {
|
|
384
|
+
<tr>
|
|
385
|
+
@for (cell of row; track $index; let i = $index) {
|
|
386
|
+
<td [class.text-end]="isNumeric(columns()[i])" [class.text-break]="!isNumeric(columns()[i])">
|
|
387
|
+
@if (cell.check) { <spark-icon name="check-lg" class="text-success" aria-hidden="true" /><span class="visually-hidden">{{ cell.text }}</span> } @else { {{ cell.text }} }
|
|
388
|
+
</td>
|
|
389
|
+
}
|
|
390
|
+
</tr>
|
|
391
|
+
}
|
|
392
|
+
</tbody>
|
|
393
|
+
</bs-table>
|
|
394
|
+
} @else {
|
|
395
|
+
<span class="text-body-secondary small" data-empty>{{ lang.t(settings().empty ?? 'dashboards.empty', '—') }}</span>
|
|
396
|
+
}
|
|
397
|
+
`,
|
|
398
|
+
isInline: true,
|
|
399
|
+
dependencies: [{
|
|
400
|
+
kind: "component",
|
|
401
|
+
type: BsTableComponent,
|
|
402
|
+
selector: "bs-table",
|
|
403
|
+
inputs: [
|
|
404
|
+
"isResponsive",
|
|
405
|
+
"striped",
|
|
406
|
+
"hover",
|
|
407
|
+
"border",
|
|
408
|
+
"ariaRowCount"
|
|
409
|
+
]
|
|
410
|
+
}, {
|
|
411
|
+
kind: "component",
|
|
412
|
+
type: SparkIconComponent,
|
|
413
|
+
selector: "spark-icon",
|
|
414
|
+
inputs: ["name"]
|
|
415
|
+
}],
|
|
416
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
417
|
+
});
|
|
418
|
+
};
|
|
419
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
420
|
+
minVersion: "12.0.0",
|
|
421
|
+
version: "22.2.2",
|
|
422
|
+
ngImport: i0,
|
|
423
|
+
type: SparkDashboardTableComponent,
|
|
424
|
+
decorators: [{
|
|
425
|
+
type: Component,
|
|
426
|
+
args: [{
|
|
427
|
+
selector: "spark-dashboard-table",
|
|
428
|
+
imports: [BsTableComponent, SparkIconComponent],
|
|
429
|
+
template: `
|
|
430
|
+
@if (rows().length > 0) {
|
|
431
|
+
<bs-table [isResponsive]="true" class="d-block mb-0">
|
|
432
|
+
<thead>
|
|
433
|
+
<tr>
|
|
434
|
+
@for (column of columns(); track column.key) {
|
|
435
|
+
<th [class.text-end]="isNumeric(column)">{{ header(column) }}</th>
|
|
436
|
+
}
|
|
437
|
+
</tr>
|
|
438
|
+
</thead>
|
|
439
|
+
<tbody>
|
|
440
|
+
@for (row of cells(); track $index) {
|
|
441
|
+
<tr>
|
|
442
|
+
@for (cell of row; track $index; let i = $index) {
|
|
443
|
+
<td [class.text-end]="isNumeric(columns()[i])" [class.text-break]="!isNumeric(columns()[i])">
|
|
444
|
+
@if (cell.check) { <spark-icon name="check-lg" class="text-success" aria-hidden="true" /><span class="visually-hidden">{{ cell.text }}</span> } @else { {{ cell.text }} }
|
|
445
|
+
</td>
|
|
446
|
+
}
|
|
447
|
+
</tr>
|
|
448
|
+
}
|
|
449
|
+
</tbody>
|
|
450
|
+
</bs-table>
|
|
451
|
+
} @else {
|
|
452
|
+
<span class="text-body-secondary small" data-empty>{{ lang.t(settings().empty ?? 'dashboards.empty', '—') }}</span>
|
|
453
|
+
}
|
|
454
|
+
`,
|
|
455
|
+
changeDetection: ChangeDetectionStrategy.OnPush
|
|
456
|
+
}]
|
|
457
|
+
}],
|
|
458
|
+
propDecorators: {
|
|
459
|
+
value: [{
|
|
460
|
+
type: i0.Input,
|
|
461
|
+
args: [{
|
|
462
|
+
isSignal: true,
|
|
463
|
+
alias: "value",
|
|
464
|
+
required: false
|
|
465
|
+
}]
|
|
466
|
+
}],
|
|
467
|
+
options: [{
|
|
468
|
+
type: i0.Input,
|
|
469
|
+
args: [{
|
|
470
|
+
isSignal: true,
|
|
471
|
+
alias: "options",
|
|
472
|
+
required: false
|
|
473
|
+
}]
|
|
474
|
+
}]
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
function toSparkTableRows(value) {
|
|
478
|
+
if (Array.isArray(value)) return value.filter((r) => r !== null && typeof r === "object" && !Array.isArray(r));
|
|
479
|
+
if (value !== null && typeof value === "object") return Object.entries(value).map(([key, v]) => ({
|
|
480
|
+
key,
|
|
481
|
+
value: v
|
|
482
|
+
}));
|
|
483
|
+
if (typeof value === "string" && value.trim().startsWith("[")) try {
|
|
484
|
+
return toSparkTableRows(JSON.parse(value));
|
|
485
|
+
} catch {
|
|
486
|
+
return [];
|
|
487
|
+
}
|
|
488
|
+
return [];
|
|
489
|
+
}
|
|
490
|
+
const SPARK_DASHBOARD_METADATA_KEY = "dashboard";
|
|
491
|
+
function isSparkDashboard(item) {
|
|
492
|
+
const marker = item?.metadata?.[SPARK_DASHBOARD_METADATA_KEY];
|
|
493
|
+
return marker !== null && typeof marker === "object";
|
|
494
|
+
}
|
|
495
|
+
var SparkDashboardComponent = class SparkDashboardComponent {
|
|
496
|
+
locale = inject(LOCALE_ID);
|
|
497
|
+
renderers = inject(SPARK_ATTRIBUTE_RENDERERS);
|
|
498
|
+
context = input.required(...ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []);
|
|
499
|
+
sections = computed(() => {
|
|
500
|
+
const { item, entityType } = this.context();
|
|
501
|
+
const loaded = new Map(item.attributes.map((a) => [a.name, a]));
|
|
502
|
+
const formData = {};
|
|
503
|
+
for (const a of item.attributes) formData[a.name] = rendererValue(a);
|
|
504
|
+
const tiles = (entityType.attributes ?? []).filter((a) => loaded.has(a.name) && hasShowedOnFlag(loaded.get(a.name)?.showedOn ?? a.showedOn, ShowedOn.PersistentObject)).sort((a, b) => a.order - b.order).map((attribute) => this.tile(attribute, item, formData));
|
|
505
|
+
const groups = [...entityType.groups ?? []].sort((a, b) => a.order - b.order);
|
|
506
|
+
const groupIds = new Set(groups.map((g) => g.id));
|
|
507
|
+
const sections = [];
|
|
508
|
+
const ungrouped = tiles.filter((t) => !t.attribute.group || !groupIds.has(t.attribute.group));
|
|
509
|
+
if (ungrouped.length > 0) sections.push({
|
|
510
|
+
id: "__ungrouped__",
|
|
511
|
+
name: null,
|
|
512
|
+
tiles: ungrouped
|
|
513
|
+
});
|
|
514
|
+
for (const group of groups) {
|
|
515
|
+
const grouped = tiles.filter((t) => t.attribute.group === group.id);
|
|
516
|
+
if (grouped.length > 0) sections.push({
|
|
517
|
+
id: group.id,
|
|
518
|
+
name: group.name,
|
|
519
|
+
label: group.label,
|
|
520
|
+
tiles: grouped
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
return sections;
|
|
524
|
+
}, ...ngDevMode ? [{ debugName: "sections" }] : /* istanbul ignore next */ []);
|
|
525
|
+
generatedAt = computed(() => {
|
|
526
|
+
const marker = this.context().item.metadata?.[SPARK_DASHBOARD_METADATA_KEY];
|
|
527
|
+
const at = marker && typeof marker === "object" ? marker["generatedAtUtc"] : null;
|
|
528
|
+
if (typeof at !== "string") return null;
|
|
529
|
+
const date = new Date(at);
|
|
530
|
+
return Number.isNaN(date.getTime()) ? null : date.toLocaleTimeString(this.locale);
|
|
531
|
+
}, ...ngDevMode ? [{ debugName: "generatedAt" }] : /* istanbul ignore next */ []);
|
|
532
|
+
tile(attribute, item, formData) {
|
|
533
|
+
const value = rendererValue(item.attributes.find((a) => a.name === attribute.name));
|
|
534
|
+
const component = (attribute.renderer ? this.renderers.find((r) => r.name === attribute.renderer) : void 0)?.detailComponent ?? null;
|
|
535
|
+
const columnSpan = attribute.columnSpan ?? (attribute.renderer === "spark-dashboard-table" ? 3 : 1);
|
|
536
|
+
return {
|
|
537
|
+
attribute,
|
|
538
|
+
span: columnSpan >= 3 ? "row" : columnSpan === 2 ? 2 : 1,
|
|
539
|
+
component,
|
|
540
|
+
inputs: component ? withDeclaredInputs(component, {
|
|
541
|
+
value,
|
|
542
|
+
attribute,
|
|
543
|
+
options: attribute.rendererOptions,
|
|
544
|
+
formData,
|
|
545
|
+
item
|
|
546
|
+
}) : {},
|
|
547
|
+
text: formatSparkDashboardValue(value, void 0, this.locale)
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
551
|
+
minVersion: "12.0.0",
|
|
552
|
+
version: "22.2.2",
|
|
553
|
+
ngImport: i0,
|
|
554
|
+
type: SparkDashboardComponent,
|
|
555
|
+
deps: [],
|
|
556
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
557
|
+
});
|
|
558
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
559
|
+
minVersion: "17.0.0",
|
|
560
|
+
version: "22.2.2",
|
|
561
|
+
type: SparkDashboardComponent,
|
|
562
|
+
isStandalone: true,
|
|
563
|
+
selector: "spark-dashboard",
|
|
564
|
+
inputs: { context: {
|
|
565
|
+
classPropertyName: "context",
|
|
566
|
+
publicName: "context",
|
|
567
|
+
isSignal: true,
|
|
568
|
+
isRequired: true,
|
|
569
|
+
transformFunction: null
|
|
570
|
+
} },
|
|
571
|
+
ngImport: i0,
|
|
572
|
+
template: `
|
|
573
|
+
<div class="spark-dashboard mx-3 my-2">
|
|
574
|
+
@for (section of sections(); track section.id) {
|
|
575
|
+
<section class="mb-3" [attr.data-section]="section.name">
|
|
576
|
+
@if (section.name) {
|
|
577
|
+
<h3 class="h6 text-body-secondary mb-2">{{ section.label | resolveTranslation:section.name }}</h3>
|
|
578
|
+
}
|
|
579
|
+
<div class="spark-dashboard-tiles">
|
|
580
|
+
@for (tile of section.tiles; track tile.attribute.id) {
|
|
581
|
+
<bs-card class="d-block h-100" [class.spark-dashboard-span-2]="tile.span === 2"
|
|
582
|
+
[class.spark-dashboard-span-row]="tile.span === 'row'" [attr.data-tile]="tile.attribute.name">
|
|
583
|
+
<bs-card-body>
|
|
584
|
+
<div class="small text-body-secondary mb-1">{{ tile.attribute.label | resolveTranslation:tile.attribute.name }}</div>
|
|
585
|
+
@if (tile.component) {
|
|
586
|
+
<ng-container *ngComponentOutlet="tile.component; inputs: tile.inputs" />
|
|
587
|
+
} @else {
|
|
588
|
+
<div class="fs-4 fw-semibold text-break">{{ tile.text }}</div>
|
|
589
|
+
}
|
|
590
|
+
</bs-card-body>
|
|
591
|
+
</bs-card>
|
|
592
|
+
}
|
|
593
|
+
</div>
|
|
594
|
+
</section>
|
|
595
|
+
}
|
|
596
|
+
@if (generatedAt(); as at) {
|
|
597
|
+
<p class="small text-body-secondary mb-0" data-generated>{{ 'dashboards.updated' | t }} {{ at }}</p>
|
|
598
|
+
}
|
|
599
|
+
</div>
|
|
600
|
+
`,
|
|
601
|
+
isInline: true,
|
|
602
|
+
styles: [".spark-dashboard-tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(12rem,100%),1fr));gap:.75rem}.spark-dashboard-tiles>*{min-width:0}.spark-dashboard-span-row{grid-column:1 / -1}@media(min-width:576px){.spark-dashboard-span-2{grid-column:span 2}}\n"],
|
|
603
|
+
dependencies: [
|
|
604
|
+
{
|
|
605
|
+
kind: "directive",
|
|
606
|
+
type: NgComponentOutlet,
|
|
607
|
+
selector: "[ngComponentOutlet]",
|
|
608
|
+
inputs: [
|
|
609
|
+
"ngComponentOutlet",
|
|
610
|
+
"ngComponentOutletInputs",
|
|
611
|
+
"ngComponentOutletInjector",
|
|
612
|
+
"ngComponentOutletEnvironmentInjector",
|
|
613
|
+
"ngComponentOutletContent",
|
|
614
|
+
"ngComponentOutletNgModule"
|
|
615
|
+
],
|
|
616
|
+
exportAs: ["ngComponentOutlet"]
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
kind: "component",
|
|
620
|
+
type: BsCardComponent,
|
|
621
|
+
selector: "bs-card",
|
|
622
|
+
inputs: ["color", "outline"]
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
kind: "component",
|
|
626
|
+
type: BsCardBodyComponent,
|
|
627
|
+
selector: "bs-card-body"
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
kind: "pipe",
|
|
631
|
+
type: ResolveTranslationPipe,
|
|
632
|
+
name: "resolveTranslation"
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
kind: "pipe",
|
|
636
|
+
type: TranslateKeyPipe,
|
|
637
|
+
name: "t"
|
|
638
|
+
}
|
|
639
|
+
],
|
|
640
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
641
|
+
});
|
|
642
|
+
};
|
|
643
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
644
|
+
minVersion: "12.0.0",
|
|
645
|
+
version: "22.2.2",
|
|
646
|
+
ngImport: i0,
|
|
647
|
+
type: SparkDashboardComponent,
|
|
648
|
+
decorators: [{
|
|
649
|
+
type: Component,
|
|
650
|
+
args: [{
|
|
651
|
+
selector: "spark-dashboard",
|
|
652
|
+
imports: [
|
|
653
|
+
NgComponentOutlet,
|
|
654
|
+
BsCardComponent,
|
|
655
|
+
BsCardBodyComponent,
|
|
656
|
+
ResolveTranslationPipe,
|
|
657
|
+
TranslateKeyPipe
|
|
658
|
+
],
|
|
659
|
+
template: `
|
|
660
|
+
<div class="spark-dashboard mx-3 my-2">
|
|
661
|
+
@for (section of sections(); track section.id) {
|
|
662
|
+
<section class="mb-3" [attr.data-section]="section.name">
|
|
663
|
+
@if (section.name) {
|
|
664
|
+
<h3 class="h6 text-body-secondary mb-2">{{ section.label | resolveTranslation:section.name }}</h3>
|
|
665
|
+
}
|
|
666
|
+
<div class="spark-dashboard-tiles">
|
|
667
|
+
@for (tile of section.tiles; track tile.attribute.id) {
|
|
668
|
+
<bs-card class="d-block h-100" [class.spark-dashboard-span-2]="tile.span === 2"
|
|
669
|
+
[class.spark-dashboard-span-row]="tile.span === 'row'" [attr.data-tile]="tile.attribute.name">
|
|
670
|
+
<bs-card-body>
|
|
671
|
+
<div class="small text-body-secondary mb-1">{{ tile.attribute.label | resolveTranslation:tile.attribute.name }}</div>
|
|
672
|
+
@if (tile.component) {
|
|
673
|
+
<ng-container *ngComponentOutlet="tile.component; inputs: tile.inputs" />
|
|
674
|
+
} @else {
|
|
675
|
+
<div class="fs-4 fw-semibold text-break">{{ tile.text }}</div>
|
|
676
|
+
}
|
|
677
|
+
</bs-card-body>
|
|
678
|
+
</bs-card>
|
|
679
|
+
}
|
|
680
|
+
</div>
|
|
681
|
+
</section>
|
|
682
|
+
}
|
|
683
|
+
@if (generatedAt(); as at) {
|
|
684
|
+
<p class="small text-body-secondary mb-0" data-generated>{{ 'dashboards.updated' | t }} {{ at }}</p>
|
|
685
|
+
}
|
|
686
|
+
</div>
|
|
687
|
+
`,
|
|
688
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
689
|
+
styles: [".spark-dashboard-tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(12rem,100%),1fr));gap:.75rem}.spark-dashboard-tiles>*{min-width:0}.spark-dashboard-span-row{grid-column:1 / -1}@media(min-width:576px){.spark-dashboard-span-2{grid-column:span 2}}\n"]
|
|
690
|
+
}]
|
|
691
|
+
}],
|
|
692
|
+
propDecorators: { context: [{
|
|
693
|
+
type: i0.Input,
|
|
694
|
+
args: [{
|
|
695
|
+
isSignal: true,
|
|
696
|
+
alias: "context",
|
|
697
|
+
required: true
|
|
698
|
+
}]
|
|
699
|
+
}] }
|
|
700
|
+
});
|
|
701
|
+
const sparkDashboardRenderers = [
|
|
702
|
+
{
|
|
703
|
+
name: "spark-stat",
|
|
704
|
+
columnComponent: SparkStatComponent,
|
|
705
|
+
detailComponent: SparkStatComponent
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
name: "spark-meter",
|
|
709
|
+
columnComponent: SparkMeterComponent,
|
|
710
|
+
detailComponent: SparkMeterComponent
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
name: "spark-dashboard-table",
|
|
714
|
+
detailComponent: SparkDashboardTableComponent
|
|
715
|
+
}
|
|
716
|
+
];
|
|
717
|
+
function provideSparkDashboards() {
|
|
718
|
+
return provideSparkDetailLayouts({
|
|
719
|
+
id: "spark-dashboard",
|
|
720
|
+
component: SparkDashboardComponent,
|
|
721
|
+
matches: (item) => isSparkDashboard(item)
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
export { SPARK_DASHBOARD_METADATA_KEY, SparkDashboardComponent, SparkDashboardTableComponent, SparkMeterComponent, SparkStatComponent, formatSparkBytes, formatSparkDashboardValue, isSparkDashboard, provideSparkDashboards, sparkDashboardRenderers, sparkThresholdColor, toSparkNumber, toSparkTableRows };
|
|
725
|
+
|
|
726
|
+
//# sourceMappingURL=mintplayer-ng-spark-dashboards.mjs.map
|