add reset map buttons for neetwork map (pro)

This commit is contained in:
sepehr 2026-03-29 23:31:19 +03:00
parent 57badfe347
commit 7e3469a5da
4 changed files with 155 additions and 13 deletions

View file

@ -667,6 +667,10 @@ export class dataProvider {
return this.MikroWizardRPC.sendJsonRequest("/api/networkmap/get", {});
}
resetNetworkMap() {
return this.MikroWizardRPC.sendJsonRequest("/api/networkmap/reset", {});
}
bulk_add_devices(devices: any[]) {
var data = {
'devices': devices

View file

@ -1,10 +1,27 @@
<c-row class="network-container">
<c-col [xs]="12" class="network-col">
<c-card class="network-card">
<button cButton color="primary" size="sm" (click)="refreshData()" class="refresh-btn">
<i class="fas fa-sync-alt"></i> Refresh
</button>
<div #network class="network-canvas"></div>
<div class="map-actions">
<button cButton color="primary" size="sm" (click)="refreshData()" class="refresh-btn">
<i class="fas fa-sync-alt"></i> Refresh
</button>
<button cButton color="warning" size="sm" (click)="resetLocations()" class="refresh-btn">
<i class="fas fa-thumbtack"></i> Reset Locations
</button>
<button cButton color="danger" size="sm" (click)="showResetModal = true" class="refresh-btn">
<i class="fas fa-trash-alt"></i> Reset Map
</button>
</div>
<div class="network-canvas">
<div #network class="full-size"></div>
<div *ngIf="loadingMap && mikrotikData.length === 0" class="map-loading-overlay">
<div class="loader-content">
<i class="fas fa-project-diagram fa-spin"></i>
<h3>Generating Map...</h3>
<p>Please wait while we discover your network topology. This might take a few minutes. (Polling every 30s)</p>
</div>
</div>
</div>
</c-card>
</c-col>
</c-row>
@ -80,3 +97,19 @@
<button cButton color="secondary" (click)="closeWebAccessModal()">Cancel</button>
</c-modal-footer>
</c-modal>
<!-- Reset Map Confirmation Modal -->
<c-modal #ResetMapModal backdrop="static" [(visible)]="showResetModal" id="ResetMapModal">
<c-modal-header>
<h6 cModalTitle>Confirm Map Reset</h6>
<button cButtonClose (click)="showResetModal = false"></button>
</c-modal-header>
<c-modal-body>
<p>Are you sure you want to reset all network discovery data?</p>
<p class="text-danger"><i class="fas fa-exclamation-triangle"></i> This will delete all current neighbors' data and trigger a fresh scan. Node positions will also be reset.</p>
</c-modal-body>
<c-modal-footer>
<button cButton color="secondary" (click)="showResetModal = false">Cancel</button>
<button cButton color="danger" (click)="confirmResetMap()">Reset Everything</button>
</c-modal-footer>
</c-modal>

View file

@ -18,13 +18,24 @@
position: relative;
}
.refresh-btn {
.map-actions {
position: absolute;
top: 10px;
right: 10px;
right: 15px;
z-index: 1000;
display: flex;
gap: 8px;
align-items: center;
}
.refresh-btn {
padding: 6px 12px;
font-size: 12px;
display: flex;
align-items: center;
gap: 6px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
white-space: nowrap;
}
.network-canvas {
@ -34,7 +45,49 @@
border-radius: 8px;
border: 1px solid #dee2e6;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
position: relative;
overflow: hidden;
.full-size {
width: 100%;
height: 100%;
}
.map-loading-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(4px);
z-index: 1001;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
.loader-content {
i {
font-size: 4rem;
color: #3498db;
margin-bottom: 20px;
}
h3 {
color: #2c3e50;
font-weight: 600;
margin-bottom: 10px;
}
p {
color: #7f8c8d;
max-width: 400px;
margin: 0 auto;
}
}
}
::ng-deep .vis-network {
cursor: default;

View file

@ -10,7 +10,7 @@ import { DataSet } from 'vis-data';
templateUrl: "maps.component.html",
styleUrls: ["maps.component.scss"],
})
export class MapsComponent implements OnInit {
export class MapsComponent implements OnInit, OnDestroy {
public uid: number;
public uname: string;
public ispro: boolean = false;
@ -19,8 +19,11 @@ export class MapsComponent implements OnInit {
public savedPositionsKey = "network-layout";
public selectedDevice: any = null;
public showWebAccessModal: boolean = false;
public showMoreInfoModal: boolean = false;
public currentDeviceInfo: any = null;
public showResetModal: boolean = false;
public loadingMap: boolean = false;
private pollingTimer: any;
constructor(
private data_provider: dataProvider,
private router: Router,
@ -54,13 +57,35 @@ export class MapsComponent implements OnInit {
this.loadNetworkData();
}
ngOnDestroy(): void {
if (this.pollingTimer) {
clearTimeout(this.pollingTimer);
}
}
loadNetworkData(): void {
clearTimeout(this.pollingTimer);
this.loadingMap = true;
this.data_provider.getNetworkMap().then((res) => {
this.mikrotikData = res;
console.dir(res);
setTimeout(() => {
this.createNetworkMap();
}, 100);
// Normalize response - handle array or object with 'result' property
const data = (res && res.result) ? res.result : res;
if (Array.isArray(data) && data.length > 0) {
this.loadingMap = false;
this.mikrotikData = data;
setTimeout(() => {
this.createNetworkMap();
}, 100);
} else {
console.log("Map data is empty, likely generating. Retrying in 30s...");
this.mikrotikData = [];
this.pollingTimer = setTimeout(() => {
this.loadNetworkData();
}, 30000);
}
}).catch(err => {
console.error("Error loading network map:", err);
this.loadingMap = false;
});
}
@ -476,4 +501,31 @@ Object.entries(connectionMap).forEach(([connectionKey, interfacePairs]) => {
// Implement configuration interface
}
resetLocations() {
localStorage.removeItem(this.savedPositionsKey);
this.savedPositions = {};
this.refreshData();
}
confirmResetMap() {
this.showResetModal = false;
this.loadingMap = true;
this.mikrotikData = [];
this.selectedDevice = null;
this.data_provider.resetNetworkMap().then((res) => {
if (res.status === 'success') {
localStorage.removeItem(this.savedPositionsKey);
this.savedPositions = {};
this.loadNetworkData();
} else {
this.loadingMap = false;
alert("Error: " + (res.error || "Failed to reset map"));
}
}).catch(err => {
this.loadingMap = false;
alert("Error resetting map: " + err);
});
}
}