Files
content-factory/apps/frontend/src/features/article-intake/model.ts
T

88 lines
2.2 KiB
TypeScript

import type {
ArticleCreateRequest,
TargetSiteConfig,
WorkflowTemplateSummary,
} from "@pipeline/shared";
export type NewArticleDraft = {
targetSiteId: string;
workflowTemplateId: string;
briefDescription: string;
workingTitle: string;
contentType: string;
primaryKeyword: string;
};
export type WorkflowTemplateOption = {
id: string;
label: string;
version: number;
stageCount: number;
};
export type FieldErrors = Record<string, string>;
export type NewArticleFormState = {
values: NewArticleDraft;
errors: FieldErrors;
formError?: string;
};
export function initialDraft(
sites: readonly TargetSiteConfig[],
workflows: readonly WorkflowTemplateSummary[] = [],
): NewArticleDraft {
const workflowOptions = buildWorkflowTemplateOptions(workflows);
return {
targetSiteId: sites.length > 0 ? sites[0].id : "",
workflowTemplateId: workflowOptions.length > 0 ? workflowOptions[0].id : "",
briefDescription: "",
workingTitle: "",
contentType: "longform_guide",
primaryKeyword: "",
};
}
export function buildWorkflowTemplateOptions(
workflows: readonly WorkflowTemplateSummary[],
): WorkflowTemplateOption[] {
return workflows
.filter((workflow) => workflow.status === "ACTIVE")
.map((workflow) => ({
id: workflow.id,
label: `${workflow.name} v${workflow.version}`,
version: workflow.version,
stageCount: workflow.stages?.length ?? 0,
}));
}
export function buildCreateArticlePayload(
values: NewArticleDraft,
): ArticleCreateRequest {
return {
target_site_id: values.targetSiteId,
workflow_template_id: values.workflowTemplateId || null,
brief_description: values.briefDescription,
working_title: values.workingTitle || null,
language: "en",
content_type: values.contentType,
primary_keyword: values.primaryKeyword || null,
};
}
export function validateArticleDraft(values: NewArticleDraft): FieldErrors {
const errors: FieldErrors = {};
if (!values.targetSiteId) {
errors.targetSiteId = "Select a target site";
}
if (!values.briefDescription.trim()) {
errors.briefDescription = "Brief description is required";
}
if (!values.contentType.trim()) {
errors.contentType = "Content type is required";
}
return errors;
}