forked from M-Labs/web2019
Refactor resource subsystem (still needs integration)
Signed-off-by: Egor Savkin <es@m-labs.hk>
This commit is contained in:
parent
da3f18d6d9
commit
e8b1d70356
|
@ -3,7 +3,8 @@ import PropTypes from "prop-types";
|
||||||
import {Draggable} from "@hello-pangea/dnd";
|
import {Draggable} from "@hello-pangea/dnd";
|
||||||
import {OverlayTrigger} from "react-bootstrap";
|
import {OverlayTrigger} from "react-bootstrap";
|
||||||
import {DialogPopup} from "./options/DialogPopup.jsx";
|
import {DialogPopup} from "./options/DialogPopup.jsx";
|
||||||
import {nbrClocksStyle, nbrConnectorsStyle, productStyle} from "./utils";
|
import {productStyle} from "./utils";
|
||||||
|
import {Resources} from "./Resources.jsx";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that renders a product.
|
* Component that renders a product.
|
||||||
|
@ -22,6 +23,7 @@ export class ProductCartItem extends PureComponent {
|
||||||
model: PropTypes.object.isRequired,
|
model: PropTypes.object.isRequired,
|
||||||
data: PropTypes.object,
|
data: PropTypes.object,
|
||||||
ext_data: PropTypes.object,
|
ext_data: PropTypes.object,
|
||||||
|
resources: PropTypes.object,
|
||||||
onToggleOverlayRemove: PropTypes.func,
|
onToggleOverlayRemove: PropTypes.func,
|
||||||
onClickRemoveItem: PropTypes.func,
|
onClickRemoveItem: PropTypes.func,
|
||||||
onClickItem: PropTypes.func,
|
onClickItem: PropTypes.func,
|
||||||
|
@ -79,6 +81,7 @@ export class ProductCartItem extends PureComponent {
|
||||||
first,
|
first,
|
||||||
last,
|
last,
|
||||||
ext_data,
|
ext_data,
|
||||||
|
resources,
|
||||||
onCardUpdate,
|
onCardUpdate,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
@ -102,30 +105,7 @@ export class ProductCartItem extends PureComponent {
|
||||||
|
|
||||||
let render_progress;
|
let render_progress;
|
||||||
if (data) {
|
if (data) {
|
||||||
switch(model.type) {
|
|
||||||
case 'kasli':
|
|
||||||
render_progress = [
|
|
||||||
(<p key={model.type+model.id+"EEM"}>{`${data.nbrCurrentSlot}/${model.nbrSlotMax} EEM connectors used`}</p>),
|
|
||||||
(<p key={model.type+model.id+"CLK"}>{`${data.nbrCurrentClock}/${model.nbrClockMax} Clock connectors used`}</p>)
|
|
||||||
];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'vhdcicarrier':
|
|
||||||
render_progress = (<p>{`${data.nbrCurrentSlot}/${model.nbrSlotMax} EEM connectors used`}</p>);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'zotino':
|
|
||||||
case 'hd68':
|
|
||||||
render_progress = (<p>{`${data.nbrCurrentSlot}/${model.nbrSlotMax} connectors used`}</p>);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'clocker':
|
|
||||||
render_progress = (<p>{`${data.nbrCurrentClock}/${model.nbrClockMax} Clock connectors used`}</p>);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -218,28 +198,8 @@ export class ProductCartItem extends PureComponent {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* progression container */}
|
{/* progression container */}
|
||||||
{render_progress && (
|
{resources && (
|
||||||
<OverlayTrigger
|
<Resources resources={resources}/>
|
||||||
placement="top"
|
|
||||||
trigger={['click', 'hover', 'focus']}
|
|
||||||
overlay={({arrowProps, hasDoneInitialMeasure, show, ...props}) => (<div className="k-popup-connectors" {...props}>{render_progress}</div>)}
|
|
||||||
rootClose
|
|
||||||
>
|
|
||||||
<div className="progress-container">
|
|
||||||
|
|
||||||
{model.nbrSlotMax > 0 && (
|
|
||||||
<div className="nbr-connectors">
|
|
||||||
<div style={{ ...nbrConnectorsStyle(data)}}></div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{model.nbrClockMax > 0 && (
|
|
||||||
<div className="nbr-clocks">
|
|
||||||
<div style={{ ...nbrClocksStyle(data)}}></div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</OverlayTrigger>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
import {OverlayTrigger} from "react-bootstrap";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
|
||||||
|
const resourcesWidthStyle = (occupied, max) => {
|
||||||
|
return {
|
||||||
|
width: `${Math.min(occupied * 100 / max, 100)}%`,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function EEMRenderer({occupied, max}) {
|
||||||
|
return (
|
||||||
|
<div className="nbr-connectors">
|
||||||
|
<div style={{...resourcesWidthStyle(occupied, max)}}></div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function ClockRenderer({occupied, max}) {
|
||||||
|
return (
|
||||||
|
<div className="nbr-clocks">
|
||||||
|
<div style={{...resourcesWidthStyle(occupied, max)}}></div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const resource_progress_renderers = {
|
||||||
|
"eem": EEMRenderer,
|
||||||
|
"clk": ClockRenderer,
|
||||||
|
"idc": EEMRenderer
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function EEMTipRender({occupied, max}) {
|
||||||
|
return (<p>{`${occupied}/${max} EEM connectors used`}</p>);
|
||||||
|
}
|
||||||
|
|
||||||
|
function IDCTipRender({occupied, max}) {
|
||||||
|
return (<p>{`${occupied}/${max} IDC connectors used`}</p>);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ClockTipRender({occupied, max}) {
|
||||||
|
return (<p>{`${occupied}/${max} clock connectors used`}</p>);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resource_tip = {
|
||||||
|
"eem": EEMTipRender,
|
||||||
|
"clk": ClockTipRender,
|
||||||
|
"idc": IDCTipRender
|
||||||
|
}
|
||||||
|
|
||||||
|
function RenderResources({resources, library}) {
|
||||||
|
if (!resources) return null;
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
resources.forEach((value, _) => {
|
||||||
|
if (library[value.name]) result.push(library[value.name](value));
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Resources({resources}) {
|
||||||
|
return (
|
||||||
|
<OverlayTrigger
|
||||||
|
placement="top"
|
||||||
|
trigger={['click', 'hover', 'focus']}
|
||||||
|
overlay={({arrowProps, hasDoneInitialMeasure, show, ...props}) => (
|
||||||
|
<div className="k-popup-connectors" {...props}>
|
||||||
|
<RenderResources
|
||||||
|
resources={resources}
|
||||||
|
library={resource_tip}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
rootClose
|
||||||
|
>
|
||||||
|
<div className="progress-container">
|
||||||
|
<RenderResources
|
||||||
|
resources={resources}
|
||||||
|
library={resource_progress_renderers}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</OverlayTrigger>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
function EEMCounter(data, index) {
|
||||||
|
const process_slots = (item) => {
|
||||||
|
if (!item.options_data
|
||||||
|
|| item.options_data.ext_pwr === false
|
||||||
|
|| item.options_data.mono_eem === false
|
||||||
|
)
|
||||||
|
return item.slotOccupied;
|
||||||
|
else if (item.options_data.ext_pwr === true)
|
||||||
|
return 0;
|
||||||
|
else if (item.options_data.mono_eem === true || item.options_data.n_eem === "1 EEM")
|
||||||
|
return 1;
|
||||||
|
else if (item.options_data.n_eem === "3 EEM")
|
||||||
|
return 3;
|
||||||
|
|
||||||
|
return item.slotOccupied || 0;
|
||||||
|
}
|
||||||
|
let count = 0;
|
||||||
|
for (let i = index + 1; i < data.length; i++) {
|
||||||
|
if (data[i].resources.filter((value, _i) => value.name === "eem").length > 0) break;
|
||||||
|
count += process_slots(data[i]);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ClockCounter(data, index) {
|
||||||
|
const process_slots = (item) => {
|
||||||
|
return (item.options_data && item.options_data.ext_clk === true) ? 0 : (item.clockOccupied || 0);
|
||||||
|
}
|
||||||
|
let count = 0;
|
||||||
|
for (let i = index + 1; i < data.length; i++) {
|
||||||
|
if (data[i].resources.filter((value, _i) => value.name === "clk").length > 0) break;
|
||||||
|
count += process_slots(data[i]);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
function IDCCounter(data, index) {
|
||||||
|
const process_slots = (item) => {
|
||||||
|
return item.idcOccupied || 0;
|
||||||
|
}
|
||||||
|
let count = 0;
|
||||||
|
for (let i = index + 1; i < data.length; i++) {
|
||||||
|
if (data[i].resources.filter((value, _i) => value.name === "idc").length > 0) break;
|
||||||
|
count += process_slots(data[i]);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const resource_counters = {
|
||||||
|
"eem": EEMCounter,
|
||||||
|
"clk": ClockCounter,
|
||||||
|
"idc": IDCCounter
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CountResources(data, index) {
|
||||||
|
if (!data[index].resources) return null;
|
||||||
|
let result = [];
|
||||||
|
data[index].resources.forEach((item, _) => {
|
||||||
|
if (resource_counters[item.name]) result.push({
|
||||||
|
name: item.name,
|
||||||
|
occupied: resource_counters[item.name](data, index),
|
||||||
|
max: item.max
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -76,35 +76,6 @@ export const cartStyle = (style, snapshot) => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const nbrConnectorsStyle = (data) => {
|
|
||||||
if (!data || !data.nbrCurrentSlot) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
let p = data.nbrCurrentSlot * 100 / data.nbrSlotMax;
|
|
||||||
if (p > 100) {
|
|
||||||
p = 100;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
width: `${p}%`,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const nbrClocksStyle = (data) => {
|
|
||||||
if (!data || !data.nbrCurrentClock) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
let p = data.nbrCurrentClock * 100 / data.nbrClockMax;
|
|
||||||
if (p > 100) {
|
|
||||||
p = 100;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
width: `${p}%`,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const nbrOccupiedSlotsInCrate = (items) => {
|
export const nbrOccupiedSlotsInCrate = (items) => {
|
||||||
return items.reduce((prev, next) => {
|
return items.reduce((prev, next) => {
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
/**
|
||||||
|
* This module should contain warnings subsystem.
|
||||||
|
* First idea - there should be either definitive list of available warnings,
|
||||||
|
* or defined as some json logic leading to the warning message(s), similar way how FillExtData works.
|
||||||
|
* Second - resources indicator should be separate component
|
||||||
|
*/
|
Loading…
Reference in New Issue