Skip to main content

React UI components for visualizing Neuroline pipelines with MUI.

English | Русский

neuroline-ui

Demo GitHub

React components for visualizing Neuroline pipelines with Material-UI.

Installation

yarn add neuroline-ui @mui/material @emotion/react @emotion/styled @mui/icons-material

Note: This package has peer dependencies on React, MUI, and Emotion.

UI language: English-only labels (e.g. Error, Artefact).

Features

  • PipelineViewer - visual representation of pipeline execution flow
  • JobNode - individual job status display with timing information
  • JobDetailsPanel - detailed job information with tabs for artefact, input, options, error
  • StageColumn - stage grouping with parallel job visualization
  • StatusBadge - color-coded status indicators
  • ArtifactView - job artifact display
  • InputView - job input data display with edit button
  • OptionsView - job options display with edit button
  • ErrorView - job error details display
  • TypeScript Support - full type safety
  • Storybook - interactive component documentation

Quick Start

'use client';

import { PipelineViewer, JobDetailsPanel } from 'neuroline-ui';
import type { PipelineDisplayData, JobDisplayInfo } from 'neuroline-ui';
import { useEffect, useState, useCallback } from 'react';

export function PipelineDemo() {
const [pipeline, setPipeline] = useState<PipelineDisplayData | null>(null);
const [selectedJob, setSelectedJob] = useState<JobDisplayInfo | null>(null);

useEffect(() => {
// Fetch pipeline status
fetch('/api/pipeline/status')
.then(res => res.json())
.then(setPipeline);
}, []);

const handleJobClick = useCallback((job: JobDisplayInfo) => {
setSelectedJob(job);
}, []);

return (
<div>
{pipeline && (
<PipelineViewer
pipeline={pipeline}
onJobClick={handleJobClick}
selectedJobName={selectedJob?.name}
/>
)}
{selectedJob && (
<JobDetailsPanel
job={selectedJob}
onInputEditClick={(job) => console.log('Edit input:', job)}
onOptionsEditClick={(job) => console.log('Edit options:', job)}
/>
)}
</div>
);
}

Components

PipelineViewer

Main component for visualizing pipeline execution.

import { PipelineViewer } from 'neuroline-ui';

<PipelineViewer
pipeline={{
pipelineId: 'pl_123',
pipelineType: 'data-processing',
status: 'processing',
stages: [
{
index: 0,
jobs: [
{
name: 'fetch-data',
status: 'done',
startedAt: new Date('2024-01-01T00:00:00Z'),
finishedAt: new Date('2024-01-01T00:00:02Z'),
artifact: { size: 2048 },
},
],
},
{
index: 1,
jobs: [
{
name: 'process-data',
status: 'processing',
startedAt: new Date('2024-01-01T00:00:02Z'),
input: { records: 150 },
options: { batchSize: 50 },
},
],
},
],
}}
onJobClick={(job) => console.log('Job clicked:', job)}
selectedJobName="fetch-data"
/>

Props:

PropTypeDefaultDescription
pipelinePipelineDisplayDataRequiredPipeline data with stages
onJobClick(job: JobDisplayInfo) => void-Click handler for job nodes
selectedJobNamestring-Name of currently selected job

JobDetailsPanel

Panel for displaying detailed job information with tabs.

import { JobDetailsPanel } from 'neuroline-ui';

<JobDetailsPanel
job={{
name: 'process-data',
status: 'done',
startedAt: new Date(),
finishedAt: new Date(),
artifact: { processed: true, count: 150 },
input: { records: 150, format: 'json' },
options: { batchSize: 50, parallel: true },
}}
onInputEditClick={(job) => console.log('Edit input:', job)}
onOptionsEditClick={(job) => console.log('Edit options:', job)}
/>

Props:

PropTypeDefaultDescription
jobJobDisplayInfoRequiredJob to display
onInputEditClick(job: JobDisplayInfo) => void-Edit input callback
onOptionsEditClick(job: JobDisplayInfo) => void-Edit options callback

JobNode

Individual job display component.

import { JobNode } from 'neuroline-ui';

<JobNode
job={{
name: 'fetch-data',
status: 'done',
startedAt: new Date(),
finishedAt: new Date(),
artifact: { size: 2048 },
}}
isSelected={true}
onClick={(job) => console.log('Clicked:', job)}
/>

Props:

PropTypeDefaultDescription
jobJobDisplayInfoRequiredJob data
isSelectedbooleanfalseHighlight as selected
onClick(job: JobDisplayInfo) => void-Click handler

StageColumn

Stage grouping component for parallel jobs.

import { StageColumn } from 'neuroline-ui';

