feat: Mail FilterPanel, SortPanel, GroupPanel like Contacts + remove saved-filters button from Contacts and Mail
This commit is contained in:
@@ -452,16 +452,6 @@ export function ContactsListPage() {
|
||||
),
|
||||
onClick: () => {},
|
||||
},
|
||||
// Saved filters
|
||||
{
|
||||
id: 'saved-filters',
|
||||
plugin: 'contacts',
|
||||
label: 'Gespeicherte Filter',
|
||||
type: 'button' as const,
|
||||
group: 'actions',
|
||||
icon: <Bookmark className="w-3.5 h-3.5" strokeWidth={2} />,
|
||||
onClick: () => setSavedFiltersOpen(true),
|
||||
},
|
||||
// Print — icon only, right side
|
||||
...(canAccess('contacts:read') ? [{
|
||||
id: 'print',
|
||||
|
||||
+53
-32
@@ -18,7 +18,10 @@ import { MailDetail } from '@/components/mail/MailDetail';
|
||||
import { MailComposeForm, type ComposeMode } from '@/components/mail/MailComposeForm';
|
||||
import { useWindowStore } from '@/store/windowStore';
|
||||
import { usePluginToolbarStore } from '@/store/pluginToolbarStore';
|
||||
import { ArrowRight, ArrowUpDown, Bookmark, Check, ChevronLeft, ExternalLink, Loader2, Plus, Redo2, Trash2, TrendingUp, Undo2 } from 'lucide-react';
|
||||
import { ArrowRight, Check, ChevronLeft, ExternalLink, Loader2, Plus, Redo2, Trash2, TrendingUp, Undo2 } from 'lucide-react';
|
||||
import { MailFilterPanel, type FilterState as MailFilterState, emptyFilterState as emptyMailFilterState } from '@/components/mail/MailFilterPanel';
|
||||
import { MailSortPanel, type SortState as MailSortState, emptySortState as emptyMailSortState } from '@/components/mail/MailSortPanel';
|
||||
import { MailGroupPanel, type GroupState as MailGroupState, emptyGroupState as emptyMailGroupState } from '@/components/mail/MailGroupPanel';
|
||||
import type { Tag } from '@/api/tags';
|
||||
import { useSavedFilters } from '@/api/savedFilters';
|
||||
import {
|
||||
@@ -87,6 +90,9 @@ export function MailPage() {
|
||||
const [isSyncing, setIsSyncing] = useState(false);
|
||||
const [selectedTags, setSelectedTags] = useState<Tag[]>([]);
|
||||
const { data: savedFilters } = useSavedFilters('mail');
|
||||
const [mailFilterState, setMailFilterState] = useState<MailFilterState>(emptyMailFilterState);
|
||||
const [mailSortState, setMailSortState] = useState<MailSortState>(emptyMailSortState);
|
||||
const [mailGroupState, setMailGroupState] = useState<MailGroupState>(emptyMailGroupState);
|
||||
|
||||
// Ref to track the current folder ID for async callbacks (prevents race conditions)
|
||||
const selectedFolderIdRef = useRef<string | null>(null);
|
||||
@@ -594,44 +600,59 @@ export function MailPage() {
|
||||
onSearch: handleSearch,
|
||||
onClick: () => {},
|
||||
},
|
||||
// Filter dropdown — sort + saved filters (like Contacts)
|
||||
// FilterPanel — Multi-condition filter (like Contacts)
|
||||
{
|
||||
id: 'filter-sort',
|
||||
id: 'filter-panel',
|
||||
plugin: 'mail',
|
||||
label: 'Sortieren',
|
||||
type: 'dropdown' as const,
|
||||
label: 'Filter',
|
||||
type: 'custom' as const,
|
||||
group: 'filter',
|
||||
icon: <ArrowUpDown className="w-3.5 h-3.5" strokeWidth={2} />,
|
||||
menuWidth: '200px',
|
||||
menuOptions: [
|
||||
{ value: 'date-desc', label: 'Datum ↓ (neueste zuerst)', active: sortBy === 'date' && sortOrder === 'desc', onClick: () => { setSortBy('date'); setSortOrder('desc'); } },
|
||||
{ value: 'date-asc', label: 'Datum ↑ (älteste zuerst)', active: sortBy === 'date' && sortOrder === 'asc', onClick: () => { setSortBy('date'); setSortOrder('asc'); } },
|
||||
{ value: 'from-asc', label: 'Absender A-Z', active: sortBy === 'from' && sortOrder === 'asc', onClick: () => { setSortBy('from'); setSortOrder('asc'); } },
|
||||
{ value: 'from-desc', label: 'Absender Z-A', active: sortBy === 'from' && sortOrder === 'desc', onClick: () => { setSortBy('from'); setSortOrder('desc'); } },
|
||||
{ value: 'subject-asc', label: 'Betreff A-Z', active: sortBy === 'subject' && sortOrder === 'asc', onClick: () => { setSortBy('subject'); setSortOrder('asc'); } },
|
||||
{ value: 'subject-desc', label: 'Betreff Z-A', active: sortBy === 'subject' && sortOrder === 'desc', onClick: () => { setSortBy('subject'); setSortOrder('desc'); } },
|
||||
],
|
||||
customComponent: (
|
||||
<MailFilterPanel
|
||||
filters={mailFilterState}
|
||||
onFiltersChange={setMailFilterState}
|
||||
savedFilters={(savedFilters || []).map((f: any) => ({ id: f.id, name: f.name, filterState: f.filter_criteria || emptyMailFilterState }))}
|
||||
onSaveFilter={(name, state) => {
|
||||
// TODO: save via API
|
||||
console.log('Save filter', name, state);
|
||||
}}
|
||||
onLoadFilter={(state) => setMailFilterState(state)}
|
||||
onDeleteFilter={(id) => {
|
||||
// TODO: delete via API
|
||||
console.log('Delete filter', id);
|
||||
}}
|
||||
/>
|
||||
),
|
||||
onClick: () => {},
|
||||
},
|
||||
// SortPanel — Multi-field sort (like Contacts)
|
||||
{
|
||||
id: 'filter-saved',
|
||||
id: 'sort-panel',
|
||||
plugin: 'mail',
|
||||
label: 'Gespeicherte Filter',
|
||||
type: 'dropdown' as const,
|
||||
group: 'filter',
|
||||
icon: <Bookmark className="w-3.5 h-3.5" strokeWidth={2} />,
|
||||
menuWidth: '220px',
|
||||
menuOptions: (savedFilters || []).length > 0
|
||||
? (savedFilters || []).map((f: any) => ({
|
||||
value: f.id,
|
||||
label: f.name,
|
||||
onClick: () => {
|
||||
if (f.filter_criteria?.search !== undefined) handleSearch(f.filter_criteria.search);
|
||||
if (f.filter_criteria?.sortBy) setSortBy(f.filter_criteria.sortBy);
|
||||
if (f.filter_criteria?.sortOrder) setSortOrder(f.filter_criteria.sortOrder);
|
||||
},
|
||||
}))
|
||||
: [{ value: 'none', label: 'Keine gespeicherten Filter', disabled: true, onClick: () => {} }],
|
||||
label: 'Sortieren',
|
||||
type: 'custom' as const,
|
||||
group: 'sort',
|
||||
customComponent: (
|
||||
<MailSortPanel
|
||||
sortState={mailSortState}
|
||||
onSortChange={setMailSortState}
|
||||
/>
|
||||
),
|
||||
onClick: () => {},
|
||||
},
|
||||
// GroupPanel — Multi-field grouping (like Contacts)
|
||||
{
|
||||
id: 'group-panel',
|
||||
plugin: 'mail',
|
||||
label: 'Gruppierung',
|
||||
type: 'custom' as const,
|
||||
group: 'group',
|
||||
customComponent: (
|
||||
<MailGroupPanel
|
||||
groupState={mailGroupState}
|
||||
onGroupChange={setMailGroupState}
|
||||
/>
|
||||
),
|
||||
onClick: () => {},
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user