feat(scenarios): link scenarios to a default environment
- add optional ManyToOne relation from scenario to environment entity - expose environmentId in create/update DTOs, service, and MCP tools - pre-select linked environment in run modals on detail and list pages - add environment selector to create/edit scenario forms - show linked environment as a navigable link on scenario detail page
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { useState, SubmitEvent } from 'react';
|
||||
import { useEffect, useState, SubmitEvent } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { X, Save, ClipboardList } from 'lucide-react';
|
||||
import { scenarios } from '../../api';
|
||||
import { Breadcrumbs, Button, Card, Input, CodeEditor, useToast } from '../../ui';
|
||||
import { scenarios, environments } from '../../api';
|
||||
import type { Environment } from '../../api';
|
||||
import { Breadcrumbs, Button, Card, Input, CodeEditor, Select, useToast } from '../../ui';
|
||||
import styles from '../Page.module.css';
|
||||
|
||||
export function CreateScenarioPage() {
|
||||
@@ -13,9 +14,15 @@ export function CreateScenarioPage() {
|
||||
|
||||
const [name, setName] = useState('');
|
||||
const [description, setDescription] = useState('');
|
||||
const [environmentId, setEnvironmentId] = useState('');
|
||||
const [envs, setEnvs] = useState<Environment[]>([]);
|
||||
const [nameError, setNameError] = useState('');
|
||||
const [saving, setSaving] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
environments.list(1, 200).then((r) => setEnvs(r?.data ?? [])).catch(() => {});
|
||||
}, []);
|
||||
|
||||
const handleSubmit = async (e: SubmitEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
if (!name.trim()) {
|
||||
@@ -24,7 +31,7 @@ export function CreateScenarioPage() {
|
||||
}
|
||||
setSaving(true);
|
||||
try {
|
||||
const scenario = await scenarios.create(name.trim(), description.trim() || undefined);
|
||||
const scenario = await scenarios.create(name.trim(), description.trim() || undefined, environmentId || undefined);
|
||||
toast.success(t('scenarios.created'));
|
||||
navigate(`/scenarios/${scenario.id}`);
|
||||
} catch (err) {
|
||||
@@ -74,6 +81,15 @@ export function CreateScenarioPage() {
|
||||
rows={8}
|
||||
/>
|
||||
</div>
|
||||
<Select
|
||||
label={t('scenarios.form_environment')}
|
||||
value={environmentId}
|
||||
onChange={(e) => setEnvironmentId(e.target.value)}
|
||||
options={[
|
||||
{ value: '', label: t('scenarios.form_environment_none') },
|
||||
...envs.map((env) => ({ value: env.id, label: env.name })),
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.formActions}>
|
||||
|
||||
Reference in New Issue
Block a user