<StageColumn
stage={{
index: 1,
jobs: [
{ name: 'job1', status: 'done' },
{ name: 'job2', status: 'done' },
],
}}
selectedJobName="job1"
onJobClick={(job) => console.log(job)}
/>

StatusBadge

Status indicator with color coding.

import { StatusBadge } from 'neuroline-ui';

<StatusBadge status="processing" size="small" />

Status colors:

  • pending - Gray
  • processing - Cyan (animated)
  • done - Green
  • error - Red

ArtifactView

Display job artifact data.

import { ArtifactView } from 'neuroline-ui';

<ArtifactView artifact={{ processed: true, count: 150 }} />

InputView

Display job input data with optional edit button.

import { InputView } from 'neuroline-ui';

<InputView
input={{ records: 150, format: 'json' }}
onEditClick={() => console.log('Edit input')}
/>

OptionsView

Display job options with optional edit button.

import { OptionsView } from 'neuroline-ui';

<OptionsView
options={{ batchSize: 50, parallel: true }}
onEditClick={() => console.log('Edit options')}
/>

ErrorView

Display job error details (supports error history with retries).

import { ErrorView } from 'neuroline-ui';

<ErrorView errors={[{ message: 'Database connection timeout', stack: 'Error: ...', attempt: 0 }]} />

Types

import type {
PipelineDisplayData,
StageDisplayInfo,
JobDisplayInfo,
JobError,
JobStatus,
PipelineStatus,
SerializableValue,
} from 'neuroline-ui';

JobDisplayInfo

interface JobDisplayInfo {
name: string;
status: 'pending' | 'processing' | 'done' | 'error';
startedAt?: Date;
finishedAt?: Date;
errors: JobError[];
artifact?: SerializableValue;
input?: SerializableValue;
options?: SerializableValue;
}

StageDisplayInfo

interface StageDisplayInfo {
index: number;
jobs: JobDisplayInfo[];
}

PipelineDisplayData

interface PipelineDisplayData {
pipelineId: string;
pipelineType: string;
status: 'processing' | 'done' | 'error';
stages: StageDisplayInfo[];
input?: SerializableValue;
error?: { message: string; jobName?: string };
}

SerializableValue

type SerializableValue = Record<string, unknown> | string | number | boolean | null;

Styling

All components use MUI's sx prop and support theme customization.

Custom Theme

import { ThemeProvider, createTheme } from '@mui/material';
import { PipelineViewer } from 'neuroline-ui';

const theme = createTheme({
palette: {
primary: { main: '#7c4dff' },
success: { main: '#00e676' },
error: { main: '#ff1744' },
info: { main: '#00e5ff' },
},
});

<ThemeProvider theme={theme}>
<PipelineViewer pipeline={pipeline} />
</ThemeProvider>

Storybook

Run Storybook for interactive component documentation:

yarn workspace neuroline-ui storybook

This will start Storybook on http://localhost:6006 with live examples of all components.

Integration Examples

With Next.js App Router

'use client';

import { PipelineViewer, JobDetailsPanel } from 'neuroline-ui';
import type { PipelineDisplayData, JobDisplayInfo } from 'neuroline-ui';
import { Container, Typography } from '@mui/material';
import { useState, useEffect, useCallback } from 'react';

export default function PipelinePage({ params }: { params: { id: string } }) {
const [pipeline, setPipeline] = useState<PipelineDisplayData | null>(null);
const [selectedJob, setSelectedJob] = useState<JobDisplayInfo | null>(null);

useEffect(() => {
const pollStatus = async () => {
const res = await fetch(`/api/pipeline/${params.id}/status`);
const data = await res.json();
setPipeline(data);

if (data.status === 'processing') {
setTimeout(pollStatus, 1000);
}
};

pollStatus();
}, [params.id]);

const handleJobClick = useCallback((job: JobDisplayInfo) => {
setSelectedJob(job);
}, []);

return (
<Container>
<Typography variant="h4" gutterBottom>
Pipeline: {params.id}
</Typography>
{pipeline && (
<PipelineViewer
pipeline={pipeline}
onJobClick={handleJobClick}
selectedJobName={selectedJob?.name}
/>
)}
{selectedJob && <JobDetailsPanel job={selectedJob} />}
</Container>
);
}

Development

Build the package:

yarn workspace neuroline-ui build

Watch mode:

yarn workspace neuroline-ui dev

License

UNLICENSED


neuroline-ui

Demo GitHub

React компоненты для визуализации Neuroline пайплайнов с Material-UI.

Установка

yarn add neuroline-ui @mui/material @emotion/react @emotion/styled @mui/icons-material

