Skip to content

Commit e327f8e

Browse files
added functionality for clear all history
1 parent 6273f66 commit e327f8e

3 files changed

Lines changed: 142 additions & 11 deletions

File tree

content-gen/src/app/frontend/src/components/ChatHistory.tsx

Lines changed: 90 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
Compose20Regular,
2525
Delete20Regular,
2626
Edit20Regular,
27+
DismissCircle20Regular,
2728
} from '@fluentui/react-icons';
2829

2930
interface ConversationSummary {
@@ -55,8 +56,30 @@ export function ChatHistory({
5556
const [isLoading, setIsLoading] = useState(true);
5657
const [error, setError] = useState<string | null>(null);
5758
const [showAll, setShowAll] = useState(false);
59+
const [isClearAllDialogOpen, setIsClearAllDialogOpen] = useState(false);
60+
const [isClearing, setIsClearing] = useState(false);
5861
const INITIAL_COUNT = 5;
5962

63+
const handleClearAllConversations = useCallback(async () => {
64+
setIsClearing(true);
65+
try {
66+
const response = await fetch('/api/conversations', {
67+
method: 'DELETE',
68+
});
69+
if (response.ok) {
70+
setConversations([]);
71+
onNewConversation();
72+
setIsClearAllDialogOpen(false);
73+
} else {
74+
console.error('Failed to clear all conversations');
75+
}
76+
} catch (err) {
77+
console.error('Error clearing all conversations:', err);
78+
} finally {
79+
setIsClearing(false);
80+
}
81+
}, [onNewConversation]);
82+
6083
const handleDeleteConversation = useCallback(async (conversationId: string) => {
6184
try {
6285
const response = await fetch(`/api/conversations/${conversationId}`, {
@@ -170,17 +193,51 @@ export function ChatHistory({
170193
backgroundColor: tokens.colorNeutralBackground3,
171194
overflow: 'hidden',
172195
}}>
173-
<Text
174-
weight="semibold"
175-
size={300}
176-
style={{
177-
marginBottom: '12px',
178-
color: tokens.colorNeutralForeground1,
179-
flexShrink: 0,
180-
}}
181-
>
182-
Chat History
183-
</Text>
196+
<div style={{
197+
display: 'flex',
198+
justifyContent: 'space-between',
199+
alignItems: 'center',
200+
marginBottom: '12px',
201+
flexShrink: 0,
202+
}}>
203+
<Text
204+
weight="semibold"
205+
size={300}
206+
style={{
207+
color: tokens.colorNeutralForeground1,
208+
}}
209+
>
210+
Chat History
211+
</Text>
212+
<Menu>
213+
<MenuTrigger disableButtonEnhancement>
214+
<Button
215+
appearance="subtle"
216+
icon={<MoreHorizontal20Regular />}
217+
size="small"
218+
title="More options"
219+
disabled={isGenerating}
220+
style={{
221+
minWidth: '24px',
222+
height: '24px',
223+
padding: '2px',
224+
color: tokens.colorNeutralForeground3,
225+
}}
226+
/>
227+
</MenuTrigger>
228+
<MenuPopover>
229+
<MenuList>
230+
<MenuItem
231+
icon={<DismissCircle20Regular />}
232+
onClick={() => setIsClearAllDialogOpen(true)}
233+
disabled={displayConversations.length === 0}
234+
>
235+
Clear all chat history
236+
</MenuItem>
237+
</MenuList>
238+
</MenuPopover>
239+
</Menu>
240+
</div>
184241

185242
<div style={{
186243
borderBottom: `1px solid ${tokens.colorNeutralStroke2}`,
@@ -295,6 +352,28 @@ export function ChatHistory({
295352
</Link>
296353
</div>
297354
</div>
355+
356+
{/* Clear All Confirmation Dialog */}
357+
<Dialog open={isClearAllDialogOpen} onOpenChange={(_, data) => !isClearing && setIsClearAllDialogOpen(data.open)}>
358+
<DialogSurface>
359+
<DialogTitle>Clear all chat history</DialogTitle>
360+
<DialogBody>
361+
<DialogContent>
362+
<Text>
363+
Are you sure you want to delete all chat history? This action cannot be undone and all conversations will be permanently removed.
364+
</Text>
365+
</DialogContent>
366+
</DialogBody>
367+
<DialogActions>
368+
<Button appearance="secondary" onClick={() => setIsClearAllDialogOpen(false)} disabled={isClearing}>
369+
Cancel
370+
</Button>
371+
<Button appearance="primary" onClick={handleClearAllConversations} disabled={isClearing}>
372+
{isClearing ? 'Clearing...' : 'Clear All'}
373+
</Button>
374+
</DialogActions>
375+
</DialogSurface>
376+
</Dialog>
298377
</div>
299378
);
300379
}

content-gen/src/backend/app.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,29 @@ async def update_conversation(conversation_id: str):
13251325
return jsonify({"error": "Failed to rename conversation"}), 500
13261326

13271327

1328+
@app.route("/api/conversations", methods=["DELETE"])
1329+
async def delete_all_conversations():
1330+
"""
1331+
Delete all conversations for the current user.
1332+
1333+
Uses authenticated user from EasyAuth headers.
1334+
"""
1335+
auth_user = get_authenticated_user()
1336+
user_id = auth_user["user_principal_id"]
1337+
1338+
try:
1339+
cosmos_service = await get_cosmos_service()
1340+
deleted_count = await cosmos_service.delete_all_conversations(user_id)
1341+
return jsonify({
1342+
"success": True,
1343+
"message": f"Deleted {deleted_count} conversations",
1344+
"deleted_count": deleted_count
1345+
})
1346+
except Exception as e:
1347+
logger.warning(f"Failed to delete all conversations: {e}")
1348+
return jsonify({"error": "Failed to delete conversations"}), 500
1349+
1350+
13281351
# ==================== Brand Guidelines Endpoints ====================
13291352

13301353
@app.route("/api/brand-guidelines", methods=["GET"])

content-gen/src/backend/services/cosmos_service.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,35 @@ async def rename_conversation(
586586
result = await self._conversations_container.upsert_item(conversation)
587587
return result
588588

589+
async def delete_all_conversations(
590+
self,
591+
user_id: str
592+
) -> int:
593+
"""
594+
Delete all conversations for a user.
595+
596+
Args:
597+
user_id: User ID to delete conversations for
598+
599+
Returns:
600+
Number of conversations deleted
601+
"""
602+
await self.initialize()
603+
604+
# First get all conversations for the user
605+
conversations = await self.get_user_conversations(user_id, limit=1000)
606+
607+
deleted_count = 0
608+
for conv in conversations:
609+
try:
610+
await self.delete_conversation(conv["id"], user_id)
611+
deleted_count += 1
612+
except Exception as e:
613+
logger.warning(f"Failed to delete conversation {conv['id']}: {e}")
614+
615+
logger.info(f"Deleted {deleted_count} conversations for user {user_id}")
616+
return deleted_count
617+
589618

590619
# Singleton instance
591620
_cosmos_service: Optional[CosmosDBService] = None

0 commit comments

Comments
 (0)