introduce support for instances in price calculator
This commit is contained in:
parent
8bb8930361
commit
6ad8b9aa49
3 changed files with 134 additions and 25 deletions
|
@ -9,6 +9,7 @@ class PriceCalculator {
|
||||||
this.storagePrice = null;
|
this.storagePrice = null;
|
||||||
this.currentOffering = null;
|
this.currentOffering = null;
|
||||||
this.selectedConfiguration = null;
|
this.selectedConfiguration = null;
|
||||||
|
this.replicaInfo = null;
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,9 +42,11 @@ class PriceCalculator {
|
||||||
this.cpuRange = document.getElementById('cpuRange');
|
this.cpuRange = document.getElementById('cpuRange');
|
||||||
this.memoryRange = document.getElementById('memoryRange');
|
this.memoryRange = document.getElementById('memoryRange');
|
||||||
this.storageRange = document.getElementById('storageRange');
|
this.storageRange = document.getElementById('storageRange');
|
||||||
|
this.instancesRange = document.getElementById('instancesRange');
|
||||||
this.cpuValue = document.getElementById('cpuValue');
|
this.cpuValue = document.getElementById('cpuValue');
|
||||||
this.memoryValue = document.getElementById('memoryValue');
|
this.memoryValue = document.getElementById('memoryValue');
|
||||||
this.storageValue = document.getElementById('storageValue');
|
this.storageValue = document.getElementById('storageValue');
|
||||||
|
this.instancesValue = document.getElementById('instancesValue');
|
||||||
this.serviceLevelInputs = document.querySelectorAll('input[name="serviceLevel"]');
|
this.serviceLevelInputs = document.querySelectorAll('input[name="serviceLevel"]');
|
||||||
this.planSelect = document.getElementById('planSelect');
|
this.planSelect = document.getElementById('planSelect');
|
||||||
|
|
||||||
|
@ -58,6 +61,7 @@ class PriceCalculator {
|
||||||
this.planDescription = document.getElementById('planDescription');
|
this.planDescription = document.getElementById('planDescription');
|
||||||
this.planCpus = document.getElementById('planCpus');
|
this.planCpus = document.getElementById('planCpus');
|
||||||
this.planMemory = document.getElementById('planMemory');
|
this.planMemory = document.getElementById('planMemory');
|
||||||
|
this.planInstances = document.getElementById('planInstances');
|
||||||
this.planServiceLevel = document.getElementById('planServiceLevel');
|
this.planServiceLevel = document.getElementById('planServiceLevel');
|
||||||
this.managedServicePrice = document.getElementById('managedServicePrice');
|
this.managedServicePrice = document.getElementById('managedServicePrice');
|
||||||
this.storagePriceEl = document.getElementById('storagePrice');
|
this.storagePriceEl = document.getElementById('storagePrice');
|
||||||
|
@ -68,6 +72,41 @@ class PriceCalculator {
|
||||||
this.orderButton = document.querySelector('a[href="#order-form"]');
|
this.orderButton = document.querySelector('a[href="#order-form"]');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update slider display values (min/max text below sliders)
|
||||||
|
updateSliderDisplayValues() {
|
||||||
|
// Update CPU slider display
|
||||||
|
if (this.cpuRange) {
|
||||||
|
const cpuMinDisplay = document.getElementById('cpuMinDisplay');
|
||||||
|
const cpuMaxDisplay = document.getElementById('cpuMaxDisplay');
|
||||||
|
if (cpuMinDisplay) cpuMinDisplay.textContent = this.cpuRange.min;
|
||||||
|
if (cpuMaxDisplay) cpuMaxDisplay.textContent = this.cpuRange.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update Memory slider display
|
||||||
|
if (this.memoryRange) {
|
||||||
|
const memoryMinDisplay = document.getElementById('memoryMinDisplay');
|
||||||
|
const memoryMaxDisplay = document.getElementById('memoryMaxDisplay');
|
||||||
|
if (memoryMinDisplay) memoryMinDisplay.textContent = this.memoryRange.min + ' GB';
|
||||||
|
if (memoryMaxDisplay) memoryMaxDisplay.textContent = this.memoryRange.max + ' GB';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update Storage slider display
|
||||||
|
if (this.storageRange) {
|
||||||
|
const storageMinDisplay = document.getElementById('storageMinDisplay');
|
||||||
|
const storageMaxDisplay = document.getElementById('storageMaxDisplay');
|
||||||
|
if (storageMinDisplay) storageMinDisplay.textContent = this.storageRange.min + ' GB';
|
||||||
|
if (storageMaxDisplay) storageMaxDisplay.textContent = this.storageRange.max + ' GB';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update Instances slider display
|
||||||
|
if (this.instancesRange) {
|
||||||
|
const instancesMinDisplay = document.getElementById('instancesMinDisplay');
|
||||||
|
const instancesMaxDisplay = document.getElementById('instancesMaxDisplay');
|
||||||
|
if (instancesMinDisplay) instancesMinDisplay.textContent = this.instancesRange.min;
|
||||||
|
if (instancesMaxDisplay) instancesMaxDisplay.textContent = this.instancesRange.max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Setup order button click handler
|
// Setup order button click handler
|
||||||
setupOrderButton() {
|
setupOrderButton() {
|
||||||
if (this.orderButton) {
|
if (this.orderButton) {
|
||||||
|
@ -115,6 +154,7 @@ class PriceCalculator {
|
||||||
vcpus: config.vcpus,
|
vcpus: config.vcpus,
|
||||||
memory: config.memory,
|
memory: config.memory,
|
||||||
storage: config.storage,
|
storage: config.storage,
|
||||||
|
instances: config.instances,
|
||||||
serviceLevel: config.serviceLevel,
|
serviceLevel: config.serviceLevel,
|
||||||
totalPrice: config.totalPrice
|
totalPrice: config.totalPrice
|
||||||
});
|
});
|
||||||
|
@ -129,6 +169,7 @@ Plan: ${config.planName} (${config.planGroup})
|
||||||
vCPUs: ${config.vcpus}
|
vCPUs: ${config.vcpus}
|
||||||
Memory: ${config.memory} GB
|
Memory: ${config.memory} GB
|
||||||
Storage: ${config.storage} GB
|
Storage: ${config.storage} GB
|
||||||
|
Instances: ${config.instances}
|
||||||
Service Level: ${config.serviceLevel}
|
Service Level: ${config.serviceLevel}
|
||||||
|
|
||||||
Total Monthly Price: CHF ${config.totalPrice}
|
Total Monthly Price: CHF ${config.totalPrice}
|
||||||
|
@ -158,17 +199,21 @@ Please contact me with next steps for ordering this configuration.`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract storage price from pricing data
|
// Extract replica information and storage price from pricing data
|
||||||
extractStoragePrice() {
|
extractStoragePrice() {
|
||||||
if (!this.pricingData) return;
|
if (!this.pricingData) return;
|
||||||
|
|
||||||
// Find the first plan with storage pricing data
|
// Find the first plan with storage pricing data and replica info
|
||||||
for (const groupName of Object.keys(this.pricingData)) {
|
for (const groupName of Object.keys(this.pricingData)) {
|
||||||
const group = this.pricingData[groupName];
|
const group = this.pricingData[groupName];
|
||||||
for (const serviceLevel of Object.keys(group)) {
|
for (const serviceLevel of Object.keys(group)) {
|
||||||
const plans = group[serviceLevel];
|
const plans = group[serviceLevel];
|
||||||
if (plans.length > 0 && plans[0].storage_price !== undefined) {
|
if (plans.length > 0 && plans[0].storage_price !== undefined) {
|
||||||
this.storagePrice = parseFloat(plans[0].storage_price);
|
this.storagePrice = parseFloat(plans[0].storage_price);
|
||||||
|
this.replicaInfo = {
|
||||||
|
ha_replica_min: plans[0].ha_replica_min || 1,
|
||||||
|
ha_replica_max: plans[0].ha_replica_max || 1
|
||||||
|
};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +222,7 @@ Please contact me with next steps for ordering this configuration.`;
|
||||||
|
|
||||||
// Setup event listeners for calculator controls
|
// Setup event listeners for calculator controls
|
||||||
setupEventListeners() {
|
setupEventListeners() {
|
||||||
if (!this.cpuRange || !this.memoryRange || !this.storageRange) return;
|
if (!this.cpuRange || !this.memoryRange || !this.storageRange || !this.instancesRange) return;
|
||||||
|
|
||||||
// Setup service levels based on available data
|
// Setup service levels based on available data
|
||||||
this.setupServiceLevels();
|
this.setupServiceLevels();
|
||||||
|
@ -198,9 +243,15 @@ Please contact me with next steps for ordering this configuration.`;
|
||||||
this.updatePricing();
|
this.updatePricing();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.instancesRange.addEventListener('input', () => {
|
||||||
|
this.instancesValue.textContent = this.instancesRange.value;
|
||||||
|
this.updatePricing();
|
||||||
|
});
|
||||||
|
|
||||||
// Service level change listeners
|
// Service level change listeners
|
||||||
this.serviceLevelInputs.forEach(input => {
|
this.serviceLevelInputs.forEach(input => {
|
||||||
input.addEventListener('change', () => {
|
input.addEventListener('change', () => {
|
||||||
|
this.updateInstancesSlider();
|
||||||
this.populatePlanDropdown();
|
this.populatePlanDropdown();
|
||||||
this.updatePricing();
|
this.updatePricing();
|
||||||
});
|
});
|
||||||
|
@ -224,6 +275,39 @@ Please contact me with next steps for ordering this configuration.`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize instances slider
|
||||||
|
this.updateInstancesSlider();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update instances slider based on service level and replica info
|
||||||
|
updateInstancesSlider() {
|
||||||
|
if (!this.instancesRange || !this.replicaInfo) return;
|
||||||
|
|
||||||
|
const serviceLevel = document.querySelector('input[name="serviceLevel"]:checked')?.value;
|
||||||
|
|
||||||
|
if (serviceLevel === 'Guaranteed Availability') {
|
||||||
|
// For GA, min is ha_replica_min
|
||||||
|
this.instancesRange.min = this.replicaInfo.ha_replica_min;
|
||||||
|
this.instancesRange.value = Math.max(this.instancesRange.value, this.replicaInfo.ha_replica_min);
|
||||||
|
} else {
|
||||||
|
// For BE, min is 1
|
||||||
|
this.instancesRange.min = 1;
|
||||||
|
this.instancesRange.value = Math.max(this.instancesRange.value, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set max to ha_replica_max
|
||||||
|
this.instancesRange.max = this.replicaInfo.ha_replica_max;
|
||||||
|
|
||||||
|
// Update display value
|
||||||
|
this.instancesValue.textContent = this.instancesRange.value;
|
||||||
|
|
||||||
|
// Update the min/max display under the slider using direct IDs
|
||||||
|
const instancesMinDisplay = document.getElementById('instancesMinDisplay');
|
||||||
|
const instancesMaxDisplay = document.getElementById('instancesMaxDisplay');
|
||||||
|
|
||||||
|
if (instancesMinDisplay) instancesMinDisplay.textContent = this.instancesRange.min;
|
||||||
|
if (instancesMaxDisplay) instancesMaxDisplay.textContent = this.instancesRange.max;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup service levels dynamically from pricing data
|
// Setup service levels dynamically from pricing data
|
||||||
|
@ -270,6 +354,7 @@ Please contact me with next steps for ordering this configuration.`;
|
||||||
|
|
||||||
// Add event listener
|
// Add event listener
|
||||||
input.addEventListener('change', () => {
|
input.addEventListener('change', () => {
|
||||||
|
this.updateInstancesSlider();
|
||||||
this.populatePlanDropdown();
|
this.populatePlanDropdown();
|
||||||
this.updatePricing();
|
this.updatePricing();
|
||||||
});
|
});
|
||||||
|
@ -281,7 +366,7 @@ Please contact me with next steps for ordering this configuration.`;
|
||||||
// Update the serviceLevelInputs reference
|
// Update the serviceLevelInputs reference
|
||||||
this.serviceLevelInputs = document.querySelectorAll('input[name="serviceLevel"]');
|
this.serviceLevelInputs = document.querySelectorAll('input[name="serviceLevel"]');
|
||||||
|
|
||||||
// Calculate and set slider maximums based on available plans
|
// Calculate and set slider maximums based on available plans - this will call updateSliderDisplayValues()
|
||||||
this.updateSliderMaximums();
|
this.updateSliderMaximums();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,17 +394,14 @@ Please contact me with next steps for ordering this configuration.`;
|
||||||
// Set slider maximums with some padding
|
// Set slider maximums with some padding
|
||||||
if (maxCpus > 0) {
|
if (maxCpus > 0) {
|
||||||
this.cpuRange.max = Math.ceil(maxCpus);
|
this.cpuRange.max = Math.ceil(maxCpus);
|
||||||
// Update the max display under the slider
|
|
||||||
const cpuMaxDisplay = this.cpuRange.parentElement.querySelector('.d-flex.justify-content-between .text-muted span:last-child');
|
|
||||||
if (cpuMaxDisplay) cpuMaxDisplay.textContent = Math.ceil(maxCpus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxMemory > 0) {
|
if (maxMemory > 0) {
|
||||||
this.memoryRange.max = Math.ceil(maxMemory);
|
this.memoryRange.max = Math.ceil(maxMemory);
|
||||||
// Update the max display under the slider
|
|
||||||
const memoryMaxDisplay = this.memoryRange.parentElement.querySelector('.d-flex.justify-content-between .text-muted span:last-child');
|
|
||||||
if (memoryMaxDisplay) memoryMaxDisplay.textContent = Math.ceil(maxMemory) + ' GB';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update display values after changing min/max - moved to end and call explicitly
|
||||||
|
this.updateSliderDisplayValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate plan dropdown based on selected service level
|
// Populate plan dropdown based on selected service level
|
||||||
|
@ -404,20 +486,22 @@ Please contact me with next steps for ordering this configuration.`;
|
||||||
// Update pricing with specific plan
|
// Update pricing with specific plan
|
||||||
updatePricingWithPlan(selectedPlan) {
|
updatePricingWithPlan(selectedPlan) {
|
||||||
const storage = parseInt(this.storageRange?.value || 20);
|
const storage = parseInt(this.storageRange?.value || 20);
|
||||||
|
const instances = parseInt(this.instancesRange?.value || 1);
|
||||||
|
|
||||||
this.showPlanDetails(selectedPlan, storage);
|
this.showPlanDetails(selectedPlan, storage, instances);
|
||||||
this.updateStatusMessage('Plan selected directly!', 'success');
|
this.updateStatusMessage('Plan selected directly!', 'success');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main pricing update function
|
// Main pricing update function
|
||||||
updatePricing() {
|
updatePricing() {
|
||||||
if (!this.pricingData || !this.cpuRange || !this.memoryRange || !this.storageRange) return;
|
if (!this.pricingData || !this.cpuRange || !this.memoryRange || !this.storageRange || !this.instancesRange) return;
|
||||||
|
|
||||||
// Reset plan selection if in auto-select mode
|
// Reset plan selection if in auto-select mode
|
||||||
if (!this.planSelect?.value) {
|
if (!this.planSelect?.value) {
|
||||||
const cpus = parseInt(this.cpuRange.value);
|
const cpus = parseInt(this.cpuRange.value);
|
||||||
const memory = parseInt(this.memoryRange.value);
|
const memory = parseInt(this.memoryRange.value);
|
||||||
const storage = parseInt(this.storageRange.value);
|
const storage = parseInt(this.storageRange.value);
|
||||||
|
const instances = parseInt(this.instancesRange.value);
|
||||||
const serviceLevel = document.querySelector('input[name="serviceLevel"]:checked')?.value;
|
const serviceLevel = document.querySelector('input[name="serviceLevel"]:checked')?.value;
|
||||||
|
|
||||||
if (!serviceLevel) return;
|
if (!serviceLevel) return;
|
||||||
|
@ -426,7 +510,7 @@ Please contact me with next steps for ordering this configuration.`;
|
||||||
const matchedPlan = this.findBestMatchingPlan(cpus, memory, serviceLevel);
|
const matchedPlan = this.findBestMatchingPlan(cpus, memory, serviceLevel);
|
||||||
|
|
||||||
if (matchedPlan) {
|
if (matchedPlan) {
|
||||||
this.showPlanDetails(matchedPlan, storage);
|
this.showPlanDetails(matchedPlan, storage, instances);
|
||||||
this.updateStatusMessage('Perfect match found!', 'success');
|
this.updateStatusMessage('Perfect match found!', 'success');
|
||||||
} else {
|
} else {
|
||||||
this.showNoMatch();
|
this.showNoMatch();
|
||||||
|
@ -439,7 +523,7 @@ Please contact me with next steps for ordering this configuration.`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show plan details in the UI
|
// Show plan details in the UI
|
||||||
showPlanDetails(plan, storage) {
|
showPlanDetails(plan, storage, instances) {
|
||||||
if (!this.selectedPlanDetails) return;
|
if (!this.selectedPlanDetails) return;
|
||||||
|
|
||||||
// Show plan details section
|
// Show plan details section
|
||||||
|
@ -456,16 +540,18 @@ Please contact me with next steps for ordering this configuration.`;
|
||||||
if (this.planDescription) this.planDescription.textContent = plan.compute_plan_group_description || '';
|
if (this.planDescription) this.planDescription.textContent = plan.compute_plan_group_description || '';
|
||||||
if (this.planCpus) this.planCpus.textContent = plan.vcpus;
|
if (this.planCpus) this.planCpus.textContent = plan.vcpus;
|
||||||
if (this.planMemory) this.planMemory.textContent = plan.ram + ' GB';
|
if (this.planMemory) this.planMemory.textContent = plan.ram + ' GB';
|
||||||
|
if (this.planInstances) this.planInstances.textContent = instances;
|
||||||
if (this.planServiceLevel) this.planServiceLevel.textContent = serviceLevel;
|
if (this.planServiceLevel) this.planServiceLevel.textContent = serviceLevel;
|
||||||
|
|
||||||
// Calculate pricing using storage price from the plan data
|
// Calculate pricing using storage price from the plan data
|
||||||
const computePriceValue = parseFloat(plan.compute_plan_price);
|
const computePriceValue = parseFloat(plan.compute_plan_price);
|
||||||
const servicePriceValue = parseFloat(plan.sla_price);
|
const servicePriceValue = parseFloat(plan.sla_price);
|
||||||
const managedServicePrice = computePriceValue + servicePriceValue;
|
const managedServicePricePerInstance = computePriceValue + servicePriceValue;
|
||||||
|
const managedServicePrice = managedServicePricePerInstance * instances;
|
||||||
|
|
||||||
// Use storage price from plan data or fallback to instance variable
|
// Use storage price from plan data or fallback to instance variable
|
||||||
const storageUnitPrice = plan.storage_price !== undefined ? parseFloat(plan.storage_price) : this.storagePrice;
|
const storageUnitPrice = plan.storage_price !== undefined ? parseFloat(plan.storage_price) : this.storagePrice;
|
||||||
const storagePriceValue = storage * storageUnitPrice;
|
const storagePriceValue = storage * storageUnitPrice * instances;
|
||||||
const totalPriceValue = managedServicePrice + storagePriceValue;
|
const totalPriceValue = managedServicePrice + storagePriceValue;
|
||||||
|
|
||||||
// Update pricing display
|
// Update pricing display
|
||||||
|
@ -481,6 +567,7 @@ Please contact me with next steps for ordering this configuration.`;
|
||||||
vcpus: plan.vcpus,
|
vcpus: plan.vcpus,
|
||||||
memory: plan.ram,
|
memory: plan.ram,
|
||||||
storage: storage,
|
storage: storage,
|
||||||
|
instances: instances,
|
||||||
serviceLevel: serviceLevel,
|
serviceLevel: serviceLevel,
|
||||||
totalPrice: totalPriceValue.toFixed(2)
|
totalPrice: totalPriceValue.toFixed(2)
|
||||||
};
|
};
|
||||||
|
|
|
@ -176,8 +176,8 @@
|
||||||
</label>
|
</label>
|
||||||
<input type="range" class="form-range" id="cpuRange" min="1" max="32" value="2" step="1">
|
<input type="range" class="form-range" id="cpuRange" min="1" max="32" value="2" step="1">
|
||||||
<div class="d-flex justify-content-between text-muted small">
|
<div class="d-flex justify-content-between text-muted small">
|
||||||
<span>1</span>
|
<span id="cpuMinDisplay">1</span>
|
||||||
<span>32</span>
|
<span id="cpuMaxDisplay">32</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -189,8 +189,8 @@
|
||||||
</label>
|
</label>
|
||||||
<input type="range" class="form-range" id="memoryRange" min="1" max="128" value="4" step="1">
|
<input type="range" class="form-range" id="memoryRange" min="1" max="128" value="4" step="1">
|
||||||
<div class="d-flex justify-content-between text-muted small">
|
<div class="d-flex justify-content-between text-muted small">
|
||||||
<span>1 GB</span>
|
<span id="memoryMinDisplay">1 GB</span>
|
||||||
<span>128 GB</span>
|
<span id="memoryMaxDisplay">128 GB</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -202,8 +202,21 @@
|
||||||
</label>
|
</label>
|
||||||
<input type="range" class="form-range" id="storageRange" min="10" max="1000" value="20" step="10">
|
<input type="range" class="form-range" id="storageRange" min="10" max="1000" value="20" step="10">
|
||||||
<div class="d-flex justify-content-between text-muted small">
|
<div class="d-flex justify-content-between text-muted small">
|
||||||
<span>10 GB</span>
|
<span id="storageMinDisplay">10 GB</span>
|
||||||
<span>1000 GB</span>
|
<span id="storageMaxDisplay">1000 GB</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Instances Slider -->
|
||||||
|
<div class="mb-4">
|
||||||
|
<label for="instancesRange" class="form-label d-flex justify-content-between">
|
||||||
|
<span>Instances</span>
|
||||||
|
<span class="fw-bold" id="instancesValue">1</span>
|
||||||
|
</label>
|
||||||
|
<input type="range" class="form-range" id="instancesRange" min="1" max="1" value="1" step="1">
|
||||||
|
<div class="d-flex justify-content-between text-muted small">
|
||||||
|
<span id="instancesMinDisplay">1</span>
|
||||||
|
<span id="instancesMaxDisplay">1</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -255,15 +268,22 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<div class="col-4">
|
<div class="col-3">
|
||||||
<small class="text-muted">vCPUs</small>
|
<small class="text-muted">vCPUs</small>
|
||||||
<div class="fw-bold" id="planCpus"></div>
|
<div class="fw-bold" id="planCpus"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="col-3">
|
||||||
<small class="text-muted">Memory</small>
|
<small class="text-muted">Memory</small>
|
||||||
<div class="fw-bold" id="planMemory"></div>
|
<div class="fw-bold" id="planMemory"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="col-3">
|
||||||
|
<small class="text-muted">Instances</small>
|
||||||
|
<div class="fw-bold" id="planInstances"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-12">
|
||||||
<small class="text-muted">Service Level</small>
|
<small class="text-muted">Service Level</small>
|
||||||
<div class="fw-bold">
|
<div class="fw-bold">
|
||||||
<a href="https://products.vshn.ch/service_levels.html" target="_blank" class="text-decoration-none" id="planServiceLevel"></a>
|
<a href="https://products.vshn.ch/service_levels.html" target="_blank" class="text-decoration-none" id="planServiceLevel"></a>
|
||||||
|
|
|
@ -369,6 +369,8 @@ def generate_pricing_data(offering):
|
||||||
"sla_price": sla_price,
|
"sla_price": sla_price,
|
||||||
"final_price": final_price,
|
"final_price": final_price,
|
||||||
"storage_price": storage_price_data.get(currency, 0),
|
"storage_price": storage_price_data.get(currency, 0),
|
||||||
|
"ha_replica_min": appcat_price.ha_replica_min,
|
||||||
|
"ha_replica_max": appcat_price.ha_replica_max,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue