import { t } from '@/i18n' import type { ArticleCapability, CoverageEntry } from '@/lib/articleTypes' import { holds } from '@/lib/editorCapabilities' import { unpublishLabel } from '@/lib/editorLabels' export interface OverflowItem { key: 'unpublish' | 'editSlug' | 'move' | 'deleteVersion' | 'deleteArticle' label: string icon: string danger: boolean disabled: boolean reason: string onSelect: () => void } export interface OverflowContext { capabilities: ArticleCapability[] siblings: CoverageEntry[] language: string | null unpublishInMenu: boolean handlers: Partial void>> } function ignore() { return undefined } function unavailable(key: OverflowItem['key'], context: OverflowContext): Partial { return context.handlers[key] ? {} : { disabled: true, reason: t('Not available yet.') } } function item( key: OverflowItem['key'], label: string, icon: string, context: OverflowContext, extra: Partial = {}, ): OverflowItem { return { key, label, icon, danger: false, disabled: false, reason: '', onSelect: context.handlers[key] ?? ignore, ...unavailable(key, context), ...extra, } } function deleteVersionLabel(language: string | null) { return language ? t('Delete {0} version', [language]) : t('Delete article') } function blocksWholeArticle(context: OverflowContext) { return context.siblings.some((sibling) => !holds(sibling.capabilities, 'delete')) } function blockedExtra(blocked: boolean, reason: string): Partial { return blocked ? { disabled: true, reason } : {} } function editItems(context: OverflowContext): OverflowItem[] { const blocked = blocksWholeArticle(context) return [ item('editSlug', t('Edit slug'), 'i-lucide-link', context), item( 'move', t('Move article'), 'i-lucide-arrow-right-left', context, blockedExtra(blocked, t("You can't delete this article.")), ), ] } function deleteItems(context: OverflowContext): OverflowItem[] { if (context.language && context.siblings.length === 0) { return [ item('deleteArticle', t('Delete article'), 'i-lucide-trash-2', context, { danger: true, }), ] } const versionItem = item( 'deleteVersion', deleteVersionLabel(context.language), 'i-lucide-trash-2', context, { danger: true }, ) if (!context.language) { return [versionItem] } const blocked = blocksWholeArticle(context) return [ versionItem, item('deleteArticle', t('Delete article'), 'i-lucide-trash-2', context, { danger: !blocked, ...blockedExtra(blocked, t("You can't delete this article.")), }), ] } export function overflowItems(context: OverflowContext): OverflowItem[] { const items: OverflowItem[] = [] if (context.unpublishInMenu) { items.push(item('unpublish', unpublishLabel(context.language), 'i-lucide-eye-off', context)) } if (holds(context.capabilities, 'edit')) { items.push(...editItems(context)) } if (holds(context.capabilities, 'delete')) { items.push(...deleteItems(context)) } return items }