88 lines
2.2 KiB
TypeScript
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;
|
|
}
|