webapp/src/components/TaskForm.tsx

101 lines
3.4 KiB
TypeScript
Raw Normal View History

import React, { useState } from 'react';
import { View, StyleSheet, ScrollView } from 'react-native';
import { TextInput, Menu, Button, Divider, Text } from 'react-native-paper';
import { Task, RobotAction } from '../types/task';
import { LOCATIONS, ROBOT_ACTIONS, PAYLOADS, LOCATIONS_BAYS } from '../data/mockData';
interface TaskFormProps {
task: Task;
onTaskChange: (updatedTask: Task) => void;
}
const TaskForm: React.FC<TaskFormProps> = ({ task, onTaskChange }) => {
const [menuVisible, setMenuVisible] = useState<{ [key: string]: boolean }>({});
const openMenu = (name: string) => setMenuVisible(prev => ({ ...prev, [name]: true }));
const closeMenu = (name: string) => setMenuVisible(prev => ({ ...prev, [name]: false }));
const handleParamChange = (field: string, value: string | RobotAction) => {
const updatedTask = {
...task,
parameters: {
...task.parameters,
[field]: value,
},
};
onTaskChange(updatedTask);
};
const renderDropdown = (
name: string,
label: string,
value: string,
items: { label: string, value: string }[]
) => (
<View style={styles.input}>
<Text>{label}</Text>
<Menu
visible={menuVisible[name]}
onDismiss={() => closeMenu(name)}
anchor={
<Button onPress={() => openMenu(name)} mode="outlined">
{value || `选择${label}`}
</Button>
}
>
<ScrollView style={{ maxHeight: 200 }}>
{items.map(item => (
<Menu.Item
key={item.value}
onPress={() => {
handleParamChange(name, item.value);
closeMenu(name);
}}
title={item.label}
/>
))}
</ScrollView>
</Menu>
</View>
);
return (
<ScrollView contentContainerStyle={styles.container}>
<TextInput
label="任务名称"
value={task.name}
onChangeText={text => onTaskChange({ ...task, name: text })}
style={styles.input}
mode="outlined"
/>
{renderDropdown('startLocation', '起点', task.parameters.startLocation, LOCATIONS)}
{renderDropdown('endLocation', '终点', task.parameters.endLocation, LOCATIONS)}
<TextInput
label="途经点 (可选)"
value={task.parameters.waypoint || ''}
onChangeText={text => handleParamChange('waypoint', text)}
style={styles.input}
mode="outlined"
/>
{renderDropdown('robotAction', '机器人动作', task.parameters.robotAction, ROBOT_ACTIONS)}
{renderDropdown('payload', '载荷', task.parameters.payload, PAYLOADS)}
{renderDropdown('locationBay', '库位', task.parameters.locationBay, LOCATIONS_BAYS)}
</ScrollView>
);
};
const styles = StyleSheet.create({
container: {
padding: 16,
},
input: {
marginBottom: 16,
},
});
export default TaskForm;