update button based on state

This commit is contained in:
2025-09-24 11:57:26 -05:00
parent 0acfcc0d08
commit b120f85ccd
2 changed files with 259 additions and 216 deletions

View File

@@ -324,6 +324,7 @@ const AsyncChat = ({
<InputAdornment position="end">
<Button
component="label"
color={formik.values.file ? "success" : "inherit"}
startIcon={<AttachFile />}
role={undefined}
tabIndex={-1}

View File

@@ -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 { useMaterialUIController } from "../../ui-kit/context"
import { useContext, useEffect, useRef, useState } from "react"
import MDBox from "../../ui-kit/components/MDBox";
import { useMaterialUIController } from "../../ui-kit/context";
import { useContext, useEffect, useRef, useState } from "react";
// Images
import MDTypography from "../../ui-kit/components/MDTypography"
import { CardFooter } from "react-bootstrap"
import MDInput from "../../ui-kit/components/MDInput"
import { ErrorMessage, Field, Form, Formik } from "formik"
import MDButton from "../../ui-kit/components/MDButton"
import { AttachFile, Send } from "@mui/icons-material"
import Header2 from "../../components/Header2/Header2"
import DashboardWrapperLayout from "../../components/DashboardWrapperLayout/DashboardWrapperLayout"
import * as Yup from 'yup';
import { Announcement, AnnouncementType, Conversation, ConversationPrompt, ConversationPromptType, ConversationType } from "../../data"
import { axiosInstance } from "../../../axiosApi"
import { AxiosResponse } from "axios"
import { ConversationContext } from "../../contexts/ConversationContext"
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"
import MDTypography from "../../ui-kit/components/MDTypography";
import { CardFooter } from "react-bootstrap";
import MDInput from "../../ui-kit/components/MDInput";
import { ErrorMessage, Field, Form, Formik } from "formik";
import MDButton from "../../ui-kit/components/MDButton";
import { AttachFile, Send } from "@mui/icons-material";
import Header2 from "../../components/Header2/Header2";
import DashboardWrapperLayout from "../../components/DashboardWrapperLayout/DashboardWrapperLayout";
import * as Yup from "yup";
import {
Announcement,
AnnouncementType,
Conversation,
ConversationPrompt,
ConversationPromptType,
ConversationType,
} from "../../data";
import { axiosInstance } from "../../../axiosApi";
import { AxiosResponse } from "axios";
import { ConversationContext } from "../../contexts/ConversationContext";
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= {
response: string
index: number
type RenderMessageProps = {
response: string;
index: number;
};
type AsyncChatProps = {
selectedConversation: number | undefined
conversationTitle: string
conversations: Conversation[]
setConversations: React.Dispatch<React.SetStateAction<Conversation[]>>
setSelectedConversation: React.Dispatch<React.SetStateAction<number | undefined>>
drawerWidth: number;
}
selectedConversation: number | undefined;
conversationTitle: string;
conversations: Conversation[];
setConversations: React.Dispatch<React.SetStateAction<Conversation[]>>;
setSelectedConversation: React.Dispatch<
React.SetStateAction<number | undefined>
>;
drawerWidth: number;
};
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')({
clip: 'rect(0 0 0 0)',
clipPath: 'inset(50%)',
const VisuallyHiddenInput = styled("input")({
clip: "rect(0 0 0 0)",
clipPath: "inset(50%)",
height: 1,
overflow: 'hidden',
position: 'absolute',
overflow: "hidden",
position: "absolute",
bottom: 0,
left: 0,
whiteSpace: 'nowrap',
whiteSpace: "nowrap",
width: 1,
});
@@ -67,22 +86,21 @@ type PromptValues = {
file: Blob | null;
fileType: string | null;
modelName: string;
};
const models: CustomSelectItem[] = [
{
label: "General",
value: "GENERAL"
value: "GENERAL",
},
{
label: "Code",
value: "CODE"
value: "CODE",
},
{
label: "Reasoning",
value: "REASONING"
}
value: "REASONING",
},
];
const AlwaysScrollToBottom = (): JSX.Element => {
@@ -91,182 +109,203 @@ const AlwaysScrollToBottom = (): JSX.Element => {
return <div ref={elementRef} />;
};
const AsyncDashboardInner =({}): JSX.Element => {
const AsyncDashboardInner = ({}): JSX.Element => {
const [controller, dispatch] = useMaterialUIController();
const {
darkMode,
} = controller;
const buttonColor = darkMode? 'dark' : 'light';
const [announcements, setAnnouncement] = useState<Announcement[]>([]);
const [subscribe, unsubscribe, socket, sendMessage] = useContext(WebSocketContext)
const { account } = useContext(AccountContext)
const { darkMode } = controller;
const buttonColor = darkMode ? "dark" : "light";
const [announcements, setAnnouncement] = useState<Announcement[]>([]);
const [subscribe, unsubscribe, socket, sendMessage] =
useContext(WebSocketContext);
const { account } = useContext(AccountContext);
const [isClosing, setIsClosing] = useState(false);
const {conversations, selectedConversation, setSelectedConversation} = useContext(ConversationContext);
const [isClosing, setIsClosing] = useState(false);
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((status, message) => new Announcement({
async function GetAnnouncements() {
const response: AxiosResponse<AnnouncementType[]> =
await axiosInstance.get("announcment/get/");
setAnnouncement(
response.data.map(
(status, message) =>
new Announcement({
status: status,
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
}
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 }),
];
return(
<DashboardLayout>
<Header2 />
<MDBox sx={{mt:5}}>
conversationRef.current = tempConversations;
</MDBox>1
<MDBox sx={{ margin: '0 auto', width: '80%', height: '80%', minHeight: '80%', maxHeight: '80%', align:'center'}}>
<Card>
<CardContent>
<MDTypography variant="h3" >
{conversationTitle}
setConversationDetails(tempConversations);
// TODO: add the file here
</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>
sendMessage(prompt, selectedConversation, file, fileType, modelName);
resetForm();
} catch (e) {
console.log(`error ${e}`);
// TODO: make this user friendly
}
};
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
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
{/* <MDInput
label="Prompt"
/> */}
</CardFooter>
</Card>
<Footer />
</MDBox>
</DashboardLayout>
)
}
</CardFooter>
</Card>
<Footer />
</MDBox>
</DashboardLayout>
);
};
const AsyncDashboard2 = ({}): JSX.Element => {
return(
return (
<DashboardWrapperLayout>
<AsyncDashboardInner />
</DashboardWrapperLayout>
);
};
<<<<<<< HEAD
<DashboardWrapperLayout>
<AsyncDashboardInner />
@@ -279,3 +318,6 @@ const AsyncDashboard2 = ({}): JSX.Element => {
}
export default AsyncDashboard2
=======
export default AsyncDashboard2;
>>>>>>> b24fbf2 (update button based on state)