frontend_nyla/src/components/Automation2FlowEditor/editor/CanvasHeader.tsx

130 lines
3.8 KiB
TypeScript

/**
* CanvasHeader - Workflow controls (Neu, Speichern, laden, Ausführen) and execute result.
*/
import React from 'react';
import { FaCog, FaPlay, FaSpinner } from 'react-icons/fa';
import type { Automation2Workflow, ExecuteGraphResponse } from '../../../api/automation2Api';
import styles from './Automation2FlowEditor.module.css';
interface CanvasHeaderProps {
workflows: Automation2Workflow[];
currentWorkflowId: string | null;
onWorkflowSelect: (workflowId: string | null) => void;
onNew: () => void;
onSave: () => void;
onExecute: () => void;
onWorkflowSettings?: () => void;
saving: boolean;
executing: boolean;
hasNodes: boolean;
executeResult: ExecuteGraphResponse | null;
}
export const CanvasHeader: React.FC<CanvasHeaderProps> = ({
workflows,
currentWorkflowId,
onWorkflowSelect,
onNew,
onSave,
onExecute,
onWorkflowSettings,
saving,
executing,
hasNodes,
executeResult,
}) => (
<div className={styles.canvasHeader}>
<div style={{ display: 'flex', alignItems: 'center', gap: '1rem', flexWrap: 'wrap' }}>
<h4 className={styles.canvasTitle} style={{ margin: 0 }}>
Workflow-Editor
</h4>
{onWorkflowSettings && (
<button
type="button"
className={styles.canvasGearBtn}
title="Workflow-Konfiguration (Einstieg / Starts)"
aria-label="Workflow-Konfiguration"
onClick={onWorkflowSettings}
>
<FaCog />
</button>
)}
<button type="button" className={styles.retryButton} onClick={onNew}>
Neu
</button>
<button
type="button"
className={styles.retryButton}
onClick={onSave}
disabled={saving || !hasNodes}
>
{saving ? <FaSpinner className={styles.spinner} /> : 'Speichern'}
</button>
<select
value={currentWorkflowId ?? ''}
onChange={(e) => {
const id = e.target.value ? e.target.value : null;
onWorkflowSelect(id);
}}
style={{ padding: '0.4rem', minWidth: 180 }}
>
<option value=""> Workflow laden </option>
{workflows.map((w) => (
<option key={w.id} value={w.id}>
{w.label}
</option>
))}
</select>
<button
type="button"
className={styles.retryButton}
onClick={onExecute}
disabled={executing || !hasNodes}
>
{executing ? (
<>
<FaSpinner className={styles.spinner} style={{ marginRight: '0.5rem', display: 'inline-block' }} />
Ausführen
</>
) : (
<>
<FaPlay style={{ marginRight: '0.5rem' }} />
Ausführen
</>
)}
</button>
</div>
{executeResult && (
<div
style={{
marginTop: '0.5rem',
padding: '0.5rem',
borderRadius: 6,
fontSize: '0.875rem',
background: executeResult.success
? 'rgba(40,167,69,0.15)'
: (executeResult as { paused?: boolean }).paused
? 'rgba(0,123,255,0.15)'
: 'rgba(220,53,69,0.15)',
color: executeResult.success
? 'var(--success-color,#28a745)'
: (executeResult as { paused?: boolean }).paused
? 'var(--primary-color,#007bff)'
: 'var(--danger-color,#dc3545)',
}}
>
{executeResult.success ? (
<> Ausführung abgeschlossen.</>
) : (executeResult as { paused?: boolean }).paused ? (
<>
Workflow pausiert. Öffne <strong>Workflows & Tasks</strong> in der Sidebar, um den
Task zu bearbeiten.
</>
) : (
<> {executeResult.error ?? 'Unbekannter Fehler'}</>
)}
</div>
)}
</div>
);