diff --git a/panel/src/panel/static/htmx.min.js b/panel/src/panel/static/htmx.min.js index e4006f42..76d10777 120000 --- a/panel/src/panel/static/htmx.min.js +++ b/panel/src/panel/static/htmx.min.js @@ -1 +1 @@ -/home/vg/src/Fediversity/nix/store/mwqqk0qmldzvv4xj9kq2lbah2flhc44z-source/dist/htmx.js \ No newline at end of file +/nix/store/mwqqk0qmldzvv4xj9kq2lbah2flhc44z-source/dist/htmx.js \ No newline at end of file diff --git a/panel/src/panel/static/style.sass b/panel/src/panel/static/style.sass index 53e52a36..f860ae38 100644 --- a/panel/src/panel/static/style.sass +++ b/panel/src/panel/static/style.sass @@ -3,3 +3,24 @@ body margin: 0 font-family: sans-serif box-sizing: border-box + +.loader + width: 48px + height: 48px + border: 5px solid #000 + border-bottom-color: #F34508 + border-radius: 50% + box-sizing: border-box + animation: rotation 1s linear infinite + display: inline-block + +@keyframes rotation + 0% { transform: rotate(0deg) } + 100% { transform: rotate(360deg) } + +#spinner-container + position: absolute + top: 50% + left: 50% + transform: translate(-50%, -50%) + display: block \ No newline at end of file diff --git a/panel/src/panel/templates/configuration_form.html b/panel/src/panel/templates/configuration_form.html index 474aa4f6..ffc78e3d 100644 --- a/panel/src/panel/templates/configuration_form.html +++ b/panel/src/panel/templates/configuration_form.html @@ -1,11 +1,23 @@ {% extends "base.html" %} {% block content %} -<form method="post" enctype="multipart/form-data" action="{% url 'configuration_form' %}"> +<form method="post" enctype="multipart/form-data" action="{% url 'save' %}"> {% csrf_token %} {{ form.as_p }} + <button id="deploy-button" class="button" + hx-post="{% url 'deployment_status' %}" + hx-trigger="click" + hx-indicator="#spinner-container" + hx-disabled-elt="this" + hx-swap="none" + name="deploy"> + Deploy + </button> - <button class="button" type="submit" name="deploy">Deploy</button> <button class="button" type="submit" name="save">Save</button> + + <div id="spinner-container" class="htmx-indicator"> + <span class="loader"></span> + </div> </form> {% endblock %} diff --git a/panel/src/panel/tests/test_configuration_form.py b/panel/src/panel/tests/test_configuration_form.py index a96d8441..805b0e34 100644 --- a/panel/src/panel/tests/test_configuration_form.py +++ b/panel/src/panel/tests/test_configuration_form.py @@ -13,7 +13,7 @@ class ConfigurationForm(TestCase): password=self.password ) - self.config_url = reverse('configuration_form') + self.config_url = reverse('save') def test_configuration_form_submission(self): config = Configuration.objects.create( @@ -36,12 +36,13 @@ class ConfigurationForm(TestCase): enable=True, mastodon_enable=True, ) - + print(form_data) response = self.client.post(self.config_url, data=form_data) self.assertEqual(response.status_code, 302) config.refresh_from_db() + print(config.parsed_value) self.assertTrue(config.parsed_value.enable) self.assertTrue(config.parsed_value.mastodon.enable) # this should not have changed diff --git a/panel/src/panel/urls.py b/panel/src/panel/urls.py index 2f0ba434..011a2843 100644 --- a/panel/src/panel/urls.py +++ b/panel/src/panel/urls.py @@ -26,4 +26,6 @@ urlpatterns = [ path("account/", views.AccountDetail.as_view(), name='account_detail'), path("services/", views.ServiceList.as_view(), name='service_list'), path("configuration/", views.ConfigurationForm.as_view(), name='configuration_form'), + path("deployment/status/", views.DeploymentStatus.as_view(), name='deployment_status'), + path("save/", views.Save.as_view(), name='save'), ] diff --git a/panel/src/panel/views.py b/panel/src/panel/views.py index 16d29849..6e45df92 100644 --- a/panel/src/panel/views.py +++ b/panel/src/panel/views.py @@ -1,6 +1,7 @@ from enum import Enum import json import subprocess +import os from django.urls import reverse_lazy from django.contrib.auth.mixins import LoginRequiredMixin @@ -9,9 +10,9 @@ from django.views.generic import TemplateView, DetailView from django.views.generic.edit import FormView from panel import models, settings +from panel import models from panel.configuration import forms - class Index(TemplateView): template_name = 'index.html' @@ -33,51 +34,12 @@ class ConfigurationForm(LoginRequiredMixin, FormView): success_url = reverse_lazy('configuration_form') form_class = forms.Form - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - return context - def get_object(self): """Get or create the configuration object for the current user""" obj, created = models.Configuration.objects.get_or_create( operator=self.request.user, ) - # Check for deploy button - if "deploy" in self.request.POST.keys(): - submission = obj.parsed_value.model_dump_json() - # FIXME: let the user specify these from the form (#190) - dummy_user = { - "initialUser": { - "displayName": "Testy McTestface", - "username": "test", - "password": "testtest", - "email": "test@test.com", - }, - } - # serialize back and forth now we still need to manually inject the dummy user - deployment = json.dumps(dummy_user | json.loads(submission)) - env = { - "PATH": settings.bin_path, - # pass in form info to our deployment - "DEPLOYMENT": deployment, - } - cmd = [ - "nix", - "develop", - # workaround to pass in info to nixops4 thru env vars, tho impure :( - "--extra-experimental-features", - "configurable-impure-env", - "--command", - "nixops4", - "apply", - "test", - ] - subprocess.run( - cmd, - cwd=settings.repo_dir, - env=env, - ) return obj # TODO(@fricklerhandwerk): @@ -120,9 +82,57 @@ class ConfigurationForm(LoginRequiredMixin, FormView): initial.update(self.convert_enums_to_names(config_dict)) return initial +class Save(ConfigurationForm): def form_valid(self, form): obj = self.get_object() obj.value = form.to_python().model_dump_json() obj.save() return super().form_valid(form) + +class DeploymentStatus(ConfigurationForm): + def form_valid(self, form): + obj = self.get_object() + obj.save() + + # Check for deploy button + if "deploy" in self.request.POST.keys(): + self.deployment(obj) + + return super().form_valid(form) + + def deployment(self, obj): + submission = obj.parsed_value.model_dump_json() + # FIXME: let the user specify these from the form (#190) + dummy_user = { + "initialUser": { + "displayName": "Testy McTestface", + "username": "test", + "password": "testtest", + "email": "test@test.com", + }, + } + # serialize back and forth now we still need to manually inject the dummy user + deployment = json.dumps(dummy_user | json.loads(submission)) + env = { + "PATH": settings.bin_path, + # pass in form info to our deployment + "DEPLOYMENT": deployment, + } + cmd = [ + "nix", + "develop", + "--extra-experimental-features", + "configurable-impure-env", + "--command", + "nixops4", + "apply", + "test", + ] + deployment_result = subprocess.run( + cmd, + cwd=settings.repo_dir, + env=env, + ) + print(deployment_result) + return deployment_result \ No newline at end of file