sc-portal/app/src/app/networking/networks/networks.component.html

169 lines
8.1 KiB
HTML

<div class="d-flex flex-column h-100">
<div class="container text-center mt-1">
<div class="btn-toolbar pt-2" [formGroup]="editorForm">
<div class="btn-group flex-grow-1 flex-grow-sm-0 mb-3">
<button class="btn btn-lg btn-info" (click)="showVlanEditor()" [disabled]="loadingIndicator">
Create a new virtual network
</button>
</div>
<span class="d-none d-sm-block flex-grow-1"></span>
<ng-container *ngIf="vlans && vlans.length">
<div class="input-group mb-3 input-group-pill flex-grow-1 flex-grow-sm-0 me-sm-3 w-sm-auto w-100">
<input type="text" class="form-control" placeholder="Search by name or description..." formControlName="searchTerm" appAlphaOnly="^[A-Za-z0-9_-]+$">
<button class="btn btn-outline-info" type="button" (click)="clearSearch()" [disabled]="!editorForm.get('searchTerm').value"
tooltip="Clear search" container="body" placement="top" [adaptivePosition]="false">
<fa-icon icon="times" size="sm" [fixedWidth]="true"></fa-icon>
</button>
</div>
<div class="btn-group flex-grow-1 flex-grow-sm-0 mb-3 w-sm-auto w-100" dropdown placement="bottom left">
<button class="btn btn-outline-info dropdown-toggle" dropdownToggle>
Sort by {{ editorForm.get('sortProperty').value === 'vlan_id' ? 'id' : editorForm.get('sortProperty').value }}
</button>
<ul id="dropdown-split" *dropdownMenu class="dropdown-menu dropdown-menu-right" role="menu">
<li role="menuitem">
<button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'vlan_id'" (click)="setSortProperty('vlan_id')">
Id
</button>
</li>
<li role="menuitem">
<button class="dropdown-item" [class.active]="editorForm.get('sortProperty').value === 'name'" (click)="setSortProperty('name')">
Name
</button>
</li>
</ul>
</div>
</ng-container>
</div>
<div class="spinner-border text-center text-info text-faded" role="status" *ngIf="loadingIndicator">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<div class="overflow-auto flex-grow-1 mt-1">
<div class="container my-2">
<h2 *ngIf="listItems && listItems.length === 0 && vlans && vlans.length > 0" class="text-uppercase">
{{ 'networking.networks.list.noResults' | translate }}
</h2>
<accordion [isAnimated]="false" [closeOthers]="false">
<accordion-group *ngFor="let vlan of listItems" (isOpenChange)="getNetworks($event, vlan)">
<div class="d-flex justify-content-between align-items-center sticky-top" accordion-heading
[tooltip]="vlan.description" placement="top" [adaptivePosition]="false" container="body">
<h4 class="mb-0">
<span class="text-info me-2">{{ vlan.name }}</span>
<small class="vlan-id text-faded">
Unique ID: <b>{{ vlan.vlan_id }}</b>
</small>
</h4>
<fa-icon icon="angle-right" [fixedWidth]="true" [rotate]="vlan.expanded ? 90 : 0" class="text-info"></fa-icon>
</div>
<div class="table-responsive">
<div class="text-center my-3" *ngIf="vlan.working">
<div class="spinner-border text-info text-faded" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<p *ngIf="(!vlan.networks || !vlan.networks.length) && !vlan.working" class="text-center text-info text-faded p-3 mb-0">
The "{{ vlan.name }}" virtual network is empty.
</p>
<table class="table table-hover" *ngIf="vlan.networks && vlan.networks.length && !vlan.working">
<thead>
<tr>
<th>Name</th>
<th>Subnet</th>
<th>IP Range</th>
<th>Gateway</th>
<th>Resolvers</th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let network of vlan.networks">
<td>
<div>
<span class="badge badge-discreet text-uppercase float-end">{{ network.fabric ? 'fabric' : 'global' }}</span>
<div class="network-name float-start">{{ network.name }}</div>
</div>
</td>
<td>
{{ network.subnet }}
</td>
<td>
<span *ngIf="network.provision_start_ip">
{{ network.provision_start_ip }} ··· {{ network.provision_end_ip }}
</span>
</td>
<td>
{{ network.gateway }}
</td>
<td>
<div class="text-truncate resolvers" [tooltip]="network.resolvers | json" placement="top"
container="body" [adaptivePosition]="false">
<span *ngFor="let ip of network.resolvers" class="resolver">{{ ip }}</span>
</div>
</td>
<td class="text-end">
<div class="btn-group btn-group-sm" dropdown placement="bottom right" container="body">
<button class="btn btn-link text-info" tooltip="Edit this network" container="body"
placement="top" [adaptivePosition]="false" (click)="showNetworkEditor(vlan, network)">
<fa-icon icon="pen" [fixedWidth]="true" size="sm"></fa-icon>
</button>
<button class="btn btn-link text-info" dropdownToggle
tooltip="More options" container="body" placement="top" [adaptivePosition]="false">
<fa-icon icon="ellipsis-v" [fixedWidth]="true" size="sm"></fa-icon>
</button>
<ul id="dropdown-split" *dropdownMenu class="dropdown-menu dropdown-menu-right" role="menu" aria-labelledby="button-split">
<li role="menuitem">
<button class="dropdown-item" (click)="deleteNetwork(vlan, network)">
<fa-icon icon="trash" [fixedWidth]="true"></fa-icon>
Delete this network
</button>
</li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="card-footer px-2 d-flex justify-content-between align-items-center">
<button class="btn btn-outline-info" (click)="showNetworkEditor(vlan)">Create a new network</button>
<div class="btn-group btn-group-sm" dropdown placement="bottom right" container="body">
<button class="btn btn-link text-info" dropdownToggle
tooltip="Virtual network options" container="body" placement="top" [adaptivePosition]="false">
<fa-icon icon="ellipsis-v" [fixedWidth]="true" size="sm"></fa-icon>
</button>
<ul id="dropdown-split" *dropdownMenu class="dropdown-menu dropdown-menu-right" role="menu" aria-labelledby="button-split">
<li role="menuitem">
<button class="dropdown-item" (click)="showVlanEditor(vlan)">
<fa-icon icon="pen" [fixedWidth]="true"></fa-icon>
Edit this virtual network
</button>
</li>
<li class="dropdown-divider"></li>
<li role="menuitem">
<button class="dropdown-item" (click)="deleteVlan(vlan)">
<fa-icon icon="trash" [fixedWidth]="true"></fa-icon>
Delete this virtual network
</button>
</li>
</ul>
</div>
</div>
</accordion-group>
</accordion>
</div>
</div>
</div>