generated from john/python-template
delete button on transcript header
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Awaitable
|
||||
from collections.abc import Callable
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
@@ -9,12 +11,15 @@ from nicegui import ui
|
||||
|
||||
from transcription.models import Transcript
|
||||
|
||||
type TranscriptAction = Callable[[Transcript], Awaitable[None] | None]
|
||||
|
||||
|
||||
def render_transcript_revision_row(
|
||||
*,
|
||||
transcript: Transcript,
|
||||
initially_expanded: bool = False,
|
||||
classes: str = "w-full",
|
||||
on_delete: TranscriptAction | None = None,
|
||||
) -> Any:
|
||||
"""Render one collapsible row for a single transcript revision."""
|
||||
status_label = "Failed" if transcript.error_detail else "Transcribed"
|
||||
@@ -26,9 +31,34 @@ def render_transcript_revision_row(
|
||||
)
|
||||
|
||||
with expansion, ui.column().classes("w-full q-gutter-y-sm q-pa-sm"):
|
||||
with expansion.add_slot("header"), ui.column().classes("w-full"):
|
||||
ui.label(header).classes("text-subtitle1 text-weight-medium")
|
||||
ui.label(caption).classes("text-caption text-grey-5")
|
||||
with expansion.add_slot("header"), ui.row().classes("w-full items-start justify-between q-gutter-md"):
|
||||
with ui.column().classes("q-gutter-none"):
|
||||
ui.label(header).classes("text-subtitle1 text-weight-medium")
|
||||
ui.label(caption).classes("text-caption text-grey-5")
|
||||
|
||||
if on_delete is not None:
|
||||
with ui.dialog() as delete_dialog, ui.card().classes("q-pa-md"):
|
||||
ui.label("Delete this transcript revision?").classes("text-body1")
|
||||
with ui.row().classes("w-full justify-end q-gutter-sm"):
|
||||
ui.button("Cancel", on_click=lambda: delete_dialog.submit(False)).props("flat")
|
||||
ui.button("Delete", on_click=lambda: delete_dialog.submit(True)).props(
|
||||
'unelevated color="negative"'
|
||||
)
|
||||
|
||||
async def delete_current_transcript() -> None:
|
||||
delete_dialog.open()
|
||||
confirmed = await delete_dialog
|
||||
if not confirmed:
|
||||
return
|
||||
|
||||
maybe_awaitable = on_delete(transcript)
|
||||
if isinstance(maybe_awaitable, Awaitable):
|
||||
await maybe_awaitable
|
||||
|
||||
with ui.column(align_items="center").classes("self-center q-gutter-none"):
|
||||
ui.button(icon="delete", on_click=delete_current_transcript).props(
|
||||
'flat round dense color="negative"'
|
||||
)
|
||||
_metadata_row(label="Provider", value=transcript.provider)
|
||||
_metadata_row(label="Model", value=transcript.model)
|
||||
_metadata_row(label="Created", value=_format_created_at(transcript.created_at))
|
||||
|
||||
@@ -10,7 +10,9 @@ from nicegui import ui
|
||||
from transcription.app_state import resolve_session_factory
|
||||
from transcription.models import JobStatus
|
||||
from transcription.services.jobs import JobService
|
||||
from transcription.services.transcription import TranscriptionService
|
||||
from transcription.ui.components.app_shell import render_navigation_header
|
||||
from transcription.ui.components.error_presenter import show_error
|
||||
from transcription.ui.components.table.jobs import render_jobs_table
|
||||
|
||||
from ..components.document_panzoom import render_document_panzoom
|
||||
@@ -49,6 +51,7 @@ def register_page() -> None:
|
||||
async def job_detail_page(job_id: str, request: Request) -> None:
|
||||
session_factory = resolve_session_factory(request.app.state)
|
||||
jobs_service = JobService(session_factory=session_factory)
|
||||
transcription_service = TranscriptionService(session_factory=session_factory)
|
||||
render_navigation_header(current_path="/jobs")
|
||||
|
||||
job = await jobs_service.read_job(job_id=UUID(job_id))
|
||||
@@ -66,5 +69,31 @@ def register_page() -> None:
|
||||
ui.chip(job.status.value.upper(), color="green", text_color="white").props("outline")
|
||||
case _:
|
||||
ui.label(f"{job.status.value}").classes("text-subtitle1 text-weight-medium")
|
||||
for i, transcript in enumerate(job.transcripts):
|
||||
render_transcript_revision_row(transcript=transcript, initially_expanded=(i == 0))
|
||||
|
||||
async def delete_transcript_by_id(transcript_id: UUID, revision: int) -> None:
|
||||
try:
|
||||
transcript = await transcription_service.read_transcript(transcript_id=transcript_id)
|
||||
await transcription_service.delete_transcript(transcript)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
show_error(exc, title="Delete failed", operation="jobs.delete_transcript")
|
||||
return
|
||||
|
||||
ui.notify(f"Deleted revision {revision}", type="positive")
|
||||
await render_transcript_list.refresh()
|
||||
|
||||
@ui.refreshable
|
||||
async def render_transcript_list() -> None:
|
||||
refreshed_job = await jobs_service.read_job(job_id=UUID(job_id))
|
||||
for i, transcript in enumerate(refreshed_job.transcripts):
|
||||
render_transcript_revision_row(
|
||||
transcript=transcript,
|
||||
initially_expanded=(i == 0),
|
||||
on_delete=(
|
||||
lambda _transcript, tid=transcript.id, rev=transcript.revision: delete_transcript_by_id(
|
||||
tid,
|
||||
rev,
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
await render_transcript_list()
|
||||
|
||||
Reference in New Issue
Block a user