Fix broken reference links and web UI bugs
- Fix RFC URLs with leading zeros (rfc0020 -> rfc20) via int filter - Draft refs: internal link for drafts in our DB, Datatracker for external - BCP refs: link to rfc-editor.org/info/bcpN - Add DB connection teardown (@app.teardown_appcontext) - Fix JS syntax error in gap_demo.html (HTML-escaped string in script tag) - Add URL encoding to all query params in drafts.html and draft_detail.html - Fix variable shadowing of Flask's g import in gaps_demo() - Add None safety for ideas search data attribute Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -256,7 +256,7 @@
|
||||
</h2>
|
||||
<div class="flex flex-wrap gap-1.5">
|
||||
{% for cat in draft.rating.categories %}
|
||||
<a href="/drafts?cat={{ cat }}"
|
||||
<a href="/drafts?cat={{ cat | urlencode }}"
|
||||
class="px-2.5 py-1 rounded-full text-xs bg-slate-800/60 text-slate-400 border border-slate-700 hover:border-blue-500 hover:text-blue-400 transition">
|
||||
{{ cat }}
|
||||
</a>
|
||||
@@ -275,16 +275,28 @@
|
||||
<div class="flex flex-wrap gap-1.5 max-h-48 overflow-y-auto">
|
||||
{% for ref in draft.refs %}
|
||||
{% if ref.type == 'rfc' %}
|
||||
<a href="https://www.rfc-editor.org/rfc/{{ ref.id }}" target="_blank" rel="noopener"
|
||||
<a href="https://www.rfc-editor.org/rfc/rfc{{ ref.id | int }}" target="_blank" rel="noopener"
|
||||
class="px-2 py-0.5 rounded text-[10px] font-medium ref-rfc hover:opacity-80 transition">
|
||||
RFC {{ ref.id.replace('rfc', '') }}
|
||||
RFC {{ ref.id | int }}
|
||||
</a>
|
||||
{% elif ref.type == 'draft' %}
|
||||
{% if ref.id in known_drafts %}
|
||||
<a href="/drafts/{{ ref.id }}"
|
||||
class="px-2 py-0.5 rounded text-[10px] font-medium ref-draft hover:opacity-80 transition">
|
||||
{{ ref.id }}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="https://datatracker.ietf.org/doc/{{ ref.id }}/" target="_blank" rel="noopener"
|
||||
class="px-2 py-0.5 rounded text-[10px] font-medium ref-draft hover:opacity-80 transition">
|
||||
{{ ref.id }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% elif ref.type == 'bcp' %}
|
||||
<a href="https://www.rfc-editor.org/info/bcp{{ ref.id }}" target="_blank" rel="noopener"
|
||||
class="px-2 py-0.5 rounded text-[10px] font-medium ref-other hover:opacity-80 transition">
|
||||
BCP {{ ref.id }}
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="px-2 py-0.5 rounded text-[10px] font-medium ref-other">
|
||||
{{ ref.type|upper }} {{ ref.id }}
|
||||
</span>
|
||||
|
||||
@@ -178,10 +178,10 @@
|
||||
{% if categories %}
|
||||
<div class="mt-4 pt-3 border-t border-slate-800/50">
|
||||
<div class="flex flex-wrap gap-1.5">
|
||||
<a href="/drafts?q={{ search }}&min_score={{ min_score }}&sort={{ sort }}&dir={{ sort_dir }}"
|
||||
<a href="/drafts?q={{ search | urlencode }}&min_score={{ min_score }}&sort={{ sort }}&dir={{ sort_dir }}"
|
||||
class="cat-pill {% if not current_cat %}cat-pill-active{% endif %}">All</a>
|
||||
{% for cat, count in categories.items() %}
|
||||
<a href="/drafts?cat={{ cat }}&q={{ search }}&min_score={{ min_score }}&sort={{ sort }}&dir={{ sort_dir }}"
|
||||
<a href="/drafts?cat={{ cat }}&q={{ search | urlencode }}&min_score={{ min_score }}&sort={{ sort }}&dir={{ sort_dir }}"
|
||||
class="cat-pill {% if current_cat == cat %}cat-pill-active{% endif %}">
|
||||
{{ cat }} <span class="opacity-50">{{ count }}</span>
|
||||
</a>
|
||||
@@ -326,7 +326,7 @@
|
||||
{% if result.pages > 1 %}
|
||||
<nav class="flex items-center justify-center gap-1.5 mt-6">
|
||||
{% if result.page > 1 %}
|
||||
<a href="/drafts?page={{ result.page - 1 }}&q={{ search }}&cat={{ current_cat }}&min_score={{ min_score }}&sort={{ sort }}&dir={{ sort_dir }}"
|
||||
<a href="/drafts?page={{ result.page - 1 }}&q={{ search | urlencode }}&cat={{ current_cat | urlencode }}&min_score={{ min_score }}&sort={{ sort }}&dir={{ sort_dir }}"
|
||||
class="page-btn page-btn-inactive">
|
||||
<svg class="w-4 h-4 inline" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/></svg>
|
||||
Prev
|
||||
@@ -337,7 +337,7 @@
|
||||
{% set end_page = [result.pages, result.page + 2]|min %}
|
||||
|
||||
{% if start_page > 1 %}
|
||||
<a href="/drafts?page=1&q={{ search }}&cat={{ current_cat }}&min_score={{ min_score }}&sort={{ sort }}&dir={{ sort_dir }}"
|
||||
<a href="/drafts?page=1&q={{ search | urlencode }}&cat={{ current_cat | urlencode }}&min_score={{ min_score }}&sort={{ sort }}&dir={{ sort_dir }}"
|
||||
class="page-btn page-btn-inactive">1</a>
|
||||
{% if start_page > 2 %}<span class="text-slate-600 px-1">...</span>{% endif %}
|
||||
{% endif %}
|
||||
@@ -346,19 +346,19 @@
|
||||
{% if p == result.page %}
|
||||
<span class="page-btn page-btn-active">{{ p }}</span>
|
||||
{% else %}
|
||||
<a href="/drafts?page={{ p }}&q={{ search }}&cat={{ current_cat }}&min_score={{ min_score }}&sort={{ sort }}&dir={{ sort_dir }}"
|
||||
<a href="/drafts?page={{ p }}&q={{ search | urlencode }}&cat={{ current_cat | urlencode }}&min_score={{ min_score }}&sort={{ sort }}&dir={{ sort_dir }}"
|
||||
class="page-btn page-btn-inactive">{{ p }}</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if end_page < result.pages %}
|
||||
{% if end_page < result.pages - 1 %}<span class="text-slate-600 px-1">...</span>{% endif %}
|
||||
<a href="/drafts?page={{ result.pages }}&q={{ search }}&cat={{ current_cat }}&min_score={{ min_score }}&sort={{ sort }}&dir={{ sort_dir }}"
|
||||
<a href="/drafts?page={{ result.pages }}&q={{ search | urlencode }}&cat={{ current_cat | urlencode }}&min_score={{ min_score }}&sort={{ sort }}&dir={{ sort_dir }}"
|
||||
class="page-btn page-btn-inactive">{{ result.pages }}</a>
|
||||
{% endif %}
|
||||
|
||||
{% if result.page < result.pages %}
|
||||
<a href="/drafts?page={{ result.page + 1 }}&q={{ search }}&cat={{ current_cat }}&min_score={{ min_score }}&sort={{ sort }}&dir={{ sort_dir }}"
|
||||
<a href="/drafts?page={{ result.page + 1 }}&q={{ search | urlencode }}&cat={{ current_cat | urlencode }}&min_score={{ min_score }}&sort={{ sort }}&dir={{ sort_dir }}"
|
||||
class="page-btn page-btn-inactive">
|
||||
Next
|
||||
<svg class="w-4 h-4 inline" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg>
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
{% block extra_scripts %}
|
||||
<script>
|
||||
function downloadCurrentDraft() {
|
||||
const text = {{ draft_text | tojson if draft_text else '""' }};
|
||||
const text = {{ (draft_text or '') | tojson }};
|
||||
const filename = {{ (draft_info.filename if draft_info else 'draft.txt') | tojson }};
|
||||
if (!text) return;
|
||||
const blob = new Blob([text], { type: 'text/plain' });
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
<div class="divide-y divide-slate-800/50 max-h-[600px] overflow-y-auto" id="ideaList">
|
||||
{% for idea in data.ideas %}
|
||||
<div class="idea-item px-4 py-3 hover:bg-slate-800/50 transition"
|
||||
data-search="{{ idea.title|lower }} {{ idea.description|lower }} {{ idea.draft_name|lower }}"
|
||||
data-search="{{ (idea.title or '')|lower }} {{ (idea.description or '')|lower }} {{ (idea.draft_name or '')|lower }}"
|
||||
data-type="{{ idea.type|default('other', true)|lower }}">
|
||||
<div class="flex items-center gap-2 mb-1 flex-wrap">
|
||||
<span class="text-sm font-medium text-slate-200">{{ idea.title }}</span>
|
||||
|
||||
Reference in New Issue
Block a user