Files
geo/apps/admin-web/src/lib/article-list-actions.ts
T

99 lines
2.4 KiB
TypeScript
Raw Normal View History

import type { ArticleDetail } from '@geo/shared-types'
export interface ArticleActionState {
showPublish: boolean
showEdit: boolean
showPreview: boolean
showCopy: boolean
showDelete: boolean
showRegenerate: boolean
}
export interface ArticleActionSource {
generate_status?: string | null
source_type?: string | null
}
const regeneratableSourceTypes = new Set(['template', 'custom_generation', 'imitation', 'kol'])
export function resolveArticleActionState(
articleOrGenerateStatus?: ArticleActionSource | string | null,
): ArticleActionState {
const generateStatus =
typeof articleOrGenerateStatus === 'string'
? articleOrGenerateStatus
: articleOrGenerateStatus?.generate_status
const sourceType =
typeof articleOrGenerateStatus === 'string' ? undefined : articleOrGenerateStatus?.source_type
if (generateStatus === 'completed') {
return {
showPublish: true,
showEdit: true,
showPreview: true,
showCopy: true,
showDelete: true,
showRegenerate: false,
}
}
if (generateStatus === 'draft') {
return {
showPublish: false,
showEdit: true,
showPreview: false,
showCopy: false,
showDelete: true,
showRegenerate: false,
}
}
if (generateStatus === 'failed') {
return {
showPublish: false,
showEdit: false,
showPreview: false,
showCopy: false,
showDelete: true,
showRegenerate: sourceType ? regeneratableSourceTypes.has(sourceType) : false,
}
}
return {
showPublish: false,
showEdit: false,
showPreview: true,
showCopy: false,
showDelete: true,
showRegenerate: false,
}
}
export function buildArticleClipboardContent(
detail: Pick<ArticleDetail, 'title' | 'markdown_content'>,
): string {
2026-05-20 17:00:57 +08:00
const title = detail.title?.trim() ?? ''
const markdown = detail.markdown_content?.trim() ?? ''
if (!title) {
return markdown
}
if (!markdown) {
return `# ${title}`
}
if (getLeadingH1Text(markdown) === title) {
return markdown
}
return [`# ${title}`, markdown].join('\n\n').trim()
}
function getLeadingH1Text(markdown: string): string | null {
const normalizedMarkdown = markdown.replace(/^\uFEFF/, '').trimStart()
const firstLine = normalizedMarkdown.split(/\r?\n/, 1)[0]?.trim() ?? ''
const match = firstLine.match(/^#\s+(.+?)\s*#*$/)
return match?.[1]?.trim() ?? null
}