frontend: Add more details to the jobs/[job_id] page

This commit is contained in:
wilson 2026-03-27 09:46:26 +00:00
parent 746aa5f382
commit c7c01c0143
7 changed files with 120 additions and 15 deletions

View file

@ -1,4 +1,4 @@
// This file is auto-generated by @hey-api/openapi-ts // This file is auto-generated by @hey-api/openapi-ts
export { analyzePosApiPosPost, createGenerationJobApiGeneratePost, getJobApiJobsJobIdGet, getJobsApiJobsGet, getMediaFileMediaFilenameGet, healthHealthGet, loginAuthLoginPost, type Options, regenerateAudioApiJobsJobIdRegenerateAudioPost, registerAuthRegisterPost, translateTextApiTranslateGet } from './sdk.gen'; export { analyzePosApiPosPost, createGenerationJobApiGeneratePost, getArticlesBffArticlesGet, getJobApiJobsJobIdGet, getJobsApiJobsGet, getMediaFileMediaFilenameGet, healthHealthGet, loginAuthLoginPost, type Options, regenerateAudioApiJobsJobIdRegenerateAudioPost, registerAuthRegisterPost, translateTextApiTranslateGet } from './sdk.gen';
export type { AnalyzePosApiPosPostData, AnalyzePosApiPosPostError, AnalyzePosApiPosPostErrors, AnalyzePosApiPosPostResponse, AnalyzePosApiPosPostResponses, ClientOptions, CreateGenerationJobApiGeneratePostData, CreateGenerationJobApiGeneratePostError, CreateGenerationJobApiGeneratePostErrors, CreateGenerationJobApiGeneratePostResponse, CreateGenerationJobApiGeneratePostResponses, GenerationRequest, GenerationResponse, GetJobApiJobsJobIdGetData, GetJobApiJobsJobIdGetError, GetJobApiJobsJobIdGetErrors, GetJobApiJobsJobIdGetResponse, GetJobApiJobsJobIdGetResponses, GetJobsApiJobsGetData, GetJobsApiJobsGetResponse, GetJobsApiJobsGetResponses, GetMediaFileMediaFilenameGetData, GetMediaFileMediaFilenameGetError, GetMediaFileMediaFilenameGetErrors, GetMediaFileMediaFilenameGetResponses, HealthHealthGetData, HealthHealthGetResponse, HealthHealthGetResponses, HttpValidationError, JobListResponse, JobResponse, JobSummary, LoginAuthLoginPostData, LoginAuthLoginPostError, LoginAuthLoginPostErrors, LoginAuthLoginPostResponse, LoginAuthLoginPostResponses, LoginRequest, PosRequest, PosResponse, RegenerateAudioApiJobsJobIdRegenerateAudioPostData, RegenerateAudioApiJobsJobIdRegenerateAudioPostError, RegenerateAudioApiJobsJobIdRegenerateAudioPostErrors, RegenerateAudioApiJobsJobIdRegenerateAudioPostResponse, RegenerateAudioApiJobsJobIdRegenerateAudioPostResponses, RegisterAuthRegisterPostData, RegisterAuthRegisterPostError, RegisterAuthRegisterPostErrors, RegisterAuthRegisterPostResponses, RegisterRequest, TokenInfo, TokenResponse, TranslateTextApiTranslateGetData, TranslateTextApiTranslateGetError, TranslateTextApiTranslateGetErrors, TranslateTextApiTranslateGetResponse, TranslateTextApiTranslateGetResponses, TranslationResponse, ValidationError } from './types.gen'; export type { AnalyzePosApiPosPostData, AnalyzePosApiPosPostError, AnalyzePosApiPosPostErrors, AnalyzePosApiPosPostResponse, AnalyzePosApiPosPostResponses, ArticleResponse, ArticlesResponse, ClientOptions, CreateGenerationJobApiGeneratePostData, CreateGenerationJobApiGeneratePostError, CreateGenerationJobApiGeneratePostErrors, CreateGenerationJobApiGeneratePostResponse, CreateGenerationJobApiGeneratePostResponses, GenerationRequest, GenerationResponse, GetArticlesBffArticlesGetData, GetArticlesBffArticlesGetResponse, GetArticlesBffArticlesGetResponses, GetJobApiJobsJobIdGetData, GetJobApiJobsJobIdGetError, GetJobApiJobsJobIdGetErrors, GetJobApiJobsJobIdGetResponse, GetJobApiJobsJobIdGetResponses, GetJobsApiJobsGetData, GetJobsApiJobsGetResponse, GetJobsApiJobsGetResponses, GetMediaFileMediaFilenameGetData, GetMediaFileMediaFilenameGetError, GetMediaFileMediaFilenameGetErrors, GetMediaFileMediaFilenameGetResponses, HealthHealthGetData, HealthHealthGetResponse, HealthHealthGetResponses, HttpValidationError, JobListResponse, JobResponse, JobSummary, LoginAuthLoginPostData, LoginAuthLoginPostError, LoginAuthLoginPostErrors, LoginAuthLoginPostResponse, LoginAuthLoginPostResponses, LoginRequest, PosRequest, PosResponse, RegenerateAudioApiJobsJobIdRegenerateAudioPostData, RegenerateAudioApiJobsJobIdRegenerateAudioPostError, RegenerateAudioApiJobsJobIdRegenerateAudioPostErrors, RegenerateAudioApiJobsJobIdRegenerateAudioPostResponse, RegenerateAudioApiJobsJobIdRegenerateAudioPostResponses, RegisterAuthRegisterPostData, RegisterAuthRegisterPostError, RegisterAuthRegisterPostErrors, RegisterAuthRegisterPostResponses, RegisterRequest, TokenInfo, TokenResponse, TranslateTextApiTranslateGetData, TranslateTextApiTranslateGetError, TranslateTextApiTranslateGetErrors, TranslateTextApiTranslateGetResponse, TranslateTextApiTranslateGetResponses, TranslationResponse, ValidationError } from './types.gen';

