@esfaenza/admin-module 20.3.13 → 20.3.16
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/esfaenza-admin-module.mjs +650 -4
- package/fesm2022/esfaenza-admin-module.mjs.map +1 -1
- package/index.d.ts +279 -19
- package/package.json +2 -2
|
@@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common';
|
|
|
3
3
|
import * as i7 from '@angular/forms';
|
|
4
4
|
import { FormsModule } from '@angular/forms';
|
|
5
5
|
import * as i0 from '@angular/core';
|
|
6
|
-
import { InjectionToken, Injectable, Inject, Component, ViewChild, EventEmitter, Output, Input, Pipe, NgModule } from '@angular/core';
|
|
6
|
+
import { InjectionToken, Injectable, Inject, Component, ViewChild, EventEmitter, Output, Input, Pipe, inject, NgModule } from '@angular/core';
|
|
7
7
|
import * as i4 from '@angular/router';
|
|
8
8
|
import { RouterModule } from '@angular/router';
|
|
9
9
|
import * as i8$1 from 'ngx-bootstrap/modal';
|
|
@@ -30,6 +30,7 @@ import * as i10 from '@esfaenza/core/directives';
|
|
|
30
30
|
import { DirectivesModule } from '@esfaenza/core/directives';
|
|
31
31
|
import { GenericItem, KeyValue as KeyValue$1 } from '@esfaenza/core/domain';
|
|
32
32
|
import { __decorate } from 'tslib';
|
|
33
|
+
import * as am5 from '@amcharts/amcharts5';
|
|
33
34
|
import { ComponentsModule } from '@esfaenza/core/components';
|
|
34
35
|
|
|
35
36
|
class AuditsView extends AppSearch {
|
|
@@ -42,6 +43,7 @@ class AuditsView extends AppSearch {
|
|
|
42
43
|
|
|
43
44
|
const ADM_MODULE_PATH = new InjectionToken('ADM_MODULE_PATH');
|
|
44
45
|
const ADM_CONVERSATIONS = new InjectionToken('ADM_CONVERSATIONS');
|
|
46
|
+
const ADM_TOPACT_V2 = new InjectionToken('ADM_TOPACT_V2');
|
|
45
47
|
|
|
46
48
|
class AdmAuditLoc extends LocalizationService {
|
|
47
49
|
constructor(injector) {
|
|
@@ -152,6 +154,12 @@ class AdminModuleBaseService {
|
|
|
152
154
|
let ret = await firstValueFrom(this.http.post(POST_Director_GetTopActivities, sv, pars));
|
|
153
155
|
return ret;
|
|
154
156
|
}
|
|
157
|
+
// Stesso URL di getTopActivities: con DirectorFeature.TopActivityV2 attivo il backend-for-frontend risponde con il contratto v2
|
|
158
|
+
async getTopActivitiesV2(be, req) {
|
|
159
|
+
var pars = new HttpParams().set("be", be ?? "");
|
|
160
|
+
let ret = await firstValueFrom(this.http.post(POST_Director_GetTopActivities, req, pars));
|
|
161
|
+
return ret;
|
|
162
|
+
}
|
|
155
163
|
async getInfos(be) {
|
|
156
164
|
var pars = new HttpParams().set("be", be ?? "");
|
|
157
165
|
let ret = await firstValueFrom(this.http.get(GET_Director_GetInfos, pars, null, false).pipe(catchError(_ => of(null))));
|
|
@@ -1094,6 +1102,633 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.34", ngImpo
|
|
|
1094
1102
|
args: [ADM_MODULE_PATH]
|
|
1095
1103
|
}] }] });
|
|
1096
1104
|
|
|
1105
|
+
// Enum della Top Activity v2: i numeri sono quelli del backend (le risposte li riportano come numeri)
|
|
1106
|
+
var TopActivityDimension;
|
|
1107
|
+
(function (TopActivityDimension) {
|
|
1108
|
+
TopActivityDimension[TopActivityDimension["WaitClass"] = 0] = "WaitClass";
|
|
1109
|
+
TopActivityDimension[TopActivityDimension["EventType"] = 1] = "EventType";
|
|
1110
|
+
TopActivityDimension[TopActivityDimension["WaitEvent"] = 2] = "WaitEvent";
|
|
1111
|
+
TopActivityDimension[TopActivityDimension["Instance"] = 3] = "Instance";
|
|
1112
|
+
TopActivityDimension[TopActivityDimension["UserSession"] = 4] = "UserSession";
|
|
1113
|
+
TopActivityDimension[TopActivityDimension["UserName"] = 5] = "UserName";
|
|
1114
|
+
TopActivityDimension[TopActivityDimension["Tenant"] = 6] = "Tenant";
|
|
1115
|
+
TopActivityDimension[TopActivityDimension["SessionType"] = 7] = "SessionType";
|
|
1116
|
+
TopActivityDimension[TopActivityDimension["BackgroundSession"] = 8] = "BackgroundSession";
|
|
1117
|
+
TopActivityDimension[TopActivityDimension["JobName"] = 9] = "JobName";
|
|
1118
|
+
TopActivityDimension[TopActivityDimension["ConsumerGroup"] = 10] = "ConsumerGroup";
|
|
1119
|
+
TopActivityDimension[TopActivityDimension["ThreadType"] = 11] = "ThreadType";
|
|
1120
|
+
TopActivityDimension[TopActivityDimension["Api"] = 12] = "Api";
|
|
1121
|
+
TopActivityDimension[TopActivityDimension["Machine"] = 13] = "Machine";
|
|
1122
|
+
})(TopActivityDimension || (TopActivityDimension = {}));
|
|
1123
|
+
var TopActivityDataSource;
|
|
1124
|
+
(function (TopActivityDataSource) {
|
|
1125
|
+
TopActivityDataSource[TopActivityDataSource["Memory"] = 0] = "Memory";
|
|
1126
|
+
TopActivityDataSource[TopActivityDataSource["MemoryAndStored"] = 1] = "MemoryAndStored";
|
|
1127
|
+
})(TopActivityDataSource || (TopActivityDataSource = {}));
|
|
1128
|
+
var TopActivityResolution;
|
|
1129
|
+
(function (TopActivityResolution) {
|
|
1130
|
+
TopActivityResolution[TopActivityResolution["Low"] = 0] = "Low";
|
|
1131
|
+
TopActivityResolution[TopActivityResolution["Medium"] = 1] = "Medium";
|
|
1132
|
+
TopActivityResolution[TopActivityResolution["High"] = 2] = "High";
|
|
1133
|
+
TopActivityResolution[TopActivityResolution["Maximum"] = 3] = "Maximum";
|
|
1134
|
+
})(TopActivityResolution || (TopActivityResolution = {}));
|
|
1135
|
+
var TopActivityMaximumThreads;
|
|
1136
|
+
(function (TopActivityMaximumThreads) {
|
|
1137
|
+
TopActivityMaximumThreads[TopActivityMaximumThreads["None"] = 0] = "None";
|
|
1138
|
+
TopActivityMaximumThreads[TopActivityMaximumThreads["Cores"] = 1] = "Cores";
|
|
1139
|
+
TopActivityMaximumThreads[TopActivityMaximumThreads["Threads"] = 2] = "Threads";
|
|
1140
|
+
})(TopActivityMaximumThreads || (TopActivityMaximumThreads = {}));
|
|
1141
|
+
|
|
1142
|
+
class TopActivityV2Filter {
|
|
1143
|
+
}
|
|
1144
|
+
// Richiesta della Top Activity v2: date in ISO UTC (…Z), campi non valorizzati = default del backend
|
|
1145
|
+
class TopActivityV2Request {
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
class AdmTopActivityV2Loc extends LocalizationService {
|
|
1149
|
+
constructor(injector) {
|
|
1150
|
+
super(injector);
|
|
1151
|
+
super.set("it->en", "Attività Principali", ["Top Activities"]);
|
|
1152
|
+
super.set("it->en", "CPU", ["CPUs"]);
|
|
1153
|
+
super.set("it->en", "Da", ["From"]);
|
|
1154
|
+
super.set("it->en", "A", ["To"]);
|
|
1155
|
+
super.set("it->en", "Istanza", ["Instance"]);
|
|
1156
|
+
super.set("it->en", "Istanza corrente", ["Current instance"]);
|
|
1157
|
+
super.set("it->en", "Tutte le istanze", ["All instances"]);
|
|
1158
|
+
super.set("it->en", "Origine dati", ["Data source"]);
|
|
1159
|
+
super.set("it->en", "Memoria e storico", ["Memory and history"]);
|
|
1160
|
+
super.set("it->en", "Solo memoria", ["Memory only"]);
|
|
1161
|
+
super.set("it->en", "Aggiornamento automatico", ["Auto refresh"]);
|
|
1162
|
+
super.set("it->en", "Spento", ["Off"]);
|
|
1163
|
+
super.set("it->en", "Dimensione", ["Dimension"]);
|
|
1164
|
+
super.set("it->en", "Risoluzione", ["Resolution"]);
|
|
1165
|
+
super.set("it->en", "Bassa", ["Low"]);
|
|
1166
|
+
super.set("it->en", "Media", ["Medium"]);
|
|
1167
|
+
super.set("it->en", "Alta", ["High"]);
|
|
1168
|
+
super.set("it->en", "Massima", ["Maximum"]);
|
|
1169
|
+
super.set("it->en", "Attività totale", ["Total activity"]);
|
|
1170
|
+
super.set("it->en", "Limite", ["Limit"]);
|
|
1171
|
+
super.set("it->en", "Worker thread", ["Worker threads"]);
|
|
1172
|
+
super.set("it->en", "CPU Massime", ["Maximum CPUs"]);
|
|
1173
|
+
super.set("it->en", "Thread Massimi", ["Maximum Threads"]);
|
|
1174
|
+
super.set("it->en", "Filtri", ["Filters"]);
|
|
1175
|
+
super.set("it->en", "Filtra", ["Filter"]);
|
|
1176
|
+
super.set("it->en", "Rimuovi", ["Remove"]);
|
|
1177
|
+
super.set("it->en", "Prima di questo istante i dati vengono dallo storico (un campione ogni 10 secondi)", ["Before this instant data comes from history (one sample every 10 seconds)"]);
|
|
1178
|
+
super.set("it->en", "Sessioni attive medie", ["Average active sessions"]);
|
|
1179
|
+
super.set("it->en", "sessioni", ["sessions"]);
|
|
1180
|
+
super.set("it->en", "Carico i Dati", ["Loading Data"]);
|
|
1181
|
+
super.set("it->en", "Nessun dato nella finestra", ["No data in the window"]);
|
|
1182
|
+
super.set("it->en", "Tabelle", ["Tables"]);
|
|
1183
|
+
super.set("it->en", "agganciato alla fine", ["anchored to the end"]);
|
|
1184
|
+
super.set("it->en", "Attività", ["Activity"]);
|
|
1185
|
+
super.set("it->en", "Altri", ["Others"]);
|
|
1186
|
+
super.set("it->en", "(non attribuito)", ["(not attributed)"]);
|
|
1187
|
+
super.set("it->en", "(nessuno)", ["(none)"]);
|
|
1188
|
+
super.set("it->en", "Classe di attesa", ["Wait class"]);
|
|
1189
|
+
super.set("it->en", "Tipo evento", ["Event type"]);
|
|
1190
|
+
super.set("it->en", "Nodo", ["Node"]);
|
|
1191
|
+
super.set("it->en", "Sessione", ["Session"]);
|
|
1192
|
+
super.set("it->en", "Utente", ["User"]);
|
|
1193
|
+
super.set("it->en", "Tenant", ["Tenant"]);
|
|
1194
|
+
super.set("it->en", "Tipo sessione", ["Session type"]);
|
|
1195
|
+
super.set("it->en", "Sessione di background", ["Background session"]);
|
|
1196
|
+
super.set("it->en", "Job", ["Job"]);
|
|
1197
|
+
super.set("it->en", "Gruppo di consumo", ["Consumer group"]);
|
|
1198
|
+
super.set("it->en", "Tipo thread", ["Thread type"]);
|
|
1199
|
+
super.set("it->en", "Macchina", ["Machine"]);
|
|
1200
|
+
super.set("it->en", "Tipo", ["Type"]);
|
|
1201
|
+
super.set("it->en", "Processo", ["Process"]);
|
|
1202
|
+
}
|
|
1203
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: AdmTopActivityV2Loc, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1204
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: AdmTopActivityV2Loc }); }
|
|
1205
|
+
}
|
|
1206
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: AdmTopActivityV2Loc, decorators: [{
|
|
1207
|
+
type: Injectable
|
|
1208
|
+
}], ctorParameters: () => [{ type: i0.Injector }] });
|
|
1209
|
+
|
|
1210
|
+
class SessionDetailLoc extends LocalizationService {
|
|
1211
|
+
constructor(injector) {
|
|
1212
|
+
super(injector);
|
|
1213
|
+
super.set("it->en", "Dettaglio Sessione", ["Session Detail"]);
|
|
1214
|
+
super.set("it->en", "Istanza", ["Instance"]);
|
|
1215
|
+
super.set("it->en", "Seriale", ["Serial"]);
|
|
1216
|
+
super.set("it->en", "Stato", ["Status"]);
|
|
1217
|
+
super.set("it->en", "Tipo", ["Type"]);
|
|
1218
|
+
super.set("it->en", "Utente", ["User"]);
|
|
1219
|
+
super.set("it->en", "Prime Istruzioni", ["Top Nodes"]);
|
|
1220
|
+
super.set("it->en", "Nodo", ["Node"]);
|
|
1221
|
+
super.set("it->en", "Descrizione Nodo", ["Node Description"]);
|
|
1222
|
+
super.set("it->en", "Attività", ["Activity"]);
|
|
1223
|
+
super.set("it->en", "Tipo Nodo", ["Node Type"]);
|
|
1224
|
+
super.set("it->en", "Classe Attesa", ["Wait Class Name"]);
|
|
1225
|
+
super.set("it->en", "Statistiche Thread", ["Thread Statistics"]);
|
|
1226
|
+
super.set("it->en", "Attesa corrente", ["Current Wait"]);
|
|
1227
|
+
super.set("it->en", "Nodo di attesa", ["Wait Node"]);
|
|
1228
|
+
super.set("it->en", "Attesa su", ["Waiting On"]);
|
|
1229
|
+
super.set("it->en", "Classe", ["Class"]);
|
|
1230
|
+
super.set("it->en", "Tempo Attesa", ["Wait Time"]);
|
|
1231
|
+
super.set("it->en", "Chiudi", ["Close"]);
|
|
1232
|
+
}
|
|
1233
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: SessionDetailLoc, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1234
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: SessionDetailLoc }); }
|
|
1235
|
+
}
|
|
1236
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: SessionDetailLoc, decorators: [{
|
|
1237
|
+
type: Injectable
|
|
1238
|
+
}], ctorParameters: () => [{ type: i0.Injector }] });
|
|
1239
|
+
|
|
1240
|
+
// Angular
|
|
1241
|
+
// Dettaglio sessione condiviso (stesso contenuto del dialog della pagina Top Activity di sempre): il dialog che lo ospita resta del chiamante,
|
|
1242
|
+
// il clic su un nodo viene rilanciato con onNodeSelected perché il dettaglio nodo è anch'esso un dialog del chiamante
|
|
1243
|
+
class SessionDetailComponent {
|
|
1244
|
+
constructor(lc) {
|
|
1245
|
+
this.lc = lc;
|
|
1246
|
+
this.onClose = new EventEmitter();
|
|
1247
|
+
this.onNodeSelected = new EventEmitter();
|
|
1248
|
+
this.seriesPropertiesMapping = {};
|
|
1249
|
+
this.propertiesSeriesMapping = {
|
|
1250
|
+
["cputime"]: "CPU",
|
|
1251
|
+
["waittime"]: "Wait",
|
|
1252
|
+
["scripttime"]: "Scripting",
|
|
1253
|
+
["dbtime"]: "DB",
|
|
1254
|
+
["nettime"]: "Network",
|
|
1255
|
+
["throttletime"]: "Throttling",
|
|
1256
|
+
["sleeptime"]: "Sleep",
|
|
1257
|
+
["iotime"]: "IO"
|
|
1258
|
+
};
|
|
1259
|
+
}
|
|
1260
|
+
ngOnInit() {
|
|
1261
|
+
this.threadSelectionChanged(null);
|
|
1262
|
+
}
|
|
1263
|
+
threadSelectionChanged(selection) {
|
|
1264
|
+
this.SelectedTopNodes = null;
|
|
1265
|
+
this.SelectedSessions = null;
|
|
1266
|
+
requestAnimationFrame(() => {
|
|
1267
|
+
let sessDet = (selection?.count || 0) == 0 ? this.SessionDetails : selection.items[0];
|
|
1268
|
+
this.SelectedTopNodes = sessDet.nodes;
|
|
1269
|
+
if (!sessDet.sessions || sessDet.sessions.length == 0)
|
|
1270
|
+
return;
|
|
1271
|
+
let series = [];
|
|
1272
|
+
let props = Object.keys(sessDet.sessions[0]);
|
|
1273
|
+
for (let i = 0; i < props.length; i++) {
|
|
1274
|
+
if (props[i] != 'sampletime') {
|
|
1275
|
+
let s = new LineSerie(this.propertiesSeriesMapping[props[i]], [], null, null, "sessions");
|
|
1276
|
+
series.push(s);
|
|
1277
|
+
this.seriesPropertiesMapping[props[i]] = s;
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
for (let i = 0; i < sessDet.sessions.length; i++) {
|
|
1281
|
+
let itemref = sessDet.sessions[i];
|
|
1282
|
+
let theD = new Date(itemref.sampletime);
|
|
1283
|
+
for (let i = 0; i < props.length; i++)
|
|
1284
|
+
if (props[i] != 'sampletime')
|
|
1285
|
+
this.seriesPropertiesMapping[props[i]].values.push(new DateValue(theD, itemref[props[i]]));
|
|
1286
|
+
}
|
|
1287
|
+
this.SelectedSessions = new LineChartData(series);
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
onChartLoaded(chart) {
|
|
1291
|
+
let readyHandler = () => {
|
|
1292
|
+
chart.Chart.xAxes.each(x => x.zoom(0, 1, 0));
|
|
1293
|
+
chart.Chart.yAxes.each(y => y.zoom(0, 1, 0));
|
|
1294
|
+
chart.Chart.root.events.off("frameended", readyHandler);
|
|
1295
|
+
};
|
|
1296
|
+
chart.Chart.root.events.onDebounced("frameended", readyHandler, 500);
|
|
1297
|
+
}
|
|
1298
|
+
closeDialog() {
|
|
1299
|
+
this.onClose.emit(true);
|
|
1300
|
+
}
|
|
1301
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: SessionDetailComponent, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1302
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.34", type: SessionDetailComponent, isStandalone: false, selector: "session-detail", inputs: { SessionDetails: "SessionDetails" }, outputs: { onClose: "onClose", onNodeSelected: "onNodeSelected" }, ngImport: i0, template: "<div class=\"modal-dialog modal-feminist\" emaDraggable>\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title pull-left\">{{'Dettaglio Sessione' | localize: lc}}<span *ngIf=\"SessionDetails\"> {{SessionDetails.sid}}</span></h4>\r\n <button type=\"button\" class=\"close pull-right\" (click)=\"closeDialog()\" aria-label=\"Close\"><span aria-hidden=\"true\">×</span></button>\r\n </div>\r\n <div class=\"modal-body\" *ngIf=\"SessionDetails\">\r\n <div class=\"row\">\r\n <div *ngIf=\"SessionDetails.instanceid\" class=\"col-md-6\"><strong>{{'Istanza' | localize: lc}}</strong>: {{SessionDetails.instanceid}} </div>\r\n <div class=\"col-md-6\"><strong>{{'Seriale' | localize: lc}}</strong>: {{SessionDetails.serial}} </div>\r\n <div class=\"col-md-6\"><strong>{{'Stato' | localize: lc}}</strong>: {{SessionDetails.status}} </div>\r\n <div class=\"col-md-6\"><strong>{{'Tipo' | localize: lc}}</strong>: {{SessionDetails.type}}</div>\r\n <div class=\"col-md-6\"><strong>{{'Utente' | localize: lc}}</strong>: {{SessionDetails.user}} <span *ngIf=\"SessionDetails.tenant\">({{SessionDetails.tenant}})</span></div>\r\n </div>\r\n\r\n <div style=\"display: flex; width: 100%; margin-top: 15px;\">\r\n <div style=\"flex-grow: 0;display: flex;flex-direction: column\">\r\n <h5>{{'Prime Istruzioni' | localize: lc}}</h5>\r\n <div *ngIf=\"SelectedTopNodes\">\r\n <es-table [(ngModel)]=\"SelectedTopNodes\" [ArraymodeItemsPerPage]=\"10\">\r\n <ng-template #header>\r\n <th class=\"app-col-min\">{{'Nodo' | localize: lc}}</th>\r\n <th>{{'Descrizione Nodo' | localize: lc}}</th>\r\n <th class=\"app-col-min\">{{'Attivit\u00E0' | localize: lc}}</th>\r\n <th class=\"app-col-min app-nowrap\">{{'Tipo Nodo' | localize: lc}}</th>\r\n <th class=\"app-col-min app-nowrap\">{{'Classe Attesa' | localize: lc}}</th>\r\n </ng-template>\r\n\r\n <ng-template #body let-node>\r\n <td class=\"app-col-min\"><span class=\"app-link\" (click)=\"onNodeSelected.emit(node.profnodeid)\">{{node.profnodeid}}</span></td>\r\n <td><span title=\"{{node.profnodedesc}}\">{{node.profnodedesc?.length > 40 ? node.profnodedesc.substr(0,40) + \"...\" : node.profnodedesc}}</span></td>\r\n <td class=\"app-nowrap\">{{(node.activity == \"NaN\" ? null : node.activity) | number : '1.1-2' : 'it'}} %</td>\r\n <td>{{node.nodetypename}}</td>\r\n <td>{{node.waitclassname}}</td>\r\n </ng-template>\r\n </es-table>\r\n </div>\r\n </div>\r\n <div style=\"width: 15px;\"></div>\r\n <div style=\"flex-grow: 2;display: flex;flex-direction: column\">\r\n <h5>{{'Attivit\u00E0' | localize: lc}}</h5>\r\n <div *ngIf=\"SelectedSessions\" style=\"width: 100%; height: 290px\">\r\n <es-line-chart [MinGridDistance]=\"65\"\r\n [Timeline]=\"false\"\r\n [FinalInstants]=\"false\"\r\n [Stacked]=\"true\"\r\n [LegendPadding]=\"{top: 0, bottom: 7, right: 0, left: 10}\"\r\n [Fill]=\"true\"\r\n [MergeDatasets]=\"true\"\r\n [Data]=\"SelectedSessions\"\r\n [Legend]=\"true\"\r\n name=\"shared_session_details\"\r\n [DataGroupingThreshold]=\"99999999\"\r\n (chartLoaded)=\"onChartLoaded($event)\">\r\n </es-line-chart>\r\n </div>\r\n </div>\r\n </div>\r\n <div style=\"display: flex; width: 100%;\">\r\n <div style=\"flex-grow: 1;\">\r\n <h5>{{'Statistiche Thread' | localize: lc}}</h5>\r\n <div>\r\n <es-table [(ngModel)]=\"SessionDetails.threads\" [ArraymodeItemsPerPage]=\"10\" [Selection]=\"true\" [SingleSelection]=\"true\" (onSelectionChanged)=\"threadSelectionChanged($event)\">\r\n <ng-template #header>\r\n <th>Thread</th>\r\n <th>{{'Stato' | localize: lc}}</th>\r\n <th>{{'Tipo' | localize: lc}}</th>\r\n <th>API</th>\r\n <th>{{'Attesa corrente' | localize: lc}}</th>\r\n <th>{{'Nodo di attesa' | localize: lc}}</th>\r\n <th>{{'Attesa su' | localize: lc}}</th>\r\n <th>{{'Classe' | localize: lc}}</th>\r\n <th>Par. 1</th>\r\n <th>Par. 2</th>\r\n <th>Par. 3</th>\r\n <th>{{'Tempo Attesa' | localize: lc}}</th>\r\n </ng-template>\r\n\r\n <ng-template #body let-thread>\r\n <td>{{thread.tid}}</td>\r\n <td>{{thread.status}}</td>\r\n <td>{{thread.type}}</td>\r\n <td>{{thread.api}}</td>\r\n <td>{{thread.wait}}</td>\r\n <td>{{thread.waitnode}}</td>\r\n <td>{{thread.waiteventtype}}</td>\r\n <td>{{thread.waitclassname}}</td>\r\n <td>{{thread.waitpar1}}</td>\r\n <td>{{thread.waitpar2}}</td>\r\n <td>{{thread.waitpar3}}</td>\r\n <td>{{(thread.waittime == \"NaN\" ? null : thread.waittime) | number : '1.1-2' : 'it'}}</td>\r\n </ng-template>\r\n </es-table>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"closeDialog()\">{{'Chiudi' | localize: lc}}</button>\r\n </div>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8.EsTableComponent, selector: "es-table", inputs: ["globalCheck", "autoUpdate", "seconds", "researchInProgress", "globalColVisCheck", "EsThTdProvider", "CornerMenuOptions", "ColumnsResizable", "ColumnsPinnable", "AutoUpdate", "Height", "EmptySpaceBackgroundColor", "EsTableHandledSearch", "MaxHeight", "ContainerClass", "XLSXExport", "CSVExport", "AllSearch", "HighCellDensity", "Selection", "ShowLoadingOnBootstrap", "Removal", "RemovalCondition", "Export", "ShiftClick", "CountLabel", "HidePaging", "HidePagingCount", "HidePagingButtons", "ContextMenu", "ExportFileName", "TableClass", "ExportFunction", "ExportOnlyVisibleColumns", "HasHeaderGroup", "HasSecondaryHeaderGroup", "HeaderHidden", "BodyHidden", "SelectionDisabled", "SingleSelection", "RowClassAssigner", "OrderByColumn", "MultipleOrderingDirectives", "HiddenColumns", "ColumnsOrdering", "SearchView", "SelectAll", "UseArrayModePaging", "DynamicRowColumnsDefinition", "DynamicOperations", "Hierarchy", "ParentKey", "OwnKey", "AutoSortHierarchy", "StartsExpanded", "SavePreferences", "DefaultAlignment", "PagingStyle", "RowGroupingPagingStyle", "ItemSourceProperty", "UseSelectionCache", "ShowItemGroupsColumns", "Editable", "RangeSelection", "SearchThrottle", "ArraymodeItemsPerPage"], outputs: ["globalCheckChange", "autoUpdateChange", "secondsChange", "researchInProgressChange", "globalColVisCheckChange", "onOrderChanged", "onSearchRequest", "onSelectionChanged", "onRemoval", "onAbortRemoval", "onModelChange", "onOpenContextMenu", "onCornerAction", "onDynamicOperation"] }, { kind: "component", type: i2.EsLineChartComponent, selector: "es-line-chart", inputs: ["Data", "DataArray", "Step", "DataGroupBucketSize", "DataGroupingThreshold", "StrokeSize", "AllowGaps", "MergeDatasets", "FinalInstants", "Min", "Max", "Fill", "Stacked"] }, { kind: "directive", type: i10.Draggable, selector: "[emaDraggable]", inputs: ["emaDraggable"] }, { kind: "pipe", type: i5.DecimalPipe, name: "number" }, { kind: "pipe", type: i1.LocalizePipe, name: "localize" }], viewProviders: [{ provide: LocalizationService, useClass: SessionDetailLoc }] }); }
|
|
1303
|
+
}
|
|
1304
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: SessionDetailComponent, decorators: [{
|
|
1305
|
+
type: Component,
|
|
1306
|
+
args: [{ selector: "session-detail", viewProviders: [{ provide: LocalizationService, useClass: SessionDetailLoc }], standalone: false, template: "<div class=\"modal-dialog modal-feminist\" emaDraggable>\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title pull-left\">{{'Dettaglio Sessione' | localize: lc}}<span *ngIf=\"SessionDetails\"> {{SessionDetails.sid}}</span></h4>\r\n <button type=\"button\" class=\"close pull-right\" (click)=\"closeDialog()\" aria-label=\"Close\"><span aria-hidden=\"true\">×</span></button>\r\n </div>\r\n <div class=\"modal-body\" *ngIf=\"SessionDetails\">\r\n <div class=\"row\">\r\n <div *ngIf=\"SessionDetails.instanceid\" class=\"col-md-6\"><strong>{{'Istanza' | localize: lc}}</strong>: {{SessionDetails.instanceid}} </div>\r\n <div class=\"col-md-6\"><strong>{{'Seriale' | localize: lc}}</strong>: {{SessionDetails.serial}} </div>\r\n <div class=\"col-md-6\"><strong>{{'Stato' | localize: lc}}</strong>: {{SessionDetails.status}} </div>\r\n <div class=\"col-md-6\"><strong>{{'Tipo' | localize: lc}}</strong>: {{SessionDetails.type}}</div>\r\n <div class=\"col-md-6\"><strong>{{'Utente' | localize: lc}}</strong>: {{SessionDetails.user}} <span *ngIf=\"SessionDetails.tenant\">({{SessionDetails.tenant}})</span></div>\r\n </div>\r\n\r\n <div style=\"display: flex; width: 100%; margin-top: 15px;\">\r\n <div style=\"flex-grow: 0;display: flex;flex-direction: column\">\r\n <h5>{{'Prime Istruzioni' | localize: lc}}</h5>\r\n <div *ngIf=\"SelectedTopNodes\">\r\n <es-table [(ngModel)]=\"SelectedTopNodes\" [ArraymodeItemsPerPage]=\"10\">\r\n <ng-template #header>\r\n <th class=\"app-col-min\">{{'Nodo' | localize: lc}}</th>\r\n <th>{{'Descrizione Nodo' | localize: lc}}</th>\r\n <th class=\"app-col-min\">{{'Attivit\u00E0' | localize: lc}}</th>\r\n <th class=\"app-col-min app-nowrap\">{{'Tipo Nodo' | localize: lc}}</th>\r\n <th class=\"app-col-min app-nowrap\">{{'Classe Attesa' | localize: lc}}</th>\r\n </ng-template>\r\n\r\n <ng-template #body let-node>\r\n <td class=\"app-col-min\"><span class=\"app-link\" (click)=\"onNodeSelected.emit(node.profnodeid)\">{{node.profnodeid}}</span></td>\r\n <td><span title=\"{{node.profnodedesc}}\">{{node.profnodedesc?.length > 40 ? node.profnodedesc.substr(0,40) + \"...\" : node.profnodedesc}}</span></td>\r\n <td class=\"app-nowrap\">{{(node.activity == \"NaN\" ? null : node.activity) | number : '1.1-2' : 'it'}} %</td>\r\n <td>{{node.nodetypename}}</td>\r\n <td>{{node.waitclassname}}</td>\r\n </ng-template>\r\n </es-table>\r\n </div>\r\n </div>\r\n <div style=\"width: 15px;\"></div>\r\n <div style=\"flex-grow: 2;display: flex;flex-direction: column\">\r\n <h5>{{'Attivit\u00E0' | localize: lc}}</h5>\r\n <div *ngIf=\"SelectedSessions\" style=\"width: 100%; height: 290px\">\r\n <es-line-chart [MinGridDistance]=\"65\"\r\n [Timeline]=\"false\"\r\n [FinalInstants]=\"false\"\r\n [Stacked]=\"true\"\r\n [LegendPadding]=\"{top: 0, bottom: 7, right: 0, left: 10}\"\r\n [Fill]=\"true\"\r\n [MergeDatasets]=\"true\"\r\n [Data]=\"SelectedSessions\"\r\n [Legend]=\"true\"\r\n name=\"shared_session_details\"\r\n [DataGroupingThreshold]=\"99999999\"\r\n (chartLoaded)=\"onChartLoaded($event)\">\r\n </es-line-chart>\r\n </div>\r\n </div>\r\n </div>\r\n <div style=\"display: flex; width: 100%;\">\r\n <div style=\"flex-grow: 1;\">\r\n <h5>{{'Statistiche Thread' | localize: lc}}</h5>\r\n <div>\r\n <es-table [(ngModel)]=\"SessionDetails.threads\" [ArraymodeItemsPerPage]=\"10\" [Selection]=\"true\" [SingleSelection]=\"true\" (onSelectionChanged)=\"threadSelectionChanged($event)\">\r\n <ng-template #header>\r\n <th>Thread</th>\r\n <th>{{'Stato' | localize: lc}}</th>\r\n <th>{{'Tipo' | localize: lc}}</th>\r\n <th>API</th>\r\n <th>{{'Attesa corrente' | localize: lc}}</th>\r\n <th>{{'Nodo di attesa' | localize: lc}}</th>\r\n <th>{{'Attesa su' | localize: lc}}</th>\r\n <th>{{'Classe' | localize: lc}}</th>\r\n <th>Par. 1</th>\r\n <th>Par. 2</th>\r\n <th>Par. 3</th>\r\n <th>{{'Tempo Attesa' | localize: lc}}</th>\r\n </ng-template>\r\n\r\n <ng-template #body let-thread>\r\n <td>{{thread.tid}}</td>\r\n <td>{{thread.status}}</td>\r\n <td>{{thread.type}}</td>\r\n <td>{{thread.api}}</td>\r\n <td>{{thread.wait}}</td>\r\n <td>{{thread.waitnode}}</td>\r\n <td>{{thread.waiteventtype}}</td>\r\n <td>{{thread.waitclassname}}</td>\r\n <td>{{thread.waitpar1}}</td>\r\n <td>{{thread.waitpar2}}</td>\r\n <td>{{thread.waitpar3}}</td>\r\n <td>{{(thread.waittime == \"NaN\" ? null : thread.waittime) | number : '1.1-2' : 'it'}}</td>\r\n </ng-template>\r\n </es-table>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"closeDialog()\">{{'Chiudi' | localize: lc}}</button>\r\n </div>\r\n </div>\r\n</div>\r\n" }]
|
|
1307
|
+
}], ctorParameters: () => [{ type: i1.LocalizationService }], propDecorators: { SessionDetails: [{
|
|
1308
|
+
type: Input
|
|
1309
|
+
}], onClose: [{
|
|
1310
|
+
type: Output
|
|
1311
|
+
}], onNodeSelected: [{
|
|
1312
|
+
type: Output
|
|
1313
|
+
}] } });
|
|
1314
|
+
|
|
1315
|
+
// Angular
|
|
1316
|
+
const STORAGE_KEY = "HotSearchTopActV2";
|
|
1317
|
+
const TABLES_WINDOW_MS = 5 * 60 * 1000;
|
|
1318
|
+
const INSTANCE_CURRENT = "@current";
|
|
1319
|
+
const INSTANCE_ALL = "@all";
|
|
1320
|
+
// WaitClass ed EventType hanno valori fissi: colori fissi, così il grafico si legge sempre allo stesso modo
|
|
1321
|
+
const FIXED_COLORS = {
|
|
1322
|
+
Cpu: "#43a047", Database: "#1e88e5", Script: "#8e24aa", Network: "#8d6e63", IO: "#0288d1", Sleep: "#bdbdbd", Throttle: "#fb8c00", Wait: "#fdd835",
|
|
1323
|
+
Latch: "#e53935", Semaphore: "#f06292", Enqueue: "#c62828", ReadWriteLock: "#ad1457", Fence: "#6d4c41", ConditionVariable: "#00897b", Scheduler: "#5e35b1"
|
|
1324
|
+
};
|
|
1325
|
+
const PALETTE = ["#1e88e5", "#43a047", "#fb8c00", "#8e24aa", "#e53935", "#00897b", "#fdd835", "#6d4c41", "#3949ab", "#c0ca33"];
|
|
1326
|
+
const OTHER_COLOR = "#9e9e9e";
|
|
1327
|
+
const TOTAL_COLOR = "#212121";
|
|
1328
|
+
class TopActivityV2LegendItem {
|
|
1329
|
+
}
|
|
1330
|
+
class TopActivityV2FilterChip {
|
|
1331
|
+
}
|
|
1332
|
+
// Impostazioni ricordate fra una visita e l'altra (la finestra temporale riparte sempre dall'ultima ora)
|
|
1333
|
+
class TopActivityV2Settings {
|
|
1334
|
+
}
|
|
1335
|
+
class AdmTopActivityV2Component {
|
|
1336
|
+
constructor(dateExts, lc, localStorage, intercom, route, adms, zone) {
|
|
1337
|
+
this.dateExts = dateExts;
|
|
1338
|
+
this.lc = lc;
|
|
1339
|
+
this.localStorage = localStorage;
|
|
1340
|
+
this.intercom = intercom;
|
|
1341
|
+
this.route = route;
|
|
1342
|
+
this.adms = adms;
|
|
1343
|
+
this.zone = zone;
|
|
1344
|
+
this.Dim = TopActivityDimension;
|
|
1345
|
+
// Filtri
|
|
1346
|
+
this.filterfrom = "";
|
|
1347
|
+
this.filterto = "";
|
|
1348
|
+
this.instance = INSTANCE_CURRENT;
|
|
1349
|
+
this.dataSource = String(TopActivityDataSource.MemoryAndStored);
|
|
1350
|
+
this.dimension = String(TopActivityDimension.WaitClass);
|
|
1351
|
+
this.resolution = String(TopActivityResolution.Medium);
|
|
1352
|
+
this.totalActivity = false;
|
|
1353
|
+
this.maxCpu = true;
|
|
1354
|
+
this.maxThreadsKind = String(TopActivityMaximumThreads.Threads);
|
|
1355
|
+
this.tableDims = [String(TopActivityDimension.UserSession), String(TopActivityDimension.WaitEvent)];
|
|
1356
|
+
this.filters = [];
|
|
1357
|
+
this.refreshSeconds = "0";
|
|
1358
|
+
// Sorgenti delle select
|
|
1359
|
+
this.Instances = [];
|
|
1360
|
+
this.DataSources = [];
|
|
1361
|
+
this.Dimensions = [];
|
|
1362
|
+
this.Resolutions = [];
|
|
1363
|
+
this.ThreadKinds = [];
|
|
1364
|
+
this.RefreshOptions = [];
|
|
1365
|
+
// Risultato
|
|
1366
|
+
this.loading = false;
|
|
1367
|
+
this.legend = [];
|
|
1368
|
+
this.tables = [];
|
|
1369
|
+
// Time slider: fine della finestra di 5 minuti delle tabelle, in millisecondi
|
|
1370
|
+
this.sliderMin = 0;
|
|
1371
|
+
this.sliderMax = 0;
|
|
1372
|
+
this.sliderStep = 1000;
|
|
1373
|
+
this.sliderValue = 0;
|
|
1374
|
+
this.sliderAnchored = true;
|
|
1375
|
+
this.tablesWindowLabel = "";
|
|
1376
|
+
this.chartFrom = 0;
|
|
1377
|
+
this.chartTo = 0;
|
|
1378
|
+
this.colors = {};
|
|
1379
|
+
this.be = route.snapshot.params["be"] || "";
|
|
1380
|
+
this.intercom.send(InboundMessageTypes.Navigation, { sub: false, routeTitle: this.lc.loc(this.route.snapshot.data["title"]) });
|
|
1381
|
+
}
|
|
1382
|
+
async ngOnInit() {
|
|
1383
|
+
this.buildSources();
|
|
1384
|
+
let saved = this.route.snapshot.queryParams["ignoreStorage"] ? null : await firstValueFrom(this.localStorage.getItem(STORAGE_KEY), { defaultValue: null });
|
|
1385
|
+
if (saved)
|
|
1386
|
+
this.applySettings(saved);
|
|
1387
|
+
this.setLastHour();
|
|
1388
|
+
this.loadInstances();
|
|
1389
|
+
this.refreshInfos();
|
|
1390
|
+
this.search();
|
|
1391
|
+
}
|
|
1392
|
+
ngOnDestroy() {
|
|
1393
|
+
clearInterval(this.refreshTimer);
|
|
1394
|
+
}
|
|
1395
|
+
// #region Ricerca
|
|
1396
|
+
searchClicked() {
|
|
1397
|
+
this.refreshInfos();
|
|
1398
|
+
this.search();
|
|
1399
|
+
}
|
|
1400
|
+
async search() {
|
|
1401
|
+
let req = this.buildRequest();
|
|
1402
|
+
this.loading = true;
|
|
1403
|
+
try {
|
|
1404
|
+
let res = await this.adms.getTopActivitiesV2(this.be, req);
|
|
1405
|
+
this.applyResult(req, res);
|
|
1406
|
+
this.saveSettings();
|
|
1407
|
+
}
|
|
1408
|
+
catch {
|
|
1409
|
+
// L'errore (finestra non valida, backend non raggiungibile...) lo mostra già HTTPService
|
|
1410
|
+
}
|
|
1411
|
+
finally {
|
|
1412
|
+
this.loading = false;
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
buildRequest() {
|
|
1416
|
+
let to = this.toDate(this.filterto) ?? new Date();
|
|
1417
|
+
let from = this.toDate(this.filterfrom) ?? new Date(to.getTime() - 3600 * 1000);
|
|
1418
|
+
let req = new TopActivityV2Request();
|
|
1419
|
+
req.From = from.toISOString();
|
|
1420
|
+
req.To = to.toISOString();
|
|
1421
|
+
req.Global = this.instance != INSTANCE_CURRENT;
|
|
1422
|
+
if (this.instance != INSTANCE_CURRENT && this.instance != INSTANCE_ALL)
|
|
1423
|
+
req.InstanceId = this.instance;
|
|
1424
|
+
req.DataSource = +this.dataSource;
|
|
1425
|
+
req.Dimension = +this.dimension;
|
|
1426
|
+
if (this.filters.length > 0)
|
|
1427
|
+
req.Filters = this.filters.map(t => t.filter);
|
|
1428
|
+
req.TotalActivity = this.totalActivity;
|
|
1429
|
+
req.MaximumThreads = this.maxCpu ? +this.maxThreadsKind : TopActivityMaximumThreads.None;
|
|
1430
|
+
req.Resolution = +this.resolution;
|
|
1431
|
+
req.Tables = this.tableDims.map(t => +t);
|
|
1432
|
+
req.TopCount = 10;
|
|
1433
|
+
// Lo slider agganciato a destra segue la fine del grafico; spostato resta fermo finché cade dentro la finestra
|
|
1434
|
+
let outside = this.sliderValue <= from.getTime() || this.sliderValue > to.getTime();
|
|
1435
|
+
if (this.sliderAnchored || outside) {
|
|
1436
|
+
this.sliderAnchored = true;
|
|
1437
|
+
this.sliderValue = to.getTime();
|
|
1438
|
+
}
|
|
1439
|
+
req.TablesTo = new Date(this.sliderValue).toISOString();
|
|
1440
|
+
req.TablesFrom = new Date(Math.max(from.getTime(), this.sliderValue - TABLES_WINDOW_MS)).toISOString();
|
|
1441
|
+
return req;
|
|
1442
|
+
}
|
|
1443
|
+
applyResult(req, res) {
|
|
1444
|
+
this.result = res;
|
|
1445
|
+
this.tables = res?.Tables ?? [];
|
|
1446
|
+
this.chartFrom = new Date(req.From).getTime();
|
|
1447
|
+
this.chartTo = new Date(req.To).getTime();
|
|
1448
|
+
this.sliderStep = Math.max(1, res?.BucketSeconds || 1) * 1000;
|
|
1449
|
+
this.sliderMin = Math.min(this.chartTo, this.chartFrom + TABLES_WINDOW_MS);
|
|
1450
|
+
this.sliderMax = this.chartTo;
|
|
1451
|
+
this.sliderValue = new Date(req.TablesTo).getTime();
|
|
1452
|
+
this.updateTablesWindowLabel();
|
|
1453
|
+
if (!res) {
|
|
1454
|
+
this.chartData = null;
|
|
1455
|
+
this.legend = [];
|
|
1456
|
+
this.lastChartKey = null;
|
|
1457
|
+
return;
|
|
1458
|
+
}
|
|
1459
|
+
let memoryFrom = res.MemoryFrom ? this.parseUtc(res.MemoryFrom) : null;
|
|
1460
|
+
this.memoryFrom = memoryFrom && memoryFrom.getTime() > this.chartFrom ? this.fmt(memoryFrom) : null;
|
|
1461
|
+
// Se è cambiata solo la finestra delle tabelle il grafico resta quello di prima: ridisegnarlo lo farebbe lampeggiare
|
|
1462
|
+
let chartKey = JSON.stringify({ ...req, TablesFrom: null, TablesTo: null, Tables: null, TopCount: null });
|
|
1463
|
+
if (chartKey == this.lastChartKey && this.chartData) {
|
|
1464
|
+
this.drawTablesWindow();
|
|
1465
|
+
return;
|
|
1466
|
+
}
|
|
1467
|
+
this.lastChartKey = chartKey;
|
|
1468
|
+
let times = (res.Times ?? []).map(t => this.parseUtc(t));
|
|
1469
|
+
let fixed = res.Dimension == TopActivityDimension.WaitClass || res.Dimension == TopActivityDimension.EventType;
|
|
1470
|
+
let uom = this.lc.loc("sessioni");
|
|
1471
|
+
let series = [];
|
|
1472
|
+
this.colors = {};
|
|
1473
|
+
this.legend = (res.Components ?? []).map((c, i) => {
|
|
1474
|
+
let color = c.Other ? OTHER_COLOR : (fixed && FIXED_COLORS[c.Key]) || PALETTE[i % PALETTE.length];
|
|
1475
|
+
if (c.Key != null)
|
|
1476
|
+
this.colors[c.Key] = color;
|
|
1477
|
+
let label = this.valueLabel(c.Label, c.Other, res.Dimension);
|
|
1478
|
+
series.push(new LineSerie(label, times.map((t, j) => new DateValue(t, c.Values?.[j] ?? 0)), null, color, uom));
|
|
1479
|
+
return { key: c.Key, label: label, color: color, other: c.Other, activity: c.Activity, percentage: c.Percentage };
|
|
1480
|
+
});
|
|
1481
|
+
// L'attività totale è una linea scura sopra le aree impilate, non impilata a sua volta
|
|
1482
|
+
if (res.TotalActivity)
|
|
1483
|
+
series.push(new LineSerie(this.lc.loc("Attività totale"), times.map((t, j) => new DateValue(t, res.TotalActivity[j] ?? 0)), null, TOTAL_COLOR, uom, false, false));
|
|
1484
|
+
let limit = null;
|
|
1485
|
+
if (res.MaximumThreads != null)
|
|
1486
|
+
limit = new Limit(res.MaximumThreads, this.lc.loc(+this.maxThreadsKind == TopActivityMaximumThreads.Cores ? "CPU Massime" : "Thread Massimi"));
|
|
1487
|
+
// L'asse Y non si allarga da solo per le linee limite
|
|
1488
|
+
let peak = Math.max(res.PeakActiveSessions ?? 0, ...(res.TotalActivity ?? [0]));
|
|
1489
|
+
this.chartMax = limit ? Math.max(peak, res.MaximumThreads) * 1.1 : undefined;
|
|
1490
|
+
this.chartData = series.length > 0 ? new LineChartData(series, limit) : null;
|
|
1491
|
+
}
|
|
1492
|
+
// #endregion
|
|
1493
|
+
// #region Grafico, legenda e filtri
|
|
1494
|
+
onChartLoaded(chart) {
|
|
1495
|
+
// Il grafico viene ricreato a ogni cambio di dati: l'area della finestra delle tabelle va rifatta
|
|
1496
|
+
this.chart = chart;
|
|
1497
|
+
this.windowAxis = null;
|
|
1498
|
+
this.drawTablesWindow();
|
|
1499
|
+
}
|
|
1500
|
+
drawTablesWindow() {
|
|
1501
|
+
let dateAxis = this.chart?.ChartService?.dateAxis;
|
|
1502
|
+
if (!dateAxis || !this.sliderMax)
|
|
1503
|
+
return;
|
|
1504
|
+
let end = this.sliderValue;
|
|
1505
|
+
let start = Math.max(this.chartFrom, end - TABLES_WINDOW_MS);
|
|
1506
|
+
this.zone.runOutsideAngular(() => {
|
|
1507
|
+
if (this.windowAxis !== dateAxis) {
|
|
1508
|
+
this.windowAxis = dateAxis;
|
|
1509
|
+
this.windowRange = dateAxis.makeDataItem({ value: start, endValue: end });
|
|
1510
|
+
dateAxis.createAxisRange(this.windowRange);
|
|
1511
|
+
this.windowRange.get("axisFill")?.setAll({ fill: am5.color(0x546e7a), fillOpacity: 0.18, visible: true });
|
|
1512
|
+
this.windowRange.get("grid")?.set("forceHidden", true);
|
|
1513
|
+
this.windowRange.get("label")?.set("forceHidden", true);
|
|
1514
|
+
}
|
|
1515
|
+
else
|
|
1516
|
+
this.windowRange.setAll({ value: start, endValue: end });
|
|
1517
|
+
});
|
|
1518
|
+
}
|
|
1519
|
+
addFilter(item) {
|
|
1520
|
+
// Il componente "altri" non è filtrabile, come in Oracle
|
|
1521
|
+
if (item.other || !this.result)
|
|
1522
|
+
return;
|
|
1523
|
+
let filter = new TopActivityV2Filter();
|
|
1524
|
+
filter.Dimension = this.result.Dimension;
|
|
1525
|
+
filter.Value = item.key ?? "";
|
|
1526
|
+
if (this.filters.some(t => t.filter.Dimension == filter.Dimension && t.filter.Value == filter.Value))
|
|
1527
|
+
return;
|
|
1528
|
+
this.filters.push({ filter: filter, label: `${this.dimensionLabel(filter.Dimension)} = ${item.label}` });
|
|
1529
|
+
this.totalActivity = true;
|
|
1530
|
+
this.search();
|
|
1531
|
+
}
|
|
1532
|
+
removeFilter(index) {
|
|
1533
|
+
this.filters.splice(index, 1);
|
|
1534
|
+
this.search();
|
|
1535
|
+
}
|
|
1536
|
+
// #endregion
|
|
1537
|
+
// #region Time slider e tabelle
|
|
1538
|
+
sliderMoving() {
|
|
1539
|
+
this.updateTablesWindowLabel();
|
|
1540
|
+
this.drawTablesWindow();
|
|
1541
|
+
}
|
|
1542
|
+
sliderChanged() {
|
|
1543
|
+
// Il range input arrotonda al passo: "agganciato" se è a meno di un passo dalla fine
|
|
1544
|
+
this.sliderAnchored = this.sliderMax - this.sliderValue < this.sliderStep;
|
|
1545
|
+
this.search();
|
|
1546
|
+
}
|
|
1547
|
+
updateTablesWindowLabel() {
|
|
1548
|
+
if (!this.sliderMax) {
|
|
1549
|
+
this.tablesWindowLabel = "";
|
|
1550
|
+
return;
|
|
1551
|
+
}
|
|
1552
|
+
let start = Math.max(this.chartFrom, this.sliderValue - TABLES_WINDOW_MS);
|
|
1553
|
+
this.tablesWindowLabel = `${this.fmt(new Date(start))} - ${this.fmt(new Date(this.sliderValue))}`;
|
|
1554
|
+
}
|
|
1555
|
+
isClickable(item) {
|
|
1556
|
+
return !item.Other && (!!item.Session || !!item.Event?.EventId);
|
|
1557
|
+
}
|
|
1558
|
+
openItem(item) {
|
|
1559
|
+
if (!this.isClickable(item))
|
|
1560
|
+
return;
|
|
1561
|
+
if (item.Session)
|
|
1562
|
+
this.loadSessionDetails(item.Session);
|
|
1563
|
+
else
|
|
1564
|
+
this.loadNodeDetails(item.Event.EventId);
|
|
1565
|
+
}
|
|
1566
|
+
breakdownWidth(item, part) {
|
|
1567
|
+
return item.Activity ? part.Activity / item.Activity * 100 : 0;
|
|
1568
|
+
}
|
|
1569
|
+
breakdownColor(part) {
|
|
1570
|
+
return part.Other || part.Key == null ? OTHER_COLOR : this.colors[part.Key] ?? OTHER_COLOR;
|
|
1571
|
+
}
|
|
1572
|
+
itemLabel(item, table) {
|
|
1573
|
+
return this.valueLabel(item.Label, item.Other, table.Dimension);
|
|
1574
|
+
}
|
|
1575
|
+
loadNodeDetails(nodeId) {
|
|
1576
|
+
this.NodeDetails = null;
|
|
1577
|
+
this.dlgNodeDetails.show();
|
|
1578
|
+
requestAnimationFrame(async () => {
|
|
1579
|
+
this.NodeDetails = await this.adms.getNodeStats(this.be, nodeId, this.instance != INSTANCE_CURRENT);
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
loadSessionDetails(session) {
|
|
1583
|
+
this.SessionDetails = null;
|
|
1584
|
+
this.dlgSessionDetails.show();
|
|
1585
|
+
requestAnimationFrame(async () => {
|
|
1586
|
+
this.SessionDetails = await this.adms.getSessionStats(this.be, session.SessionId?.toString(), session.SerialNo?.toString(), session.InstanceId);
|
|
1587
|
+
});
|
|
1588
|
+
}
|
|
1589
|
+
// #endregion
|
|
1590
|
+
// #region Aggiornamento automatico
|
|
1591
|
+
refreshChanged() {
|
|
1592
|
+
clearInterval(this.refreshTimer);
|
|
1593
|
+
this.refreshTimer = null;
|
|
1594
|
+
let seconds = +this.refreshSeconds;
|
|
1595
|
+
if (seconds > 0)
|
|
1596
|
+
this.refreshTimer = setInterval(() => this.shiftWindow(), seconds * 1000);
|
|
1597
|
+
}
|
|
1598
|
+
// Sposta in avanti la finestra della stessa durata: lo slider agganciato la segue, quello spostato resta dov'è
|
|
1599
|
+
shiftWindow() {
|
|
1600
|
+
if (this.loading)
|
|
1601
|
+
return;
|
|
1602
|
+
let to = this.toDate(this.filterto) ?? new Date();
|
|
1603
|
+
let from = this.toDate(this.filterfrom) ?? new Date(to.getTime() - 3600 * 1000);
|
|
1604
|
+
let now = new Date();
|
|
1605
|
+
this.filterfrom = this.fmt(new Date(now.getTime() - (to.getTime() - from.getTime())));
|
|
1606
|
+
this.filterto = this.fmt(now);
|
|
1607
|
+
this.search();
|
|
1608
|
+
}
|
|
1609
|
+
// #endregion
|
|
1610
|
+
// #region Supporto
|
|
1611
|
+
buildSources() {
|
|
1612
|
+
this.DataSources = [
|
|
1613
|
+
new KeyValue(String(TopActivityDataSource.MemoryAndStored), this.lc.loc("Memoria e storico")),
|
|
1614
|
+
new KeyValue(String(TopActivityDataSource.Memory), this.lc.loc("Solo memoria"))
|
|
1615
|
+
];
|
|
1616
|
+
this.Dimensions = Object.keys(TopActivityDimension).filter(t => !isNaN(+t)).map(t => new KeyValue(t, this.dimensionLabel(+t)));
|
|
1617
|
+
this.Resolutions = [
|
|
1618
|
+
new KeyValue(String(TopActivityResolution.Low), this.lc.loc("Bassa")),
|
|
1619
|
+
new KeyValue(String(TopActivityResolution.Medium), this.lc.loc("Media")),
|
|
1620
|
+
new KeyValue(String(TopActivityResolution.High), this.lc.loc("Alta")),
|
|
1621
|
+
new KeyValue(String(TopActivityResolution.Maximum), this.lc.loc("Massima"))
|
|
1622
|
+
];
|
|
1623
|
+
this.ThreadKinds = [
|
|
1624
|
+
new KeyValue(String(TopActivityMaximumThreads.Threads), this.lc.loc("Worker thread")),
|
|
1625
|
+
new KeyValue(String(TopActivityMaximumThreads.Cores), "CPU")
|
|
1626
|
+
];
|
|
1627
|
+
this.RefreshOptions = [
|
|
1628
|
+
new KeyValue("0", this.lc.loc("Spento")),
|
|
1629
|
+
new KeyValue("15", "15 s"),
|
|
1630
|
+
new KeyValue("30", "30 s"),
|
|
1631
|
+
new KeyValue("60", "60 s")
|
|
1632
|
+
];
|
|
1633
|
+
this.Instances = [
|
|
1634
|
+
new KeyValue(INSTANCE_CURRENT, this.lc.loc("Istanza corrente")),
|
|
1635
|
+
new KeyValue(INSTANCE_ALL, this.lc.loc("Tutte le istanze"))
|
|
1636
|
+
];
|
|
1637
|
+
}
|
|
1638
|
+
async loadInstances() {
|
|
1639
|
+
try {
|
|
1640
|
+
let instances = await this.adms.getInstances(this.be);
|
|
1641
|
+
this.Instances = [...this.Instances.slice(0, 2), ...(instances ?? []).map(t => new KeyValue(t.id, t.description))];
|
|
1642
|
+
}
|
|
1643
|
+
catch {
|
|
1644
|
+
// Senza elenco istanze restano "corrente" e "tutte"
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
async refreshInfos() {
|
|
1648
|
+
// DirectorInfos è facoltativo: se scoppia la pagina va avanti lo stesso
|
|
1649
|
+
this.DirInfos = await this.adms.getInfos(this.be);
|
|
1650
|
+
}
|
|
1651
|
+
dimensionLabel(dimension) {
|
|
1652
|
+
switch (dimension) {
|
|
1653
|
+
case TopActivityDimension.WaitClass: return this.lc.loc("Classe di attesa");
|
|
1654
|
+
case TopActivityDimension.EventType: return this.lc.loc("Tipo evento");
|
|
1655
|
+
case TopActivityDimension.WaitEvent: return this.lc.loc("Nodo");
|
|
1656
|
+
case TopActivityDimension.Instance: return this.lc.loc("Istanza");
|
|
1657
|
+
case TopActivityDimension.UserSession: return this.lc.loc("Sessione");
|
|
1658
|
+
case TopActivityDimension.UserName: return this.lc.loc("Utente");
|
|
1659
|
+
case TopActivityDimension.Tenant: return this.lc.loc("Tenant");
|
|
1660
|
+
case TopActivityDimension.SessionType: return this.lc.loc("Tipo sessione");
|
|
1661
|
+
case TopActivityDimension.BackgroundSession: return this.lc.loc("Sessione di background");
|
|
1662
|
+
case TopActivityDimension.JobName: return this.lc.loc("Job");
|
|
1663
|
+
case TopActivityDimension.ConsumerGroup: return this.lc.loc("Gruppo di consumo");
|
|
1664
|
+
case TopActivityDimension.ThreadType: return this.lc.loc("Tipo thread");
|
|
1665
|
+
case TopActivityDimension.Api: return "API";
|
|
1666
|
+
case TopActivityDimension.Machine: return this.lc.loc("Macchina");
|
|
1667
|
+
}
|
|
1668
|
+
return String(dimension);
|
|
1669
|
+
}
|
|
1670
|
+
valueLabel(label, other, dimension) {
|
|
1671
|
+
if (other)
|
|
1672
|
+
return this.lc.loc("Altri");
|
|
1673
|
+
if (label == null || label === "")
|
|
1674
|
+
return this.lc.loc(dimension == TopActivityDimension.WaitEvent ? "(non attribuito)" : "(nessuno)");
|
|
1675
|
+
return label;
|
|
1676
|
+
}
|
|
1677
|
+
applySettings(saved) {
|
|
1678
|
+
this.instance = saved.instance ?? this.instance;
|
|
1679
|
+
this.dataSource = saved.dataSource ?? this.dataSource;
|
|
1680
|
+
this.dimension = saved.dimension ?? this.dimension;
|
|
1681
|
+
this.resolution = saved.resolution ?? this.resolution;
|
|
1682
|
+
this.totalActivity = saved.totalActivity ?? this.totalActivity;
|
|
1683
|
+
this.maxCpu = saved.maxCpu ?? this.maxCpu;
|
|
1684
|
+
this.maxThreadsKind = saved.maxThreadsKind ?? this.maxThreadsKind;
|
|
1685
|
+
this.tableDims = saved.tableDims?.length == 2 ? saved.tableDims : this.tableDims;
|
|
1686
|
+
this.filters = saved.filters ?? [];
|
|
1687
|
+
}
|
|
1688
|
+
saveSettings() {
|
|
1689
|
+
let settings = {
|
|
1690
|
+
instance: this.instance,
|
|
1691
|
+
dataSource: this.dataSource,
|
|
1692
|
+
dimension: this.dimension,
|
|
1693
|
+
resolution: this.resolution,
|
|
1694
|
+
totalActivity: this.totalActivity,
|
|
1695
|
+
maxCpu: this.maxCpu,
|
|
1696
|
+
maxThreadsKind: this.maxThreadsKind,
|
|
1697
|
+
tableDims: this.tableDims,
|
|
1698
|
+
filters: this.filters
|
|
1699
|
+
};
|
|
1700
|
+
this.localStorage.setItem(STORAGE_KEY, settings).subscribe();
|
|
1701
|
+
}
|
|
1702
|
+
setLastHour() {
|
|
1703
|
+
let now = new Date();
|
|
1704
|
+
this.filterfrom = this.fmt(new Date(now.getTime() - 3600 * 1000));
|
|
1705
|
+
this.filterto = this.fmt(now);
|
|
1706
|
+
}
|
|
1707
|
+
toDate(value) {
|
|
1708
|
+
return value ? this.dateExts.getDateConvertion(value).toDate() : null;
|
|
1709
|
+
}
|
|
1710
|
+
fmt(date) {
|
|
1711
|
+
return dayjs(date).format(this.lc.token("getFullDateDisplayFormat"));
|
|
1712
|
+
}
|
|
1713
|
+
// Le date della risposta sono UTC "dd/MM/yyyy HH:mm:ss" senza fuso
|
|
1714
|
+
parseUtc(value) {
|
|
1715
|
+
let m = /^(\d{2})\/(\d{2})\/(\d{4}) (\d{2}):(\d{2}):(\d{2})$/.exec(value ?? "");
|
|
1716
|
+
return m ? new Date(Date.UTC(+m[3], +m[2] - 1, +m[1], +m[4], +m[5], +m[6])) : new Date(value);
|
|
1717
|
+
}
|
|
1718
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: AdmTopActivityV2Component, deps: [{ token: i1$1.DateService }, { token: i1.LocalizationService }, { token: i3.PreferencesService }, { token: i1$1.InterComService }, { token: i4.ActivatedRoute }, { token: AdminModuleBaseService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1719
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.34", type: AdmTopActivityV2Component, isStandalone: false, selector: "topact_v2", providers: [{ provide: LocalizationService, useClass: AdmTopActivityV2Loc }], viewQueries: [{ propertyName: "dlgNodeDetails", first: true, predicate: ["dlgNodeDetails"], descendants: true }, { propertyName: "dlgSessionDetails", first: true, predicate: ["dlgSessionDetails"], descendants: true }], ngImport: i0, template: "<div class=\"row\">\r\n <div class=\"col-12\">\r\n <div class=\"card app-overflow-visible\" widget>\r\n <div class=\"card-header\">\r\n <span class=\"text-uppercase\">\r\n {{'Attivit\u00E0 Principali' | localize: lc}}\r\n @if (DirInfos) {\r\n <span> - \r\n {{'' + DirInfos.cpus + ' ' + ('CPU' | localize: lc) + (DirInfos.rssplan ? ' - ' + DirInfos.rssplan : '')}} \r\n Load average: {{ DirInfos.lavg1 | number : '1.1-2' : 'it'}} {{ DirInfos.lavg5 | number : '1.1-2' : 'it'}} {{ DirInfos.lavg15 | number : '1.1-2' : 'it'}}\r\n </span>\r\n }\r\n </span>\r\n </div>\r\n <div class=\"card-body widget-body\">\r\n <form role=\"form\">\r\n <div class=\"row app-first-filter-line\">\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\">\r\n <form-datetime [readonly]=\"refreshSeconds != '0'\" [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"filterfrom\" name=\"filterfrom\" [Placeholder]=\"'Da' | localize: lc\"></form-datetime>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\">\r\n <form-datetime [readonly]=\"refreshSeconds != '0'\" [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"filterto\" name=\"filterto\" [Placeholder]=\"'A' | localize: lc\"></form-datetime>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\">\r\n <form-select [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"instance\" name=\"instance\" [Source]=\"Instances\" [Placeholder]=\"'Istanza' | localize: lc\" (inputChange)=\"search()\"></form-select>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\">\r\n <form-select [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"dataSource\" name=\"dataSource\" [Source]=\"DataSources\" [Placeholder]=\"'Origine dati' | localize: lc\" (inputChange)=\"search()\"></form-select>\r\n </div>\r\n <div class=\"col-xl-1 col-lg-1 col-md-2\">\r\n <button [disabled]=\"loading || refreshSeconds != '0'\" class=\"input-group-addon btn app-btn-search app-margin-top-20\" (click)=\"searchClicked()\" type=\"submit\"><i class=\"fa\" [class.fa-search]=\"!loading\" [class.fa-spinner]=\"loading\" [class.fa-spin]=\"loading\"></i></button>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-4 app-filter-wrapper\">\r\n <form-select [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"refreshSeconds\" name=\"refreshSeconds\" [Source]=\"RefreshOptions\" [Placeholder]=\"'Aggiornamento automatico' | localize: lc\" (inputChange)=\"refreshChanged()\"></form-select>\r\n </div>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\">\r\n <form-select [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"dimension\" name=\"dimension\" [Source]=\"Dimensions\" [Placeholder]=\"'Dimensione' | localize: lc\" (inputChange)=\"search()\"></form-select>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\">\r\n <form-select [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"resolution\" name=\"resolution\" [Source]=\"Resolutions\" [Placeholder]=\"'Risoluzione' | localize: lc\" (inputChange)=\"search()\"></form-select>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\" style=\"display: flex; height: 38px;\">\r\n <form-checkbox [FormLayout]=\"false\" [SliderMode]=\"true\" [Validation]=\"false\" [(ngModel)]=\"totalActivity\" name=\"totalActivity\" (inputChange)=\"search()\"></form-checkbox> \r\n <span class=\"app-padding-top-5 app-padding-left-5\">{{'Attivit\u00E0 totale' | localize: lc}}</span>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\" style=\"display: flex; height: 38px;\">\r\n <form-checkbox [FormLayout]=\"false\" [SliderMode]=\"true\" [Validation]=\"false\" [(ngModel)]=\"maxCpu\" name=\"maxCpu\" (inputChange)=\"search()\"></form-checkbox> \r\n <span class=\"app-padding-top-5 app-padding-left-5\">{{'Limite' | localize: lc}}</span>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\">\r\n <form-select [FormLayout]=\"false\" [Validation]=\"false\" [disabled]=\"!maxCpu\" [(ngModel)]=\"maxThreadsKind\" name=\"maxThreadsKind\" [Source]=\"ThreadKinds\" (inputChange)=\"search()\"></form-select>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n @if (filters.length > 0) {\r\n <div class=\"app-margin-top-5\">\r\n <strong>{{'Filtri' | localize: lc}}:</strong> \r\n @for (chip of filters; track $index) {\r\n <span style=\"display: inline-block; border: 1px solid #bbb; border-radius: 12px; padding: 1px 8px; margin: 0 5px 3px 0;\">\r\n {{chip.label}} <a class=\"app-pointer\" [title]=\"'Rimuovi' | localize: lc\" (click)=\"removeFilter($index)\">×</a>\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n @if (memoryFrom) {\r\n <div class=\"app-margin-top-5\"><small><em>{{'Prima di questo istante i dati vengono dallo storico (un campione ogni 10 secondi)' | localize: lc}}: {{memoryFrom}}</em></small></div>\r\n }\r\n\r\n <div class=\"row\">\r\n <div class=\"col-md-12 app-margin-top-5\">\r\n <div style=\"width: 100%; height: 300px\">\r\n @if (chartData) {\r\n <es-line-chart [MinGridDistance]=\"65\"\r\n [Timeline]=\"false\"\r\n [FinalInstants]=\"false\"\r\n [Stacked]=\"true\"\r\n [Step]=\"true\"\r\n [Fill]=\"true\"\r\n [MergeDatasets]=\"true\"\r\n [Data]=\"chartData\"\r\n [Max]=\"chartMax\"\r\n [Legend]=\"false\"\r\n [YTitle]=\"'Sessioni attive medie' | localize: lc\"\r\n name=\"topactv2\"\r\n [DataGroupingThreshold]=\"99999999\"\r\n (chartLoaded)=\"onChartLoaded($event)\"></es-line-chart>\r\n } @else {\r\n <p><em>{{(loading ? 'Carico i Dati' : 'Nessun dato nella finestra') | localize: lc}}</em></p>\r\n }\r\n </div>\r\n\r\n <!-- Legenda: un clic su una voce la aggiunge ai filtri (\"altri\" non \u00E8 filtrabile) -->\r\n <div class=\"app-margin-top-5\">\r\n @for (item of legend; track $index) {\r\n <span [class.app-pointer]=\"!item.other\" [title]=\"item.other ? '' : ('Filtra' | localize: lc)\" (click)=\"addFilter(item)\" style=\"display: inline-block; margin: 0 12px 3px 0; white-space: nowrap;\">\r\n <span [style.background]=\"item.color\" style=\"display: inline-block; width: 10px; height: 10px; margin-right: 4px;\"></span>{{item.label}} <small>{{item.percentage | number : '1.0-1' : 'it'}}%</small>\r\n </span>\r\n }\r\n @if (result?.TotalActivity) {\r\n <span style=\"display: inline-block; margin: 0 12px 3px 0; white-space: nowrap;\">\r\n <span style=\"display: inline-block; width: 14px; height: 2px; background: #212121; margin: 0 4px 3px 0;\"></span>{{'Attivit\u00E0 totale' | localize: lc}}\r\n </span>\r\n }\r\n </div>\r\n\r\n @if (sliderMax > sliderMin) {\r\n <div style=\"display: flex; align-items: center; gap: 10px;\" class=\"app-margin-top-5\">\r\n <span class=\"app-nowrap\"><strong>{{'Tabelle' | localize: lc}}</strong>: {{tablesWindowLabel}}</span>\r\n <input type=\"range\" style=\"flex-grow: 1;\" [min]=\"sliderMin\" [max]=\"sliderMax\" [step]=\"sliderStep\" [ngModel]=\"sliderValue\" (ngModelChange)=\"sliderValue = $event; sliderMoving()\" (change)=\"sliderChanged()\" />\r\n @if (sliderAnchored) {\r\n <small class=\"app-nowrap\"><em>{{'agganciato alla fine' | localize: lc}}</em></small>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"row app-margin-top-5\">\r\n @for (table of tables; track $index; let i = $index) {\r\n <div class=\"col-md-6\">\r\n <div style=\"display: flex; align-items: center; gap: 8px;\">\r\n <div style=\"width: 220px;\">\r\n <form-select [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"tableDims[i]\" name=\"tabledim{{i}}\" [Source]=\"Dimensions\" (inputChange)=\"search()\"></form-select>\r\n </div>\r\n <small>{{'Attivit\u00E0' | localize: lc}}: {{table.Activity | number : '1.1-3' : 'it'}}</small>\r\n </div>\r\n <es-table [(ngModel)]=\"table.Items\" [HidePaging]=\"true\">\r\n <ng-template #header>\r\n <th>{{dimensionLabel(table.Dimension)}}</th>\r\n <th class=\"app-col-min\">{{'Attivit\u00E0' | localize: lc}}</th>\r\n <th class=\"app-col-min\">%</th>\r\n @if (table.Dimension == Dim.UserSession) {\r\n <th>{{'Utente' | localize: lc}}</th>\r\n <th>{{'Tenant' | localize: lc}}</th>\r\n <th>{{'Tipo' | localize: lc}}</th>\r\n <th>{{'Processo' | localize: lc}}</th>\r\n <th>{{'Gruppo di consumo' | localize: lc}}</th>\r\n }\r\n @if (table.Dimension == Dim.WaitEvent) {\r\n <th>{{'Tipo evento' | localize: lc}}</th>\r\n <th>{{'Classe di attesa' | localize: lc}}</th>\r\n }\r\n </ng-template>\r\n <ng-template #body let-item>\r\n <td>\r\n @if (isClickable(item)) {\r\n <span class=\"app-link\" [title]=\"item.Key\" (click)=\"openItem(item)\">{{itemLabel(item, table)}}</span>\r\n } @else {\r\n <span>{{itemLabel(item, table)}}</span>\r\n }\r\n </td>\r\n <td class=\"app-nowrap\">\r\n <div style=\"display: flex; align-items: center; gap: 6px;\">\r\n <div style=\"display: flex; width: 90px; height: 10px; background: #eee;\">\r\n @for (part of item.Breakdown; track $index) {\r\n <div [style.width.%]=\"breakdownWidth(item, part)\" [style.background]=\"breakdownColor(part)\"></div>\r\n }\r\n </div>\r\n {{item.Activity | number : '1.2-2' : 'it'}}\r\n </div>\r\n </td>\r\n <td class=\"app-nowrap\">{{item.Percentage | number : '1.1-2' : 'it'}} %</td>\r\n @if (table.Dimension == Dim.UserSession) {\r\n <td>{{item.Session?.UserName}}</td>\r\n <td>{{item.Session?.TenantId}}</td>\r\n <td>{{item.Session?.SessionType}}</td>\r\n <td>{{item.Session?.BgProcessName || item.Session?.JobName}}</td>\r\n <td>{{item.Session?.ConsumerGroup}}</td>\r\n }\r\n @if (table.Dimension == Dim.WaitEvent) {\r\n <td>{{item.Event?.EventType}}</td>\r\n <td>{{item.Event?.WaitClass}}</td>\r\n }\r\n </ng-template>\r\n </es-table>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div bsModal #dlgNodeDetails=\"bs-modal\" class=\"modal fade\" role=\"dialog\" aria-hidden=\"true\">\r\n @if (NodeDetails) {\r\n <node-detail [NodeDetails]=\"NodeDetails\" (onClose)=\"dlgNodeDetails.hide()\"></node-detail>\r\n }\r\n</div>\r\n\r\n<div bsModal #dlgSessionDetails=\"bs-modal\" class=\"modal fade\" role=\"dialog\" aria-hidden=\"true\">\r\n @if (SessionDetails) {\r\n <session-detail [SessionDetails]=\"SessionDetails\" (onClose)=\"dlgSessionDetails.hide()\" (onNodeSelected)=\"loadNodeDetails($event)\"></session-detail>\r\n }\r\n</div>\r\n", dependencies: [{ kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.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: i7.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i7.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i8$1.ModalDirective, selector: "[bsModal]", inputs: ["config", "closeInterceptor"], outputs: ["onShow", "onShown", "onHide", "onHidden"], exportAs: ["bs-modal"] }, { kind: "component", type: i8.EsTableComponent, selector: "es-table", inputs: ["globalCheck", "autoUpdate", "seconds", "researchInProgress", "globalColVisCheck", "EsThTdProvider", "CornerMenuOptions", "ColumnsResizable", "ColumnsPinnable", "AutoUpdate", "Height", "EmptySpaceBackgroundColor", "EsTableHandledSearch", "MaxHeight", "ContainerClass", "XLSXExport", "CSVExport", "AllSearch", "HighCellDensity", "Selection", "ShowLoadingOnBootstrap", "Removal", "RemovalCondition", "Export", "ShiftClick", "CountLabel", "HidePaging", "HidePagingCount", "HidePagingButtons", "ContextMenu", "ExportFileName", "TableClass", "ExportFunction", "ExportOnlyVisibleColumns", "HasHeaderGroup", "HasSecondaryHeaderGroup", "HeaderHidden", "BodyHidden", "SelectionDisabled", "SingleSelection", "RowClassAssigner", "OrderByColumn", "MultipleOrderingDirectives", "HiddenColumns", "ColumnsOrdering", "SearchView", "SelectAll", "UseArrayModePaging", "DynamicRowColumnsDefinition", "DynamicOperations", "Hierarchy", "ParentKey", "OwnKey", "AutoSortHierarchy", "StartsExpanded", "SavePreferences", "DefaultAlignment", "PagingStyle", "RowGroupingPagingStyle", "ItemSourceProperty", "UseSelectionCache", "ShowItemGroupsColumns", "Editable", "RangeSelection", "SearchThrottle", "ArraymodeItemsPerPage"], outputs: ["globalCheckChange", "autoUpdateChange", "secondsChange", "researchInProgressChange", "globalColVisCheckChange", "onOrderChanged", "onSearchRequest", "onSelectionChanged", "onRemoval", "onAbortRemoval", "onModelChange", "onOpenContextMenu", "onCornerAction", "onDynamicOperation"] }, { kind: "component", type: i9.EsFormSelectComponent, selector: "form-select", inputs: ["OptionsTemplate"] }, { kind: "component", type: i9.EsFormDateTimeComponent, selector: "form-datetime" }, { kind: "component", type: i9.EsFormCheckboxComponent, selector: "form-checkbox", inputs: ["SliderMode"] }, { kind: "component", type: i2.EsLineChartComponent, selector: "es-line-chart", inputs: ["Data", "DataArray", "Step", "DataGroupBucketSize", "DataGroupingThreshold", "StrokeSize", "AllowGaps", "MergeDatasets", "FinalInstants", "Min", "Max", "Fill", "Stacked"] }, { kind: "directive", type: i10.Widget, selector: "[widget]" }, { kind: "component", type: SessionDetailComponent, selector: "session-detail", inputs: ["SessionDetails"], outputs: ["onClose", "onNodeSelected"] }, { kind: "component", type: NodeDetailComponent, selector: "node-detail", inputs: ["NodeDetails"], outputs: ["onClose"] }, { kind: "pipe", type: i5.DecimalPipe, name: "number" }, { kind: "pipe", type: i1.LocalizePipe, name: "localize" }] }); }
|
|
1720
|
+
}
|
|
1721
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: AdmTopActivityV2Component, decorators: [{
|
|
1722
|
+
type: Component,
|
|
1723
|
+
args: [{ selector: "topact_v2", providers: [{ provide: LocalizationService, useClass: AdmTopActivityV2Loc }], standalone: false, template: "<div class=\"row\">\r\n <div class=\"col-12\">\r\n <div class=\"card app-overflow-visible\" widget>\r\n <div class=\"card-header\">\r\n <span class=\"text-uppercase\">\r\n {{'Attivit\u00E0 Principali' | localize: lc}}\r\n @if (DirInfos) {\r\n <span> - \r\n {{'' + DirInfos.cpus + ' ' + ('CPU' | localize: lc) + (DirInfos.rssplan ? ' - ' + DirInfos.rssplan : '')}} \r\n Load average: {{ DirInfos.lavg1 | number : '1.1-2' : 'it'}} {{ DirInfos.lavg5 | number : '1.1-2' : 'it'}} {{ DirInfos.lavg15 | number : '1.1-2' : 'it'}}\r\n </span>\r\n }\r\n </span>\r\n </div>\r\n <div class=\"card-body widget-body\">\r\n <form role=\"form\">\r\n <div class=\"row app-first-filter-line\">\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\">\r\n <form-datetime [readonly]=\"refreshSeconds != '0'\" [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"filterfrom\" name=\"filterfrom\" [Placeholder]=\"'Da' | localize: lc\"></form-datetime>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\">\r\n <form-datetime [readonly]=\"refreshSeconds != '0'\" [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"filterto\" name=\"filterto\" [Placeholder]=\"'A' | localize: lc\"></form-datetime>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\">\r\n <form-select [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"instance\" name=\"instance\" [Source]=\"Instances\" [Placeholder]=\"'Istanza' | localize: lc\" (inputChange)=\"search()\"></form-select>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\">\r\n <form-select [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"dataSource\" name=\"dataSource\" [Source]=\"DataSources\" [Placeholder]=\"'Origine dati' | localize: lc\" (inputChange)=\"search()\"></form-select>\r\n </div>\r\n <div class=\"col-xl-1 col-lg-1 col-md-2\">\r\n <button [disabled]=\"loading || refreshSeconds != '0'\" class=\"input-group-addon btn app-btn-search app-margin-top-20\" (click)=\"searchClicked()\" type=\"submit\"><i class=\"fa\" [class.fa-search]=\"!loading\" [class.fa-spinner]=\"loading\" [class.fa-spin]=\"loading\"></i></button>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-4 app-filter-wrapper\">\r\n <form-select [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"refreshSeconds\" name=\"refreshSeconds\" [Source]=\"RefreshOptions\" [Placeholder]=\"'Aggiornamento automatico' | localize: lc\" (inputChange)=\"refreshChanged()\"></form-select>\r\n </div>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\">\r\n <form-select [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"dimension\" name=\"dimension\" [Source]=\"Dimensions\" [Placeholder]=\"'Dimensione' | localize: lc\" (inputChange)=\"search()\"></form-select>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\">\r\n <form-select [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"resolution\" name=\"resolution\" [Source]=\"Resolutions\" [Placeholder]=\"'Risoluzione' | localize: lc\" (inputChange)=\"search()\"></form-select>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\" style=\"display: flex; height: 38px;\">\r\n <form-checkbox [FormLayout]=\"false\" [SliderMode]=\"true\" [Validation]=\"false\" [(ngModel)]=\"totalActivity\" name=\"totalActivity\" (inputChange)=\"search()\"></form-checkbox> \r\n <span class=\"app-padding-top-5 app-padding-left-5\">{{'Attivit\u00E0 totale' | localize: lc}}</span>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\" style=\"display: flex; height: 38px;\">\r\n <form-checkbox [FormLayout]=\"false\" [SliderMode]=\"true\" [Validation]=\"false\" [(ngModel)]=\"maxCpu\" name=\"maxCpu\" (inputChange)=\"search()\"></form-checkbox> \r\n <span class=\"app-padding-top-5 app-padding-left-5\">{{'Limite' | localize: lc}}</span>\r\n </div>\r\n <div class=\"col-xl-2 col-lg-2 col-md-6 app-filter-wrapper\">\r\n <form-select [FormLayout]=\"false\" [Validation]=\"false\" [disabled]=\"!maxCpu\" [(ngModel)]=\"maxThreadsKind\" name=\"maxThreadsKind\" [Source]=\"ThreadKinds\" (inputChange)=\"search()\"></form-select>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n @if (filters.length > 0) {\r\n <div class=\"app-margin-top-5\">\r\n <strong>{{'Filtri' | localize: lc}}:</strong> \r\n @for (chip of filters; track $index) {\r\n <span style=\"display: inline-block; border: 1px solid #bbb; border-radius: 12px; padding: 1px 8px; margin: 0 5px 3px 0;\">\r\n {{chip.label}} <a class=\"app-pointer\" [title]=\"'Rimuovi' | localize: lc\" (click)=\"removeFilter($index)\">×</a>\r\n </span>\r\n }\r\n </div>\r\n }\r\n\r\n @if (memoryFrom) {\r\n <div class=\"app-margin-top-5\"><small><em>{{'Prima di questo istante i dati vengono dallo storico (un campione ogni 10 secondi)' | localize: lc}}: {{memoryFrom}}</em></small></div>\r\n }\r\n\r\n <div class=\"row\">\r\n <div class=\"col-md-12 app-margin-top-5\">\r\n <div style=\"width: 100%; height: 300px\">\r\n @if (chartData) {\r\n <es-line-chart [MinGridDistance]=\"65\"\r\n [Timeline]=\"false\"\r\n [FinalInstants]=\"false\"\r\n [Stacked]=\"true\"\r\n [Step]=\"true\"\r\n [Fill]=\"true\"\r\n [MergeDatasets]=\"true\"\r\n [Data]=\"chartData\"\r\n [Max]=\"chartMax\"\r\n [Legend]=\"false\"\r\n [YTitle]=\"'Sessioni attive medie' | localize: lc\"\r\n name=\"topactv2\"\r\n [DataGroupingThreshold]=\"99999999\"\r\n (chartLoaded)=\"onChartLoaded($event)\"></es-line-chart>\r\n } @else {\r\n <p><em>{{(loading ? 'Carico i Dati' : 'Nessun dato nella finestra') | localize: lc}}</em></p>\r\n }\r\n </div>\r\n\r\n <!-- Legenda: un clic su una voce la aggiunge ai filtri (\"altri\" non \u00E8 filtrabile) -->\r\n <div class=\"app-margin-top-5\">\r\n @for (item of legend; track $index) {\r\n <span [class.app-pointer]=\"!item.other\" [title]=\"item.other ? '' : ('Filtra' | localize: lc)\" (click)=\"addFilter(item)\" style=\"display: inline-block; margin: 0 12px 3px 0; white-space: nowrap;\">\r\n <span [style.background]=\"item.color\" style=\"display: inline-block; width: 10px; height: 10px; margin-right: 4px;\"></span>{{item.label}} <small>{{item.percentage | number : '1.0-1' : 'it'}}%</small>\r\n </span>\r\n }\r\n @if (result?.TotalActivity) {\r\n <span style=\"display: inline-block; margin: 0 12px 3px 0; white-space: nowrap;\">\r\n <span style=\"display: inline-block; width: 14px; height: 2px; background: #212121; margin: 0 4px 3px 0;\"></span>{{'Attivit\u00E0 totale' | localize: lc}}\r\n </span>\r\n }\r\n </div>\r\n\r\n @if (sliderMax > sliderMin) {\r\n <div style=\"display: flex; align-items: center; gap: 10px;\" class=\"app-margin-top-5\">\r\n <span class=\"app-nowrap\"><strong>{{'Tabelle' | localize: lc}}</strong>: {{tablesWindowLabel}}</span>\r\n <input type=\"range\" style=\"flex-grow: 1;\" [min]=\"sliderMin\" [max]=\"sliderMax\" [step]=\"sliderStep\" [ngModel]=\"sliderValue\" (ngModelChange)=\"sliderValue = $event; sliderMoving()\" (change)=\"sliderChanged()\" />\r\n @if (sliderAnchored) {\r\n <small class=\"app-nowrap\"><em>{{'agganciato alla fine' | localize: lc}}</em></small>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"row app-margin-top-5\">\r\n @for (table of tables; track $index; let i = $index) {\r\n <div class=\"col-md-6\">\r\n <div style=\"display: flex; align-items: center; gap: 8px;\">\r\n <div style=\"width: 220px;\">\r\n <form-select [FormLayout]=\"false\" [Validation]=\"false\" [(ngModel)]=\"tableDims[i]\" name=\"tabledim{{i}}\" [Source]=\"Dimensions\" (inputChange)=\"search()\"></form-select>\r\n </div>\r\n <small>{{'Attivit\u00E0' | localize: lc}}: {{table.Activity | number : '1.1-3' : 'it'}}</small>\r\n </div>\r\n <es-table [(ngModel)]=\"table.Items\" [HidePaging]=\"true\">\r\n <ng-template #header>\r\n <th>{{dimensionLabel(table.Dimension)}}</th>\r\n <th class=\"app-col-min\">{{'Attivit\u00E0' | localize: lc}}</th>\r\n <th class=\"app-col-min\">%</th>\r\n @if (table.Dimension == Dim.UserSession) {\r\n <th>{{'Utente' | localize: lc}}</th>\r\n <th>{{'Tenant' | localize: lc}}</th>\r\n <th>{{'Tipo' | localize: lc}}</th>\r\n <th>{{'Processo' | localize: lc}}</th>\r\n <th>{{'Gruppo di consumo' | localize: lc}}</th>\r\n }\r\n @if (table.Dimension == Dim.WaitEvent) {\r\n <th>{{'Tipo evento' | localize: lc}}</th>\r\n <th>{{'Classe di attesa' | localize: lc}}</th>\r\n }\r\n </ng-template>\r\n <ng-template #body let-item>\r\n <td>\r\n @if (isClickable(item)) {\r\n <span class=\"app-link\" [title]=\"item.Key\" (click)=\"openItem(item)\">{{itemLabel(item, table)}}</span>\r\n } @else {\r\n <span>{{itemLabel(item, table)}}</span>\r\n }\r\n </td>\r\n <td class=\"app-nowrap\">\r\n <div style=\"display: flex; align-items: center; gap: 6px;\">\r\n <div style=\"display: flex; width: 90px; height: 10px; background: #eee;\">\r\n @for (part of item.Breakdown; track $index) {\r\n <div [style.width.%]=\"breakdownWidth(item, part)\" [style.background]=\"breakdownColor(part)\"></div>\r\n }\r\n </div>\r\n {{item.Activity | number : '1.2-2' : 'it'}}\r\n </div>\r\n </td>\r\n <td class=\"app-nowrap\">{{item.Percentage | number : '1.1-2' : 'it'}} %</td>\r\n @if (table.Dimension == Dim.UserSession) {\r\n <td>{{item.Session?.UserName}}</td>\r\n <td>{{item.Session?.TenantId}}</td>\r\n <td>{{item.Session?.SessionType}}</td>\r\n <td>{{item.Session?.BgProcessName || item.Session?.JobName}}</td>\r\n <td>{{item.Session?.ConsumerGroup}}</td>\r\n }\r\n @if (table.Dimension == Dim.WaitEvent) {\r\n <td>{{item.Event?.EventType}}</td>\r\n <td>{{item.Event?.WaitClass}}</td>\r\n }\r\n </ng-template>\r\n </es-table>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div bsModal #dlgNodeDetails=\"bs-modal\" class=\"modal fade\" role=\"dialog\" aria-hidden=\"true\">\r\n @if (NodeDetails) {\r\n <node-detail [NodeDetails]=\"NodeDetails\" (onClose)=\"dlgNodeDetails.hide()\"></node-detail>\r\n }\r\n</div>\r\n\r\n<div bsModal #dlgSessionDetails=\"bs-modal\" class=\"modal fade\" role=\"dialog\" aria-hidden=\"true\">\r\n @if (SessionDetails) {\r\n <session-detail [SessionDetails]=\"SessionDetails\" (onClose)=\"dlgSessionDetails.hide()\" (onNodeSelected)=\"loadNodeDetails($event)\"></session-detail>\r\n }\r\n</div>\r\n" }]
|
|
1724
|
+
}], ctorParameters: () => [{ type: i1$1.DateService }, { type: i1.LocalizationService }, { type: i3.PreferencesService }, { type: i1$1.InterComService }, { type: i4.ActivatedRoute }, { type: AdminModuleBaseService }, { type: i0.NgZone }], propDecorators: { dlgNodeDetails: [{
|
|
1725
|
+
type: ViewChild,
|
|
1726
|
+
args: ["dlgNodeDetails"]
|
|
1727
|
+
}], dlgSessionDetails: [{
|
|
1728
|
+
type: ViewChild,
|
|
1729
|
+
args: ["dlgSessionDetails"]
|
|
1730
|
+
}] } });
|
|
1731
|
+
|
|
1097
1732
|
class LocksView extends AppSearch {
|
|
1098
1733
|
constructor() { super(); }
|
|
1099
1734
|
}
|
|
@@ -1805,11 +2440,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.34", ngImpo
|
|
|
1805
2440
|
}], ctorParameters: () => [{ type: i1$1.InterComService }] });
|
|
1806
2441
|
|
|
1807
2442
|
// Angular
|
|
2443
|
+
// La Top Activity v2 prende la rotta "topact" solo se DirectorFeature.TopActivityV2 è attivo nella configurazione del modulo,
|
|
2444
|
+
// altrimenti la guardia fallisce e la rotta successiva apre la pagina di sempre
|
|
2445
|
+
const topActivityV2Enabled = () => inject(ADM_TOPACT_V2, { optional: true }) ?? false;
|
|
1808
2446
|
const routeConfig = [
|
|
1809
2447
|
{
|
|
1810
2448
|
path: "", children: [
|
|
1811
2449
|
{ path: "serverworkers/:be", component: AdmWrkComponent, data: { title: "Ricerca Processi Applicativi", internalNavigation: false } },
|
|
1812
2450
|
{ path: "profiler/:be", component: AdmProfilerComponent, data: { title: "Profiler del Server", internalNavigation: false } },
|
|
2451
|
+
{ path: "topact/:be", component: AdmTopActivityV2Component, canMatch: [topActivityV2Enabled], data: { title: "Attività Principali", internalNavigation: false } },
|
|
1813
2452
|
{ path: "topact/:be", component: AdmTopActivitiesComponent, data: { title: "Attività Principali", internalNavigation: false } },
|
|
1814
2453
|
{ path: "metrics/:be", component: AdmMetricsComponent, data: { title: "Metriche di Sistema", internalNavigation: false } },
|
|
1815
2454
|
{ path: "serverlogs/:be", component: AdmLogsComponent, data: { title: "Log del Server", internalNavigation: false } },
|
|
@@ -1819,6 +2458,7 @@ const routeConfig = [
|
|
|
1819
2458
|
{ path: "metadataquery/:be", component: MtdQueryComponent, data: { title: "Ricerca Viste Dinamiche Applicative", internalNavigation: false } },
|
|
1820
2459
|
{ path: "serverworkers", component: AdmWrkComponent, data: { title: "Ricerca Processi Applicativi", internalNavigation: false } },
|
|
1821
2460
|
{ path: "profiler", component: AdmProfilerComponent, data: { title: "Profiler del Server", internalNavigation: false } },
|
|
2461
|
+
{ path: "topact", component: AdmTopActivityV2Component, canMatch: [topActivityV2Enabled], data: { title: "Attività Principali", internalNavigation: false } },
|
|
1822
2462
|
{ path: "topact", component: AdmTopActivitiesComponent, data: { title: "Attività Principali", internalNavigation: false } },
|
|
1823
2463
|
{ path: "metrics", component: AdmMetricsComponent, data: { title: "Metriche di Sistema", internalNavigation: false } },
|
|
1824
2464
|
{ path: "serverlogs", component: AdmLogsComponent, data: { title: "Log del Server", internalNavigation: false } },
|
|
@@ -1854,6 +2494,8 @@ const COMPONENTS = [
|
|
|
1854
2494
|
AdmWrkComponent,
|
|
1855
2495
|
AdmProfilerComponent,
|
|
1856
2496
|
AdmTopActivitiesComponent,
|
|
2497
|
+
AdmTopActivityV2Component,
|
|
2498
|
+
SessionDetailComponent,
|
|
1857
2499
|
AdmDynamicViewsComponent,
|
|
1858
2500
|
AdmLogsComponent,
|
|
1859
2501
|
AdmAuditsComponent,
|
|
@@ -1876,6 +2518,8 @@ class AdmModule {
|
|
|
1876
2518
|
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.34", ngImport: i0, type: AdmModule, declarations: [AdmWrkComponent,
|
|
1877
2519
|
AdmProfilerComponent,
|
|
1878
2520
|
AdmTopActivitiesComponent,
|
|
2521
|
+
AdmTopActivityV2Component,
|
|
2522
|
+
SessionDetailComponent,
|
|
1879
2523
|
AdmDynamicViewsComponent,
|
|
1880
2524
|
AdmLogsComponent,
|
|
1881
2525
|
AdmAuditsComponent,
|
|
@@ -1903,7 +2547,8 @@ class AdmModule {
|
|
|
1903
2547
|
DirectivesModule, i4.RouterModule, FormatTimePipe] }); }
|
|
1904
2548
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: AdmModule, providers: [
|
|
1905
2549
|
AdminModuleCommService,
|
|
1906
|
-
{ provide: ADM_CONVERSATIONS, useFactory: () => !!myconfig.TransactionTimeoutSeconds }
|
|
2550
|
+
{ provide: ADM_CONVERSATIONS, useFactory: () => !!myconfig.TransactionTimeoutSeconds },
|
|
2551
|
+
{ provide: ADM_TOPACT_V2, useFactory: () => !!myconfig?.DirectorFeature?.TopActivityV2 }
|
|
1907
2552
|
], imports: [MODULES] }); }
|
|
1908
2553
|
}
|
|
1909
2554
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.34", ngImport: i0, type: AdmModule, decorators: [{
|
|
@@ -1913,7 +2558,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.34", ngImpo
|
|
|
1913
2558
|
declarations: [...COMPONENTS],
|
|
1914
2559
|
providers: [
|
|
1915
2560
|
AdminModuleCommService,
|
|
1916
|
-
{ provide: ADM_CONVERSATIONS, useFactory: () => !!myconfig.TransactionTimeoutSeconds }
|
|
2561
|
+
{ provide: ADM_CONVERSATIONS, useFactory: () => !!myconfig.TransactionTimeoutSeconds },
|
|
2562
|
+
{ provide: ADM_TOPACT_V2, useFactory: () => !!myconfig?.DirectorFeature?.TopActivityV2 }
|
|
1917
2563
|
]
|
|
1918
2564
|
}]
|
|
1919
2565
|
}], ctorParameters: () => [{ type: AdminModuleCommService }] });
|
|
@@ -1926,5 +2572,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.34", ngImpo
|
|
|
1926
2572
|
* Generated bundle index. Do not edit.
|
|
1927
2573
|
*/
|
|
1928
2574
|
|
|
1929
|
-
export { ADM_CONVERSATIONS, ADM_MODULE_PATH, AdmMessageTypes, AdmModule, MK_ADM, routeConfig };
|
|
2575
|
+
export { ADM_CONVERSATIONS, ADM_MODULE_PATH, ADM_TOPACT_V2, AdmMessageTypes, AdmModule, MK_ADM, routeConfig, topActivityV2Enabled };
|
|
1930
2576
|
//# sourceMappingURL=esfaenza-admin-module.mjs.map
|