@inf-minds/jobs-ui 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/components/ConnectionStatus.d.ts +33 -0
  2. package/dist/components/ConnectionStatus.js +19 -0
  3. package/dist/components/CreateJobForm.d.ts +34 -0
  4. package/dist/components/CreateJobForm.js +45 -0
  5. package/dist/components/Dashboard.d.ts +56 -0
  6. package/dist/components/Dashboard.js +30 -0
  7. package/dist/components/JobCard.d.ts +30 -0
  8. package/dist/components/JobCard.js +21 -0
  9. package/dist/components/JobEventLog.d.ts +37 -0
  10. package/dist/components/JobEventLog.js +41 -0
  11. package/dist/components/JobFilters.d.ts +36 -0
  12. package/dist/components/JobFilters.js +21 -0
  13. package/dist/components/JobList.d.ts +35 -0
  14. package/dist/components/JobList.js +25 -0
  15. package/dist/components/JobProgress.d.ts +44 -0
  16. package/dist/components/JobProgress.js +35 -0
  17. package/dist/components/JobStatusBadge.d.ts +42 -0
  18. package/dist/components/JobStatusBadge.js +32 -0
  19. package/dist/components/index.d.ts +9 -0
  20. package/dist/components/index.js +11 -0
  21. package/dist/hooks/index.d.ts +4 -0
  22. package/dist/hooks/index.js +6 -0
  23. package/dist/hooks/use-connection.d.ts +34 -0
  24. package/dist/hooks/use-connection.js +66 -0
  25. package/dist/hooks/use-job-list.d.ts +70 -0
  26. package/dist/hooks/use-job-list.js +64 -0
  27. package/dist/hooks/use-job-stream.d.ts +58 -0
  28. package/dist/hooks/use-job-stream.js +73 -0
  29. package/dist/hooks/use-job.d.ts +56 -0
  30. package/dist/hooks/use-job.js +64 -0
  31. package/dist/index.d.ts +4 -0
  32. package/dist/index.js +8 -0
  33. package/dist/store/index.d.ts +2 -0
  34. package/dist/store/index.js +3 -0
  35. package/dist/store/job-stream-store.d.ts +23 -0
  36. package/dist/store/job-stream-store.js +161 -0
  37. package/dist/store/types.d.ts +72 -0
  38. package/dist/store/types.js +3 -0
  39. package/dist/styles/components.css +223 -0
  40. package/dist/styles/index.d.ts +25 -0
  41. package/dist/styles/index.js +27 -0
  42. package/dist/styles/preset.d.ts +19 -0
  43. package/dist/styles/preset.js +52 -0
  44. package/dist/types/index.d.ts +1 -0
  45. package/dist/types/index.js +3 -0
  46. package/dist/types/renderers.d.ts +55 -0
  47. package/dist/types/renderers.js +3 -0
  48. package/package.json +54 -0
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Props for ConnectionStatus component.
3
+ */
4
+ export interface ConnectionStatusProps {
5
+ /** Whether the connection is active */
6
+ connected: boolean;
7
+ /** Error message if connection failed */
8
+ error?: string;
9
+ /** Whether reconnection is in progress */
10
+ reconnecting?: boolean;
11
+ /** Label for connected state */
12
+ connectedLabel?: string;
13
+ /** Label for disconnected state */
14
+ disconnectedLabel?: string;
15
+ /** Custom class name */
16
+ className?: string;
17
+ }
18
+ /**
19
+ * Connection status indicator component.
20
+ *
21
+ * Displays the current connection state with optional error
22
+ * and reconnecting indicators. Uses data attributes for styling.
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * <ConnectionStatus
27
+ * connected={connected}
28
+ * error={error}
29
+ * reconnecting={!connected && !error}
30
+ * />
31
+ * ```
32
+ */
33
+ export declare function ConnectionStatus({ connected, error, reconnecting, connectedLabel, disconnectedLabel, className, }: ConnectionStatusProps): JSX.Element;
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Connection status indicator component.
4
+ *
5
+ * Displays the current connection state with optional error
6
+ * and reconnecting indicators. Uses data attributes for styling.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * <ConnectionStatus
11
+ * connected={connected}
12
+ * error={error}
13
+ * reconnecting={!connected && !error}
14
+ * />
15
+ * ```
16
+ */
17
+ export function ConnectionStatus({ connected, error, reconnecting, connectedLabel = 'Connected', disconnectedLabel = 'Disconnected', className, }) {
18
+ return (_jsxs("div", { "data-connection-status": true, "data-connected": connected, className: className, children: [_jsx("span", { "data-status-text": true, children: connected ? connectedLabel : disconnectedLabel }), !connected && reconnecting && (_jsx("span", { "data-reconnecting": true, children: "Reconnecting..." })), error && _jsx("span", { "data-error": true, children: error })] }));
19
+ }
@@ -0,0 +1,34 @@
1
+ import type { JobRendererRegistry } from '../types/renderers.js';
2
+ /**
3
+ * Props for CreateJobForm component.
4
+ */
5
+ export interface CreateJobFormProps {
6
+ /** Available job types */
7
+ jobTypes: string[];
8
+ /** Registry of renderers for job-specific form fields */
9
+ renderers: JobRendererRegistry;
10
+ /** Callback when form is submitted with valid input */
11
+ onSubmit: (jobType: string, input: unknown) => void;
12
+ /** Whether the form is disabled */
13
+ disabled?: boolean;
14
+ /** Whether submission is in progress */
15
+ loading?: boolean;
16
+ /** Custom class name */
17
+ className?: string;
18
+ }
19
+ /**
20
+ * Form for creating new jobs.
21
+ *
22
+ * Uses the renderer plugin system to display job-type-specific
23
+ * form fields and validation. Uses data attributes for styling.
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * <CreateJobForm
28
+ * jobTypes={['haiku', 'summary']}
29
+ * renderers={renderers}
30
+ * onSubmit={(type, input) => createJob(type, input)}
31
+ * />
32
+ * ```
33
+ */
34
+ export declare function CreateJobForm({ jobTypes, renderers, onSubmit, disabled, loading, className, }: CreateJobFormProps): JSX.Element;
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // ABOUTME: Form component for creating new jobs
3
+ // ABOUTME: Uses renderer plugin system for job-type-specific form fields
4
+ import { useState, useRef } from 'react';
5
+ /**
6
+ * Form for creating new jobs.
7
+ *
8
+ * Uses the renderer plugin system to display job-type-specific
9
+ * form fields and validation. Uses data attributes for styling.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * <CreateJobForm
14
+ * jobTypes={['haiku', 'summary']}
15
+ * renderers={renderers}
16
+ * onSubmit={(type, input) => createJob(type, input)}
17
+ * />
18
+ * ```
19
+ */
20
+ export function CreateJobForm({ jobTypes, renderers, onSubmit, disabled = false, loading = false, className, }) {
21
+ const [selectedType, setSelectedType] = useState(jobTypes[0] || '');
22
+ const [error, setError] = useState(null);
23
+ const formRef = useRef(null);
24
+ const renderer = renderers[selectedType];
25
+ const handleSubmit = (e) => {
26
+ e.preventDefault();
27
+ setError(null);
28
+ if (!renderer || !formRef.current) {
29
+ return;
30
+ }
31
+ const formData = new FormData(formRef.current);
32
+ const result = renderer.validateInput(formData);
33
+ if (result && typeof result === 'object' && 'error' in result) {
34
+ setError(result.error);
35
+ return;
36
+ }
37
+ onSubmit(selectedType, result);
38
+ };
39
+ const handleTypeChange = (e) => {
40
+ setSelectedType(e.target.value);
41
+ setError(null);
42
+ };
43
+ const isDisabled = disabled || loading;
44
+ return (_jsxs("form", { ref: formRef, "data-create-job-form": true, "data-disabled": isDisabled || undefined, className: className, onSubmit: handleSubmit, children: [_jsx("select", { "aria-label": "Job type", value: selectedType, onChange: handleTypeChange, disabled: isDisabled, "data-job-type-select": true, children: jobTypes.map((type) => (_jsx("option", { value: type, children: type }, type))) }), _jsx("div", { "data-form-fields": true, children: renderer ? (renderer.renderFormFields()) : (_jsx("p", { children: "No configuration available for this job type" })) }), error && _jsx("div", { "data-form-error": true, children: error }), _jsx("button", { type: "submit", disabled: isDisabled, children: loading ? 'Creating...' : 'Create Job' })] }));
45
+ }
@@ -0,0 +1,56 @@
1
+ import { ReactNode } from 'react';
2
+ /**
3
+ * Props for Dashboard component.
4
+ */
5
+ export interface DashboardProps {
6
+ /** Content for the header section */
7
+ header?: ReactNode;
8
+ /** Content for the sidebar section */
9
+ sidebar?: ReactNode;
10
+ /** Content for the footer section */
11
+ footer?: ReactNode;
12
+ /** Main content */
13
+ children: ReactNode;
14
+ /** Custom class name */
15
+ className?: string;
16
+ }
17
+ /**
18
+ * Props for Dashboard.Section component.
19
+ */
20
+ export interface DashboardSectionProps {
21
+ /** Section title */
22
+ title: string;
23
+ /** Section content */
24
+ children: ReactNode;
25
+ /** Whether section is collapsible */
26
+ collapsible?: boolean;
27
+ /** Custom class name */
28
+ className?: string;
29
+ }
30
+ /**
31
+ * Dashboard section subcomponent.
32
+ */
33
+ declare function DashboardSection({ title, children, collapsible, className, }: DashboardSectionProps): JSX.Element;
34
+ /**
35
+ * Dashboard layout component.
36
+ *
37
+ * Provides a flexible layout structure with optional header, sidebar,
38
+ * main content area, and footer. Uses data attributes for styling.
39
+ *
40
+ * @example
41
+ * ```tsx
42
+ * <Dashboard
43
+ * header={<h1>Jobs Dashboard</h1>}
44
+ * sidebar={<Navigation />}
45
+ * >
46
+ * <Dashboard.Section title="Active Jobs">
47
+ * <JobList jobs={jobs} />
48
+ * </Dashboard.Section>
49
+ * </Dashboard>
50
+ * ```
51
+ */
52
+ export declare function Dashboard({ header, sidebar, footer, children, className, }: DashboardProps): JSX.Element;
53
+ export declare namespace Dashboard {
54
+ var Section: typeof DashboardSection;
55
+ }
56
+ export {};
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Dashboard section subcomponent.
4
+ */
5
+ function DashboardSection({ title, children, collapsible, className, }) {
6
+ return (_jsxs("section", { "data-dashboard-section": true, "data-collapsible": collapsible || undefined, "aria-label": title, className: className, children: [_jsx("h3", { children: title }), children] }));
7
+ }
8
+ /**
9
+ * Dashboard layout component.
10
+ *
11
+ * Provides a flexible layout structure with optional header, sidebar,
12
+ * main content area, and footer. Uses data attributes for styling.
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * <Dashboard
17
+ * header={<h1>Jobs Dashboard</h1>}
18
+ * sidebar={<Navigation />}
19
+ * >
20
+ * <Dashboard.Section title="Active Jobs">
21
+ * <JobList jobs={jobs} />
22
+ * </Dashboard.Section>
23
+ * </Dashboard>
24
+ * ```
25
+ */
26
+ export function Dashboard({ header, sidebar, footer, children, className, }) {
27
+ return (_jsxs("div", { "data-dashboard": true, "data-has-sidebar": sidebar ? true : undefined, "data-has-header": header ? true : undefined, className: className, children: [header && _jsx("header", { "data-dashboard-header": true, children: header }), _jsxs("div", { "data-dashboard-body": true, children: [sidebar && _jsx("aside", { "data-dashboard-sidebar": true, children: sidebar }), _jsx("main", { "data-dashboard-main": true, children: children })] }), footer && _jsx("footer", { "data-dashboard-footer": true, children: footer })] }));
28
+ }
29
+ // Attach Section as a static property
30
+ Dashboard.Section = DashboardSection;
@@ -0,0 +1,30 @@
1
+ import type { JobData, JobTypeRenderer } from '../types/renderers.js';
2
+ /**
3
+ * Props for JobCard component.
4
+ */
5
+ export interface JobCardProps<TInput = unknown, TOutput = unknown> {
6
+ /** Job data to display */
7
+ job: JobData<TInput, TOutput>;
8
+ /** Custom renderer for job-specific content */
9
+ renderer?: JobTypeRenderer<TInput, TOutput>;
10
+ /** Callback when retry button is clicked */
11
+ onRetry?: (jobId: string) => void;
12
+ /** Custom class name */
13
+ className?: string;
14
+ }
15
+ /**
16
+ * Generic job card component.
17
+ *
18
+ * Displays job status, content, errors, and retry functionality.
19
+ * Uses data attributes for CSS styling.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * <JobCard
24
+ * job={job}
25
+ * renderer={myRenderer}
26
+ * onRetry={(id) => handleRetry(id)}
27
+ * />
28
+ * ```
29
+ */
30
+ export declare function JobCard<TInput = unknown, TOutput = unknown>({ job, renderer, onRetry, className, }: JobCardProps<TInput, TOutput>): JSX.Element;
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { JobStatusBadge } from './JobStatusBadge.js';
3
+ /**
4
+ * Generic job card component.
5
+ *
6
+ * Displays job status, content, errors, and retry functionality.
7
+ * Uses data attributes for CSS styling.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * <JobCard
12
+ * job={job}
13
+ * renderer={myRenderer}
14
+ * onRetry={(id) => handleRetry(id)}
15
+ * />
16
+ * ```
17
+ */
18
+ export function JobCard({ job, renderer, onRetry, className, }) {
19
+ const isFailed = job.status === 'failed';
20
+ return (_jsxs("div", { "data-job-card": true, "data-status": job.status, className: className, children: [_jsxs("div", { "data-job-card-header": true, children: [_jsx("span", { "data-job-id": true, children: job.id }), _jsx(JobStatusBadge, { status: job.status })] }), _jsx("div", { "data-job-card-content": true, children: renderer ? (renderer.renderContent(job)) : (job.output !== undefined && (_jsx("pre", { children: JSON.stringify(job.output, null, 2) }))) }), job.error && (_jsx("div", { "data-job-card-error": true, children: job.error })), isFailed && onRetry && (_jsx("div", { "data-job-card-actions": true, children: _jsx("button", { onClick: () => onRetry(job.id), "data-retry-button": true, children: "Retry" }) }))] }));
21
+ }
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ /**
3
+ * Props for JobEventLog component.
4
+ */
5
+ export interface JobEventLogProps<TEvent> {
6
+ /** Events to display */
7
+ events: TEvent[];
8
+ /** Render function for each event */
9
+ renderEvent: (event: TEvent, index: number) => React.ReactNode;
10
+ /** Auto-scroll to bottom when new events arrive (default: true) */
11
+ autoScroll?: boolean;
12
+ /** Maximum height - enables scrolling */
13
+ maxHeight?: string | number;
14
+ /** Custom class name */
15
+ className?: string;
16
+ }
17
+ /**
18
+ * Scrollable event log component.
19
+ *
20
+ * Unstyled by default - use CSS to style via data attributes:
21
+ * - `[data-job-event-log]` - container
22
+ * - `[data-job-event-log-empty]` - shown when no events
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * <JobEventLog
27
+ * events={events}
28
+ * maxHeight={400}
29
+ * renderEvent={(event) => (
30
+ * <div key={event.id}>
31
+ * <span>{event.type}</span>: {event.message}
32
+ * </div>
33
+ * )}
34
+ * />
35
+ * ```
36
+ */
37
+ export declare function JobEventLog<TEvent>({ events, renderEvent, autoScroll, maxHeight, className, }: JobEventLogProps<TEvent>): JSX.Element;
@@ -0,0 +1,41 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // ABOUTME: JobEventLog component for displaying job events
3
+ // ABOUTME: Supports auto-scroll and custom event rendering
4
+ import { useRef, useEffect } from 'react';
5
+ /**
6
+ * Scrollable event log component.
7
+ *
8
+ * Unstyled by default - use CSS to style via data attributes:
9
+ * - `[data-job-event-log]` - container
10
+ * - `[data-job-event-log-empty]` - shown when no events
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * <JobEventLog
15
+ * events={events}
16
+ * maxHeight={400}
17
+ * renderEvent={(event) => (
18
+ * <div key={event.id}>
19
+ * <span>{event.type}</span>: {event.message}
20
+ * </div>
21
+ * )}
22
+ * />
23
+ * ```
24
+ */
25
+ export function JobEventLog({ events, renderEvent, autoScroll = true, maxHeight, className, }) {
26
+ const containerRef = useRef(null);
27
+ const prevEventsLengthRef = useRef(events.length);
28
+ // Auto-scroll when new events arrive
29
+ useEffect(() => {
30
+ if (autoScroll && events.length > prevEventsLengthRef.current && containerRef.current) {
31
+ containerRef.current.scrollTop = containerRef.current.scrollHeight;
32
+ }
33
+ prevEventsLengthRef.current = events.length;
34
+ }, [events.length, autoScroll]);
35
+ const style = {};
36
+ if (maxHeight !== undefined) {
37
+ style.maxHeight = typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight;
38
+ style.overflowY = 'auto';
39
+ }
40
+ return (_jsx("div", { ref: containerRef, "data-job-event-log": true, className: className, style: style, children: events.length === 0 ? (_jsx("div", { "data-job-event-log-empty": true, children: "No events yet" })) : (events.map((event, index) => renderEvent(event, index))) }));
41
+ }
@@ -0,0 +1,36 @@
1
+ import type { JobStatus } from './JobStatusBadge.js';
2
+ /**
3
+ * Props for JobFilters component.
4
+ */
5
+ export interface JobFiltersProps {
6
+ /** Current status filter value */
7
+ statusFilter: JobStatus | 'all';
8
+ /** Current type filter value */
9
+ typeFilter: string | 'all';
10
+ /** Available job types for filtering */
11
+ availableTypes: string[];
12
+ /** Callback when status filter changes */
13
+ onStatusChange: (status: JobStatus | 'all') => void;
14
+ /** Callback when type filter changes */
15
+ onTypeChange: (type: string | 'all') => void;
16
+ /** Custom class name */
17
+ className?: string;
18
+ }
19
+ /**
20
+ * Filter controls for job lists.
21
+ *
22
+ * Provides dropdown filters for job status and type.
23
+ * Uses data attributes for CSS styling.
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * <JobFilters
28
+ * statusFilter={statusFilter}
29
+ * typeFilter={typeFilter}
30
+ * availableTypes={['haiku', 'summary']}
31
+ * onStatusChange={setStatusFilter}
32
+ * onTypeChange={setTypeFilter}
33
+ * />
34
+ * ```
35
+ */
36
+ export declare function JobFilters({ statusFilter, typeFilter, availableTypes, onStatusChange, onTypeChange, className, }: JobFiltersProps): JSX.Element;
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Filter controls for job lists.
4
+ *
5
+ * Provides dropdown filters for job status and type.
6
+ * Uses data attributes for CSS styling.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * <JobFilters
11
+ * statusFilter={statusFilter}
12
+ * typeFilter={typeFilter}
13
+ * availableTypes={['haiku', 'summary']}
14
+ * onStatusChange={setStatusFilter}
15
+ * onTypeChange={setTypeFilter}
16
+ * />
17
+ * ```
18
+ */
19
+ export function JobFilters({ statusFilter, typeFilter, availableTypes, onStatusChange, onTypeChange, className, }) {
20
+ return (_jsxs("div", { "data-job-filters": true, className: className, children: [_jsxs("select", { "aria-label": "Filter by status", value: statusFilter, onChange: (e) => onStatusChange(e.target.value), "data-filter-status": true, children: [_jsx("option", { value: "all", children: "All Statuses" }), _jsx("option", { value: "pending", children: "Pending" }), _jsx("option", { value: "running", children: "Running" }), _jsx("option", { value: "completed", children: "Completed" }), _jsx("option", { value: "failed", children: "Failed" })] }), _jsxs("select", { "aria-label": "Filter by type", value: typeFilter, onChange: (e) => onTypeChange(e.target.value), "data-filter-type": true, children: [_jsx("option", { value: "all", children: "All Types" }), availableTypes.map((type) => (_jsx("option", { value: type, children: type }, type)))] })] }));
21
+ }
@@ -0,0 +1,35 @@
1
+ import type { JobData, JobRendererRegistry } from '../types/renderers.js';
2
+ /**
3
+ * Props for JobList component.
4
+ */
5
+ export interface JobListProps {
6
+ /** Jobs to display */
7
+ jobs: JobData[];
8
+ /** Registry of renderers for different job types */
9
+ renderers?: JobRendererRegistry;
10
+ /** Callback when retry button is clicked */
11
+ onRetry?: (jobId: string) => void;
12
+ /** Title for the section */
13
+ title?: string;
14
+ /** Message to display when list is empty */
15
+ emptyMessage?: string;
16
+ /** Custom class name */
17
+ className?: string;
18
+ }
19
+ /**
20
+ * Job list component with grid layout.
21
+ *
22
+ * Displays a list of jobs with optional title and empty state handling.
23
+ * Uses data attributes for CSS styling.
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * <JobList
28
+ * jobs={jobs}
29
+ * title="Active Jobs"
30
+ * renderers={{ 'haiku': haikuRenderer }}
31
+ * onRetry={(id) => handleRetry(id)}
32
+ * />
33
+ * ```
34
+ */
35
+ export declare function JobList({ jobs, renderers, onRetry, title, emptyMessage, className, }: JobListProps): JSX.Element;
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { JobCard } from './JobCard.js';
3
+ /**
4
+ * Job list component with grid layout.
5
+ *
6
+ * Displays a list of jobs with optional title and empty state handling.
7
+ * Uses data attributes for CSS styling.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * <JobList
12
+ * jobs={jobs}
13
+ * title="Active Jobs"
14
+ * renderers={{ 'haiku': haikuRenderer }}
15
+ * onRetry={(id) => handleRetry(id)}
16
+ * />
17
+ * ```
18
+ */
19
+ export function JobList({ jobs, renderers, onRetry, title, emptyMessage = 'No jobs', className, }) {
20
+ // Empty state
21
+ if (jobs.length === 0) {
22
+ return (_jsx("div", { "data-job-list-empty": true, className: className, children: emptyMessage }));
23
+ }
24
+ return (_jsxs("section", { "data-job-list": true, className: className, children: [title && (_jsxs("h2", { "data-job-list-title": true, children: [title, " (", jobs.length, ")"] })), _jsx("div", { "data-job-list-grid": true, children: jobs.map((job) => (_jsx(JobCard, { job: job, renderer: renderers?.[job.type], onRetry: onRetry }, job.id))) })] }));
25
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Props for JobProgress component.
3
+ */
4
+ export interface JobProgressProps {
5
+ /** Progress value (0.0 - 1.0) */
6
+ value: number;
7
+ /** Optional message */
8
+ message?: string;
9
+ /** Show percentage label */
10
+ showLabel?: boolean;
11
+ /** Custom class name */
12
+ className?: string;
13
+ }
14
+ /**
15
+ * Simple progress bar component.
16
+ *
17
+ * Unstyled by default - use CSS to style via data attributes:
18
+ * - `[data-job-progress]` - container
19
+ * - `[data-job-progress-bar]` - the fill bar
20
+ * - `[data-job-progress-label]` - the percentage label
21
+ * - `[data-job-progress-message]` - the message
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * <JobProgress value={0.5} message="Processing..." showLabel />
26
+ * ```
27
+ *
28
+ * @example CSS
29
+ * ```css
30
+ * [data-job-progress] {
31
+ * height: 8px;
32
+ * background: #e5e7eb;
33
+ * border-radius: 4px;
34
+ * overflow: hidden;
35
+ * }
36
+ *
37
+ * [data-job-progress-bar] {
38
+ * height: 100%;
39
+ * background: #3b82f6;
40
+ * transition: width 0.3s ease;
41
+ * }
42
+ * ```
43
+ */
44
+ export declare function JobProgress({ value, message, showLabel, className, }: JobProgressProps): JSX.Element;
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Simple progress bar component.
4
+ *
5
+ * Unstyled by default - use CSS to style via data attributes:
6
+ * - `[data-job-progress]` - container
7
+ * - `[data-job-progress-bar]` - the fill bar
8
+ * - `[data-job-progress-label]` - the percentage label
9
+ * - `[data-job-progress-message]` - the message
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * <JobProgress value={0.5} message="Processing..." showLabel />
14
+ * ```
15
+ *
16
+ * @example CSS
17
+ * ```css
18
+ * [data-job-progress] {
19
+ * height: 8px;
20
+ * background: #e5e7eb;
21
+ * border-radius: 4px;
22
+ * overflow: hidden;
23
+ * }
24
+ *
25
+ * [data-job-progress-bar] {
26
+ * height: 100%;
27
+ * background: #3b82f6;
28
+ * transition: width 0.3s ease;
29
+ * }
30
+ * ```
31
+ */
32
+ export function JobProgress({ value, message, showLabel = false, className, }) {
33
+ const percentage = Math.round(Math.max(0, Math.min(1, value)) * 100);
34
+ return (_jsxs("div", { "data-job-progress": true, className: className, children: [_jsx("div", { "data-job-progress-bar": true, style: { width: `${percentage}%` }, role: "progressbar", "aria-valuenow": percentage, "aria-valuemin": 0, "aria-valuemax": 100 }), showLabel && (_jsxs("span", { "data-job-progress-label": true, children: [percentage, "%"] })), message && (_jsx("span", { "data-job-progress-message": true, children: message }))] }));
35
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Job status values.
3
+ */
4
+ export type JobStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
5
+ /**
6
+ * Props for JobStatusBadge component.
7
+ */
8
+ export interface JobStatusBadgeProps {
9
+ /** Job status */
10
+ status: JobStatus;
11
+ /** Custom class name */
12
+ className?: string;
13
+ }
14
+ /**
15
+ * Status badge component.
16
+ *
17
+ * Unstyled by default - use CSS to style via data attributes:
18
+ * - `[data-job-status]` - container
19
+ * - `[data-status="pending"]`, `[data-status="running"]`, etc. - for status-specific styles
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * <JobStatusBadge status="running" />
24
+ * ```
25
+ *
26
+ * @example CSS
27
+ * ```css
28
+ * [data-job-status] {
29
+ * padding: 2px 8px;
30
+ * border-radius: 4px;
31
+ * font-size: 12px;
32
+ * font-weight: 500;
33
+ * }
34
+ *
35
+ * [data-status="pending"] { background: #fef3c7; color: #92400e; }
36
+ * [data-status="running"] { background: #dbeafe; color: #1e40af; }
37
+ * [data-status="completed"] { background: #d1fae5; color: #065f46; }
38
+ * [data-status="failed"] { background: #fee2e2; color: #991b1b; }
39
+ * [data-status="cancelled"] { background: #f3f4f6; color: #4b5563; }
40
+ * ```
41
+ */
42
+ export declare function JobStatusBadge({ status, className, }: JobStatusBadgeProps): JSX.Element;
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * Status badge component.
4
+ *
5
+ * Unstyled by default - use CSS to style via data attributes:
6
+ * - `[data-job-status]` - container
7
+ * - `[data-status="pending"]`, `[data-status="running"]`, etc. - for status-specific styles
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * <JobStatusBadge status="running" />
12
+ * ```
13
+ *
14
+ * @example CSS
15
+ * ```css
16
+ * [data-job-status] {
17
+ * padding: 2px 8px;
18
+ * border-radius: 4px;
19
+ * font-size: 12px;
20
+ * font-weight: 500;
21
+ * }
22
+ *
23
+ * [data-status="pending"] { background: #fef3c7; color: #92400e; }
24
+ * [data-status="running"] { background: #dbeafe; color: #1e40af; }
25
+ * [data-status="completed"] { background: #d1fae5; color: #065f46; }
26
+ * [data-status="failed"] { background: #fee2e2; color: #991b1b; }
27
+ * [data-status="cancelled"] { background: #f3f4f6; color: #4b5563; }
28
+ * ```
29
+ */
30
+ export function JobStatusBadge({ status, className, }) {
31
+ return (_jsx("span", { "data-job-status": true, "data-status": status, className: className, children: status }));
32
+ }
@@ -0,0 +1,9 @@
1
+ export { JobProgress, type JobProgressProps } from './JobProgress.js';
2
+ export { JobEventLog, type JobEventLogProps } from './JobEventLog.js';
3
+ export { JobStatusBadge, type JobStatusBadgeProps, type JobStatus } from './JobStatusBadge.js';
4
+ export { JobCard, type JobCardProps } from './JobCard.js';
5
+ export { JobList, type JobListProps } from './JobList.js';
6
+ export { JobFilters, type JobFiltersProps } from './JobFilters.js';
7
+ export { ConnectionStatus, type ConnectionStatusProps } from './ConnectionStatus.js';
8
+ export { CreateJobForm, type CreateJobFormProps } from './CreateJobForm.js';
9
+ export { Dashboard, type DashboardProps, type DashboardSectionProps } from './Dashboard.js';
@@ -0,0 +1,11 @@
1
+ // ABOUTME: Components module exports
2
+ // ABOUTME: Re-exports all React components for job UI
3
+ export { JobProgress } from './JobProgress.js';
4
+ export { JobEventLog } from './JobEventLog.js';
5
+ export { JobStatusBadge } from './JobStatusBadge.js';
6
+ export { JobCard } from './JobCard.js';
7
+ export { JobList } from './JobList.js';
8
+ export { JobFilters } from './JobFilters.js';
9
+ export { ConnectionStatus } from './ConnectionStatus.js';
10
+ export { CreateJobForm } from './CreateJobForm.js';
11
+ export { Dashboard } from './Dashboard.js';
@@ -0,0 +1,4 @@
1
+ export { useJobStream, type UseJobStreamOptions, type UseJobStreamResult } from './use-job-stream.js';
2
+ export { useJob, type UseJobResult, type FetchJobFn, type JobData } from './use-job.js';
3
+ export { useJobList, type UseJobListResult, type FetchJobsFn, type ListJobsOptions, type ListJobsResult } from './use-job-list.js';
4
+ export { useConnection, type UseConnectionOptions, type UseConnectionResult } from './use-connection.js';