140 lines
5.1 KiB
TypeScript
140 lines
5.1 KiB
TypeScript
/*
|
|
* @Author : Eleanor Mao
|
|
* @Date : 2024-04-09 10:36:44
|
|
* @LastEditTime : 2024-04-09 10:36:44
|
|
*
|
|
*
|
|
*/
|
|
import React, { ChangeEvent, KeyboardEvent, useEffect, useRef, useState } from "react";
|
|
import Grid from '@mui/material/Grid';
|
|
import Box from '@mui/material/Box';
|
|
import Button from '@mui/material/Button';
|
|
import TextField from '@mui/material/TextField';
|
|
import OutlinedInput from '@mui/material/OutlinedInput';
|
|
import SendIcon from '@mui/icons-material/Send';
|
|
import List from '@mui/material/List';
|
|
import Chip from '@mui/material/Chip';
|
|
import Divider from '@mui/material/Divider';
|
|
import { ChatItem } from "./ChatItem";
|
|
import Stack from '@mui/material/Stack';
|
|
import { uniqueId } from 'lodash';
|
|
import Typography from "@mui/material/Typography";
|
|
import { Editor } from "./Editor";
|
|
|
|
interface Message {
|
|
id: string;
|
|
message: string;
|
|
isMe: boolean;
|
|
}
|
|
|
|
const SupportedBlock = ['BotMessage', 'Chat', 'EmailSender', 'Script'];
|
|
|
|
export const Create = () => {
|
|
const [chatList, setChatList] = useState<Message[]>([]);
|
|
const [workflowName, setWorkFlowName] = useState('My workflow');
|
|
const [chatInput, setChatInput] = useState('');
|
|
const chatContentRef = useRef<HTMLUListElement>(null);
|
|
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
setChatInput(e.target.value);
|
|
};
|
|
|
|
const handleClickChip = (text: string) => () => {
|
|
setChatInput(s => s + text);
|
|
};
|
|
const handleSend = () => {
|
|
setChatList([...chatList, {
|
|
id: uniqueId(),
|
|
message: chatInput,
|
|
isMe: true
|
|
}]);
|
|
setChatInput('');
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (chatContentRef.current) {
|
|
chatContentRef.current.scrollTop = chatContentRef.current.scrollHeight - chatContentRef.current.offsetHeight;
|
|
}
|
|
}, [chatList]);
|
|
|
|
return (
|
|
<>
|
|
<Grid container spacing={2}>
|
|
<Grid item xs={12}>
|
|
<TextField value={workflowName} focused fullWidth variant="outlined" label="Workflow Name"
|
|
placeholder="Please name your workflow" onChange={e => {
|
|
setWorkFlowName(e.target.value);
|
|
}}/>
|
|
|
|
</Grid>
|
|
<Grid item xs={12}>
|
|
<Grid container spacing={2}>
|
|
<Grid item xs>
|
|
<Box sx={{ border: 1, height: 600, borderRadius: 1, mt: 4, borderColor: 'rgba(0,0,0,0.23)' }}>
|
|
<div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
|
|
<List ref={chatContentRef}
|
|
style={{ flex: '1 1 auto', overflowY: 'auto', overflowX: 'hidden' }}
|
|
sx={{ p: 2 }}>
|
|
{chatList.map(chat => <ChatItem isMe={chat.isMe} message={chat.message} key={chat.id}/>)}
|
|
</List>
|
|
<Box sx={{ display: 'flex', flex: '0 0 auto', p: 2, borderTop: 1, borderColor: 'divider' }}>
|
|
<Grid container spacing={2}>
|
|
<Grid item xs={12} style={{ gap: 8 }}>
|
|
<Stack direction="row" spacing={1}>
|
|
<Typography variant="body2">
|
|
Supported Action Types:
|
|
</Typography>
|
|
{SupportedBlock.map(label => (
|
|
<Chip label={label} key={label} size="small" clickable
|
|
onClick={handleClickChip(label)}/>))}
|
|
</Stack>
|
|
</Grid>
|
|
<Grid item xs>
|
|
<OutlinedInput fullWidth size="small" onChange={handleChange}
|
|
onKeyDown={(e: KeyboardEvent<HTMLInputElement>) => {
|
|
if (e.key === 'Enter' && chatInput.length) {
|
|
e.preventDefault();
|
|
handleSend();
|
|
}
|
|
}}
|
|
multiline maxRows={3}
|
|
value={chatInput}/>
|
|
</Grid>
|
|
<Grid item xs="auto" justifyContent="center">
|
|
<Button variant="contained" size="large" disabled={!chatInput.length} onClick={handleSend}>
|
|
<SendIcon/>
|
|
</Button>
|
|
</Grid>
|
|
</Grid>
|
|
</Box>
|
|
</div>
|
|
</Box>
|
|
</Grid>
|
|
<Grid item xs={4}>
|
|
<Box sx={{ border: 1, height: 600, borderRadius: 1, p: 2, mt: 4, borderColor: 'rgba(0,0,0,0.23)' }}>
|
|
Preview
|
|
</Box>
|
|
</Grid>
|
|
</Grid>
|
|
<Divider sx={{ mt: 4, mb: 4 }}/>
|
|
<Editor/>
|
|
|
|
</Grid>
|
|
</Grid>
|
|
<Box
|
|
sx={{
|
|
position: 'fixed',
|
|
bottom: 0,
|
|
left: 0,
|
|
right: 0,
|
|
p: 2,
|
|
boxShadow: 2,
|
|
borderTop: 1,
|
|
borderColor: 'divider',
|
|
display: { xs: 'flex' }, justifyContent: "flex-end"
|
|
}}>
|
|
<Button variant="contained" style={{ width: 100 }}>Save</Button>
|
|
</Box>
|
|
</>
|
|
);
|
|
};
|