mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-29 16:43:16 +00:00
Merge pull request #929 from TomasMatarazzo/issue-button-to-clean-chat-history
Issue button to clean chat history
This commit is contained in:
@@ -37,6 +37,12 @@ def delete_conversation():
|
||||
|
||||
return {"status": "ok"}
|
||||
|
||||
@user.route("/api/delete_all_conversations", methods=["POST"])
|
||||
def delete_all_conversations():
|
||||
user_id = "local"
|
||||
conversations_collection.delete_many({"user":user_id})
|
||||
return {"status": "ok"}
|
||||
|
||||
@user.route("/api/get_conversations", methods=["get"])
|
||||
def get_conversations():
|
||||
# provides a list of conversations
|
||||
|
||||
@@ -58,4 +58,5 @@
|
||||
"vite": "^5.0.13",
|
||||
"vite-plugin-svgr": "^4.2.0"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,9 @@ interface ModalProps {
|
||||
modalState: string;
|
||||
isError: boolean;
|
||||
errorMessage?: string;
|
||||
textDelete?: boolean;
|
||||
}
|
||||
|
||||
const Modal = (props: ModalProps) => {
|
||||
return (
|
||||
<div
|
||||
@@ -23,7 +25,7 @@ const Modal = (props: ModalProps) => {
|
||||
onClick={() => props.handleSubmit()}
|
||||
className="ml-auto h-10 w-20 rounded-3xl bg-violet-800 text-white transition-all hover:bg-violet-700"
|
||||
>
|
||||
Save
|
||||
{props.textDelete ? 'Delete' : 'Save'}
|
||||
</button>
|
||||
{props.isCancellable && (
|
||||
<button
|
||||
|
||||
@@ -20,6 +20,8 @@ import Add from './assets/add.svg';
|
||||
import UploadIcon from './assets/upload.svg';
|
||||
import { ActiveState } from './models/misc';
|
||||
import APIKeyModal from './preferences/APIKeyModal';
|
||||
import DeleteConvModal from './preferences/DeleteConvModal';
|
||||
|
||||
import {
|
||||
selectApiKeyStatus,
|
||||
selectSelectedDocs,
|
||||
@@ -29,6 +31,8 @@ import {
|
||||
selectConversations,
|
||||
setConversations,
|
||||
selectConversationId,
|
||||
selectModalStateDeleteConv,
|
||||
setModalStateDeleteConv,
|
||||
} from './preferences/preferenceSlice';
|
||||
import {
|
||||
setConversation,
|
||||
@@ -66,7 +70,9 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
const docs = useSelector(selectSourceDocs);
|
||||
const selectedDocs = useSelector(selectSelectedDocs);
|
||||
const conversations = useSelector(selectConversations);
|
||||
const modalStateDeleteConv = useSelector(selectModalStateDeleteConv);
|
||||
const conversationId = useSelector(selectConversationId);
|
||||
|
||||
const { isMobile } = useMediaQuery();
|
||||
const [isDarkTheme] = useDarkTheme();
|
||||
const [isDocsListOpen, setIsDocsListOpen] = useState(false);
|
||||
@@ -92,6 +98,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
fetchConversations();
|
||||
}
|
||||
}, [conversations, dispatch]);
|
||||
|
||||
async function fetchConversations() {
|
||||
return await getConversations()
|
||||
.then((fetchedConversations) => {
|
||||
@@ -102,6 +109,16 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
});
|
||||
}
|
||||
|
||||
const handleDeleteAllConversations = () => {
|
||||
fetch(`${apiHost}/api/delete_all_conversations`, {
|
||||
method: 'POST',
|
||||
})
|
||||
.then(() => {
|
||||
fetchConversations();
|
||||
})
|
||||
.catch((error) => console.error(error));
|
||||
};
|
||||
|
||||
const handleDeleteConversation = (id: string) => {
|
||||
fetch(`${apiHost}/api/delete_conversation?id=${id}`, {
|
||||
method: 'POST',
|
||||
@@ -260,7 +277,9 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
<div className="mb-auto h-[56vh] overflow-y-auto overflow-x-hidden dark:text-white">
|
||||
{conversations && (
|
||||
<div>
|
||||
<p className="ml-6 mt-3 text-sm font-semibold">Chats</p>
|
||||
<div className=" my-auto mx-4 mt-2 flex h-6 items-center justify-between gap-4 rounded-3xl">
|
||||
<p className="my-auto ml-6 text-sm font-semibold">Chats</p>
|
||||
</div>
|
||||
<div className="conversations-container">
|
||||
{conversations?.map((conversation) => (
|
||||
<ConversationTile
|
||||
@@ -312,7 +331,6 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
</p>
|
||||
</NavLink>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2 border-b-[1.5px] py-2 dark:border-b-purple-taupe">
|
||||
<NavLink
|
||||
to="/about"
|
||||
@@ -370,6 +388,7 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<SelectDocsModal
|
||||
modalState={selectedDocsModalState}
|
||||
setModalState={setSelectedDocsModalState}
|
||||
@@ -380,6 +399,11 @@ export default function Navigation({ navOpen, setNavOpen }: NavigationProps) {
|
||||
setModalState={setApiKeyModalState}
|
||||
isCancellable={isApiKeySet}
|
||||
/>
|
||||
<DeleteConvModal
|
||||
modalState={modalStateDeleteConv}
|
||||
setModalState={setModalStateDeleteConv}
|
||||
handleDeleteAllConv={handleDeleteAllConversations}
|
||||
/>
|
||||
<Upload
|
||||
modalState={uploadModalState}
|
||||
setModalState={setUploadModalState}
|
||||
|
||||
63
frontend/src/preferences/DeleteConvModal.tsx
Normal file
63
frontend/src/preferences/DeleteConvModal.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
import { useRef } from 'react';
|
||||
import { ActiveState } from '../models/misc';
|
||||
import { useMediaQuery, useOutsideAlerter } from './../hooks';
|
||||
import Modal from '../Modal';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Action } from '@reduxjs/toolkit';
|
||||
|
||||
export default function DeleteConvModal({
|
||||
modalState,
|
||||
setModalState,
|
||||
handleDeleteAllConv,
|
||||
}: {
|
||||
modalState: ActiveState;
|
||||
setModalState: (val: ActiveState) => Action;
|
||||
handleDeleteAllConv: () => void;
|
||||
}) {
|
||||
const dispatch = useDispatch();
|
||||
const modalRef = useRef(null);
|
||||
const { isMobile } = useMediaQuery();
|
||||
|
||||
useOutsideAlerter(
|
||||
modalRef,
|
||||
() => {
|
||||
if (isMobile && modalState === 'ACTIVE') {
|
||||
dispatch(setModalState('INACTIVE'));
|
||||
}
|
||||
},
|
||||
[modalState],
|
||||
);
|
||||
|
||||
function handleSubmit() {
|
||||
handleDeleteAllConv();
|
||||
dispatch(setModalState('INACTIVE'));
|
||||
}
|
||||
|
||||
function handleCancel() {
|
||||
dispatch(setModalState('INACTIVE'));
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
handleCancel={handleCancel}
|
||||
isError={false}
|
||||
modalState={modalState}
|
||||
isCancellable={true}
|
||||
handleSubmit={handleSubmit}
|
||||
textDelete={true}
|
||||
render={() => {
|
||||
return (
|
||||
<article
|
||||
ref={modalRef}
|
||||
className="mx-auto mt-24 flex w-[90vw] max-w-lg flex-col gap-4 rounded-t-lg bg-white p-6 shadow-lg"
|
||||
>
|
||||
<p className="text-xl text-jet">
|
||||
Are you sure you want to delete all the conversations?
|
||||
</p>
|
||||
<p className="text-md leading-6 text-gray-500"></p>
|
||||
</article>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
import {
|
||||
PayloadAction,
|
||||
createListenerMiddleware,
|
||||
createSlice,
|
||||
isAnyOf,
|
||||
} from '@reduxjs/toolkit';
|
||||
import { Doc, setLocalApiKey, setLocalRecentDocs } from './preferenceApi';
|
||||
import { RootState } from '../store';
|
||||
import { ActiveState } from '../models/misc';
|
||||
|
||||
interface Preference {
|
||||
apiKey: string;
|
||||
@@ -13,6 +15,7 @@ interface Preference {
|
||||
chunks: string;
|
||||
sourceDocs: Doc[] | null;
|
||||
conversations: { name: string; id: string }[] | null;
|
||||
modalState: ActiveState;
|
||||
}
|
||||
|
||||
const initialState: Preference = {
|
||||
@@ -32,6 +35,7 @@ const initialState: Preference = {
|
||||
} as Doc,
|
||||
sourceDocs: null,
|
||||
conversations: null,
|
||||
modalState: 'INACTIVE',
|
||||
};
|
||||
|
||||
export const prefSlice = createSlice({
|
||||
@@ -56,6 +60,9 @@ export const prefSlice = createSlice({
|
||||
setChunks: (state, action) => {
|
||||
state.chunks = action.payload;
|
||||
},
|
||||
setModalStateDeleteConv: (state, action: PayloadAction<ActiveState>) => {
|
||||
state.modalState = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -66,6 +73,7 @@ export const {
|
||||
setConversations,
|
||||
setPrompt,
|
||||
setChunks,
|
||||
setModalStateDeleteConv,
|
||||
} = prefSlice.actions;
|
||||
export default prefSlice.reducer;
|
||||
|
||||
@@ -114,6 +122,8 @@ export const selectSelectedDocsStatus = (state: RootState) =>
|
||||
!!state.preference.selectedDocs;
|
||||
export const selectSourceDocs = (state: RootState) =>
|
||||
state.preference.sourceDocs;
|
||||
export const selectModalStateDeleteConv = (state: RootState) =>
|
||||
state.preference.modalState;
|
||||
export const selectSelectedDocs = (state: RootState) =>
|
||||
state.preference.selectedDocs;
|
||||
export const selectConversations = (state: RootState) =>
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
setPrompt,
|
||||
setChunks,
|
||||
selectChunks,
|
||||
setModalStateDeleteConv,
|
||||
} from '../preferences/preferenceSlice';
|
||||
|
||||
const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com';
|
||||
@@ -43,6 +44,7 @@ const General: React.FC = () => {
|
||||
};
|
||||
fetchPrompts();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="mt-[59px]">
|
||||
<div className="mb-4">
|
||||
@@ -93,6 +95,19 @@ const General: React.FC = () => {
|
||||
apiHost={apiHost}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-55 w-56">
|
||||
<p className="font-bold text-jet dark:text-bright-gray">
|
||||
Delete all conversations
|
||||
</p>
|
||||
<button
|
||||
className="mt-2 flex w-full cursor-pointer items-center justify-between rounded-3xl border-2 border-solid border-purple-30 bg-white px-5 py-3 text-purple-30 hover:bg-purple-30 hover:text-white dark:border-chinese-silver dark:bg-transparent"
|
||||
onClick={() => dispatch(setModalStateDeleteConv('ACTIVE'))}
|
||||
>
|
||||
<span className="overflow-hidden text-ellipsis dark:text-bright-gray">
|
||||
Delete
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -34,6 +34,7 @@ const store = configureStore({
|
||||
model: '1.0',
|
||||
},
|
||||
],
|
||||
modalState: 'INACTIVE',
|
||||
},
|
||||
},
|
||||
reducer: {
|
||||
|
||||
Reference in New Issue
Block a user