Примечание: Этот пакет имеет peer-зависимости от React, MUI и Emotion.

Язык интерфейса: только английский (например, Error, Artefact).

Возможности

  • PipelineViewer - визуальное представление процесса выполнения pipeline
  • JobNode - отображение статуса отдельной job с информацией о времени
  • JobDetailsPanel - детальная информация о job с табами для artefact, input, options, error
  • StageColumn - группировка stage с визуализацией параллельных jobs
  • StatusBadge - цветные индикаторы статуса
  • ArtifactView - отображение артефакта job
  • InputView - отображение входных данных job с кнопкой редактирования
  • OptionsView - отображение опций job с кнопкой редактирования
  • ErrorView - отображение деталей ошибки job
  • TypeScript поддержка - полная типобезопасность
  • Storybook - интерактивная документация компонентов

Быстрый старт

'use client';

import { PipelineViewer, JobDetailsPanel } from 'neuroline-ui';
import type { PipelineDisplayData, JobDisplayInfo } from 'neuroline-ui';
import { useEffect, useState, useCallback } from 'react';

export function PipelineDemo() {
const [pipeline, setPipeline] = useState<PipelineDisplayData | null>(null);
const [selectedJob, setSelectedJob] = useState<JobDisplayInfo | null>(null);

useEffect(() => {
// Получение статуса pipeline
fetch('/api/pipeline/status')
.then(res => res.json())
.then(setPipeline);
}, []);

const handleJobClick = useCallback((job: JobDisplayInfo) => {
setSelectedJob(job);
}, []);

return (
<div>
{pipeline && (
<PipelineViewer
pipeline={pipeline}
onJobClick={handleJobClick}
selectedJobName={selectedJob?.name}
/>
)}
{selectedJob && (
<JobDetailsPanel
job={selectedJob}
onInputEditClick={(job) => console.log('Редактировать input:', job)}
onOptionsEditClick={(job) => console.log('Редактировать options:', job)}
/>
)}
</div>
);
}

Компоненты

PipelineViewer

Основной компонент для визуализации выполнения pipeline.

import { PipelineViewer } from 'neuroline-ui';

<PipelineViewer
pipeline={{
pipelineId: 'pl_123',
pipelineType: 'data-processing',
status: 'processing',
stages: [
{
index: 0,
jobs: [
{
name: 'fetch-data',
status: 'done',
startedAt: new Date('2024-01-01T00:00:00Z'),
finishedAt: new Date('2024-01-01T00:00:02Z'),
artifact: { size: 2048 },
},
],
},
{
index: 1,
jobs: [
{
name: 'process-data',
status: 'processing',
startedAt: new Date('2024-01-01T00:00:02Z'),
input: { records: 150 },
options: { batchSize: 50 },
},
],
},
],
}}
onJobClick={(job) => console.log('Job clicked:', job)}
selectedJobName="fetch-data"
/>

Пропсы:

ПропТипПо умолчаниюОписание
pipelinePipelineDisplayDataОбязательноДанные pipeline со stages
onJobClick(job: JobDisplayInfo) => void-Обработчик клика по job
selectedJobNamestring-Имя выбранной job

JobDetailsPanel

Панель для отображения детальной информации о job с табами.

import { JobDetailsPanel } from 'neuroline-ui';

<JobDetailsPanel
job={{
name: 'process-data',
status: 'done',
startedAt: new Date(),
finishedAt: new Date(),
artifact: { processed: true, count: 150 },
input: { records: 150, format: 'json' },
options: { batchSize: 50, parallel: true },
}}
onInputEditClick={(job) => console.log('Редактировать input:', job)}
onOptionsEditClick={(job) => console.log('Редактировать options:', job)}
/>

Пропсы:

ПропТипПо умолчаниюОписание
jobJobDisplayInfoОбязательноJob для отображения
onInputEditClick(job: JobDisplayInfo) => void-Callback редактирования input
onOptionsEditClick(job: JobDisplayInfo) => void-Callback редактирования options

JobNode

Компонент отображения отдельной job.

import { JobNode } from 'neuroline-ui';

<JobNode
job={{
name: 'fetch-data',
status: 'done',
startedAt: new Date(),
finishedAt: new Date(),
artifact: { size: 2048 },
}}
isSelected={true}
onClick={(job) => console.log('Clicked:', job)}
/>

Пропсы:

ПропТипПо умолчаниюОписание
jobJobDisplayInfoОбязательноДанные job
isSelectedbooleanfalseПодсветить как выбранную
onClick(job: JobDisplayInfo) => void-Обработчик клика

StageColumn

Компонент группировки stage для параллельных jobs.

import { StageColumn } from 'neuroline-ui';

