From 144e6116b55e96f8d87ddd46c70e2ca710cfe5dd Mon Sep 17 00:00:00 2001 From: jamesstottmoj Date: Mon, 2 Dec 2024 12:19:14 +0000 Subject: [PATCH] Added initial feedback form --- controlpanel/api/migrations/0048_feedback.py | 41 ++++++++++ controlpanel/api/models/__init__.py | 1 + controlpanel/api/models/feedback.py | 23 ++++++ controlpanel/frontend/forms.py | 10 +++ .../frontend/jinja2/feedback-create.html | 80 +++++++++++++++++++ .../frontend/jinja2/feedback-thanks.html | 12 +++ controlpanel/frontend/urls.py | 2 + controlpanel/frontend/views/__init__.py | 1 + controlpanel/frontend/views/feedback.py | 26 ++++++ 9 files changed, 196 insertions(+) create mode 100644 controlpanel/api/migrations/0048_feedback.py create mode 100644 controlpanel/api/models/feedback.py create mode 100644 controlpanel/frontend/jinja2/feedback-create.html create mode 100644 controlpanel/frontend/jinja2/feedback-thanks.html create mode 100644 controlpanel/frontend/views/feedback.py diff --git a/controlpanel/api/migrations/0048_feedback.py b/controlpanel/api/migrations/0048_feedback.py new file mode 100644 index 00000000..022b64ba --- /dev/null +++ b/controlpanel/api/migrations/0048_feedback.py @@ -0,0 +1,41 @@ +# Generated by Django 5.1.2 on 2024-11-29 15:32 + +# Third-party +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("api", "0047_app_cloud_platform_role_arn"), + ] + + operations = [ + migrations.CreateModel( + name="Feedback", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ( + "satisfaction_rating", + models.IntegerField( + choices=[ + (5, "Very satisfied"), + (4, "Satisfied"), + (3, "Neither satisfied or dissatisfied"), + (2, "Dissatisfied"), + (1, "Very dissatisfied"), + ] + ), + ), + ("suggestions", models.TextField()), + ], + options={ + "db_table": "control_panel_api_feedback", + }, + ), + ] diff --git a/controlpanel/api/models/__init__.py b/controlpanel/api/models/__init__.py index 4b49f607..81cd1f7a 100644 --- a/controlpanel/api/models/__init__.py +++ b/controlpanel/api/models/__init__.py @@ -8,6 +8,7 @@ from controlpanel.api.models.app import App from controlpanel.api.models.app_ip_allowlist import AppIPAllowList from controlpanel.api.models.apps3bucket import AppS3Bucket +from controlpanel.api.models.feedback import Feedback from controlpanel.api.models.iam_managed_policy import IAMManagedPolicy from controlpanel.api.models.parameter import Parameter from controlpanel.api.models.policys3bucket import PolicyS3Bucket diff --git a/controlpanel/api/models/feedback.py b/controlpanel/api/models/feedback.py new file mode 100644 index 00000000..797aeaa3 --- /dev/null +++ b/controlpanel/api/models/feedback.py @@ -0,0 +1,23 @@ +# Third-party +from django.db import models + + +class Feedback(models.Model): + SATISFACTION_RATINGS = [ + (5, "Very satisfied"), + (4, "Satisfied"), + (3, "Neither satisfied or dissatisfied"), + (2, "Dissatisfied"), + (1, "Very dissatisfied"), + ] + + satisfaction_rating = models.IntegerField( + choices=SATISFACTION_RATINGS, + null=False, + blank=False, + ) + + suggestions = models.TextField() + + class Meta: + db_table = "control_panel_api_feedback" diff --git a/controlpanel/frontend/forms.py b/controlpanel/frontend/forms.py index c688ace2..65d2e93b 100644 --- a/controlpanel/frontend/forms.py +++ b/controlpanel/frontend/forms.py @@ -16,6 +16,7 @@ from controlpanel.api.models import ( QUICKSIGHT_EMBED_PERMISSION, App, + Feedback, S3Bucket, Tool, User, @@ -655,3 +656,12 @@ def grant_access(self): self.user.user_permissions.add(permission) else: self.user.user_permissions.remove(permission) + + +class FeedbackForm(forms.ModelForm): + class Meta: + model = Feedback + fields = [ + "satisfaction_rating", + "suggestions", + ] diff --git a/controlpanel/frontend/jinja2/feedback-create.html b/controlpanel/frontend/jinja2/feedback-create.html new file mode 100644 index 00000000..4a50d138 --- /dev/null +++ b/controlpanel/frontend/jinja2/feedback-create.html @@ -0,0 +1,80 @@ +{% from "error-message/macro.html" import govukErrorMessage %} +{% from "label/macro.html" import govukLabel %} +{% from "radios/macro.html" import govukRadios %} +{% from "includes/auth0-connections-form.html" import auth0_connections_form with context %} + + +{% extends "base.html" %} + +{% set page_title = "Feedback" %} + +{% block content %} +

