Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added ipnetwork.idraw
Binary file not shown.
2 changes: 1 addition & 1 deletion src/ConsoleApplication/ConsoleApplication.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<ImplicitUsings>disable</ImplicitUsings>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>..\System.Net.IPNetwork.snk</AssemblyOriginatorKeyFile>
<Version>3.2.0</Version>
<Version>3.4.0</Version>
<RootNamespace>System.Net</RootNamespace>
<LangVersion>latestmajor</LangVersion>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down
12 changes: 12 additions & 0 deletions src/Web/App.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
<FocusOnNavigate RouteData="@routeData" Selector="h1"/>
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
48 changes: 48 additions & 0 deletions src/Web/Components/IPNetworkTable.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
@using System.Net
@code {
[Parameter]
public IPNetwork2? IPNetwork { get; set; } = IPNetwork2.Parse("192.168.0.1");
}

@if (IPNetwork == null)
{
<span>Loading...</span>
}
else
{
<table>
<tr>
<th>IPNetwork</th><td>@IPNetwork</td>
</tr>
<tr>
<th>Network</th><td>@IPNetwork.Network</td>
</tr>
<tr>
<th>Netmask</th><td>@IPNetwork.Netmask</td>
</tr>
<tr>
<th>Cidr</th><td>@IPNetwork.Cidr</td>
</tr>
<tr>
<th>Broadcast</th><td>@IPNetwork.Broadcast</td>
</tr>
<tr>
<th>FirstUsable</th><td>@IPNetwork.FirstUsable</td>
</tr>
<tr>
<th>LastUsable</th><td>@IPNetwork.LastUsable</td>
</tr>
<tr>
<th>Usable</th><td>@IPNetwork.Usable</td>
</tr>
<tr>
<th>First</th><td>@IPNetwork.First</td>
</tr>
<tr>
<th>Last</th><td>@IPNetwork.Last</td>
</tr>
<tr>
<th>Total</th><td>@IPNetwork.Total</td>
</tr>
</table>
}
16 changes: 16 additions & 0 deletions src/Web/Layout/MainLayout.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu/>
</div>

<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>

<article class="content px-4">
@Body
</article>
</main>
</div>
77 changes: 77 additions & 0 deletions src/Web/Layout/MainLayout.razor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}

main {
flex: 1;
}

.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}

.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}

.top-row ::deep a, .top-row ::deep .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}

.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
text-decoration: underline;
}

.top-row ::deep a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}

@media (max-width: 640.98px) {
.top-row {
justify-content: space-between;
}

.top-row ::deep a, .top-row ::deep .btn-link {
margin-left: 0;
}
}

@media (min-width: 641px) {
.page {
flex-direction: row;
}

.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}

.top-row {
position: sticky;
top: 0;
z-index: 1;
}

.top-row.auth ::deep a:first-child {
flex: 1;
text-align: right;
width: 0;
}

.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}
40 changes: 40 additions & 0 deletions src/Web/Layout/NavMenu.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">Web</a>
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
</div>

<div class="@NavMenuCssClass nav-scrollable" @onclick="ToggleNavMenu">
<nav class="nav flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="parse">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Parse
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="parserange">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> ParseRange
</NavLink>
</div>
</nav>
</div>

@code {
private bool collapseNavMenu = true;

private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;

private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}

}
83 changes: 83 additions & 0 deletions src/Web/Layout/NavMenu.razor.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
.navbar-toggler {
background-color: rgba(255, 255, 255, 0.1);
}

.top-row {
min-height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}

.navbar-brand {
font-size: 1.1rem;
}

.bi {
display: inline-block;
position: relative;
width: 1.25rem;
height: 1.25rem;
margin-right: 0.75rem;
top: -1px;
background-size: cover;
}

.bi-house-door-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
}

.bi-plus-square-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
}

.bi-list-nested-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
}

.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}

.nav-item:first-of-type {
padding-top: 1rem;
}

.nav-item:last-of-type {
padding-bottom: 1rem;
}

.nav-item ::deep a {
color: #d7d7d7;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
}

.nav-item ::deep a.active {
background-color: rgba(255,255,255,0.37);
color: white;
}

.nav-item ::deep a:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}

@media (min-width: 641px) {
.navbar-toggler {
display: none;
}

.collapse {
/* Never collapse the sidebar for wide screens */
display: block;
}

.nav-scrollable {
/* Allow sidebar to scroll for tall menus */
height: calc(100vh - 3.5rem);
overflow-y: auto;
}
}
7 changes: 7 additions & 0 deletions src/Web/Pages/Home.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@page "/"

<PageTitle>Home</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.
63 changes: 63 additions & 0 deletions src/Web/Pages/Parse.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
@page "/parse"
@using System.ComponentModel.DataAnnotations
@using System.Net
@using Web.Components

<PageTitle>Parse</PageTitle>

<h1>IPNetwork.Parse</h1>

<EditForm Model="Model" OnValidSubmit="Submit" FormName="Parse">
<DataAnnotationsValidator />
<ValidationSummary />
<p role="status">
<InputText @bind-Value="Model!.IPNetwork" />
<InputSelect @bind-Value="Model!.CidrGuess">
<option checked="@(Model!.CidrGuess == "ClassFull")"
value="ClassFull">
ClassFull
</option>
<option checked="@(Model!.CidrGuess == "ClassLess")"
value="ClassLess">
ClassLess
</option>
<option checked="@(Model!.CidrGuess == "NetworkAware")"
value="NetworkAware">
NetworkAware
</option>
</InputSelect></p>
<button type="submit">Submit</button>
</EditForm>

<IPNetworkTable IPNetwork="@ipn" />

@code {
[SupplyParameterFromForm]

private ParseModel? Model { get; set; }

private IPNetwork2? ipn { get; set; } = IPNetwork2.Parse("192.168.0.1");

protected override void OnInitialized() =>
Model ??= new() { IPNetwork = "192.168.0.1" };

private void Submit()
{
ICidrGuess cidrGuess = Model.CidrGuess switch
{
"ClassFull" => CidrGuess.ClassFull,
"ClassLess" => CidrGuess.ClassLess,
"NetworkAware" => CidrGuess.NetworkAware,
_ => CidrGuess.ClassFull // default
};
ipn = IPNetwork2.Parse(Model?.IPNetwork, cidrGuess);

}

public class ParseModel
{
[Required]
public string? IPNetwork { get; set; }
public string? CidrGuess { get; set; }
}
}
Loading
Loading