feat: window management system with minimize, fullscreen, and AI chat split
- Window manager store (Zustand) for managing open/minimized/fullscreen windows - Window component with header controls: KI-Chat toggle, fullscreen, minimize, close - AI chat panel with streaming chat via existing /ai/sessions API - WindowContainer renders all non-minimized windows - TopBar shows minimized windows as clickable pills - ContactEditForm extracted from ContactEditModal for window rendering - ContactsList and ContactDetailPage use openWindow() instead of modal state - Draggable windows with z-index management
This commit is contained in:
@@ -15,7 +15,8 @@ import { usePluginToolbarStore } from '@/store/pluginToolbarStore';
|
||||
import { ContactFolderTree, type ContactFilter } from '@/components/contacts/ContactFolderTree';
|
||||
import { ContactList, type ContactViewMode } from '@/components/contacts/ContactList';
|
||||
import { ContactDetail } from '@/components/contacts/ContactDetail';
|
||||
import { ContactEditModal } from '@/components/contacts/ContactEditModal';
|
||||
import { ContactEditForm } from '@/components/contacts/ContactEditForm';
|
||||
import { useWindowStore } from '@/store/windowStore';
|
||||
import { SavedFilters } from '@/components/SavedFilters';
|
||||
import { ArrowDownAZ, ArrowUpZA, ChevronLeft, LayoutGrid, List, Plus } from 'lucide-react';
|
||||
import {
|
||||
@@ -39,8 +40,7 @@ export function ContactsListPage() {
|
||||
const [viewMode, setViewMode] = useState<ContactViewMode>('list');
|
||||
const [selectedContactId, setSelectedContactId] = useState<string | null>(null);
|
||||
const [activeView, setActiveView] = useState<'folders' | 'list' | 'detail'>('folders');
|
||||
const [editModalOpen, setEditModalOpen] = useState(false);
|
||||
const [editingContact, setEditingContact] = useState<UnifiedContact | null>(null);
|
||||
const openWindow = useWindowStore((s) => s.openWindow);
|
||||
|
||||
// Debounce search
|
||||
useEffect(() => {
|
||||
@@ -134,19 +134,40 @@ export function ContactsListPage() {
|
||||
setPage(1);
|
||||
}, []);
|
||||
|
||||
// Handle edit modal saved
|
||||
const handleSaved = useCallback((id: string) => {
|
||||
setSelectedContactId(id);
|
||||
setActiveView('detail');
|
||||
}, []);
|
||||
|
||||
// Handle create
|
||||
const handleCreate = useCallback(() => {
|
||||
setEditingContact(null);
|
||||
setEditModalOpen(true);
|
||||
}, []);
|
||||
openWindow({
|
||||
title: t('contacts.create'),
|
||||
type: 'contact-create',
|
||||
component: ContactEditForm,
|
||||
componentProps: {
|
||||
onClose: () => {},
|
||||
onSaved: handleSaved,
|
||||
},
|
||||
});
|
||||
}, [openWindow, t, handleSaved]);
|
||||
|
||||
// Handle edit
|
||||
const handleEdit = useCallback(() => {
|
||||
if (selectedContact) {
|
||||
setEditingContact(selectedContact);
|
||||
setEditModalOpen(true);
|
||||
openWindow({
|
||||
title: t('contacts.edit'),
|
||||
type: 'contact-edit',
|
||||
component: ContactEditForm,
|
||||
componentProps: {
|
||||
contact: selectedContact,
|
||||
onClose: () => {},
|
||||
onSaved: handleSaved,
|
||||
},
|
||||
});
|
||||
}
|
||||
}, [selectedContact]);
|
||||
}, [selectedContact, openWindow, t, handleSaved]);
|
||||
|
||||
// Handle delete (from detail)
|
||||
const handleDeleted = useCallback(() => {
|
||||
@@ -154,12 +175,6 @@ export function ContactsListPage() {
|
||||
setActiveView('list');
|
||||
}, []);
|
||||
|
||||
// Handle edit modal saved
|
||||
const handleSaved = useCallback((id: string) => {
|
||||
setSelectedContactId(id);
|
||||
setActiveView('detail');
|
||||
}, []);
|
||||
|
||||
// Register toolbar items
|
||||
const registerItems = usePluginToolbarStore((s) => s.registerItems);
|
||||
const unregisterPlugin = usePluginToolbarStore((s) => s.unregisterPlugin);
|
||||
@@ -458,13 +473,7 @@ export function ContactsListPage() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Edit/Create Modal */}
|
||||
<ContactEditModal
|
||||
open={editModalOpen}
|
||||
onClose={() => setEditModalOpen(false)}
|
||||
contact={editingContact}
|
||||
onSaved={handleSaved}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user