instance launching (fake)
This commit is contained in:
@@ -315,9 +315,25 @@
|
||||
<div class="step-pane" id="step4">
|
||||
<h5 class="mb-4">Port Configuration</h5>
|
||||
<div class="mb-3">
|
||||
<label for="port" class="form-label">Port Number <span class="text-danger">*</span></label>
|
||||
<label for="port" class="form-label">Internal Port Number <span class="text-danger">*</span></label>
|
||||
<input type="number" class="form-control" id="port" required min="1024" max="65535">
|
||||
<div class="form-text">Ports below 1024 are reserved for system use. Suggested port: <span id="suggestedPort">3000</span></div>
|
||||
<div class="form-text">Ports below 1024 are reserved for system use. Ports are automatically assigned by the system but you can change it if you want.</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Web Addresses <span class="text-danger">*</span></label>
|
||||
<div id="webAddressesContainer">
|
||||
<div class="input-group mb-2">
|
||||
<span class="input-group-text">https://</span>
|
||||
<input type="text" class="form-control web-address" required placeholder="your-domain.com">
|
||||
<button type="button" class="btn btn-outline-danger remove-address" onclick="removeWebAddress(this)" style="display: none;">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" onclick="addWebAddress()">
|
||||
<i class="fas fa-plus"></i> Add Another Address
|
||||
</button>
|
||||
<div class="form-text">Enter the domain names where your instance will be accessible</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -367,12 +383,36 @@
|
||||
|
||||
<!-- Step 6 -->
|
||||
<div class="step-pane" id="step6">
|
||||
<h4>Launch</h4>
|
||||
<p class="text-muted">Ready to launch your instance!</p>
|
||||
<div class="text-center">
|
||||
<i class="fas fa-rocket fa-4x mb-4" style="color: var(--primary-color);"></i>
|
||||
<h4>Ready to Launch!</h4>
|
||||
<p class="text-muted mb-4">Review your instance configuration before launching</p>
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title mb-3">Instance Configuration</h5>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<p><strong>Repository:</strong> <span id="reviewRepo"></span></p>
|
||||
<p><strong>Branch:</strong> <span id="reviewBranch"></span></p>
|
||||
<p><strong>Company:</strong> <span id="reviewCompany"></span></p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<p><strong>Port:</strong> <span id="reviewPort"></span></p>
|
||||
<p><strong>Web Addresses:</strong> <span id="reviewWebAddresses"></span></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-primary btn-lg" onclick="launchInstance()">
|
||||
<i class="fas fa-rocket me-2"></i> Launch Instance
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="modal-footer d-flex justify-content-end" id="launchStepsFooter">
|
||||
<button type="button" class="btn btn-secondary" onclick="previousStep()">
|
||||
<i class="fas fa-arrow-left me-1"></i> Previous
|
||||
</button>
|
||||
@@ -470,6 +510,16 @@
|
||||
font-size: 0.875rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end !important;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.modal-footer button {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Edit Instance Modal -->
|
||||
@@ -1290,13 +1340,25 @@ function updateStepDisplay() {
|
||||
item.classList.toggle('completed', step < currentStep);
|
||||
});
|
||||
|
||||
// Update buttons
|
||||
const prevButton = document.querySelector('.modal-footer .btn-secondary');
|
||||
const nextButton = document.querySelector('.modal-footer .btn-primary');
|
||||
// Get the modal footer
|
||||
const modalFooter = document.getElementById('launchStepsFooter');
|
||||
const prevButton = modalFooter.querySelector('.btn-secondary');
|
||||
const nextButton = modalFooter.querySelector('.btn-primary');
|
||||
|
||||
// Always show the footer
|
||||
modalFooter.style.display = 'block';
|
||||
|
||||
// Show/hide Previous button based on step
|
||||
prevButton.style.display = currentStep === 1 ? 'none' : 'inline-block';
|
||||
nextButton.innerHTML = currentStep === totalSteps ? 'Launch Instance' : 'Next <i class="fas fa-arrow-right ms-1"></i>';
|
||||
|
||||
// Show/hide Next button based on step
|
||||
if (currentStep === totalSteps) {
|
||||
nextButton.style.display = 'none';
|
||||
} else {
|
||||
nextButton.style.display = 'inline-block';
|
||||
nextButton.innerHTML = 'Next <i class="fas fa-arrow-right ms-1"></i>';
|
||||
}
|
||||
|
||||
// If we're on step 4, get the next available port
|
||||
if (currentStep === 4) {
|
||||
getNextAvailablePort();
|
||||
@@ -1310,13 +1372,18 @@ function nextStep() {
|
||||
if (currentStep === 3 && !validateStep3()) {
|
||||
return;
|
||||
}
|
||||
if (currentStep === 4 && !validateStep4()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentStep < totalSteps) {
|
||||
currentStep++;
|
||||
updateStepDisplay();
|
||||
} else {
|
||||
// Handle final step (launch instance)
|
||||
launchInstance();
|
||||
|
||||
// Update review section if we're moving to the final step
|
||||
if (currentStep === totalSteps) {
|
||||
updateReviewSection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1620,5 +1687,142 @@ function validateStep3() {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Function to validate step 4
|
||||
function validateStep4() {
|
||||
const port = document.getElementById('port').value;
|
||||
const webAddresses = document.querySelectorAll('.web-address');
|
||||
|
||||
// Validate port
|
||||
if (!port || port < 1024 || port > 65535) {
|
||||
alert('Please enter a valid port number between 1024 and 65535');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate web addresses
|
||||
if (webAddresses.length === 0) {
|
||||
alert('Please add at least one web address');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Basic domain validation for each address
|
||||
const domainRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9](?:\.[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9])*\.[a-zA-Z]{2,}$/;
|
||||
for (const address of webAddresses) {
|
||||
if (!address.value) {
|
||||
alert('Please fill in all web addresses');
|
||||
return false;
|
||||
}
|
||||
if (!domainRegex.test(address.value)) {
|
||||
alert(`Please enter a valid domain name for: ${address.value}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for duplicate addresses
|
||||
const addresses = Array.from(webAddresses).map(addr => addr.value.toLowerCase());
|
||||
const uniqueAddresses = new Set(addresses);
|
||||
if (addresses.length !== uniqueAddresses.size) {
|
||||
alert('Please remove duplicate web addresses');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Function to add a new web address input
|
||||
function addWebAddress() {
|
||||
const container = document.getElementById('webAddressesContainer');
|
||||
const newAddress = document.createElement('div');
|
||||
newAddress.className = 'input-group mb-2';
|
||||
newAddress.innerHTML = `
|
||||
<span class="input-group-text">https://</span>
|
||||
<input type="text" class="form-control web-address" required placeholder="your-domain.com">
|
||||
<button type="button" class="btn btn-outline-danger remove-address" onclick="removeWebAddress(this)">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
`;
|
||||
container.appendChild(newAddress);
|
||||
|
||||
// Show remove buttons if there's more than one address
|
||||
updateRemoveButtons();
|
||||
}
|
||||
|
||||
// Function to remove a web address input
|
||||
function removeWebAddress(button) {
|
||||
button.closest('.input-group').remove();
|
||||
updateRemoveButtons();
|
||||
}
|
||||
|
||||
// Function to update remove buttons visibility
|
||||
function updateRemoveButtons() {
|
||||
const addresses = document.querySelectorAll('.web-address');
|
||||
const removeButtons = document.querySelectorAll('.remove-address');
|
||||
|
||||
// Show remove buttons only if there's more than one address
|
||||
removeButtons.forEach(button => {
|
||||
button.style.display = addresses.length > 1 ? 'block' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// Function to get all web addresses
|
||||
function getAllWebAddresses() {
|
||||
return Array.from(document.querySelectorAll('.web-address')).map(input => input.value);
|
||||
}
|
||||
|
||||
// Function to update the review section
|
||||
function updateReviewSection() {
|
||||
// Get all the values
|
||||
const repo = document.getElementById('giteaRepoSelect').value;
|
||||
const branch = document.getElementById('giteaBranchSelect').value;
|
||||
const company = document.getElementById('companyName').value;
|
||||
const port = document.getElementById('port').value;
|
||||
const webAddresses = Array.from(document.querySelectorAll('.web-address'))
|
||||
.map(input => input.value)
|
||||
.join(', ');
|
||||
|
||||
// Update the review section
|
||||
document.getElementById('reviewRepo').textContent = repo;
|
||||
document.getElementById('reviewBranch').textContent = branch;
|
||||
document.getElementById('reviewCompany').textContent = company;
|
||||
document.getElementById('reviewPort').textContent = port;
|
||||
document.getElementById('reviewWebAddresses').textContent = webAddresses;
|
||||
}
|
||||
|
||||
// Function to launch the instance
|
||||
function launchInstance() {
|
||||
// Collect all the data
|
||||
const instanceData = {
|
||||
repository: document.getElementById('giteaRepoSelect').value,
|
||||
branch: document.getElementById('giteaBranchSelect').value,
|
||||
company: {
|
||||
name: document.getElementById('companyName').value,
|
||||
industry: document.getElementById('industry').value,
|
||||
streetAddress: document.getElementById('streetAddress').value,
|
||||
city: document.getElementById('city').value,
|
||||
state: document.getElementById('state').value,
|
||||
zipCode: document.getElementById('zipCode').value,
|
||||
country: document.getElementById('country').value,
|
||||
website: document.getElementById('website').value,
|
||||
email: document.getElementById('email').value,
|
||||
phone: document.getElementById('phone').value,
|
||||
description: document.getElementById('companyDescription').value
|
||||
},
|
||||
port: document.getElementById('port').value,
|
||||
webAddresses: Array.from(document.querySelectorAll('.web-address')).map(input => input.value),
|
||||
colors: {
|
||||
primary: document.getElementById('primaryColor').value,
|
||||
secondary: document.getElementById('secondaryColor').value
|
||||
}
|
||||
};
|
||||
|
||||
// Store the data in sessionStorage
|
||||
sessionStorage.setItem('instanceLaunchData', JSON.stringify(instanceData));
|
||||
|
||||
// Close the modal
|
||||
launchStepsModal.hide();
|
||||
|
||||
// Redirect to the launch progress page
|
||||
window.location.href = '/instances/launch-progress';
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user