Give feedback on the Analytical Platform

+ + +
+ {{ csrf_input }} + + {{ govukRadios({ + "name": "satisfaction_rating", + "fieldset": { + "legend": { + "text": "Satisfaction survey", + "classes": "govuk-fieldset__legend--l", + }, + }, + "items": [ + { + "value": 5, + "text": "Very satisfied", + "checked": form.satisfaction_rating.value() == "5" + }, + { + "value": 4, + "text": "Satisfied", + "checked": form.satisfaction_rating.value() == "4" + }, + { + "value": 3, + "text": "Neither satisfied or dissatisfied", + "checked": form.satisfaction_rating.value() == "3" + }, + { + "value": 2, + "text": "Dissatisfied", + "checked": form.satisfaction_rating.value() == "2" + }, + { + "value": 1, + "text": "Very dissatisfied", + "checked": form.satisfaction_rating.value() == "1" + }, + ], + "errorMessage": { "text": form.errors.get("satisfaction_rating") } if form.errors.get("satisfaction_rating") else {} + }) }} + + + +
+

+ +

+
+ Do not include personal or financial information, like your National Insurance number or credit card details. +
+ + {% if form.errors.get("suggestions") %} + {{ govukErrorMessage({"text": form.errors.get("suggestions")}) }} + {% endif %} + + +
+ + +
+ +
+
+{% endblock %} diff --git a/controlpanel/frontend/jinja2/feedback-thanks.html b/controlpanel/frontend/jinja2/feedback-thanks.html new file mode 100644 index 00000000..9bcbf5db --- /dev/null +++ b/controlpanel/frontend/jinja2/feedback-thanks.html @@ -0,0 +1,12 @@ +{% from "error-message/macro.html" import govukErrorMessage %} +{% from "includes/auth0-connections-form.html" import auth0_connections_form with context %} + + +{% extends "base.html" %} + +{% set page_title = "Thank you" %} + +{% block content %} +

Thank you for your feedback

+

Your feedback will help us improve the service.

+{% endblock %} diff --git a/controlpanel/frontend/urls.py b/controlpanel/frontend/urls.py index e5f15d1b..eabd5177 100644 --- a/controlpanel/frontend/urls.py +++ b/controlpanel/frontend/urls.py @@ -268,4 +268,6 @@ ), path("parameters//delete/", views.ParameterDelete.as_view(), name="delete-parameter"), path("quicksight/", views.QuicksightView.as_view(), name="quicksight"), + path("feedback/", views.CreateFeedback.as_view(), name="feedback-create"), + path("feedback/thanks", views.FeedbackThanks.as_view(), name="feedback-thanks"), ] diff --git a/controlpanel/frontend/views/__init__.py b/controlpanel/frontend/views/__init__.py index 46fd2cb3..255e0380 100644 --- a/controlpanel/frontend/views/__init__.py +++ b/controlpanel/frontend/views/__init__.py @@ -58,6 +58,7 @@ UpdateIAMManagedPolicyAccessLevel, WebappBucketList, ) +from controlpanel.frontend.views.feedback import CreateFeedback, FeedbackThanks from controlpanel.frontend.views.help import Help from controlpanel.frontend.views.ip_allowlist import ( IPAllowlistCreate, diff --git a/controlpanel/frontend/views/feedback.py b/controlpanel/frontend/views/feedback.py new file mode 100644 index 00000000..7c1d16bd --- /dev/null +++ b/controlpanel/frontend/views/feedback.py @@ -0,0 +1,26 @@ +# Third-party +from django.urls import reverse_lazy +from django.views.generic import TemplateView +from django.views.generic.edit import CreateView, FormMixin + +# First-party/Local +from controlpanel.api.models import Feedback +from controlpanel.frontend.forms import FeedbackForm +from controlpanel.oidc import OIDCLoginRequiredMixin + + +class CreateFeedback(OIDCLoginRequiredMixin, CreateView): + form_class = FeedbackForm + model = Feedback + template_name = "feedback-create.html" + + def get_success_url(self): + return reverse_lazy("feedback-thanks") + + def form_valid(self, form): + form.save() + return FormMixin.form_valid(self, form) + + +class FeedbackThanks(OIDCLoginRequiredMixin, TemplateView): + template_name = "feedback-thanks.html"