mirror of
https://github.com/BorysLevytskyi/BitwiseCmd.git
synced 2025-12-21 12:12:44 +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 .content { padding-left: 10px}
|
||||||
.result .cur { margin-right: 5px; }
|
.result .cur { margin-right: 5px; }
|
||||||
|
|
||||||
.hashLink { text-decoration: none; margin-left: 5px; visibility: hidden }
|
.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; }
|
.hashLink:hover { text-decoration: underline; margin-left: 5px; background: none; }
|
||||||
.result:hover .hashLink { visibility: visible }
|
.result:hover .hashLink { visibility: visible }
|
||||||
|
|
||||||
.expression .label { font-weight: bold; padding-right: 5px; text-align: right; }
|
.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 ul { list-style-type: none; margin: 0; padding: 0; }
|
||||||
.help p { margin-top: 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; }
|
.error { color: maroon; }
|
||||||
|
|
||||||
.soft { opacity: 0.7 }
|
.soft { opacity: 0.7 }
|
||||||
@@ -68,13 +68,13 @@ code { font-size: 1.2em; font-weight: bold; }
|
|||||||
.light .on { color: #121212; }
|
.light .on { color: #121212; }
|
||||||
.light .prefix { color: #888}
|
.light .prefix { color: #888}
|
||||||
.light .other { color: #bbb }
|
.light .other { color: #bbb }
|
||||||
.light .hashLink, .light .hashLink:visited { color: #ddd }
|
.light .hashLink, .light .hashLink:visited { color: #ddd; }
|
||||||
.light .hashLink:hover { color: #888 }
|
.light .hashLink:hover { color: #888 }
|
||||||
.light ul.top-links li:hover { background: #ddd }
|
.light ul.top-links li:hover { background: #ddd }
|
||||||
.light .error { color: #da586d }
|
.light .error { color: #da586d }
|
||||||
.light button { color: black}
|
.light button.btn { color: black}
|
||||||
.light button:hover { background: #ddd}
|
.light button.btn:hover { background: #ddd}
|
||||||
.light button:disabled { color: #888; background-color: inherit; }
|
.light button.btn:disabled { color: #888; background-color: inherit; }
|
||||||
|
|
||||||
/* Dark */
|
/* Dark */
|
||||||
.dark { background: #121212; color: white;}
|
.dark { background: #121212; color: white;}
|
||||||
@@ -90,9 +90,9 @@ code { font-size: 1.2em; font-weight: bold; }
|
|||||||
.dark .hashLink:hover { color: #999 }
|
.dark .hashLink:hover { color: #999 }
|
||||||
.dark ul.top-links li:hover { background: #333 }
|
.dark ul.top-links li:hover { background: #333 }
|
||||||
.dark .error { color: #da586d}
|
.dark .error { color: #da586d}
|
||||||
.dark button { color: white}
|
.dark button.btn { color: white}
|
||||||
.dark button:hover { background: #333}
|
.dark button.btn:hover { background: #333}
|
||||||
.dark button:disabled { color: #999; background-color: inherit; }
|
.dark button.btn:disabled { color: #999; background-color: inherit; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Midnight Theme
|
Midnight Theme
|
||||||
@@ -113,9 +113,9 @@ code { font-size: 1.2em; font-weight: bold; }
|
|||||||
.midnight ul.top-links li:hover { background: #132537 }
|
.midnight ul.top-links li:hover { background: #132537 }
|
||||||
.midnight .error { color:#da586d}
|
.midnight .error { color:#da586d}
|
||||||
.midnight .changelog .item-new .date { font-weight: bold }
|
.midnight .changelog .item-new .date { font-weight: bold }
|
||||||
.midnight button { color: white}
|
.midnight button.btn { color: white}
|
||||||
.midnight button:hover { background: #132537}
|
.midnight button.btn:hover { background: #132537}
|
||||||
.midnight button:disabled { color: #85a0ad; background-color: inherit; }
|
.midnight button.btn:disabled { color: #85a0ad; background-color: inherit; }
|
||||||
|
|
||||||
button {
|
button {
|
||||||
border: none;
|
border: none;
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ function SubnetView(props : {subnet : SubnetCommand}) {
|
|||||||
</td>
|
</td>
|
||||||
<td data-test-name="decimal">
|
<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>
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.vpc-view .address-space {
|
.vpc-view .address-space {
|
||||||
font-size: 1.5em;
|
font-size: 1.2em;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import BinaryStringView from '../../core/components/BinaryString';
|
import BinaryStringView from '../../core/components/BinaryString';
|
||||||
import './VpcView.css';
|
import './VpcView.css';
|
||||||
import { getNetworkAddress, getBroadCastAddress, createSubnetMaskIp, getAddressSpaceSize } from '../subnet-utils';
|
import { getNetworkAddress, getAddressSpaceSize } from '../subnet-utils';
|
||||||
import { chunkifyString } from '../../core/utils';
|
|
||||||
import IpAddressBinaryString from './IpAddressBinaryString';
|
import IpAddressBinaryString from './IpAddressBinaryString';
|
||||||
import { IpAddress, IpAddressWithSubnetMask, SubnetCommand, VpcCommand } from '../models';
|
import { IpAddress, IpAddressWithSubnetMask, VpcCommand } from '../models';
|
||||||
import formatter, { padLeft } from '../../core/formatter';
|
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
|
const MAX_NON_HOSTS_BITS = 30; // leave two bits for hosts min
|
||||||
|
|
||||||
function SubnetView(props : {vpc : VpcCommand}) {
|
function SubnetView(props: { vpc: VpcCommand }) {
|
||||||
|
|
||||||
const [vpc, setVpc] = useState(VpcModel.create(props.vpc));
|
const [vpc, setVpc] = useState(VpcModel.create(props.vpc));
|
||||||
|
|
||||||
@@ -19,93 +21,107 @@ function SubnetView(props : {vpc : VpcCommand}) {
|
|||||||
const hostsPerSubnet = getAddressSpaceSize(subnetMaskSize);
|
const hostsPerSubnet = getAddressSpaceSize(subnetMaskSize);
|
||||||
const networkAddress = getNetworkAddress(vpc.cidr);
|
const networkAddress = getNetworkAddress(vpc.cidr);
|
||||||
|
|
||||||
const decrSubnet = () => setVpc(vpc.changeSubnetBits(vpc.subnetBits-1));
|
const decrSubnet = () => setVpc(vpc.changeSubnetBits(vpc.subnetBits - 1));
|
||||||
const incrSubnet = () => setVpc(vpc.changeSubnetBits(vpc.subnetBits+1));
|
const incrSubnet = () => setVpc(vpc.changeSubnetBits(vpc.subnetBits + 1));
|
||||||
const incrVpc = () => setVpc(vpc.changeVpcCidr(new IpAddressWithSubnetMask(vpc.cidr.ipAddress, vpc.cidr.maskBits+1)));
|
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 decrVpc = () => setVpc(vpc.changeVpcCidr(new IpAddressWithSubnetMask(vpc.cidr.ipAddress, vpc.cidr.maskBits - 1)));
|
||||||
|
|
||||||
|
|
||||||
const split = formatter.splitByMasks(networkAddress.toBinaryString(), vpc.cidr.maskBits, subnetMaskSize);
|
const split = formatter.splitByMasks(networkAddress.toBinaryString(), vpc.cidr.maskBits, subnetMaskSize);
|
||||||
|
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
|
|
||||||
<div className="expression vpc-view">
|
<div className="expression vpc-view">
|
||||||
|
|
||||||
<div className="address-container">
|
<div className="address-container">
|
||||||
<div>
|
<div>
|
||||||
<span>VPC Network Address</span>
|
<span>VPC Network Address</span>
|
||||||
</div>
|
</div>
|
||||||
<BinaryStringView binaryString={split.vpc} disableHighlight={true} className="address-space soft" />
|
<div>
|
||||||
<BinaryStringView binaryString={split.subnet} disableHighlight={true} className="address-space subnet-part"/>
|
<BinaryStringView binaryString={split.vpc} disableHighlight={true} className="address-space soft" />
|
||||||
<BinaryStringView binaryString={split.hosts} disableHighlight={true} className="address-space host-part" />
|
<BinaryStringView binaryString={split.subnet} disableHighlight={true} className="address-space subnet-part" />
|
||||||
<span className="address-space decimal-part">{networkAddress.toString()}</span>
|
<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>
|
</div>
|
||||||
|
|
||||||
<table className="vpc-details">
|
<table className="vpc-details">
|
||||||
<tr>
|
<tbody>
|
||||||
<td className="soft">
|
<tr>
|
||||||
VPC CIDR Mask:
|
<td className="soft">
|
||||||
|
VPC CIDR Mask:
|
||||||
</td>
|
</td>
|
||||||
<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}
|
/{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>
|
||||||
|
<td className="soft">
|
||||||
|
Subnet CIDR Mask:
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
<td>
|
||||||
<tr>
|
<button className="btn" onClick={decrSubnet} disabled={vpc.subnetBits <= 1} title="Increase subnet bits">-</button>
|
||||||
<td className="soft">
|
|
||||||
Subnet CIDR Mask:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<button onClick={decrSubnet} disabled={vpc.subnetBits <= 1} title="Increase subnet bits">-</button>
|
|
||||||
/{subnetMaskSize}
|
/{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>
|
||||||
|
<td className="soft">
|
||||||
|
Max Subnets in VPC:
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
<td>
|
||||||
<tr>
|
<button className="btn" onClick={decrSubnet} disabled={vpc.subnetBits <= 1} title="Decrease subnet bits">-</button>
|
||||||
<td className="soft">
|
{maxSubnets}
|
||||||
Max Subnets in VPC:
|
<button className="btn" onClick={incrSubnet} disabled={vpc.cidr.maskBits + vpc.subnetBits >= MAX_NON_HOSTS_BITS} title="Increase subnet bits">+</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="soft">
|
||||||
|
Max Hosts in VPC:
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button onClick={decrSubnet} disabled={vpc.subnetBits <= 1} title="Decrease subnet bits">-</button>
|
{maxSubnets * hostsPerSubnet}
|
||||||
{maxSubnets}
|
</td>
|
||||||
<button onClick={incrSubnet} disabled={vpc.cidr.maskBits + vpc.subnetBits >= MAX_NON_HOSTS_BITS} title="Increase subnet bits">+</button>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="soft">
|
||||||
|
Hosts Per Subnet:
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
<td>
|
||||||
<tr>
|
{hostsPerSubnet}
|
||||||
<td className="soft">
|
</td>
|
||||||
Max Hosts in VPC:
|
</tr>
|
||||||
</td>
|
</tbody>
|
||||||
<td>
|
</table>
|
||||||
{maxSubnets*hostsPerSubnet}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className="soft">
|
|
||||||
Hosts Per Subnet:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{hostsPerSubnet}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Indicator2(props: { ip: IpAddress, descr: string}) {
|
function Indicator2(props: { ip: IpAddress, descr: string }) {
|
||||||
|
|
||||||
const {ip, descr} = props;
|
const { ip, descr } = props;
|
||||||
|
|
||||||
return <tr>
|
return <tr>
|
||||||
<td className="soft" data-test-name="label">{descr}</td>
|
<td className="soft" data-test-name="label">{descr}</td>
|
||||||
<td data-test-name="decimal" className="ip-address-col">
|
<td data-test-name="decimal" className="ip-address-col">
|
||||||
{ip.toString()}
|
{ip.toString()}
|
||||||
</td>
|
</td>
|
||||||
<td data-test-name="bin">
|
<td data-test-name="bin">
|
||||||
<IpAddressBinaryString ip={ip} />
|
<IpAddressBinaryString ip={ip} />
|
||||||
</td>
|
</td>
|
||||||
</tr>;
|
</tr>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SubnetView;
|
export default SubnetView;
|
||||||
@@ -114,17 +130,23 @@ class VpcModel {
|
|||||||
cidr: IpAddressWithSubnetMask;
|
cidr: IpAddressWithSubnetMask;
|
||||||
subnetBits: number;
|
subnetBits: number;
|
||||||
subnetNum: number;
|
subnetNum: number;
|
||||||
|
showLegend: boolean;
|
||||||
|
|
||||||
constructor(cidr: IpAddressWithSubnetMask, subnetBits: number) {
|
constructor(cidr: IpAddressWithSubnetMask, subnetBits: number) {
|
||||||
this.cidr = cidr;
|
this.cidr = cidr;
|
||||||
this.subnetBits = subnetBits;
|
this.subnetBits = subnetBits;
|
||||||
this.subnetNum = 0;
|
this.subnetNum = 0;
|
||||||
|
this.showLegend = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static create(vpc: VpcCommand) {
|
static create(vpc: VpcCommand) {
|
||||||
return new VpcModel(vpc.cidr, vpc.subnetBits);
|
return new VpcModel(vpc.cidr, vpc.subnetBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clone() : VpcModel {
|
||||||
|
return Object.assign(new VpcModel(this.cidr, this.subnetBits), this);
|
||||||
|
}
|
||||||
|
|
||||||
changeSubnetBits(n: number) {
|
changeSubnetBits(n: number) {
|
||||||
return new VpcModel(this.cidr, n);
|
return new VpcModel(this.cidr, n);
|
||||||
}
|
}
|
||||||
@@ -132,4 +154,10 @@ class VpcModel {
|
|||||||
changeVpcCidr(newCidr: IpAddressWithSubnetMask) {
|
changeVpcCidr(newCidr: IpAddressWithSubnetMask) {
|
||||||
return new VpcModel(newCidr, this.subnetBits);
|
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 {
|
getAdressSpaceSize(): number {
|
||||||
const spaceLengthInBits = 32 - this.maskBits;
|
return getAddressSpaceSize(this.maskBits);
|
||||||
return getAddressSpaceSize(spaceLengthInBits);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toString() {
|
toString() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
|
|
||||||
const APP_VERSION = 6;
|
const APP_VERSION = 7;
|
||||||
|
|
||||||
export type PersistedAppData = {
|
export type PersistedAppData = {
|
||||||
emphasizeBytes: boolean;
|
emphasizeBytes: boolean;
|
||||||
@@ -59,6 +59,14 @@ export default class AppState {
|
|||||||
this.triggerChanged();
|
this.triggerChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeResult(index: number) {
|
||||||
|
if(index < 0 || index >= this.commandResults.length)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.commandResults.splice(index, 1);
|
||||||
|
this.triggerChanged();
|
||||||
|
}
|
||||||
|
|
||||||
toggleEmphasizeBytes() {
|
toggleEmphasizeBytes() {
|
||||||
this.emphasizeBytes = !this.emphasizeBytes;
|
this.emphasizeBytes = !this.emphasizeBytes;
|
||||||
this.triggerChanged();
|
this.triggerChanged();
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export default class AppRoot extends React.Component<AppRootProps, AppRootState>
|
|||||||
getResultViews() : JSX.Element[] {
|
getResultViews() : JSX.Element[] {
|
||||||
|
|
||||||
var results = this.state.commandResults.map((r, i) =>
|
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}
|
{r.view}
|
||||||
</DisplayResultView>);
|
</DisplayResultView>);
|
||||||
return results;
|
return results;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ function DebugIndicators(props: {appState: AppState}) {
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
return <div className="debug-indicators">
|
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>
|
</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 React from 'react';
|
||||||
import AppState from '../AppState';
|
import AppState from '../AppState';
|
||||||
|
|
||||||
@@ -6,23 +8,32 @@ type DisplayResultProps = {
|
|||||||
appState: AppState,
|
appState: AppState,
|
||||||
inputHash: string,
|
inputHash: string,
|
||||||
input: string,
|
input: string,
|
||||||
key: number,
|
resultKey: number,
|
||||||
|
resultIndex: number,
|
||||||
onRemove?: (i: number) => void;
|
onRemove?: (i: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class DisplayResultView extends React.Component<DisplayResultProps> {
|
const DisplayResultView: React.FunctionComponent<DisplayResultProps> = (props) => {
|
||||||
render() {
|
|
||||||
|
const resultKey : number = props.resultKey;
|
||||||
|
const appState = props.appState;
|
||||||
|
|
||||||
return <div className="result">
|
return <div className="result">
|
||||||
<div className="input mono">
|
<div className="input mono">
|
||||||
<span className="cur">
|
<span className="cur">
|
||||||
></span>{this.props.input}
|
></span>{props.input}
|
||||||
<a className="hashLink" title="Link for this expression" href={window.location.pathname + '#' + this.props.inputHash}>#</a>
|
<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>
|
||||||
<div className="content">
|
<div className="content">
|
||||||
{this.props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
</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="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="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="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>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className="section">
|
<div className="section">
|
||||||
|
|||||||
@@ -2,18 +2,21 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
export type ToggleProps = {
|
export type ToggleProps = {
|
||||||
text: string,
|
text?: string,
|
||||||
isOn: boolean,
|
isOn: boolean,
|
||||||
title: string,
|
title: string,
|
||||||
elementId?: string
|
elementId?: string
|
||||||
onClick: () => void
|
onClick: () => void
|
||||||
};
|
};
|
||||||
|
|
||||||
function Toggle(props: ToggleProps) {
|
const Toggle: React.FunctionComponent<ToggleProps> = (props) => {
|
||||||
|
|
||||||
return <span id={props.elementId}
|
return <span id={props.elementId}
|
||||||
className={"indicator " + getIndicator(props.isOn)}
|
className={"indicator " + getIndicator(props.isOn)}
|
||||||
title={props.title}
|
title={props.title}
|
||||||
onClick={() => props.onClick()}>{props.text}</span>
|
onClick={() => props.onClick()}>
|
||||||
|
{ !props.children ? props.text : props.children }
|
||||||
|
</span>
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIndicator(value : boolean) {
|
function getIndicator(value : boolean) {
|
||||||
|
|||||||
@@ -7,6 +7,14 @@ function WhatsnewResultView() {
|
|||||||
return <div className="changelog">
|
return <div className="changelog">
|
||||||
<h3>Changelog</h3>
|
<h3>Changelog</h3>
|
||||||
<div className="item item-new">
|
<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/>
|
<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" />
|
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>
|
</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user