Add recipe link, fix step count, add nav counts
- Make recipe name clickable link to recipe page on run detail - Fix step count to use plan.steps length as fallback - Add nav_counts support to base template for showing counts in brackets - Add get_nav_counts helper in dependencies - Pass nav_counts on home page Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -139,3 +139,48 @@ def get_cache_service():
|
|||||||
cache_manager=get_cache_manager(),
|
cache_manager=get_cache_manager(),
|
||||||
database=get_database(),
|
database=get_database(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def get_nav_counts(actor_id: Optional[str] = None) -> dict:
|
||||||
|
"""
|
||||||
|
Get counts for navigation bar display.
|
||||||
|
|
||||||
|
Returns dict with: runs, recipes, effects, media, storage
|
||||||
|
"""
|
||||||
|
counts = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
import database
|
||||||
|
counts["media"] = await database.count_user_items(actor_id) if actor_id else 0
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
recipe_service = get_recipe_service()
|
||||||
|
recipes = await recipe_service.list_recipes(actor_id)
|
||||||
|
counts["recipes"] = len(recipes)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
run_service = get_run_service()
|
||||||
|
runs = await run_service.list_runs(actor_id)
|
||||||
|
counts["runs"] = len(runs)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
cache_mgr = get_cache_manager()
|
||||||
|
effects = cache_mgr.list_by_type('effect')
|
||||||
|
counts["effects"] = len(effects)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
import database
|
||||||
|
storage_providers = await database.get_user_storage_providers(actor_id) if actor_id else []
|
||||||
|
counts["storage"] = len(storage_providers) if storage_providers else 0
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return counts
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ async def home(request: Request):
|
|||||||
user=user,
|
user=user,
|
||||||
readme_html=readme_html,
|
readme_html=readme_html,
|
||||||
stats=stats,
|
stats=stats,
|
||||||
|
nav_counts=stats, # Reuse stats for nav counts
|
||||||
active_tab="home",
|
active_tab="home",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
{% block nav_items %}
|
{% block nav_items %}
|
||||||
<nav class="flex items-center space-x-6">
|
<nav class="flex items-center space-x-6">
|
||||||
<a href="/runs" class="text-gray-300 hover:text-white {% if active_tab == 'runs' %}text-white font-medium{% endif %}">Runs</a>
|
<a href="/runs" class="text-gray-300 hover:text-white {% if active_tab == 'runs' %}text-white font-medium{% endif %}">Runs{% if nav_counts and nav_counts.runs %} ({{ nav_counts.runs }}){% endif %}</a>
|
||||||
<a href="/recipes" class="text-gray-300 hover:text-white {% if active_tab == 'recipes' %}text-white font-medium{% endif %}">Recipes</a>
|
<a href="/recipes" class="text-gray-300 hover:text-white {% if active_tab == 'recipes' %}text-white font-medium{% endif %}">Recipes{% if nav_counts and nav_counts.recipes %} ({{ nav_counts.recipes }}){% endif %}</a>
|
||||||
<a href="/effects" class="text-gray-300 hover:text-white {% if active_tab == 'effects' %}text-white font-medium{% endif %}">Effects</a>
|
<a href="/effects" class="text-gray-300 hover:text-white {% if active_tab == 'effects' %}text-white font-medium{% endif %}">Effects{% if nav_counts and nav_counts.effects %} ({{ nav_counts.effects }}){% endif %}</a>
|
||||||
<a href="/media" class="text-gray-300 hover:text-white {% if active_tab == 'media' %}text-white font-medium{% endif %}">Media</a>
|
<a href="/media" class="text-gray-300 hover:text-white {% if active_tab == 'media' %}text-white font-medium{% endif %}">Media{% if nav_counts and nav_counts.media %} ({{ nav_counts.media }}){% endif %}</a>
|
||||||
<a href="/storage" class="text-gray-300 hover:text-white {% if active_tab == 'storage' %}text-white font-medium{% endif %}">Storage</a>
|
<a href="/storage" class="text-gray-300 hover:text-white {% if active_tab == 'storage' %}text-white font-medium{% endif %}">Storage{% if nav_counts and nav_counts.storage %} ({{ nav_counts.storage }}){% endif %}</a>
|
||||||
<a href="/download/client" class="text-gray-300 hover:text-white" title="Download CLI client">Client</a>
|
<a href="/download/client" class="text-gray-300 hover:text-white" title="Download CLI client">Client</a>
|
||||||
</nav>
|
</nav>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -37,12 +37,20 @@
|
|||||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
|
||||||
<div class="bg-gray-800 rounded-lg p-4">
|
<div class="bg-gray-800 rounded-lg p-4">
|
||||||
<div class="text-gray-500 text-sm">Recipe</div>
|
<div class="text-gray-500 text-sm">Recipe</div>
|
||||||
<div class="text-white font-medium">{{ run.recipe_name or run.recipe[:16] ~ '...' if run.recipe and run.recipe|length > 16 else run.recipe or 'Unknown' }}</div>
|
<div class="text-white font-medium">
|
||||||
|
{% if run.recipe %}
|
||||||
|
<a href="/recipes/{{ run.recipe }}" class="hover:text-blue-400">
|
||||||
|
{{ run.recipe_name or (run.recipe[:16] ~ '...') }}
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
Unknown
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-gray-800 rounded-lg p-4">
|
<div class="bg-gray-800 rounded-lg p-4">
|
||||||
<div class="text-gray-500 text-sm">Steps</div>
|
<div class="text-gray-500 text-sm">Steps</div>
|
||||||
<div class="text-white font-medium">
|
<div class="text-white font-medium">
|
||||||
{{ run.executed or 0 }} / {{ run.total_steps or '?' }}
|
{{ run.executed or 0 }} / {{ run.total_steps or (plan.steps|length if plan and plan.steps else '?') }}
|
||||||
{% if run.cached_steps %}
|
{% if run.cached_steps %}
|
||||||
<span class="text-purple-400 text-sm">({{ run.cached_steps }} cached)</span>
|
<span class="text-purple-400 text-sm">({{ run.cached_steps }} cached)</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
Reference in New Issue
Block a user