Refactor web build process and update documentation
- Removed Node.js build artifacts from .gitignore and adjusted Makefile to reflect changes in web UI build process, now using server-rendered Go templates instead of React. - Updated README to clarify the new web UI architecture and output formats, emphasizing the removal of the Node.js build step. - Added a command to set the number of frames per render task in manager configuration, enhancing user control over rendering settings. - Improved Gitea workflow by removing unnecessary npm install step, streamlining the CI process.
This commit is contained in:
49
web/templates/admin.html
Normal file
49
web/templates/admin.html
Normal file
@@ -0,0 +1,49 @@
|
||||
{{ define "page_admin" }}
|
||||
{{ $view := .Data }}
|
||||
<section class="card">
|
||||
<h1>Admin Panel</h1>
|
||||
<div class="check-row">
|
||||
<label>
|
||||
<input id="registration-enabled" type="checkbox" {{ if index $view "registration_enabled" }}checked{{ end }}>
|
||||
Allow new registrations
|
||||
</label>
|
||||
<button id="save-registration" class="btn">Save</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<h2>Runners</h2>
|
||||
<div id="admin-runners"
|
||||
hx-get="/ui/fragments/admin/runners"
|
||||
hx-trigger="load, every 6s"
|
||||
hx-swap="innerHTML">
|
||||
<p>Loading runners...</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<h2>Users</h2>
|
||||
<div id="admin-users"
|
||||
hx-get="/ui/fragments/admin/users"
|
||||
hx-trigger="load, every 10s"
|
||||
hx-swap="innerHTML">
|
||||
<p>Loading users...</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<div class="section-head">
|
||||
<h2>Runner API Keys</h2>
|
||||
<button id="create-api-key" class="btn">Create API Key</button>
|
||||
</div>
|
||||
<div id="admin-apikeys"
|
||||
hx-get="/ui/fragments/admin/apikeys"
|
||||
hx-trigger="load, every 10s"
|
||||
hx-swap="innerHTML">
|
||||
<p>Loading API keys...</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<p id="admin-message" class="alert notice hidden"></p>
|
||||
<p id="admin-error" class="alert error hidden"></p>
|
||||
{{ end }}
|
||||
48
web/templates/base.html
Normal file
48
web/templates/base.html
Normal file
@@ -0,0 +1,48 @@
|
||||
{{ define "base" }}
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{ .Title }} - JiggaBlend</title>
|
||||
<link rel="stylesheet" href="/assets/style.css">
|
||||
<script src="https://unpkg.com/htmx.org@1.9.12"></script>
|
||||
</head>
|
||||
<body>
|
||||
{{ if .User }}
|
||||
<header class="topbar">
|
||||
<div class="brand">JiggaBlend</div>
|
||||
<nav class="nav">
|
||||
<a href="/jobs" class="{{ if eq .CurrentPath "/jobs" }}active{{ end }}">Jobs</a>
|
||||
<a href="/jobs/new" class="{{ if eq .CurrentPath "/jobs/new" }}active{{ end }}">Submit</a>
|
||||
{{ if .User.IsAdmin }}<a href="/admin" class="{{ if eq .CurrentPath "/admin" }}active{{ end }}">Admin</a>{{ end }}
|
||||
</nav>
|
||||
<div class="account">
|
||||
<span>{{ .User.Name }}</span>
|
||||
<form method="post" action="/logout">
|
||||
<button type="submit" class="btn subtle">Logout</button>
|
||||
</form>
|
||||
</div>
|
||||
</header>
|
||||
{{ end }}
|
||||
|
||||
<main class="container">
|
||||
{{ if .Error }}<div class="alert error">{{ .Error }}</div>{{ end }}
|
||||
{{ if .Notice }}<div class="alert notice">{{ .Notice }}</div>{{ end }}
|
||||
{{ if eq .ContentTemplate "page_login" }}
|
||||
{{ template "page_login" . }}
|
||||
{{ else if eq .ContentTemplate "page_jobs" }}
|
||||
{{ template "page_jobs" . }}
|
||||
{{ else if eq .ContentTemplate "page_jobs_new" }}
|
||||
{{ template "page_jobs_new" . }}
|
||||
{{ else if eq .ContentTemplate "page_job_show" }}
|
||||
{{ template "page_job_show" . }}
|
||||
{{ else if eq .ContentTemplate "page_admin" }}
|
||||
{{ template "page_admin" . }}
|
||||
{{ end }}
|
||||
</main>
|
||||
|
||||
{{ if .PageScript }}<script src="{{ .PageScript }}"></script>{{ end }}
|
||||
</body>
|
||||
</html>
|
||||
{{ end }}
|
||||
60
web/templates/job_new.html
Normal file
60
web/templates/job_new.html
Normal file
@@ -0,0 +1,60 @@
|
||||
{{ define "page_jobs_new" }}
|
||||
<section id="job-upload-section" class="card">
|
||||
<h1>Create Render Job</h1>
|
||||
<div class="stepper">
|
||||
<div id="step-upload" class="step active">1. Upload & Analyze</div>
|
||||
<div id="step-config" class="step">2. Review & Submit</div>
|
||||
</div>
|
||||
|
||||
<form id="upload-analyze-form" class="stack">
|
||||
<label>Upload Blend/ZIP
|
||||
<input type="file" id="source-file" name="file" accept=".blend,.zip,application/zip,application/x-zip-compressed" required>
|
||||
</label>
|
||||
<label id="main-blend-wrapper" class="hidden">Main Blend (for ZIP with multiple .blend files)
|
||||
<select id="main-blend-select"></select>
|
||||
</label>
|
||||
<button type="submit" class="btn primary">Upload and Analyze</button>
|
||||
</form>
|
||||
|
||||
<div id="upload-status" class="stack hidden"></div>
|
||||
<p id="job-create-error" class="alert error hidden"></p>
|
||||
</section>
|
||||
|
||||
<section id="job-config-section" class="card hidden">
|
||||
<h2>Review Render Settings</h2>
|
||||
<p class="muted">Values are prefilled from extracted metadata; adjust before submission.</p>
|
||||
<div id="metadata-preview" class="stack"></div>
|
||||
|
||||
<form id="job-config-form" class="stack">
|
||||
<label>Job Name
|
||||
<input type="text" id="job-name" name="name" required>
|
||||
</label>
|
||||
<div class="grid-2">
|
||||
<label>Frame Start
|
||||
<input type="number" id="frame-start" name="frame_start" min="0" required>
|
||||
</label>
|
||||
<label>Frame End
|
||||
<input type="number" id="frame-end" name="frame_end" min="0" required>
|
||||
</label>
|
||||
</div>
|
||||
<label>Output Format
|
||||
<select name="output_format" id="output-format">
|
||||
<option value="EXR">EXR</option>
|
||||
<option value="EXR_264_MP4">EXR + H264 MP4</option>
|
||||
<option value="EXR_AV1_MP4">EXR + AV1 MP4</option>
|
||||
<option value="EXR_VP9_WEBM">EXR + VP9 WEBM</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>Blender Version (optional)
|
||||
<select name="blender_version" id="blender-version">
|
||||
<option value="">Auto-detect from file</option>
|
||||
</select>
|
||||
</label>
|
||||
<div class="check-row">
|
||||
<label><input type="checkbox" id="unhide-objects" name="unhide_objects"> Unhide objects/collections</label>
|
||||
<label><input type="checkbox" id="enable-execution" name="enable_execution"> Enable auto-execution in Blender</label>
|
||||
</div>
|
||||
<button type="submit" class="btn primary">Create Job</button>
|
||||
</form>
|
||||
</section>
|
||||
{{ end }}
|
||||
97
web/templates/job_show.html
Normal file
97
web/templates/job_show.html
Normal file
@@ -0,0 +1,97 @@
|
||||
{{ define "page_job_show" }}
|
||||
{{ $view := .Data }}
|
||||
{{ $job := index $view "job" }}
|
||||
<section class="card">
|
||||
<div class="section-head">
|
||||
<h1>Job #{{ $job.ID }} - {{ $job.Name }}</h1>
|
||||
<a href="/jobs" class="btn subtle">Back</a>
|
||||
</div>
|
||||
<p>Status: <span id="job-status-badge" class="status {{ statusClass $job.Status }}">{{ $job.Status }}</span></p>
|
||||
<p>Progress: <span id="job-progress-text">{{ progressInt $job.Progress }}%</span></p>
|
||||
<div class="progress">
|
||||
<div class="progress-fill" data-progress="{{ progressInt $job.Progress }}"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
{{ if $job.FrameStart }}<span>Frames: {{ derefInt $job.FrameStart }}{{ if $job.FrameEnd }}-{{ derefInt $job.FrameEnd }}{{ end }}</span>{{ end }}
|
||||
{{ if $job.OutputFormat }}<span>Format: {{ derefString $job.OutputFormat }}</span>{{ end }}
|
||||
<span>Created: {{ formatTime $job.CreatedAt }}</span>
|
||||
</div>
|
||||
<div class="section-head">
|
||||
<button id="cancel-job-btn" class="btn{{ if not (or (eq $job.Status "pending") (eq $job.Status "running")) }} hidden{{ end }}" data-cancel-job="{{ $job.ID }}">Cancel Job</button>
|
||||
<button id="delete-job-btn" class="btn danger{{ if not (or (eq $job.Status "completed") (eq $job.Status "failed") (eq $job.Status "cancelled")) }} hidden{{ end }}" data-delete-job="{{ $job.ID }}">Delete Job</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<div class="section-head">
|
||||
<h2>Tasks</h2>
|
||||
<button id="tasks-refresh" class="btn tiny">Refresh tasks</button>
|
||||
</div>
|
||||
<div id="tasks-fragment"
|
||||
hx-get="/ui/fragments/jobs/{{ $job.ID }}/tasks"
|
||||
hx-trigger="load"
|
||||
hx-swap="innerHTML">
|
||||
<p>Loading tasks...</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<div class="section-head">
|
||||
<h2>Files</h2>
|
||||
<div class="row">
|
||||
<a href="/api/jobs/{{ $job.ID }}/files/exr-zip" class="btn tiny">Download all EXR (.zip)</a>
|
||||
<button id="files-refresh" class="btn tiny">Refresh files</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="files-fragment"
|
||||
hx-get="/ui/fragments/jobs/{{ $job.ID }}/files"
|
||||
hx-trigger="load"
|
||||
hx-swap="innerHTML">
|
||||
<p>Loading files...</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div id="exr-preview-modal" class="modal hidden" role="dialog" aria-modal="true" aria-labelledby="exr-preview-title">
|
||||
<div class="modal-backdrop" data-modal-close></div>
|
||||
<div class="modal-content">
|
||||
<div class="section-head">
|
||||
<h3 id="exr-preview-title">EXR Preview</h3>
|
||||
<button type="button" id="exr-preview-close" class="btn tiny subtle" data-modal-close>Close</button>
|
||||
</div>
|
||||
<p id="exr-preview-name" class="muted"></p>
|
||||
<div class="modal-body">
|
||||
<img id="exr-preview-image" alt="EXR preview" class="preview-image hidden">
|
||||
<p id="exr-preview-loading" class="muted">Loading preview...</p>
|
||||
<p id="exr-preview-error" class="alert error hidden"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="card">
|
||||
<div class="section-head">
|
||||
<h2>Task Logs</h2>
|
||||
<span id="task-log-status" class="muted">Select a task to view logs.</span>
|
||||
</div>
|
||||
<div class="log-controls">
|
||||
<label>Task
|
||||
<select id="task-log-task-id">
|
||||
<option value="">Choose a task...</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>Level
|
||||
<select id="task-log-level-filter">
|
||||
<option value="">All</option>
|
||||
<option value="INFO">INFO</option>
|
||||
<option value="WARN">WARN</option>
|
||||
<option value="ERROR">ERROR</option>
|
||||
<option value="DEBUG">DEBUG</option>
|
||||
</select>
|
||||
</label>
|
||||
<label class="log-toggle"><input id="task-log-auto-refresh" type="checkbox" checked> Auto refresh</label>
|
||||
<label class="log-toggle"><input id="task-log-follow" type="checkbox" checked> Follow tail</label>
|
||||
<button id="task-log-refresh" class="btn">Refresh now</button>
|
||||
<button id="task-log-copy" class="btn subtle">Copy logs</button>
|
||||
</div>
|
||||
<div id="task-log-output" class="logs log-lines"></div>
|
||||
</section>
|
||||
{{ end }}
|
||||
16
web/templates/jobs.html
Normal file
16
web/templates/jobs.html
Normal file
@@ -0,0 +1,16 @@
|
||||
{{ define "page_jobs" }}
|
||||
<section class="card">
|
||||
<div class="section-head">
|
||||
<h1>Your Jobs</h1>
|
||||
<a href="/jobs/new" class="btn primary">New Job</a>
|
||||
</div>
|
||||
<div
|
||||
id="jobs-fragment"
|
||||
hx-get="/ui/fragments/jobs"
|
||||
hx-trigger="load, every 5s"
|
||||
hx-swap="innerHTML"
|
||||
>
|
||||
<p>Loading jobs...</p>
|
||||
</div>
|
||||
</section>
|
||||
{{ end }}
|
||||
41
web/templates/login.html
Normal file
41
web/templates/login.html
Normal file
@@ -0,0 +1,41 @@
|
||||
{{ define "page_login" }}
|
||||
<section class="card narrow">
|
||||
<h1>Sign in to JiggaBlend</h1>
|
||||
{{ $view := .Data }}
|
||||
{{ if index $view "error" }}
|
||||
<div class="alert error">Login error: {{ index $view "error" }}</div>
|
||||
{{ end }}
|
||||
|
||||
<div class="auth-grid">
|
||||
{{ if index $view "google_enabled" }}
|
||||
<a class="btn" href="/api/auth/google/login">Continue with Google</a>
|
||||
{{ end }}
|
||||
{{ if index $view "discord_enabled" }}
|
||||
<a class="btn" href="/api/auth/discord/login">Continue with Discord</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
{{ if index $view "local_enabled" }}
|
||||
<div class="split">
|
||||
<form id="login-form" class="stack">
|
||||
<h2>Local Login</h2>
|
||||
<label>Email or Username<input type="text" name="username" required></label>
|
||||
<label>Password<input type="password" name="password" required></label>
|
||||
<button type="submit" class="btn primary">Login</button>
|
||||
</form>
|
||||
|
||||
<form id="register-form" class="stack">
|
||||
<h2>Register</h2>
|
||||
<label>Name<input type="text" name="name" required></label>
|
||||
<label>Email<input type="email" name="email" required></label>
|
||||
<label>Password<input type="password" name="password" minlength="8" required></label>
|
||||
<button type="submit" class="btn">Register</button>
|
||||
</form>
|
||||
</div>
|
||||
{{ else }}
|
||||
<p>Local authentication is disabled.</p>
|
||||
{{ end }}
|
||||
|
||||
<p id="auth-error" class="alert error hidden"></p>
|
||||
</section>
|
||||
{{ end }}
|
||||
36
web/templates/partials/admin_apikeys.html
Normal file
36
web/templates/partials/admin_apikeys.html
Normal file
@@ -0,0 +1,36 @@
|
||||
{{ define "partial_admin_apikeys" }}
|
||||
{{ $keys := index . "keys" }}
|
||||
{{ if not $keys }}
|
||||
<p>No API keys generated yet.</p>
|
||||
{{ else }}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Scope</th>
|
||||
<th>Prefix</th>
|
||||
<th>Active</th>
|
||||
<th>Created</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range $key := $keys }}
|
||||
<tr>
|
||||
<td>{{ $key.ID }}</td>
|
||||
<td>{{ $key.Name }}</td>
|
||||
<td>{{ $key.Scope }}</td>
|
||||
<td>{{ $key.Key }}</td>
|
||||
<td>{{ if $key.IsActive }}yes{{ else }}no{{ end }}</td>
|
||||
<td>{{ formatTime $key.CreatedAt }}</td>
|
||||
<td class="row">
|
||||
<button class="btn tiny" data-revoke-apikey="{{ $key.ID }}">Revoke</button>
|
||||
<button class="btn tiny danger" data-delete-apikey="{{ $key.ID }}">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
35
web/templates/partials/admin_runners.html
Normal file
35
web/templates/partials/admin_runners.html
Normal file
@@ -0,0 +1,35 @@
|
||||
{{ define "partial_admin_runners" }}
|
||||
{{ $runners := index . "runners" }}
|
||||
{{ if not $runners }}
|
||||
<p>No runners registered.</p>
|
||||
{{ else }}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Host</th>
|
||||
<th>Status</th>
|
||||
<th>Priority</th>
|
||||
<th>Heartbeat</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range $runner := $runners }}
|
||||
<tr>
|
||||
<td>{{ $runner.ID }}</td>
|
||||
<td>{{ $runner.Name }}</td>
|
||||
<td>{{ $runner.Hostname }}</td>
|
||||
<td><span class="status {{ statusClass $runner.Status }}">{{ $runner.Status }}</span></td>
|
||||
<td>{{ $runner.Priority }}</td>
|
||||
<td>{{ formatTime $runner.LastHeartbeat }}</td>
|
||||
<td class="row">
|
||||
<button class="btn tiny danger" data-delete-runner="{{ $runner.ID }}">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
44
web/templates/partials/admin_users.html
Normal file
44
web/templates/partials/admin_users.html
Normal file
@@ -0,0 +1,44 @@
|
||||
{{ define "partial_admin_users" }}
|
||||
{{ $users := index . "users" }}
|
||||
{{ $currentUserID := index . "current_user_id" }}
|
||||
{{ if not $users }}
|
||||
<p>No users found.</p>
|
||||
{{ else }}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Provider</th>
|
||||
<th>Admin</th>
|
||||
<th>Created</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range $user := $users }}
|
||||
<tr>
|
||||
<td>{{ $user.ID }}</td>
|
||||
<td>{{ $user.Name }}</td>
|
||||
<td>{{ $user.Email }}</td>
|
||||
<td>{{ if $user.OAuthProvider }}{{ $user.OAuthProvider }}{{ else }}local{{ end }}</td>
|
||||
<td>{{ if $user.IsAdmin }}yes{{ else }}no{{ end }}</td>
|
||||
<td>{{ formatTime $user.CreatedAt }}</td>
|
||||
<td class="row">
|
||||
{{ if and $user.IsAdmin (eq $user.ID $currentUserID) }}
|
||||
<button class="btn tiny" disabled title="You cannot revoke your own admin status">
|
||||
Revoke Admin
|
||||
</button>
|
||||
{{ else }}
|
||||
<button class="btn tiny" data-set-admin="{{ $user.ID }}" data-admin-value="{{ if $user.IsAdmin }}false{{ else }}true{{ end }}">
|
||||
{{ if $user.IsAdmin }}Revoke Admin{{ else }}Make Admin{{ end }}
|
||||
</button>
|
||||
{{ end }}
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
82
web/templates/partials/job_files.html
Normal file
82
web/templates/partials/job_files.html
Normal file
@@ -0,0 +1,82 @@
|
||||
{{ define "partial_job_files" }}
|
||||
{{ $jobID := index . "job_id" }}
|
||||
{{ $files := index . "files" }}
|
||||
{{ $isAdmin := index . "is_admin" }}
|
||||
{{ $adminInputFiles := index . "admin_input_files" }}
|
||||
{{ if not $files }}
|
||||
<p>No output files found yet.</p>
|
||||
{{ else }}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
{{ if $isAdmin }}<th>Type</th>{{ end }}
|
||||
<th>Size</th>
|
||||
<th>Created</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range $file := $files }}
|
||||
<tr>
|
||||
<td>{{ $file.ID }}</td>
|
||||
<td>{{ $file.FileName }}</td>
|
||||
{{ if $isAdmin }}<td>{{ $file.FileType }}</td>{{ end }}
|
||||
<td>{{ $file.FileSize }}</td>
|
||||
<td>{{ formatTime $file.CreatedAt }}</td>
|
||||
<td class="row">
|
||||
<a class="btn tiny" href="/api/jobs/{{ $jobID }}/files/{{ $file.ID }}/download">Download</a>
|
||||
{{ if hasSuffixFold $file.FileName ".exr" }}
|
||||
<button
|
||||
type="button"
|
||||
class="btn tiny"
|
||||
data-exr-preview-url="/api/jobs/{{ $jobID }}/files/{{ $file.ID }}/preview-exr"
|
||||
data-exr-preview-name="{{ $file.FileName }}"
|
||||
>
|
||||
Preview
|
||||
</button>
|
||||
{{ end }}
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
{{ end }}
|
||||
|
||||
{{ if $isAdmin }}
|
||||
<details class="admin-context">
|
||||
<summary>Admin: context/input files</summary>
|
||||
{{ if not $adminInputFiles }}
|
||||
<p>No context/input files found.</p>
|
||||
{{ else }}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Type</th>
|
||||
<th>Size</th>
|
||||
<th>Created</th>
|
||||
<th>Download</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range $file := $adminInputFiles }}
|
||||
<tr>
|
||||
<td>{{ $file.ID }}</td>
|
||||
<td>{{ $file.FileName }}</td>
|
||||
<td>{{ $file.FileType }}</td>
|
||||
<td>{{ $file.FileSize }}</td>
|
||||
<td>{{ formatTime $file.CreatedAt }}</td>
|
||||
<td>
|
||||
<a class="btn tiny" href="/api/jobs/{{ $jobID }}/files/{{ $file.ID }}/download">Download</a>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
{{ end }}
|
||||
</details>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
37
web/templates/partials/job_tasks.html
Normal file
37
web/templates/partials/job_tasks.html
Normal file
@@ -0,0 +1,37 @@
|
||||
{{ define "partial_job_tasks" }}
|
||||
{{ $tasks := index . "tasks" }}
|
||||
{{ if not $tasks }}
|
||||
<p>No tasks yet.</p>
|
||||
{{ else }}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Type</th>
|
||||
<th>Status</th>
|
||||
<th>Frame(s)</th>
|
||||
<th>Step</th>
|
||||
<th>Retries</th>
|
||||
<th>Error</th>
|
||||
<th>Logs</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range $task := $tasks }}
|
||||
<tr>
|
||||
<td>{{ $task.ID }}</td>
|
||||
<td>{{ $task.TaskType }}</td>
|
||||
<td><span class="status {{ statusClass $task.Status }}">{{ $task.Status }}</span></td>
|
||||
<td>{{ $task.Frame }}{{ if $task.FrameEnd }}-{{ derefInt $task.FrameEnd }}{{ end }}</td>
|
||||
<td>{{ if $task.CurrentStep }}{{ $task.CurrentStep }}{{ else }}-{{ end }}</td>
|
||||
<td>{{ $task.RetryCount }}</td>
|
||||
<td>{{ if $task.Error }}{{ $task.Error }}{{ else }}-{{ end }}</td>
|
||||
<td>
|
||||
<button class="btn tiny" data-view-logs-task-id="{{ $task.ID }}">View logs</button>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
40
web/templates/partials/jobs_table.html
Normal file
40
web/templates/partials/jobs_table.html
Normal file
@@ -0,0 +1,40 @@
|
||||
{{ define "partial_jobs_table" }}
|
||||
{{ $jobs := index . "jobs" }}
|
||||
{{ if not $jobs }}
|
||||
<p>No jobs yet. Submit one to get started.</p>
|
||||
{{ else }}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Status</th>
|
||||
<th>Progress</th>
|
||||
<th>Frames</th>
|
||||
<th>Format</th>
|
||||
<th>Created</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range $job := $jobs }}
|
||||
<tr>
|
||||
<td><a class="job-link" href="/jobs/{{ $job.ID }}">{{ $job.Name }}</a></td>
|
||||
<td><span class="status {{ statusClass $job.Status }}">{{ $job.Status }}</span></td>
|
||||
<td>{{ progressInt $job.Progress }}%</td>
|
||||
<td>{{ if $job.FrameStart }}{{ derefInt $job.FrameStart }}{{ end }}{{ if $job.FrameEnd }}-{{ derefInt $job.FrameEnd }}{{ end }}</td>
|
||||
<td>{{ if $job.OutputFormat }}{{ derefString $job.OutputFormat }}{{ else }}-{{ end }}</td>
|
||||
<td>{{ formatTime $job.CreatedAt }}</td>
|
||||
<td class="row">
|
||||
{{ if or (eq $job.Status "pending") (eq $job.Status "running") }}
|
||||
<button class="btn tiny" data-cancel-job="{{ $job.ID }}">Cancel</button>
|
||||
{{ end }}
|
||||
{{ if or (eq $job.Status "completed") (eq $job.Status "failed") (eq $job.Status "cancelled") }}
|
||||
<button class="btn tiny danger" data-delete-job="{{ $job.ID }}">Delete</button>
|
||||
{{ end }}
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
Reference in New Issue
Block a user