Add dark theme

This commit is contained in:
Fabien LEFEBVRE (d1ceward)
2025-06-16 15:37:37 +02:00
parent 8ad9fe33ca
commit 9cec248ad8
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,7 +24,7 @@
<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>
@@ -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>
<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 %}
@@ -32,18 +32,18 @@
{% 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>
<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>
@@ -51,7 +51,7 @@
{% 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,22 +59,22 @@
{% 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 #}
@@ -83,9 +83,9 @@
</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>
@@ -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,14 +228,14 @@
{% 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 %}
<span>{{ issuetag.value.value }} <span class="text-xs">({{ issuetag.pct }}%)</span>{% if not forloop.last %}</span>,{% endif %}

View File

@@ -32,9 +32,9 @@
<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>
@@ -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,9 +24,9 @@
<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>
@@ -36,9 +36,9 @@
<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>
@@ -50,9 +50,9 @@
<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>
@@ -63,9 +63,9 @@
<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>
@@ -78,9 +78,9 @@
<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>
@@ -93,9 +93,9 @@
<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 %}
@@ -138,9 +138,9 @@
{% 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 %}
@@ -166,9 +166,9 @@ the fact that we commented-out rather than clobbered reveals a small amount of d
<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>
@@ -182,9 +182,9 @@ the fact that we commented-out rather than clobbered reveals a small amount of d
{# 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>
@@ -195,9 +195,9 @@ the fact that we commented-out rather than clobbered reveals a small amount of d
<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>
@@ -208,9 +208,9 @@ the fact that we commented-out rather than clobbered reveals a small amount of d
<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

@@ -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,13 +11,13 @@
<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 -->
@@ -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,28 +45,28 @@
<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>
@@ -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

@@ -18,17 +18,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>
@@ -41,12 +41,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">
@@ -54,16 +54,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 %}
@@ -72,23 +72,23 @@
{% 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>
<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 #}
{# 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>
{% 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 %}
@@ -96,36 +96,36 @@
{% 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>
{% 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 %}
{% endspaceless %}
{# 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>
@@ -134,15 +134,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>
@@ -158,19 +158,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.
@@ -224,7 +224,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" />
@@ -234,7 +234,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" />
@@ -245,7 +245,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" />
@@ -254,7 +254,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>
@@ -54,12 +54,12 @@
{% 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 %}
@@ -108,7 +108,7 @@
<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

@@ -9,10 +9,10 @@
<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>
<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,7 +24,7 @@
<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>
<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>
@@ -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>
<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

@@ -27,8 +27,8 @@
{% tailwind_formfield form.retention_max_event_count %}
{% tailwind_formfield form.dsn %}
<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>
</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 '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>
<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>
<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,7 +24,7 @@
<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>
<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>
@@ -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>
</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,28 +26,28 @@
<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>.
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>.
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>

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>
@@ -68,13 +68,13 @@ 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>.
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>.
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>

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>
@@ -65,13 +65,13 @@ 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>.
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>.
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>

View File

@@ -64,13 +64,13 @@ 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>.
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>.
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>

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>
<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>
<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,7 +24,7 @@
<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>
<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>
@@ -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>
</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 %}

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,9 +17,9 @@
<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>
@@ -28,9 +28,9 @@
<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>
@@ -40,9 +40,9 @@
<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>
@@ -50,7 +50,7 @@
<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,5 +1,5 @@
{% 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">
@@ -7,11 +7,25 @@
{% 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,5 +1,5 @@
{% 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">
@@ -7,9 +7,23 @@
{% 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,5 +1,5 @@
{% 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>
@@ -8,46 +8,60 @@
{% 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,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,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 %}