Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redesign user settings UI #1042

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 4 additions & 38 deletions server/crashmanager/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,31 +178,6 @@ class Meta:


class UserSettingsForm(ModelForm):
helper = FormHelper()
helper.layout = Layout(
"defaultToolsFilter",
Row(
Field("defaultProviderId", wrapper_class="col-md-6"),
Field("defaultTemplateId", wrapper_class="col-md-6"),
),
"email",
HTML("""<p><strong>Subscribe to notifications:</strong></p>"""),
"inaccessible_bug",
"coverage_drop",
"bucket_hit",
"tasks_failed",
Submit("submit", "Save settings", css_class="btn btn-danger"),
)
defaultToolsFilter = ModelMultipleChoiceField(
queryset=Tool.objects.all(),
label="Select the tools you would like to include in your default views:",
widget=CheckboxSelectMultiple(),
required=False,
)
defaultProviderId = ModelChoiceField(
queryset=BugProvider.objects.all(), label="Default Provider:", empty_label=None
)
defaultTemplateId = ChoiceField(label="Default Template:")
email = EmailField(label="Email:")

class Meta:
Expand All @@ -220,17 +195,6 @@ class Meta:
def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user", None)
super().__init__(*args, **kwargs)

self.fields["defaultTemplateId"].choices = list(
dict.fromkeys(
[
(t.pk, f"{p.classname}: {t}")
for p in BugProvider.objects.all()
for t in p.getInstance().getTemplateList()
]
)
)

instance = kwargs.get("instance", None)
if instance:
self.initial["email"] = instance.user.email
Expand All @@ -239,8 +203,10 @@ def __init__(self, *args, **kwargs):
self.fields["email"].required = False
self.fields["email"].widget.attrs["readonly"] = True

self.fields["defaultToolsFilter"].required = False

def clean_defaultToolsFilter(self):
data = self.cleaned_data["defaultToolsFilter"]
data = self.cleaned_data.get("defaultToolsFilter", None)
if (
self.user
and list(self.user.defaultToolsFilter.all()) != list(data)
Expand All @@ -252,7 +218,7 @@ def clean_defaultToolsFilter(self):
return data

def clean_defaultProviderId(self):
data = self.cleaned_data["defaultProviderId"].id
data = self.cleaned_data["defaultProviderId"]
return data

def save(self, *args, **kwargs):
Expand Down
41 changes: 37 additions & 4 deletions server/crashmanager/templates/usersettings.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{% extends 'layouts/layout_base.html' %}
{% load crispy_forms_tags %}

{% block title %}User Settings{% endblock title %}

Expand All @@ -8,19 +7,53 @@
<div class="panel panel-default">
<div class="panel-heading"><i class="bi bi-gear-fill"></i> User Settings</div>
<div class="panel-body">
<form method="post">
<form method="post" class="block">
{% csrf_token %}
{% crispy form %}

<usersettingsform
:default-tools-options="[
{% for tool in defaultToolsFilterChoices %}
{ code: '{{ tool.id }}', name: '{{ tool.name }}' },
{% endfor %}
]"
:default-tools-selected="[
{% for tool in defaultToolsFilter %}
{ code: '{{ tool.id }}', name: '{{ tool.name }}' },
{% endfor %}
]"
:default-provider-options="[
{% for provider in defaultProviderChoices %}
{ id: '{{ provider.id }}', name: '{{ provider.hostname }}' },
{% endfor %}
]"
:default-provider-selected="{{ user.defaultProviderId }}"
:default-template-options="[
{% for template in defaultTemplateChoices %}
{ id: {{ template.0 }}, name: '{{ template.1 }}' },
{% endfor %}
]"
:default-template-selected="{{ user.defaultTemplateId }}"
initial-email="{{ email }}"
:allow-email-edit="{{ allow_email_edit|yesno:'true,false' }}"
:subscribe-notification-options="[
{% for notification in notificationChoices %}
{ code: '{{ notification.id }}', name: '{{ notification.label }}', selected: {{ notification.initial|yesno:'true,false' }} },
{% endfor %}
]"
:form-errors="{{form_errors}}"
/>

</form>
</div>
</div>

{% if bugzilla_providers %}
<div class="panel panel-default">
<div class="panel-heading"><i class="bi bi-gear-fill"></i> Bugzilla Providers Settings</div>
<div class="panel-body">
Provide API Keys to authenticate calls to your Bugzilla Providers on this browser.
{% for p in bugzilla_providers %}
<providerkey :provider-id="{{ p.pk }}" provider-hostname="{{ p.hostname }}"></providerkey>
<providerkey :provider-id="{{ p.pk }}" provider-hostname="{{ p.hostname }}"></providerkey>
{% endfor %}
</div>
</div>
Expand Down
52 changes: 49 additions & 3 deletions server/crashmanager/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from wsgiref.util import FileWrapper

from django.conf import settings as django_settings
from django.conf import settings as djangosettings
from django.core.exceptions import FieldError, PermissionDenied, SuspiciousOperation
from django.db.models import F, Q
from django.db.models.aggregates import Count, Min
Expand Down Expand Up @@ -1666,10 +1667,55 @@ def get_object(self):

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["bugzilla_providers"] = BugProvider.objects.filter(
classname="BugzillaProvider"
user_object = self.get_object()

# Prepare form errors if any
form = self.get_form()
form_errors = {field: errors for field, errors in form.errors.items()}

# Prepare all form-related data
context.update(
{
"defaultToolsFilter": user_object.defaultToolsFilter.all(),
"defaultToolsFilterChoices": Tool.objects.all(),
"defaultProviderChoices": BugProvider.objects.all(),
"defaultTemplateChoices": [
(t.pk, f"{p.classname}: {t}")
for p in BugProvider.objects.all()
for t in p.getInstance().getTemplateList()
],
"bugzilla_providers": BugProvider.objects.filter(
classname="BugzillaProvider"
),
"user": user_object,
"email": self.request.user.email,
"allow_email_edit": djangosettings.ALLOW_EMAIL_EDITION,
"form_errors": form_errors,
"notificationChoices": [
{
"id": "inaccessible_bug",
"label": "Inaccessible Bug",
"initial": user_object.inaccessible_bug,
},
{
"id": "coverage_drop",
"label": "Coverage Drop",
"initial": user_object.coverage_drop,
},
{
"id": "bucket_hit",
"label": "Bucket Hit",
"initial": user_object.bucket_hit,
},
{
"id": "tasks_failed",
"label": "Tasks Failed",
"initial": user_object.tasks_failed,
},
],
}
)
context["user"] = self.request.user

return context


Expand Down
11 changes: 11 additions & 0 deletions server/frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions server/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"sweetalert": "^2.1.2",
"vue": "^3.4.21",
"vue-loading-overlay": "^6.0.3",
"vue-multiselect": "^3.1.0",
"vue-router": "^4.3.0"
},
"devDependencies": {
Expand Down
3 changes: 3 additions & 0 deletions server/frontend/src/components/ProviderKey.vue
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,7 @@ export default defineComponent({
.mt-light {
margin-top: 0.5rem;
}
.btn {
margin-left: 0.8rem;
}
</style>
Loading