Merge pull request #125 from d1ceward/feature/add_dark_theme

Add dark mode (a few tiny fixes will follow in a follow-up commit)
This commit is contained in:
Klaas van Schelven
2025-07-07 11:19:16 +02:00
committed by GitHub
59 changed files with 589 additions and 511 deletions

View File

@@ -13,7 +13,7 @@
<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>
<li class="bg-cyan-50 dark:bg-cyan-900 border-2 border-cyan-800 dark:border-cyan-400 p-4 rounded-lg">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
@@ -24,9 +24,9 @@
<div class="ml-auto mt-6">
<form action="{% url "auth_token_create" %}" method="post">
{% csrf_token %} {# margins display slightly different from the <a href version that I have for e.g. project memembers, but I don't care _that_ much #}
<button 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">Add Token</button>
<button class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md">Add Token</button>
</form>
</div>
</div>
</div>
<div>
@@ -36,12 +36,12 @@
<table class="w-full mt-8">
<tbody>
<thead>
<tr class="bg-slate-200">
<tr class="bg-slate-200 dark:bg-slate-800">
<th class="w-full p-4 text-left text-xl" colspan="2">Auth Tokens</th>
</tr>
{% for auth_token in auth_tokens %}
<tr class="bg-white border-slate-200 border-b-2">
<tr class="bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-700 border-b-2">
<td class="w-full p-4">
<div>
{{ auth_token.token }}
@@ -50,13 +50,13 @@
<td class="p-4">
<div class="flex justify-end">
<button name="action" value="delete:{{ auth_token.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">Delete</button>
</div>
<button name="action" value="delete:{{ auth_token.id }}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Delete</button>
</div>
</td>
</tr>
{% empty %}
<tr class="bg-white border-slate-200 border-b-2">
<tr class="bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-700 border-b-2">
<td class="w-full p-4">
<div>
No Auth Tokens.

View File

@@ -24,11 +24,11 @@ SystemWarning = namedtuple('SystemWarning', ['message', 'ignore_url'])
FREE_VERSION_WARNING = mark_safe(
"""This is the free version of Bugsink; usage is limited to a single user for local development only.
Using this software in production requires a
<a href="https://www.bugsink.com/#pricing" target="_blank" class="font-bold text-slate-800">paid licence</a>.""")
<a href="https://www.bugsink.com/#pricing" target="_blank" class="font-bold text-slate-800 dark:text-slate-100">paid licence</a>.""")
EMAIL_BACKEND_WARNING = mark_safe(
"""Email is not set up, emails won't be sent. To get the most out of Bugsink, please
<a href="https://www.bugsink.com/docs/settings/#email" target="_blank" class="font-bold text-slate-800">set up
<a href="https://www.bugsink.com/docs/settings/#email" target="_blank" class="font-bold text-slate-800 dark:text-slate-100">set up
email</a>.""")

View File

@@ -1,45 +1,45 @@
{% load add_to_qs %}
<form action="{% url this_view issue_pk=issue.pk nav="last" %}" method="get">{# nav="last": when doing a new search on an event-page, you want the most recent matching event to show up #}
<input type="text" name="q" value="{{ q }}" placeholder="search..." class="focus:border-cyan-500 focus:ring-cyan-200 rounded-md mr-2"/>
<input type="text" name="q" value="{{ q }}" placeholder="search..." class="focus:border-cyan-500 dark:focus:border-cyan-400 focus:ring-cyan-200 dark:focus:ring-cyan-700 rounded-md mr-2"/>
</form>
{% if has_prev %} {# no need for 'is_first': if you can go to the left, you can go all the way to the left too #}
<a href="{% url this_view issue_pk=issue.pk nav="first" %}{% current_qs %}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring inline-flex items-center justify-center" title="First event">
<a href="{% url this_view issue_pk=issue.pk nav="first" %}{% current_qs %}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring inline-flex items-center justify-center" title="First event">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M3.22 7.595a.75.75 0 0 0 0 1.06l3.25 3.25a.75.75 0 0 0 1.06-1.06l-2.72-2.72 2.72-2.72a.75.75 0 0 0-1.06-1.06l-3.25 3.25Zm8.25-3.25-3.25 3.25a.75.75 0 0 0 0 1.06l3.25 3.25a.75.75 0 1 0 1.06-1.06l-2.72-2.72 2.72-2.72a.75.75 0 0 0-1.06-1.06Z" clip-rule="evenodd" /></svg>
</a>
{% else %}
<div class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="First event">
<div class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="First event">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M3.22 7.595a.75.75 0 0 0 0 1.06l3.25 3.25a.75.75 0 0 0 1.06-1.06l-2.72-2.72 2.72-2.72a.75.75 0 0 0-1.06-1.06l-3.25 3.25Zm8.25-3.25-3.25 3.25a.75.75 0 0 0 0 1.06l3.25 3.25a.75.75 0 1 0 1.06-1.06l-2.72-2.72 2.72-2.72a.75.75 0 0 0-1.06-1.06Z" clip-rule="evenodd" /></svg>
</div>
{% endif %}
{% if has_prev %}
<a href="{% url this_view issue_pk=issue.pk digest_order=event.digest_order nav="prev" %}{% current_qs %}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring inline-flex items-center justify-center" title="Previous event">
<a href="{% url this_view issue_pk=issue.pk digest_order=event.digest_order nav="prev" %}{% current_qs %}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring inline-flex items-center justify-center" title="Previous event">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M9.78 4.22a.75.75 0 0 1 0 1.06L7.06 8l2.72 2.72a.75.75 0 1 1-1.06 1.06L5.47 8.53a.75.75 0 0 1 0-1.06l3.25-3.25a.75.75 0 0 1 1.06 0Z" clip-rule="evenodd" /></svg>
</a>
{% else %}
<div class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Previous event">
<div class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Previous event">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M9.78 4.22a.75.75 0 0 1 0 1.06L7.06 8l2.72 2.72a.75.75 0 1 1-1.06 1.06L5.47 8.53a.75.75 0 0 1 0-1.06l3.25-3.25a.75.75 0 0 1 1.06 0Z" clip-rule="evenodd" /></svg>
</div>
{% endif %}
{% if has_next %}
<a href="{% url this_view issue_pk=issue.pk digest_order=event.digest_order nav="next" %}{% current_qs %}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring inline-flex items-center justify-center" title="Next event">
<a href="{% url this_view issue_pk=issue.pk digest_order=event.digest_order nav="next" %}{% current_qs %}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring inline-flex items-center justify-center" title="Next event">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M6.22 4.22a.75.75 0 0 1 1.06 0l3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06L8.94 8 6.22 5.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" /></svg>
</a>
{% else %}
<div class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Next event">
<div class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Next event">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M6.22 4.22a.75.75 0 0 1 1.06 0l3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06L8.94 8 6.22 5.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" /></svg>
</div>
{% endif %}
{% if has_next %}
<a href="{% url this_view issue_pk=issue.pk nav="last" %}{% current_qs %}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring inline-flex items-center justify-center" title="Last event">
<a href="{% url this_view issue_pk=issue.pk nav="last" %}{% current_qs %}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring inline-flex items-center justify-center" title="Last event">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M12.78 7.595a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06l2.72-2.72-2.72-2.72a.75.75 0 0 1 1.06-1.06l3.25 3.25Zm-8.25-3.25 3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06l2.72-2.72-2.72-2.72a.75.75 0 0 1 1.06-1.06Z" clip-rule="evenodd" /></svg>
</a>
{% else %}
<div class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Last event">
<div class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Last event">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M12.78 7.595a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06l2.72-2.72-2.72-2.72a.75.75 0 0 1 1.06-1.06l3.25 3.25Zm-8.25-3.25 3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06l2.72-2.72-2.72-2.72a.75.75 0 0 1 1.06-1.06Z" clip-rule="evenodd" /></svg>
</div>

View File

@@ -14,16 +14,16 @@
{% csrf_token %}
{% if issue.is_resolved %}{# i.e. buttons disabled #}
{# see issues/tests.py for why this is turned off ATM #}
{# <button 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" name="action" value="reopen">Reopen</button> #}
{# <button class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md" name="action" value="reopen">Reopen</button> #}
{% spaceless %}{# needed to avoid whitespace between the looks-like-one-buttons #}
{% if issue.project.has_releases %}
<button disabled class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 rounded-s-md" name="action" value="resolved_next">Resolved in next release</button>
<button disabled class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 rounded-s-md" name="action" value="resolved_next">Resolved in next release</button>
<button disabled class="font-bold text-slate-300 fill-slate-300 stroke-slate-300 border-slate-300 pl-4 pr-4 pb-2 pt-2 border-r-2 border-t-2 border-b-2 rounded-e-md"><svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
<button disabled class="font-bold text-slate-300 dark:text-slate-600 fill-slate-300 dark:fill-slate-600 stroke-slate-300 dark:stroke-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 border-r-2 border-t-2 border-b-2 rounded-e-md"><svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
{# we just hide the whole dropdown; this is the easiest implementation of not-showing the dropdown #}
{% else %}
<button disabled class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 rounded-md" name="action" value="resolved">Resolve</button>
<button disabled class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 rounded-md" name="action" value="resolved">Resolve</button>
{% endif %}
{% endspaceless %}
@@ -31,27 +31,27 @@
{% spaceless %}{# needed to avoid whitespace between the looks-like-one-buttons #}
{% if issue.project.has_releases %}
{# 'by next' is shown even if 'by current' is also shown: just because you haven't seen 'by current' doesn't mean it's actually already solved; and in fact we show this option first precisely because we can always show it #}
<button 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-s-md" name="action" value="resolved_next">Resolved in next release</button>
{# 'by next' is shown even if 'by current' is also shown: just because you haven't seen 'by current' doesn't mean it's actually already solved; and in fact we show this option first precisely because we can always show it #}
<button class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-s-md" name="action" value="resolved_next">Resolved in next release</button>
<div class="dropdown">
<button disabled {# disabled b/c clicking the dropdown does nothing - we have hover for that #} class="font-bold text-slate-800 fill-slate-800 border-slate-500 pl-4 pr-4 pb-2 pt-2 border-r-2 border-t-2 border-b-2 hover:bg-slate-200 active:ring rounded-e-md"><svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
<button disabled {# disabled b/c clicking the dropdown does nothing - we have hover for that #} class="font-bold text-slate-800 dark:text-slate-100 fill-slate-800 dark:fill-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-r-2 border-t-2 border-b-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-e-md"><svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
{# note that we can depend on get_latest_release being available, because we're in the 'project.has_releases' branch #}
<div class="dropdown-content-right flex-col pl-2">
{% if not issue.occurs_in_last_release %}
<button name="action" value="resolved_release:{{ issue.project.get_latest_release.version }}" class="block self-stretch font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 border-l-2 border-r-2 border-b-2 bg-white hover:bg-slate-200 active:ring text-left whitespace-nowrap">Resolved in latest ({{ issue.project.get_latest_release.get_short_version }})</button>
<button name="action" value="resolved_release:{{ issue.project.get_latest_release.version }}" class="block self-stretch font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 border-l-2 border-r-2 border-b-2 bg-white dark:bg-slate-900 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring text-left whitespace-nowrap">Resolved in latest ({{ issue.project.get_latest_release.get_short_version }})</button>
{% else %}
<button name="action" value="resolved_release:{{ issue.project.get_latest_release.version }}" disabled class="block self-stretch font-bold text-slate-300 border-slate-200 pl-4 pr-4 pb-2 pt-2 border-l-2 border-r-2 border-b-2 bg-white text-left whitespace-nowrap">Resolved in latest ({{ issue.project.get_latest_release.get_short_version }})</button>
<button name="action" value="resolved_release:{{ issue.project.get_latest_release.version }}" disabled class="block self-stretch font-bold text-slate-300 dark:text-slate-600 border-slate-200 dark:border-slate-700 pl-4 pr-4 pb-2 pt-2 border-l-2 border-r-2 border-b-2 bg-white dark:bg-slate-900 text-left whitespace-nowrap">Resolved in latest ({{ issue.project.get_latest_release.get_short_version }})</button>
{% endif %}
</div>
</div>
</div>
{% else %}
<button 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" name="action" value="resolve">Resolve</button>
<button class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md" name="action" value="resolve">Resolve</button>
{% endif %}
{% endspaceless %}
@@ -59,33 +59,33 @@
{% spaceless %}{# needed to avoid whitespace between the looks-like-one-buttons #}
{% if not issue.is_muted and not issue.is_resolved %}
<button class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 hover:bg-slate-200 active:ring rounded-s-md" name="action" value="mute">Mute</button>
<button class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-s-md" name="action" value="mute">Mute</button>
{% else %}
<button disabled class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 rounded-s-md" name="action" value="mute">Mute</button>
<button disabled class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 rounded-s-md" name="action" value="mute">Mute</button>
{% endif %}
<div class="dropdown">
{% if not issue.is_muted and not issue.is_resolved %}
<button disabled {# disabled b/c clicking the dropdown does nothing - we have hover for that #} class="font-bold text-slate-500 fill-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2 hover:bg-slate-200 active:ring">Mute for/until&nbsp;&nbsp;<svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
<button disabled {# disabled b/c clicking the dropdown does nothing - we have hover for that #} class="font-bold text-slate-500 dark:text-slate-300 fill-slate-500 dark:fill-slate-500 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring">Mute for/until&nbsp;&nbsp;<svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
<div class="dropdown-content-right flex-col">
{% for mute_option in mute_options %}
<button name="action" value="mute_{{ mute_option.for_or_until }}:{{ mute_option.period_name }},{{ mute_option.nr_of_periods }},{{ mute_option.gte_threshold }}" class="block self-stretch font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 border-l-2 border-r-2 border-b-2 bg-white hover:bg-slate-200 active:ring text-left whitespace-nowrap">{% if mute_option.for_or_until == "for" %}{{ mute_option.nr_of_periods }} {{ mute_option.period_name }}{% if mute_option.nr_of_periods != 1 %}s{% endif %}{% else %}{{ mute_option.gte_threshold }} events per {% if mute_option.nr_of_periods != 1%} {{ mute_option.nr_of_periods }} {{ mute_option.period_name }}s{% else %} {{ mute_option.period_name }}{% endif %}{% endif %}</button>
<button name="action" value="mute_{{ mute_option.for_or_until }}:{{ mute_option.period_name }},{{ mute_option.nr_of_periods }},{{ mute_option.gte_threshold }}" class="block self-stretch font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 border-l-2 border-r-2 border-b-2 bg-white dark:bg-slate-900 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring text-left whitespace-nowrap">{% if mute_option.for_or_until == "for" %}{{ mute_option.nr_of_periods }} {{ mute_option.period_name }}{% if mute_option.nr_of_periods != 1 %}s{% endif %}{% else %}{{ mute_option.gte_threshold }} events per {% if mute_option.nr_of_periods != 1%} {{ mute_option.nr_of_periods }} {{ mute_option.period_name }}s{% else %} {{ mute_option.period_name }}{% endif %}{% endif %}</button>
{% endfor %}
</div>
{% else %}
<button disabled class="font-bold text-slate-300 fill-slate-300 border-slate-300 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2">Mute for/until&nbsp;&nbsp;<svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
<button disabled class="font-bold text-slate-300 dark:text-slate-600 fill-slate-300 dark:fill-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2">Mute for/until&nbsp;&nbsp;<svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
{# note that when the issue is muted, no further muting is allowed. this is a design decision, I figured this is the easiest-to-understand UI, #}
{# both at the point-of-clicking and when displaying the when-will-this-be-unmuted in some place #}
{# (the alternative would be to allow multiple simulteneous reasons for unmuting to exist next to each other #}
{# we just hide the whole dropdown; this is the easiest implementation of not-showing the dropdown when the issue is already muted #}
{% endif %}
</div>
</div>
{% if issue.is_muted and not issue.is_resolved %}
<button class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2 hover:bg-slate-200 active:ring rounded-e-md" name="action" value="unmute">Unmute</button>
<button class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-e-md" name="action" value="unmute">Unmute</button>
{% else %}
<button disabled class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2 rounded-e-md" name="action" value="unmute">Unmute</button>
<button disabled class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2 rounded-e-md" name="action" value="unmute">Unmute</button>
{% endif %}
{% endspaceless %}
@@ -106,14 +106,14 @@
{# overflow-x-auto is needed at the level of the flex item such that it works at the level where we need it (the code listings)#}
<div class="ml-4 mb-4 mr-4 border-2 overflow-x-auto flex-[2_1_96rem]"><!-- the whole of the big tabbed view--> {# 96rem is 1536px, which matches the 2xl class; this is no "must" but eyeballing revealed: good result #}
<div class="flex bg-slate-50 border-b-2"><!-- container for the actual tab buttons -->
<a href="/issues/issue/{{ issue.id }}/event/{% if event %}{{ event.id }}{% else %}last{% endif %}/{% current_qs %}"><div class="p-4 font-bold hover:bg-slate-200 {% if tab == "stacktrace" %}text-cyan-500 border-cyan-500 border-b-4{% else %}text-slate-500 border-slate-400 hover:border-b-4{% endif %}">Stacktrace</div></a>
<a href="/issues/issue/{{ issue.id }}/event/{% if event %}{{ event.id }}{% else %}last{% endif %}/details/{% current_qs %}"><div class="p-4 font-bold hover:bg-slate-200 {% if tab == "event-details" %}text-cyan-500 border-cyan-500 border-b-4{% else %}text-slate-500 border-slate-400 hover:border-b-4{% endif %}">Event&nbsp;Details</div></a>
<a href="/issues/issue/{{ issue.id }}/event/{% if event %}{{ event.id }}{% else %}last{% endif %}/breadcrumbs/{% current_qs %}"><div class="p-4 font-bold hover:bg-slate-200 {% if tab == "breadcrumbs" %}text-cyan-500 border-cyan-500 border-b-4{% else %}text-slate-500 border-slate-400 hover:border-b-4{% endif %}">Breadcrumbs</div></a>
<a href="/issues/issue/{{ issue.id }}/events/{% current_qs %}"><div class="p-4 font-bold hover:bg-slate-200 {% if tab == "event-list" %}text-cyan-500 border-cyan-500 border-b-4{% else %}text-slate-500 border-slate-400 hover:border-b-4{% endif %}">Event&nbsp;List</div></a>
<a href="/issues/issue/{{ issue.id }}/tags/{% current_qs %}"><div class="p-4 font-bold hover:bg-slate-200 {% if tab == "tags" %}text-cyan-500 border-cyan-500 border-b-4{% else %}text-slate-500 border-slate-400 hover:border-b-4{% endif %}">Tags</div></a>
<a href="/issues/issue/{{ issue.id }}/grouping/{% current_qs %}"><div class="p-4 font-bold hover:bg-slate-200 {% if tab == "grouping" %}text-cyan-500 border-cyan-500 border-b-4{% else %}text-slate-500 border-slate-400 hover:border-b-4{% endif %}">Grouping</div></a>
<a href="/issues/issue/{{ issue.id }}/history/{% current_qs %}"><div class="p-4 font-bold hover:bg-slate-200 {% if tab == "history" %}text-cyan-500 border-cyan-500 border-b-4{% else %}text-slate-500 border-slate-400 hover:border-b-4{% endif %}">History</div></a>
<div class="flex bg-slate-50 dark:bg-slate-800 border-b-2"><!-- container for the actual tab buttons -->
<a href="/issues/issue/{{ issue.id }}/event/{% if event %}{{ event.id }}{% else %}last{% endif %}/{% current_qs %}"><div class="p-4 font-bold hover:bg-slate-200 dark:hover:bg-slate-800 {% if tab == "stacktrace" %}text-cyan-500 dark:text-cyan-300 border-cyan-500 border-b-4{% else %}text-slate-500 border-slate-400 hover:border-b-4{% endif %}">Stacktrace</div></a>
<a href="/issues/issue/{{ issue.id }}/event/{% if event %}{{ event.id }}{% else %}last{% endif %}/details/{% current_qs %}"><div class="p-4 font-bold hover:bg-slate-200 dark:hover:bg-slate-800 {% if tab == "event-details" %}text-cyan-500 dark:text-cyan-300 border-cyan-500 border-b-4{% else %}text-slate-500 border-slate-400 hover:border-b-4{% endif %}">Event&nbsp;Details</div></a>
<a href="/issues/issue/{{ issue.id }}/event/{% if event %}{{ event.id }}{% else %}last{% endif %}/breadcrumbs/{% current_qs %}"><div class="p-4 font-bold hover:bg-slate-200 dark:hover:bg-slate-800 {% if tab == "breadcrumbs" %}text-cyan-500 dark:text-cyan-300 border-cyan-500 border-b-4{% else %}text-slate-500 border-slate-400 hover:border-b-4{% endif %}">Breadcrumbs</div></a>
<a href="/issues/issue/{{ issue.id }}/events/{% current_qs %}"><div class="p-4 font-bold hover:bg-slate-200 dark:hover:bg-slate-800 {% if tab == "event-list" %}text-cyan-500 dark:text-cyan-300 border-cyan-500 border-b-4{% else %}text-slate-500 border-slate-400 hover:border-b-4{% endif %}">Event&nbsp;List</div></a>
<a href="/issues/issue/{{ issue.id }}/tags/{% current_qs %}"><div class="p-4 font-bold hover:bg-slate-200 dark:hover:bg-slate-800 {% if tab == "tags" %}text-cyan-500 dark:text-cyan-300 border-cyan-500 border-b-4{% else %}text-slate-500 border-slate-400 hover:border-b-4{% endif %}">Tags</div></a>
<a href="/issues/issue/{{ issue.id }}/grouping/{% current_qs %}"><div class="p-4 font-bold hover:bg-slate-200 dark:hover:bg-slate-800 {% if tab == "grouping" %}text-cyan-500 dark:text-cyan-300 border-cyan-500 border-b-4{% else %}text-slate-500 border-slate-400 hover:border-b-4{% endif %}">Grouping</div></a>
<a href="/issues/issue/{{ issue.id }}/history/{% current_qs %}"><div class="p-4 font-bold hover:bg-slate-200 dark:hover:bg-slate-800 {% if tab == "history" %}text-cyan-500 dark:text-cyan-300 border-cyan-500 border-b-4{% else %}text-slate-500 border-slate-400 hover:border-b-4{% endif %}">History</div></a>
</div>
<div class="m-4"><!-- div for tab_content -->
@@ -121,9 +121,9 @@
{% endblock %}
</div>
<div class="flex p-4 bg-slate-200 border-b-2"><!-- bottom nav bar -->
<div class="flex p-4 bg-slate-200 dark:bg-slate-800 border-b-2"><!-- bottom nav bar -->
{% if is_event_page %}<div>Event {{ event.digest_order|intcomma }} of {{ issue.digested_event_count|intcomma }} which occured at <span class="font-bold">{{ event.ingested_at|date:"j M G:i T" }}</span></div>{% endif %}
<div class="ml-auto pr-4 font-bold text-slate-500">
<div class="ml-auto pr-4 font-bold text-slate-500 dark:text-slate-300">
{% if is_event_page %}
<a href="/events/event/{{ event.id }}/download/">Download</a>
| <a href="/events/event/{{ event.id }}/raw/" >JSON</a>
@@ -131,7 +131,7 @@
{% endif %}
{% if app_settings.USE_ADMIN and user.is_staff %}
{% if is_event_page %}
{% if is_event_page %}
| <a href="/admin/events/event/{{ event.id }}/change/">Event Admin</a> |
{% endif %}
<a href="/admin/issues/issue/{{ issue.id }}/change/">Issue Admin</a>
@@ -145,19 +145,19 @@
<div class="border-2 mb-4 mr-4"><!-- "issue: key info" box -->
<div class="font-bold border-b-2">
<div class="p-4 border-slate-50 text-slate-500 border-b-2"> {# div-in-div to match the spacing of the tabs, which is caused by the hover-thick-line; we use border-2 on both sides rather than border-b-4 to get the text aligned centeredly #}
<div class="p-4 border-slate-50 dark:border-slate-900 text-slate-500 dark:text-slate-300"> {# div-in-div to match the spacing of the tabs, which is caused by the hover-thick-line; we use border-2 on both sides rather than border-b-4 to get the text aligned centeredly #}
Issue Key Info
</div>
</div>
<div class="p-4">
<div class="mb-4">
<div class="text-sm font-bold text-slate-500">Issue #</div>
<div class="text-sm font-bold text-slate-500 dark:text-slate-300">Issue #</div>
<div>{{ issue.friendly_id }} </div>
</div>
<div class="mb-4">
<div class="text-sm font-bold text-slate-500">State</div>
<div class="text-sm font-bold text-slate-500 dark:text-slate-300">State</div>
<div>
{% if issue.is_resolved %}
Resolved
@@ -185,7 +185,7 @@
</div>
<div class="mb-4">
<div class="text-sm font-bold text-slate-500">Nr. of events:</div>
<div class="text-sm font-bold text-slate-500 dark:text-slate-300">Nr. of events:</div>
<div>{{ issue.digested_event_count|intcomma }}
{% if issue.digested_event_count != issue.stored_event_count %}
total seen</div><div>{{ issue.stored_event_count|intcomma }} available</div>
@@ -196,24 +196,24 @@
{% if issue.digested_event_count > 1 %}
<div class="mb-4">
<div class="text-sm font-bold text-slate-500">First seen:</div>
<div class="text-sm font-bold text-slate-500 dark:text-slate-300">First seen:</div>
<div>{{ issue.first_seen|date:"j M G:i T" }}</div>
</div>
<div class="mb-4">
<div class="text-sm font-bold text-slate-500">Last seen:</div>
<div class="text-sm font-bold text-slate-500 dark:text-slate-300">Last seen:</div>
<div>{{ issue.last_seen|date:"j M G:i T" }}</div>
</div>
{% else %}
<div class="mb-4">
<div class="text-sm font-bold text-slate-500">Seen at:</div>
<div class="text-sm font-bold text-slate-500 dark:text-slate-300">Seen at:</div>
<div>{{ issue.first_seen|date:"j M G:i T" }}</div>
</div>
{% endif %}
{% if issue.get_events_at_2 %}
<div class="mb-4">
<div class="text-sm font-bold text-slate-500">Seen in releases:</div>
<div class="text-sm font-bold text-slate-500 dark:text-slate-300">Seen in releases:</div>
<div>
{% for version in issue.get_events_at_2 %}
<span {% if version|issha %}class="font-mono"{% endif %}>{{ version|shortsha }}{% if not forloop.last %}</span>,{% endif %}
@@ -228,16 +228,16 @@
{% if tab != "tags" and issue.tags_summary %}
<div class="border-2 mb-4 mr-4"><!-- "issue: tags" box -->
<div class="font-bold border-b-2">
<div class="p-4 border-slate-50 text-slate-500">
<div class="p-4 border-slate-50 dark:border-slate-900 text-slate-500 dark:text-slate-300">
Issue Tags
</div>
</div>
<div class="p-4">
{% for issuetags in issue.tags_summary %}
<div class="mb-4">
<div class="text-sm font-bold text-slate-500">{{ issuetags.0.key.key }}:</div>
<div class="text-sm font-bold text-slate-500 dark:text-slate-300">{{ issuetags.0.key.key }}:</div>
<div>
{% for issuetag in issuetags %}
{% for issuetag in issuetags %}
<span>{{ issuetag.value.value }} <span class="text-xs">({{ issuetag.pct }}%)</span>{% if not forloop.last %}</span>,{% endif %}
{% endfor %}
</div>

View File

@@ -32,14 +32,14 @@
<tbody>
{% for breadcrumb in breadcrumbs %}
<tr class="border-slate-200 border-2 ">
<tr class="border-slate-200 dark:border-slate-700 border-2 ">
<td class="p-4 font-bold text-slate-500 align-top">
<td class="p-4 font-bold text-slate-500 dark:text-slate-300 align-top">
{{ breadcrumb.category }}
</td>
{% comment %}
{# not _that_ useful
{# not _that_ useful
<td class="ml-0 pb-4 pt-4 pr-4">
{{ breadcrumb.type }}
</td>
@@ -48,7 +48,7 @@
<td class="w-full p-4 font-mono">
{{ breadcrumb.message }}
</td>
<td class="p-4 font-bold text-slate-500 align-top">
<td class="p-4 font-bold text-slate-500 dark:text-slate-300 align-top">
{{ breadcrumb.timestamp }}
{# {{ breadcrumb.timestamp|date:"G:i T" and milis }} #}
</td>

View File

@@ -16,34 +16,34 @@
<div class="flex place-content-end">
{# copy/paste of _event_nav, but not based on any event (we have none), prev/next are meaningless also; first/last only when we have an event_qs to navigate through #}
<form action="{% url this_view issue_pk=issue.pk nav="last" %}" method="get">{# nav="last": when doing a new search on an event-page, you want the most recent matching event to show up #}
<input type="text" name="q" value="{{ q }}" placeholder="search..." class="focus:border-cyan-500 focus:ring-cyan-200 rounded-md mr-2"/>
<input type="text" name="q" value="{{ q }}" placeholder="search..." class="focus:border-cyan-500 dark:focus:border-cyan-400 focus:ring-cyan-200 dark:focus:ring-cyan-700 rounded-md mr-2"/>
</form>
{% if event_qs_count %}
<a href="{% url this_view issue_pk=issue.pk nav="first" %}{% current_qs %}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring inline-flex items-center justify-center" title="First event">
<a href="{% url this_view issue_pk=issue.pk nav="first" %}{% current_qs %}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring inline-flex items-center justify-center" title="First event">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M3.22 7.595a.75.75 0 0 0 0 1.06l3.25 3.25a.75.75 0 0 0 1.06-1.06l-2.72-2.72 2.72-2.72a.75.75 0 0 0-1.06-1.06l-3.25 3.25Zm8.25-3.25-3.25 3.25a.75.75 0 0 0 0 1.06l3.25 3.25a.75.75 0 1 0 1.06-1.06l-2.72-2.72 2.72-2.72a.75.75 0 0 0-1.06-1.06Z" clip-rule="evenodd" />
</svg>
</a>
{% else %}
<div class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="First event">
<div class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="First event">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M3.22 7.595a.75.75 0 0 0 0 1.06l3.25 3.25a.75.75 0 0 0 1.06-1.06l-2.72-2.72 2.72-2.72a.75.75 0 0 0-1.06-1.06l-3.25 3.25Zm8.25-3.25-3.25 3.25a.75.75 0 0 0 0 1.06l3.25 3.25a.75.75 0 1 0 1.06-1.06l-2.72-2.72 2.72-2.72a.75.75 0 0 0-1.06-1.06Z" clip-rule="evenodd" /></svg>
</div>
{% endif %}
<div class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Previous event">
<div class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Previous event">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M9.78 4.22a.75.75 0 0 1 0 1.06L7.06 8l2.72 2.72a.75.75 0 1 1-1.06 1.06L5.47 8.53a.75.75 0 0 1 0-1.06l3.25-3.25a.75.75 0 0 1 1.06 0Z" clip-rule="evenodd" /></svg>
</div>
<div class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Next event">
<div class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Next event">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M6.22 4.22a.75.75 0 0 1 1.06 0l3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06L8.94 8 6.22 5.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" /></svg>
</div>
{% if event_qs_count %}
<a href="{% url this_view issue_pk=issue.pk nav="last" %}{% current_qs %}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring inline-flex items-center justify-center" title="Last event">
<a href="{% url this_view issue_pk=issue.pk nav="last" %}{% current_qs %}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring inline-flex items-center justify-center" title="Last event">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M12.78 7.595a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06l2.72-2.72-2.72-2.72a.75.75 0 0 1 1.06-1.06l3.25 3.25Zm-8.25-3.25 3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06l2.72-2.72-2.72-2.72a.75.75 0 0 1 1.06-1.06Z" clip-rule="evenodd" /></svg>
</a>
{% else %}
<div class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Last event">
<div class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Last event">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M12.78 7.595a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06l2.72-2.72-2.72-2.72a.75.75 0 0 1 1.06-1.06l3.25 3.25Zm-8.25-3.25 3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06l2.72-2.72-2.72-2.72a.75.75 0 0 1 1.06-1.06Z" clip-rule="evenodd" /></svg>
</div>

View File

@@ -24,21 +24,21 @@
<div class="mb-6">
{% for key, value in key_info %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value|linebreaks }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value|linebreaks }}</div>
</div>
{% endfor %}
</div>
{% if logentry_info %}
<h1 id="logentry" class="text-2xl font-bold mt-4">Log Entry</h1>
<div class="mb-6">
{% for key, value in logentry_info %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value|linebreaks }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value|linebreaks }}</div>
</div>
{% endfor %}
</div>
@@ -47,12 +47,12 @@
{% if deployment_info %}
<h1 id="deployment" class="text-2xl font-bold mt-4">Deployment</h1>
<div class="mb-6">
{% for key, value in deployment_info %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value|linebreaks }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value|linebreaks }}</div>
</div>
{% endfor %}
</div>
@@ -60,12 +60,12 @@
{% if event.get_tags %}
<h1 id="tags" class="text-2xl font-bold mt-4">Tags</h1>
<div class="mb-6">
{% for tag in event.get_tags %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ tag.value.key.key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ tag.value.value|linebreaks }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ tag.value.key.key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ tag.value.value|linebreaks }}</div>
</div>
{% endfor %}
</div>
@@ -75,12 +75,12 @@
{# note: in the (September 2024) sentry.io interface, user info is displayed under 'contexts', but in the data it simply lives top-level as #}
{# is implied by parsed_data.user -- I checked in a recent (September 2024) event.schema.json #}
<h1 id="user" class="text-2xl font-bold mt-4">User</h1>
<div class="mb-6">
{% for key, value in parsed_data.user|items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value|linebreaks }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value|linebreaks }}</div>
</div>
{% endfor %}
</div>
@@ -89,13 +89,13 @@
{% if parsed_data.request %}
<h1 id="request" class="text-2xl font-bold mt-4">Request</h1>
<div class="mb-6">
<div>
{% for key, value in parsed_data.request|items %}
{% if key != "headers" and key != "env" %}{# we deal with these below #}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value|linebreaks }}</div>{# forloop.last doesn't work given the if-statement; we can fix that by pre-processing in the view #}
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value|linebreaks }}</div>{# forloop.last doesn't work given the if-statement; we can fix that by pre-processing in the view #}
</div>
{% endif %}
{% endfor %}
@@ -105,9 +105,9 @@
<h3 class="font-bold mt-2">REQUEST HEADERS</h3>
<div>
{% for key, value in parsed_data.request.headers.items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %} border-dotted">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value|linebreaks }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %} border-dotted">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value|linebreaks }}</div>
</div>
{% endfor %}
</div>
@@ -118,9 +118,9 @@
<div>
{% for key, value in parsed_data.request.env.items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %} border-dotted">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value|linebreaks }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %} border-dotted">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value|linebreaks }}</div>
</div>
{% endfor %}
@@ -133,14 +133,14 @@
{% if contexts %}
<h1 id="runtime" class="text-2xl font-bold mt-4">Contexts</h1>
<div class="mb-6">
{% for context_key, context in contexts|items %}
<h3 class="font-bold mt-2">{{ context_key|upper }}</h3>
{% for key, value in context|items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value|linebreaks }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value|linebreaks }}</div>
</div>
{% endfor %}
{% endfor %}
@@ -150,7 +150,7 @@
{% comment %}
earlier I said about "tracing": I don't believe much in this whole business of tracing, so I'm not going to display the associated data either
now that we "just display all contexts" this is no longer true... some of the feeling persists, but I don't think
now that we "just display all contexts" this is no longer true... some of the feeling persists, but I don't think
that I'm so much anti-tracing that I want specifically exclude it from a generic loop. The data's there, let's just
show it (in a non-special way)
{% endcomment %}
@@ -163,12 +163,12 @@ the fact that we commented-out rather than clobbered reveals a small amount of d
{% if parsed_data.contexts.runtime %}
{# sentry gives this prime location (even a picture)... but why... it's kinda obvious what you're working in right? Maybe I could put it at the top of the modules list instead. And check if there's any other relevant info in that runtime context (RTFM) #}
<h1 id="runtime" class="text-2xl font-bold mt-4">Runtime</h1>
<div class="mb-6">
{% for key, value in parsed_data.contexts.runtime|items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value|linebreaks }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value|linebreaks }}</div>
</div>
{% endfor %}
</div>
@@ -177,14 +177,14 @@ the fact that we commented-out rather than clobbered reveals a small amount of d
{% if parsed_data.modules %}
<h1 id="modules" class="text-2xl font-bold mt-4">Modules</h1>
<div class="mb-6">
{# we have observed that (emperically) the keys in most of the above are sorted in some kind of meaningful way from important to non-important #}
{# however, for modules I'd rather just have an alphabetical list. #}
{% for key, value in parsed_data.modules|sorted_items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value|linebreaks }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value|linebreaks }}</div>
</div>
{% endfor %}
</div>
@@ -192,12 +192,12 @@ the fact that we commented-out rather than clobbered reveals a small amount of d
{% if parsed_data.sdk %}
<h1 id="sdk" class="text-2xl font-bold mt-4">SDK</h1>
<div class="mb-6">
{% for key, value in parsed_data.sdk|items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value|linebreaks }}</div> {# the actual value may be a dict/list, but we'll just print it as a string; this is plenty of space for something as (hopefully) irrelevant as the SDK #}
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value|linebreaks }}</div> {# the actual value may be a dict/list, but we'll just print it as a string; this is plenty of space for something as (hopefully) irrelevant as the SDK #}
</div>
{% endfor %}
</div>
@@ -205,12 +205,12 @@ the fact that we commented-out rather than clobbered reveals a small amount of d
{% if parsed_data.extra %}
<h1 id="extra" class="text-2xl font-bold mt-4">Extra</h1>
<div class="mb-6">
{% for key, value in parsed_data.extra|items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value|linebreaks }}</div> {# the actual value may be a dict/list, but we'll just print it as a string; this is plenty of space for something as (hopefully) irrelevant #}
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value|linebreaks }}</div> {# the actual value may be a dict/list, but we'll just print it as a string; this is plenty of space for something as (hopefully) irrelevant #}
</div>
{% endfor %}
</div>

View File

@@ -9,7 +9,7 @@
<div class="flex">
<div class="overflow-hidden">
<div class="italic">
Showing {{ page_obj.start_index|intcomma }} - {{ page_obj.end_index|intcomma }} of
Showing {{ page_obj.start_index|intcomma }} - {{ page_obj.end_index|intcomma }} of
{% if page_obj.paginator.count == issue.stored_event_count and issue.stored_event_count == issue.digested_event_count %} {# all equal #}
{{ page_obj.paginator.count|intcomma }} total events.
{% elif page_obj.paginator.count == issue.stored_event_count and issue.stored_event_count != issue.digested_event_count %} {# evictions applied #}
@@ -27,44 +27,44 @@
{# adapted copy/pasta from _event_nav #}
<div class="flex place-content-end">
<form action="." method="get">
<input type="text" name="q" value="{{ q }}" placeholder="search..." class="focus:border-cyan-500 focus:ring-cyan-200 rounded-md mr-2"/>
<input type="text" name="q" value="{{ q }}" placeholder="search..." class="focus:border-cyan-500 dark:focus:border-cyan-400 focus:ring-cyan-200 dark:focus:ring-cyan-700 rounded-md mr-2"/>
</form>
{% if page_obj.has_previous %} {# no need for 'is_first': if you can go to the left, you can go all the way to the left too #}
<a href="?{% add_to_qs page=1 %}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring inline-flex items-center justify-center" title="First page">
<a href="?{% add_to_qs page=1 %}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring inline-flex items-center justify-center" title="First page">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M3.22 7.595a.75.75 0 0 0 0 1.06l3.25 3.25a.75.75 0 0 0 1.06-1.06l-2.72-2.72 2.72-2.72a.75.75 0 0 0-1.06-1.06l-3.25 3.25Zm8.25-3.25-3.25 3.25a.75.75 0 0 0 0 1.06l3.25 3.25a.75.75 0 1 0 1.06-1.06l-2.72-2.72 2.72-2.72a.75.75 0 0 0-1.06-1.06Z" clip-rule="evenodd" /></svg></a>
{% else %}
<div class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="First page">
<div class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="First page">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M3.22 7.595a.75.75 0 0 0 0 1.06l3.25 3.25a.75.75 0 0 0 1.06-1.06l-2.72-2.72 2.72-2.72a.75.75 0 0 0-1.06-1.06l-3.25 3.25Zm8.25-3.25-3.25 3.25a.75.75 0 0 0 0 1.06l3.25 3.25a.75.75 0 1 0 1.06-1.06l-2.72-2.72 2.72-2.72a.75.75 0 0 0-1.06-1.06Z" clip-rule="evenodd" /></svg>
</div>
{% endif %}
{% if page_obj.has_previous %}
<a href="?{% add_to_qs page=page_obj.previous_page_number %}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring inline-flex items-center justify-center" title="Previous page">
<a href="?{% add_to_qs page=page_obj.previous_page_number %}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring inline-flex items-center justify-center" title="Previous page">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M9.78 4.22a.75.75 0 0 1 0 1.06L7.06 8l2.72 2.72a.75.75 0 1 1-1.06 1.06L5.47 8.53a.75.75 0 0 1 0-1.06l3.25-3.25a.75.75 0 0 1 1.06 0Z" clip-rule="evenodd" /></svg>
</a>
{% else %}
<div class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Previous page">
<div class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Previous page">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M9.78 4.22a.75.75 0 0 1 0 1.06L7.06 8l2.72 2.72a.75.75 0 1 1-1.06 1.06L5.47 8.53a.75.75 0 0 1 0-1.06l3.25-3.25a.75.75 0 0 1 1.06 0Z" clip-rule="evenodd" /></svg>
</div>
{% endif %}
{% if page_obj.has_next %}
<a href="?{% add_to_qs page=page_obj.next_page_number %}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring inline-flex items-center justify-center" title="Next page">
<a href="?{% add_to_qs page=page_obj.next_page_number %}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring inline-flex items-center justify-center" title="Next page">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M6.22 4.22a.75.75 0 0 1 1.06 0l3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06L8.94 8 6.22 5.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" /></svg>
</a>
{% else %}
<div class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Next page">
<div class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Next page">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M6.22 4.22a.75.75 0 0 1 1.06 0l3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06L8.94 8 6.22 5.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" /></svg>
</div>
{% endif %}
{% if page_obj.has_next %}
<a href="?{% add_to_qs page=page_obj.paginator.num_pages %}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring inline-flex items-center justify-center" title="Last page">
<a href="?{% add_to_qs page=page_obj.paginator.num_pages %}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring inline-flex items-center justify-center" title="Last page">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M12.78 7.595a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06l2.72-2.72-2.72-2.72a.75.75 0 0 1 1.06-1.06l3.25 3.25Zm-8.25-3.25 3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06l2.72-2.72-2.72-2.72a.75.75 0 0 1 1.06-1.06Z" clip-rule="evenodd" /></svg>
</a>
{% else %}
<div class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Last page">
<div class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md inline-flex items-center justify-center" title="Last page">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6"><path fill-rule="evenodd" d="M12.78 7.595a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06l2.72-2.72-2.72-2.72a.75.75 0 0 1 1.06-1.06l3.25 3.25Zm-8.25-3.25 3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06l2.72-2.72-2.72-2.72a.75.75 0 0 1 1.06-1.06Z" clip-rule="evenodd" /></svg>
</div>
@@ -79,27 +79,27 @@
<thead>
<tr>
<td class="p-4 align-top text-slate-800 font-bold">
<td class="p-4 align-top text-slate-800 dark:text-slate-100 font-bold">
#
</td>
<td class="p-4 align-top text-slate-800 font-bold">
<td class="p-4 align-top text-slate-800 dark:text-slate-100 font-bold">
ID
</td>
<td class="p-4 align-top text-slate-800 font-bold">
<td class="p-4 align-top text-slate-800 dark:text-slate-100 font-bold">
Timestamp
</td>
<td class="p-4 w-full align-top text-slate-800 font-bold">
<td class="p-4 w-full align-top text-slate-800 dark:text-slate-100 font-bold">
Title
</td>
<td class="p-4 align-top text-slate-800 font-bold">
<td class="p-4 align-top text-slate-800 dark:text-slate-100 font-bold">
Release
</td>
<td class="p-4 align-top text-slate-800 font-bold">
<td class="p-4 align-top text-slate-800 dark:text-slate-100 font-bold">
Environment
</td>
</tr>
@@ -116,13 +116,13 @@ TODO
{% endcomment %}
{% for event in page_obj %}
<tr class="border-slate-200 border-2 ">
<tr class="border-slate-200 dark:border-slate-700 border-2 ">
<td class="p-4 font-bold text-slate-500 align-top">
<td class="p-4 font-bold text-slate-500 dark:text-slate-300 align-top">
<a href="/issues/issue/{{ issue.id }}/event/{{ event.id }}/{% current_qs %}">{{ event.digest_order }}</a>
</td>
<td class="p-4 font-bold text-slate-500 align-top"> {# how useful is this really? #}
<td class="p-4 font-bold text-slate-500 dark:text-slate-300 align-top"> {# how useful is this really? #}
<a href="/issues/issue/{{ issue.id }}/event/{{ event.id }}/{% current_qs %}">{{ event.id|truncatechars:9 }}</a>
</td>
@@ -152,7 +152,7 @@ TODO
</tr>
{% empty %}
<tr>
<td colspan="6" class="p-4 text-slate-800 italic">
<td colspan="6" class="p-4 text-slate-800 dark:text-slate-100 italic">
No events found{% if q %} for "{{ q }}"{% endif %}.
</td>
</tr>

View File

@@ -11,15 +11,15 @@
<div class="flex"><!-- single turningpoint (for 'your comments')-->
<div class="flex-none">
<div class="pt-8 pr-2">
<img class="w-12 h-12 rounded-full border-2 border-slate-300" src="https://gravatar.com/avatar/{{ request.user|gravatar_sha }}?s=48&d=robohash" alt="{{ request.user|best_displayname }}">
<img class="w-12 h-12 rounded-full border-2 border-slate-300 dark:border-slate-600" src="https://gravatar.com/avatar/{{ request.user|gravatar_sha }}?s=48&d=robohash" alt="{{ request.user|best_displayname }}">
</div>
</div>
<div class="border-slate-300 border-2 rounded-md mt-6 flex-auto"><!-- the "your comments balloon" -->
<div class="border-slate-300 dark:border-slate-600 border-2 rounded-md mt-6 flex-auto"><!-- the "your comments balloon" -->
<div class="pl-4 flex triangle-left"><!-- 'header' row -->
<div class="mt-4 mb-4">
<span class="font-bold text-slate-800 italic">Add comment as manual annotation</span>
<span class="font-bold text-slate-800 dark:text-slate-100 italic">Add comment as manual annotation</span>
</div>
<div class="ml-auto flex"> <!-- 'header' row right side -->
<div class="p-4">
Now
@@ -27,12 +27,12 @@
</div>
</div>
<div class="border-t-2 pl-4 pr-4 pb-4 border-slate-300">{# 'body' part of the balloon (separated by a line) #}
<div class="border-t-2 pl-4 pr-4 pb-4 border-slate-300 dark:border-slate-600">{# 'body' part of the balloon (separated by a line) #}
<div class="mt-4">
<form action="{% url "history_comment_new" issue_pk=issue.id %}" method="post">
{% csrf_token %}
<textarea name="comment" placeholder="comments..." class="focus:border-cyan-500 focus:ring-cyan-200 rounded-md w-full h-32" onkeypress="submitOnCtrlEnter(event)"></textarea>
<button class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 mt-2 border-2 rounded-md hover:bg-slate-200 active:ring">Post comment</button>
<textarea name="comment" placeholder="comments..." class="bg-slate-50 dark:bg-slate-800 focus:border-cyan-500 dark:focus:border-cyan-400 focus:ring-cyan-200 dark:focus:ring-cyan-700 rounded-md w-full h-32" onkeypress="submitOnCtrlEnter(event)"></textarea>
<button class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 mt-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring">Post comment</button>
</form>
</div>
</div>{# 'body' part of the balloon #}
@@ -45,39 +45,39 @@
<div class="flex-none">
<div class="pt-8 pr-2">
{% if turningpoint.user_id %}
<img class="w-12 h-12 rounded-full border-2 border-slate-300" src="https://gravatar.com/avatar/{{ turningpoint.user|gravatar_sha }}?s=48&d=robohash" alt="{{ turningpoint.user|best_displayname }}">
<img class="w-12 h-12 rounded-full border-2 border-slate-300 dark:border-slate-600" src="https://gravatar.com/avatar/{{ turningpoint.user|gravatar_sha }}?s=48&d=robohash" alt="{{ turningpoint.user|best_displayname }}">
{% else %}
<img class="w-12 h-12 rounded-full border-2 border-slate-300" src="{% static 'images/bugsink-logo.png' %}" alt="Bugsink">
<img class="w-12 h-12 rounded-full border-2 border-slate-300 dark:border-slate-600" src="{% static 'images/bugsink-logo.png' %}" alt="Bugsink">
{% endif %}
</div>
</div>
<div class="border-slate-300 border-2 rounded-md mt-6 flex-auto js-balloon"><!-- the "balloon" -->
<div class="border-slate-300 dark:border-slate-600 border-2 rounded-md mt-6 flex-auto js-balloon"><!-- the "balloon" -->
<div class="pl-4 flex triangle-left"><!-- 'header' row -->
<div class="mt-4 mb-4">
<span class="font-bold text-slate-800">{{ turningpoint.get_kind_display }}</span> by
<span class="font-bold text-slate-800">{% if turningpoint.user_id %}{{ turningpoint.user|best_displayname }}{% else %}Bugsink{% endif %}</span>
<span class="font-bold text-slate-800 dark:text-slate-100">{{ turningpoint.get_kind_display }}</span> by
<span class="font-bold text-slate-800 dark:text-slate-100">{% if turningpoint.user_id %}{{ turningpoint.user|best_displayname }}{% else %}Bugsink{% endif %}</span>
{% if turningpoint.user_id == request.user.id %}
<span class="text-slate-500 pl-1" onclick="toggleCommentEditable(this)" title="Edit comment">
<span class="text-slate-500 dark:text-slate-300 pl-1" onclick="toggleCommentEditable(this)" title="Edit comment">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-4 h-4 inline">
<path fill-rule="evenodd" d="M11.013 2.513a1.75 1.75 0 0 1 2.475 2.474L6.226 12.25a2.751 2.751 0 0 1-.892.596l-2.047.848a.75.75 0 0 1-.98-.98l.848-2.047a2.75 2.75 0 0 1 .596-.892l7.262-7.261Z" clip-rule="evenodd" />
</svg>
</span>
{% if turningpoint.kind == 100 %}
<span class="text-slate-500 pl-1" onclick="deleteComment('{% url "history_comment_delete" issue_pk=issue.id comment_pk=turningpoint.pk %}')" title="Delete comment">
<span class="text-slate-500 dark:text-slate-300 pl-1" onclick="deleteComment('{% url "history_comment_delete" issue_pk=issue.id comment_pk=turningpoint.pk %}')" title="Delete comment">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-4 h-4 inline">
<path fill-rule="evenodd" d="M5 3.25V4H2.75a.75.75 0 0 0 0 1.5h.3l.815 8.15A1.5 1.5 0 0 0 5.357 15h5.285a1.5 1.5 0 0 0 1.493-1.35l.815-8.15h.3a.75.75 0 0 0 0-1.5H11v-.75A2.25 2.25 0 0 0 8.75 1h-1.5A2.25 2.25 0 0 0 5 3.25Zm2.25-.75a.75.75 0 0 0-.75.75V4h3v-.75a.75.75 0 0 0-.75-.75h-1.5ZM6.05 6a.75.75 0 0 1 .787.713l.275 5.5a.75.75 0 0 1-1.498.075l-.275-5.5A.75.75 0 0 1 6.05 6Zm3.9 0a.75.75 0 0 1 .712.787l-.275 5.5a.75.75 0 0 1-1.498-.075l.275-5.5a.75.75 0 0 1 .786-.711Z" clip-rule="evenodd" />
</svg>
</span>
{% endif %}
{% endif %}
</div>
<div class="ml-auto flex"> <!-- 'header' row right side -->
<div class="p-4 text-right">
@@ -87,7 +87,7 @@
</div>
{% if turningpoint.parsed_metadata or turningpoint.triggering_event_id or turningpoint.comment or turningpoint.user_id == request.user.id %} {# the last clause means: editable, hence space must be reserved #}
<div class="border-t-2 pl-4 pr-4 pb-4 border-slate-300">{# 'body' part of the balloon (separated by a line) #}
<div class="border-t-2 pl-4 pr-4 pb-4 border-slate-300 dark:border-slate-600">{# 'body' part of the balloon (separated by a line) #}
<div class="mt-4">
<div class="js-comment-plain">
{{ turningpoint.comment|linebreaksbr }}
@@ -97,8 +97,8 @@
<div class="js-comment-editable hidden">
<form action="{% url "history_comment_edit" issue_pk=issue.id comment_pk=turningpoint.pk %}" method="post">
{% csrf_token %}
<textarea name="comment" placeholder="comments..." class="focus:border-cyan-500 focus:ring-cyan-200 rounded-md w-full h-32" onkeypress="submitOnCtrlEnter(event)">{{ turningpoint.comment }}</textarea>{# note: we don't actually use {{ form.comments }} here; this means the show-red-on-invalid loop won't work but since everything is valid and we haven't implemented the other parts of that loop that's fine #}
<button class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 mt-2 border-2 rounded-md hover:bg-slate-200 active:ring">Update comment</button>
<textarea name="comment" placeholder="comments..." class="bg-slate-50 dark:bg-slate-800 focus:border-cyan-500 dark:focus:border-cyan-400 focus:ring-cyan-200 dark:focus:ring-cyan-700 rounded-md w-full h-32" onkeypress="submitOnCtrlEnter(event)">{{ turningpoint.comment }}</textarea>{# note: we don't actually use {{ form.comments }} here; this means the show-red-on-invalid loop won't work but since everything is valid and we haven't implemented the other parts of that loop that's fine #}
<button class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 mt-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring">Update comment</button>
</form>
</div>
{% endif %}
@@ -150,7 +150,7 @@
{% if turningpoint.triggering_event_id %}
<div class="mt-4">
<a href="{% url "event_by_internal_id" event_pk=turningpoint.triggering_event_id %}" class="underline decoration-dotted font-bold text-slate-500">Triggering event</a>
<a href="{% url "event_by_internal_id" event_pk=turningpoint.triggering_event_id %}" class="underline decoration-dotted font-bold text-slate-500 dark:text-slate-300">Triggering event</a>
</div>
{% endif %}

View File

@@ -35,17 +35,17 @@
</div>
{% endif %}
<div class="flex bg-slate-50 border-b-2 mt-4 items-end">
<div class="flex bg-slate-50 dark:bg-slate-800 border-b-2 mt-4 items-end">
<div class="flex">
<a href="{% url "issue_list_open" project_pk=project.id %}"><div class="p-4 font-bold hover:bg-slate-200 {% if state_filter == "open" %}text-cyan-500 border-cyan-500 border-b-4 {% else %}text-slate-500 hover:border-b-4 hover:border-slate-400{% endif %}">Open</div></a>
<a href="{% url "issue_list_unresolved" project_pk=project.id %}"><div class="p-4 font-bold hover:bg-slate-200 {% if state_filter == "unresolved" %}text-cyan-500 border-cyan-500 border-b-4 {% else %}text-slate-500 hover:border-b-4 hover:border-slate-400{% endif %}">Unresolved</div></a>
<a href="{% url "issue_list_muted" project_pk=project.id %}"><div class="p-4 font-bold hover:bg-slate-200 {% if state_filter == "muted" %}text-cyan-500 border-cyan-500 border-b-4{% else %}text-slate-500 hover:border-slate-400 hover:border-b-4{% endif %}">Muted</div></a>
<a href="{% url "issue_list_resolved" project_pk=project.id %}"><div class="p-4 font-bold hover:bg-slate-200 {% if state_filter == "resolved" %}text-cyan-500 border-cyan-500 border-b-4 {% else %}text-slate-500 hover:border-slate-400 hover:border-b-4{% endif %}">Resolved</div></a>
<a href="{% url "issue_list_all" project_pk=project.id %}"><div class="p-4 font-bold hover:bg-slate-200 {% if state_filter == "all" %}text-cyan-500 border-cyan-500 border-b-4{% else %}text-slate-500 hover:border-slate-400 hover:border-b-4{% endif %}">All</div></a>
<a href="{% url "issue_list_open" project_pk=project.id %}"><div class="p-4 font-bold hover:bg-slate-200 dark:hover:bg-slate-800 {% if state_filter == "open" %}text-cyan-500 dark:text-cyan-300 border-cyan-500 border-b-4 {% else %}text-slate-500 dark:text-slate-300 hover:border-b-4 hover:border-slate-400{% endif %}">Open</div></a>
<a href="{% url "issue_list_unresolved" project_pk=project.id %}"><div class="p-4 font-bold hover:bg-slate-200 dark:hover:bg-slate-800 {% if state_filter == "unresolved" %}text-cyan-500 dark:text-cyan-300 border-cyan-500 border-b-4 {% else %}text-slate-500 dark:text-slate-300 hover:border-b-4 hover:border-slate-400{% endif %}">Unresolved</div></a>
<a href="{% url "issue_list_muted" project_pk=project.id %}"><div class="p-4 font-bold hover:bg-slate-200 dark:hover:bg-slate-800 {% if state_filter == "muted" %}text-cyan-500 dark:text-cyan-300 border-cyan-500 border-b-4{% else %}text-slate-500 dark:text-slate-300 hover:border-slate-400 hover:border-b-4{% endif %}">Muted</div></a>
<a href="{% url "issue_list_resolved" project_pk=project.id %}"><div class="p-4 font-bold hover:bg-slate-200 dark:hover:bg-slate-800 {% if state_filter == "resolved" %}text-cyan-500 dark:text-cyan-300 border-cyan-500 border-b-4 {% else %}text-slate-500 dark:text-slate-300 hover:border-slate-400 hover:border-b-4{% endif %}">Resolved</div></a>
<a href="{% url "issue_list_all" project_pk=project.id %}"><div class="p-4 font-bold hover:bg-slate-200 dark:hover:bg-slate-800 {% if state_filter == "all" %}text-cyan-500 dark:text-cyan-300 border-cyan-500 border-b-4{% else %}text-slate-500 dark:text-slate-300 hover:border-slate-400 hover:border-b-4{% endif %}">All</div></a>
</div>
<div class="ml-auto p-2">
<form action="." method="get">
<input type="text" name="q" value="{{ q }}" placeholder="search issues..." class="focus:border-cyan-500 focus:ring-cyan-200 rounded-md"/>
<input type="text" name="q" value="{{ q }}" placeholder="search issues..." class="bg-slate-50 dark:bg-slate-800 focus:border-cyan-500 dark:focus:border-cyan-400 focus:ring-cyan-200 dark:focus:ring-cyan-700 rounded-md"/>
</form>
</div>
</div>
@@ -58,12 +58,12 @@
<table class="w-full">
<thead> {# I briefly considered hiding this thead if there are no items but it actually looks worse; instead, we just hide that one checkbox #}
<tr class="bg-white border-slate-300 border-l-2 border-r-2">
<tr class="bg-white dark:bg-slate-900 border-slate-300 dark:border-slate-600 border-l-2 border-r-2">
<td>
<div class="m-1 rounded-full hover:bg-slate-100 cursor-pointer" onclick="toggleContainedCheckbox(this); matchIssueCheckboxesStateToMain(this)">
<div class="m-1 rounded-full hover:bg-slate-100 dark:hover:bg-slate-700 cursor-pointer" onclick="toggleContainedCheckbox(this); matchIssueCheckboxesStateToMain(this)">
{# the below sounds expensive, but this list is cached #}
{% if page_obj.object_list|length > 0 %}<input type="checkbox" class="bg-white border-cyan-800 text-cyan-500 focus:ring-cyan-200 m-4 cursor-pointer js-main-checkbox" onclick="event.stopPropagation(); matchIssueCheckboxesStateToMain(this.parentNode)"/>{% endif %}
{% if page_obj.object_list|length > 0 %}<input type="checkbox" class="bg-white dark:bg-slate-900 border-cyan-800 dark:border-cyan-400 text-cyan-500 dark:text-cyan-300 focus:ring-cyan-200 dark:focus:ring-cyan-700 m-4 cursor-pointer js-main-checkbox" onclick="event.stopPropagation(); matchIssueCheckboxesStateToMain(this.parentNode)"/>{% endif %}
</div>
</td>
<td class="w-full ml-0 pb-4 pt-4 pr-4 flex">
@@ -71,16 +71,16 @@
{% if disable_resolve_buttons %}
{# see issues/tests.py for why this is turned off ATM #}
{# <button 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" name="action" value="reopen">Reopen</button> #}
{# <button class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md" name="action" value="reopen">Reopen</button> #}
{% spaceless %}{# needed to avoid whitespace between the looks-like-one-buttons #}
{% if project.has_releases %}
<button disabled class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 rounded-s-md" name="action" value="resolved_next">Resolved in next release</button>
<button disabled class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 rounded-s-md" name="action" value="resolved_next">Resolved in next release</button>
<button disabled class="font-bold text-slate-300 fill-slate-300 border-slate-300 pl-4 pr-4 pb-2 pt-2 border-r-2 border-t-2 border-b-2 rounded-e-md"><svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
<button disabled class="font-bold text-slate-300 dark:text-slate-600 fill-slate-300 dark:fill-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 border-r-2 border-t-2 border-b-2 rounded-e-md"><svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
{# we just hide the whole dropdown; this is the easiest implementation of not-showing the dropdown #}
{% else %}
<button disabled class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 rounded-md" name="action" value="resolved">Resolve</button>
<button disabled class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 rounded-md" name="action" value="resolved">Resolve</button>
{% endif %}
{% endspaceless %}
@@ -88,24 +88,24 @@
{% spaceless %}{# needed to avoid whitespace between the looks-like-one-buttons #}
{% if project.has_releases %}
{# 'by next' is shown even if 'by current' is also shown: just because you haven't seen 'by current' doesn't mean it's actually already solved; and in fact we show this option first precisely because we can always show it #}
<button 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-s-md" name="action" value="resolved_next">Resolved in next release</button>
{# 'by next' is shown even if 'by current' is also shown: just because you haven't seen 'by current' doesn't mean it's actually already solved; and in fact we show this option first precisely because we can always show it #}
<button class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-s-md" name="action" value="resolved_next">Resolved in next release</button>
<div class="dropdown">
<button disabled {# disabled b/c clicking the dropdown does nothing - we have hover for that #} class="font-bold text-slate-800 fill-slate-800 border-slate-500 pl-4 pr-4 pb-2 pt-2 border-r-2 border-t-2 border-b-2 hover:bg-slate-200 active:ring rounded-e-md"><svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
<button disabled {# disabled b/c clicking the dropdown does nothing - we have hover for that #} class="font-bold text-slate-800 dark:text-slate-100 fill-slate-800 dark:fill-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-r-2 border-t-2 border-b-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-e-md"><svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
{# note that we can depend on get_latest_release being available, because we're in the 'project.has_releases' branch #}
<div class="dropdown-content-right flex-col pl-2">
{# note that an if-statement ("issue.occurs_in_last_release") is missing here, because we're not on the level of a single issue #}
{# note that an if-statement ("issue.occurs_in_last_release") is missing here, because we're not on the level of a single issue #}
{# handling of that question (but per-issue, and after-click) is done in views.py, _q_for_invalid_for_action() #}
<button name="action" value="resolved_release:{{ project.get_latest_release.version }}" class="block self-stretch font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 border-l-2 border-r-2 border-b-2 bg-white hover:bg-slate-200 active:ring text-left whitespace-nowrap">Resolved in latest ({{ project.get_latest_release.get_short_version }})</button>
<button name="action" value="resolved_release:{{ project.get_latest_release.version }}" class="block self-stretch font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 border-l-2 border-r-2 border-b-2 bg-white dark:bg-slate-900 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring text-left whitespace-nowrap">Resolved in latest ({{ project.get_latest_release.get_short_version }})</button>
</div>
</div>
</div>
{% else %}
<button 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" name="action" value="resolve">Resolve</button>
<button class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md" name="action" value="resolve">Resolve</button>
{% endif %}
{% endspaceless %}
@@ -113,30 +113,30 @@
{% spaceless %}{# needed to avoid whitespace between the looks-like-one-buttons #}
{% if not disable_mute_buttons %}
<button name="action" value="mute" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 hover:bg-slate-200 active:ring rounded-s-md">Mute</button>
<button name="action" value="mute" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-s-md">Mute</button>
{% else %}
<button disabled name="action" value="mute" class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 rounded-s-md">Mute</button>
<button disabled name="action" value="mute" class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 rounded-s-md">Mute</button>
{% endif %}
<div class="dropdown">
{% if not disable_mute_buttons %}
<button disabled {# disabled b/c clicking the dropdown does nothing - we have hover for that #} class="font-bold text-slate-500 fill-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2 hover:bg-slate-200 active:ring">Mute for/until&nbsp;&nbsp;<svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
<button disabled {# disabled b/c clicking the dropdown does nothing - we have hover for that #} class="font-bold text-slate-500 dark:text-slate-300 fill-slate-500 dark:fill-slate-500 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring">Mute for/until&nbsp;&nbsp;<svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
<div class="dropdown-content-right flex-col">
{% for mute_option in mute_options %}
<button name="action" value="mute_{{ mute_option.for_or_until }}:{{ mute_option.period_name }},{{ mute_option.nr_of_periods }},{{ mute_option.gte_threshold }}" class="block self-stretch font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 border-l-2 border-r-2 border-b-2 bg-white hover:bg-slate-200 active:ring text-left whitespace-nowrap">{% if mute_option.for_or_until == "for" %}{{ mute_option.nr_of_periods }} {{ mute_option.period_name }}{% if mute_option.nr_of_periods != 1 %}s{% endif %}{% else %}{{ mute_option.gte_threshold }} events per {% if mute_option.nr_of_periods != 1%} {{ mute_option.nr_of_periods }} {{ mute_option.period_name }}s{% else %} {{ mute_option.period_name }}{% endif %}{% endif %}</button>
<button name="action" value="mute_{{ mute_option.for_or_until }}:{{ mute_option.period_name }},{{ mute_option.nr_of_periods }},{{ mute_option.gte_threshold }}" class="block self-stretch font-bold text-slate-500 dark:text-slate-300 border-slate-300 pl-4 pr-4 pb-2 pt-2 border-l-2 border-r-2 border-b-2 bg-white dark:bg-slate-900 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring text-left whitespace-nowrap">{% if mute_option.for_or_until == "for" %}{{ mute_option.nr_of_periods }} {{ mute_option.period_name }}{% if mute_option.nr_of_periods != 1 %}s{% endif %}{% else %}{{ mute_option.gte_threshold }} events per {% if mute_option.nr_of_periods != 1%} {{ mute_option.nr_of_periods }} {{ mute_option.period_name }}s{% else %} {{ mute_option.period_name }}{% endif %}{% endif %}</button>
{% endfor %}
</div>
{% else %}
<button disabled class="font-bold text-slate-300 fill-slate-300 border-slate-300 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2">Mute for/until&nbsp;&nbsp;<svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
<button disabled class="font-bold text-slate-300 dark:text-slate-600 fill-slate-300 dark:fill-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2">Mute for/until&nbsp;&nbsp;<svg xmlns="http://www.w3.org/2000/svg" fill="full" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 inline"><path d="M6.5,8.5l6,7l6-7H6.5z"/></svg></button>
{# we just hide the whole dropdown; this is the easiest implementation of not-showing the dropdown when the issue is already muted #}
{% endif %}
</div>
</div>
{% if not disable_unmute_buttons %}
<button class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2 hover:bg-slate-200 active:ring rounded-e-md" name="action" value="unmute">Unmute</button>
<button class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-e-md" name="action" value="unmute">Unmute</button>
{% else %}
<button disabled class="font-bold text-slate-300 border-slate-300 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2 rounded-e-md" name="action" value="unmute">Unmute</button>
<button disabled class="font-bold text-slate-300 dark:text-slate-600 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 border-r-2 border-b-2 border-t-2 rounded-e-md" name="action" value="unmute">Unmute</button>
{% endif %}
<div class="dropdown">
@@ -152,7 +152,7 @@
{# NOTE: "reopen" is not available in the UI as per the notes in issue_detail #}
{# only for resolved/muted items <button class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 hover:bg-slate-200 active:ring rounded-md">Reopen</button> #}
{# only for resolved/muted items <button class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Reopen</button> #}
</div>
</td>
@@ -161,15 +161,15 @@
</thead>
<tbody>
{% for issue in page_obj %}
<tr class="bg-slate-50 border-slate-300 border-2 ">
<tr class="bg-slate-50 dark:bg-slate-800 border-slate-300 dark:border-slate-600 border-2 ">
<td>
<div class="m-1 rounded-full hover:bg-slate-100 cursor-pointer" onclick="toggleContainedCheckbox(this); matchMainCheckboxStateToIssueCheckboxes()">
<input type="checkbox" {% if issue.id in unapplied_issue_ids %}checked{% endif %} name="issue_ids[]" value="{{ issue.id }}" class="bg-white border-cyan-800 text-cyan-500 focus:ring-cyan-200 m-4 cursor-pointer js-issue-checkbox" onclick="event.stopPropagation(); {# prevent the container's handler from undoing the default action #} matchMainCheckboxStateToIssueCheckboxes()"/>
<div class="m-1 rounded-full hover:bg-slate-100 dark:hover:bg-slate-700 cursor-pointer" onclick="toggleContainedCheckbox(this); matchMainCheckboxStateToIssueCheckboxes()">
<input type="checkbox" {% if issue.id in unapplied_issue_ids %}checked{% endif %} name="issue_ids[]" value="{{ issue.id }}" class="bg-white dark:bg-slate-900 border-cyan-800 dark:border-cyan-400 text-cyan-500 dark:text-cyan-300 focus:ring-cyan-200 dark:focus:ring-cyan-700 m-4 cursor-pointer js-issue-checkbox" onclick="event.stopPropagation(); {# prevent the container's handler from undoing the default action #} matchMainCheckboxStateToIssueCheckboxes()"/>
</div>
</td>
<td class="w-full ml-0 pb-4 pt-4 pr-4">
<div>
<a href="/issues/issue/{{ issue.id }}/event/last/{% current_qs %}" class="text-cyan-500 fill-cyan-500 font-bold {% if issue.is_resolved %}italic{% endif %}">{% if issue.is_resolved %}<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6 inline"><path fill-rule="evenodd" d="M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z" clip-rule="evenodd" />
<a href="/issues/issue/{{ issue.id }}/event/last/{% current_qs %}" class="text-cyan-500 dark:text-cyan-300 fill-cyan-500 font-bold {% if issue.is_resolved %}italic{% endif %}">{% if issue.is_resolved %}<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-6 h-6 inline"><path fill-rule="evenodd" d="M12.416 3.376a.75.75 0 0 1 .208 1.04l-5 7.5a.75.75 0 0 1-1.154.114l-3-3a.75.75 0 0 1 1.06-1.06l2.353 2.353 4.493-6.74a.75.75 0 0 1 1.04-.207Z" clip-rule="evenodd" />
</svg>{% endif %}{% if issue.is_muted %}<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 inline">
<path stroke-linecap="round" stroke-linejoin="round" d="M17.25 9.75 19.5 12m0 0 2.25 2.25M19.5 12l2.25-2.25M19.5 12l-2.25 2.25m-10.5-6 4.72-4.72a.75.75 0 0 1 1.28.53v15.88a.75.75 0 0 1-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.009 9.009 0 0 1 2.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75Z" />
</svg>&nbsp;&nbsp;{% endif %}{{ issue.title|truncatechars:100 }}</a>
@@ -185,19 +185,19 @@
</tr>
{% empty %}
<tr class="bg-slate-50 border-slate-300 border-2 ">
<tr class="bg-slate-50 dark:bg-slate-800 border-slate-300 dark:border-slate-600 border-2 ">
<td>
</td>
<td class="w-full ml-0 pb-4 pt-4 pr-4 text-center">
<div class="p-4 text-xl font-bold text-slate-800">
<div class="p-4 text-xl font-bold text-slate-800 dark:text-slate-100">
{% if q %}{# a single text is the catch-all for searching w/o results; 'seems enough' because one would generally only search after already having seen some issues (or not), i.e. having seen the relevant message as per below #}
No {{ state_filter }} issues found for "{{ q }}"
{% else %}
{% if state_filter == "open" %}
Congratulations! You have no open issues.
{% if project.digested_event_count == 0 %}
This might mean you have not yet <a class="text-cyan-500 font-bold" href="{% url "project_sdk_setup" project_pk=project.id %}">set up your SDK</a>.
This might mean you have not yet <a class="text-cyan-500 dark:text-cyan-300 font-bold" href="{% url "project_sdk_setup" project_pk=project.id %}">set up your SDK</a>.
{% endif %}
{% else %}
No {{ state_filter }} issues found.
@@ -251,7 +251,7 @@
<div class="flex ml-auto justify-end">{# the div with a few project-related icons (pjt-members, pjt-settings, my settings, dsn) on the lower RHS #}
{% if not app_settings.SINGLE_USER %}{% if member.is_admin or request.user.is_superuser %}
<div class="rounded-full hover:bg-slate-100 p-2 cursor-pointer text-slate-700" onclick="followContainedLink(this);" title="Project members">
<div class="rounded-full hover:bg-slate-100 dark:hover:bg-slate-700 p-2 cursor-pointer text-slate-700" onclick="followContainedLink(this);" title="Project members">
<a href="{% url 'project_members' 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="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z" />
@@ -261,7 +261,7 @@
{% endif %}{% endif %}
{% if member.is_admin or request.user.is_superuser %}
<div class="rounded-full hover:bg-slate-100 p-2 cursor-pointer text-slate-700" onclick="followContainedLink(this);" title="Project settings">
<div class="rounded-full hover:bg-slate-100 dark:hover:bg-slate-700 p-2 cursor-pointer text-slate-700" onclick="followContainedLink(this);" title="Project settings">
<a href="{% url 'project_edit' 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="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z" />
@@ -272,7 +272,7 @@
{% endif %}
{# member-existance is implied if you can see this page #}
<div class="rounded-full hover:bg-slate-100 p-2 cursor-pointer text-slate-700" onclick="followContainedLink(this);" title="Project membership (notification settings){# verbose! #}">
<div class="rounded-full hover:bg-slate-100 dark:hover:bg-slate-700 p-2 cursor-pointer text-slate-700" onclick="followContainedLink(this);" title="Project membership (notification settings){# verbose! #}">
<a href="{% url 'project_member_settings' project_pk=project.id user_pk=request.user.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" />
@@ -281,7 +281,7 @@
</div>
{# member-existance is implied if you can see this page #}
<div class="rounded-full hover:bg-slate-100 p-2 cursor-pointer text-slate-700" onclick="followContainedLink(this);" title="SDK Setup (connect app)">
<div class="rounded-full hover:bg-slate-100 dark:hover:bg-slate-700 p-2 cursor-pointer text-slate-700" onclick="followContainedLink(this);" title="SDK Setup (connect app)">
<a href="{% url 'project_sdk_setup' project_pk=project.id %}">
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="size-8">
<path d="M202.7,259.7l-31.5,31.5c-5.6,5.6-8.6,13-8.6,20.9c0,7.9,3.1,15.3,8.6,20.9l6.1,6.1l-3.7,3.7c-11.1,11.1-29.2,11.1-40.4,0

View File

@@ -40,10 +40,10 @@
{% if forloop.counter0 == 0 %}
<div class="ml-auto flex-none">
<div class="flex place-content-end">
<button class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring" onclick="showAllFrames()">Show all</button>
<button class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring" onclick="showInAppFrames()">Show in-app</button>
<button class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring" onclick="showRaisingFrame()">Show raise</button>
<button class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring" onclick="hideAllFrames()">Collapse all</button>
<button class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring" onclick="showAllFrames()">Show all</button>
<button class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring" onclick="showInAppFrames()">Show in-app</button>
<button class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring" onclick="showRaisingFrame()">Show raise</button>
<button class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-800 active:ring" onclick="hideAllFrames()">Collapse all</button>
{% include "issues/_event_nav.html" %}
</div>
@@ -53,13 +53,13 @@
{% for frame in exception.stacktrace.frames %}
{% with frame=frame|pygmentize:event.platform %}
<div class="bg-white w-full font-mono"> {# per frame div #}
<div class="bg-white dark:bg-slate-900 w-full font-mono"> {# per frame div #}
{% if frame.raise_point %}<span id="raise"></span>{% endif %}
{% if frame.in_app %}<span id="in-app"></span>{% endif %}
{% if forloop.first and forloop.parentloop.first %}<span id="first-frame"></span>{% endif %}
<div class="flex pl-4 pt-2 pb-2 border-b-2 {% if forloop.first %}border-t-2{% endif %} bg-slate-100 border-slate-400 cursor-pointer" onclick="toggleFrameVisibility(this)"> {# per frame header div #}
<div class="flex pl-4 pt-2 pb-2 border-b-2 {% if forloop.first %}border-t-2{% endif %} bg-slate-100 dark:bg-slate-700 border-slate-400 cursor-pointer" onclick="toggleFrameVisibility(this)"> {# per frame header div #}
<div> {# filename, function, lineno #}
{% if frame.in_app %}
@@ -72,13 +72,13 @@
<div class="ml-auto pr-4">{# indicator for frame's position in stacktrace #}
{% if stack_of_plates and forloop.first or not stack_of_plates and forloop.last %}
{% if stack_of_plates and forloop.parentloop.first or not stack_of_plates and forloop.parentloop.last %}
<span class="bg-slate-200 pl-2 pr-2 pt-1 pb-1 rounded-md whitespace-nowrap">raise {{ exception.type }}</span>
<span class="bg-slate-200 dark:bg-slate-800 pl-2 pr-2 pt-1 pb-1 rounded-md whitespace-nowrap">raise {{ exception.type }}</span>
{% else %}
<span class="bg-slate-200 pl-2 pr-2 pt-1 pb-1 rounded-md whitespace-nowrap">raise {{ exception.type }} (handled)</span>
<span class="bg-slate-200 dark:bg-slate-800 pl-2 pr-2 pt-1 pb-1 rounded-md whitespace-nowrap">raise {{ exception.type }} (handled)</span>
{% endif %}
{% elif stack_of_plates and forloop.last or not stack_of_plates and forloop.first %} {# strictly speaking, not actually "else", but to avoid clutter we hide 'outermost' info when this is also the raise-point #}
{% if stack_of_plates and forloop.parentloop.first or not stack_of_plates and forloop.parentloop.last %}
<span class="bg-slate-200 pl-2 pr-2 pt-1 pb-1 rounded-md whitespace-nowrap">→ begin</span>
<span class="bg-slate-200 dark:bg-slate-800 pl-2 pr-2 pt-1 pb-1 rounded-md whitespace-nowrap">→ begin</span>
{% else %}
{% comment %}I find it (quite too) hard to come up with a good name for this type of frame that is both short and clear. Thoughts so fare were:
* try...
@@ -90,7 +90,7 @@
* "divergence w/ main exception"
* first unique frame
{% endcomment %}
<span class="bg-slate-200 pl-2 pr-2 pt-1 pb-1 rounded-md whitespace-nowrap">try…</span>
<span class="bg-slate-200 dark:bg-slate-800 pl-2 pr-2 pt-1 pb-1 rounded-md whitespace-nowrap">try…</span>
{% endif %}
{% endif %}
@@ -103,12 +103,12 @@
</div>
</div> {# per frame header div #}
<div class="js-frame-details {% if frame.in_app %}js-in-app{% endif %} border-slate-400 overflow-hidden transition-all {% if stack_of_plates and forloop.parentloop.first and forloop.first or not stack_of_plates and forloop.parentloop.last and forloop.last %}js-raising-frame{% endif %}"
<div class="js-frame-details {% if frame.in_app %}js-in-app{% endif %} border-slate-400 overflow-hidden transition-all {% if stack_of_plates and forloop.parentloop.first and forloop.first or not stack_of_plates and forloop.parentloop.last and forloop.last %}js-raising-frame{% endif %}"
{% if not frame.raise_point %}data-collapsed="true" style="height: 0px"{% endif %}> {# collapsable part #}
<div class="pl-6 pr-6 {% if not forloop.last %}border-b-2 border-slate-400{% endif %}">{# convience div for padding & border; the border is basically the top-border of the next header #}
{% if "context_line" in frame and frame.context_line is not None %}
<div class="bg-slate-50 syntax-coloring mt-6 mb-6">{# code listing #}
<div class="bg-slate-50 dark:bg-slate-800 syntax-coloring mt-6 mb-6">{# code listing #}
{# the spread-out pX-6 in this code is intentional to ensure the padding is visible when scrolling to the right, and not visible when scrolling is possible (i.e. the text is cut-off awkwardly to hint at scrolling #}
<ol class="list-decimal overflow-x-auto list-inside pt-6 pb-6 {% if frame|firstlineno is None %}list-none{% endif %}" start="{{ frame|firstlineno }}">
{% for line in frame.pre_context %}<li class="pl-6"><div class="whitespace-pre w-full inline pr-6">{{ line }} {# leave space to avoid collapse #}</div></li>{% endfor %}
@@ -123,13 +123,13 @@
{% if frame.vars %}
<div class="mt-4 mb-6">{# variables #}
<div class="flex">
<div class="w-1/3 pt-2 font-bold border-b-2 border-slate-500 pl-4">Variable</div>
<div class="w-2/3 pt-2 font-bold border-b-2 border-slate-500 pr-4">Value</div>
<div class="w-1/3 pt-2 font-bold border-b-2 border-slate-500 dark:border-slate-400 pl-4">Variable</div>
<div class="w-2/3 pt-2 font-bold border-b-2 border-slate-500 dark:border-slate-400 pr-4">Value</div>
</div>
{% for var, value in frame.vars|items %}
<div class="flex">
<div class="w-1/3 pl-4 {% if not forloop.last or frame.vars|incomplete %}border-b-2 border-dotted border-slate-300{% endif %}">{{ var }}</div>
<div class="w-2/3 pr-4 {% if not forloop.last or frame.vars|incomplete %} border-b-2 border-dotted border-slate-300{% endif %}">{{ value|format_var }}</div>
<div class="w-1/3 pl-4 {% if not forloop.last or frame.vars|incomplete %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ var }}</div>
<div class="w-2/3 pr-4 {% if not forloop.last or frame.vars|incomplete %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ value|format_var }}</div>
</div>
{% endfor %}
{% if frame.vars|incomplete %}

View File

@@ -8,11 +8,11 @@
<h1 id="{{ issuetags.0.key.key }}" class="text-2xl font-bold mt-4">{{ issuetags.0.key.key }}:</h1>
<div class="mb-6">
{% for issuetag in issuetags %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-2/3 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ issuetag.value.value }}</div>
<div class="w-1/6 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ issuetag.pct }}%</div>
<div class="w-1/6 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ issuetag.count }} events</div>
{% for issuetag in issuetags %}
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-2/3 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ issuetag.value.value }}</div>
<div class="w-1/6 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ issuetag.pct }}%</div>
<div class="w-1/6 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ issuetag.count }} events</div>
</div>
{% endfor %}
</div>

View File

@@ -15,7 +15,7 @@
<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>
<li class="bg-cyan-50 dark:bg-cyan-900 border-2 border-cyan-800 dark:border-cyan-400 p-4 rounded-lg">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
@@ -24,8 +24,8 @@
<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>
<a class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md" href="{% url "project_messaging_service_add" project_pk=project.pk %}">Add</a>
</div>
</div>
<div>
@@ -35,31 +35,31 @@
<table class="w-full mt-8">
<tbody>
<thead>
<tr class="bg-slate-200">
<tr class="bg-slate-200 dark:bg-slate-800">
<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">
<tr class="bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-700 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>
<a href="{% url "project_messaging_service_edit" project_pk=project.pk service_pk=service_config.pk %}" class="text-xl text-cyan-500 dark:text-cyan-300 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>
<button name="action" value="test:{{ service_config.id }}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Test</button>
<button name="action" value="remove:{{ service_config.id }}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Remove</button>
</div>
</td>
</tr>
{% empty %}
<tr class="bg-white border-slate-200 border-b-2">
<tr class="bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-700 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>.
No Messaging Services Configured. <a href="{% url "project_messaging_service_add" project_pk=project.pk %}" class="text-cyan-500 dark:text-cyan-300 font-bold">Add Messaging Service</a>.
</div>
</td>
</tr>
@@ -73,8 +73,8 @@
<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>
<a href="{% url "project_edit" project_pk=project.pk %}" class="text-cyan-500 dark:text-cyan-300 font-bold">Settings</a>
<span class="font-bold text-slate-500 dark:text-slate-300">|</span> <a href="{% url "project_list" %}" class="text-cyan-500 dark:text-cyan-300 font-bold">Back to Projects</a>
</div>
</div>
</div>

View File

@@ -47,8 +47,8 @@
{% tailwind_formfield form.dsn %}
<div class="flex items-center mt-4">
<button name="action" value="save" class="font-bold py-2 px-4 rounded bg-cyan-200 text-slate-800 border-2 border-slate-500 hover:bg-cyan-400 active:ring">Save</button>
<a href="{% url "project_list" %}" class="text-cyan-500 font-bold ml-4">Cancel</a>
<button name="action" value="invite" class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md">Save</button>
<a href="{% url "project_list" %}" class="text-cyan-500 dark:text-cyan-300 font-bold ml-2">Cancel</a>
<button type="button" id="deleteButton" class="font-bold py-2 px-4 rounded bg-red-500 text-white border-2 border-red-600 hover:bg-red-600 active:ring ml-auto">Delete Project</button>
</div>
</form>

View File

@@ -17,7 +17,7 @@
<div class="ml-auto"><!-- top, RHS (buttons) -->
{% if can_create %}
<div>
<a class="block 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_new' %}">New Project</a>
<a class="block font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md" href="{% url 'project_new' %}">New Project</a>
</div>
{% endif %}
</div> {# top, RHS (buttons) #}
@@ -27,17 +27,17 @@
<div class="m-4"><!-- main content -->
<div class="flex bg-slate-50 mt-4 items-end">
<div class="flex bg-slate-50 dark:bg-slate-800 mt-4 items-end">
<div class="flex">
<a href="{% url "project_list_mine" %}"><div class="p-4 font-bold text-xl hover:bg-slate-200 {% if ownership_filter == "mine" %}text-cyan-500 border-cyan-500 border-b-4 {% else %}text-slate-500 hover:border-b-4 hover:border-slate-400{% endif %}">My Projects</div></a>
<a href="{% url "project_list_mine" %}"><div class="p-4 font-bold text-xl hover:bg-slate-200 dark:hover:bg-slate-800 {% if ownership_filter == "mine" %}text-cyan-500 dark:text-cyan-300 border-cyan-500 border-b-4 {% else %}text-slate-500 dark:text-slate-300 hover:border-b-4 hover:border-slate-400{% endif %}">My Projects</div></a>
{% if not app_settings.SINGLE_USER %}
<a href="{% url "project_list_teams" %}"><div class="p-4 font-bold text-xl hover:bg-slate-200 {% if ownership_filter == "teams" %}text-cyan-500 border-cyan-500 border-b-4 {% else %}text-slate-500 hover:border-b-4 hover:border-slate-400{% endif %}">Team Projects</div></a>
<a href="{% url "project_list_other" %}"><div class="p-4 font-bold text-xl hover:bg-slate-200 {% if ownership_filter == "other" %}text-cyan-500 border-cyan-500 border-b-4 {% else %}text-slate-500 hover:border-b-4 hover:border-slate-400{% endif %}">Other Projects</div></a>
<a href="{% url "project_list_teams" %}"><div class="p-4 font-bold text-xl hover:bg-slate-200 dark:hover:bg-slate-800 {% if ownership_filter == "teams" %}text-cyan-500 dark:text-cyan-300 border-cyan-500 border-b-4 {% else %}text-slate-500 dark:text-slate-300 hover:border-b-4 hover:border-slate-400{% endif %}">Team Projects</div></a>
<a href="{% url "project_list_other" %}"><div class="p-4 font-bold text-xl hover:bg-slate-200 dark:hover:bg-slate-800 {% if ownership_filter == "other" %}text-cyan-500 dark:text-cyan-300 border-cyan-500 border-b-4 {% else %}text-slate-500 dark:text-slate-300 hover:border-b-4 hover:border-slate-400{% endif %}">Other Projects</div></a>
{% endif %}
</div>
{% comment %}
<div class="ml-auto p-2">
<input type="text" name="search" placeholder="search projects..." class="focus:border-cyan-500 focus:ring-cyan-200 rounded-md"/>
<input type="text" name="search" placeholder="search projects..." class="bg-slate-50 dark:bg-slate-800 focus:border-cyan-500 dark:focus:border-cyan-400 focus:ring-cyan-200 dark:focus:ring-cyan-700 rounded-md"/>
</div>
{% endcomment %}
</div>
@@ -50,13 +50,13 @@
<table class="w-full">
<tbody>
{% for project in project_list %}
<tr class="bg-white border-slate-200 border-b-2">
<tr class="bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-700 border-b-2">
<td class="w-full p-4">
<div>
{% if project.member or request.user.is_superuser %}
<a href="/issues/{{ project.id }}" class="text-xl text-cyan-500 font-bold">{{ project.name }}</a>
<a href="/issues/{{ project.id }}" class="text-xl text-cyan-500 dark:text-cyan-300 font-bold">{{ project.name }}</a>
{% else %}
<span class="text-xl text-slate-800 font-bold">{{ project.name }}</span>
<span class="text-xl text-slate-800 dark:text-slate-100 font-bold">{{ project.name }}</span>
{% endif %}
</div>
<div>
@@ -64,23 +64,23 @@
| {{ project.member_count }} members
{# | {{ project.open_issue_count }} open issues #}
{% if project.member %}
| <a href="{% url 'project_member_settings' project_pk=project.id user_pk=request.user.id %}" class="font-bold text-cyan-500">my settings</a>
| <a href="{% url 'project_member_settings' project_pk=project.id user_pk=request.user.id %}" class="font-bold text-cyan-500 dark:text-cyan-300">my settings</a>
{% endif %}
</div>
</td>
<td class="pr-2 text-center">
{% if project.member %}
{% if not project.member.accepted %}
<span class="bg-slate-100 rounded-2xl px-4 py-2 ml-2 text-sm">You're&nbsp;invited!</span>
<span class="bg-slate-100 dark:bg-slate-700 rounded-2xl px-4 py-2 ml-2 text-sm">You're&nbsp;invited!</span>
{% elif project.member.is_admin %} {# NOTE: we intentionally hide admin-ness for non-accepted users; #}
<span class="bg-cyan-100 rounded-2xl px-4 py-2 ml-2 text-sm">Admin</span>
<span class="bg-cyan-100 dark:bg-cyan-900 rounded-2xl px-4 py-2 ml-2 text-sm">Admin</span>
{% endif %}
{% endif %}
</td>
<td class="pr-2">
{% if not app_settings.SINGLE_USER %}{% if project.member.is_admin or request.user.is_superuser %}
<div class="rounded-full hover:bg-slate-100 p-2 cursor-pointer" onclick="followContainedLink(this);" title="Project members">
<div class="rounded-full hover:bg-slate-100 dark:hover:bg-slate-700 p-2 cursor-pointer" onclick="followContainedLink(this);" title="Project members">
<a href="{% url 'project_members' 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="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z" />
@@ -92,7 +92,7 @@
<td class="pr-2">
{% if project.member.is_admin or request.user.is_superuser %}
<div class="rounded-full hover:bg-slate-100 p-2 cursor-pointer"onclick="followContainedLink(this);" title="Project settings">
<div class="rounded-full hover:bg-slate-100 dark:hover:bg-slate-700 p-2 cursor-pointer"onclick="followContainedLink(this);" title="Project settings">
<a href="{% url 'project_edit' 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="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z" />
@@ -105,7 +105,7 @@
<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">
<div class="rounded-full hover:bg-slate-100 dark:hover:bg-slate-700 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" />
@@ -117,7 +117,7 @@
<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)">
<div class="rounded-full hover:bg-slate-100 dark:hover:bg-slate-700 p-2 cursor-pointer" onclick="followContainedLink(this);" title="SDK setup (connect app)">
<a href="{% url 'project_sdk_setup' project_pk=project.id %}">
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="size-8">
<path d="M202.7,259.7l-31.5,31.5c-5.6,5.6-8.6,13-8.6,20.9c0,7.9,3.1,15.3,8.6,20.9l6.1,6.1l-3.7,3.7c-11.1,11.1-29.2,11.1-40.4,0
@@ -137,21 +137,21 @@
{% endif %}
</td>
<td>
<td class="pr-2">
{% if project.member %}
{% if not project.member.accepted %}
<div>
<a href="{% url 'project_members_accept' project_pk=project.id %}" class="font-bold text-cyan-500">Invitation</a>
</div>
<a href="{% url 'project_members_accept' project_pk=project.id %}" class="font-bold text-cyan-500 dark:text-cyan-300">Invitation</a>
</div>
{% else %}
<div>
<button name="action" value="leave:{{ project.id }}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 hover:bg-slate-200 active:ring rounded-md">Leave</button>
</div>
<button name="action" value="leave:{{ project.id }}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Leave</button>
</div>
{% endif %}
{% else %}
{% if ownership_filter == "teams" or project.is_joinable or request.user.is_superuser %}{# ownership_filter check: you can always join your own team's projects, so if you're looking at a list of them... #}
<div>
<button name="action" value="join:{{ project.id }}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 hover:bg-slate-200 active:ring rounded-md">Join</button>
<button name="action" value="join:{{ project.id }}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 dark:hover:bg-slate-700 active:ring rounded-md">Join</button>
</div>
{% endif %}
{% endif %}
@@ -159,7 +159,7 @@
</tr>
{% empty %}
<tr class="bg-white border-slate-200 border-b-2">
<tr class="bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-700 border-b-2">
<td class="w-full p-4">
No projects found.
</td>

View File

@@ -17,7 +17,7 @@
<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>
<li class="bg-cyan-50 dark:bg-cyan-900 border-2 border-cyan-800 dark:border-cyan-400 p-4 rounded-lg">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
@@ -37,11 +37,11 @@
{% tailwind_formfield form.role %}
{% tailwind_formfield form.send_email_alerts %}
<button 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>
<button class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md">Save</button>
{% if this_is_you %}
<a href="{% url "project_list" %}" class="text-cyan-500 font-bold ml-2">Cancel</a> {# not quite perfect, because "you" can also click on yourself in the member list #}
<a href="{% url "project_list" %}" class="text-cyan-500 dark:text-cyan-300 font-bold ml-2">Cancel</a> {# not quite perfect, because "you" can also click on yourself in the member list #}
{% else %}
<a href="{% url "project_members" project_pk=project.pk %}" class="text-cyan-500 font-bold ml-2">Cancel</a>
<a href="{% url "project_members" project_pk=project.pk %}" class="text-cyan-500 dark:text-cyan-300 font-bold ml-2">Cancel</a>
{% endif %}
</form>

View File

@@ -15,7 +15,7 @@
<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>
<li class="bg-cyan-50 dark:bg-cyan-900 border-2 border-cyan-800 dark:border-cyan-400 p-4 rounded-lg">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
@@ -24,8 +24,8 @@
<h1 class="text-4xl mt-4 font-bold">Project Members</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_members_invite" project_pk=project.pk %}">Invite Member</a>
</div>
<a class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md" href="{% url "project_members_invite" project_pk=project.pk %}">Invite Member</a>
</div>
</div>
<div>
@@ -35,19 +35,19 @@
<table class="w-full mt-8">
<tbody>
<thead>
<tr class="bg-slate-200">
<tr class="bg-slate-200 dark:bg-slate-800">
<th class="w-full p-4 text-left text-xl" colspan="2">{{ project.name }}</th>
</tr>
{% for member in members %}
<tr class="bg-white border-slate-200 border-b-2">
<tr class="bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-700 border-b-2">
<td class="w-full p-4">
<div>
<a href="{% url "project_member_settings" project_pk=project.pk user_pk=member.user_id %}" class="text-xl text-cyan-500 font-bold">{{ member.user.email }}</a> {# "best name" perhaps later? #}
{% if not member.accepted %}
<span class="bg-slate-100 rounded-2xl px-4 py-2 ml-2 text-sm">Invitation pending</span>
<span class="bg-slate-100 dark:bg-slate-700 rounded-2xl px-4 py-2 ml-2 text-sm">Invitation pending</span>
{% elif member.is_admin %} {# NOTE: we intentionally hide admin-ness for non-accepted users #}
<span class="bg-cyan-100 rounded-2xl px-4 py-2 ml-2 text-sm">Admin</span>
<span class="bg-cyan-100 dark:bg-cyan-900 rounded-2xl px-4 py-2 ml-2 text-sm">Admin</span>
{% endif %}
</div>
</td>
@@ -55,23 +55,23 @@
<td class="p-4">
<div class="flex justify-end">
{% if not member.accepted %}
<button name="action" value="reinvite:{{ member.user_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">Reinvite</button>
<button name="action" value="reinvite:{{ member.user_id }}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Reinvite</button>
{% endif %}
{% if request.user == member.user %}
<button name="action" value="remove:{{ member.user_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">Leave</button>
<button name="action" value="remove:{{ member.user_id }}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Leave</button>
{% else %} {# NOTE: in our setup request_user_is_admin is implied because only admins may view the membership page #}
<button name="action" value="remove:{{ member.user_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>
<button name="action" value="remove:{{ member.user_id }}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Remove</button>
{% endif %}
</div>
</div>
</td>
</tr>
{% empty %}
<tr class="bg-white border-slate-200 border-b-2">
<tr class="bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-700 border-b-2">
<td class="w-full p-4">
<div>
{# Note: this is already somewhat exceptional, because the usually you'll at least see yourself here (unless you're a superuser and a project has become memberless) #}
No members yet. <a href="{% url "project_members_invite" project_pk=project.pk %}" class="text-cyan-500 font-bold">Invite someone</a>.
No members yet. <a href="{% url "project_members_invite" project_pk=project.pk %}" class="text-cyan-500 dark:text-cyan-300 font-bold">Invite someone</a>.
</div>
</td>
</tr>
@@ -85,8 +85,8 @@
<div class="flex flex-direction-row">
<div class="ml-auto py-8 pr-4">
<a href="{% url "team_members" team_pk=project.team_id %}" class="text-cyan-500 font-bold">{{ project.team.name }} Members</a>
<span class="font-bold text-slate-500">|</span> <a href="{% url "project_list" %}" class="text-cyan-500 font-bold">Back to Projects</a>
<a href="{% url "team_members" team_pk=project.team_id %}" class="text-cyan-500 dark:text-cyan-300 font-bold">{{ project.team.name }} Members</a>
<span class="font-bold text-slate-500 dark:text-slate-300">|</span> <a href="{% url "project_list" %}" class="text-cyan-500 dark:text-cyan-300 font-bold">Back to Projects</a>
</div>
</div>
</div>

View File

@@ -21,8 +21,8 @@
You have been invited to join the project "{{ project.name }}" in the role of "{{ membership.get_role_display }}". Please confirm by clicking the button below.
</div>
<button name="action" value="accept" 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">Accept</button>
<button name="action" value="decline" 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">Decline</button>
<button name="action" value="accept" class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md">Accept</button>
<button name="action" value="decline" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Decline</button>
</form>
</div>

View File

@@ -16,7 +16,7 @@
<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>
<li class="bg-cyan-50 dark:bg-cyan-900 border-2 border-cyan-800 dark:border-cyan-400 p-4 rounded-lg">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
@@ -32,23 +32,23 @@
{% tailwind_formfield_implicit form.email %}
<div class="text-lg ml-1 mb-8"> {# ml-1 is strictly speaking not aligned, but visually it looks better "to me"; perhaps because of all of the round elements? #}
<div class="text-slate-800 font-bold">{{ form.role.label }}</div>
<div class="text-slate-800 dark:text-slate-100 font-bold">{{ form.role.label }}</div>
<div class="flex items-center">
{{ form.role }}
</div>
{% if form.role.errors %}
{% for error in form.role.errors %}
<div class="text-red-500 pt-1 px-2 text-sm">{{ error }}</div>
<div class="text-red-500 dark:text-red-400 pt-1 px-2 text-sm">{{ error }}</div>
{% endfor %}
{% elif form.role.help_text %}
<div class="text-gray-500 pt-1 px-2 text-sm">{{ form.role.help_text|safe }}</div>
<div class="text-gray-500 dark:text-gray-400 pt-1 px-2 text-sm">{{ form.role.help_text|safe }}</div>
{% endif %}
</div>
<button name="action" value="invite" 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">Invite Member</button>
<button name="action" value="invite_and_add_another" 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">Invite and add another</button>
<a href="{% url "project_members" project_pk=project.pk %}" class="font-bold text-slate-500 ml-4">Cancel</a>
<button name="action" value="invite" class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md">Invite Member</button>
<button name="action" value="invite_and_add_another" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Invite and add another</button>
<a href="{% url "project_members" project_pk=project.pk %}" class="font-bold text-slate-500 dark:text-slate-300 ml-4">Cancel</a>
</form>

View File

@@ -16,7 +16,7 @@
<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>
<li class="bg-cyan-50 dark:bg-cyan-900 border-2 border-cyan-800 dark:border-cyan-400 p-4 rounded-lg">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
@@ -33,8 +33,8 @@
{% 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>
<button name="action" value="add" class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md">Save</button>
<a href="{% url "project_alerts_setup" project_pk=project.pk %}" class="font-bold text-slate-500 dark:text-slate-300 ml-4">Cancel</a>
</form>

View File

@@ -22,8 +22,8 @@
{% tailwind_formfield form.visibility %}
{% tailwind_formfield form.retention_max_event_count %}
<button name="action" value="invite" 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_list" %}" class="text-cyan-500 font-bold ml-2">Cancel</a>
<button name="action" value="invite" class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md">Save</button>
<a href="{% url "project_list" %}" class="text-cyan-500 dark:text-cyan-300 font-bold ml-2">Cancel</a>
</form>

View File

@@ -26,30 +26,30 @@
<ul class="flex mt-8">
<li>
<a class="text-cyan-500 font-bold text-center" href="python/"><img src="{% static 'images/lang-python.png' %}" class="w-24 mx-4" alt="Python"><div class="mt-2">Python</div></a>
<a class="text-cyan-500 dark:text-cyan-300 font-bold text-center" href="python/"><img src="{% static 'images/lang-python.png' %}" class="w-24 mx-4" alt="Python"><div class="mt-2">Python</div></a>
</li>
<li>
<a class="text-cyan-500 font-bold text-center" href="javascript/"><img src="{% static 'images/lang-javascript.png' %}" class="w-24 mx-4" alt="JavaScript"><div class="mt-2">JavaScript</div></a>
<a class="text-cyan-500 dark:text-cyan-300 font-bold text-center" href="javascript/"><img src="{% static 'images/lang-javascript.png' %}" class="w-24 mx-4" alt="JavaScript"><div class="mt-2">JavaScript</div></a>
</li>
<li>
<a class="text-cyan-500 font-bold text-center" href="php/"><img src="{% static 'images/lang-php.png' %}" class="w-24 mx-4" alt="PHP"><div class="mt-2">PHP</div></a>
<a class="text-cyan-500 dark:text-cyan-300 font-bold text-center" href="php/"><img src="{% static 'images/lang-php.png' %}" class="w-24 mx-4" alt="PHP"><div class="mt-2">PHP</div></a>
</li>
</ul>
</div>
<div class="mt-4">
Not listed? It will probably work anyway! Just use the DSN above, and let us know if you run into any issues (on <a href="https://github.com/bugsink/bugsink/issues" class="text-cyan-500 font-bold">GitHub</a> or <a href="https://discord.gg/6Af6Yzz77C" class="text-cyan-500 font-bold">Discord</a>).
Not listed? It will probably work anyway! Just use the DSN above, and let us know if you run into any issues (on <a href="https://github.com/bugsink/bugsink/issues" class="text-cyan-500 dark:text-cyan-300 font-bold">GitHub</a> or <a href="https://discord.gg/6Af6Yzz77C" class="text-cyan-500 dark:text-cyan-300 font-bold">Discord</a>).
</div>
<div class="mt-4">
After triggering an event on purpose, it should now appear in the <a href="{% url "issue_list_open" project_pk=project.pk %}" class="text-cyan-500 font-bold">list of open issues</a>.
<div class="mt-4">
After triggering an event on purpose, it should now appear in the <a href="{% url "issue_list_open" project_pk=project.pk %}" class="text-cyan-500 dark:text-cyan-300 font-bold">list of open issues</a>.
</div>
<h2 class="mt-6 text-2xl font-bold">Further reading</h2>
<div class="mt-4">
For more information on how to use the SDK, check the <a href="https://www.bugsink.com/docs/sdk-recommendations/" class="text-cyan-500 font-bold">Bugsink-specific SDK recommendations</a>.
<div class="mt-4">
For more information on how to use the SDK, check the <a href="https://www.bugsink.com/docs/sdk-recommendations/" class="text-cyan-500 dark:text-cyan-300 font-bold">Bugsink-specific SDK recommendations</a>.
</div>
</div>
</div>

View File

@@ -13,8 +13,8 @@
<div class="mt-4">
Connect your JavaScript application to Bugsink to start tracking errors.
Bugsink is compatible with the <a class="text-cyan-500 font-bold" href="https://docs.sentry.io/platforms/javascript/">Sentry SDK</a>.
Detailed instructions per framework are in the <a class="text-cyan-500 font-bold" href="https://docs.sentry.io/platforms/javascript/">Sentry SDK Documentation</a>. In the below we provide an overview, zoom in on the differences between Bugsink and Sentry, and provide a snippet with the correct DSN set.
Bugsink is compatible with the <a class="text-cyan-500 dark:text-cyan-300 font-bold" href="https://docs.sentry.io/platforms/javascript/">Sentry SDK</a>.
Detailed instructions per framework are in the <a class="text-cyan-500 dark:text-cyan-300 font-bold" href="https://docs.sentry.io/platforms/javascript/">Sentry SDK Documentation</a>. In the below we provide an overview, zoom in on the differences between Bugsink and Sentry, and provide a snippet with the correct DSN set.
</div>
<h2 class="mt-8 text-2xl font-bold">Step 1: Install the SDK</h2>
@@ -67,16 +67,16 @@ Sentry.init({
throw new Error("Error Thrown on purpose to send it to Bugsink");
{% endcode %}
<div class="mt-4">
Your event should now appear in the <a href="{% url "issue_list_open" project_pk=project.pk %}" class="text-cyan-500 font-bold">list of open issues</a>.
<div class="mt-4">
Your event should now appear in the <a href="{% url "issue_list_open" project_pk=project.pk %}" class="text-cyan-500 dark:text-cyan-300 font-bold">list of open issues</a>.
</div>
<h2 class="mt-6 text-2xl font-bold">Further reading</h2>
<div class="mt-4">
For more information on how to use the SDK, check the <a href="https://www.bugsink.com/docs/sdk-recommendations/" class="text-cyan-500 font-bold">Bugsink-specific SDK recommendations</a>.
<div class="mt-4">
For more information on how to use the SDK, check the <a href="https://www.bugsink.com/docs/sdk-recommendations/" class="text-cyan-500 dark:text-cyan-300 font-bold">Bugsink-specific SDK recommendations</a>.
</div>
</div>
</div>

View File

@@ -13,8 +13,8 @@
<div class="mt-4">
Connect your PHP application to Bugsink to start tracking errors.
Bugsink is compatible with the <a class="text-cyan-500 font-bold" href="https://docs.sentry.io/platforms/php/">Sentry SDK</a>.
Note that the instructions for <a class="text-cyan-500 font-bold" href="https://docs.sentry.io/platforms/php/guides/laravel/">Laravel</a> and <a class="text-cyan-500 font-bold" href="https://docs.sentry.io/platforms/php/guides/symfony/">Symfony</a> are quite different from plain PHP.
Bugsink is compatible with the <a class="text-cyan-500 dark:text-cyan-300 font-bold" href="https://docs.sentry.io/platforms/php/">Sentry SDK</a>.
Note that the instructions for <a class="text-cyan-500 dark:text-cyan-300 font-bold" href="https://docs.sentry.io/platforms/php/guides/laravel/">Laravel</a> and <a class="text-cyan-500 dark:text-cyan-300 font-bold" href="https://docs.sentry.io/platforms/php/guides/symfony/">Symfony</a> are quite different from plain PHP.
In the below we provide an overview, zoom in on the differences between Bugsink and Sentry, and provide a snippet with the correct DSN set.
</div>
@@ -64,16 +64,16 @@ try {
}
?>{% endcode %}
<div class="mt-4">
Your event should now appear in the <a href="{% url "issue_list_open" project_pk=project.pk %}" class="text-cyan-500 font-bold">list of open issues</a>.
<div class="mt-4">
Your event should now appear in the <a href="{% url "issue_list_open" project_pk=project.pk %}" class="text-cyan-500 dark:text-cyan-300 font-bold">list of open issues</a>.
</div>
<h2 class="mt-6 text-2xl font-bold">Further reading</h2>
<div class="mt-4">
For more information on how to use the SDK, check the <a href="https://www.bugsink.com/docs/sdk-recommendations/" class="text-cyan-500 font-bold">Bugsink-specific SDK recommendations</a>.
<div class="mt-4">
For more information on how to use the SDK, check the <a href="https://www.bugsink.com/docs/sdk-recommendations/" class="text-cyan-500 dark:text-cyan-300 font-bold">Bugsink-specific SDK recommendations</a>.
</div>
</div>
</div>

View File

@@ -13,7 +13,7 @@
<div class="mt-4">
Connect your Python application to Bugsink to start tracking errors.
Bugsink is compatible with the Sentry SDK. A basic setup is the following:
Bugsink is compatible with the Sentry SDK. A basic setup is the following:
</div>
<h2 class="mt-8 text-2xl font-bold">Step 1: Install the SDK</h2>
@@ -63,16 +63,16 @@ sentry_sdk.init(
raise Exception("Raised Exception on purpose to send it to Bugsink")
{% endcode %}
<div class="mt-4">
Your event should now appear in the <a href="{% url "issue_list_open" project_pk=project.pk %}" class="text-cyan-500 font-bold">list of open issues</a>.
<div class="mt-4">
Your event should now appear in the <a href="{% url "issue_list_open" project_pk=project.pk %}" class="text-cyan-500 dark:text-cyan-300 font-bold">list of open issues</a>.
</div>
<h2 class="mt-6 text-2xl font-bold">Further reading</h2>
<div class="mt-4">
For more information on how to use the SDK, check the <a href="https://www.bugsink.com/docs/sdk-recommendations/" class="text-cyan-500 font-bold">Bugsink-specific SDK recommendations</a>.
<div class="mt-4">
For more information on how to use the SDK, check the <a href="https://www.bugsink.com/docs/sdk-recommendations/" class="text-cyan-500 dark:text-cyan-300 font-bold">Bugsink-specific SDK recommendations</a>.
</div>
</div>
</div>

View File

@@ -24,8 +24,8 @@
{% tailwind_formfield form.name %}
{% tailwind_formfield form.visibility %}
<button name="action" value="invite" 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 "team_list" %}" class="text-cyan-500 font-bold ml-2">Cancel</a>
<button name="action" value="invite" class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md">Save</button>
<a href="{% url "team_list" %}" class="text-cyan-500 dark:text-cyan-300 font-bold ml-2">Cancel</a>
</form>
</div>

View File

@@ -17,7 +17,7 @@
<div class="ml-auto"><!-- top, RHS (buttons) -->
{% if can_create %}
<div>
<a class="block 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 'team_new' %}">New Team</a>
<a class="block font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md" href="{% url 'team_new' %}">New Team</a>
</div>
{% endif %}
</div> {# top, RHS (buttons) #}
@@ -26,14 +26,14 @@
<div class="m-4"><!-- main content -->
<div class="flex bg-slate-50 mt-4 items-end">
<div class="flex bg-slate-50 dark:bg-slate-800 mt-4 items-end">
<div class="flex">
<a href="{% url "team_list_mine" %}"><div class="p-4 font-bold text-xl hover:bg-slate-200 {% if ownership_filter == "mine" %}text-cyan-500 border-cyan-500 border-b-4 {% else %}text-slate-500 hover:border-b-4 hover:border-slate-400{% endif %}">My Teams</div></a>
<a href="{% url "team_list_other" %}"><div class="p-4 font-bold text-xl hover:bg-slate-200 {% if ownership_filter == "other" %}text-cyan-500 border-cyan-500 border-b-4 {% else %}text-slate-500 hover:border-b-4 hover:border-slate-400{% endif %}">Other Teams</div></a>
<a href="{% url "team_list_mine" %}"><div class="p-4 font-bold text-xl hover:bg-slate-200 dark:hover:bg-slate-800 {% if ownership_filter == "mine" %}text-cyan-500 dark:text-cyan-400 border-cyan-500 border-b-4 {% else %}text-slate-500 dark:text-slate-300 hover:border-b-4 hover:border-slate-400 dark:hover:border-slate-500{% endif %}">My Teams</div></a>
<a href="{% url "team_list_other" %}"><div class="p-4 font-bold text-xl hover:bg-slate-200 dark:hover:bg-slate-800 {% if ownership_filter == "other" %}text-cyan-500 dark:text-cyan-400 border-cyan-500 border-b-4 {% else %}text-slate-500 dark:text-slate-300 hover:border-b-4 hover:border-slate-400 dark:hover:border-slate-500{% endif %}">Other Teams</div></a>
</div>
{% comment %}
<div class="ml-auto p-2">
<input type="text" name="search" placeholder="search teams..." class="focus:border-cyan-500 focus:ring-cyan-200 rounded-md"/>
<input type="text" name="search" placeholder="search teams..." class="bg-slate-50 dark:bg-slate-800 focus:border-cyan-500 dark:focus:border-cyan-400 focus:ring-cyan-200 dark:focus:ring-cyan-700 rounded-md"/>
</div>
{% endcomment %}
</div>
@@ -46,16 +46,16 @@
<table class="w-full">
<tbody>
{% for team in team_list %}
<tr class="bg-white border-slate-200 border-b-2">
<tr class="bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-700 border-b-2">
<td class="w-full p-4">
<div class="text-xl font-bold text-slate-800">
<div class="text-xl font-bold text-slate-800 dark:text-slate-100">
{{ team.name }}
</div>
<div>
{{ team.project_count }} projects
| {{ team.member_count }} members
{% if team.member %}
| <a href="{% url 'team_member_settings' team_pk=team.id user_pk=request.user.id %}" class="font-bold text-cyan-500">my settings</a>
| <a href="{% url 'team_member_settings' team_pk=team.id user_pk=request.user.id %}" class="font-bold text-cyan-500 dark:text-cyan-400">my settings</a>
{% endif %}
</div>
</td>
@@ -63,9 +63,9 @@
<td class="pr-2 text-center">
{% if team.member %}
{% if not team.member.accepted %}
<span class="bg-slate-100 rounded-2xl px-4 py-2 ml-2 text-sm">You're&nbsp;invited!</span>
<span class="bg-slate-100 dark:bg-slate-700 rounded-2xl px-4 py-2 ml-2 text-sm">You're&nbsp;invited!</span>
{% elif team.member.is_admin %} {# NOTE: we intentionally hide admin-ness for non-accepted users #}
<span class="bg-cyan-100 rounded-2xl px-4 py-2 ml-2 text-sm">Admin</span>
<span class="bg-cyan-100 dark:bg-cyan-900 rounded-2xl px-4 py-2 ml-2 text-sm">Admin</span>
{% endif %}
{% endif %}
</td>
@@ -73,7 +73,7 @@
{# strictly: if not app_settings.SINGLE_USER; in practice it won't matter much, because in SINGLE_USER mode you won't end up in a team overview anyway #}
<td class="pr-2">
{% if team.member.is_admin or request.user.is_superuser %}
<div class="rounded-full hover:bg-slate-100 p-2 cursor-pointer" onclick="followContainedLink(this);" title="Team members">
<div class="rounded-full hover:bg-slate-100 dark:hover:bg-slate-700 p-2 cursor-pointer" onclick="followContainedLink(this);" title="Team members">
<a href="{% url 'team_members' team_pk=team.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="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z" />
@@ -85,7 +85,7 @@
<td class="pr-2">
{% if team.member.is_admin or request.user.is_superuser %}
<div class="rounded-full hover:bg-slate-100 p-2 cursor-pointer"onclick="followContainedLink(this);" title="Team settings">
<div class="rounded-full hover:bg-slate-100 dark:hover:bg-slate-700 p-2 cursor-pointer"onclick="followContainedLink(this);" title="Team settings">
<a href="{% url "team_edit" team_pk=team.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="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z" />
@@ -96,21 +96,21 @@
{% endif %}
</td>
<td>
<td class="pr-2"">
{% if team.member %}
{% if not team.member.accepted %}
<div>
<a href="{% url 'team_members_accept' team_pk=team.id %}" class="font-bold text-cyan-500">Invitation</a>
</div>
<a href="{% url 'team_members_accept' team_pk=team.id %}" class="font-bold text-cyan-500 dark:text-cyan-400">Invitation</a>
</div>
{% else %}
<div>
<button name="action" value="leave:{{ team.id }}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 hover:bg-slate-200 active:ring rounded-md">Leave</button>
</div>
<button name="action" value="leave:{{ team.id }}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Leave</button>
</div>
{% endif %}
{% else %}
{% if team.is_joinable or request.user.is_superuser %}
<div>
<button name="action" value="join:{{ team.id }}" class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 hover:bg-slate-200 active:ring rounded-md">Join</button>
<button name="action" value="join:{{ team.id }}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Join</button>
</div>
{% endif %}
{% endif %}
@@ -118,7 +118,7 @@
</tr>
{% empty %}
<tr class="bg-white border-slate-200 border-b-2">
<tr class="bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-700 border-b-2">
<td class="w-full p-4">
No teams found.
</td>

View File

@@ -17,7 +17,7 @@
<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>
<li class="bg-cyan-50 dark:bg-cyan-900 border-2 border-cyan-800 dark:border-cyan-400 p-4 rounded-lg">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
@@ -37,11 +37,11 @@
{% tailwind_formfield form.role %}
{% tailwind_formfield form.send_email_alerts %}
<button 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>
<button class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md">Save</button>
{% if this_is_you %}
<a href="{% url "team_list" %}" class="text-cyan-500 font-bold ml-2">Cancel</a> {# not quite perfect, because "you" can also click on yourself in the member list #}
<a href="{% url "team_list" %}" class="text-cyan-500 dark:text-cyan-300 font-bold ml-2">Cancel</a> {# not quite perfect, because "you" can also click on yourself in the member list #}
{% else %}
<a href="{% url "team_members" team_pk=team.pk %}" class="text-cyan-500 font-bold ml-2">Cancel</a>
<a href="{% url "team_members" team_pk=team.pk %}" class="text-cyan-500 dark:text-cyan-300 font-bold ml-2">Cancel</a>
{% endif %}
</form>

View File

@@ -15,7 +15,7 @@
<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>
<li class="bg-cyan-50 dark:bg-cyan-900 border-2 border-cyan-800 dark:border-cyan-400 p-4 rounded-lg">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
@@ -24,8 +24,8 @@
<h1 class="text-4xl mt-4 font-bold">Team Members</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 "team_members_invite" team_pk=team.pk %}">Invite Member</a>
</div>
<a class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md" href="{% url "team_members_invite" team_pk=team.pk %}">Invite Member</a>
</div>
</div>
<div>
@@ -35,19 +35,19 @@
<table class="w-full mt-8">
<tbody>
<thead>
<tr class="bg-slate-200">
<tr class="bg-slate-200 dark:bg-slate-800">
<th class="w-full p-4 text-left text-xl" colspan="2">{{ team.name }}</th>
</tr>
{% for member in members %}
<tr class="bg-white border-slate-200 border-b-2">
<tr class="bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-700 border-b-2">
<td class="w-full p-4">
<div>
<a href="{% url "team_member_settings" team_pk=team.pk user_pk=member.user_id %}" class="text-xl text-cyan-500 font-bold">{{ member.user.email }}</a> {# "best name" perhaps later? #}
<a href="{% url "team_member_settings" team_pk=team.pk user_pk=member.user_id %}" class="text-xl text-cyan-500 dark:text-cyan-300 font-bold">{{ member.user.email }}</a> {# "best name" perhaps later? #}
{% if not member.accepted %}
<span class="bg-slate-100 rounded-2xl px-4 py-2 ml-2 text-sm">Invitation pending</span>
<span class="bg-slate-100 dark:bg-slate-700 rounded-2xl px-4 py-2 ml-2 text-sm">Invitation pending</span>
{% elif member.is_admin %} {# NOTE: we intentionally hide admin-ness for non-accepted users #}
<span class="bg-cyan-100 rounded-2xl px-4 py-2 ml-2 text-sm">Admin</span>
<span class="bg-cyan-100 dark:bg-cyan-900 rounded-2xl px-4 py-2 ml-2 text-sm">Admin</span>
{% endif %}
</div>
</td>
@@ -55,23 +55,23 @@
<td class="p-4">
<div class="flex justify-end">
{% if not member.accepted %}
<button name="action" value="reinvite:{{ member.user_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">Reinvite</button>
<button name="action" value="reinvite:{{ member.user_id }}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Reinvite</button>
{% endif %}
{% if request.user == member.user %}
<button name="action" value="remove:{{ member.user_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">Leave</button>
<button name="action" value="remove:{{ member.user_id }}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Leave</button>
{% else %} {# NOTE: in our setup request_user_is_admin is implied because only admins may view the membership page #}
<button name="action" value="remove:{{ member.user_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>
<button name="action" value="remove:{{ member.user_id }}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Remove</button>
{% endif %}
</div>
</div>
</td>
</tr>
{% empty %}
<tr class="bg-white border-slate-200 border-b-2">
<tr class="bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-700 border-b-2">
<td class="w-full p-4">
<div>
{# Note: this is already somewhat exceptional, because the usually you'll at least see yourself here (unless you're a superuser and a team has become memberless) #}
No members yet. <a href="{% url "team_members_invite" team_pk=team.pk %}" class="text-cyan-500 font-bold">Invite someone</a>.
No members yet. <a href="{% url "team_members_invite" team_pk=team.pk %}" class="text-cyan-500 dark:text-cyan-300 font-bold">Invite someone</a>.
</div>
</td>
</tr>
@@ -85,7 +85,7 @@
<div class="flex flex-direction-row">
<div class="ml-auto py-8 pr-4">
<a href="{% url "team_list" %}" class="text-cyan-500 font-bold">Back to Teams</a>
<a href="{% url "team_list" %}" class="text-cyan-500 dark:text-cyan-300 font-bold">Back to Teams</a>
</div>
</div>
</div>

View File

@@ -21,8 +21,8 @@
You have been invited to join the team "{{ team.name }}" in the role of "{{ membership.get_role_display }}". Please confirm by clicking the button below.
</div>
<button name="action" value="accept" 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">Accept</button>
<button name="action" value="decline" 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">Decline</button>
<button name="action" value="accept" class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md">Accept</button>
<button name="action" value="decline" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Decline</button>
</form>
</div>

View File

@@ -18,7 +18,7 @@
<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>
<li class="bg-cyan-50 dark:bg-cyan-900 border-2 border-cyan-800 dark:border-cyan-400 p-4 rounded-lg">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
@@ -34,23 +34,23 @@
{% tailwind_formfield_implicit form.email %}
<div class="text-lg ml-1 mb-8"> {# ml-1 is strictly speaking not aligned, but visually it looks better "to me"; perhaps because of all of the round elements? #}
<div class="text-slate-800 font-bold">{{ form.role.label }}</div>
<div class="text-slate-800 dark:text-slate-100 font-bold">{{ form.role.label }}</div>
<div class="flex items-center">
{{ form.role }}
</div>
{% if form.role.errors %}
{% for error in form.role.errors %}
<div class="text-red-500 pt-1 px-2 text-sm">{{ error }}</div>
<div class="text-red-500 dark:text-red-400 pt-1 px-2 text-sm">{{ error }}</div>
{% endfor %}
{% elif form.role.help_text %}
<div class="text-gray-500 pt-1 px-2 text-sm">{{ form.role.help_text|safe }}</div>
<div class="text-gray-500 dark:text-gray-400 pt-1 px-2 text-sm">{{ form.role.help_text|safe }}</div>
{% endif %}
</div>
<button name="action" value="invite" 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">Invite Member</button>
<button name="action" value="invite_and_add_another" 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">Invite and add another</button>
<a href="{% url "team_members" team_pk=team.pk %}" class="font-bold text-slate-500 ml-4">Cancel</a>
<button name="action" value="invite" class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md">Invite Member</button>
<button name="action" value="invite_and_add_another" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Invite and add another</button>
<a href="{% url "team_members" team_pk=team.pk %}" class="font-bold text-slate-500 dark:text-slate-300 ml-4">Cancel</a>
</form>

View File

@@ -20,8 +20,8 @@
{% tailwind_formfield form.name %}
{% tailwind_formfield form.visibility %}
<button name="action" value="invite" 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 "team_list" %}" class="text-cyan-500 font-bold ml-2">Cancel</a>
<button name="action" value="invite" class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md">Save</button>
<a href="{% url "team_list" %}" class="text-cyan-500 dark:text-cyan-300 font-bold ml-2">Cancel</a>
</form>

View File

@@ -14,7 +14,7 @@
You will find more information in:
<ul class="list-disc pt-4 pl-4">
<li>the server logs (stdout of your Docker, or in journalctl)</li>
<li>if you're <a href="https://www.bugsink.com/docs/dogfooding/" class="text-cyan-500 font-bold">dogfooding Bugsink</a>, in Bugsink itself</li>
<li>if you're <a href="https://www.bugsink.com/docs/dogfooding/" class="text-cyan-500 dark:text-cyan-300 font-bold">dogfooding Bugsink</a>, in Bugsink itself</li>
</ul>
</div>

View File

@@ -18,11 +18,11 @@
<div class="mb-6">
{% for key, annotated_count in model_counts|items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/6 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-1/6 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} text-right">{{ annotated_count.count|intcomma }}</div>
<div class="w-1/6 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} pl-4 text-slate-500">{% if annotated_count.timestamp %}cached {{ annotated_count.timestamp|date:"G:i T" }}{% else %}&nbsp;{% endif %}</div>
<div class="w-1/2 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %}">&nbsp;</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/6 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-1/6 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} text-right">{{ annotated_count.count|intcomma }}</div>
<div class="w-1/6 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} pl-4 text-slate-500 dark:text-slate-300">{% if annotated_count.timestamp %}cached {{ annotated_count.timestamp|date:"G:i T" }}{% else %}&nbsp;{% endif %}</div>
<div class="w-1/2 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">&nbsp;</div>
</div>
{% endfor %}

View File

@@ -15,9 +15,9 @@
<h2 class="text-2xl font-bold mt-4">Relevant settings</h2>
{% for key, value in relevant_settings|items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value }}</div>
</div>
{% endfor %}
@@ -25,32 +25,32 @@
<h2 class="text-2xl font-bold mt-4">POST Data</h2>
<form action="{% url 'csrf_debug' %}" method="post">
{% csrf_token %}
<button 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">Click to debug</button>
<button class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md">Click to debug</button>
</form>
{% else %}
<h2 class="text-2xl font-bold mt-4">Request Headers (META)</h2>
{% for key, value in META|items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %} {% if key == "HTTP_ORIGIN" or key == "HTTP_REFERER" or key == SECURE_PROXY_SSL_HEADER %}text-black{% else %}text-slate-300{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %} {% if key == "HTTP_ORIGIN" or key == "HTTP_REFERER" or key == SECURE_PROXY_SSL_HEADER %}text-black{% else %}text-slate-300{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value }}</div>
</div>
{% endfor %}
<h2 class="text-2xl font-bold mt-4">Middleware.process_view</h2>
{% for key, value in process_view|items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value }}</div>
</div>
{% endfor %}
{% if origin_verified_steps %}
<h2 class="text-2xl font-bold mt-4">_origin_verified: steps</h2>
{% for key, value in origin_verified_steps|items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value }}</div>
</div>
{% endfor %}
{% endif %}
@@ -58,18 +58,18 @@
{% if check_referer_steps %}
<h2 class="text-2xl font-bold mt-4">_check_referer: steps</h2>
{% for key, value in check_referer_steps|items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value }}</div>
</div>
{% endfor %}
{% endif %}
<h2 class="text-2xl font-bold mt-4">POST data</h2>
{% for key, value in POST|items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value }}</div>
</div>
{% endfor %}
@@ -80,7 +80,7 @@
<div>
To try again with the least risk of confusion, reload this page <i>without</i> reposting it first, and then POST again using the button.
</div>
{% endif %}

View File

@@ -5,16 +5,16 @@
{% block content %}
<div class="bg-cyan-100 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<div class="bg-cyan-100 dark:bg-cyan-900 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white dark:bg-slate-900 lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 dark:bg-slate-800 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<a href="/"><img src="{% static 'images/bugsink-logo.png' %}" class="h-8 w-8 md:h-16 md:w-16" alt="Bugsink logo"></a>
</div>
<div class="p-12 md:pt-24 md:pl-24 md:pr-24 md:pb-16">
{% if form.errors %}
<div class="mb-8 text-red-500">Your username and password didn't match. Please try again.</div>
<div class="mb-8 text-red-500 dark:text-red-400">Your username and password didn't match. Please try again.</div>
{% elif next %}
{% if user.is_authenticated %}
@@ -30,13 +30,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="absolute ml-3" width="24">
<path fill-rule="evenodd" d="M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z" clip-rule="evenodd" />
</svg>
<input name="username" type="text" class="bg-slate-200 pl-12 py-2 md:py-4 focus:outline-none w-full" {% if form.username.value %}value="{{ form.username.value }}"{% endif %} placeholder="Username" />
<input name="username" type="text" class="bg-slate-200 dark:bg-slate-800 pl-12 py-2 md:py-4 focus:outline-none w-full" {% if form.username.value %}value="{{ form.username.value }}"{% endif %} placeholder="Username" />
</div>
<div class="flex items-center text-lg mb-6 md:mb-8">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="absolute ml-3" width="24">
<path fill-rule="evenodd" d="M12 1.5a5.25 5.25 0 0 0-5.25 5.25v3a3 3 0 0 0-3 3v6.75a3 3 0 0 0 3 3h10.5a3 3 0 0 0 3-3v-6.75a3 3 0 0 0-3-3v-3c0-2.9-2.35-5.25-5.25-5.25Zm3.75 8.25v-3a3.75 3.75 0 1 0-7.5 0v3h7.5Z" clip-rule="evenodd" />
</svg>
<input name="password" type="password" class="bg-slate-200 pl-12 py-2 md:py-4 focus:outline-none w-full" {% if form.password.value %}value="{{ form.password.value }}"{% endif %} placeholder="Password" />
<input name="password" type="password" class="bg-slate-200 dark:bg-slate-800 pl-12 py-2 md:py-4 focus:outline-none w-full" {% if form.password.value %}value="{{ form.password.value }}"{% endif %} placeholder="Password" />
</div>
<input type="hidden" name="next" value="{{ next }}">
<button class="bg-slate-800 font-medium p-2 md:p-4 text-white uppercase w-full">Login</button>
@@ -44,8 +44,8 @@
</form>
<div class="mt-4">
<a href="{% url 'request_reset_password' %}" class="text-slate-800">Forgot password?</a>
{% if registration_enabled %}<a href="{% url 'signup' %}" class="float-right text-slate-800">Create an account</a>{% endif %}
<a href="{% url 'request_reset_password' %}" class="text-slate-800 dark:text-slate-100">Forgot password?</a>
{% if registration_enabled %}<a href="{% url 'signup' %}" class="float-right text-slate-800 dark:text-slate-100">Create an account</a>{% endif %}
</div>
</div>

View File

@@ -17,40 +17,40 @@
<div class="mb-6">
{% for key, value in bugsink_settings|items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value }}</div>
</div>
{% endfor %}
</div>
<h1 class="text-2xl font-bold mt-4">Snappea</h1>
<div class="mb-6">
{% for key, value in snappea_settings|items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value }}</div>
</div>
{% endfor %}
</div>
<h1 class="text-2xl font-bold mt-4">Misc</h1>
<div class="mb-6">
{% for key, value in misc_settings|items %}
<div class="flex {% if forloop.first %}border-slate-300 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %} font-mono">{{ value }}</div>
<div class="flex {% if forloop.first %}border-slate-300 dark:border-slate-600 border-t-2{% endif %}">
<div class="w-1/4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %}">{{ key }}</div>
<div class="w-3/4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300 dark:border-slate-600{% endif %} font-mono">{{ value }}</div>
</div>
{% endfor %}
</div>
<h1 class="text-2xl font-bold mt-4">System info</h1>
<div class="mb-6">
<div class="flex border-slate-300 border-t-2">
<div class="flex border-slate-300 dark:border-slate-600 border-t-2">
<div class="w-1/4">Version</div>
<div class="w-3/4">{{ version }}</div>
</div>

View File

@@ -6,9 +6,9 @@
{% block content %}
<div class="bg-cyan-100 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<div class="bg-cyan-100 dark:bg-cyan-900 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white dark:bg-slate-900 lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 dark:bg-slate-800 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<a href="/"><img src="{% static 'images/bugsink-logo.png' %}" class="h-8 w-8 md:h-16 md:w-16" alt="Bugsink logo"></a>
</div>
@@ -26,8 +26,8 @@
</form>
<div class="mt-4">
<a href="{% url 'request_reset_password' %}" class="text-slate-800">Forgot password?</a>
<a href="{% url 'login' %}" class="float-right text-slate-800">Log in instead</a>
<a href="{% url 'request_reset_password' %}" class="text-slate-800 dark:text-slate-100">Forgot password?</a>
<a href="{% url 'login' %}" class="float-right text-slate-800 dark:text-slate-100">Log in instead</a>
</div>
</div>

File diff suppressed because one or more lines are too long

View File

@@ -8,6 +8,7 @@
const defaultTheme = require("tailwindcss/defaultTheme");
module.exports = {
darkMode: ['selector', '[data-theme="dark"]'],
content: [
/**
* HTML. Paths to Django template files that will contain Tailwind CSS classes.
@@ -44,6 +45,7 @@ module.exports = {
// '../../**/*.py'
"../../issues/views.py",
"../../theme/templatetags/code.py",
"../../theme/templatetags/tailwind_forms.py",
],
theme: {
extend: {

View File

@@ -1,17 +1,31 @@
{% load static tailwind_tags %}<!DOCTYPE html>{# copy of base.html, but without variables (and hence no menu), for use in contextless templates (e.g. 500.html) #}
<html lang="en">
<html lang="en" data-theme="{% if user.is_authenticated %}{{ user.theme_preference }}{% else %}system{% endif %}">
<head>
<title>{% block title %}Bugsink{% endblock %}</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% tailwind_preload_css %}
{% tailwind_css %}
<script>
// System theme detection and switching
(function() {
const html = document.documentElement;
function applySystemTheme() {
if (document.documentElement.getAttribute('data-theme') === 'system') {
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
html.setAttribute('data-theme', isDark ? 'dark' : 'light');
}
}
applySystemTheme();
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', applySystemTheme);
})();
</script>
</head>
<body>
<body class="dark:bg-slate-700 dark:text-slate-100">
<div id="content">
<div class="flex pl-4 bg-slate-200">
<div class="flex pl-4 bg-slate-200 dark:bg-slate-800">
<a href="/"><img src="{% static 'images/bugsink-logo.png' %}" class="p-2 h-12 w-12" alt="Bugsink logo"></a>
<a href="/"><div class="pt-4 pb-4 pl-2 pr-2 font-bold">Bugsink</div></a>
</div>

View File

@@ -1,15 +1,29 @@
{% load static tailwind_tags %}<!DOCTYPE html>{# copy of bare_base.html, but without even a menu bar #}
<html lang="en">
<html lang="en" data-theme="{% if user.is_authenticated %}{{ user.theme_preference }}{% else %}system{% endif %}">
<head>
<title>{% block title %}Bugsink{% endblock %}</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% tailwind_preload_css %}
{% tailwind_css %}
<script>
// System theme detection and switching
(function() {
const html = document.documentElement;
function applySystemTheme() {
if (document.documentElement.getAttribute('data-theme') === 'system') {
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
html.setAttribute('data-theme', isDark ? 'dark' : 'light');
}
}
applySystemTheme();
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', applySystemTheme);
})();
</script>
</head>
<body>
<body class="dark:bg-slate-700 dark:text-slate-100">
<div id="content">
<div>
{% block content %}{% endblock %}

View File

@@ -1,53 +1,67 @@
{% load static tailwind_tags version add_to_qs %}<!DOCTYPE html>
<html lang="en">
<html lang="en" data-theme="{% if user.is_authenticated %}{{ user.theme_preference }}{% else %}system{% endif %}">
<!-- version: {% version %} -->
<head>
<title>{% block title %}{{ site_title }}{% endblock %}</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% tailwind_preload_css %}
{% tailwind_css %}
<script>
// System theme detection and switching
(function() {
const html = document.documentElement;
function applySystemTheme() {
if (document.documentElement.getAttribute('data-theme') === 'system') {
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
html.setAttribute('data-theme', isDark ? 'dark' : 'light');
}
}
applySystemTheme();
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', applySystemTheme);
})();
</script>
</head>
<body>
<body class="dark:bg-slate-700 dark:text-slate-100">
<div id="content">
<div class="flex pl-4 bg-slate-200">
<div class="flex pl-4 bg-slate-200 dark:bg-slate-800">
<a href="/"><img src="{% static 'images/bugsink-logo.png' %}" class="p-2 h-12 w-12" alt="Bugsink logo"></a>
<a href="/"><div class="px-2 py-2 my-2 font-bold hover:bg-slate-300 rounded-xl">{{ site_title }}</div></a>
<a href="/"><div class="px-2 py-2 my-2 font-bold hover:bg-slate-300 dark:hover:bg-slate-700 rounded-xl">{{ site_title }}</div></a>
{% if not app_settings.SINGLE_TEAM %}
<a href="{% url "team_list" %}"><div class="px-4 py-2 my-2 hover:bg-slate-300 rounded-xl">Teams</div></a>
<a href="{% url "team_list" %}"><div class="px-4 py-2 my-2 hover:bg-slate-300 dark:hover:bg-slate-700 rounded-xl">Teams</div></a>
{% endif %}
<a href="{% url "project_list" %}"><div class="px-4 py-2 my-2 hover:bg-slate-300 rounded-xl">Projects</div></a>
<a href="{% url "project_list" %}"><div class="px-4 py-2 my-2 hover:bg-slate-300 dark:hover:bg-slate-700 rounded-xl">Projects</div></a>
{% if project %}
<a href="{% url "issue_list_open" project_pk=project.pk %}{% current_qs %}"><div class="px-4 py-2 my-2 hover:bg-slate-300 rounded-xl">Issues ({{ project.name }})</div></a>
<a href="{% url "issue_list_open" project_pk=project.pk %}{% current_qs %}"><div class="px-4 py-2 my-2 hover:bg-slate-300 dark:hover:bg-slate-700 rounded-xl">Issues ({{ project.name }})</div></a>
{% endif %}
<div class="ml-auto flex">
{% if app_settings.USE_ADMIN and user.is_staff %}
<a href="/admin/"><div class="px-4 py-2 my-2 hover:bg-slate-300 rounded-xl">Admin</div></a>
<a href="/admin/"><div class="px-4 py-2 my-2 hover:bg-slate-300 dark:hover:bg-slate-700 rounded-xl">Admin</div></a>
{% endif %}
{% if user.is_superuser %}
<a href="/users/"><div class="px-4 py-2 my-2 hover:bg-slate-300 rounded-xl">Users</div></a>
<a href="/bsmain/auth_tokens/"><div class="px-4 py-2 my-2 hover:bg-slate-300 rounded-xl">Tokens</div></a>
<a href="/users/"><div class="px-4 py-2 my-2 hover:bg-slate-300 dark:hover:bg-slate-700 rounded-xl">Users</div></a>
<a href="/bsmain/auth_tokens/"><div class="px-4 py-2 my-2 hover:bg-slate-300 dark:hover:bg-slate-700 rounded-xl">Tokens</div></a>
{% endif %}
{% if logged_in_user.is_anonymous %}
<a href="/accounts/login/"><div class="px-4 py-2 my-2 hover:bg-slate-300 rounded-xl">Login</div></a> {# I don't think this is actually ever shown in practice, because you must always be logged in #}
<a href="/accounts/login/"><div class="px-4 py-2 my-2 hover:bg-slate-300 dark:hover:bg-slate-700 rounded-xl">Login</div></a> {# I don't think this is actually ever shown in practice, because you must always be logged in #}
{% else %}
<a href="/accounts/preferences/"><div class="px-4 py-2 my-2 hover:bg-slate-300 rounded-xl">Preferences</div></a>
<div class="px-4 py-2 my-2 mr-2 hover:bg-slate-300 rounded-xl"><form id="logout-form" method="post" action="{% url 'logout' %}">{% csrf_token %}<button type="submit">Log out</button></form></div>
<a href="/accounts/preferences/"><div class="px-4 py-2 my-2 hover:bg-slate-300 dark:hover:bg-slate-700 rounded-xl">Preferences</div></a>
<div class="px-4 py-2 my-2 mr-2 hover:bg-slate-300 dark:hover:bg-slate-700 rounded-xl"><form id="logout-form" method="post" action="{% url 'logout' %}">{% csrf_token %}<button type="submit">Log out</button></form></div>
{% endif %}
</div>
</div>
{% for system_warning in system_warnings %}
<div class="flex p-4 bg-yellow-100 border-b-2 border-yellow-200">
<div>
<div class="flex p-4 bg-yellow-100 dark:bg-yellow-900 border-b-2 border-yellow-200 dark:border-yellow-700">
<div class="text-slate-800 dark:text-slate-100">
{{ system_warning.message }}
</div>
{% if system_warning.ignore_url %}
@@ -57,7 +71,7 @@
{% endfor %}
{% comment %} {# for use when we introduce a notification system #}
<div class="flex p-4 bg-yellow-100 border-b-2 border-yellow-200">
<div class="flex p-4 bg-yellow-100 dark:bg-yellow-900 border-b-2 border-yellow-200 dark:border-yellow-700">
<div>
Foo bar baz
</div>

View File

@@ -2,17 +2,17 @@
<div class="text-lg mb-6 md:mb-8">
{% if not implicit %}
<div class="text-slate-800 font-bold">{{ formfield.label }}:</div>
<div class="text-slate-800 dark:text-slate-100 font-bold">{{ formfield.label }}:</div>
{% endif %}
{{ formfield }}
{% if formfield.errors %}
{% for error in formfield.errors %}
<div class="text-red-500 pt-1 px-2 text-sm">{{ error }}</div>
<div class="text-red-500 dark:text-red-400 pt-1 px-2 text-sm">{{ error }}</div>
{% endfor %}
{% elif formfield.help_text %}
<div class="text-gray-500 pt-1 px-2 text-sm">{{ formfield.help_text|safe }}</div>
<div class="text-gray-500 dark:text-gray-400 pt-1 px-2 text-sm">{{ formfield.help_text|safe }}</div>
{% endif %}
</div>
{% endif %}

View File

@@ -37,4 +37,4 @@ class CodeNode(template.Node):
lexer = get_lexer_by_name(lang, stripall=True)
return highlight(code, lexer, formatter).replace("highlight", "p-4 mt-4 bg-slate-50 syntax-coloring")
return highlight(code, lexer, formatter).replace("highlight", "p-4 mt-4 bg-slate-50 dark:bg-slate-800 syntax-coloring")

View File

@@ -11,9 +11,9 @@ def tailwind_formfield(formfield, implicit=False):
return {"formfield": None}
if formfield.errors:
formfield.field.widget.attrs['class'] = "bg-red-50"
formfield.field.widget.attrs['class'] = "bg-red-50 dark:bg-red-900"
else:
formfield.field.widget.attrs['class'] = "bg-slate-50"
formfield.field.widget.attrs['class'] = "bg-slate-50 dark:bg-slate-800"
formfield.field.widget.attrs['class'] += " pl-4 py-2 md:py-4 focus:outline-none w-full"
if implicit:

View File

@@ -140,7 +140,13 @@ class PreferencesForm(ModelForm):
# I haven't gotten a decent display for checkboxes in forms yet; the quickest hack around this is a ChoiceField
send_email_alerts = forms.ChoiceField(
label=_("Send email alerts"), choices=TRUE_FALSE_CHOICES, required=False, widget=forms.Select())
theme_preference = forms.ChoiceField(
label=_("Theme preference"),
choices=User.THEME_CHOICES,
required=True,
widget=forms.Select(),
)
class Meta:
model = User
fields = ("send_email_alerts",)
fields = ("send_email_alerts", "theme_preference",)

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.23 on 2025-06-16 08:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='user',
name='theme_preference',
field=models.CharField(choices=[('system', 'System Default'), ('light', 'Light'), ('dark', 'Dark')], default='system', max_length=10),
),
]

View File

@@ -17,6 +17,18 @@ class User(AbstractUser):
send_email_alerts = models.BooleanField(default=True, blank=True)
THEME_CHOICES = [
("system", "System Default"),
("light", "Light"),
("dark", "Dark"),
]
theme_preference = models.CharField(
max_length=10,
choices=THEME_CHOICES,
default="system",
blank=False,
)
class Meta:
db_table = 'auth_user'

View File

@@ -5,14 +5,14 @@
{% block content %}
<div class="bg-cyan-100 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<div class="bg-cyan-100 dark:bg-cyan-900 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white dark:bg-slate-900 lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 dark:bg-slate-800 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<a href="/"><img src="{% static 'images/bugsink-logo.png' %}" class="h-8 w-8 md:h-16 md:w-16" alt="Bugsink logo"></a>
</div>
<div class="p-12 md:pt-24 md:pl-24 md:pr-24 md:pb-16">
<div class="mb-8">
Confirm your email address by clicking the button below.
</div>

View File

@@ -5,9 +5,9 @@
{% block content %}
<div class="bg-cyan-100 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<div class="bg-cyan-100 dark:bg-cyan-900 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white dark:bg-slate-900 lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 dark:bg-slate-800 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<a href="/"><img src="{% static 'images/bugsink-logo.png' %}" class="h-8 w-8 md:h-16 md:w-16" alt="Bugsink logo"></a>
</div>

View File

@@ -5,14 +5,14 @@
{% block content %}
<div class="bg-cyan-100 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<div class="bg-cyan-100 dark:bg-cyan-900 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white dark:bg-slate-900 lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 dark:bg-slate-800 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<a href="/"><img src="{% static 'images/bugsink-logo.png' %}" class="h-8 w-8 md:h-16 md:w-16" alt="Bugsink logo"></a>
</div>
<div class="p-12 md:pt-24 md:pl-24 md:pr-24 md:pb-16">
You have been logged out. <a href="{% url 'login' %}" class="text-cyan-500">Log in again</a>.
You have been logged out. <a href="{% url 'login' %}" class="text-cyan-500 dark:text-cyan-300">Log in again</a>.
</div>
</div>

View File

@@ -17,7 +17,7 @@
<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>
<li class="bg-cyan-50 dark:bg-cyan-900 border-2 border-cyan-800 dark:border-cyan-400 p-4 rounded-lg">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
@@ -27,8 +27,9 @@
</div>
{% tailwind_formfield form.send_email_alerts %}
{% tailwind_formfield form.theme_preference %}
<button name="action" value="invite" 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>
<button name="action" value="invite" class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md">Save</button>
</form>
</div>

View File

@@ -6,9 +6,9 @@
{% block content %}
<div class="bg-cyan-100 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<div class="bg-cyan-100 dark:bg-cyan-900 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white dark:bg-slate-900 lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 dark:bg-slate-800 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<a href="/"><img src="{% static 'images/bugsink-logo.png' %}" class="h-8 w-8 md:h-16 md:w-16" alt="Bugsink logo"></a>
</div>
@@ -23,7 +23,7 @@
</form>
<div class="mt-4">
<a href="{% url 'login' %}" class="text-slate-800">Log in instead</a>
<a href="{% url 'login' %}" class="text-slate-800 dark:text-slate-100">Log in instead</a>
</div>
</div>

View File

@@ -6,9 +6,9 @@
{% block content %}
<div class="bg-cyan-100 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<div class="bg-cyan-100 dark:bg-cyan-900 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white dark:bg-slate-900 lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 dark:bg-slate-800 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<a href="/"><img src="{% static 'images/bugsink-logo.png' %}" class="h-8 w-8 md:h-16 md:w-16" alt="Bugsink logo"></a>
</div>
@@ -23,8 +23,8 @@
</form>
<div class="mt-4">
<a href="{% url 'request_reset_password' %}" class="text-slate-800">Forgot password?</a>
<a href="{% url 'login' %}" class="float-right text-slate-800">Log in instead</a>
<a href="{% url 'request_reset_password' %}" class="text-slate-800 dark:text-slate-100">Forgot password?</a>
<a href="{% url 'login' %}" class="float-right text-slate-800 dark:text-slate-100">Log in instead</a>
</div>
</div>

View File

@@ -6,9 +6,9 @@
{% block content %}
<div class="bg-cyan-100 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<div class="bg-cyan-100 dark:bg-cyan-900 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white dark:bg-slate-900 lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 dark:bg-slate-800 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<a href="/"><img src="{% static 'images/bugsink-logo.png' %}" class="h-8 w-8 md:h-16 md:w-16" alt="Bugsink logo"></a>
</div>
@@ -27,7 +27,7 @@
</form>
<div class="mt-4">
<a href="{% url 'login' %}" class="text-slate-800">Log in instead</a>
<a href="{% url 'login' %}" class="text-slate-800 dark:text-slate-100">Log in instead</a>
</div>
</div>

View File

@@ -5,9 +5,9 @@
{% block content %}
<div class="bg-cyan-100 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<div class="bg-cyan-100 dark:bg-cyan-900 h-screen overflow-y-scroll flex items-center justify-center"> {# the cyan background #}
<div class="bg-white dark:bg-slate-900 lg:w-5/12 md:6/12 w-10/12"> {# the centered box #}
<div class="bg-slate-200 dark:bg-slate-800 absolute left-1/2 transform -translate-x-1/2 -translate-y-1/2 rounded-full p-4 md:p-8"> {# the logo #}
<a href="/"><img src="{% static 'images/bugsink-logo.png' %}" class="h-8 w-8 md:h-16 md:w-16" alt="Bugsink logo"></a>
</div>

View File

@@ -23,8 +23,8 @@
{% tailwind_formfield form.username %}
<button name="action" value="invite" 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 "user_list" %}" class="text-cyan-500 font-bold ml-2">Cancel</a>
<button name="action" value="invite" class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md">Save</button>
<a href="{% url "user_list" %}" class="text-cyan-500 dark:text-cyan-300 font-bold ml-2">Cancel</a>
</form>
</div>

View File

@@ -6,21 +6,21 @@
{% block content %}
<!-- Delete Confirmation Modal -->
<div id="deleteModal" class="hidden fixed inset-0 bg-slate-600 bg-opacity-50 overflow-y-auto h-full w-full z-50 flex items-center justify-center">
<div class="relative p-6 border border-slate-300 w-96 shadow-lg rounded-md bg-white">
<div id="deleteModal" class="hidden fixed inset-0 bg-slate-600 dark:bg-slate-900 bg-opacity-50 dark:bg-opacity-50 overflow-y-auto h-full w-full z-50 flex items-center justify-center">
<div class="relative p-6 border border-slate-300 dark:border-slate-600 w-96 shadow-lg rounded-md bg-white dark:bg-slate-900">
<div class="text-center m-4">
<h3 class="text-2xl font-semibold text-slate-800 mt-3 mb-4">Delete User</h3>
<h3 class="text-2xl font-semibold text-slate-800 dark:text-slate-100 mt-3 mb-4">Delete User</h3>
<div class="mt-4 mb-6">
<p class="text-slate-700">
<p class="text-slate-700 dark:text-slate-300">
Are you sure you want to delete this user? This action cannot be undone.
</p>
</div>
<div class="flex items-center justify-center space-x-4 mb-4">
<button id="cancelDelete" class="text-cyan-500 font-bold">Cancel</button>
<button id="cancelDelete" class="text-cyan-500 dark:text-cyan-300 font-bold">Cancel</button>
<form method="post" action="." id="deleteForm">
{% csrf_token %}
<input type="hidden" name="action" id="deleteAction" value="">
<button type="submit" class="font-bold py-2 px-4 rounded bg-red-500 text-white border-2 border-red-600 hover:bg-red-600 active:ring">Confirm</button>
<button type="submit" class="font-bold py-2 px-4 rounded bg-red-500 dark:bg-red-700 text-white border-2 border-red-600 dark:border-red-400 hover:bg-red-600 dark:hover:bg-red-800 active:ring">Confirm</button>
</form>
</div>
</div>
@@ -35,18 +35,17 @@
<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>
<li class="bg-cyan-50 dark:bg-cyan-900 border-2 border-cyan-800 dark:border-cyan-400 p-4 rounded-lg">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
<div class="flex">
<h1 class="text-4xl mt-4 font-bold">Users</h1>
{% comment %}
Our current invite-system is tied to either a team or a project; no "global" invites (yet).
<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 "team_members_invite" team_pk=team.pk %}">Invite Member</a>
<a class="font-bold text-slate-800 dark:text-slate-100 border-slate-500 dark:border-slate-400 pl-4 pr-4 pb-2 pt-2 ml-1 border-2 bg-cyan-200 dark:bg-cyan-700 hover:bg-cyan-400 dark:hover:bg-cyan-600 active:ring rounded-md" href="{% url "team_members_invite" team_pk=team.pk %}">Invite Member</a>
</div>
{% endcomment %}
</div>
@@ -58,18 +57,17 @@
<table class="w-full mt-8">
<tbody>
<thead>
<tr class="bg-slate-200">
<tr class="bg-slate-200 dark:bg-slate-800">
<th class="w-full p-4 text-left text-xl" colspan="2">Users</th>
</tr>
{% for user in users %}
<tr class="bg-white border-slate-200 border-b-2">
<tr class="bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-700 border-b-2">
<td class="w-full p-4">
<div>
<a href="{% url "user_edit" user_pk=user.pk %}" class="text-xl text-cyan-500 font-bold">{{ user.username }}</a> {# "best name" perhaps later? #}
{# <span class="bg-slate-100 rounded-2xl px-4 py-2 ml-2 text-sm">Invitation pending</span> #} {# perhaps useful for "not active"? #}
<a href="{% url "user_edit" user_pk=user.pk %}" class="text-xl text-cyan-500 dark:text-cyan-300 font-bold">{{ user.username }}</a>
{% if member.is_superuser %}
<span class="bg-cyan-100 rounded-2xl px-4 py-2 ml-2 text-sm">Superuser</span>
<span class="bg-cyan-100 dark:bg-cyan-900 rounded-2xl px-4 py-2 ml-2 text-sm">Superuser</span>
{% endif %}
</div>
</td>
@@ -78,10 +76,10 @@
<div class="flex justify-end">
{% if not request.user == user %}
{% if user.is_active %}
<button name="action" value="deactivate:{{ user.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">Deactivate</button>
<button name="action" value="deactivate:{{ user.id }}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Deactivate</button>
{% else %}
<button name="action" value="activate:{{ user.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">Activate</button>
<button type="button" class="delete-button font-bold py-2 px-4 rounded bg-red-500 text-white border-2 border-red-600 hover:bg-red-600 active:ring ml-4" data-user-id="{{ user.id }}">Delete</button>
<button name="action" value="activate:{{ user.id }}" class="font-bold text-slate-500 dark:text-slate-300 border-slate-300 dark:border-slate-600 pl-4 pr-4 pb-2 pt-2 ml-2 border-2 hover:bg-slate-200 dark:hover:bg-slate-800 active:ring rounded-md">Activate</button>
<button type="button" class="delete-button font-bold py-2 px-4 rounded bg-red-500 dark:bg-red-700 text-white border-2 border-red-600 dark:border-red-400 hover:bg-red-600 dark:hover:bg-red-800 active:ring ml-4" data-user-id="{{ user.id }}">Delete</button>
{% endif %}
{% endif %}
</div>
@@ -90,7 +88,6 @@
</tr>
{% endfor %}
{#% empty %} not needed, a site without users cannot be visited by a user #}
</tbody>
</table>
@@ -100,7 +97,7 @@
{% comment %}
<div class="flex flex-direction-row">
<div class="ml-auto py-8 pr-4">
<a href="{% url "..." %}" class="text-cyan-500 font-bold">Back to Xxxx</a> {# perhaps once this is part of some other flow #}
<a href="{% url "..." %}" class="text-cyan-500 dark:text-cyan-300 font-bold">Back to Xxxx</a> {# perhaps once this is part of some other flow #}
</div>
</div>
{% endcomment %}
@@ -113,4 +110,4 @@
var csrftoken = '{{ csrf_token }}';
</script>
<script src="{% static 'js/user_list.js' %}"></script>
{% endblock %}
{% endblock %}