projects/cobbler-frontend/src/app/items/network-interface/overview/network-interface-overview.component.ts
OnInit
OnDestroy
AfterViewInit
| selector | cobbler-network-interface-overview |
| standalone | true |
| imports |
MatTableModule
MatIconModule
MatButtonModule
MatTooltip
MatPaginatorModule
|
| styleUrls | ./network-interface-overview.component.scss |
| templateUrl | ./network-interface-overview.component.html |
| styleUrl | ./network-interface-overview.component.scss |
No results matching.
MatTableModule
MatMenuModule
MatIconModule
MatButtonModule
MatTooltip
MatPaginatorModule
OnInit
OnDestroy
AfterViewInit
Properties |
|
Methods |
constructor()
|
| addNetworkInterface |
addNetworkInterface()
|
|
Returns :
void
|
| deleteInterface | ||||||
deleteInterface(interfaceName: string)
|
||||||
|
Parameters :
Returns :
void
|
| ngAfterViewInit |
ngAfterViewInit()
|
|
Returns :
void
|
| ngOnDestroy |
ngOnDestroy()
|
|
Returns :
void
|
| ngOnInit |
ngOnInit()
|
|
Returns :
void
|
| renameInterface | ||||||
renameInterface(name: string)
|
||||||
|
Parameters :
Returns :
void
|
| Private retrieveInterfaces |
retrieveInterfaces()
|
|
Returns :
void
|
| showInterface | ||||||
showInterface(name: string)
|
||||||
|
Parameters :
Returns :
void
|
| Private _snackBar |
Type : unknown
|
Default value : inject(MatSnackBar)
|
| Private cobblerApiService |
Type : unknown
|
Default value : inject(CobblerApiService)
|
| dataSource |
Type : unknown
|
Default value : new MatTableDataSource<NetworkInterfacePair>([])
|
| Readonly dialog |
Type : unknown
|
Default value : inject<MatDialog>(MatDialog)
|
| displayedColumns |
Type : string[]
|
Default value : [
'name',
'mac_address',
'ipv4_address',
'ipv6_address',
'actions',
]
|
| Private ngUnsubscribe |
Type : unknown
|
Default value : new Subject<void>()
|
| paginator |
Type : MatPaginator
|
Decorators :
@ViewChild(MatPaginator)
|
| Private route |
Type : unknown
|
Default value : inject(ActivatedRoute)
|
| Private router |
Type : unknown
|
Default value : inject(Router)
|
| systemName |
Type : string
|
| table |
Type : MatTable<System>
|
Decorators :
@ViewChild(MatTable)
|
| Private userService |
Type : unknown
|
Default value : inject(UserService)
|
import {
AfterViewInit,
Component,
OnDestroy,
OnInit,
ViewChild,
inject,
} from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { MatSnackBar } from '@angular/material/snack-bar';
import {
MatTable,
MatTableDataSource,
MatTableModule,
} from '@angular/material/table';
import { MatTooltip } from '@angular/material/tooltip';
import { ActivatedRoute, Router } from '@angular/router';
import { CobblerApiService, NetworkInterface, System } from 'cobbler-api';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { DialogConfirmCancelData } from '../../../common/dialog-box-confirm-cancel-edit/dialog-box-confirm-cancel-edit.component';
import { DialogItemRenameComponent } from '../../../common/dialog-item-rename/dialog-item-rename.component';
import { UserService } from '../../../services/user.service';
import Utils from '../../../utils';
import { TemplateCreateComponent } from '../../template/create/template-create.component';
import { NetworkInterfaceCreateComponent } from '../create/network-interface-create.component';
import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
interface NetworkInterfacePair {
interfaceName: string;
networkInterface: NetworkInterface;
}
@Component({
selector: 'cobbler-network-interface-overview',
imports: [
MatTableModule,
MatMenuModule,
MatIconModule,
MatButtonModule,
MatTooltip,
MatPaginatorModule,
],
templateUrl: './network-interface-overview.component.html',
styleUrl: './network-interface-overview.component.scss',
})
export class NetworkInterfaceOverviewComponent
implements OnInit, OnDestroy, AfterViewInit
{
private route = inject(ActivatedRoute);
private userService = inject(UserService);
private cobblerApiService = inject(CobblerApiService);
private router = inject(Router);
private _snackBar = inject(MatSnackBar);
readonly dialog = inject<MatDialog>(MatDialog);
// Unsubscribe
private ngUnsubscribe = new Subject<void>();
// Table
displayedColumns: string[] = [
'name',
'mac_address',
'ipv4_address',
'ipv6_address',
'actions',
];
dataSource = new MatTableDataSource<NetworkInterfacePair>([]);
systemName: string;
@ViewChild(MatTable) table: MatTable<System>;
@ViewChild(MatPaginator) paginator!: MatPaginator;
constructor() {
this.systemName = this.route.snapshot.paramMap.get('name');
}
ngOnInit(): void {
this.retrieveInterfaces();
}
ngAfterViewInit(): void {
this.dataSource.paginator = this.paginator;
}
ngOnDestroy(): void {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
private retrieveInterfaces(): void {
this.cobblerApiService
.get_system(this.systemName, false, false, this.userService.token)
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe((cobblerSystem) => {
const result = new Array<NetworkInterfacePair>();
cobblerSystem.interfaces.forEach(
(networkInterfaceMap, networkInterfaceName) => {
const networkInterfaceObject = Object.fromEntries(
networkInterfaceMap,
) as NetworkInterface;
result.push({
interfaceName: networkInterfaceName,
networkInterface: networkInterfaceObject,
});
},
);
this.dataSource.data = result;
});
}
addNetworkInterface(): void {
const dialogRef = this.dialog.open(NetworkInterfaceCreateComponent, {
width: '40%',
data: { systemName: this.systemName },
});
dialogRef.afterClosed().subscribe((result) => {
if (typeof result === 'string') {
this.router.navigate([
'/items',
'system',
this.systemName,
'interface',
result,
]);
}
});
}
showInterface(name: string): void {
this.router.navigate([
'/items',
'system',
this.systemName,
'interface',
name,
]);
}
renameInterface(name: string): void {
const dialogRef = this.dialog.open(DialogItemRenameComponent, {
data: {
itemType: 'NetworkInterface',
itemName: name,
itemUid: '',
},
});
dialogRef.afterClosed().subscribe((newItemName) => {
if (newItemName === undefined) {
// Cancel means we don't need to rename the system
return;
}
this.cobblerApiService
.get_system_handle(this.systemName, this.userService.token)
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe({
next: (systemHandle) => {
const interfaceMap = new Map<string, string>();
interfaceMap.set('interface', name);
interfaceMap.set('rename_interface', newItemName);
this.cobblerApiService
.modify_system(
systemHandle,
'rename_interface',
interfaceMap,
this.userService.token,
)
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe({
next: (value) => {
this.cobblerApiService
.save_system(systemHandle, this.userService.token)
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe({
next: () => {
this.retrieveInterfaces();
},
error: (error) => {
// HTML encode the error message since it originates from XML
this._snackBar.open(
Utils.toHTML(error.message),
$localize`:@@snackbar.action.close:Close`,
);
},
});
},
error: (error) => {
// HTML encode the error message since it originates from XML
this._snackBar.open(
Utils.toHTML(error.message),
$localize`:@@snackbar.action.close:Close`,
);
},
});
},
error: (error) => {
// HTML encode the error message since it originates from XML
this._snackBar.open(
Utils.toHTML(error.message),
$localize`:@@snackbar.action.close:Close`,
);
},
});
});
}
deleteInterface(interfaceName: string): void {
this.cobblerApiService
.get_system_handle(this.systemName, this.userService.token)
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe({
next: (systemHandle) => {
this.cobblerApiService
.modify_system(
systemHandle,
'delete_interface',
interfaceName,
this.userService.token,
)
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe({
next: (value) => {
if (value) {
this.cobblerApiService
.save_system(systemHandle, this.userService.token)
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe({
next: () => {
this.retrieveInterfaces();
},
error: (error) => {
// HTML encode the error message since it originates from XML
this._snackBar.open(
Utils.toHTML(error.message),
$localize`:@@snackbar.action.close:Close`,
);
},
});
} else {
this._snackBar.open(
$localize`:@@error.delete-failed:Delete failed! Check server logs for more information.`,
$localize`:@@snackbar.action.close:Close`,
);
}
},
error: (err) => {
// HTML encode the error message since it originates from XML
this._snackBar.open(
Utils.toHTML(err.message),
$localize`:@@snackbar.action.close:Close`,
);
},
});
},
error: (err) => {
// HTML encode the error message since it originates from XML
this._snackBar.open(
Utils.toHTML(err.message),
$localize`:@@snackbar.action.close:Close`,
);
},
});
}
}
<div class="title-table">
<div class="title-row">
<h1 class="title title-cell-text" i18n="@@network-interface.overview.title">
INTERFACES FOR SYSTEM - {{ systemName }}
</h1>
<span class="title-cell-button">
<button
mat-icon-button
data-testid="item-add-button"
(click)="this.addNetworkInterface()"
matTooltip="Add Network Interface"
i18n-matTooltip="@@network-interface.overview.add-tooltip"
>
<mat-icon>add</mat-icon>
</button></span
>
</div>
</div>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef i18n="@@table.col.name">Name</th>
<td mat-cell *matCellDef="let element">{{ element.interfaceName }}</td>
</ng-container>
<!-- MAC Column -->
<ng-container matColumnDef="mac_address">
<th
mat-header-cell
*matHeaderCellDef
i18n="@@network-interface.overview.col.mac-address"
>
MAC Address
</th>
<td mat-cell *matCellDef="let element">
{{ element.networkInterface.mac_address }}
</td>
</ng-container>
<!-- IPv4 Address Column -->
<ng-container matColumnDef="ipv4_address">
<th
mat-header-cell
*matHeaderCellDef
i18n="@@network-interface.overview.col.ipv4-address"
>
IPv4 Address
</th>
<td mat-cell *matCellDef="let element">
{{ element.networkInterface.ip }}
</td>
</ng-container>
<!-- IPv6 Address Column -->
<ng-container matColumnDef="ipv6_address">
<th
mat-header-cell
*matHeaderCellDef
i18n="@@network-interface.overview.col.ipv6-address"
>
IPv6 Address
</th>
<td mat-cell *matCellDef="let element">
{{ element.networkInterface.ipv6_address }}
</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
<button mat-icon-button [matMenuTriggerFor]="menu">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item (click)="showInterface(element.interfaceName)">
<mat-icon>visibility</mat-icon>
<span i18n="@@item.action.show-details">Show details</span>
</button>
<button mat-menu-item (click)="renameInterface(element.interfaceName)">
<mat-icon>edit</mat-icon>
<span i18n="@@item.action.rename">Rename</span>
</button>
<button mat-menu-item (click)="deleteInterface(element.interfaceName)">
<mat-icon>delete</mat-icon>
<span i18n="@@item.action.delete">Delete</span>
</button>
</mat-menu>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
<mat-paginator
[length]="100"
[pageSize]="10"
[pageSizeOptions]="[5, 10, 25, 100]"
aria-label="Select page"
i18n-aria-label="@@paginator.select-page"
>
</mat-paginator>
./network-interface-overview.component.scss
.title-table {
display: table;
width: 100%;
}
.title-row {
display: table-cell;
width: 100%;
}
.title-cell-text {
display: table-cell;
width: 100%;
vertical-align: middle;
}
.title-cell-button {
display: table-cell;
}
.form-replicate {
min-width: 150px;
max-width: 600px;
width: 100%;
}
.form-field-full-width {
width: 100%;
}
table.mat-mdc-table {
border-radius: 14px 14px 0 0;
box-shadow: none;
overflow: hidden;
background-color: white;
}
// Table cell
.mat-mdc-header-cell {
border-bottom: 1px solid #cbcbcb;
}
.mat-mdc-cell {
border-bottom: 1px solid #cbcbcb;
}
.mat-mdc-paginator {
border-radius: 0 0 12px 12px;
background-color: white;
}
:host-context(.dark-theme) .mat-mdc-table {
background-color: #1a1b1f;
}
:host-context(.dark-theme) .mat-mdc-paginator {
background-color: #1a1b1f;
}
:host-context(.dark-theme) .mat-mdc-header-cell {
border-bottom: 1px solid #555555;
}
:host-context(.dark-theme) .mat-mdc-cell {
border-bottom: 1px solid #555555;
}
:host-context(.dark-theme) a {
color: white;
}
:host-context(.dark-theme) .link-icon {
color: rgba(255, 255, 255, 0.372);
}