Fix frontend build for CV profile and draft types

This commit is contained in:
2026-03-29 00:58:05 +01:00
parent 839a2ed80d
commit 4253d33dfd
2 changed files with 38 additions and 16 deletions
+2
View File
@@ -213,6 +213,7 @@ export const translations = {
profileCvStructuredEditorHelp: "Edit reusable CV data directly so generators and matching can work from stable fields instead of raw text alone.",
profileCvExtractionHistory: "Extraction history",
profileCvExtractionHistoryHelp: "See which parser run produced the current structured profile and reprocess from the stored source artifact when needed.",
profileCvExtractionHistoryEmpty: "No extraction runs yet.",
profileCvProfileVersion: "Profile v{count}",
profileCvCurrentRun: "Current run",
profileCvNoStoredArtifact: "No stored artifact",
@@ -1113,6 +1114,7 @@ export const translations = {
profileCvStructuredEditorHelp: "Rediger gjenbrukbare CV-data direkte slik at generatorer og matching kan jobbe fra stabile felt i stedet for bare råtekst.",
profileCvExtractionHistory: "Ekstraksjonshistorikk",
profileCvExtractionHistoryHelp: "Se hvilken parserkjøring som produserte den nåværende strukturerte profilen, og kjør på nytt fra det lagrede kildeartefaktet ved behov.",
profileCvExtractionHistoryEmpty: "Ingen ekstraksjonskjøringer ennå.",
profileCvProfileVersion: "Profil v{count}",
profileCvCurrentRun: "Gjeldende kjøring",
profileCvNoStoredArtifact: "Ingen lagret kildefil",
+36 -16
View File
@@ -35,14 +35,26 @@ function formatDateRange(start?: string | null, end?: string | null, isCurrent?:
export function renderTailoredCvDraftText(source?: Partial<TailoredCvDraft> | null) {
const draft = emptyTailoredCvDraft();
const sourceSummary = source?.summary;
const sourceSelectedSkills = source?.selectedSkills;
const sourceExperience = source?.experience;
const sourceEducation = source?.education;
const sourceCustomSections = source?.customSections;
const summary = Array.isArray(sourceSummary) ? sourceSummary.filter(Boolean) : [];
const selectedSkills = Array.isArray(sourceSelectedSkills) ? sourceSelectedSkills.filter(Boolean) : [];
const experience = Array.isArray(sourceExperience) ? sourceExperience.filter(Boolean) : [];
const education = Array.isArray(sourceEducation) ? sourceEducation.filter(Boolean) : [];
const customSections = Array.isArray(sourceCustomSections) ? sourceCustomSections.filter(Boolean) : [];
const normalized = {
...draft,
...source,
summary: Array.isArray(source?.summary) ? source.summary.filter(Boolean) : [],
selectedSkills: Array.isArray(source?.selectedSkills) ? source.selectedSkills.filter(Boolean) : [],
experience: Array.isArray(source?.experience) ? source.experience.filter(Boolean) : [],
education: Array.isArray(source?.education) ? source.education.filter(Boolean) : [],
customSections: Array.isArray(source?.customSections) ? source.customSections.filter(Boolean) : [],
summary,
selectedSkills,
experience,
education,
customSections,
};
const sections: string[] = [];
@@ -88,39 +100,47 @@ export function renderTailoredCvDraftText(source?: Partial<TailoredCvDraft> | nu
export function normalizeTailoredCvDraft(source?: Partial<TailoredCvDraft> | null): TailoredCvDraft {
const empty = emptyTailoredCvDraft();
const sourceSummary = source?.summary;
const sourceSelectedSkills = source?.selectedSkills;
const sourceExperience = source?.experience;
const sourceEducation = source?.education;
const sourceCustomSections = source?.customSections;
const sourceRenderOptions = source?.renderOptions;
const sourceSectionOrder = sourceRenderOptions?.sectionOrder;
const normalized: TailoredCvDraft = {
...empty,
...source,
templateId: source?.templateId?.trim() || empty.templateId,
headline: source?.headline ?? "",
summary: Array.isArray(source?.summary) ? source!.summary.filter(Boolean) : [],
selectedSkills: Array.isArray(source?.selectedSkills) ? source!.selectedSkills.filter(Boolean) : [],
experience: Array.isArray(source?.experience) ? source!.experience.map((item) => ({
summary: Array.isArray(sourceSummary) ? sourceSummary.filter(Boolean) : [],
selectedSkills: Array.isArray(sourceSelectedSkills) ? sourceSelectedSkills.filter(Boolean) : [],
experience: Array.isArray(sourceExperience) ? sourceExperience.map((item) => ({
title: item?.title ?? "",
company: item?.company ?? "",
location: item?.location ?? "",
start: item?.start ?? "",
end: item?.end ?? "",
isCurrent: Boolean(item?.isCurrent),
bullets: Array.isArray(item?.bullets) ? item!.bullets.filter(Boolean) : [],
bullets: Array.isArray(item?.bullets) ? item.bullets.filter(Boolean) : [],
})) : [],
education: Array.isArray(source?.education) ? source!.education.map((item) => ({
education: Array.isArray(sourceEducation) ? sourceEducation.map((item) => ({
qualification: item?.qualification ?? "",
institution: item?.institution ?? "",
location: item?.location ?? "",
start: item?.start ?? "",
end: item?.end ?? "",
details: Array.isArray(item?.details) ? item!.details.filter(Boolean) : [],
details: Array.isArray(item?.details) ? item.details.filter(Boolean) : [],
})) : [],
customSections: Array.isArray(source?.customSections) ? source!.customSections.map((item) => ({
customSections: Array.isArray(sourceCustomSections) ? sourceCustomSections.map((item) => ({
title: item?.title ?? "",
items: Array.isArray(item?.items) ? item!.items.filter(Boolean) : [],
items: Array.isArray(item?.items) ? item.items.filter(Boolean) : [],
})) : [],
renderOptions: {
...empty.renderOptions,
...source?.renderOptions,
sectionOrder: Array.isArray(source?.renderOptions?.sectionOrder) && source.renderOptions.sectionOrder.length > 0
? source.renderOptions.sectionOrder.filter(Boolean)
...sourceRenderOptions,
sectionOrder: Array.isArray(sourceSectionOrder) && sourceSectionOrder.length > 0
? sourceSectionOrder.filter(Boolean)
: DEFAULT_SECTION_ORDER,
},
status: source?.status?.trim() || empty.status,