feat: serve isolated companies below a fixed product path
All checks were successful
All checks were successful
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
This commit is contained in:
parent
09e2239bc6
commit
9345a1bb1a
28 changed files with 350 additions and 117 deletions
|
|
@ -18,7 +18,7 @@
|
|||
<ul class="space-y-1">
|
||||
{% for a in kritische_fristen %}
|
||||
<li class="flex items-center justify-between py-1 text-sm">
|
||||
<a href="/ausschreibungen/{{ a.pk }}/" class="text-brand-700 hover:underline truncate max-w-xs">{{ a.titel }}</a>
|
||||
<a href="{% url 'ausschreibungen:detail' pk=a.pk %}" class="text-brand-700 hover:underline truncate max-w-xs">{{ a.titel }}</a>
|
||||
<span class="ml-2 shrink-0 {% if a.abgabe_bis.date <= today %}text-red-600 font-medium{% else %}text-amber-600{% endif %}">
|
||||
{{ a.abgabe_bis|date:"d.m.Y H:i" }}
|
||||
</span>
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
<ul class="space-y-1">
|
||||
{% for a in ohne_entscheidung %}
|
||||
<li class="py-1 text-sm">
|
||||
<a href="/ausschreibungen/{{ a.pk }}/entscheidung/" class="text-brand-700 hover:underline">{{ a.titel }}</a>
|
||||
<a href="{% url 'ausschreibungen:entscheidung' pk=a.pk %}" class="text-brand-700 hover:underline">{{ a.titel }}</a>
|
||||
<span class="text-slate-400 text-xs ml-1">seit {{ a.erstellt_am|date:"d.m.Y" }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
<ul class="space-y-1">
|
||||
{% for aufgabe in ueberfaellige_aufgaben %}
|
||||
<li class="flex items-center justify-between py-1 text-sm">
|
||||
<a href="/ausschreibungen/{{ aufgabe.ausschreibung_id }}/aufgaben/" class="text-brand-700 hover:underline truncate max-w-xs">
|
||||
<a href="{% url 'ausschreibungen:aufgaben:liste' ausschreibung_id=aufgabe.ausschreibung_id %}" class="text-brand-700 hover:underline truncate max-w-xs">
|
||||
{{ aufgabe.titel }}
|
||||
</a>
|
||||
<span class="text-red-600 text-xs ml-2 shrink-0">{{ aufgabe.frist|date:"d.m.Y" }}</span>
|
||||
|
|
@ -88,7 +88,7 @@
|
|||
<ul class="space-y-1">
|
||||
{% for a in laufende_ausschreibungen %}
|
||||
<li class="flex items-center justify-between py-1 text-sm">
|
||||
<a href="/ausschreibungen/{{ a.pk }}/" class="text-brand-700 hover:underline truncate max-w-xs">{{ a.titel }}</a>
|
||||
<a href="{% url 'ausschreibungen:detail' pk=a.pk %}" class="text-brand-700 hover:underline truncate max-w-xs">{{ a.titel }}</a>
|
||||
{% status_badge a.get_status_display a.status %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
{% block content %}
|
||||
<div class="flex items-center justify-between mb-5">
|
||||
<h1 class="page-title">Freigaben: {{ ausschreibung.titel }}</h1>
|
||||
<button hx-get="/freigaben/modal/?ct={{ ct_id }}&oid={{ ausschreibung.pk }}"
|
||||
<button hx-get="{% url 'freigabe_modal' %}?ct={{ ct_id }}&oid={{ ausschreibung.pk }}"
|
||||
hx-target="#modal-container"
|
||||
class="btn-primary">Freigabe erteilen</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
<div class="flex gap-2 mb-5 flex-wrap">
|
||||
{% for et in entity_types %}
|
||||
<a href="/felder/{{ et }}/"
|
||||
<a href="{% url 'feld_konfiguration_liste' entity_type=et %}"
|
||||
class="px-3 py-1 rounded text-sm {% if et == entity_type %}bg-brand-600 text-white{% else %}bg-slate-100 text-slate-700 hover:bg-slate-200{% endif %}">
|
||||
{{ et }}
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
</div>
|
||||
|
||||
<div x-show="formOpen" x-cloak class="mb-4 bg-slate-50 border border-slate-200 rounded-lg p-3">
|
||||
<form hx-post="/core/attrs/{{ ct_id }}/{{ oid }}/neu/"
|
||||
<form hx-post="{% url 'custom_attribute_neu' content_type_id=ct_id object_id=oid %}"
|
||||
hx-target="closest div[x-data]"
|
||||
hx-swap="outerHTML"
|
||||
class="space-y-2">
|
||||
|
|
@ -39,19 +39,19 @@
|
|||
<span class="text-slate-700 flex-1">{{ attr.value|default:"—" }}</span>
|
||||
<span class="text-xs text-slate-400 bg-slate-100 rounded px-1.5">{{ attr.data_type }}</span>
|
||||
<div class="flex gap-1">
|
||||
<form hx-post="/core/attrs/{{ ct_id }}/{{ oid }}/{{ attr.pk }}/sort/"
|
||||
<form hx-post="{% url 'custom_attribute_sort' content_type_id=ct_id object_id=oid attr_pk=attr.pk %}"
|
||||
hx-target="closest div[x-data]" hx-swap="outerHTML" class="inline">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="direction" value="up">
|
||||
<button type="submit" class="text-slate-300 hover:text-slate-600 text-xs">↑</button>
|
||||
</form>
|
||||
<form hx-post="/core/attrs/{{ ct_id }}/{{ oid }}/{{ attr.pk }}/sort/"
|
||||
<form hx-post="{% url 'custom_attribute_sort' content_type_id=ct_id object_id=oid attr_pk=attr.pk %}"
|
||||
hx-target="closest div[x-data]" hx-swap="outerHTML" class="inline">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="direction" value="down">
|
||||
<button type="submit" class="text-slate-300 hover:text-slate-600 text-xs">↓</button>
|
||||
</form>
|
||||
<form hx-post="/core/attrs/{{ ct_id }}/{{ oid }}/{{ attr.pk }}/loeschen/"
|
||||
<form hx-post="{% url 'custom_attribute_loeschen' content_type_id=ct_id object_id=oid attr_pk=attr.pk %}"
|
||||
hx-target="closest div[x-data]" hx-swap="outerHTML" class="inline"
|
||||
onsubmit="return confirm('Löschen?')">
|
||||
{% csrf_token %}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<tr id="feld-{{ entity_type }}-{{ field_name }}" class="border-b border-slate-100 hover:bg-slate-50">
|
||||
<td class="py-2 font-mono text-xs text-slate-700">{{ field_name }}</td>
|
||||
<td class="py-2">
|
||||
<form hx-post="/felder/{{ entity_type }}/{{ field_name }}/toggle/"
|
||||
<form hx-post="{% url 'feld_konfiguration_toggle' entity_type=entity_type field_name=field_name %}"
|
||||
hx-target="#feld-{{ entity_type }}-{{ field_name }}"
|
||||
hx-swap="outerHTML"
|
||||
class="flex items-center gap-2">
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
</form>
|
||||
</td>
|
||||
<td class="py-2 text-center">
|
||||
<form hx-post="/felder/{{ entity_type }}/{{ field_name }}/toggle/"
|
||||
<form hx-post="{% url 'feld_konfiguration_toggle' entity_type=entity_type field_name=field_name %}"
|
||||
hx-target="#feld-{{ entity_type }}-{{ field_name }}"
|
||||
hx-swap="outerHTML">
|
||||
{% csrf_token %}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,6 @@
|
|||
<p class="text-6xl font-bold text-slate-200 mb-4">404</p>
|
||||
<h1 class="page-title mb-2">Seite nicht gefunden</h1>
|
||||
<p class="text-slate-500 mb-6">Die angeforderte Seite existiert nicht oder wurde verschoben.</p>
|
||||
<a href="/" class="btn-primary">Zur Übersicht</a>
|
||||
<a href="{% url 'home' %}" class="btn-primary">Zur Übersicht</a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,6 @@
|
|||
<p class="text-6xl font-bold text-slate-200 mb-4">500</p>
|
||||
<h1 class="page-title mb-2">Interner Serverfehler</h1>
|
||||
<p class="text-slate-500 mb-6">Ein unerwarteter Fehler ist aufgetreten. Bitte versuche es später erneut.</p>
|
||||
<a href="/" class="btn-primary">Zur Übersicht</a>
|
||||
<a href="{% url 'home' %}" class="btn-primary">Zur Übersicht</a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
</span>
|
||||
</td>
|
||||
<td class="py-2 pr-3" @click.stop>
|
||||
<form hx-post="/feedback/backlog/{{ eintrag.pk }}/bearbeiten/"
|
||||
<form hx-post="{% url 'feedback:eintrag_bearbeiten' pk=eintrag.pk %}"
|
||||
hx-target="#eintrag-wrapper-{{ eintrag.pk }}"
|
||||
hx-swap="outerHTML">
|
||||
{% csrf_token %}
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
{# edit row #}
|
||||
<tr x-show="editing" x-cloak class="bg-slate-50 border-b border-slate-200">
|
||||
<td colspan="6" class="px-6 pt-3 pb-4">
|
||||
<form hx-post="/feedback/backlog/{{ eintrag.pk }}/bearbeiten/"
|
||||
<form hx-post="{% url 'feedback:eintrag_bearbeiten' pk=eintrag.pk %}"
|
||||
hx-target="#eintrag-wrapper-{{ eintrag.pk }}"
|
||||
hx-swap="outerHTML">
|
||||
{% csrf_token %}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<button hx-get="/feedback/modal/"
|
||||
<button hx-get="{% url 'feedback:modal' %}"
|
||||
hx-target="#modal-container"
|
||||
hx-swap="innerHTML"
|
||||
class="fixed bottom-6 right-6 bg-white border border-slate-300 shadow-lg
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<div class="bg-white rounded-xl shadow-xl p-6 w-full max-w-md mx-4"
|
||||
@click.outside="open = false">
|
||||
<h2 class="page-title text-xl mb-4">Feedback</h2>
|
||||
<form hx-post="/feedback/" hx-target="#modal-container" hx-swap="innerHTML">
|
||||
<form hx-post="{% url 'feedback:submit' %}" hx-target="#modal-container" hx-swap="innerHTML">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="seite_kontext" value="{{ request.path }}">
|
||||
{% if current_ausschreibung %}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<div class="bg-white rounded-xl shadow-xl p-6 w-full max-w-md mx-4"
|
||||
@click.outside="open = false">
|
||||
<h2 class="page-title text-xl mb-4">Freigabe erteilen</h2>
|
||||
<form hx-post="/freigaben/erteilen/" hx-target="#modal-container" hx-swap="innerHTML">
|
||||
<form hx-post="{% url 'freigabe_erteilen' %}" hx-target="#modal-container" hx-swap="innerHTML">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="content_type_id" value="{{ content_type_id }}">
|
||||
<input type="hidden" name="object_id" value="{{ object_id }}">
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
{% if ausschreibungen %}
|
||||
<div class="px-3 py-1 text-xs font-medium text-slate-400 uppercase tracking-wide">Ausschreibungen</div>
|
||||
{% for a in ausschreibungen %}
|
||||
<a href="/ausschreibungen/{{ a.pk }}/"
|
||||
<a href="{% url 'ausschreibungen:detail' pk=a.pk %}"
|
||||
class="flex items-center gap-2 px-4 py-2 text-sm text-slate-700 hover:bg-slate-50">
|
||||
<span class="text-base">📋</span>
|
||||
<span>{{ a.titel }}</span>
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
{% if dokumente %}
|
||||
<div class="px-3 py-1 text-xs font-medium text-slate-400 uppercase tracking-wide mt-1">Dokumente</div>
|
||||
{% for d in dokumente %}
|
||||
<a href="/ausschreibungen/{{ d.ausschreibung.pk }}/dokumente/"
|
||||
<a href="{% url 'ausschreibungen:dokumente:liste' ausschreibung_id=d.ausschreibung.pk %}"
|
||||
class="flex items-center gap-2 px-4 py-2 text-sm text-slate-700 hover:bg-slate-50">
|
||||
<span class="text-base">📄</span>
|
||||
<span>{{ d.dateiname }}</span>
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
{% if nachweise %}
|
||||
<div class="px-3 py-1 text-xs font-medium text-slate-400 uppercase tracking-wide mt-1">Nachweise</div>
|
||||
{% for n in nachweise %}
|
||||
<a href="/bibliothek/nachweise/{{ n.pk }}/"
|
||||
<a href="{% url 'bibliothek:nachweis_detail' pk=n.pk %}"
|
||||
class="flex items-center gap-2 px-4 py-2 text-sm text-slate-700 hover:bg-slate-50">
|
||||
<span class="text-base">🏆</span>
|
||||
<span>{{ n.titel }}</span>
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
{% if referenzen %}
|
||||
<div class="px-3 py-1 text-xs font-medium text-slate-400 uppercase tracking-wide mt-1">Referenzen</div>
|
||||
{% for r in referenzen %}
|
||||
<a href="/bibliothek/referenzen/{{ r.pk }}/"
|
||||
<a href="{% url 'bibliothek:referenz_detail' pk=r.pk %}"
|
||||
class="flex items-center gap-2 px-4 py-2 text-sm text-slate-700 hover:bg-slate-50">
|
||||
<span class="text-base">⭐</span>
|
||||
<span>{{ r.referenztitel }}</span>
|
||||
|
|
@ -53,7 +53,7 @@
|
|||
{% if marktbegleiter %}
|
||||
<div class="px-3 py-1 text-xs font-medium text-slate-400 uppercase tracking-wide mt-1">Marktbegleiter</div>
|
||||
{% for m in marktbegleiter %}
|
||||
<a href="/marktbegleiter/{{ m.pk }}/"
|
||||
<a href="{% url 'marktbegleiter:detail' pk=m.pk %}"
|
||||
class="flex items-center gap-2 px-4 py-2 text-sm text-slate-700 hover:bg-slate-50">
|
||||
<span class="text-base">🔍</span>
|
||||
<span>{{ m.name }}</span>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
x-show="sidebarOpen"
|
||||
x-cloak>
|
||||
<nav class="p-3 space-y-1 flex-1">
|
||||
<a href="/"
|
||||
<a href="{% url 'home' %}"
|
||||
class="sidebar-link {% if request.resolver_match.url_name == 'dashboard' %}sidebar-link-active{% endif %}">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/>
|
||||
|
|
@ -16,8 +16,8 @@
|
|||
<span x-text="open ? '▾' : '▸'" class="text-slate-400"></span>
|
||||
</button>
|
||||
<div x-show="open" class="ml-3 space-y-1">
|
||||
<a href="/ausschreibungen/" class="sidebar-link">Alle Ausschreibungen</a>
|
||||
<a href="/ausschreibungen/neu/" class="sidebar-link text-brand-600 font-medium">+ Neu</a>
|
||||
<a href="{% url 'ausschreibungen:liste' %}" class="sidebar-link">Alle Ausschreibungen</a>
|
||||
<a href="{% url 'ausschreibungen:neu' %}" class="sidebar-link text-brand-600 font-medium">+ Neu</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -27,10 +27,10 @@
|
|||
<span x-text="open ? '▾' : '▸'" class="text-slate-400"></span>
|
||||
</button>
|
||||
<div x-show="open" class="ml-3 space-y-1">
|
||||
<a href="/bibliothek/nachweise/" class="sidebar-link">Nachweise</a>
|
||||
<a href="/bibliothek/referenzen/" class="sidebar-link">Referenzen</a>
|
||||
<a href="/bibliothek/leistungsblaetter/" class="sidebar-link">Leistungsblätter</a>
|
||||
<a href="/bibliothek/entscheidungsregeln/" class="sidebar-link">Entscheidungsregeln</a>
|
||||
<a href="{% url 'bibliothek:nachweise_liste' %}" class="sidebar-link">Nachweise</a>
|
||||
<a href="{% url 'bibliothek:referenz_liste' %}" class="sidebar-link">Referenzen</a>
|
||||
<a href="{% url 'bibliothek:leistungsblaetter_liste' %}" class="sidebar-link">Leistungsblätter</a>
|
||||
<a href="{% url 'bibliothek:entscheidungsregeln_liste' %}" class="sidebar-link">Entscheidungsregeln</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -40,17 +40,17 @@
|
|||
<span x-text="open ? '▾' : '▸'" class="text-slate-400"></span>
|
||||
</button>
|
||||
<div x-show="open" class="ml-3 space-y-1">
|
||||
<a href="/partner/subunternehmer/" class="sidebar-link">Subunternehmer</a>
|
||||
<a href="/partner/dienstleistertypen/" class="sidebar-link">Dienstleistertypen</a>
|
||||
<a href="{% url 'partner:su_liste' %}" class="sidebar-link">Subunternehmer</a>
|
||||
<a href="{% url 'partner:dt_liste' %}" class="sidebar-link">Dienstleistertypen</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="/aufgaben/" class="sidebar-link">Aufgaben</a>
|
||||
<a href="/marktbegleiter/" class="sidebar-link">Marktbegleiter</a>
|
||||
<a href="/feedback/backlog/" class="sidebar-link">Feedback-Backlog</a>
|
||||
<a href="{% url 'aufgaben_global' %}" class="sidebar-link">Aufgaben</a>
|
||||
<a href="{% url 'marktbegleiter:liste' %}" class="sidebar-link">Marktbegleiter</a>
|
||||
<a href="{% url 'feedback:backlog' %}" class="sidebar-link">Feedback-Backlog</a>
|
||||
|
||||
{% if request.user.is_staff %}
|
||||
<a href="/admin/" class="sidebar-link text-slate-400">Administration</a>
|
||||
<a href="{% url 'admin:index' %}" class="sidebar-link text-slate-400">Administration</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
</svg>
|
||||
</button>
|
||||
|
||||
<a href="/" class="text-brand-700 font-semibold text-lg shrink-0">Vergabe Teilnahme</a>
|
||||
<a href="{% url 'home' %}" class="text-brand-700 font-semibold text-lg shrink-0">Vergabe Teilnahme</a>
|
||||
|
||||
<form hx-get="/suche/" hx-target="#search-results" hx-trigger="input changed delay:300ms"
|
||||
<form hx-get="{% url 'suche' %}" hx-target="#search-results" hx-trigger="input changed delay:300ms"
|
||||
class="relative flex-1 max-w-lg mx-auto">
|
||||
<input name="q" type="search" placeholder="Ausschreibung, Aufgabe, Dokument suchen..."
|
||||
autocomplete="off"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue