diff --git a/.flake8 b/.flake8 index 4b852abd7..06fe235c0 100644 --- a/.flake8 +++ b/.flake8 @@ -25,6 +25,7 @@ ignore = W503, W504, F403, + F811, B007, B950, W191, diff --git a/.github/helper/flake8.conf b/.github/helper/flake8.conf index 8a97e17c9..e6f31158d 100644 --- a/.github/helper/flake8.conf +++ b/.github/helper/flake8.conf @@ -57,6 +57,7 @@ ignore = F401, F403, F405, + F811, W191, W291, W292, diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 696d9596f..627715b63 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -18,7 +18,8 @@ const NO_CACHE_KEYS = [ "frappe.desk.search.search_link", "frappe.model.workflow.get_transitions", "frappe.desk.reportview.get_count", - "frappe.core.doctype.server_script.server_script.enabled" + "frappe.core.doctype.server_script.server_script.enabled", + "raven.api.message_actions.get_action_defaults" ] @@ -80,21 +81,17 @@ const router = createBrowserRouter( import('./pages/settings/ServerScripts/SchedulerEvents/CreateSchedulerEvent')} /> import('./pages/settings/ServerScripts/SchedulerEvents/ViewSchedulerEvent')} /> + + + import('./pages/settings/MessageActions/MessageActionList')} /> + import('./pages/settings/MessageActions/CreateMessageAction')} /> + import('./pages/settings/MessageActions/ViewMessageAction')} /> + import('@/pages/ChatSpace')}> import('./components/feature/threads/ThreadDrawer/ThreadDrawer')} /> - {/* import('./pages/settings/Settings')}> - - import('./pages/settings/Webhooks/WebhookList')} /> - import('./pages/settings/Webhooks/CreateWebhook')} /> - import('./pages/settings/Webhooks/ViewWebhook')} /> - import('./pages/settings/ServerScripts/SchedulerEvents/SchedulerEvents')} /> - import('./pages/settings/ServerScripts/SchedulerEvents/CreateSchedulerEvent')} /> - import('./pages/settings/ServerScripts/SchedulerEvents/ViewSchedulerEvent')} /> - - */} import('./pages/NotFound')} /> diff --git a/frontend/src/components/feature/CommandMenu/CommandMenu.tsx b/frontend/src/components/feature/CommandMenu/CommandMenu.tsx index cb505be87..939198045 100644 --- a/frontend/src/components/feature/CommandMenu/CommandMenu.tsx +++ b/frontend/src/components/feature/CommandMenu/CommandMenu.tsx @@ -6,8 +6,6 @@ import './commandMenu.styles.css' import ChannelList from './ChannelList' import UserList from './UserList' import clsx from 'clsx' -import { BiCog, BiFile, BiMoon, BiSearch, BiSmile } from 'react-icons/bi' -import ArchivedChannelList from './ArchivedChannelList' import { atom, useAtom } from 'jotai' import { useIsDesktop } from '@/hooks/useMediaQuery' import { Drawer, DrawerContent } from '@/components/layout/Drawer' diff --git a/frontend/src/components/feature/CommandMenu/SettingsList.tsx b/frontend/src/components/feature/CommandMenu/SettingsList.tsx index adc0cb403..b39d3341e 100644 --- a/frontend/src/components/feature/CommandMenu/SettingsList.tsx +++ b/frontend/src/components/feature/CommandMenu/SettingsList.tsx @@ -1,6 +1,6 @@ import { Command } from 'cmdk' import { useSetAtom } from 'jotai' -import { BiBot, BiFile, BiGroup, BiMessageSquareDots, BiUserCircle } from 'react-icons/bi' +import { BiBoltCircle, BiBot, BiFile, BiGroup, BiMessageSquareDots, BiTime, BiUserCircle } from 'react-icons/bi' import { useNavigate } from 'react-router-dom' import { commandMenuOpenAtom } from './CommandMenu' import { PiOpenAiLogo } from 'react-icons/pi' @@ -47,12 +47,17 @@ const SettingsList = (props: Props) => { HR + + + Message Actions + + - + Scheduled Messages - + Webhooks diff --git a/frontend/src/components/feature/chat/ChatMessage/MessageActions/MessageActionSubMenu.tsx b/frontend/src/components/feature/chat/ChatMessage/MessageActions/MessageActionSubMenu.tsx new file mode 100644 index 000000000..25e3cef96 --- /dev/null +++ b/frontend/src/components/feature/chat/ChatMessage/MessageActions/MessageActionSubMenu.tsx @@ -0,0 +1,65 @@ +import { ContextMenu, Flex, Text } from '@radix-ui/themes' +import { BiBoltCircle } from 'react-icons/bi' +import { useFrappeGetDocList } from 'frappe-react-sdk' +import { RavenMessageAction } from '@/types/RavenIntegrations/RavenMessageAction' +import { useSetAtom } from 'jotai' +import { messageActionAtom } from '@/components/feature/message-actions/MessageActionController' + +type Props = { + messageID: string, +} + +const MessageActionSubMenu = (props: Props) => { + return + + + + Actions + + + + + {/* + + + Create Action + + */} + + +} + +export default MessageActionSubMenu + + +const MessageActionSubMenuContent = (props: Props) => { + + const { data } = useFrappeGetDocList("Raven Message Action", { + fields: ['name', 'action_name'], + filters: [ + ['enabled', '=', 1] + ], + orderBy: { + field: 'action', + order: 'asc' + } + }, undefined, { + revalidateOnFocus: false, + }) + + const setMessageAction = useSetAtom(messageActionAtom) + + return <> + {data && data.length > 0 ? data?.map((action) => { + return setMessageAction({ actionID: action.name, messageID: props.messageID })}> + + {action.action_name} + + + }) + + : + No Actions Available + } + +} \ No newline at end of file diff --git a/frontend/src/components/feature/chat/ChatMessage/MessageActions/MessageActions.tsx b/frontend/src/components/feature/chat/ChatMessage/MessageActions/MessageActions.tsx index 7a224638a..db1419c18 100644 --- a/frontend/src/components/feature/chat/ChatMessage/MessageActions/MessageActions.tsx +++ b/frontend/src/components/feature/chat/ChatMessage/MessageActions/MessageActions.tsx @@ -12,6 +12,7 @@ import { AiOutlineEdit } from 'react-icons/ai' import { LuForward, LuReply } from 'react-icons/lu' import { MdOutlineEmojiEmotions } from "react-icons/md"; import { CreateThreadContextItem } from './QuickActions/CreateThreadButton' +import MessageActionSubMenu from './MessageActionSubMenu' export interface MessageContextMenuProps { message?: Message | null, @@ -103,6 +104,8 @@ export const MessageContextMenu = ({ message, onDelete, onEdit, onReply, onForwa } + + {isOwner && {message.message_type === 'Text' && diff --git a/frontend/src/components/feature/message-actions/MessageActionController.tsx b/frontend/src/components/feature/message-actions/MessageActionController.tsx new file mode 100644 index 000000000..c79be5249 --- /dev/null +++ b/frontend/src/components/feature/message-actions/MessageActionController.tsx @@ -0,0 +1,30 @@ +import { atom, useAtom } from 'jotai' +import MessageActionModal from './MessageActionModal' + +type MessageActionAtomType = { + actionID: string, + messageID: string +} +export const messageActionAtom = atom({ + actionID: '', + messageID: '' +}) + +const MessageActionController = () => { + + const [messageAction, setMessageAction] = useAtom(messageActionAtom) + + const closeMessageAction = () => { + setMessageAction({ actionID: '', messageID: '' }) + } + + return ( + + ) +} + +export default MessageActionController \ No newline at end of file diff --git a/frontend/src/components/feature/message-actions/MessageActionForm.tsx b/frontend/src/components/feature/message-actions/MessageActionForm.tsx new file mode 100644 index 000000000..4771a9eb8 --- /dev/null +++ b/frontend/src/components/feature/message-actions/MessageActionForm.tsx @@ -0,0 +1,196 @@ +import { ErrorText, HelperText, Label } from '@/components/common/Form' +import LinkFormField from '@/components/common/LinkField/LinkFormField' +import { HStack, Stack } from '@/components/layout/Stack' +import { RavenMessageAction } from '@/types/RavenIntegrations/RavenMessageAction' +import { Box, Checkbox, Grid, Select, Text, TextArea, TextField } from '@radix-ui/themes' +import { Tabs } from '@radix-ui/themes' +import { ChangeEvent } from 'react' +import { Controller, useFormContext } from 'react-hook-form' +import { BiBoltCircle } from 'react-icons/bi' +import { LuVariable } from 'react-icons/lu' +import MessageActionVariableBuilder from './MessageActionVariableBuilder' + +const ICON_PROPS = { + size: 18, + className: 'mr-1.5' +} + + +const MessageActionForm = () => { + return ( + + + General + Fields + + + + + + + + + + + ) +} + +export default MessageActionForm + + +const GeneralTab = () => { + const { register, control, formState: { errors }, setValue, watch } = useFormContext() + + const action = watch('action') + + const onActionChange = (event: ChangeEvent) => { + + if (event.target.value !== 'Custom Function') { + setValue('custom_function_path', '') + } + + if (event.target.value !== "Create Document") { + setValue('document_type', '') + } + } + return + + + + + + { + setValue('title', e.target.value.trim()) + } + })} + placeholder="Create support ticket" + aria-invalid={errors.action_name ? 'true' : 'false'} + /> + + {errors.action_name && {errors.action_name?.message}} + + + + + ( + field.onChange(value)}> + + + Create Document + Custom Function + + + )} + /> + + {errors.action && {errors.action?.message}} + + {action === "Create Document" && + + + The document you want this action to create. + + {errors.document_type && {errors.document_type?.message}} + } + + {action === 'Custom Function' && + + +