mirror of
https://github.com/jlengrand/bugsink.git
synced 2026-03-10 08:01:17 +00:00
82
projects/templates/projects/project_alerts_setup.html
Normal file
82
projects/templates/projects/project_alerts_setup.html
Normal file
@@ -0,0 +1,82 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}Alerts · {{ project.name }} · {{ site_title }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
|
||||
|
||||
<div class="flex items-center justify-center">
|
||||
|
||||
<div class="m-4 max-w-4xl flex-auto">
|
||||
|
||||
{% if messages %}
|
||||
<ul class="mb-4">
|
||||
{% for message in messages %}
|
||||
{# if we introduce different levels we can use{% message.level == DEFAULT_MESSAGE_LEVELS.SUCCESS %} #}
|
||||
<li class="bg-cyan-50 border-2 border-cyan-800 p-4 rounded-lg">{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<div class="flex">
|
||||
<h1 class="text-4xl mt-4 font-bold">{{ project.name }} · Alerts</h1>
|
||||
|
||||
<div class="ml-auto mt-6">
|
||||
<a class="font-bold text-slate-800 border-slate-500 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 bg-cyan-200 hover:bg-cyan-400 active:ring rounded-md" href="{% url "project_messaging_service_add" project_pk=project.pk %}">Add</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<form action="." method="post">
|
||||
{% csrf_token %}
|
||||
|
||||
<table class="w-full mt-8">
|
||||
<tbody>
|
||||
<thead>
|
||||
<tr class="bg-slate-200">
|
||||
<th class="w-full p-4 text-left text-xl" colspan="2">Messaging Services</th>
|
||||
</tr>
|
||||
|
||||
{% for service_config in service_configs %}
|
||||
<tr class="bg-white border-slate-200 border-b-2">
|
||||
<td class="w-full p-4">
|
||||
<div>
|
||||
<a href="{% url "project_messaging_service_edit" project_pk=project.pk service_pk=service_config.pk %}" class="text-xl text-cyan-500 font-bold">{{ service_config.display_name }}</a>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td class="p-4">
|
||||
<div class="flex justify-end">
|
||||
<button name="action" value="test:{{ service_config.id }}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 active:ring rounded-md">Test</button>
|
||||
<button name="action" value="remove:{{ service_config.id }}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 active:ring rounded-md">Remove</button>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr class="bg-white border-slate-200 border-b-2">
|
||||
<td class="w-full p-4">
|
||||
<div>
|
||||
No Messaging Services Configured. <a href="{% url "project_messaging_service_add" project_pk=project.pk %}" class="text-cyan-500 font-bold">Add Messaging Service</a>.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-direction-row">
|
||||
<div class="ml-auto py-8 pr-4">
|
||||
<a href="{% url "project_edit" project_pk=project.pk %}" class="text-cyan-500 font-bold">Settings</a>
|
||||
<span class="font-bold text-slate-500">|</span> <a href="{% url "project_list" %}" class="text-cyan-500 font-bold">Back to Projects</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -103,6 +103,18 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td class="pr-2">
|
||||
{% if project.member or request.user.is_superuser %}
|
||||
<div class="rounded-full hover:bg-slate-100 p-2 cursor-pointer" onclick="followContainedLink(this);" title="Alerting Settings">
|
||||
<a href="{% url 'project_alerts_setup' project_pk=project.id %}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-8">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M10.34 15.84c-.688-.06-1.386-.09-2.09-.09H7.5a4.5 4.5 0 1 1 0-9h.75c.704 0 1.402-.03 2.09-.09m0 9.18c.253.962.584 1.892.985 2.783.247.55.06 1.21-.463 1.511l-.657.38c-.551.318-1.26.117-1.527-.461a20.845 20.845 0 0 1-1.44-4.282m3.102.069a18.03 18.03 0 0 1-.59-4.59c0-1.586.205-3.124.59-4.59m0 9.18a23.848 23.848 0 0 1 8.835 2.535M10.34 6.66a23.847 23.847 0 0 0 8.835-2.535m0 0A23.74 23.74 0 0 0 18.795 3m.38 1.125a23.91 23.91 0 0 1 1.014 5.395m-1.014 8.855c-.118.38-.245.754-.38 1.125m.38-1.125a23.91 23.91 0 0 0 1.014-5.395m0-3.46c.495.413.811 1.035.811 1.73 0 .695-.316 1.317-.811 1.73m0-3.46a24.347 24.347 0 0 1 0 3.46" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td class="pr-2">
|
||||
{% if project.member or request.user.is_superuser %}
|
||||
<div class="rounded-full hover:bg-slate-100 p-2 cursor-pointer" onclick="followContainedLink(this);" title="SDK setup (connect app)">
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% load tailwind_forms %}
|
||||
|
||||
{% block title %}Messaging Service · {{ project.name }} · {{ site_title }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="flex items-center justify-center">
|
||||
|
||||
<div class="m-4 max-w-4xl flex-auto">
|
||||
<form action="." method="post">
|
||||
{% csrf_token %}
|
||||
|
||||
{% if messages %}
|
||||
<ul>
|
||||
{% for message in messages %}
|
||||
{# if we introduce different levels we can use{% message.level == DEFAULT_MESSAGE_LEVELS.SUCCESS %} #}
|
||||
<li class="bg-cyan-50 border-2 border-cyan-800 p-4 rounded-lg">{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
<h1 class="text-4xl my-4 font-bold">Messaging Service | {{ project.name }}</h1>
|
||||
</div>
|
||||
|
||||
{% for field in form %}
|
||||
{% tailwind_formfield field %}
|
||||
{% endfor %}
|
||||
|
||||
{% for field in config_form %}
|
||||
{% tailwind_formfield field %}
|
||||
{% endfor %}
|
||||
|
||||
<button name="action" value="add" class="font-bold text-slate-800 border-slate-500 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 hover:bg-cyan-400 active:ring rounded-md">Save</button>
|
||||
<a href="{% url "project_alerts_setup" project_pk=project.pk %}" class="font-bold text-slate-500 ml-4">Cancel</a>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -2,7 +2,8 @@ from django.urls import path
|
||||
|
||||
from .views import (
|
||||
project_list, project_members, project_members_accept, project_member_settings, project_members_invite,
|
||||
project_members_accept_new_user, project_new, project_edit, project_sdk_setup)
|
||||
project_members_accept_new_user, project_new, project_edit, project_sdk_setup, project_alerts_setup,
|
||||
project_messaging_service_add, project_messaging_service_edit)
|
||||
|
||||
urlpatterns = [
|
||||
path('', project_list, name="project_list"),
|
||||
@@ -21,4 +22,10 @@ urlpatterns = [
|
||||
|
||||
path('<int:project_pk>/sdk-setup/', project_sdk_setup, name="project_sdk_setup"),
|
||||
path('<int:project_pk>/sdk-setup/<str:platform>/', project_sdk_setup, name="project_sdk_setup_platform"),
|
||||
|
||||
path('<int:project_pk>/alerts/', project_alerts_setup, name="project_alerts_setup"),
|
||||
path('<int:project_pk>/alerts/service/add/', project_messaging_service_add, name="project_messaging_service_add"),
|
||||
path(
|
||||
'<int:project_pk>/alerts/service/<int:service_pk>/edit/', project_messaging_service_edit,
|
||||
name="project_messaging_service_edit"),
|
||||
]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import json
|
||||
from datetime import timedelta
|
||||
|
||||
from django.shortcuts import render
|
||||
@@ -17,6 +18,10 @@ from teams.models import TeamMembership, Team, TeamRole
|
||||
from bugsink.app_settings import get_settings, CB_ANYBODY, CB_MEMBERS, CB_ADMINS
|
||||
from bugsink.decorators import login_exempt, atomic_for_request_method
|
||||
|
||||
from alerts.models import MessagingServiceConfig
|
||||
from alerts.forms import MessagingServiceConfigForm
|
||||
from alerts.service_backends.slack import SlackConfigForm
|
||||
|
||||
from .models import Project, ProjectMembership, ProjectRole, ProjectVisibility
|
||||
from .forms import ProjectMembershipForm, MyProjectMembershipForm, ProjectMemberInviteForm, ProjectForm
|
||||
from .tasks import send_project_invite_email, send_project_invite_email_new_user
|
||||
@@ -399,3 +404,84 @@ def project_sdk_setup(request, project_pk, platform=""):
|
||||
"project": project,
|
||||
"dsn": project.dsn,
|
||||
})
|
||||
|
||||
|
||||
@atomic_for_request_method
|
||||
def project_alerts_setup(request, project_pk):
|
||||
project = Project.objects.get(id=project_pk)
|
||||
_check_project_admin(project, request.user)
|
||||
|
||||
if request.method == 'POST':
|
||||
full_action_str = request.POST.get('action')
|
||||
action, service_id = full_action_str.split(":", 1)
|
||||
if action == "remove":
|
||||
MessagingServiceConfig.objects.filter(project=project_pk, id=service_id).delete()
|
||||
elif action == "test":
|
||||
service = MessagingServiceConfig.objects.get(project=project_pk, id=service_id)
|
||||
service_backend = service.get_backend()
|
||||
service_backend.send_test_message()
|
||||
messages.success(
|
||||
request, "Test message sent; check the configured service to see if it arrived.")
|
||||
|
||||
return render(request, 'projects/project_alerts_setup.html', {
|
||||
'project': project,
|
||||
'service_configs': project.service_configs.all(),
|
||||
})
|
||||
|
||||
|
||||
@atomic_for_request_method
|
||||
def project_messaging_service_add(request, project_pk):
|
||||
project = Project.objects.get(id=project_pk)
|
||||
_check_project_admin(project, request.user)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = MessagingServiceConfigForm(project, request.POST)
|
||||
config_form = SlackConfigForm(data=request.POST)
|
||||
|
||||
if form.is_valid() and config_form.is_valid():
|
||||
service = form.save(commit=False)
|
||||
service.config = json.dumps(config_form.get_config())
|
||||
service.save()
|
||||
|
||||
messages.success(request, "Messaging service added successfully.")
|
||||
return redirect('project_alerts_setup', project_pk=project_pk)
|
||||
|
||||
else:
|
||||
form = MessagingServiceConfigForm(project)
|
||||
config_form = SlackConfigForm()
|
||||
|
||||
return render(request, 'projects/project_messaging_service_edit.html', {
|
||||
'project': project,
|
||||
'form': form,
|
||||
'config_form': config_form,
|
||||
})
|
||||
|
||||
|
||||
@atomic_for_request_method
|
||||
def project_messaging_service_edit(request, project_pk, service_pk):
|
||||
project = Project.objects.get(id=project_pk)
|
||||
_check_project_admin(project, request.user)
|
||||
|
||||
instance = project.service_configs.get(id=service_pk)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = MessagingServiceConfigForm(project, request.POST, instance=instance)
|
||||
config_form = SlackConfigForm(data=request.POST)
|
||||
|
||||
if form.is_valid() and config_form.is_valid():
|
||||
service = form.save(commit=False)
|
||||
service.config = json.dumps(config_form.get_config())
|
||||
service.save()
|
||||
|
||||
messages.success(request, "Messaging service updated successfully.")
|
||||
return redirect('project_alerts_setup', project_pk=project_pk)
|
||||
|
||||
else:
|
||||
form = MessagingServiceConfigForm(project, instance=instance)
|
||||
config_form = SlackConfigForm(config=json.loads(instance.config))
|
||||
|
||||
return render(request, 'projects/project_messaging_service_edit.html', {
|
||||
'project': project,
|
||||
'form': form,
|
||||
'config_form': config_form,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user