Improve basis workspace UX with clearly separated form and table sections
This commit is contained in:
138
app/admin_web.py
138
app/admin_web.py
@@ -682,68 +682,86 @@ def _basis_item_workspace_body(
|
|||||||
)
|
)
|
||||||
|
|
||||||
return f"""
|
return f"""
|
||||||
<p class="muted">
|
|
||||||
Parent Item: <strong>#{basis_item.id}</strong> |
|
|
||||||
Tryout: <strong>{escape(basis_item.tryout_id)}</strong> |
|
|
||||||
Slot: <strong>{basis_item.slot}</strong> |
|
|
||||||
Website: <strong>{basis_item.website_id}</strong> |
|
|
||||||
Source Snapshot QID: <strong>{basis_item.source_snapshot_question_id or '-'}</strong>
|
|
||||||
</p>
|
|
||||||
<p class="muted">
|
|
||||||
Family Usage: impressions=<strong>{int(family_stats.get("impressions", 0.0))}</strong>,
|
|
||||||
unique users=<strong>{int(family_stats.get("unique_users", 0.0))}</strong>,
|
|
||||||
frequency=<strong>{family_stats.get("frequency", 0.0):.2f}</strong>
|
|
||||||
</p>
|
|
||||||
<p class="muted"><strong>Stem:</strong> {escape(_truncate(basis_item.stem, 260))}</p>
|
|
||||||
{success_html}
|
{success_html}
|
||||||
{error_html}
|
{error_html}
|
||||||
<h3 style="margin-top:18px">Variant Filters</h3>
|
<section style="border:1px solid #e2e8f0;border-radius:12px;padding:16px;background:#f8fafc;">
|
||||||
<form method="get" action="/admin/basis-items/{basis_item.id}" autocomplete="off">
|
<h3 style="margin:0 0 10px;">Parent Summary</h3>
|
||||||
<label for="status">Status</label>
|
<p class="muted" style="margin:0 0 8px;">
|
||||||
<select id="status" name="status">
|
Parent Item: <strong>#{basis_item.id}</strong> |
|
||||||
<option value="" {"selected" if status_filter == "" else ""}>All</option>
|
Tryout: <strong>{escape(basis_item.tryout_id)}</strong> |
|
||||||
<option value="draft" {"selected" if status_filter == "draft" else ""}>draft</option>
|
Slot: <strong>{basis_item.slot}</strong> |
|
||||||
<option value="approved" {"selected" if status_filter == "approved" else ""}>approved</option>
|
Website: <strong>{basis_item.website_id}</strong> |
|
||||||
<option value="active" {"selected" if status_filter == "active" else ""}>active</option>
|
Source Snapshot QID: <strong>{basis_item.source_snapshot_question_id or '-'}</strong>
|
||||||
<option value="rejected" {"selected" if status_filter == "rejected" else ""}>rejected</option>
|
</p>
|
||||||
<option value="archived" {"selected" if status_filter == "archived" else ""}>archived</option>
|
<p class="muted" style="margin:0 0 8px;">
|
||||||
<option value="stale" {"selected" if status_filter == "stale" else ""}>stale</option>
|
Family Usage: impressions=<strong>{int(family_stats.get("impressions", 0.0))}</strong>,
|
||||||
</select>
|
unique users=<strong>{int(family_stats.get("unique_users", 0.0))}</strong>,
|
||||||
<label for="level">Level</label>
|
frequency=<strong>{family_stats.get("frequency", 0.0):.2f}</strong>
|
||||||
<select id="level" name="level">
|
</p>
|
||||||
<option value="" {"selected" if level_filter == "" else ""}>All</option>
|
<p class="muted" style="margin:0;"><strong>Stem:</strong> {escape(_truncate(basis_item.stem, 260))}</p>
|
||||||
<option value="mudah" {"selected" if level_filter == "mudah" else ""}>mudah</option>
|
</section>
|
||||||
<option value="sulit" {"selected" if level_filter == "sulit" else ""}>sulit</option>
|
|
||||||
</select>
|
<section style="margin-top:16px;border:1px solid #e2e8f0;border-radius:12px;padding:16px;background:#fff;">
|
||||||
<label for="run_id">Generation Run ID</label>
|
<h3 style="margin:0 0 8px;">Generate Variants</h3>
|
||||||
<input id="run_id" name="run_id" type="number" min="1" value="{escape(run_id_filter)}">
|
<p class="muted" style="margin:0 0 12px;">Create new AI child variants for this parent.</p>
|
||||||
<label for="min_frequency">Min Frequency</label>
|
<form method="post" action="/admin/basis-items/{basis_item.id}/generate" autocomplete="off">
|
||||||
<input id="min_frequency" name="min_frequency" type="number" min="0" step="0.1" value="{escape(min_frequency_filter)}">
|
<label for="target_level">Target Level</label>
|
||||||
<div class="actions">
|
<select id="target_level" name="target_level">
|
||||||
<button type="submit">Apply Filters</button>
|
<option value="mudah" {"selected" if target_level == "mudah" else ""}>mudah</option>
|
||||||
<a href="/admin/basis-items/{basis_item.id}" style="display:inline-block;padding:12px 14px;border-radius:10px;background:#e2e8f0;color:#0f172a;text-decoration:none;font-size:15px;font-weight:600;">Reset</a>
|
<option value="sulit" {"selected" if target_level == "sulit" else ""}>sulit</option>
|
||||||
</div>
|
</select>
|
||||||
</form>
|
<label for="ai_model">Model</label>
|
||||||
<form method="post" action="/admin/basis-items/{basis_item.id}/generate" autocomplete="off">
|
<select id="ai_model" name="ai_model">{model_options}</select>
|
||||||
<label for="target_level">Target Level</label>
|
<label for="generation_count">Generate Count</label>
|
||||||
<select id="target_level" name="target_level">
|
<input id="generation_count" name="generation_count" type="number" min="1" max="50" value="{escape(generation_count)}">
|
||||||
<option value="mudah" {"selected" if target_level == "mudah" else ""}>mudah</option>
|
<p class="muted">Recommended: 1-3 per run. Larger runs increase overlap and review burden.</p>
|
||||||
<option value="sulit" {"selected" if target_level == "sulit" else ""}>sulit</option>
|
<label for="operator_notes">Operator Notes (optional)</label>
|
||||||
</select>
|
<textarea id="operator_notes" name="operator_notes" rows="3">{escape(operator_notes)}</textarea>
|
||||||
<label for="ai_model">Model</label>
|
<button type="submit">Generate Variants</button>
|
||||||
<select id="ai_model" name="ai_model">{model_options}</select>
|
</form>
|
||||||
<label for="generation_count">Generate Count</label>
|
</section>
|
||||||
<input id="generation_count" name="generation_count" type="number" min="1" max="50" value="{escape(generation_count)}">
|
|
||||||
<p class="muted">Recommended: 1-3 per run. Larger runs increase overlap and review burden.</p>
|
<section style="margin-top:16px;border:1px solid #e2e8f0;border-radius:12px;padding:16px;background:#fff;">
|
||||||
<label for="operator_notes">Operator Notes (optional)</label>
|
<h3 style="margin:0 0 8px;">Filter Variants</h3>
|
||||||
<textarea id="operator_notes" name="operator_notes" rows="3">{escape(operator_notes)}</textarea>
|
<p class="muted" style="margin:0 0 12px;">Filter child variants shown in the review table below.</p>
|
||||||
<button type="submit">Generate Variants</button>
|
<form method="get" action="/admin/basis-items/{basis_item.id}" autocomplete="off">
|
||||||
</form>
|
<label for="status">Status</label>
|
||||||
<h3 style="margin-top:24px">Generation Runs for This Parent</h3>
|
<select id="status" name="status">
|
||||||
{runs_table}
|
<option value="" {"selected" if status_filter == "" else ""}>All</option>
|
||||||
<h3 style="margin-top:24px">Child Variants for This Parent</h3>
|
<option value="draft" {"selected" if status_filter == "draft" else ""}>draft</option>
|
||||||
<p class="muted">Filtered variants shown: <strong>{len(variants)}</strong></p>
|
<option value="approved" {"selected" if status_filter == "approved" else ""}>approved</option>
|
||||||
{variants_table}
|
<option value="active" {"selected" if status_filter == "active" else ""}>active</option>
|
||||||
|
<option value="rejected" {"selected" if status_filter == "rejected" else ""}>rejected</option>
|
||||||
|
<option value="archived" {"selected" if status_filter == "archived" else ""}>archived</option>
|
||||||
|
<option value="stale" {"selected" if status_filter == "stale" else ""}>stale</option>
|
||||||
|
</select>
|
||||||
|
<label for="level">Level</label>
|
||||||
|
<select id="level" name="level">
|
||||||
|
<option value="" {"selected" if level_filter == "" else ""}>All</option>
|
||||||
|
<option value="mudah" {"selected" if level_filter == "mudah" else ""}>mudah</option>
|
||||||
|
<option value="sulit" {"selected" if level_filter == "sulit" else ""}>sulit</option>
|
||||||
|
</select>
|
||||||
|
<label for="run_id">Generation Run ID</label>
|
||||||
|
<input id="run_id" name="run_id" type="number" min="1" value="{escape(run_id_filter)}">
|
||||||
|
<label for="min_frequency">Min Frequency</label>
|
||||||
|
<input id="min_frequency" name="min_frequency" type="number" min="0" step="0.1" value="{escape(min_frequency_filter)}">
|
||||||
|
<div class="actions">
|
||||||
|
<button type="submit">Apply Filters</button>
|
||||||
|
<a href="/admin/basis-items/{basis_item.id}" style="display:inline-block;padding:12px 14px;border-radius:10px;background:#e2e8f0;color:#0f172a;text-decoration:none;font-size:15px;font-weight:600;">Reset</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section style="margin-top:16px;border:1px solid #e2e8f0;border-radius:12px;padding:16px;background:#fff;">
|
||||||
|
<h3 style="margin:0 0 12px;">Generation Runs for This Parent</h3>
|
||||||
|
{runs_table}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section style="margin-top:16px;border:1px solid #e2e8f0;border-radius:12px;padding:16px;background:#fff;">
|
||||||
|
<h3 style="margin:0 0 8px;">Child Variants for This Parent</h3>
|
||||||
|
<p class="muted">Filtered variants shown: <strong>{len(variants)}</strong></p>
|
||||||
|
{variants_table}
|
||||||
|
</section>
|
||||||
<p style="margin-top:20px"><a href="/admin/basis-items">Back to Basis Items</a></p>
|
<p style="margin-top:20px"><a href="/admin/basis-items">Back to Basis Items</a></p>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user