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(),
|
||||
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,
|
||||
readme_html=readme_html,
|
||||
stats=stats,
|
||||
nav_counts=stats, # Reuse stats for nav counts
|
||||
active_tab="home",
|
||||
)
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
{% block nav_items %}
|
||||
<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="/recipes" class="text-gray-300 hover:text-white {% if active_tab == 'recipes' %}text-white font-medium{% endif %}">Recipes</a>
|
||||
<a href="/effects" class="text-gray-300 hover:text-white {% if active_tab == 'effects' %}text-white font-medium{% endif %}">Effects</a>
|
||||
<a href="/media" class="text-gray-300 hover:text-white {% if active_tab == 'media' %}text-white font-medium{% endif %}">Media</a>
|
||||
<a href="/storage" class="text-gray-300 hover:text-white {% if active_tab == 'storage' %}text-white font-medium{% endif %}">Storage</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{% 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{% 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{% 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{% 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>
|
||||
</nav>
|
||||
{% endblock %}
|
||||
|
||||
@@ -37,12 +37,20 @@
|
||||
<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="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 class="bg-gray-800 rounded-lg p-4">
|
||||
<div class="text-gray-500 text-sm">Steps</div>
|
||||
<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 %}
|
||||
<span class="text-purple-400 text-sm">({{ run.cached_steps }} cached)</span>
|
||||
{% endif %}
|
||||
|
||||
Reference in New Issue
Block a user