221 lines
8.5 KiB
TypeScript
221 lines
8.5 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 { TooltipProvider } from "@/components/ui/tooltip"
|
|
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,
|
|
paginationTotal: data.paginationTotal,
|
|
listPageSize: data.listPageSize,
|
|
paginationRangeStart: data.paginationRangeStart,
|
|
paginationRangeEnd: data.paginationRangeEnd,
|
|
onListPageSizeChange: data.handleListPageSizeChange,
|
|
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 (
|
|
<TooltipProvider delayDuration={400}>
|
|
<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>
|
|
</TooltipProvider>
|
|
)
|
|
}
|
|
|
|
export type { EmailListLayoutProps }
|