diff --git a/core/http/react-ui/src/pages/Account.jsx b/core/http/react-ui/src/pages/Account.jsx index 8f9f3d028..84d48c578 100644 --- a/core/http/react-ui/src/pages/Account.jsx +++ b/core/http/react-ui/src/pages/Account.jsx @@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next' import { useAuth } from '../context/AuthContext' import { apiKeysApi, profileApi } from '../utils/api' import LoadingSpinner from '../components/LoadingSpinner' +import PageHeader from '../components/PageHeader' import SettingRow from '../components/SettingRow' import ConfirmDialog from '../components/ConfirmDialog' import './auth.css' @@ -452,10 +453,7 @@ export default function Account() { return (
{/* Header */} -
-

{t('account.title')}

-

{t('account.subtitle')}

-
+ {/* Tab bar */}
diff --git a/core/http/react-ui/src/pages/AgentCreate.jsx b/core/http/react-ui/src/pages/AgentCreate.jsx index b7b79dd22..825a590ca 100644 --- a/core/http/react-ui/src/pages/AgentCreate.jsx +++ b/core/http/react-ui/src/pages/AgentCreate.jsx @@ -2,6 +2,7 @@ import { useState, useEffect, useMemo } from 'react' import { useParams, useNavigate, useLocation, useOutletContext, useSearchParams } from 'react-router-dom' import { agentsApi, skillsApi } from '../utils/api' import SearchableModelSelect from '../components/SearchableModelSelect' +import PageHeader from '../components/PageHeader' import { CAP_CHAT, CAP_TRANSCRIPT, CAP_TTS } from '../utils/capabilities' import Toggle from '../components/Toggle' import SettingRow from '../components/SettingRow' @@ -930,12 +931,14 @@ export default function AgentCreate() { } `} -
-

{isEdit ? `Edit Agent: ${name}` : importedConfig ? 'Import Agent' : 'Create Agent'}

- -
+ navigate('/app/agents')}> + Back + + } + />
diff --git a/core/http/react-ui/src/pages/AgentJobDetails.jsx b/core/http/react-ui/src/pages/AgentJobDetails.jsx index e4386ce12..52854a4d4 100644 --- a/core/http/react-ui/src/pages/AgentJobDetails.jsx +++ b/core/http/react-ui/src/pages/AgentJobDetails.jsx @@ -2,6 +2,7 @@ import { useState, useEffect, useRef } from 'react' import { useParams, useNavigate, useOutletContext } from 'react-router-dom' import { agentJobsApi } from '../utils/api' import LoadingSpinner from '../components/LoadingSpinner' +import PageHeader from '../components/PageHeader' const traceColors = { reasoning: { bg: 'rgba(99,102,241,0.1)', border: 'rgba(99,102,241,0.3)', icon: 'fa-brain', color: 'var(--color-primary)' }, @@ -178,22 +179,22 @@ export default function AgentJobDetails() { return (
-
-
-

Job Details

-

Live status and reasoning traces

-
-
- {(job.status === 'running' || job.status === 'pending') && ( - + )} + - )} - -
-
+
+ } + /> {/* Status Card */}
diff --git a/core/http/react-ui/src/pages/AgentJobs.jsx b/core/http/react-ui/src/pages/AgentJobs.jsx index 8b9d9b3eb..907f5e81d 100644 --- a/core/http/react-ui/src/pages/AgentJobs.jsx +++ b/core/http/react-ui/src/pages/AgentJobs.jsx @@ -6,6 +6,7 @@ import { useModels } from '../hooks/useModels' import { useAuth } from '../context/AuthContext' import { useUserMap } from '../hooks/useUserMap' import LoadingSpinner from '../components/LoadingSpinner' +import PageHeader from '../components/PageHeader' import { fileToBase64 } from '../utils/api' import Modal from '../components/Modal' import UserGroupSection from '../components/UserGroupSection' @@ -216,10 +217,7 @@ export default function AgentJobs() { if (!loading && models.length === 0) { return (
-
-

Agent Jobs

-

Manage agent tasks and automated workflows

-
+

No Models Installed

@@ -243,10 +241,7 @@ export default function AgentJobs() { if (!loading && models.length > 0 && !hasMCPModels && tasks.length === 0) { return (
-
-

Agent Jobs

-

Manage agent tasks and automated workflows

-
+

MCP Not Configured

@@ -276,15 +271,15 @@ export default function AgentJobs() { return (
-
-
-

Agent Jobs

-

Manage agent tasks and automated workflows

-
- -
+ navigate('/app/agent-jobs/tasks/new')}> + New Task + + } + />
- - - -
-
+ {name} — Status} + supporting="Agent observables and activity history" + actions={ +
+ + + + +
+ } + /> {/* Status summary */} {status && ( diff --git a/core/http/react-ui/src/pages/AgentTaskDetails.jsx b/core/http/react-ui/src/pages/AgentTaskDetails.jsx index 722c8c3a1..c07ddfd6f 100644 --- a/core/http/react-ui/src/pages/AgentTaskDetails.jsx +++ b/core/http/react-ui/src/pages/AgentTaskDetails.jsx @@ -3,6 +3,7 @@ import { useParams, useNavigate, useOutletContext, useLocation } from 'react-rou import { agentJobsApi } from '../utils/api' import { basePath } from '../utils/basePath' import ModelSelector from '../components/ModelSelector' +import PageHeader from '../components/PageHeader' import { CAP_CHAT } from '../utils/capabilities' import LoadingSpinner from '../components/LoadingSpinner' @@ -165,20 +166,20 @@ export default function AgentTaskDetails() { if (!isNew && !isEdit) { return (
-
-
-

{task.name || 'Task Details'}

- {task.description &&

{task.description}

} -
-
- - -
-
+ + + +
+ } + /> {/* Task Info */}
@@ -307,12 +308,14 @@ export default function AgentTaskDetails() { // Edit/Create form return (
-
-

{isNew ? 'Create Task' : 'Edit Task'}

- -
+ navigate('/app/agent-jobs')}> + Back + + } + /> {/* Basic Info */} diff --git a/core/http/react-ui/src/pages/Agents.jsx b/core/http/react-ui/src/pages/Agents.jsx index 0070f1917..95bbc9afa 100644 --- a/core/http/react-ui/src/pages/Agents.jsx +++ b/core/http/react-ui/src/pages/Agents.jsx @@ -5,6 +5,7 @@ import { agentsApi } from '../utils/api' import { useAuth } from '../context/AuthContext' import { useUserMap } from '../hooks/useUserMap' import UserGroupSection from '../components/UserGroupSection' +import PageHeader from '../components/PageHeader' import ConfirmDialog from '../components/ConfirmDialog' export default function Agents() { @@ -181,26 +182,26 @@ export default function Agents() { } `} -
-
-