<StageColumn
stage={{
index: 1,
jobs: [
{ name: 'job1', status: 'done' },
{ name: 'job2', status: 'done' },
],
}}
selectedJobName="job1"
onJobClick={(job) => console.log(job)}
/>

StatusBadge

Индикатор статуса с цветовым кодированием.

import { StatusBadge } from 'neuroline-ui';

<StatusBadge status="processing" size="small" />

Цвета статусов:

  • pending - Серый
  • processing - Бирюзовый (анимированный)
  • done - Зелёный
  • error - Красный

ArtifactView

Отображение артефакта job.

import { ArtifactView } from 'neuroline-ui';

<ArtifactView artifact={{ processed: true, count: 150 }} />

InputView

Отображение входных данных job с опциональной кнопкой редактирования.

import { InputView } from 'neuroline-ui';

<InputView
input={{ records: 150, format: 'json' }}
onEditClick={() => console.log('Редактировать input')}
/>

OptionsView

Отображение опций job с опциональной кнопкой редактирования.

import { OptionsView } from 'neuroline-ui';

<OptionsView
options={{ batchSize: 50, parallel: true }}
onEditClick={() => console.log('Редактировать options')}
/>

ErrorView

Отображение деталей ошибок job (включая историю ретраев).

import { ErrorView } from 'neuroline-ui';

<ErrorView errors={[{ message: 'Database connection timeout', stack: 'Error: ...', attempt: 0 }]} />

Типы

import type {
PipelineDisplayData,
StageDisplayInfo,
JobDisplayInfo,
JobError,
JobStatus,
PipelineStatus,
SerializableValue,
} from 'neuroline-ui';

JobDisplayInfo

interface JobDisplayInfo {
name: string;
status: 'pending' | 'processing' | 'done' | 'error';
startedAt?: Date;
finishedAt?: Date;
errors: JobError[];
artifact?: SerializableValue;
input?: SerializableValue;
options?: SerializableValue;
}

StageDisplayInfo

interface StageDisplayInfo {
index: number;
jobs: JobDisplayInfo[];
}

PipelineDisplayData

interface PipelineDisplayData {
pipelineId: string;
pipelineType: string;
status: 'processing' | 'done' | 'error';
stages: StageDisplayInfo[];
input?: SerializableValue;
error?: { message: string; jobName?: string };
}

SerializableValue

type SerializableValue = Record<string, unknown> | string | number | boolean | null;

Стилизация

Все компоненты используют sx проп MUI и поддерживают кастомизацию темы.

Кастомная тема

import { ThemeProvider, createTheme } from '@mui/material';
import { PipelineViewer } from 'neuroline-ui';

const theme = createTheme({
palette: {
primary: { main: '#7c4dff' },
success: { main: '#00e676' },
error: { main: '#ff1744' },
info: { main: '#00e5ff' },
},
});

<ThemeProvider theme={theme}>
<PipelineViewer pipeline={pipeline} />
</ThemeProvider>

Storybook

Запустите Storybook для интерактивной документации:

yarn workspace neuroline-ui storybook

Это запустит Storybook на http://localhost:6006 с живыми примерами всех компонентов.

Примеры интеграции

С Next.js App Router

'use client';

import { PipelineViewer, JobDetailsPanel } from 'neuroline-ui';
import type { PipelineDisplayData, JobDisplayInfo } from 'neuroline-ui';
import { Container, Typography } from '@mui/material';
import { useState, useEffect, useCallback } from 'react';

export default function PipelinePage({ params }: { params: { id: string } }) {
const [pipeline, setPipeline] = useState<PipelineDisplayData | null>(null);
const [selectedJob, setSelectedJob] = useState<JobDisplayInfo | null>(null);

useEffect(() => {
const pollStatus = async () => {
const res = await fetch(`/api/pipeline/${params.id}/status`);
const data = await res.json();
setPipeline(data);

if (data.status === 'processing') {
setTimeout(pollStatus, 1000);
}
};

pollStatus();
}, [params.id]);

const handleJobClick = useCallback((job: JobDisplayInfo) => {
setSelectedJob(job);
}, []);

return (
<Container>
<Typography variant="h4" gutterBottom>
Pipeline: {params.id}
</Typography>
{pipeline && (
<PipelineViewer
pipeline={pipeline}
onJobClick={handleJobClick}
selectedJobName={selectedJob?.name}
/>
)}
{selectedJob && <JobDetailsPanel job={selectedJob} />}
</Container>
);
}

Разработка

Сборка пакета:

yarn workspace neuroline-ui build

Режим watch:

yarn workspace neuroline-ui dev

License

UNLICENSED