ultisuite-client/components/gmail/email-list/email-list-layout.tsx
2026-05-20 18:22:36 +02:00

213 lines
8.1 KiB
TypeScript

"use client"
import { Pencil } from "lucide-react"
import { cn } from "@/lib/utils"
import { buildSearchUrl } from "@/lib/mail-search/search-params"
import { MobileXsBulkSheets } from "@/components/gmail/mobile-xs-bulk-sheets"
import { EmailListToolbar } from "@/components/gmail/email-list/email-list-toolbar"
import { EmailListBody } from "@/components/gmail/email-list/email-list-body"
import { EmailListEmailViewPane } from "@/components/gmail/email-list/email-list-email-view-pane"
import { EmailListEmpty } from "@/components/gmail/email-list/email-list-empty"
import type { EmailListProps } from "@/components/gmail/email-list/email-list-helpers"
import type { EmailListData } from "@/components/gmail/email-list/hooks/use-email-list-data"
import type { EmailListLabels } from "@/components/gmail/email-list/hooks/use-email-list-labels"
import type { EmailListSelection } from "@/components/gmail/email-list/hooks/use-email-list-selection"
import type { EmailListReading } from "@/components/gmail/email-list/hooks/use-email-list-reading"
type EmailListLayoutProps = {
props: EmailListProps
data: EmailListData
labels: EmailListLabels
selection: EmailListSelection
reading: EmailListReading
}
export function EmailListLayout({
props,
data,
labels,
selection,
reading,
}: EmailListLayoutProps) {
const { onToggleSidebar } = props
const {
splitView,
isViewMode,
isXs,
touchNav,
openCompose,
} = data
const {
mobileXsMoveSheetOpen,
mobileXsLabelSheetOpen,
handleMobileXsMoveSheetOpenChange,
handleLabelSheetOpenChange,
labelSheetTargetIds,
bulkMoveTo,
openMobileXsMoveSheet,
openMobileXsLabelSheet,
} = selection
const {
openEmail,
} = reading
const toolbarProps = {
isViewMode: data.isViewMode,
splitView: data.splitView,
listToolbarMode: data.listToolbarMode,
compactInboxTabs: data.compactInboxTabs,
isSearchMode: data.isSearchMode,
selectedFolder: data.selectedFolder,
mobileFolderLabel: data.mobileFolderLabel,
displayListEmails: data.displayListEmails,
mobileUnreadCount: data.mobileUnreadCount,
mobileSelectionMode: selection.mobileSelectionMode,
setMobileSelectionMode: selection.setMobileSelectionMode,
setSelectedEmails: selection.setSelectedEmails,
mobileXsMoreMenuOpen: selection.mobileXsMoreMenuOpen,
setMobileXsMoreMenuOpen: selection.setMobileXsMoreMenuOpen,
showBulkToolbar: selection.showBulkToolbar,
bulkSelectMenuOpen: selection.bulkSelectMenuOpen,
setBulkSelectMenuOpen: selection.setBulkSelectMenuOpen,
selectAllChecked: selection.selectAllChecked,
handleSelectAllChange: selection.handleSelectAllChange,
selectMenuAll: selection.selectMenuAll,
selectMenuNone: selection.selectMenuNone,
selectMenuRead: selection.selectMenuRead,
selectMenuUnread: selection.selectMenuUnread,
selectMenuStarred: selection.selectMenuStarred,
selectMenuUnstarred: selection.selectMenuUnstarred,
bulkArchive: selection.bulkArchive,
bulkDelete: selection.bulkDelete,
bulkSpam: selection.bulkSpam,
hasUnreadInSelection: selection.hasUnreadInSelection,
bulkMarkRead: selection.bulkMarkRead,
bulkMarkUnread: selection.bulkMarkUnread,
moveTargets: data.moveTargets,
bulkMoveTo: selection.bulkMoveTo,
labelPickerQuery: data.labelPickerQuery,
setLabelPickerQuery: data.setLabelPickerQuery,
catalogLabels: labels.catalogLabels,
resolveLabelVisual: labels.resolveLabelVisual,
bulkTargetIds: selection.bulkTargetIds,
getCatalogLabelPresence: labels.getCatalogLabelPresence,
toggleLabelOnEmails: labels.toggleLabelOnEmails,
addLabelToEmails: labels.addLabelToEmails,
isRefreshing: data.isRefreshing,
handleManualRefresh: data.handleManualRefresh,
markAllInViewAsRead: data.markAllInViewAsRead,
openMobileXsMoveSheet,
openMobileXsLabelSheet,
listPage: data.listPage,
totalPages: data.totalPages,
openMailIndex: reading.openMailIndex,
goListPrevPage: reading.goListPrevPage,
goListNextPage: reading.goListNextPage,
goToPrev: reading.goToPrev,
goToNext: reading.goToNext,
goBack: reading.goBack,
openEmail: reading.openEmail,
viewModeIsRead: reading.viewModeIsRead,
singleArchive: reading.singleArchive,
singleDelete: reading.singleDelete,
singleNotSpam: reading.singleNotSpam,
singleSpam: reading.singleSpam,
singleToggleRead: reading.singleToggleRead,
singleMoveTo: reading.singleMoveTo,
onToggleSidebar,
inboxTabBarItems: data.inboxTabBarItems,
activeInboxTabId: data.activeInboxTabId,
unseenInTabById: data.unseenInTabById,
tabUnseenSenderLineById: data.tabUnseenSenderLineById,
handleCategoryInboxTabClick: reading.handleCategoryInboxTabClick,
searchParams: data.searchParams,
searchAccount: data.searchAccount,
allEmails: data.allEmails,
setSearchFilter: data.setSearchFilter,
toggleSearchFilter: data.toggleSearchFilter,
setAdvancedOpen: data.setAdvancedOpen,
searchRouter: data.searchRouter,
buildSearchUrl,
}
return (
<div className="flex h-full min-h-0 flex-1 flex-col">
<EmailListToolbar {...toolbarProps} part="mobile" />
{!isViewMode && touchNav && (
<MobileXsBulkSheets
moveSheetOpen={isXs && mobileXsMoveSheetOpen}
onMoveSheetOpenChange={handleMobileXsMoveSheetOpenChange}
labelSheetOpen={mobileXsLabelSheetOpen}
onLabelSheetOpenChange={handleLabelSheetOpenChange}
labelPickerQuery={data.labelPickerQuery}
onLabelPickerQueryChange={data.setLabelPickerQuery}
catalogLabels={labels.catalogLabels}
resolveLabelVisual={labels.resolveLabelVisual}
moveTargets={data.moveTargets}
onMoveTo={bulkMoveTo}
getLabelPresence={(lab) => labels.getCatalogLabelPresence(labelSheetTargetIds, lab)}
onToggleCatalogLabel={(lab) => labels.toggleLabelOnEmails(labelSheetTargetIds, lab)}
onCreateLabel={(lab) => {
labels.addLabelToEmails(labelSheetTargetIds, lab)
data.setLabelPickerQuery("")
}}
/>
)}
<div className={cn("flex min-h-0 flex-1 flex-col", splitView && "min-h-0 flex-row overflow-hidden")}>
<div
className={cn(
"flex min-h-0 min-w-0 flex-col",
splitView
? "relative w-[min(42%,480px)] min-w-[280px] max-w-[480px] shrink-0 border-r border-gray-200"
: "min-h-0 flex-1"
)}
>
<EmailListToolbar {...toolbarProps} part="list" />
<EmailListBody
data={data}
labels={labels}
selection={selection}
reading={reading}
onSelectFolder={props.onSelectFolder}
/>
{splitView ? (
<button
type="button"
onClick={openCompose}
className="absolute bottom-4 right-4 z-30 flex size-14 cursor-pointer items-center justify-center rounded-2xl border border-border bg-mail-surface text-[#444746] shadow-[0_1px_3px_rgba(60,64,67,.3),0_4px_8px_rgba(60,64,67,.15)] transition-[box-shadow,background-color] hover:bg-[#f6f8fc] hover:shadow-[0_1px_3px_rgba(60,64,67,.35),0_6px_12px_rgba(60,64,67,.2)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/40"
aria-label="Nouveau message"
>
<Pencil className="size-6" strokeWidth={1.5} />
</button>
) : null}
</div>
{splitView ? (
<section className="flex min-h-0 min-w-0 flex-1 flex-col bg-mail-surface">
{openEmail ? (
<>
<EmailListToolbar {...toolbarProps} variant="reading-pane" />
<div className="flex min-h-0 flex-1 flex-col overflow-hidden rounded-none">
<EmailListEmailViewPane
data={data}
reading={reading}
selection={selection}
/>
</div>
</>
) : (
<EmailListEmpty variant="split-pane" />
)}
</section>
) : null}
</div>
</div>
)
}
export type { EmailListLayoutProps }