From 401128d5a5b322e1ec0ee9251545327c804607be Mon Sep 17 00:00:00 2001
From: dnns01 <github@dnns01.de>
Date: Fri, 3 Dec 2021 23:58:20 +0100
Subject: [PATCH] Change command add/edit/remove

---
 strolchibot/forms.py                     |  14 ++-
 strolchibot/static/js/scripts.js         |  22 +++++
 strolchibot/templates/commands/edit.html |  10 +++
 strolchibot/templates/commands/list.html |  41 +++++++++
 strolchibot/urls.py                      |   6 +-
 strolchibot/views.py                     | 110 ++++++++++++++---------
 6 files changed, 157 insertions(+), 46 deletions(-)
 create mode 100644 strolchibot/templates/commands/edit.html
 create mode 100644 strolchibot/templates/commands/list.html

diff --git a/strolchibot/forms.py b/strolchibot/forms.py
index daf9125..6e49630 100644
--- a/strolchibot/forms.py
+++ b/strolchibot/forms.py
@@ -1,6 +1,6 @@
 from django import forms
 
-from .models import Config
+from .models import Config, Command
 
 
 class BaseModelForm(forms.ModelForm):
@@ -45,3 +45,15 @@ def add_classes(fields):
         else:
             field.widget.attrs['class'] = ' w3-input '
         field.widget.attrs['placeholder'] = field.label
+
+
+class CommandForm(BaseModelForm):
+    class Meta:
+        model = Command
+        exclude = ['active']
+
+# class ClipEditForm(BaseModelForm):
+#     class Meta:
+#         model = Clip
+#         fields = ['custom_title', 'tags']
+#         widgets = {'tags': forms.widgets.CheckboxSelectMultiple()}
diff --git a/strolchibot/static/js/scripts.js b/strolchibot/static/js/scripts.js
index c92f802..b17e315 100644
--- a/strolchibot/static/js/scripts.js
+++ b/strolchibot/static/js/scripts.js
@@ -75,3 +75,25 @@ function setLabelClass(input) {
         label.classList.remove("w3-multiple-choice-checked")
     }
 }
