diff --git a/static/js/shop/ProductCartItem.jsx b/static/js/shop/ProductCartItem.jsx
index de1c22ed..9a0aca9e 100644
--- a/static/js/shop/ProductCartItem.jsx
+++ b/static/js/shop/ProductCartItem.jsx
@@ -3,7 +3,8 @@ import PropTypes from "prop-types";
import {Draggable} from "@hello-pangea/dnd";
import {OverlayTrigger} from "react-bootstrap";
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.
@@ -22,6 +23,7 @@ export class ProductCartItem extends PureComponent {
model: PropTypes.object.isRequired,
data: PropTypes.object,
ext_data: PropTypes.object,
+ resources: PropTypes.object,
onToggleOverlayRemove: PropTypes.func,
onClickRemoveItem: PropTypes.func,
onClickItem: PropTypes.func,
@@ -79,6 +81,7 @@ export class ProductCartItem extends PureComponent {
first,
last,
ext_data,
+ resources,
onCardUpdate,
} = this.props;
@@ -102,30 +105,7 @@ export class ProductCartItem extends PureComponent {
let render_progress;
if (data) {
- switch(model.type) {
- case 'kasli':
- render_progress = [
- (
{`${data.nbrCurrentSlot}/${model.nbrSlotMax} EEM connectors used`}
),
- ({`${data.nbrCurrentClock}/${model.nbrClockMax} Clock connectors used`}
)
- ];
- break;
- case 'vhdcicarrier':
- render_progress = ({`${data.nbrCurrentSlot}/${model.nbrSlotMax} EEM connectors used`}
);
- break;
-
- case 'zotino':
- case 'hd68':
- render_progress = ({`${data.nbrCurrentSlot}/${model.nbrSlotMax} connectors used`}
);
- break;
-
- case 'clocker':
- render_progress = ({`${data.nbrCurrentClock}/${model.nbrClockMax} Clock connectors used`}
);
- break;
-
- default:
- break;
- }
}
return (
@@ -218,28 +198,8 @@ export class ProductCartItem extends PureComponent {
{/* progression container */}
- {render_progress && (
- ({render_progress}
)}
- rootClose
- >
-
-
- {model.nbrSlotMax > 0 && (
-
- )}
-
- {model.nbrClockMax > 0 && (
-
- )}
-
-
+ {resources && (
+
)}
diff --git a/static/js/shop/Resources.jsx b/static/js/shop/Resources.jsx
new file mode 100644
index 00000000..4304ce90
--- /dev/null
+++ b/static/js/shop/Resources.jsx
@@ -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 (
+
+ )
+}
+
+function ClockRenderer({occupied, max}) {
+ return (
+
+ )
+}
+
+const resource_progress_renderers = {
+ "eem": EEMRenderer,
+ "clk": ClockRenderer,
+ "idc": EEMRenderer
+}
+
+
+function EEMTipRender({occupied, max}) {
+ return ({`${occupied}/${max} EEM connectors used`}
);
+}
+
+function IDCTipRender({occupied, max}) {
+ return ({`${occupied}/${max} IDC connectors used`}
);
+}
+
+function ClockTipRender({occupied, max}) {
+ return ({`${occupied}/${max} clock connectors used`}
);
+}
+
+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 (
+ (
+
+
+
+ )}
+ rootClose
+ >
+
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/static/js/shop/count_resources.js b/static/js/shop/count_resources.js
new file mode 100644
index 00000000..9aaf3a21
--- /dev/null
+++ b/static/js/shop/count_resources.js
@@ -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;
+}
\ No newline at end of file
diff --git a/static/js/shop/utils.js b/static/js/shop/utils.js
index be6f7663..30eda86d 100644
--- a/static/js/shop/utils.js
+++ b/static/js/shop/utils.js
@@ -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) => {
return items.reduce((prev, next) => {
diff --git a/static/js/shop/warnings.js b/static/js/shop/warnings.js
new file mode 100644
index 00000000..00527164
--- /dev/null
+++ b/static/js/shop/warnings.js
@@ -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
+ */
\ No newline at end of file