ui-nyla/src/components/Automation2FlowEditor/nodes/shared/HybridStaticRefField.tsx

109 lines
3.1 KiB
TypeScript

/**
* Text/number field: „Quelle wählen“ → Statisch (Eingabe) oder Kontext-Ref.
* Textfeld nur bei „Statisch“, nicht bei Kontext-Referenz.
*/
import React from 'react';
import {
StatischKontextSelect,
shouldShowStaticControl,
type PathPickMode,
} from './RefSourceSelect';
import { useAutomation2DataFlow } from '../../context/Automation2DataFlowContext';
import { isRef, isValue, createValue } from './dataRef';
import styles from '../../editor/Automation2FlowEditor.module.css';
function parseHybrid(value: unknown): { staticStr: string } {
if (isRef(value)) return { staticStr: '' };
if (isValue(value)) {
const v = value.value;
if (v === null || v === undefined) return { staticStr: '' };
return { staticStr: String(v) };
}
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
return { staticStr: String(value) };
}
return { staticStr: '' };
}
export interface HybridStaticRefFieldProps {
label: string;
value: unknown;
onChange: (value: unknown) => void;
multiline?: boolean;
inputType?: 'text' | 'number';
placeholder?: string;
/** Passed to StatischKontextSelect — use clickup_task_id for Task-ID fields. */
pathPickMode?: PathPickMode;
}
export const HybridStaticRefField: React.FC<HybridStaticRefFieldProps> = ({
label,
value,
onChange,
multiline,
inputType = 'text',
placeholder,
pathPickMode = 'default',
}) => {
const dataFlow = useAutomation2DataFlow();
const hasSources =
dataFlow &&
dataFlow.getAvailableSourceIds().some((id) => {
const n = dataFlow.nodes.find((x) => x.id === id);
if (n?.type === 'trigger.manual') return false;
if (
pathPickMode === 'exclude_forms' &&
(n?.type === 'input.form' || n?.type === 'trigger.form')
) {
return false;
}
if (pathPickMode === 'clickup_task_id') {
return Boolean(n?.type?.startsWith('clickup.'));
}
return true;
});
const { staticStr } = parseHybrid(value);
const handleStaticChange = (v: string) => {
if (inputType === 'number') {
const n = parseFloat(v);
onChange(createValue(Number.isFinite(n) ? n : ''));
} else {
onChange(createValue(v));
}
};
return (
<div className={styles.dynamicValueField}>
<label>{label}</label>
{hasSources ? (
<div style={{ marginBottom: 8 }}>
<StatischKontextSelect
value={value}
onChange={onChange}
placeholder="— Quelle wählen —"
pathPickMode={pathPickMode}
/>
</div>
) : null}
{shouldShowStaticControl(value, Boolean(hasSources)) &&
(multiline ? (
<textarea
rows={4}
value={staticStr}
onChange={(e) => handleStaticChange(e.target.value)}
placeholder={placeholder}
/>
) : (
<input
type={inputType === 'number' ? 'number' : 'text'}
value={staticStr}
onChange={(e) => handleStaticChange(e.target.value)}
placeholder={placeholder}
/>
))}
</div>
);
};