mirror of
https://github.com/BorysLevytskyi/BitwiseCmd.git
synced 2025-12-21 20:22:48 +01:00
Finilize VPC View support
This commit is contained in:
@@ -25,8 +25,8 @@ code { font-size: 1.2em; font-weight: bold; }
|
||||
.result .content { padding-left: 10px}
|
||||
.result .cur { margin-right: 5px; }
|
||||
|
||||
.hashLink { text-decoration: none; margin-left: 5px; visibility: hidden }
|
||||
.hashLink:hover { text-decoration: underline; margin-left: 5px; }
|
||||
.hashLink { text-decoration: none; margin-left: 5px; visibility: hidden; margin-right: 0; padding: 0; text-decoration: none; }
|
||||
.hashLink:hover { text-decoration: underline; margin-left: 5px; background: none; }
|
||||
.result:hover .hashLink { visibility: visible }
|
||||
|
||||
.expression .label { font-weight: bold; padding-right: 5px; text-align: right; }
|
||||
@@ -48,7 +48,7 @@ code { font-size: 1.2em; font-weight: bold; }
|
||||
.help ul { list-style-type: none; margin: 0; padding: 0; }
|
||||
.help p { margin-top: 0 }
|
||||
|
||||
.indicator { padding: 2px 5px; font-family: monospace; font-size: 1.3em; background: transparent; border: none; cursor: pointer }
|
||||
.indicator { padding: 0px 5px; background: transparent; border: none; cursor: pointer; vertical-align: middle; }
|
||||
.error { color: maroon; }
|
||||
|
||||
.soft { opacity: 0.7 }
|
||||
@@ -68,13 +68,13 @@ code { font-size: 1.2em; font-weight: bold; }
|
||||
.light .on { color: #121212; }
|
||||
.light .prefix { color: #888}
|
||||
.light .other { color: #bbb }
|
||||
.light .hashLink, .light .hashLink:visited { color: #ddd }
|
||||
.light .hashLink, .light .hashLink:visited { color: #ddd; }
|
||||
.light .hashLink:hover { color: #888 }
|
||||
.light ul.top-links li:hover { background: #ddd }
|
||||
.light .error { color: #da586d }
|
||||
.light button { color: black}
|
||||
.light button:hover { background: #ddd}
|
||||
.light button:disabled { color: #888; background-color: inherit; }
|
||||
.light button.btn { color: black}
|
||||
.light button.btn:hover { background: #ddd}
|
||||
.light button.btn:disabled { color: #888; background-color: inherit; }
|
||||
|
||||
/* Dark */
|
||||
.dark { background: #121212; color: white;}
|
||||
@@ -90,9 +90,9 @@ code { font-size: 1.2em; font-weight: bold; }
|
||||
.dark .hashLink:hover { color: #999 }
|
||||
.dark ul.top-links li:hover { background: #333 }
|
||||
.dark .error { color: #da586d}
|
||||
.dark button { color: white}
|
||||
.dark button:hover { background: #333}
|
||||
.dark button:disabled { color: #999; background-color: inherit; }
|
||||
.dark button.btn { color: white}
|
||||
.dark button.btn:hover { background: #333}
|
||||
.dark button.btn:disabled { color: #999; background-color: inherit; }
|
||||
|
||||
/*
|
||||
Midnight Theme
|
||||
@@ -113,9 +113,9 @@ code { font-size: 1.2em; font-weight: bold; }
|
||||
.midnight ul.top-links li:hover { background: #132537 }
|
||||
.midnight .error { color:#da586d}
|
||||
.midnight .changelog .item-new .date { font-weight: bold }
|
||||
.midnight button { color: white}
|
||||
.midnight button:hover { background: #132537}
|
||||
.midnight button:disabled { color: #85a0ad; background-color: inherit; }
|
||||
.midnight button.btn { color: white}
|
||||
.midnight button.btn:hover { background: #132537}
|
||||
.midnight button.btn:disabled { color: #85a0ad; background-color: inherit; }
|
||||
|
||||
button {
|
||||
border: none;
|
||||
|
||||
@@ -41,9 +41,9 @@ function SubnetView(props : {subnet : SubnetCommand}) {
|
||||
</td>
|
||||
<td data-test-name="decimal">
|
||||
|
||||
<button onClick={decrementMask} disabled={subnet.cidr.maskBits === 0} title="Decrease mask size">-</button>
|
||||
<button className="btn" onClick={decrementMask} disabled={subnet.cidr.maskBits === 0} title="Decrease mask size">-</button>
|
||||
<span>{subnet.cidr.maskBits}</span>
|
||||
<button onClick={incrementMask} disabled={subnet.cidr.maskBits === 32} title="Increase mask size">+</button>
|
||||
<button className="btn"onClick={incrementMask} disabled={subnet.cidr.maskBits === 32} title="Increase mask size">+</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
}
|
||||
|
||||
.vpc-view .address-space {
|
||||
font-size: 1.5em;
|
||||
font-size: 1.2em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import React, { useState } from 'react';
|
||||
import BinaryStringView from '../../core/components/BinaryString';
|
||||
import './VpcView.css';
|
||||
import { getNetworkAddress, getBroadCastAddress, createSubnetMaskIp, getAddressSpaceSize } from '../subnet-utils';
|
||||
import { chunkifyString } from '../../core/utils';
|
||||
import { getNetworkAddress, getAddressSpaceSize } from '../subnet-utils';
|
||||
import IpAddressBinaryString from './IpAddressBinaryString';
|
||||
import { IpAddress, IpAddressWithSubnetMask, SubnetCommand, VpcCommand } from '../models';
|
||||
import formatter, { padLeft } from '../../core/formatter';
|
||||
import { IpAddress, IpAddressWithSubnetMask, VpcCommand } from '../models';
|
||||
import formatter from '../../core/formatter';
|
||||
import Toggle from '../../shell/components/Toggle';
|
||||
import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
|
||||
|
||||
const MAX_NON_HOSTS_BITS = 30; // leave two bits for hosts min
|
||||
@@ -24,7 +26,6 @@ function SubnetView(props : {vpc : VpcCommand}) {
|
||||
const incrVpc = () => setVpc(vpc.changeVpcCidr(new IpAddressWithSubnetMask(vpc.cidr.ipAddress, vpc.cidr.maskBits + 1)));
|
||||
const decrVpc = () => setVpc(vpc.changeVpcCidr(new IpAddressWithSubnetMask(vpc.cidr.ipAddress, vpc.cidr.maskBits - 1)));
|
||||
|
||||
|
||||
const split = formatter.splitByMasks(networkAddress.toBinaryString(), vpc.cidr.maskBits, subnetMaskSize);
|
||||
|
||||
return <React.Fragment>
|
||||
@@ -35,21 +36,35 @@ function SubnetView(props : {vpc : VpcCommand}) {
|
||||
<div>
|
||||
<span>VPC Network Address</span>
|
||||
</div>
|
||||
<div>
|
||||
<BinaryStringView binaryString={split.vpc} disableHighlight={true} className="address-space soft" />
|
||||
<BinaryStringView binaryString={split.subnet} disableHighlight={true} className="address-space subnet-part" />
|
||||
<BinaryStringView binaryString={split.hosts} disableHighlight={true} className="address-space host-part" />
|
||||
<span className="address-space decimal-part">{networkAddress.toString()}</span>
|
||||
<Toggle text="[i]" isOn={vpc.showLegend} onClick={() => setVpc(vpc.toggleLegend())} title="Show/Hide Color Legend">
|
||||
<FontAwesomeIcon className="icon" icon={faQuestionCircle} size="sm" />
|
||||
</Toggle>
|
||||
</div>
|
||||
<div style={{"display" : vpc.showLegend ? '' : 'none'}}>
|
||||
<p>
|
||||
Color Legend
|
||||
</p>
|
||||
<span className="address-space soft">000</span> - VPC address bits <br/>
|
||||
<span className="address-space subnet-part">000</span> - Bits dedicated for subnets address<br/>
|
||||
<span className="address-space host-part">000</span> - Bits dedicated to host addresses inside each subnet
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table className="vpc-details">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="soft">
|
||||
VPC CIDR Mask:
|
||||
</td>
|
||||
<td>
|
||||
<button onClick={decrVpc} disabled={vpc.cidr.maskBits <= 1} title="Decrease vpc address bits">-</button>
|
||||
<button className="btn" onClick={decrVpc} disabled={vpc.cidr.maskBits <= 1} title="Decrease vpc address bits">-</button>
|
||||
/{vpc.cidr.maskBits}
|
||||
<button onClick={incrVpc} disabled={subnetMaskSize >= MAX_NON_HOSTS_BITS} title="Increse vpc address bits">+</button>
|
||||
<button className="btn" onClick={incrVpc} disabled={subnetMaskSize >= MAX_NON_HOSTS_BITS} title="Increse vpc address bits">+</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -57,9 +72,9 @@ function SubnetView(props : {vpc : VpcCommand}) {
|
||||
Subnet CIDR Mask:
|
||||
</td>
|
||||
<td>
|
||||
<button onClick={decrSubnet} disabled={vpc.subnetBits <= 1} title="Increase subnet bits">-</button>
|
||||
<button className="btn" onClick={decrSubnet} disabled={vpc.subnetBits <= 1} title="Increase subnet bits">-</button>
|
||||
/{subnetMaskSize}
|
||||
<button onClick={incrSubnet} disabled={vpc.cidr.maskBits + vpc.subnetBits >= MAX_NON_HOSTS_BITS} title="Increase subnet bits">+</button>
|
||||
<button className="btn" onClick={incrSubnet} disabled={vpc.cidr.maskBits + vpc.subnetBits >= MAX_NON_HOSTS_BITS} title="Increase subnet bits">+</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -67,9 +82,9 @@ function SubnetView(props : {vpc : VpcCommand}) {
|
||||
Max Subnets in VPC:
|
||||
</td>
|
||||
<td>
|
||||
<button onClick={decrSubnet} disabled={vpc.subnetBits <= 1} title="Decrease subnet bits">-</button>
|
||||
<button className="btn" onClick={decrSubnet} disabled={vpc.subnetBits <= 1} title="Decrease subnet bits">-</button>
|
||||
{maxSubnets}
|
||||
<button onClick={incrSubnet} disabled={vpc.cidr.maskBits + vpc.subnetBits >= MAX_NON_HOSTS_BITS} title="Increase subnet bits">+</button>
|
||||
<button className="btn" onClick={incrSubnet} disabled={vpc.cidr.maskBits + vpc.subnetBits >= MAX_NON_HOSTS_BITS} title="Increase subnet bits">+</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -88,6 +103,7 @@ function SubnetView(props : {vpc : VpcCommand}) {
|
||||
{hostsPerSubnet}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</React.Fragment>;
|
||||
@@ -114,17 +130,23 @@ class VpcModel {
|
||||
cidr: IpAddressWithSubnetMask;
|
||||
subnetBits: number;
|
||||
subnetNum: number;
|
||||
showLegend: boolean;
|
||||
|
||||
constructor(cidr: IpAddressWithSubnetMask, subnetBits: number) {
|
||||
this.cidr = cidr;
|
||||
this.subnetBits = subnetBits;
|
||||
this.subnetNum = 0;
|
||||
this.showLegend = false;
|
||||
}
|
||||
|
||||
static create(vpc: VpcCommand) {
|
||||
return new VpcModel(vpc.cidr, vpc.subnetBits);
|
||||
}
|
||||
|
||||
clone() : VpcModel {
|
||||
return Object.assign(new VpcModel(this.cidr, this.subnetBits), this);
|
||||
}
|
||||
|
||||
changeSubnetBits(n: number) {
|
||||
return new VpcModel(this.cidr, n);
|
||||
}
|
||||
@@ -132,4 +154,10 @@ class VpcModel {
|
||||
changeVpcCidr(newCidr: IpAddressWithSubnetMask) {
|
||||
return new VpcModel(newCidr, this.subnetBits);
|
||||
}
|
||||
|
||||
toggleLegend() {
|
||||
var n = new VpcModel(this.cidr, this.subnetBits);
|
||||
n.showLegend = !this.showLegend;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,7 @@ export class IpAddressWithSubnetMask {
|
||||
}
|
||||
|
||||
getAdressSpaceSize(): number {
|
||||
const spaceLengthInBits = 32 - this.maskBits;
|
||||
return getAddressSpaceSize(spaceLengthInBits);
|
||||
return getAddressSpaceSize(this.maskBits);
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import log from 'loglevel';
|
||||
|
||||
const APP_VERSION = 6;
|
||||
const APP_VERSION = 7;
|
||||
|
||||
export type PersistedAppData = {
|
||||
emphasizeBytes: boolean;
|
||||
@@ -59,6 +59,14 @@ export default class AppState {
|
||||
this.triggerChanged();
|
||||
}
|
||||
|
||||
removeResult(index: number) {
|
||||
if(index < 0 || index >= this.commandResults.length)
|
||||
return;
|
||||
|
||||
this.commandResults.splice(index, 1);
|
||||
this.triggerChanged();
|
||||
}
|
||||
|
||||
toggleEmphasizeBytes() {
|
||||
this.emphasizeBytes = !this.emphasizeBytes;
|
||||
this.triggerChanged();
|
||||
|
||||
@@ -38,7 +38,7 @@ export default class AppRoot extends React.Component<AppRootProps, AppRootState>
|
||||
getResultViews() : JSX.Element[] {
|
||||
|
||||
var results = this.state.commandResults.map((r, i) =>
|
||||
<DisplayResultView key={r.key} input={r.input} inputHash={hash.encodeHash(r.input)} appState={this.props.appState}>
|
||||
<DisplayResultView resultIndex={i} resultKey={r.key} key={r.key} input={r.input} inputHash={hash.encodeHash(r.input)} appState={this.props.appState}>
|
||||
{r.view}
|
||||
</DisplayResultView>);
|
||||
return results;
|
||||
|
||||
@@ -23,7 +23,7 @@ function DebugIndicators(props: {appState: AppState}) {
|
||||
return null;
|
||||
|
||||
return <div className="debug-indicators">
|
||||
{list.map(i => <span title={i}>[{i.substring(0,1)}] </span>)}
|
||||
{list.map(i => <span title={i} key={i}>[{i.substring(0,1)}] </span>)}
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { faTrashAlt, faHashtag } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import React from 'react';
|
||||
import AppState from '../AppState';
|
||||
|
||||
@@ -6,23 +8,32 @@ type DisplayResultProps = {
|
||||
appState: AppState,
|
||||
inputHash: string,
|
||||
input: string,
|
||||
key: number,
|
||||
resultKey: number,
|
||||
resultIndex: number,
|
||||
onRemove?: (i: number) => void;
|
||||
}
|
||||
|
||||
export default class DisplayResultView extends React.Component<DisplayResultProps> {
|
||||
render() {
|
||||
const DisplayResultView: React.FunctionComponent<DisplayResultProps> = (props) => {
|
||||
|
||||
const resultKey : number = props.resultKey;
|
||||
const appState = props.appState;
|
||||
|
||||
return <div className="result">
|
||||
<div className="input mono">
|
||||
<span className="cur">
|
||||
></span>{this.props.input}
|
||||
<a className="hashLink" title="Link for this expression" href={window.location.pathname + '#' + this.props.inputHash}>#</a>
|
||||
></span>{props.input}
|
||||
<a className="hashLink" title="Link for this expression" href={window.location.pathname + '#' + props.inputHash}>
|
||||
<FontAwesomeIcon className="icon" icon={faHashtag} size="xs" />
|
||||
</a>
|
||||
<button className="hashLink" title="Remove this result" onClick={() => appState.removeResult(props.resultIndex)}>
|
||||
<FontAwesomeIcon className="icon" icon={faTrashAlt} size="xs" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="content">
|
||||
{this.props.children}
|
||||
{props.children}
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
export default DisplayResultView;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ function HelpResultView() {
|
||||
<li><code><CommandLink text="127.0.0.1" /></code> — enter single or multiple ip addresses (separated by space) to see their binary represenation</li>
|
||||
<li><code><CommandLink text="192.168.0.1/8" /></code> — subnet mask notiations are support as well</li>
|
||||
<li><code><CommandLink text="subnet 192.168.24.1/14" /></code> — display information about subnet (network address, broadcast address, etc.)</li>
|
||||
<li><code><CommandLink text="vpc 192.168.24.1/24" /></code> — see how VPC network address bits are divided between VPC address, Subnets and Hosts</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="section">
|
||||
|
||||
@@ -2,18 +2,21 @@
|
||||
import React from "react";
|
||||
|
||||
export type ToggleProps = {
|
||||
text: string,
|
||||
text?: string,
|
||||
isOn: boolean,
|
||||
title: string,
|
||||
elementId?: string
|
||||
onClick: () => void
|
||||
};
|
||||
|
||||
function Toggle(props: ToggleProps) {
|
||||
const Toggle: React.FunctionComponent<ToggleProps> = (props) => {
|
||||
|
||||
return <span id={props.elementId}
|
||||
className={"indicator " + getIndicator(props.isOn)}
|
||||
title={props.title}
|
||||
onClick={() => props.onClick()}>{props.text}</span>
|
||||
onClick={() => props.onClick()}>
|
||||
{ !props.children ? props.text : props.children }
|
||||
</span>
|
||||
}
|
||||
|
||||
function getIndicator(value : boolean) {
|
||||
|
||||
@@ -7,6 +7,14 @@ function WhatsnewResultView() {
|
||||
return <div className="changelog">
|
||||
<h3>Changelog</h3>
|
||||
<div className="item item-new">
|
||||
<p><span className="soft date">Jul 24th, 2021</span> <br/>
|
||||
<ul>
|
||||
<li>Added support of <code>vpc</code> command to see hpw VPC network address is divided bettwen VPC, Subnets and Hosts. Try it out: <CommandLink text="vpc 192.168.24.1/24" /></li>
|
||||
<li>Added ability to remove individual results</li>
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
<div className="item">
|
||||
<p><span className="soft date">Jun 16th, 2021</span> <br/>
|
||||
Added support of <code>subnet</code> command to display information about subnet ip adress such. Try it out: <CommandLink text="subnet 192.168.24.1/14" />
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user