{t('title')}

-

{t('subtitle')}

-
-
- {agentHubURL && ( - - {t('actions.agentHub')} - - )} - - -
-
+ + {agentHubURL && ( + + {t('actions.agentHub')} + + )} + + +
+ } + /> {loading ? (
diff --git a/core/http/react-ui/src/pages/AudioTransform.jsx b/core/http/react-ui/src/pages/AudioTransform.jsx index 98526751d..fca38329e 100644 --- a/core/http/react-ui/src/pages/AudioTransform.jsx +++ b/core/http/react-ui/src/pages/AudioTransform.jsx @@ -1,6 +1,7 @@ import { useState, useEffect, useRef } from 'react' import { useParams, useOutletContext } from 'react-router-dom' import ModelSelector from '../components/ModelSelector' +import PageHeader from '../components/PageHeader' import { CAP_AUDIO_TRANSFORM } from '../utils/capabilities' import LoadingSpinner from '../components/LoadingSpinner' import ErrorWithTraceLink from '../components/ErrorWithTraceLink' @@ -166,9 +167,7 @@ export default function AudioTransform() { return (
-
-

Audio Transform

-
+ Audio Transform} />
diff --git a/core/http/react-ui/src/pages/BackendLogs.jsx b/core/http/react-ui/src/pages/BackendLogs.jsx index 3f5216dbc..1f7c2fed1 100644 --- a/core/http/react-ui/src/pages/BackendLogs.jsx +++ b/core/http/react-ui/src/pages/BackendLogs.jsx @@ -4,6 +4,7 @@ import { backendLogsApi, nodesApi } from '../utils/api' import { formatTimestamp } from '../utils/format' import { apiUrl } from '../utils/basePath' import LoadingSpinner from '../components/LoadingSpinner' +import PageHeader from '../components/PageHeader' import { useDistributedMode } from '../hooks/useDistributedMode' function wsUrl(path) { @@ -151,15 +152,10 @@ function BackendLogsDetail({ modelId }) { return (
-
-
-

- - {modelId} -

-

Backend process output

-
-
+ {modelId}} + supporting="Backend process output" + /> {/* Toolbar */}
@@ -361,17 +357,10 @@ function DistributedBackendLogsResolver({ modelId, fromTimestamp }) { // Multiple workers host this model — let the operator pick. return (
-
-
-

- - {modelId} -

-

- Hosted on {hits.length} workers — pick one to view its logs. -

-
-
+ {modelId}} + supporting={`Hosted on ${hits.length} workers — pick one to view its logs.`} + />
{hits.map(({ node, model }) => ( -
-

{t('backends.title')}

-

{t('backends.subtitle')}

-
+
@@ -378,7 +378,8 @@ export default function Backends() { Docs
-
+ } + /> {/* Upgrade Banner */} {Object.keys(upgrades).length > 0 && ( diff --git a/core/http/react-ui/src/pages/CollectionDetails.jsx b/core/http/react-ui/src/pages/CollectionDetails.jsx index c3b5957de..49ddf647a 100644 --- a/core/http/react-ui/src/pages/CollectionDetails.jsx +++ b/core/http/react-ui/src/pages/CollectionDetails.jsx @@ -2,6 +2,7 @@ import { useState, useEffect, useCallback } from 'react' import { useParams, useOutletContext, useSearchParams } from 'react-router-dom' import { agentCollectionsApi } from '../utils/api' import ConfirmDialog from '../components/ConfirmDialog' +import PageHeader from '../components/PageHeader' export default function CollectionDetails() { const { name } = useParams() @@ -292,10 +293,7 @@ export default function CollectionDetails() { } `} -
-

{name}

-

Collection details and management

-
+
- -
-
+ Fine-Tuning Experimental} + supporting="Create and manage fine-tuning jobs" + actions={ +
+ + +
+ } + /> {error && (
diff --git a/core/http/react-ui/src/pages/ImageGen.jsx b/core/http/react-ui/src/pages/ImageGen.jsx index 0ac838321..755a7bdc2 100644 --- a/core/http/react-ui/src/pages/ImageGen.jsx +++ b/core/http/react-ui/src/pages/ImageGen.jsx @@ -2,6 +2,7 @@ import { useState, useRef } from 'react' import { useParams, useOutletContext } from 'react-router-dom' import { useTranslation } from 'react-i18next' import ModelSelector from '../components/ModelSelector' +import PageHeader from '../components/PageHeader' import { CAP_IMAGE } from '../utils/capabilities' import LoadingSpinner from '../components/LoadingSpinner' import ErrorWithTraceLink from '../components/ErrorWithTraceLink' @@ -84,9 +85,7 @@ export default function ImageGen() { return (
-
-

{t('image.title')}

-
+ {t('image.title')}} />
diff --git a/core/http/react-ui/src/pages/ImportModel.jsx b/core/http/react-ui/src/pages/ImportModel.jsx index de2db9f60..6ba47ffe8 100644 --- a/core/http/react-ui/src/pages/ImportModel.jsx +++ b/core/http/react-ui/src/pages/ImportModel.jsx @@ -3,6 +3,7 @@ import { useNavigate, useOutletContext } from 'react-router-dom' import { useTranslation } from 'react-i18next' import { modelsApi, backendsApi } from '../utils/api' import LoadingSpinner from '../components/LoadingSpinner' +import PageHeader from '../components/PageHeader' import CodeEditor from '../components/CodeEditor' import SearchableSelect from '../components/SearchableSelect' import AmbiguityAlert from '../components/AmbiguityAlert' @@ -798,24 +799,24 @@ export default function ImportModel() { return (
-
-
-

{t('title')}

-

{subtitle}

-
-
- - {isPowerYaml ? ( -