Compare commits

...

5 Commits

Author SHA1 Message Date
69f979fe18 Add custom fiber length with pricing
Signed-off-by: Egor Savkin <es@m-labs.hk>
2025-03-25 16:41:38 +08:00
9cb6b16e9f Fix Number limits bypass
Signed-off-by: Egor Savkin <es@m-labs.hk>

# Conflicts:
#	static/js/shop.bundle.js
2025-03-25 16:40:52 +08:00
33a6a55369 npm update
Signed-off-by: Egor Savkin <es@m-labs.hk>
2025-03-20 12:23:18 +08:00
7b7faab505 update CXP description 2025-03-19 13:43:18 +08:00
2b1d56ef02 fix SoC datasheet link text 2025-03-19 13:40:04 +08:00
7 changed files with 1597 additions and 1577 deletions

3077
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -16,26 +16,27 @@
"url": "https://git.m-labs.hk/M-Labs/web2019.git"
},
"dependencies": {
"@hello-pangea/dnd": "^16.6.0",
"@hello-pangea/dnd": "^18.0.1",
"bootstrap": "^5.3.3",
"json-logic-js": "^2.0.5",
"react": "^18.3.1",
"react-bootstrap": "^2.10.4",
"uuid": "^9.0.1",
"zustand": "^4.5.4"
"react": "^19.0.0",
"react-bootstrap": "^2.10.9",
"uuid": "^11.1.0",
"zustand": "^5.0.3"
},
"devDependencies": {
"@babel/cli": "^7.24.8",
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/preset-react": "^7.24.7",
"@babel/cli": "^7.26.4",
"@babel/core": "^7.26.10",
"@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.26.3",
"@uidotdev/usehooks": "^2.4.1",
"babel-loader": "^9.1.3",
"babel-loader": "^10.0.0",
"babel-preset-minify": "^0.5.2",
"webpack": "^5.93.0",
"webpack-cli": "^5.1.4",
"webpack-preprocessor-loader": "^1.3.0",
"purgecss": "^7.0.2"
"purgecss": "^7.0.2",
"webpack": "^5.98.0",
"webpack-bundle-analyzer": "^4.10.2",
"webpack-cli": "^6.0.1",
"webpack-preprocessor-loader": "^1.3.0"
},
"babel": {
"presets": [

View File

@ -632,6 +632,12 @@ button {
background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000000'><path fill-rule='evenodd' d='M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708z'/></svg>");
background-repeat: no-repeat;
}
&.number-wide {
input {
width: 40%;
}
}
}
p {

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,7 @@
import React, {Component} from 'react'
import {Tip} from "./Tip";
import {valueOrFallback} from "../utils";
export class Number extends Component {
constructor(props) {
@ -7,6 +9,9 @@ export class Number extends Component {
// Initialize the state object with the initial values from the props
this.state = {
number: props.outvar in props.data ? props.data[props.outvar] : (props.fallback == null ? 0 : props.fallback),
min: valueOrFallback(props.min, -Infinity),
max: valueOrFallback(props.max, Infinity),
step: valueOrFallback(props.step, 1),
};
// Bind the event handler to this
this.handleChange = this.handleChange.bind(this);
@ -16,25 +21,25 @@ export class Number extends Component {
}
handleChange(element) {
let number = element.target.value;
const number = Math.min(Math.max(this.state.min, element.target.value), this.state.max);
this.setState({
number: Math.min(Math.max(this.props.min || -Infinity, number), this.props.max || Infinity),
number: number,
});
this.props.target.update(this.props.outvar, number);
}
handleIncrement() {
let number = this.state.number + (this.props.step || 1);
let number = this.state.number + this.state.step;
this.setState({
number: Math.min(number, this.props.max || Infinity),
number: Math.min(number, this.state.max),
});
this.props.target.update(this.props.outvar, number);
}
handleDecrement() {
let number = this.state.number - (this.props.step || 1);
let number = this.state.number - this.state.step;
this.setState({
number: Math.max(number, this.props.min || -Infinity),
number: Math.max(number, this.state.min),
});
this.props.target.update(this.props.outvar, number);
}
@ -50,8 +55,8 @@ export class Number extends Component {
render() {
let key = this.props.id + this.props.outvar;
let downDisabled = this.state.number <= this.props.min;
let upDisabled = this.state.number >= this.props.max;
let downDisabled = this.state.number <= this.state.min;
let upDisabled = this.state.number >= this.state.max;
return (
<div className={"shop-number " + (this.props.classes || "") } key={this.props.id}>
@ -73,6 +78,9 @@ export class Number extends Component {
type="number"
value={this.state.number}
onChange={this.handleChange}
step={this.state.step}
min={this.state.min}
max={this.state.max}
className="form-control"
/>

View File

@ -11,6 +11,10 @@ export const execOrReturn = (valuable, ...args) => {
return valuable;
}
export const valueOrFallback = (value, fallback) => {
return (value === undefined || value === null) ? fallback : value
}
export function FillExtCardData(data, index) {
return {
// we cannot use value id, because they are substituted with uuid

View File

@ -212,13 +212,26 @@ const shop_data = {
{type: "Switch", args: {title: "Optical fiber", outvar: "optics", tip: "Use optical fiber instead of direct attach copper cable"}},
{"if": [
{"var": "optics"},
{type: "Radio", args: {title: "Fiber cable length", outvar: "fiber_cable_len", variants: ["1 M", "3 M", "5 M"], tip: "The desired length of the optical fiber cable", fallback: 1}},
{type: "Radio", args: {title: "Fiber cable length", outvar: "fiber_cable_len", variants: ["1 M", "3 M", "5 M", "Custom"], tip: "The desired length of the optical fiber cable. The longer the cable, the higher the latency.", fallback: 1}},
{type: "Radio", args: {title: "Copper cable length", outvar: "copper_cable_len", variants: ["0.5 M", "1 M", "2 M"], tip: "The desired length of the direct attach copper cable", fallback: 0}},
]},
{"if": [
{"==": [{"var": "fiber_cable_len"}, "Custom"]},
{type: "Number", args: {title: "Length in meters", outvar: "fiber_cable_len_custom", fallback: 3,
min: 1, max: 160000, step: 1, classes: "number-wide"}},
]}
]
]
}
],
price_options: [
{"if": [
{">": [{"var": "fiber_cable_len_custom"}, 101]},
{title: (options) => `Add fiber ${options.fiber_cable_len_custom}M cable`,
price: (options) => Math.round((0.4 * (options.fiber_cable_len_custom - 100))),
disable_patch: {fiber_cable_len_custom: 3, fiber_cable_len: "3 M"}, id: "fiber_cable_len_custom"}]
},
],
resources: [
{name: "eem", max: 12},
{name: "clk", max: 4},
@ -251,12 +264,12 @@ const shop_data = {
'4 MMCX clock outputs.',
],
datasheet_file: '/docs/sinara-datasheets/1125.pdf',
datasheet_name: '1124 Carrier Kasli SoC datasheet',
datasheet_name: '1125 Carrier Kasli SoC datasheet',
size: 'big',
hp: 8,
options: [
{type: "Number", args: {title: "CoaXPress-SFP adapters", outvar: "coaxpress", min: 0, max: 4, step: 1,
fallback: 0, tip: "High speed camera interface. Multiple adapters may be supported in the future."}},
fallback: 0, tip: "One lane of CXP-12 per adapter. ARTIQ-9 supports single lane, several may be supported later with firmware upgrade."}},
{type: "Radio", args: {title: "DRTIO role", outvar: "drtio_role", variants: ["standalone", "master", "satellite"], tip: "Distributed Real Time Input/Output allows ARTIQ RTIO channels to be distributed among several satellite devices synchronized and controlled by a central core(master) device. Standalone option disables this feature."}},
{
"if": [
@ -285,8 +298,13 @@ const shop_data = {
{type: "Switch", args: {title: "Optical fiber", outvar: "optics", tip: "Use optical fiber instead of direct attach copper cable"}},
{"if": [
{"var": "optics"},
{type: "Radio", args: {title: "Fiber cable length", outvar: "fiber_cable_len", variants: ["1 M", "3 M", "5 M"], tip: "The desired length of the optical fiber cable", fallback: 1}},
{type: "Radio", args: {title: "Fiber cable length", outvar: "fiber_cable_len", variants: ["1 M", "3 M", "5 M", "Custom"], tip: "The desired length of the optical fiber cable. The longer the cable, the higher the latency.", fallback: 1}},
{type: "Radio", args: {title: "Copper cable length", outvar: "copper_cable_len", variants: ["0.5 M", "1 M", "2 M"], tip: "The desired length of the direct attach copper cable", fallback: 0}},
]},
{"if": [
{"==": [{"var": "fiber_cable_len"}, "Custom"]},
{type: "Number", args: {title: "Length in meters", outvar: "fiber_cable_len_custom", fallback: 3,
min: 1, max: 160000, step: 1, classes: "number-wide"}},
]}
]
]
@ -298,6 +316,12 @@ const shop_data = {
{title: (options) => `Add CoaXPress to SFP adapter x${options.coaxpress}`, price: (options) => (1200 * options.coaxpress),
disable_patch: {coaxpress: 0}, id: "coaxpress"}]
},
{"if": [
{">": [{"var": "fiber_cable_len_custom"}, 101]},
{title: (options) => `Add fiber ${options.fiber_cable_len_custom}M cable`,
price: (options) => Math.round((0.4 * (options.fiber_cable_len_custom - 100))),
disable_patch: {fiber_cable_len_custom: 3, fiber_cable_len: "3 M"}, id: "fiber_cable_len_custom"}]
},
],
resources: [
{name: "eem", max: 12},