From e6ae87ecc1da73cf2060867a67a13227682cb0ea Mon Sep 17 00:00:00 2001 From: Guilhem Date: Wed, 4 Feb 2026 16:44:35 +0000 Subject: [PATCH] job detail header nit (#7786) * do not truncate worker * align button right + breadscrum * remove job arg header * nit * Revert "remove job arg header" This reverts commit b68ee6d2e55c3ecec4622741b1351a41170bb148. * improve mem peak formatting * improve permissioned as layout * Fix job preview spacing inconsistency * nit spacing --- .../components/runs/JobDetailFieldConfig.ts | 35 ++++++++++- .../components/runs/JobDetailHeader.svelte | 48 +++++---------- .../lib/components/runs/JobRunsPreview.svelte | 24 ++++---- frontend/src/lib/utils.ts | 33 +++++++++++ .../(root)/(logged)/run/[...run]/+page.svelte | 59 ++++++++++--------- 5 files changed, 125 insertions(+), 74 deletions(-) diff --git a/frontend/src/lib/components/runs/JobDetailFieldConfig.ts b/frontend/src/lib/components/runs/JobDetailFieldConfig.ts index 1b4d3cc123..5d6793a40e 100644 --- a/frontend/src/lib/components/runs/JobDetailFieldConfig.ts +++ b/frontend/src/lib/components/runs/JobDetailFieldConfig.ts @@ -1,5 +1,6 @@ import type { Job } from '$lib/gen' import { triggerIconMap } from '$lib/components/triggers/utils' +import { formatMemory } from '$lib/utils' import { Calendar, Bot } from 'lucide-svelte' import BarsStaggered from '$lib/components/icons/BarsStaggered.svelte' @@ -22,6 +23,7 @@ export type JobField = | 'created_at' | 'started_at' | 'created_by' + | 'permissioned_as' | 'memory_peak' | 'run_id' | 'trigger_info' @@ -179,10 +181,20 @@ export const fieldConfigs: Record = { getValue: (job) => job.created_by || 'unknown' }, + permissioned_as: { + field: 'permissioned_as', + label: 'Permissioned as', + getValue: (job) => job.permissioned_as || null + }, + memory_peak: { field: 'memory_peak', label: 'Mem peak', - getValue: (job) => (job.mem_peak ? `${(job.mem_peak / 1024).toPrecision(5)}MB` : null) + getValue: (job) => { + if (!job.mem_peak) return null + const formatted = formatMemory(job.mem_peak, true) + return `${formatted.display}|${formatted.tooltip}` + } }, run_id: { @@ -305,6 +317,7 @@ export const categoryFieldPresence: FieldPresenceConfig = { script: { created_at: true, created_by: true, + permissioned_as: false, // Will be conditionally shown worker: true, run_id: true, started_at: true, @@ -326,6 +339,7 @@ export const categoryFieldPresence: FieldPresenceConfig = { created_at: true, started_at: true, created_by: true, + permissioned_as: false, // Will be conditionally shown worker: true, run_id: true, script_path: true, @@ -345,6 +359,7 @@ export const categoryFieldPresence: FieldPresenceConfig = { dependencies: { created_at: true, created_by: true, + permissioned_as: false, // Will be conditionally shown worker: true, run_id: true, started_at: true, @@ -365,6 +380,7 @@ export const categoryFieldPresence: FieldPresenceConfig = { flow_node: { created_at: true, created_by: true, + permissioned_as: false, // Will be conditionally shown worker: true, run_id: true, started_at: true, @@ -385,6 +401,7 @@ export const categoryFieldPresence: FieldPresenceConfig = { ai_agent: { created_at: true, created_by: true, + permissioned_as: false, // Will be conditionally shown worker: true, run_id: true, started_at: true, @@ -405,6 +422,7 @@ export const categoryFieldPresence: FieldPresenceConfig = { system: { created_at: true, created_by: true, + permissioned_as: false, // Will be conditionally shown worker: true, run_id: true, started_at: true, @@ -425,6 +443,7 @@ export const categoryFieldPresence: FieldPresenceConfig = { trigger_job: { created_at: true, created_by: true, + permissioned_as: false, // Will be conditionally shown worker: true, run_id: true, started_at: true, @@ -451,11 +470,16 @@ export function getRelevantFields(job: Job): FieldConfig[] { const category = getJobCategory(job) const fieldsPresence = categoryFieldPresence[category] - // Define the field ordering: created_by, started_at, worker, then others + // Conditionally show permissioned_as field when different from created_by + const shouldShowPermissionedAs = + job.permissioned_as !== `u/${job.created_by}` && job.permissioned_as !== job.created_by + + // Define the field ordering: created_by, permissioned_as, started_at, worker, then others const fieldOrder: JobField[] = [ 'created_at', 'started_at', 'created_by', + 'permissioned_as', 'worker', 'run_id', 'memory_peak', @@ -474,7 +498,12 @@ export function getRelevantFields(job: Job): FieldConfig[] { // Return fields in the specified order if they are present for this category return fieldOrder - .filter((fieldName) => fieldsPresence[fieldName]) + .filter((fieldName) => { + if (fieldName === 'permissioned_as') { + return shouldShowPermissionedAs + } + return fieldsPresence[fieldName] + }) .map((fieldName) => fieldConfigs[fieldName]) .filter((config) => config) // Safety check } diff --git a/frontend/src/lib/components/runs/JobDetailHeader.svelte b/frontend/src/lib/components/runs/JobDetailHeader.svelte index 53a439a1a3..a3f85906b7 100644 --- a/frontend/src/lib/components/runs/JobDetailHeader.svelte +++ b/frontend/src/lib/components/runs/JobDetailHeader.svelte @@ -91,12 +91,13 @@ return truncateRev(fullValue, 8) case 'script_hash': return truncateHash(fullValue.toString()) - case 'worker': - return truncateRev(fullValue, compact ? 8 : 12) case 'parent_job': return truncateRev(fullValue, 6) case 'schedule_path': return truncateRev(fullValue, 20) + case 'memory_peak': + // For memory, only show the display part (before the |) + return fullValue.split('|')[0] || fullValue default: return fullValue } @@ -156,31 +157,6 @@ - {:else if config.field === 'created_by'} -
- {#if job.permissioned_as !== `u/${job.created_by}` && job.permissioned_as != job.created_by} - - {#snippet text()} - {#if (job?.created_by?.length ?? 0) > 30} - Created by: {job.created_by}
- {/if} - But permissioned as {job.permissioned_as} - {/snippet} - - - {displayValue} ({job.permissioned_as}) - -
- {:else} - - {#snippet text()}{job.created_by}{/snippet} - {displayValue} - - {/if} -
{:else if config.field === 'worker'} {#if displayValue === 'no value'} @@ -223,12 +199,20 @@ href={`${base}/runs/?job_kinds=all&worker=${job?.worker}`} class="flex items-center gap-1 text-primary" > - {displayValue} + {displayValue} {/if} + {:else if config.field === 'memory_peak'} + {@const memoryParts = fullValue.split('|')} + {@const displayMem = memoryParts[0] || fullValue} + {@const tooltipMem = memoryParts[1] || fullValue} + + {#snippet text()}{tooltipMem}{/snippet} + {displayMem} + {:else if config.field === 'schedule_path' && job.schedule_path} + @@ -470,36 +470,39 @@ /> {#snippet left()} - {@const isScript = job?.job_kind === 'script'} - {@const runsHref = `/runs/${job?.script_path}${!isScript ? '?jobKind=flow' : ''}`} -
- {#if job && 'deleted' in job && !job?.deleted && ($superadmin || ($userStore?.is_admin ?? false))} - { - job?.id && deleteCompletedJob(job.id) - }, - type: 'delete' - } - ]} - > - {#snippet buttonReplacement()} - - {/if} - {/if} -
+

run/{page.params.run}

{/snippet} {#snippet right()} - {@const stem = job?.job_kind === 'script_hub' ? '/scripts' : `/${job?.job_kind}s`} {@const isScript = job?.job_kind === 'script'} + {@const runsHref = `/runs/${job?.script_path}${!isScript ? '?jobKind=flow' : ''}`} + {#if job && 'deleted' in job && !job?.deleted && ($superadmin || ($userStore?.is_admin ?? false))} + { + job?.id && deleteCompletedJob(job.id) + }, + type: 'delete' + } + ]} + > + {#snippet buttonReplacement()} + + {/if} + {/if} + {@const stem = job?.job_kind === 'script_hub' ? '/scripts' : `/${job?.job_kind}s`} {@const viewHref = `${stem}/get/${isScript ? job?.script_hash : job?.script_path}`} {#if (job?.job_kind == 'flow' || isFlowPreview(job?.job_kind)) && job?.['running'] && job?.parent_job == undefined}