feat: initial public release (MAESTRO)
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
import { HelpText } from './HelpText';
|
||||
|
||||
const SPECIAL_TARGETS = ['COMPLETE', 'ASK', 'ABORT', 'WAIT_SUBTASKS'];
|
||||
|
||||
export interface RulesTableProps {
|
||||
rules: Array<{ condition: string; next: string }>;
|
||||
movementNames: string[];
|
||||
onChange: (rules: Array<{ condition: string; next: string }>) => void;
|
||||
}
|
||||
|
||||
export function RulesTable({ rules, movementNames, onChange }: RulesTableProps) {
|
||||
const nextOptions = [...movementNames, ...SPECIAL_TARGETS];
|
||||
|
||||
const updateRule = (index: number, field: 'condition' | 'next', value: string) => {
|
||||
const updated = rules.map((r, i) => (i === index ? { ...r, [field]: value } : r));
|
||||
onChange(updated);
|
||||
};
|
||||
|
||||
const addRule = () => {
|
||||
onChange([...rules, { condition: '', next: movementNames[0] ?? 'COMPLETE' }]);
|
||||
};
|
||||
|
||||
const removeRule = (index: number) => {
|
||||
onChange(rules.filter((_, i) => i !== index));
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-slate-600 mb-1">rules</label>
|
||||
{rules.length > 0 && (
|
||||
<table className="w-full text-sm mb-2">
|
||||
<thead>
|
||||
<tr className="text-xs text-slate-500">
|
||||
<th className="text-left font-medium pb-1 pr-2">condition</th>
|
||||
<th className="text-left font-medium pb-1 pr-2 w-44">next</th>
|
||||
<th className="w-8" />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rules.map((rule, i) => (
|
||||
<tr key={i}>
|
||||
<td className="pr-2 pb-1">
|
||||
<input
|
||||
type="text"
|
||||
value={rule.condition}
|
||||
onChange={(e) => updateRule(i, 'condition', e.target.value)}
|
||||
className="w-full px-3 py-1.5 text-sm border border-slate-300 rounded-lg focus:ring-2 focus:ring-accent-ring focus:border-accent outline-none"
|
||||
placeholder="条件..."
|
||||
/>
|
||||
</td>
|
||||
<td className="pr-2 pb-1">
|
||||
<select
|
||||
value={rule.next}
|
||||
onChange={(e) => updateRule(i, 'next', e.target.value)}
|
||||
className="w-full px-3 py-1.5 text-sm border border-slate-300 rounded-lg focus:ring-2 focus:ring-accent-ring focus:border-accent outline-none bg-white"
|
||||
>
|
||||
{nextOptions.map((opt) => (
|
||||
<option key={opt} value={opt}>{opt}</option>
|
||||
))}
|
||||
</select>
|
||||
</td>
|
||||
<td className="pb-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => removeRule(i)}
|
||||
className="text-slate-400 hover:text-red-500 text-sm px-1"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
onClick={addRule}
|
||||
className="text-xs text-blue-600 hover:text-blue-700"
|
||||
>
|
||||
+ Add Rule
|
||||
</button>
|
||||
<HelpText>LLM が transition ツールで遷移先を選ぶ際の条件です</HelpText>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user