update button based on state
This commit is contained in:
@@ -324,6 +324,7 @@ const AsyncChat = ({
|
|||||||
<InputAdornment position="end">
|
<InputAdornment position="end">
|
||||||
<Button
|
<Button
|
||||||
component="label"
|
component="label"
|
||||||
|
color={formik.values.file ? "success" : "inherit"}
|
||||||
startIcon={<AttachFile />}
|
startIcon={<AttachFile />}
|
||||||
role={undefined}
|
role={undefined}
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
|
|||||||
@@ -1,64 +1,83 @@
|
|||||||
import { Card, CardContent, Divider, InputAdornment, MenuItem, Select, } from "@mui/material"
|
import {
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
Divider,
|
||||||
|
InputAdornment,
|
||||||
|
MenuItem,
|
||||||
|
Select,
|
||||||
|
} from "@mui/material";
|
||||||
|
|
||||||
import DashboardLayout from "../../ui-kit/examples/LayoutContainers/DashboardLayout"
|
import DashboardLayout from "../../ui-kit/examples/LayoutContainers/DashboardLayout";
|
||||||
|
|
||||||
import MDBox from "../../ui-kit/components/MDBox"
|
import MDBox from "../../ui-kit/components/MDBox";
|
||||||
import { useMaterialUIController } from "../../ui-kit/context"
|
import { useMaterialUIController } from "../../ui-kit/context";
|
||||||
import { useContext, useEffect, useRef, useState } from "react"
|
import { useContext, useEffect, useRef, useState } from "react";
|
||||||
|
|
||||||
// Images
|
// Images
|
||||||
import MDTypography from "../../ui-kit/components/MDTypography"
|
import MDTypography from "../../ui-kit/components/MDTypography";
|
||||||
import { CardFooter } from "react-bootstrap"
|
import { CardFooter } from "react-bootstrap";
|
||||||
import MDInput from "../../ui-kit/components/MDInput"
|
import MDInput from "../../ui-kit/components/MDInput";
|
||||||
import { ErrorMessage, Field, Form, Formik } from "formik"
|
import { ErrorMessage, Field, Form, Formik } from "formik";
|
||||||
import MDButton from "../../ui-kit/components/MDButton"
|
import MDButton from "../../ui-kit/components/MDButton";
|
||||||
import { AttachFile, Send } from "@mui/icons-material"
|
import { AttachFile, Send } from "@mui/icons-material";
|
||||||
import Header2 from "../../components/Header2/Header2"
|
import Header2 from "../../components/Header2/Header2";
|
||||||
import DashboardWrapperLayout from "../../components/DashboardWrapperLayout/DashboardWrapperLayout"
|
import DashboardWrapperLayout from "../../components/DashboardWrapperLayout/DashboardWrapperLayout";
|
||||||
import * as Yup from 'yup';
|
import * as Yup from "yup";
|
||||||
import { Announcement, AnnouncementType, Conversation, ConversationPrompt, ConversationPromptType, ConversationType } from "../../data"
|
import {
|
||||||
import { axiosInstance } from "../../../axiosApi"
|
Announcement,
|
||||||
import { AxiosResponse } from "axios"
|
AnnouncementType,
|
||||||
import { ConversationContext } from "../../contexts/ConversationContext"
|
Conversation,
|
||||||
import Markdown from "markdown-to-jsx"
|
ConversationPrompt,
|
||||||
import ConversationDetailCard from "../../components/ConversationDetailCard/ConversationDetailCard"
|
ConversationPromptType,
|
||||||
import { WebSocketContext } from "../../contexts/WebSocketContext"
|
ConversationType,
|
||||||
import { AccountContext } from "../../contexts/AccountContext"
|
} from "../../data";
|
||||||
import { styled } from '@mui/material/styles';
|
import { axiosInstance } from "../../../axiosApi";
|
||||||
import Footer from "../../components/Footer/Footer"
|
import { AxiosResponse } from "axios";
|
||||||
import { MessageContext } from "../../contexts/MessageContext"
|
import { ConversationContext } from "../../contexts/ConversationContext";
|
||||||
import CustomSelect, { CustomSelectItem } from "../../components/CustomSelect/CustomSelect"
|
import Markdown from "markdown-to-jsx";
|
||||||
|
import ConversationDetailCard from "../../components/ConversationDetailCard/ConversationDetailCard";
|
||||||
|
import { WebSocketContext } from "../../contexts/WebSocketContext";
|
||||||
|
import { AccountContext } from "../../contexts/AccountContext";
|
||||||
|
import { styled } from "@mui/material/styles";
|
||||||
|
import Footer from "../../components/Footer/Footer";
|
||||||
|
import { MessageContext } from "../../contexts/MessageContext";
|
||||||
|
import CustomSelect, {
|
||||||
|
CustomSelectItem,
|
||||||
|
} from "../../components/CustomSelect/CustomSelect";
|
||||||
|
|
||||||
const MODELS = ["Turbo","RAG"]
|
const MODELS = ["Turbo", "RAG"];
|
||||||
|
|
||||||
type RenderMessageProps= {
|
type RenderMessageProps = {
|
||||||
response: string
|
response: string;
|
||||||
index: number
|
index: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type AsyncChatProps = {
|
type AsyncChatProps = {
|
||||||
selectedConversation: number | undefined
|
selectedConversation: number | undefined;
|
||||||
conversationTitle: string
|
conversationTitle: string;
|
||||||
conversations: Conversation[]
|
conversations: Conversation[];
|
||||||
setConversations: React.Dispatch<React.SetStateAction<Conversation[]>>
|
setConversations: React.Dispatch<React.SetStateAction<Conversation[]>>;
|
||||||
setSelectedConversation: React.Dispatch<React.SetStateAction<number | undefined>>
|
setSelectedConversation: React.Dispatch<
|
||||||
drawerWidth: number;
|
React.SetStateAction<number | undefined>
|
||||||
}
|
>;
|
||||||
|
drawerWidth: number;
|
||||||
|
};
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
prompt: Yup.string().min(1, "Need to have at least one character").required("This is requried")
|
prompt: Yup.string()
|
||||||
}
|
.min(1, "Need to have at least one character")
|
||||||
)
|
.required("This is requried"),
|
||||||
|
});
|
||||||
|
|
||||||
const VisuallyHiddenInput = styled('input')({
|
const VisuallyHiddenInput = styled("input")({
|
||||||
clip: 'rect(0 0 0 0)',
|
clip: "rect(0 0 0 0)",
|
||||||
clipPath: 'inset(50%)',
|
clipPath: "inset(50%)",
|
||||||
height: 1,
|
height: 1,
|
||||||
overflow: 'hidden',
|
overflow: "hidden",
|
||||||
position: 'absolute',
|
position: "absolute",
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
whiteSpace: 'nowrap',
|
whiteSpace: "nowrap",
|
||||||
width: 1,
|
width: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -67,22 +86,21 @@ type PromptValues = {
|
|||||||
file: Blob | null;
|
file: Blob | null;
|
||||||
fileType: string | null;
|
fileType: string | null;
|
||||||
modelName: string;
|
modelName: string;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const models: CustomSelectItem[] = [
|
const models: CustomSelectItem[] = [
|
||||||
{
|
{
|
||||||
label: "General",
|
label: "General",
|
||||||
value: "GENERAL"
|
value: "GENERAL",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Code",
|
label: "Code",
|
||||||
value: "CODE"
|
value: "CODE",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Reasoning",
|
label: "Reasoning",
|
||||||
value: "REASONING"
|
value: "REASONING",
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const AlwaysScrollToBottom = (): JSX.Element => {
|
const AlwaysScrollToBottom = (): JSX.Element => {
|
||||||
@@ -91,182 +109,203 @@ const AlwaysScrollToBottom = (): JSX.Element => {
|
|||||||
return <div ref={elementRef} />;
|
return <div ref={elementRef} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
const AsyncDashboardInner =({}): JSX.Element => {
|
const AsyncDashboardInner = ({}): JSX.Element => {
|
||||||
const [controller, dispatch] = useMaterialUIController();
|
const [controller, dispatch] = useMaterialUIController();
|
||||||
const {
|
const { darkMode } = controller;
|
||||||
darkMode,
|
const buttonColor = darkMode ? "dark" : "light";
|
||||||
} = controller;
|
const [announcements, setAnnouncement] = useState<Announcement[]>([]);
|
||||||
const buttonColor = darkMode? 'dark' : 'light';
|
const [subscribe, unsubscribe, socket, sendMessage] =
|
||||||
const [announcements, setAnnouncement] = useState<Announcement[]>([]);
|
useContext(WebSocketContext);
|
||||||
const [subscribe, unsubscribe, socket, sendMessage] = useContext(WebSocketContext)
|
const { account } = useContext(AccountContext);
|
||||||
const { account } = useContext(AccountContext)
|
|
||||||
|
|
||||||
const [isClosing, setIsClosing] = useState(false);
|
const [isClosing, setIsClosing] = useState(false);
|
||||||
const {conversations, selectedConversation, setSelectedConversation} = useContext(ConversationContext);
|
const { conversations, selectedConversation, setSelectedConversation } =
|
||||||
|
useContext(ConversationContext);
|
||||||
|
|
||||||
|
const {
|
||||||
|
conversationDetails,
|
||||||
|
setConversationDetails,
|
||||||
|
stateMessage,
|
||||||
|
isGeneratingMessage,
|
||||||
|
} = useContext(MessageContext);
|
||||||
|
|
||||||
const {conversationDetails, setConversationDetails, stateMessage, isGeneratingMessage} = useContext(MessageContext);
|
const conversationRef = useRef(conversationDetails);
|
||||||
|
|
||||||
const conversationRef = useRef(conversationDetails)
|
async function GetAnnouncements() {
|
||||||
|
const response: AxiosResponse<AnnouncementType[]> =
|
||||||
|
await axiosInstance.get("announcment/get/");
|
||||||
|
setAnnouncement(
|
||||||
|
response.data.map(
|
||||||
async function GetAnnouncements(){
|
(status, message) =>
|
||||||
const response: AxiosResponse<AnnouncementType[]> = await axiosInstance.get('announcment/get/')
|
new Announcement({
|
||||||
setAnnouncement(response.data.map((status, message) => new Announcement({
|
|
||||||
status: status,
|
status: status,
|
||||||
message: message
|
message: message,
|
||||||
})))
|
}),
|
||||||
|
),
|
||||||
}
|
);
|
||||||
|
|
||||||
const conversationTitle = conversations.find(item => item.id === selectedConversation)?.title ?? 'New Conversation';
|
|
||||||
const colorName = darkMode ? 'light' : 'dark';
|
|
||||||
|
|
||||||
|
|
||||||
const handlePromptSubmit = async ({prompt, file, fileType, modelName}: PromptValues, {resetForm}: any): Promise<void> => {
|
|
||||||
|
|
||||||
// send the prompt to be saved
|
|
||||||
try{
|
|
||||||
const tempConversations: ConversationPrompt[] = [...conversationDetails, new ConversationPrompt({message: prompt, user_created:true}), new ConversationPrompt({message: '', user_created:false})]
|
|
||||||
|
|
||||||
conversationRef.current = tempConversations
|
|
||||||
|
|
||||||
setConversationDetails(tempConversations)
|
|
||||||
// TODO: add the file here
|
|
||||||
|
|
||||||
sendMessage(prompt, selectedConversation, file, fileType, modelName)
|
|
||||||
resetForm();
|
|
||||||
|
|
||||||
|
|
||||||
}catch(e){
|
|
||||||
console.log(`error ${e}`)
|
|
||||||
// TODO: make this user friendly
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const conversationTitle =
|
||||||
|
conversations.find((item) => item.id === selectedConversation)?.title ??
|
||||||
|
"New Conversation";
|
||||||
|
const colorName = darkMode ? "light" : "dark";
|
||||||
|
|
||||||
|
const handlePromptSubmit = async (
|
||||||
|
{ prompt, file, fileType, modelName }: PromptValues,
|
||||||
|
{ resetForm }: any,
|
||||||
|
): Promise<void> => {
|
||||||
|
// send the prompt to be saved
|
||||||
|
try {
|
||||||
|
const tempConversations: ConversationPrompt[] = [
|
||||||
|
...conversationDetails,
|
||||||
|
new ConversationPrompt({ message: prompt, user_created: true }),
|
||||||
|
new ConversationPrompt({ message: "", user_created: false }),
|
||||||
|
];
|
||||||
|
|
||||||
return(
|
conversationRef.current = tempConversations;
|
||||||
<DashboardLayout>
|
|
||||||
<Header2 />
|
|
||||||
<MDBox sx={{mt:5}}>
|
|
||||||
|
|
||||||
</MDBox>1
|
setConversationDetails(tempConversations);
|
||||||
<MDBox sx={{ margin: '0 auto', width: '80%', height: '80%', minHeight: '80%', maxHeight: '80%', align:'center'}}>
|
// TODO: add the file here
|
||||||
<Card>
|
|
||||||
<CardContent>
|
|
||||||
<MDTypography variant="h3" >
|
|
||||||
{conversationTitle}
|
|
||||||
|
|
||||||
</MDTypography>
|
sendMessage(prompt, selectedConversation, file, fileType, modelName);
|
||||||
</CardContent>
|
resetForm();
|
||||||
<Divider />
|
} catch (e) {
|
||||||
<CardContent>
|
console.log(`error ${e}`);
|
||||||
<>
|
// TODO: make this user friendly
|
||||||
{conversationDetails.length > 0 ?
|
}
|
||||||
conversationDetails.map((convo_detail) =>
|
};
|
||||||
convo_detail.message.length >0 ?
|
|
||||||
<ConversationDetailCard message={convo_detail.message} user_created={convo_detail.user_created} key={convo_detail.id}/> :
|
|
||||||
<ConversationDetailCard message={stateMessage} user_created={convo_detail.user_created} key={convo_detail.id}/>
|
|
||||||
)
|
|
||||||
:
|
|
||||||
<Markdown className='text-center' color='inherit'>Either select a previous conversation on start a new one.</Markdown>
|
|
||||||
}
|
|
||||||
<AlwaysScrollToBottom/>
|
|
||||||
</>
|
|
||||||
</CardContent>
|
|
||||||
<Divider />
|
|
||||||
<CardFooter>
|
|
||||||
<Formik
|
|
||||||
initialValues={{
|
|
||||||
prompt: '',
|
|
||||||
file: null,
|
|
||||||
fileType: null,
|
|
||||||
modelName: '',
|
|
||||||
}}
|
|
||||||
validationSchema={validationSchema}
|
|
||||||
onSubmit={handlePromptSubmit}
|
|
||||||
>
|
|
||||||
{(formik)=>
|
|
||||||
<Form>
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DashboardLayout>
|
||||||
|
<Header2 />
|
||||||
|
<MDBox sx={{ mt: 5 }}></MDBox>1
|
||||||
|
<MDBox
|
||||||
|
sx={{
|
||||||
|
margin: "0 auto",
|
||||||
|
width: "80%",
|
||||||
|
height: "80%",
|
||||||
|
minHeight: "80%",
|
||||||
|
maxHeight: "80%",
|
||||||
|
align: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Card>
|
||||||
|
<CardContent>
|
||||||
|
<MDTypography variant="h3">{conversationTitle}</MDTypography>
|
||||||
|
</CardContent>
|
||||||
|
<Divider />
|
||||||
|
<CardContent>
|
||||||
|
<>
|
||||||
|
{conversationDetails.length > 0 ? (
|
||||||
|
conversationDetails.map((convo_detail) =>
|
||||||
|
convo_detail.message.length > 0 ? (
|
||||||
|
<ConversationDetailCard
|
||||||
|
message={convo_detail.message}
|
||||||
|
user_created={convo_detail.user_created}
|
||||||
|
key={convo_detail.id}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<ConversationDetailCard
|
||||||
|
message={stateMessage}
|
||||||
|
user_created={convo_detail.user_created}
|
||||||
|
key={convo_detail.id}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<Markdown className="text-center" color="inherit">
|
||||||
|
Either select a previous conversation on start a new one.
|
||||||
|
</Markdown>
|
||||||
|
)}
|
||||||
|
<AlwaysScrollToBottom />
|
||||||
|
</>
|
||||||
|
</CardContent>
|
||||||
|
<Divider />
|
||||||
|
<CardFooter>
|
||||||
|
<Formik
|
||||||
|
initialValues={{
|
||||||
|
prompt: "",
|
||||||
|
file: null,
|
||||||
|
fileType: null,
|
||||||
|
modelName: "",
|
||||||
|
}}
|
||||||
|
validationSchema={validationSchema}
|
||||||
|
onSubmit={handlePromptSubmit}
|
||||||
|
>
|
||||||
|
{(formik) => (
|
||||||
|
<Form>
|
||||||
|
<Field
|
||||||
|
name={"prompt"}
|
||||||
|
fullWidth
|
||||||
|
as={MDInput}
|
||||||
|
label={"Prompt"}
|
||||||
|
errorstring={<ErrorMessage name={"prompt"} />}
|
||||||
|
size={"large"}
|
||||||
|
role={undefined}
|
||||||
|
tabIndex={-1}
|
||||||
|
variant={"outlined"}
|
||||||
|
InputProps={{
|
||||||
|
endAdornment: (
|
||||||
|
<InputAdornment position="end">
|
||||||
|
<MDButton
|
||||||
|
component="label"
|
||||||
|
startIcon={<AttachFile />}
|
||||||
|
role={undefined}
|
||||||
|
tabIndex={-1}
|
||||||
|
color={formik.values.file ? "dark" : "light"}
|
||||||
|
>
|
||||||
|
<VisuallyHiddenInput
|
||||||
|
type="file"
|
||||||
|
accept=".csv,.xlsx,.txt"
|
||||||
|
onChange={(event) => {
|
||||||
|
const file = event.target.files?.[0];
|
||||||
|
//console.log(file)
|
||||||
|
if (file) {
|
||||||
|
formik.setFieldValue("file", file);
|
||||||
|
formik.setFieldValue("fileType", file.type);
|
||||||
|
} else {
|
||||||
|
formik.setFieldValue("file", null);
|
||||||
|
formik.setFieldValue("fileType", null);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</MDButton>
|
||||||
|
<MDButton
|
||||||
|
type={"submit"}
|
||||||
|
startIcon={<Send />}
|
||||||
|
disabled={!formik.isValid}
|
||||||
|
color={buttonColor}
|
||||||
|
>
|
||||||
|
<></>
|
||||||
|
</MDButton>
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
></Field>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
|
||||||
<Field
|
{/* <MDInput
|
||||||
name={"prompt"}
|
|
||||||
fullWidth
|
|
||||||
as={MDInput}
|
|
||||||
label={'Prompt'}
|
|
||||||
errorstring={<ErrorMessage name={'prompt'}/>}
|
|
||||||
size={'large'}
|
|
||||||
role={undefined}
|
|
||||||
tabIndex={-1}
|
|
||||||
variant={"outlined"}
|
|
||||||
InputProps={{
|
|
||||||
endAdornment: (
|
|
||||||
<InputAdornment position='end'>
|
|
||||||
<MDButton
|
|
||||||
component="label"
|
|
||||||
startIcon={<AttachFile/>}
|
|
||||||
role={undefined}
|
|
||||||
tabIndex={-1}
|
|
||||||
color={buttonColor}
|
|
||||||
>
|
|
||||||
<VisuallyHiddenInput
|
|
||||||
type="file"
|
|
||||||
accept='.csv,.xlsx,.txt'
|
|
||||||
|
|
||||||
onChange={(event) => {
|
|
||||||
const file = event.target.files?.[0];
|
|
||||||
//console.log(file)
|
|
||||||
if (file) {
|
|
||||||
formik.setFieldValue('file',file)
|
|
||||||
formik.setFieldValue('fileType',file.type)
|
|
||||||
} else {
|
|
||||||
formik.setFieldValue('file',null)
|
|
||||||
formik.setFieldValue('fileType',null)
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</MDButton>
|
|
||||||
<MDButton
|
|
||||||
type={'submit'}
|
|
||||||
startIcon={<Send />}
|
|
||||||
disabled={!formik.isValid}
|
|
||||||
color={buttonColor}
|
|
||||||
>
|
|
||||||
<></>
|
|
||||||
</MDButton>
|
|
||||||
</InputAdornment>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
|
|
||||||
|
|
||||||
>
|
|
||||||
</Field>
|
|
||||||
</Form>
|
|
||||||
}
|
|
||||||
</Formik>
|
|
||||||
|
|
||||||
|
|
||||||
{/* <MDInput
|
|
||||||
label="Prompt"
|
label="Prompt"
|
||||||
/> */}
|
/> */}
|
||||||
</CardFooter>
|
</CardFooter>
|
||||||
</Card>
|
</Card>
|
||||||
<Footer />
|
<Footer />
|
||||||
</MDBox>
|
</MDBox>
|
||||||
|
</DashboardLayout>
|
||||||
</DashboardLayout>
|
);
|
||||||
)
|
};
|
||||||
}
|
|
||||||
|
|
||||||
const AsyncDashboard2 = ({}): JSX.Element => {
|
const AsyncDashboard2 = ({}): JSX.Element => {
|
||||||
return(
|
return (
|
||||||
|
<DashboardWrapperLayout>
|
||||||
|
<AsyncDashboardInner />
|
||||||
|
</DashboardWrapperLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
|
||||||
<DashboardWrapperLayout>
|
<DashboardWrapperLayout>
|
||||||
<AsyncDashboardInner />
|
<AsyncDashboardInner />
|
||||||
@@ -279,3 +318,6 @@ const AsyncDashboard2 = ({}): JSX.Element => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default AsyncDashboard2
|
export default AsyncDashboard2
|
||||||
|
=======
|
||||||
|
export default AsyncDashboard2;
|
||||||
|
>>>>>>> b24fbf2 (update button based on state)
|
||||||
|
|||||||
Reference in New Issue
Block a user