+
+
+function commandSetActive(checkbox, command) {
+    const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
+    let payload = {
+        command: command,
+        active: checkbox.checked
+    };
+
+    console.log(payload);
+    console.log(JSON.stringify(payload));
+
+    fetch('/commands/active', {
+        method: 'POST',
+        headers: {
+            'Content-Type': 'application/json',
+            'X-CSRFToken': csrftoken
+        },
+        credentials: 'same-origin',
+        body: JSON.stringify(payload)
+    }).then(response => response.json()).then(data => checkbox.checked = data.active);
+}
\ No newline at end of file
diff --git a/strolchibot/templates/commands/edit.html b/strolchibot/templates/commands/edit.html
new file mode 100644
index 0000000..9d9e724
--- /dev/null
+++ b/strolchibot/templates/commands/edit.html
@@ -0,0 +1,10 @@
+{% extends 'layout.html' %}
+
+{% block content %}
+    <form method="post">
+        {#        <input type="hidden" id="id-active" value="{{ form.name }}" name="form-active"/>#}
+        {% csrf_token %}
+        {% include 'card_form.html' %}
+        <input type="submit" value="Add/Save" class="w3-button w3-strolchpink w3-block">
+    </form>
+{% endblock %}
\ No newline at end of file
diff --git a/strolchibot/templates/commands/list.html b/strolchibot/templates/commands/list.html
new file mode 100644
index 0000000..7f3d99c
--- /dev/null
+++ b/strolchibot/templates/commands/list.html
@@ -0,0 +1,41 @@
+{% extends 'layout.html' %}
+
+{% block content %}
+    {% csrf_token %}
+    <div class="w3-card w3-white">
+        <div>
+            <a href="{% url "commands_new" %}" class="w3-button w3-strolchpink w3-right w3-margin"><i
+                    class="fas fa-plus"></i> Add Command</a>
+        </div>
+        <div class="w3-padding">
+            <table class="w3-table w3-striped">
+                <tbody>
+                <tr>
+                    <th>Command</th>
+                    <th>Texts</th>
+                    <th>Permission</th>
+                    <th>Active</th>
+                    <th></th>
+                    <th></th>
+                </tr>
+                {% for command in commands %}
+                    <tr>
+                        <td>{{ command.command }}</td>
+                        <td>{{ command.text }}</td>
+                        <td>Everyone</td>
+                        <td>
+                            <label class="switch">
+                                <input class="w3-switch" type="checkbox" {% if command.active %}checked{% endif %}
+                                       onchange="commandSetActive(this, '{{ command.command }}')">
+                                <span class="slider"></span>
+                            </label>
+                        </td>
+                        <td><a href="{% url "commands_remove" command.id %}"><em class="fas fa-trash-alt"></em></a></td>
+                        <td><a href="{% url "commands_edit" command.id %}"><em class="fas fa-pencil-alt"></em></a></td>
+                    </tr>
+                {% endfor %}
+                </tbody>
+            </table>
+        </div>
+    </div>
+{% endblock %}
\ No newline at end of file
diff --git a/strolchibot/urls.py b/strolchibot/urls.py
index 2f521cb..babb13d 100644
--- a/strolchibot/urls.py
+++ b/strolchibot/urls.py
@@ -27,8 +27,10 @@ urlpatterns = [
     path('logout/', views.logout, name="logout"),
     path('login/redirect/', views.login_redirect, name="login_redirect"),
     path('commands/', views.commands, name="commands"),
-    path('commands/remove/<int:id>', views.commands_remove, name="commands_remove"),
-    path('commands/activate/<int:id>', views.commands_activate, name="commands_activate"),
+    path('commands/new', views.commands_new, name="commands_new"),
+    path('commands/remove/<int:command_id>', views.commands_remove, name="commands_remove"),
+    path('commands/edit/<int:command_id>', views.commands_edit, name="commands_edit"),
+    path('commands/active', views.commands_set_active, name="commands_set_activate"),
     path('klassenbuch/', views.klassenbuch, name="klassenbuch"),
     path('klassenbuch/remove/<int:id>', views.klassenbuch_remove, name="klassenbuch_remove"),
     path('timers/', views.timers, name="timers"),
diff --git a/strolchibot/views.py b/strolchibot/views.py
index 8be46cf..86a7cfd 100644
--- a/strolchibot/views.py
+++ b/strolchibot/views.py
@@ -1,13 +1,14 @@
+import json
 import os
 
 import requests
 from django.contrib.auth import authenticate, login as django_login, logout as django_logout
 from django.contrib.auth.decorators import login_required
 from django.forms import modelformset_factory
-from django.http import Http404
-from django.shortcuts import render, redirect
+from django.http import Http404, JsonResponse, HttpResponse, HttpRequest
+from django.shortcuts import render, redirect, get_object_or_404
 
-from .forms import BaseModelForm, LinkProtectionConfigForm
+from .forms import BaseModelForm, LinkProtectionConfigForm, CommandForm
 from .models import Command, Klassenbuch, Timer, Config, LinkPermit, LinkWhitelist, LinkBlacklist
 
 
@@ -15,46 +16,6 @@ def home(request):
     return render(request, "home.html", {"title": "Strolchibot"})
 
 
-@login_required(login_url="/login")
-def commands(request):
-    CommandsFormSet = modelformset_factory(Command, form=BaseModelForm, fields=("command", "text", "active"))
-    if request.method == "POST":
-        formset = CommandsFormSet(request.POST, request.FILES)
-        if formset.is_valid():
-            formset.save()
-
-    forms = {
-        "Basic Configuration": {
-            "display": "card",
-            "type": "formset",
-            "name": "commands",
-            "formset": CommandsFormSet(),
-            "remove_url": "commands_remove",
-            "activate_url": "commands_activate",
-            "collapsible": True,
-
-        },
-    }
-
-    return render(request, "form.html", {"title": "Commands", "forms": forms, "active": "commands"})
-
-
-@login_required(login_url="/login")
-def commands_remove(request, id):
-    Command.objects.filter(pk=id).delete()
-
-    return redirect("/commands")
-
-
-@login_required(login_url="/login")
-def commands_activate(request, id):
-    command = Command.objects.get(pk=id)
-    command.active = not command.active
-    command.save()
-
-    return redirect("/commands")
-
-
 @login_required(login_url="/login")
 def klassenbuch(request):
     KlassenbuchFormSet = modelformset_factory(Klassenbuch, form=BaseModelForm, fields=("name", "sticker"))
@@ -273,3 +234,66 @@ def exchange_code(code):
                 "refresh_token": credentials["refresh_token"]}
 
     return None
+
+
+# <editor-fold desc="Commands">
+@login_required(login_url="/login")
+def commands(request: HttpRequest) -> HttpResponse:
+    return render(request, "commands/list.html",
+                  {"title": "Commands", "commands": Command.objects.all(), "active": "commands"})
+
+
+@login_required(login_url="/login")
+def commands_new(request: HttpRequest) -> HttpResponse:
+    if request.method == "POST":
+        form = CommandForm(request.POST)
+
+        if form.is_valid():
+            form.save()
+            return redirect("/commands")
+
+    form = CommandForm()
+
+    return render(request, "commands/edit.html",
+                  {"title": "Commands", "form": {"form": form}})
+
+
+@login_required(login_url="/login")
+def commands_remove(request: HttpRequest, command_id: int) -> HttpResponse:
+    Command.objects.filter(pk=command_id).delete()
+
+    return redirect("/commands")
+
+
+@login_required(login_url="/login")
+def commands_edit(request: HttpRequest, command_id: int) -> HttpResponse:
+    command = get_object_or_404(Command, pk=command_id)
+
+    if request.method == "POST":
+        form = CommandForm(request.POST, instance=command)
+
+        if form.is_valid():
+            form.save()
+            return redirect("/commands")
+
+    form = CommandForm(instance=command)
+
+    return render(request, "commands/edit.html",
+                  {"title": "Commands", "form": {"form": form}})
+
+
+@login_required(login_url="/login")
+def commands_set_active(request: HttpRequest) -> JsonResponse:
+    if request.method == "POST":
+        try:
+            payload = json.loads(request.body)
+            command = get_object_or_404(Command, command=payload["command"])
+            command.active = payload["active"]
+            command.save()
+
+            return JsonResponse({"active": command.active})
+        except (json.decoder.JSONDecodeError, KeyError):
+            pass
+
+    raise Http404
+# </editor-fold>
-- 
GitLab