Prechádzať zdrojové kódy

Expand_Dropdown_Options_Via_Interpolation

Removed `0` values in favor of 'Omit From Calculation' logic and dynamically generated deep numerical option arrays for Round Trip and Target Permit parameters.

        PURPOSE:
        To provide a comprehensive range of configuration without cluttering the underlying source code. Because `0` is mathematically equivalent to the `Omit From Calculation` bypasses previously established, explicitly removing `0` as a visual option streamlines user intent and removes redundancy. Additionally, leveraging ES6 string interpolation allows us to inject dozens of options (e.g. up to 50 permit tiers) cleanly within the HTML template literal.

        IMPLEMENTATION DETAILS:
        - `ts/roi.ts`: Changed the initialization fallback for `roundTripOption` from `0` to `omit` so cached users don't trigger a missing option value.
        - `ts/roi.ts`: Removed `<option value="0">0</option>` from the `working-capital` dropdown menu array.
        - `ts/roi.ts`: Replaced the hardcoded lists for `round-trip` and `target-permit` with `Array.from()` map functions that inherently join directly into the HTML string, outputting consecutive `<option>` elements spanning lengths 1-25 and 2-50 respectively.
Thomas Knott 2 týždňov pred
rodič
commit
4a8ff504cb
1 zmenil súbory, kde vykonal 8 pridanie a 32 odobranie
  1. 8 32
      ts/roi.ts

+ 8 - 32
ts/roi.ts

@@ -56,9 +56,9 @@ let capexMetric: MetricType = (localStorage.getItem('roi-capex-metric') as Metri
 let opexMetric: MetricType = (localStorage.getItem('roi-opex-metric') as MetricType) || 'vwap';
 let revenueMetric: MetricType = (localStorage.getItem('roi-revenue-metric') as MetricType) || 'vwap';
 
-// EXTREME DETAIL: Changed state variables from numerical ints to strings to natively support
-// the 'omit' and 'dynamic' categorical values alongside the raw number options.
-let roundTripOption: string = localStorage.getItem('roi-round-trip') || '0';
+// EXTREME DETAIL: Because '0' is no longer an option in the UI, we update the fallback
+// state to 'omit' to prevent the script from trying to load a non-existent dropdown item.
+let roundTripOption: string = localStorage.getItem('roi-round-trip') || 'omit';
 let showNegativeProfit: boolean = localStorage.getItem('roi-show-negative') !== 'false';
 let workingCapitalOption: string = localStorage.getItem('roi-working-capital-opt') || 'dynamic';
 let targetPermitOption: string = localStorage.getItem('roi-target-permit') || '2';
@@ -75,8 +75,9 @@ async function render() {
 	if (!metricControlsInitialized) {
 		const controls = document.createElement('div');
 		controls.style.marginBottom = '15px';
-		// EXTREME DETAIL: Converted Round Trip and Permit Number to distinct <select> dropdowns.
-		// Injected `<option value="omit">Omit From Calculation</option>` at the top of all three.
+		// EXTREME DETAIL: We generate the massive dropdown arrays on the fly using ES6 interpolation.
+		// Array.from({length: x}) creates an empty array of size x, and the mapping function evaluates
+		// the index (i) to inject the correct incremental HTML options directly into the template string.
 		controls.innerHTML = `
 			<label style="margin-right: 15px;">CapEx Price: 
 				<select id="capex-metric"><option value="vwap">VWAP</option><option value="bid">Bid</option><option value="ask">Ask</option></select>
@@ -94,15 +95,7 @@ async function render() {
 				Round Trip (hrs): 
 				<select id="round-trip">
 					<option value="omit">Omit From Calculation</option>
-					<option value="0">0</option>
-					<option value="2">2</option>
-					<option value="4">4</option>
-					<option value="8">8</option>
-					<option value="12">12</option>
-					<option value="24">24</option>
-					<option value="48">48</option>
-					<option value="72">72</option>
-					<option value="168">168</option>
+					${Array.from({length: 25}, (_, i) => `<option value="${i + 1}">${i + 1}</option>`).join('')}
 				</select>
 			</label>
 			<label style="margin-right: 15px;">
@@ -110,7 +103,6 @@ async function render() {
 				<select id="working-capital">
 					<option value="omit">Omit From Calculation</option>
 					<option value="dynamic">Max for Shipment (dynamic)</option>
-					<option value="0">0</option>
 					<option value="1">1</option>
 					<option value="2">2</option>
 					<option value="3">3</option>
@@ -126,16 +118,7 @@ async function render() {
 				Permit Number: 
 				<select id="target-permit">
 					<option value="omit">Omit From Calculation</option>
-					<option value="1">1</option>
-					<option value="2">2</option>
-					<option value="3">3</option>
-					<option value="4">4</option>
-					<option value="5">5</option>
-					<option value="6">6</option>
-					<option value="7">7</option>
-					<option value="8">8</option>
-					<option value="9">9</option>
-					<option value="10">10</option>
+					${Array.from({length: 49}, (_, i) => `<option value="${i + 2}">${i + 2}</option>`).join('')}
 				</select>
 			</label>
 		`;
@@ -267,8 +250,6 @@ async function render() {
 		
 		let capex_val = p.capex[capexMetric] / bases;
 
-		// EXTREME DETAIL: Conditionally evaluate OpEx constraints based on the new dropdown selection.
-		// If 'omit' is selected, activeWorkingCapitalDays remains 0, suppressing the cost completely.
 		let activeWorkingCapitalDays = 0;
 		if (workingCapitalOption !== 'omit') {
 			if (workingCapitalOption === 'dynamic') {
@@ -281,7 +262,6 @@ async function render() {
 			capex_val += (opex_val * activeWorkingCapitalDays);
 		}
 		
-		// EXTREME DETAIL: Target permits safely bypassed if 'omit' is active.
 		let hq_capex = 0;
 		if (targetPermitOption !== 'omit') {
 			const targetPermit = parseInt(targetPermitOption, 10);
@@ -294,7 +274,6 @@ async function render() {
 			}
 		}
 
-		// EXTREME DETAIL: Little's Law ship mathematics safely bypassed if 'omit' is active.
 		let shipsNeeded = 0;
 		let activeShipCapex = 0;
 		if (roundTripOption !== 'omit') {
@@ -379,9 +358,6 @@ async function render() {
 			'+ worker consumables\n\n' +
 			`(${formatSigFig(p.revenue_val)} - ${formatSigFig(p.opex_val)}) = ${formatSigFig(p.profit_per_base)}`;
 
-		// EXTREME DETAIL: Conditionally rendered the CapEx Tooltip breakdown.
-		// If the user selected 'Omit From Calculation' for any parameter, that specific line
-		// completely vanishes from the hover tooltip, confirming to the user that it was removed.
 		const capexCell = tr.querySelectorAll('td')[4];
 		capexCell.dataset.tooltip = `Base Construction: ${formatSigFig(p.capex[capexMetric] / (p.area / 500))}`;