Complete L1 router and template migration
- Full implementation of runs, recipes, cache routers with templates - Auth and storage routers fully migrated - Jinja2 templates for all L1 pages - Service layer for auth and storage 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
112
app/templates/recipes/detail.html
Normal file
112
app/templates/recipes/detail.html
Normal file
@@ -0,0 +1,112 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ recipe.name }} - Recipe - Art-DAG L1{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.23.0/cytoscape.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-6xl mx-auto">
|
||||
<!-- Header -->
|
||||
<div class="flex items-center space-x-4 mb-6">
|
||||
<a href="/recipes" class="text-gray-400 hover:text-white">← Recipes</a>
|
||||
<h1 class="text-2xl font-bold">{{ recipe.name }}</h1>
|
||||
{% if recipe.version %}
|
||||
<span class="text-gray-500">v{{ recipe.version }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if recipe.description %}
|
||||
<p class="text-gray-400 mb-6">{{ recipe.description }}</p>
|
||||
{% endif %}
|
||||
|
||||
<!-- DAG Visualization -->
|
||||
<div class="bg-gray-800 rounded-lg border border-gray-700 mb-6">
|
||||
<div class="border-b border-gray-700 px-4 py-2 flex items-center justify-between">
|
||||
<span class="text-gray-400 text-sm">Pipeline DAG</span>
|
||||
<span class="text-gray-500 text-sm">{{ recipe.steps | length }} steps</span>
|
||||
</div>
|
||||
<div id="dag-container" class="h-80"></div>
|
||||
</div>
|
||||
|
||||
<!-- Steps -->
|
||||
<h2 class="text-lg font-semibold mb-4">Steps</h2>
|
||||
<div class="space-y-3 mb-8">
|
||||
{% for step in recipe.steps %}
|
||||
{% set colors = {
|
||||
'effect': 'blue',
|
||||
'analyze': 'purple',
|
||||
'transform': 'green',
|
||||
'combine': 'orange',
|
||||
'output': 'cyan'
|
||||
} %}
|
||||
{% set color = colors.get(step.type, 'gray') %}
|
||||
|
||||
<div class="bg-gray-800 rounded-lg p-4 border border-gray-700">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<div class="flex items-center space-x-3">
|
||||
<span class="w-8 h-8 rounded bg-{{ color }}-900 text-{{ color }}-300 flex items-center justify-center font-mono text-sm">
|
||||
{{ loop.index }}
|
||||
</span>
|
||||
<span class="font-medium">{{ step.name }}</span>
|
||||
<span class="bg-{{ color }}-900 text-{{ color }}-300 px-2 py-0.5 rounded text-xs">
|
||||
{{ step.type }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if step.inputs %}
|
||||
<div class="text-sm text-gray-400 mb-1">
|
||||
Inputs: {{ step.inputs | join(', ') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if step.params %}
|
||||
<div class="mt-2 bg-gray-900 rounded p-2">
|
||||
<code class="text-xs text-gray-400">{{ step.params | tojson }}</code>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- YAML Source -->
|
||||
<h2 class="text-lg font-semibold mb-4">Source</h2>
|
||||
<div class="bg-gray-900 rounded-lg p-4 border border-gray-700">
|
||||
<pre class="text-sm text-gray-300 overflow-x-auto whitespace-pre-wrap">{{ recipe.yaml }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const cy = cytoscape({
|
||||
container: document.getElementById('dag-container'),
|
||||
style: [
|
||||
{ selector: 'node', style: {
|
||||
'label': 'data(label)',
|
||||
'background-color': 'data(color)',
|
||||
'color': '#fff',
|
||||
'text-valign': 'center',
|
||||
'text-halign': 'center',
|
||||
'font-size': '11px',
|
||||
'width': 'label',
|
||||
'height': 35,
|
||||
'padding': '10px',
|
||||
'shape': 'round-rectangle'
|
||||
}},
|
||||
{ selector: 'edge', style: {
|
||||
'width': 2,
|
||||
'line-color': '#4b5563',
|
||||
'target-arrow-color': '#4b5563',
|
||||
'target-arrow-shape': 'triangle',
|
||||
'curve-style': 'bezier'
|
||||
}}
|
||||
],
|
||||
elements: {{ dag_elements | tojson }},
|
||||
layout: { name: 'dagre', rankDir: 'LR', padding: 30 }
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
55
app/templates/recipes/list.html
Normal file
55
app/templates/recipes/list.html
Normal file
@@ -0,0 +1,55 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Recipes - Art-DAG L1{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="max-w-6xl mx-auto">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h1 class="text-3xl font-bold">Recipes</h1>
|
||||
</div>
|
||||
|
||||
<p class="text-gray-400 mb-8">
|
||||
Recipes define processing pipelines for audio and media. Each recipe is a DAG of effects.
|
||||
</p>
|
||||
|
||||
{% if recipes %}
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{% for recipe in recipes %}
|
||||
<a href="/recipe/{{ recipe.id }}"
|
||||
class="bg-gray-800 border border-gray-700 rounded-lg p-4 hover:border-gray-600 transition-colors">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="font-medium text-white">{{ recipe.name }}</span>
|
||||
{% if recipe.version %}
|
||||
<span class="text-gray-500 text-sm">v{{ recipe.version }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if recipe.description %}
|
||||
<p class="text-gray-400 text-sm mb-3 line-clamp-2">{{ recipe.description }}</p>
|
||||
{% endif %}
|
||||
|
||||
<div class="flex items-center justify-between text-sm">
|
||||
<span class="text-gray-500">{{ recipe.step_count or 0 }} steps</span>
|
||||
{% if recipe.last_run %}
|
||||
<span class="text-gray-500">Last run: {{ recipe.last_run }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if recipe.tags %}
|
||||
<div class="mt-2 flex flex-wrap gap-1">
|
||||
{% for tag in recipe.tags %}
|
||||
<span class="bg-gray-700 text-gray-300 px-2 py-0.5 rounded text-xs">{{ tag }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="bg-gray-800 border border-gray-700 rounded-lg p-12 text-center">
|
||||
<p class="text-gray-500 mb-4">No recipes available.</p>
|
||||
<p class="text-gray-600 text-sm">Recipes are defined in YAML format and submitted via API.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user