Some checks are pending
E2E / Playwright e2e (push) Waiting to run
- Introduced turbopack alias for canvas in next.config.mjs. - Updated package.json scripts for development and branding tasks. - Added new dependencies for Tiptap extensions. - Implemented new demo layouts for agenda, contacts, drive, and mail applications. - Enhanced globals.css for improved theming and splash screen animations. - Added OAuth callback handling for drive mounts. - Updated layout components to integrate new demo shells and improve structure.
155 lines
4.1 KiB
TypeScript
155 lines
4.1 KiB
TypeScript
/** Routage URL sous `/mail` : dossier, onglet boîte de réception, page, message ouvert. */
|
||
|
||
import {
|
||
cloneDefaultLabelRows,
|
||
tabbedInboxLabelRows,
|
||
} from "@/lib/sidebar-nav-data"
|
||
|
||
export const DEFAULT_MAIL_FOLDER = "inbox"
|
||
export const DEFAULT_INBOX_TAB = "primary"
|
||
/** Onglet boîte : tous les messages inbox sans filtre libellé catégorie. */
|
||
export const INBOX_ALL_TAB = "all"
|
||
/** Pseudo-dossier pour les résultats de recherche (query params dans l'URL). */
|
||
export const SEARCH_FOLDER_ID = "search"
|
||
|
||
/** Onglets sans pastille « nouveaux » ni ligne expéditeurs quand inactifs. */
|
||
export function inboxTabShowsInactiveMeta(tabId: string): boolean {
|
||
const tab = normalizeInboxTabSegment(tabId)
|
||
return tab !== DEFAULT_INBOX_TAB && tab !== INBOX_ALL_TAB
|
||
}
|
||
|
||
/** Segments d’URL historiques → ids libellés actuels. */
|
||
const LEGACY_INBOX_TAB_SEGMENT: Record<string, string> = {
|
||
updates: "mises-a-jour",
|
||
notifications: "newsletters",
|
||
social: "reseaux-sociaux",
|
||
purchases: "achats",
|
||
travel: "deplacements",
|
||
}
|
||
|
||
export function normalizeInboxTabSegment(tab: string): string {
|
||
return LEGACY_INBOX_TAB_SEGMENT[tab] ?? tab
|
||
}
|
||
|
||
function defaultInboxTabIdSet(): Set<string> {
|
||
const s = new Set<string>([DEFAULT_INBOX_TAB, INBOX_ALL_TAB])
|
||
for (const r of tabbedInboxLabelRows(cloneDefaultLabelRows())) {
|
||
s.add(r.id)
|
||
}
|
||
return s
|
||
}
|
||
|
||
/** Onglets boîte de réception reconnus dans l’URL (ids courants + segments legacy). */
|
||
export const INBOX_CATEGORY_TAB_IDS = (() => {
|
||
const s = defaultInboxTabIdSet()
|
||
for (const legacy of Object.keys(LEGACY_INBOX_TAB_SEGMENT)) {
|
||
s.add(legacy)
|
||
}
|
||
return s
|
||
})()
|
||
|
||
export type MailRouteState = {
|
||
folderId: string
|
||
/** Onglet catégorie ; pour `folderId !== inbox`, valeur ignorée par le filtre mais peut rester `primary`. */
|
||
inboxTab: string
|
||
page: number
|
||
mailId: string | null
|
||
}
|
||
|
||
const DEFAULT_STATE: MailRouteState = {
|
||
folderId: DEFAULT_MAIL_FOLDER,
|
||
inboxTab: DEFAULT_INBOX_TAB,
|
||
page: 1,
|
||
mailId: null,
|
||
}
|
||
|
||
function decodeSegment(s: string): string {
|
||
try {
|
||
return decodeURIComponent(s)
|
||
} catch {
|
||
return s
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Parse le tableau de segments Next (sans le préfixe `mail`).
|
||
* Ex. `['inbox','promotions','page','2','message','1']`
|
||
*/
|
||
export function parseMailSegments(
|
||
segments: string[] | undefined | null
|
||
): MailRouteState {
|
||
const raw = segments?.filter((x) => x.length > 0) ?? []
|
||
if (raw.length === 0) return { ...DEFAULT_STATE }
|
||
|
||
const parts = [...raw]
|
||
let mailId: string | null = null
|
||
let page = 1
|
||
|
||
if (parts.length >= 2 && parts[parts.length - 2] === "message") {
|
||
mailId = decodeSegment(parts[parts.length - 1]!)
|
||
parts.length -= 2
|
||
}
|
||
|
||
if (parts.length >= 2 && parts[parts.length - 2] === "page") {
|
||
const n = parseInt(parts[parts.length - 1]!, 10)
|
||
page = Number.isFinite(n) && n >= 1 ? n : 1
|
||
parts.length -= 2
|
||
}
|
||
|
||
if (parts.length === 0) {
|
||
return { ...DEFAULT_STATE, mailId, page }
|
||
}
|
||
|
||
const folderId = parts[0]!
|
||
if (folderId === "inbox") {
|
||
if (parts.length >= 2) {
|
||
const tab = parts[1]!
|
||
if (INBOX_CATEGORY_TAB_IDS.has(tab)) {
|
||
const inboxTab = normalizeInboxTabSegment(tab)
|
||
const valid = defaultInboxTabIdSet()
|
||
return {
|
||
folderId,
|
||
inboxTab: valid.has(inboxTab) ? inboxTab : DEFAULT_INBOX_TAB,
|
||
page,
|
||
mailId,
|
||
}
|
||
}
|
||
return { folderId, inboxTab: DEFAULT_INBOX_TAB, page, mailId }
|
||
}
|
||
return { folderId, inboxTab: DEFAULT_INBOX_TAB, page, mailId }
|
||
}
|
||
|
||
return {
|
||
folderId,
|
||
inboxTab: DEFAULT_INBOX_TAB,
|
||
page,
|
||
mailId,
|
||
}
|
||
}
|
||
|
||
function encodePathSegment(s: string): string {
|
||
return encodeURIComponent(s)
|
||
}
|
||
|
||
export function buildMailPath(r: MailRouteState, routeRoot = "mail"): string {
|
||
const rootParts = routeRoot.split("/").filter(Boolean)
|
||
const segs: string[] = [...rootParts, encodeURIComponent(r.folderId)]
|
||
|
||
if (r.folderId === "inbox") {
|
||
const tab = normalizeInboxTabSegment(r.inboxTab || DEFAULT_INBOX_TAB)
|
||
if (tab !== DEFAULT_INBOX_TAB) {
|
||
segs.push(tab)
|
||
}
|
||
}
|
||
|
||
if (r.page > 1) {
|
||
segs.push("page", String(r.page))
|
||
}
|
||
|
||
if (r.mailId) {
|
||
segs.push("message", encodePathSegment(r.mailId))
|
||
}
|
||
|
||
return `/${segs.join("/")}`
|
||
}
|