October feature list #226
4 changed files with 73 additions and 5 deletions
|
|
@ -93,5 +93,7 @@
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
<!-- Ybug code end -->
|
<!-- Ybug code end -->
|
||||||
|
{% block extra_js %}
|
||||||
|
{% endblock extra_js %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -93,3 +93,14 @@
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
{% block extra_js %}
|
||||||
|
{% if wildcard_dns and organization_namespace %}
|
||||||
|
<script>
|
||||||
|
const fqdnConfig = {
|
||||||
|
wildcardDns: '{{ wildcard_dns }}',
|
||||||
|
namespace: '{{ organization_namespace }}'
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script defer src="{% static "js/fqdn.js" %}"></script>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock extra_js %}
|
||||||
|
|
|
||||||
|
|
@ -132,12 +132,25 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
|
||||||
def get_instance_form(self):
|
def get_instance_form(self):
|
||||||
if not self.context_object or not self.context_object.model_form_class:
|
if not self.context_object or not self.context_object.model_form_class:
|
||||||
return None
|
return None
|
||||||
return self.context_object.model_form_class(
|
|
||||||
data=self.request.POST if self.request.method == "POST" else None,
|
|
||||||
initial = {
|
initial = {
|
||||||
"organization": self.request.organization,
|
"organization": self.request.organization,
|
||||||
"context": self.context_object,
|
"context": self.context_object,
|
||||||
},
|
}
|
||||||
|
|
||||||
|
# Pre-populate FQDN field if it exists and control plane has wildcard DNS
|
||||||
|
form_class = self.context_object.model_form_class
|
||||||
|
if (
|
||||||
|
"spec.parameters.service.fqdn" in form_class.base_fields
|
||||||
|
and self.context_object.control_plane.wildcard_dns
|
||||||
|
):
|
||||||
|
# Generate initial FQDN: instancename-namespace.wildcard_dns
|
||||||
|
# We'll set a placeholder that JavaScript will replace dynamically
|
||||||
|
initial["spec.parameters.service.fqdn"] = ""
|
||||||
|
|
||||||
|
return form_class(
|
||||||
|
data=self.request.POST if self.request.method == "POST" else None,
|
||||||
|
initial=initial,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
|
|
@ -146,6 +159,10 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
|
||||||
context["has_control_planes"] = self.planes.exists()
|
context["has_control_planes"] = self.planes.exists()
|
||||||
context["selected_plane"] = self.selected_plane
|
context["selected_plane"] = self.selected_plane
|
||||||
context["service_form"] = self.get_instance_form()
|
context["service_form"] = self.get_instance_form()
|
||||||
|
# Pass data for dynamic FQDN generation
|
||||||
|
if self.selected_plane and self.selected_plane.wildcard_dns:
|
||||||
|
context["wildcard_dns"] = self.selected_plane.wildcard_dns
|
||||||
|
context["organization_namespace"] = self.request.organization.namespace
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
|
|
||||||
38
src/servala/static/js/fqdn.js
Normal file
38
src/servala/static/js/fqdn.js
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
|
||||||
|
const initializeFqdnGeneration = () => {
|
||||||
|
const nameField = document.querySelector('input[name="name"]');
|
||||||
|
const fqdnField = document.querySelector('label[for="id_spec.parameters.service.fqdn"] + div input.array-item-input');
|
||||||
|
|
||||||
|
if (nameField && fqdnField) {
|
||||||
|
const generateFqdn = (instanceName) => {
|
||||||
|
if (!instanceName) return '';
|
||||||
|
return `${instanceName}-${fqdnConfig.namespace}.${fqdnConfig.wildcardDns}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newNameField = nameField.cloneNode(true);
|
||||||
|
nameField.parentNode.replaceChild(newNameField, nameField);
|
||||||
|
const newFqdnField = fqdnField.cloneNode(true);
|
||||||
|
fqdnField.parentNode.replaceChild(newFqdnField, fqdnField);
|
||||||
|
|
||||||
|
newNameField.addEventListener('input', function() {
|
||||||
|
if (!newFqdnField.dataset.manuallyEdited) {
|
||||||
|
newFqdnField.value = generateFqdn(this.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
newFqdnField.addEventListener('input', function() {
|
||||||
|
this.dataset.manuallyEdited = 'true';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (newNameField.value && !newFqdnField.value) {
|
||||||
|
newFqdnField.value = generateFqdn(newNameField.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', initializeFqdnGeneration);
|
||||||
|
document.body.addEventListener('htmx:afterSwap', function(event) {
|
||||||
|
if (event.detail.target.id === 'service-form') {
|
||||||
|
initializeFqdnGeneration();
|
||||||
|
}
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue