Add REST endpoints and frontend wiring for per-language project actions:
- POST /api/workspace/{project}/translation/{lang}/queue — queue translation
- POST /api/workspace/{project}/audio/{lang}/queue — queue audio generation
- GET/POST /api/workspace/{project}/format/{lang} — format metadata (EPUB/PDF)
- GET /api/workspace/{project}/review/{lang}/chapters/{chapter} — utterance review
- GET/POST /api/workspace/{project}/front-matter/{lang} — front matter editor
- GET /api/workspace/{project}/chapters/{lang} — chapter list
- GET /api/workspace/{project}/chapter-content/{lang}/{chapter} — chapter text
Frontend fixes:
- Review page shows per-language text (English source, Chinese translation, etc.)
- Non-translated languages show 'Queue translation' button only
- Speaker data from English source matched by paragraph ID
- UmbraAudio column layout: Speaker, Variation, Text, Actions
- Chapter tree in left sidebar: Front matter, Back matter, Body
- Audio Format label at top of sidebar
- Pandoc formatting toolbar for front matter text editing
144 lines
6.3 KiB
HTML
144 lines
6.3 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Project · UmbraTrans</title>
|
|
<link rel="icon" type="image/png" href="assets/umbratrans-emblem.png">
|
|
<link rel="stylesheet" href="assets/styles.css">
|
|
</head>
|
|
<body class="workspace-page">
|
|
<div class="workspace-shell">
|
|
<aside class="workspace-rail" id="workspace-rail" aria-label="Workspace navigation">
|
|
<a class="brand-lockup brand-lockup--rail" href="workspace.html">
|
|
<img class="brand-image" src="assets/umbratrans-emblem.png" alt="" aria-hidden="true">
|
|
<span>UmbraTrans</span>
|
|
</a>
|
|
<div class="rail-section-label">Project</div>
|
|
<nav class="rail-nav">
|
|
<a class="rail-link rail-link--active" href="#overview"><span class="rail-icon" aria-hidden="true">⌂</span>Overview</a>
|
|
<a class="rail-link" href="#english"><span class="rail-icon" aria-hidden="true">文</span>English Source</a>
|
|
<a class="rail-link" href="#translations"><span class="rail-icon" aria-hidden="true">译</span>Translations</a>
|
|
<a class="rail-link" href="#outputs"><span class="rail-icon" aria-hidden="true">◇</span>Outputs</a>
|
|
<a class="rail-link" href="#audio"><span class="rail-icon" aria-hidden="true">▶</span>Audio</a>
|
|
</nav>
|
|
<div class="rail-footer">
|
|
<div class="rail-user">
|
|
<span class="avatar" id="rail-avatar" aria-hidden="true">··</span>
|
|
<span>
|
|
<strong id="rail-display-name">Loading…</strong>
|
|
<small id="rail-role">Checking session</small>
|
|
</span>
|
|
</div>
|
|
<a class="text-button" href="workspace.html">Back to workspace</a>
|
|
<button class="text-button" type="button" data-signout>Sign out</button>
|
|
</div>
|
|
</aside>
|
|
|
|
<main class="workspace-main" id="overview">
|
|
<header class="workspace-topbar">
|
|
<button class="text-button" type="button" data-nav-toggle aria-expanded="false" aria-controls="workspace-rail" aria-label="Open navigation" hidden>☰</button>
|
|
<div class="breadcrumb"><a href="workspace.html">Workspace</a><span aria-hidden="true">/</span><strong id="breadcrumb-identity">Loading…</strong></div>
|
|
<div class="topbar-actions">
|
|
<span class="status-pill status-pill--info" id="project-status-pill">—</span>
|
|
<a class="text-button" href="workspace.html">Workspace</a>
|
|
<button class="text-button" type="button" data-signout>Sign out</button>
|
|
</div>
|
|
</header>
|
|
|
|
<section class="workspace-hero">
|
|
<div>
|
|
<p class="eyebrow eyebrow--teal">Project workspace</p>
|
|
<h1 id="project-title">Loading…</h1>
|
|
<p class="hero-subtitle" id="project-subtitle">—</p>
|
|
</div>
|
|
<div class="hero-actions">
|
|
<button class="button button--secondary" type="button" id="btn-queue-translation">Queue Translation</button>
|
|
<button class="button button--primary" type="button" id="btn-generate-epub">Generate EPUB</button>
|
|
<button class="button button--primary" type="button" id="btn-generate-pdf">Generate PDF</button>
|
|
<button class="button button--primary" type="button" id="btn-generate-audio">Generate Audio</button>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="pipeline-card" id="english">
|
|
<div class="section-heading">
|
|
<div>
|
|
<p class="eyebrow eyebrow--teal">Source</p>
|
|
<h2>English Source</h2>
|
|
</div>
|
|
</div>
|
|
<p class="list-summary">Original input book text (editable in line with Umbra Audio UI).</p>
|
|
<div class="table-wrap">
|
|
<table class="data-table">
|
|
<thead>
|
|
<tr><th>Chapter</th><th>Title</th><th>Words</th><th>Status</th><th></th></tr>
|
|
</thead>
|
|
<tbody id="english-tbody"></tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="pipeline-card" id="translations">
|
|
<div class="section-heading">
|
|
<div>
|
|
<p class="eyebrow eyebrow--teal">Translations</p>
|
|
<h2>Translated Versions</h2>
|
|
</div>
|
|
<div class="section-heading__actions">
|
|
<button class="chip" type="button" id="btn-add-lang">Add Language</button>
|
|
</div>
|
|
</div>
|
|
<p class="list-summary">View translations, tag for review/updates. English and Chinese shown when available.</p>
|
|
<div id="translations-list" class="project-list"></div>
|
|
<div class="empty-state" id="translations-empty">
|
|
<span class="empty-state__icon" aria-hidden="true">译</span>
|
|
<p class="empty-state__title">No translations yet</p>
|
|
<p class="empty-state__body">Queue a translation to start. Chinese translation may be in progress.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="pipeline-card" id="outputs">
|
|
<div class="section-heading">
|
|
<div>
|
|
<p class="eyebrow eyebrow--teal">Outputs</p>
|
|
<h2>Output Formats</h2>
|
|
</div>
|
|
</div>
|
|
<div class="metric-grid">
|
|
<article class="metric-card">
|
|
<span class="metric-label">EPUB</span>
|
|
<strong id="out-epub">—</strong>
|
|
<span class="metric-note">Status / availability</span>
|
|
</article>
|
|
<article class="metric-card">
|
|
<span class="metric-label">PDF</span>
|
|
<strong id="out-pdf">—</strong>
|
|
<span class="metric-note">Status / availability</span>
|
|
</article>
|
|
<article class="metric-card">
|
|
<span class="metric-label">Audio</span>
|
|
<strong id="out-audio">—</strong>
|
|
<span class="metric-note">Status / availability</span>
|
|
</article>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="pipeline-card" id="audio">
|
|
<div class="section-heading">
|
|
<div>
|
|
<p class="eyebrow eyebrow--teal">Audio</p>
|
|
<h2>Audio Production</h2>
|
|
</div>
|
|
</div>
|
|
<p class="list-summary">Audio generation queued separately. Uses translated text when available.</p>
|
|
</section>
|
|
</main>
|
|
</div>
|
|
|
|
<div id="toast" class="toast" role="status" aria-live="polite"></div>
|
|
<script src="assets/nav.js" defer></script>
|
|
<script src="assets/api.js" defer></script>
|
|
<script src="assets/workspace-project.js" defer></script>
|
|
</body>
|
|
</html>
|