diff --git a/public/favicon.ico b/public/favicon.ico
index a11777c..f416549 100644
Binary files a/public/favicon.ico and b/public/favicon.ico differ
diff --git a/public/index.html b/public/index.html
index 68c5af4..d02eafd 100644
--- a/public/index.html
+++ b/public/index.html
@@ -7,7 +7,6 @@
-
React App
+ RingCentral@Workflow Hub
diff --git a/src/AIBot.tsx b/src/AIBot.tsx
index e8f2c09..57e433e 100644
--- a/src/AIBot.tsx
+++ b/src/AIBot.tsx
@@ -23,7 +23,7 @@ export const AIBot: FC<{
Intelligence Admin Portal
-
diff --git a/src/ChatItem.tsx b/src/ChatItem.tsx
index d27e205..b794c80 100644
--- a/src/ChatItem.tsx
+++ b/src/ChatItem.tsx
@@ -40,7 +40,8 @@ const ChatMessageWrap = styled(Box)<{ isMe: boolean }>(({ isMe }) => ({
marginTop: 4,
marginBottom: 4,
display: 'flex',
- justifyContent: isMe ? 'flex-end' : 'flex-start'
+ justifyContent: isMe ? 'flex-end' : 'flex-start',
+ color: isMe ? 'rgba(0, 0, 0, 0.87)' : 'white'
}));
const ChatMessage = styled(Box)(() => ({
diff --git a/src/Create.tsx b/src/Create.tsx
index b57e9b6..42b07f2 100644
--- a/src/Create.tsx
+++ b/src/Create.tsx
@@ -12,10 +12,8 @@ import Button from '@mui/material/Button';
import TextField from '@mui/material/TextField';
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 { cloneDeep, uniqueId } from 'lodash';
import Typography from "@mui/material/Typography";
import { useLocation, useNavigate, useParams } from "react-router-dom";
@@ -29,7 +27,11 @@ import { AIBot } from "./AIBot";
import { GlipSender } from "./GlipSender";
import { ScriptBlock } from "./Script";
import { message } from 'mui-message';
-import { isChatBot } from "./transform";
+import AutoAwesomeIcon from '@mui/icons-material/AutoAwesome';
+import InputAdornment from "@mui/material/InputAdornment";
+import Stack from '@mui/material/Stack';
+import Switch from '@mui/material/Switch';
+import { styled } from "@mui/material/styles";
const DefaultMessage = [
'Hello! Please tell me what kind of workflow you want to generate!\n',
@@ -55,7 +57,7 @@ type PreValue = string | undefined | null
const preValueObj: { bot: PreValue; script: PreValue; email: PreValue; glip: PreValue } = {
bot: '',
script: '',
- email: '',
+ email: '{"to":"","subject":"","content":"${localData.Desc}"}',
glip: ''
};
@@ -66,7 +68,48 @@ interface Message {
loading?: boolean;
}
-const SupportedBlock = ['BotMessage', 'Chat', 'GlipSender', 'Script'];
+interface ActionWithStateName extends Action {
+ stateName: string;
+}
+
+const AntSwitch = styled(Switch)(({ theme }) => ({
+ width: 28,
+ height: 16,
+ padding: 0,
+ display: 'flex',
+ '&:active': {
+ '& .MuiSwitch-thumb': {
+ width: 15,
+ },
+ '& .MuiSwitch-switchBase.Mui-checked': {
+ transform: 'translateX(9px)',
+ },
+ },
+ '& .MuiSwitch-switchBase': {
+ padding: 2,
+ '&.Mui-checked': {
+ transform: 'translateX(12px)',
+ color: '#fff',
+ '& + .MuiSwitch-track': {
+ opacity: 1,
+ },
+ },
+ },
+ '& .MuiSwitch-thumb': {
+ boxShadow: '0 2px 4px 0 rgb(0 35 11 / 20%)',
+ width: 12,
+ height: 12,
+ borderRadius: 6,
+ transition: theme.transitions.create(['width'], {
+ duration: 200,
+ }),
+ },
+ '& .MuiSwitch-track': {
+ borderRadius: 16 / 2,
+ opacity: 1,
+ boxSizing: 'border-box',
+ },
+}));
export const Create: FC<{ edit?: boolean }> = ({ edit }) => {
const { id } = useParams();
@@ -88,22 +131,16 @@ export const Create: FC<{ edit?: boolean }> = ({ edit }) => {
const flowDefinition = useMemo(() => DSL2Json(workflowContent), [workflowContent]);
const previewImg = useMemo(() => Json2Preview(flowDefinition), [flowDefinition]);
const chatContentRef = useRef(null);
- const actions = useMemo(() => ((flowDefinition || {}).states || []).reduce>(() => ((flowDefinition || {}).states || []).reduce>((l, s) => {
+ }>>((l, s) => {
l.push(...s.actions.map(a => ({ ...a, stateName: s.name })));
return l;
}, []), [flowDefinition]);
- const hasEmailSender = useMemo(() => actions.some(a => a.actionType === "EmailSender"), [actions]);
- const botAddinAction = useMemo(() => actions.find(a => a.actionType === "Chat"), [actions]);
- const scriptAction = useMemo(() => actions.find(a => a.actionType === "Script"), [actions]);
- const glipSenderAction = useMemo(() => actions.find(a => a.actionType === "GlipSender"), [actions]);
+ const emailSenderAction = useMemo(() => actions.find(a => a.actionType === "EmailSender"), [actions]);
+ const botAddinAction = useMemo(() => actions.find(a => a.actionType === "Chat"), [actions]);
+ const scriptAction = useMemo(() => actions.find(a => a.actionType === "Script"), [actions]);
+ const glipSenderAction = useMemo(() => actions.find(a => a.actionType === "GlipSender"), [actions]);
const [aibot, setAIBot] = useState('');
const [script, setScript] = useState('');
const [emailData, setEmailData] = useState({
@@ -112,14 +149,11 @@ export const Create: FC<{ edit?: boolean }> = ({ edit }) => {
// eslint-disable-next-line no-template-curly-in-string
content: '${localData.Desc}',
});
- const [glipSenderData, setGlipSenderData] = useState({
- clientId: '',
- clientSecret: '',
- // eslint-disable-next-line no-template-curly-in-string
- message: ''
- });
- const [channelId, setChannelId] = useState('78394499078-4034902020');
+ const [glipSenderData, setGlipSenderData] = useState('');
+ const [isImageMode, setImageMode] = useState(true);
+ const creatorId = '4034902020';
const location = useLocation();
+ const [teamLink, setTeamLink] = useState('');
const debug = useMemo(() => {
return (new URLSearchParams(location.search)).get('debug') === 'true';
}, [location]);
@@ -148,9 +182,6 @@ export const Create: FC<{ edit?: boolean }> = ({ edit }) => {
setChatInput(e.target.value);
};
- const handleClickChip = (text: string) => () => {
- setChatInput(s => s + text);
- };
const handleSend = async () => {
const rId = uniqueId('r');
@@ -185,24 +216,15 @@ export const Create: FC<{ edit?: boolean }> = ({ edit }) => {
useEffect(() => {
if (glipSenderAction) {
let actionValueString = glipSenderAction.message;
- let crtValueString = glipSenderData.message;
- if (actionValueString !== preValueObj.glip && crtValueString === preValueObj.glip) {
- setGlipSenderData({
- clientSecret: '',
- clientId: '',
- message: actionValueString || '',
- });
+ if (actionValueString !== preValueObj.glip && glipSenderData === preValueObj.glip) {
+ setGlipSenderData(actionValueString || '');
preValueObj.glip = actionValueString || '';
}
} else {
if (preValueObj.glip) {
preValueObj.glip = '';
- setGlipSenderData({
- clientSecret: '',
- clientId: '',
- // eslint-disable-next-line no-template-curly-in-string
- message: '${localData.Desc}'
- });
+ // eslint-disable-next-line no-template-curly-in-string
+ setGlipSenderData('${localData.Desc}');
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -232,7 +254,35 @@ export const Create: FC<{ edit?: boolean }> = ({ edit }) => {
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [botAddinAction]);
-
+ useEffect(() => {
+ if (emailSenderAction) {
+ const newValueStr = JSON.stringify({
+ to: emailSenderAction.to || '',
+ subject: emailSenderAction.subject || '',
+ content: emailSenderAction.content || ''
+ });
+ const crtValueStr = JSON.stringify({
+ to: emailData.to,
+ subject: emailData.subject,
+ content: emailData.content
+ });
+ if (newValueStr !== preValueObj.email && crtValueStr === preValueObj.email) {
+ setEmailData({
+ to: emailSenderAction.to || '',
+ subject: emailSenderAction.subject || '',
+ content: emailSenderAction.content || ''
+ });
+ preValueObj.email = newValueStr || '';
+ }
+ } else {
+ setEmailData({
+ to: '',
+ subject: '',
+ // eslint-disable-next-line no-template-curly-in-string
+ content: '${localData.Desc}',
+ });
+ }
+ }, [emailSenderAction]);
useEffect(() => {
if (chatContentRef.current) {
chatContentRef.current.scrollTop = chatContentRef.current.scrollHeight - chatContentRef.current.offsetHeight;
@@ -250,15 +300,7 @@ export const Create: FC<{ edit?: boolean }> = ({ edit }) => {
setWorkflowContent('');
};
- useEffect(() => {
- if (!hasEmailSender)
- setEmailData({
- to: '',
- subject: '',
- // eslint-disable-next-line no-template-curly-in-string
- content: '${localData.Desc}',
- });
- }, [hasEmailSender]);
+
const navigate = useNavigate();
const handleSubmit = async () => {
if (!flowDefinition) return;
@@ -278,11 +320,14 @@ export const Create: FC<{ edit?: boolean }> = ({ edit }) => {
}
if (action.actionType === 'GlipSender') {
// action.url = glipSenderData.url;
- action.message = glipSenderData.message || '${localData.Desc}';
+ // eslint-disable-next-line no-template-curly-in-string
+ action.message = glipSenderData || '${localData.Desc}';
}
});
});
console.log(Json2Yml(newJson));
+ const channelId = (teamLink.replace(/[^\d]+/, '')) + '-' + creatorId;
+ console.log(channelId);
await axios.put(`/bot/workflow/${id}`, {
name: formJson.name,
content: Json2Yml(newJson)
@@ -291,7 +336,7 @@ export const Create: FC<{ edit?: boolean }> = ({ edit }) => {
await axios.delete(`/bot/workflow/${id}/bind/${channelId}`);
await axios.post(`/bot/workflow/${id}/bind`, { channelId });
}
- message.success(`Saved! ${debug ? 'Back to List and go bind your channel!' : ''}`);
+ message.success(`Publish Success! ${debug ? 'Back to List and go bind your channel!' : ''}`);
setTimeout(() => {
navigate(`/${debug ? '?debug=true' : ''}`);
}, 3000);
@@ -356,6 +401,9 @@ export const Create: FC<{ edit?: boolean }> = ({ edit }) => {
}
}}
autoFocus
+ InputProps={{
+ startAdornment:
+ }}
variant="outlined"
focused placeholder="Enter your goal ..."
multiline maxRows={3}
@@ -372,21 +420,56 @@ export const Create: FC<{ edit?: boolean }> = ({ edit }) => {
-
- {!previewImg ? <>👋 The flow chart will be previewed here!
😻 Tell the AI robot what you want to
- do! > :
-
}
+
+ {!previewImg ?
+ 👋 The flow chart will be previewed here!
😻 Tell the AI robot what
+ you want to
+ do!
:
+ (
+ <>
+
+ Raw
+ setImageMode(checked)}/>
+ Image
+
+ {isImageMode ?
+
:
+ {workflowContent}
+ }
+ >
+ )
+ }
- {!!scriptAction || hasEmailSender || !!botAddinAction ?
+ {!!scriptAction || !!emailSenderAction || !!botAddinAction || !!glipSenderAction ?
- Please fill in the following information related to your workflow nodes. 👇🏻👇🏻 : null}
- {hasEmailSender && }
+ Please fill in the following information related to your workflow nodes. 👇🏻👇🏻 : null}
+ {!!emailSenderAction && }
{!!botAddinAction && }
{!!scriptAction && }
- {!!glipSenderAction && }
+ {!!glipSenderAction &&
+ {
+ if (isTeamLink) {
+ setTeamLink(value);
+ } else {
+ setGlipSenderData(value);
+ }
+ }}/>}
@@ -404,7 +487,7 @@ export const Create: FC<{ edit?: boolean }> = ({ edit }) => {
borderColor: 'divider',
display: { xs: 'flex' }, justifyContent: "flex-end"
}}>
-
+
>
);
diff --git a/src/Editor.tsx b/src/Editor.tsx
index f74bffb..de7f6b9 100644
--- a/src/Editor.tsx
+++ b/src/Editor.tsx
@@ -6,7 +6,7 @@
*
*/
-import React, { useState } from 'react';
+import React from 'react';
import MonacoEditor from 'react-monaco-editor';
export const Editor: React.FC<{ value: string; onChange: (value: string) => void }> = ({ value, onChange }) => {
diff --git a/src/EmailSender.tsx b/src/EmailSender.tsx
index a1d336d..61b0059 100644
--- a/src/EmailSender.tsx
+++ b/src/EmailSender.tsx
@@ -24,15 +24,15 @@ export const EmailSender: FC<{
Email Sender
diff --git a/src/GlipSender.tsx b/src/GlipSender.tsx
index 81283df..ef73b76 100644
--- a/src/GlipSender.tsx
+++ b/src/GlipSender.tsx
@@ -1,41 +1,94 @@
-import React, { ChangeEvent, FC, useEffect, useState } from 'react';
+import React, { ChangeEvent, FC, useState } from 'react';
import Paper from '@mui/material/Paper';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import TextField from '@mui/material/TextField';
+import InputAdornment from "@mui/material/InputAdornment";
+import IconButton from '@mui/material/IconButton';
+import Visibility from '@mui/icons-material/Visibility';
+import VisibilityOff from '@mui/icons-material/VisibilityOff';
+import { MenuItem, Select, SelectChangeEvent } from "@mui/material";
export const GlipSender: FC<{
+ value: string;
debug?: boolean
- value: { clientId: string; clientSecret: string; message: string };
- onChange: (value: {
- clientId: string; clientSecret: string; message: string
- }) => void
-}> = ({ value, debug, onChange }) => {
+ edit?: boolean
+ id?: string
+ teamLink: string
+ onChange: (value: string, isTeamLink?: boolean) => void
+}> = ({ value, id,teamLink, debug, edit, onChange }) => {
const handleChange = (e: ChangeEvent) => {
- onChange({
- ...value,
- [e.target.name]: e.target.value
- });
+ onChange(e.target.value);
};
+ const [showPassword, setShowPassword] = React.useState(edit ? false : true);
+
+ const handleClickShowPassword = () => setShowPassword((show) => !show);
+
+ const handleMouseDownPassword = (event: React.MouseEvent) => {
+ event.preventDefault();
+ };
+
+ const [senderType, setSenderType] = useState('default');
+ const handleChangeType = (e: SelectChangeEvent) => {
+ setSenderType(e.target.value);
+ };
+
+ const handleChangeTeam = (event: React.ChangeEvent) => {
+ onChange(event.target.value, true)
+ };
+
+
return (
- GlipSender
-
- WFL Hub will send messages via RingCentral Bot, please fill in:
-
+ GlipSender
{!debug &&
<>
-
-
+
+ {senderType === 'default' ? <>
+
+ WFL Hub will send message via default bot @David-Bot
+
+
+ > :
+ <>
+
+ WFL Hub will send messages via your RingCentral Bot, please
+ fill in:
+
+
+
+
+ {showPassword ? : }
+
+
+ )
+ }}
+ />
+ >}
+
>}
diff --git a/src/List.tsx b/src/List.tsx
index 4fef18b..669c2b6 100644
--- a/src/List.tsx
+++ b/src/List.tsx
@@ -39,6 +39,7 @@ interface Workflow {
id: string;
name: string;
lastModifiedTime: string;
+ emoji?: string;
}
export const List = () => {
@@ -52,7 +53,10 @@ export const List = () => {
total: number
workflows: Workflow[]
}>('/api/public/wf/config/v1/account/10086/workflows').then(({ data }) => {
- setList(data.workflows);
+ setList(data.workflows.map(it => ({
+ ...it,
+ emoji: getRandomEmoji()
+ })));
});
}, []);
const handleOpen = () => {
@@ -84,7 +88,7 @@ export const List = () => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const formJson = Object.fromEntries((formData as any).entries());
- const channelId = formJson.channelId.trim();
+ const channelId = `${formJson.groupId.trim()}-${formJson.creatorId.trim()}`;
await axios.delete(`/bot/workflow/${showBindModal}/bind/${channelId}`);
await axios.post(`/bot/workflow/${showBindModal}/bind`, { channelId });
message.success('Success!');
@@ -105,7 +109,7 @@ export const List = () => {
- {getRandomEmoji()} {item.name || 'My Workflow'}
+ {item.emoji} {item.name || 'My Workflow'}
{
:
- }
+ }}>Bind : }
+ {/**/}
@@ -147,7 +151,6 @@ export const List = () => {
margin="dense"
id="name"
name="name"
- defaultValue="My workflow"
label="Workflow Name"
fullWidth
focused
@@ -169,10 +172,17 @@ export const List = () => {
+
diff --git a/src/index.css b/src/index.css
index 0846f2c..6e535b3 100644
--- a/src/index.css
+++ b/src/index.css
@@ -30,3 +30,7 @@ a {
.MuiButton-contained:hover {
background-color: rgb(118, 126, 168) !important;
}
+
+.Mui-focused .MuiOutlinedInput-notchedOutline {
+ /*color: #aab5f1*/
+}
diff --git a/src/loadYml.ts b/src/loadYml.ts
index 6b8bfb7..0afe03e 100644
--- a/src/loadYml.ts
+++ b/src/loadYml.ts
@@ -71,7 +71,6 @@ export interface Definition {
export function Json2Preview(definition?: Definition): string {
if (!definition) return '';
try {
- console.log(transformDSL(definition));
return compress(transformDSL(definition), '/svg/');
} catch (e) {
console.error(e);
diff --git a/src/transform.ts b/src/transform.ts
index 940bf73..ed14765 100644
--- a/src/transform.ts
+++ b/src/transform.ts
@@ -1,13 +1,12 @@
import { Action, Definition, State } from "./loadYml";
-const EVENT_COLOR = "#LightYellow";
-const HTTP_COLOR = "#Peru";
-const SCRIPT_COLOR = "#Olive;text:white";
-const BOT_COLOR = "#Blue;text:white";
-const EMAIL_SENDER_COLOR = "#Red;text:white";
-const CHAT_BOT_COLOR = "#Orange;text:white";
-const GLIP_COLOR = "#Pink;text:white";
-const DEFAULT_COLOR = '#Grey;text;white';
+const EVENT_COLOR = "#IndianRed";
+const HTTP_COLOR = "#Sienna";
+const SCRIPT_COLOR = "#Olive";
+const BOT_COLOR = "#RoyalBlue";
+const EMAIL_SENDER_COLOR = "#Crimson";
+const CHAT_BOT_COLOR = "#OrangeRed";
+const GLIP_COLOR = "#DeepPink";
const EVENT_NAME = ": Event";
const HTTP_NAME = ": Http";
@@ -15,33 +14,28 @@ const SCRIPT_NAME = ": Script";
const BOT_NAME = ": Chat";
const EMAIL_SENDER_NAME = ": EmailSender";
const GLIP_SENDER_NAME = ': GlipSender';
-const EXIT_NAME = ": Exit";
-function isHttp(actions: Action[]): boolean {
+export function isHttp(actions: Action[]): boolean {
return actions
.some((action) => action.actionType === "HttpRequest");
}
-function isScript(actions: Action[]): boolean {
+export function isScript(actions: Action[]): boolean {
return actions
.some((action) => action.actionType === "Script");
}
-function isChat(actions: Action[]): boolean {
+export function isChat(actions: Action[]): boolean {
return actions
.some((action) => action.actionType === 'ChatBot');
}
-function isGlipSender(actions: Action[]): boolean {
+export function isGlipSender(actions: Action[]): boolean {
return actions
.some((action) => action.actionType === 'GlipSender');
}
-function isExit(actions: Action[]): boolean {
- return actions.some((action) => action.actionType === 'Exit');
-}
-
-function isEmailSender(actions: Action[]): boolean {
+export function isEmailSender(actions: Action[]): boolean {
return actions
.some((action) => action.actionType === "EmailSender");
}
@@ -188,8 +182,22 @@ export function transformDSL(definition: Definition): string {
sb += drawStateLine(eventState, state) || '';
}
return `@startuml
-
+ skinparam backgroundColor #242425
+ skinparam state {
+ FontColor white
+ BackgroundColor DimGray
+ BorderColor #AAB5F1
+ ArrowColor #AAB5F1
+ ArrowFontColor #AAB5F1
+ }
+
+ skinparam activity {
+ StartColor Silver
+ EndColor Silver
+ }
+
${sb}
+
@enduml
`;
}