Skip to content

Commit 08ff88d

Browse files
committed
feat: improve asset source sorting and display in assets view
Signed-off-by: Manuel Abascal <mjabascal10@gmail.com>
1 parent 0a89a40 commit 08ff88d

File tree

4 files changed

+70
-26
lines changed

4 files changed

+70
-26
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# UTMStack 10.9.2 Release Notes
22

33
-- Added new Pacific time zones (New Zealand and Fiji) to the Date Settings section.
4-
-- Added TLS connection options and setup steps for secure Syslog integration
4+
-- Added TLS connection options and setup steps for secure Syslog integration
5+
-- Improved sorting of asset sources in tables, ensuring consistent and predictable order for names, IPs, and combined entries.

frontend/src/app/assets-discover/assets-view/assets-view.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ <h5 class="card-title mb-0 text-uppercase label-header">
9898
<th (sort)="onSortBy($event)"
9999
[isSortable]="true"
100100
[sortEvent]="sortEvent"
101-
[sortable]="'assetIp'"
101+
[sortable]="'displayName'"
102102
appColumnSortable
103103
class="font-weight-semibold cursor-pointer">
104104
Source
@@ -143,7 +143,7 @@ <h5 class="card-title mb-0 text-uppercase label-header">
143143
<app-asset-status [asset]="asset"></app-asset-status>
144144
</td>
145145
<td>
146-
{{getAssetSource(asset)}}
146+
{{ asset.displayName }}
147147
</td>
148148
<td>
149149
<div class="d-flex justify-content-start align-items-start flex-wrap w-100 h-100"

frontend/src/app/assets-discover/assets-view/assets-view.component.ts

Lines changed: 64 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {AssetFilterType} from '../shared/types/asset-filter.type';
3030
import {UtmDataInputStatus} from '../shared/types/data-source-input.type';
3131
import {NetScanType} from '../shared/types/net-scan.type';
3232
import {SourceDataTypeConfigComponent} from '../source-data-type-config/source-data-type-config.component';
33+
import {SortDirection} from "../../shared/directives/sortable/type/sort-direction.type";
3334

3435
@Component({
3536
selector: 'app-assets-view',
@@ -105,11 +106,6 @@ export class AssetsViewComponent implements OnInit, OnDestroy {
105106

106107
}
107108

108-
ngOnDestroy(): void {
109-
this.stopInterval(true);
110-
this.assetFiltersBehavior.$assetFilter.next(null);
111-
}
112-
113109
setInitialWidth() {
114110
const dimensions = calcTableDimension(this.pageWidth);
115111
this.tableWidth = dimensions.tableWidth;
@@ -122,9 +118,28 @@ export class AssetsViewComponent implements OnInit, OnDestroy {
122118
}
123119

124120
getAssets() {
125-
this.utmNetScanService.query(this.requestParam).subscribe(response => {
121+
this.utmNetScanService.query(this.requestParam)
122+
.subscribe(response => {
126123
this.totalItems = Number(response.headers.get('X-Total-Count'));
127-
this.assets = response.body;
124+
const assets = response.body || [];
125+
126+
this.assets = assets.map(asset => {
127+
const displayName =
128+
asset.assetName && asset.assetIp
129+
? `${asset.assetName} (${asset.assetIp})`
130+
: asset.assetName
131+
? asset.assetName
132+
: asset.assetIp
133+
? asset.assetIp
134+
: 'Unknown source';
135+
136+
const sortKey = (asset.assetName || '') + (asset.assetIp || '');
137+
138+
return { ...asset, displayName, sortKey };
139+
});
140+
141+
console.log(this.assets);
142+
128143
this.loading = false;
129144
});
130145
}
@@ -154,8 +169,42 @@ export class AssetsViewComponent implements OnInit, OnDestroy {
154169
}
155170

156171
onSortBy($event: SortEvent) {
157-
this.requestParam.sort = $event.column + ',' + $event.direction;
158-
this.getAssets();
172+
if ($event.column === 'displayName') {
173+
this.sortAssets($event.direction);
174+
} else {
175+
this.requestParam.sort = $event.column + ',' + $event.direction;
176+
this.getAssets();
177+
}
178+
}
179+
180+
sortAssets(direction: SortDirection) {
181+
this.assets.sort((a, b) => {
182+
183+
if (a.displayName === 'Unknown source') { return 1; }
184+
if (b.displayName === 'Unknown source') { return -1; }
185+
186+
const aVal = a.sortKey!;
187+
const bVal = b.sortKey!;
188+
189+
const ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/;
190+
const aIsIP = ipRegex.test(aVal);
191+
const bIsIP = ipRegex.test(bVal);
192+
193+
if (aIsIP && bIsIP) {
194+
const aOctets = aVal.split('.').map(Number);
195+
const bOctets = bVal.split('.').map(Number);
196+
for (let i = 0; i < 4; i++) {
197+
if (aOctets[i] !== bOctets[i]) { return direction === 'asc' ? aOctets[i] - bOctets[i] : bOctets[i] - aOctets[i]; }
198+
}
199+
return 0;
200+
}
201+
202+
if (aIsIP) { return direction === 'asc' ? -1 : 1; }
203+
if (bIsIP) { return direction === 'asc' ? 1 : -1; }
204+
205+
const cmp = aVal.localeCompare(bVal, undefined, { numeric: true, sensitivity: 'base' });
206+
return direction === 'asc' ? cmp : -cmp;
207+
});
159208
}
160209

161210
toggleCheck() {
@@ -279,19 +328,6 @@ export class AssetsViewComponent implements OnInit, OnDestroy {
279328
});
280329
}
281330

282-
283-
getAssetSource(asset: NetScanType) {
284-
if (asset.assetName && asset.assetIp) {
285-
return asset.assetName + ' (' + asset.assetIp + ')';
286-
} else if (asset.assetName) {
287-
return asset.assetName;
288-
} else if (asset.assetIp) {
289-
return asset.assetIp;
290-
} else {
291-
return 'Unknown source';
292-
}
293-
}
294-
295331
navigateToDataManagement(ip: string) {
296332
const queryParams = {alertType: 'ALERT'};
297333
queryParams[ALERT_SENSOR_FIELD] = ElasticOperatorsEnum.IS + ChartValueSeparator.BUCKET_SEPARATOR + ip;
@@ -374,7 +410,12 @@ export class AssetsViewComponent implements OnInit, OnDestroy {
374410
if (!this.interval) {
375411
this.interval = setInterval(() => {
376412
this.getAssets();
377-
}, 10000);
413+
}, 60000);
378414
}
379415
}
416+
417+
ngOnDestroy(): void {
418+
this.stopInterval(true);
419+
this.assetFiltersBehavior.$assetFilter.next(null);
420+
}
380421
}

frontend/src/app/assets-discover/shared/types/net-scan.type.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,6 @@ export class NetScanType {
3535
assetOsPlatform?: string;
3636
assetOsMinorVersion?: string;
3737
assetOsMajorVersion?: string;
38+
displayName?: string;
39+
sortKey?: string;
3840
}

0 commit comments

Comments
 (0)