View file

@ -2,7 +2,7 @@
import type { Client, Options as Options2, TDataShape } from './client'; import type { Client, Options as Options2, TDataShape } from './client';
import { client } from './client.gen'; import { client } from './client.gen';
import type { AnalyzePosApiPosPostData, AnalyzePosApiPosPostErrors, AnalyzePosApiPosPostResponses, CreateGenerationJobApiGeneratePostData, CreateGenerationJobApiGeneratePostErrors, CreateGenerationJobApiGeneratePostResponses, GetJobApiJobsJobIdGetData, GetJobApiJobsJobIdGetErrors, GetJobApiJobsJobIdGetResponses, GetJobsApiJobsGetData, GetJobsApiJobsGetResponses, GetMediaFileMediaFilenameGetData, GetMediaFileMediaFilenameGetErrors, GetMediaFileMediaFilenameGetResponses, HealthHealthGetData, HealthHealthGetResponses, LoginAuthLoginPostData, LoginAuthLoginPostErrors, LoginAuthLoginPostResponses, RegenerateAudioApiJobsJobIdRegenerateAudioPostData, RegenerateAudioApiJobsJobIdRegenerateAudioPostErrors, RegenerateAudioApiJobsJobIdRegenerateAudioPostResponses, RegisterAuthRegisterPostData, RegisterAuthRegisterPostErrors, RegisterAuthRegisterPostResponses, TranslateTextApiTranslateGetData, TranslateTextApiTranslateGetErrors, TranslateTextApiTranslateGetResponses } from './types.gen'; import type { AnalyzePosApiPosPostData, AnalyzePosApiPosPostErrors, AnalyzePosApiPosPostResponses, CreateGenerationJobApiGeneratePostData, CreateGenerationJobApiGeneratePostErrors, CreateGenerationJobApiGeneratePostResponses, GetArticlesBffArticlesGetData, GetArticlesBffArticlesGetResponses, GetJobApiJobsJobIdGetData, GetJobApiJobsJobIdGetErrors, GetJobApiJobsJobIdGetResponses, GetJobsApiJobsGetData, GetJobsApiJobsGetResponses, GetMediaFileMediaFilenameGetData, GetMediaFileMediaFilenameGetErrors, GetMediaFileMediaFilenameGetResponses, HealthHealthGetData, HealthHealthGetResponses, LoginAuthLoginPostData, LoginAuthLoginPostErrors, LoginAuthLoginPostResponses, RegenerateAudioApiJobsJobIdRegenerateAudioPostData, RegenerateAudioApiJobsJobIdRegenerateAudioPostErrors, RegenerateAudioApiJobsJobIdRegenerateAudioPostResponses, RegisterAuthRegisterPostData, RegisterAuthRegisterPostErrors, RegisterAuthRegisterPostResponses, TranslateTextApiTranslateGetData, TranslateTextApiTranslateGetErrors, TranslateTextApiTranslateGetResponses } from './types.gen';
export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = Options2<TData, ThrowOnError> & { export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = Options2<TData, ThrowOnError> & {
/** /**
@ -80,6 +80,11 @@ export const regenerateAudioApiJobsJobIdRegenerateAudioPost = <ThrowOnError exte
...options ...options
}); });
/**
* Get Articles
*/
export const getArticlesBffArticlesGet = <ThrowOnError extends boolean = false>(options?: Options<GetArticlesBffArticlesGetData, ThrowOnError>) => (options?.client ?? client).get<GetArticlesBffArticlesGetResponses, unknown, ThrowOnError>({ url: '/bff/articles', ...options });
/** /**
* Register * Register
*/ */
@ -107,11 +112,7 @@ export const loginAuthLoginPost = <ThrowOnError extends boolean = false>(options
/** /**
* Get Media File * Get Media File
*/ */
export const getMediaFileMediaFilenameGet = <ThrowOnError extends boolean = false>(options: Options<GetMediaFileMediaFilenameGetData, ThrowOnError>) => (options.client ?? client).get<GetMediaFileMediaFilenameGetResponses, GetMediaFileMediaFilenameGetErrors, ThrowOnError>({ export const getMediaFileMediaFilenameGet = <ThrowOnError extends boolean = false>(options: Options<GetMediaFileMediaFilenameGetData, ThrowOnError>) => (options.client ?? client).get<GetMediaFileMediaFilenameGetResponses, GetMediaFileMediaFilenameGetErrors, ThrowOnError>({ url: '/media/{filename}', ...options });
security: [{ scheme: 'bearer', type: 'http' }],
url: '/media/{filename}',
...options
});
/** /**
* Health * Health

View file

@ -4,6 +4,34 @@ export type ClientOptions = {
baseUrl: `${string}://src` | (string & {}); baseUrl: `${string}://src` | (string & {});
}; };
/**
* ArticleResponse
*/
export type ArticleResponse = {
/**
* Target Language
*/
target_language: string;
/**
* Complexity Level
*/
complexity_level: string;
/**
* Input Texts
*/
input_texts: Array<string>;
};
/**
* ArticlesResponse
*/
export type ArticlesResponse = {
/**
* Articles
*/
articles: Array<ArticleResponse>;
};
/** /**
* GenerationRequest * GenerationRequest
*/ */
@ -20,10 +48,6 @@ export type GenerationRequest = {
* Input Texts * Input Texts
*/ */
input_texts: Array<string>; input_texts: Array<string>;
/**
* Topic
*/
topic?: string | null;
/** /**
* Source Language * Source Language
*/ */
@ -100,10 +124,22 @@ export type JobResponse = {
* Generated Text * Generated Text
*/ */
generated_text?: string | null; generated_text?: string | null;
/**
* Generated Text Pos
*/
generated_text_pos?: {
[key: string]: unknown;
} | null;
/** /**
* Translated Text * Translated Text
*/ */
translated_text?: string | null; translated_text?: string | null;
/**
* Translated Text Pos
*/
translated_text_pos?: {
[key: string]: unknown;
} | null;
/** /**
* Input Summary * Input Summary
*/ */
@ -112,6 +148,12 @@ export type JobResponse = {
* Audio Url * Audio Url
*/ */
audio_url?: string | null; audio_url?: string | null;
/**
* Audio Transcript
*/
audio_transcript?: {
[key: string]: unknown;
} | null;
/** /**
* Error Message * Error Message
*/ */
@ -134,6 +176,14 @@ export type JobSummary = {
* Created At * Created At
*/ */
created_at: string; created_at: string;
/**
* Completed At
*/
completed_at?: string | null;
/**
* Error Message
*/
error_message?: string | null;
}; };
/** /**
@ -450,6 +500,22 @@ export type RegenerateAudioApiJobsJobIdRegenerateAudioPostResponses = {
export type RegenerateAudioApiJobsJobIdRegenerateAudioPostResponse = RegenerateAudioApiJobsJobIdRegenerateAudioPostResponses[keyof RegenerateAudioApiJobsJobIdRegenerateAudioPostResponses]; export type RegenerateAudioApiJobsJobIdRegenerateAudioPostResponse = RegenerateAudioApiJobsJobIdRegenerateAudioPostResponses[keyof RegenerateAudioApiJobsJobIdRegenerateAudioPostResponses];
export type GetArticlesBffArticlesGetData = {
body?: never;
path?: never;
query?: never;
url: '/bff/articles';
};
export type GetArticlesBffArticlesGetResponses = {
/**
* Successful Response
*/
200: ArticlesResponse;
};
export type GetArticlesBffArticlesGetResponse = GetArticlesBffArticlesGetResponses[keyof GetArticlesBffArticlesGetResponses];
export type RegisterAuthRegisterPostData = { export type RegisterAuthRegisterPostData = {
body: RegisterRequest; body: RegisterRequest;
path?: never; path?: never;

File diff suppressed because one or more lines are too long

View file

@ -11,7 +11,7 @@ export const load: PageServerLoad = async ({ locals }) => {
} }
}); });
const { data, error, response } = await getJobsApiJobsGet({ const { data, error } = await getJobsApiJobsGet({
client client
}); });

View file

@ -5,7 +5,7 @@ import { PUBLIC_API_BASE_URL } from '$env/static/public';
export const load: ServerLoad = async ({ params, locals }) => { export const load: ServerLoad = async ({ params, locals }) => {
const { data, response } = await getJobApiJobsJobIdGet({ const { data, response } = await getJobApiJobsJobIdGet({
headers: { Authorization: `Bearer ${locals.authToken ?? ''}` }, headers: { Authorization: `Bearer ${locals.authToken ?? ''}` },
path: { job_id: params.job_id } path: { job_id: params.job_id as string }
}); });
if (!data || response.status !== 200) { if (!data || response.status !== 200) {

View file

@ -114,6 +114,29 @@
<div class="prose prose-translated">{job.translated_text}</div> <div class="prose prose-translated">{job.translated_text}</div>
</section> </section>
{/if} {/if}
<!-- POS is JSON data about parts-of-speech -->
{#if job.audio_transcript}
<section class="content-section">
<h2 class="section-title">Audio Transcript</h2>
<div class="pos-text">{JSON.stringify(JSON.parse(job.audio_transcript as any), null, 2)}</div>
</section>
{/if}
{#if job.generated_text_pos}
<section class="content-section">
<h2 class="section-title">Generated Text with POS Tags</h2>
<div class="pos-text">{JSON.stringify(job.generated_text_pos, null, 2)}</div>
</section>
{/if}
{#if job.translated_text_pos}
<section class="content-section">
<h2 class="section-title">Translated Text with POS Tags</h2>
<div class="pos-text">{JSON.stringify(job.translated_text_pos, null, 2)}</div>
</section>
{/if}
</div> </div>
<style> <style>
@ -281,6 +304,21 @@
font-style: italic; font-style: italic;
} }
.pos-text {
font-family: var(--font-mono);
font-size: var(--text-body-sm);
line-height: var(--leading-relaxed);
color: var(--color-on-surface);
background-color: var(--color-surface-container-low);
padding: var(--space-4);
border-radius: var(--radius-md);
overflow-x: auto;
overflow-y: scroll;
max-height: 300px;
white-space: pre-wrap;
}
/* --- Audio --- */ /* --- Audio --- */
.audio-player { .audio-player {