mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-08-24 07:12:18 +10:00
fix: render cover letter exports without resume chrome
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
||||
WidthType,
|
||||
} from "docx";
|
||||
import { parseColorString } from "@reactive-resume/utils/color";
|
||||
import { shouldShowResumeHeader } from "./cover-letter";
|
||||
import { toSafeDocxLink } from "./link-utils";
|
||||
import { renderBuiltInSection, renderCustomSection, renderSummary, setRenderConfig } from "./section-renderers";
|
||||
|
||||
@@ -413,9 +414,10 @@ export function buildDocument(data: ResumeData, resolveTitle?: SectionTitleResol
|
||||
textColorHex,
|
||||
primaryColorHex: colorHex,
|
||||
};
|
||||
const showHeader = shouldShowResumeHeader(data);
|
||||
|
||||
// Header placement depends on template
|
||||
if (templateConfig.headerPosition === "full-width") {
|
||||
if (templateConfig.headerPosition === "full-width" && showHeader) {
|
||||
setRenderConfig(mainConfig);
|
||||
documentChildren.push(...buildHeader(data, colorHex, textColorHex));
|
||||
}
|
||||
@@ -434,7 +436,7 @@ export function buildDocument(data: ResumeData, resolveTitle?: SectionTitleResol
|
||||
setRenderConfig(mainConfig);
|
||||
|
||||
const mainParagraphs: Paragraph[] = [];
|
||||
if (templateConfig.headerPosition === "main-only") {
|
||||
if (templateConfig.headerPosition === "main-only" && showHeader) {
|
||||
mainParagraphs.push(...buildHeader(data, colorHex, textColorHex));
|
||||
}
|
||||
for (const sectionId of layoutPage.main) {
|
||||
@@ -445,7 +447,7 @@ export function buildDocument(data: ResumeData, resolveTitle?: SectionTitleResol
|
||||
setRenderConfig({ ...mainConfig, textColorHex: sidebarTextColorHex, primaryColorHex: sidebarHeadingColorHex });
|
||||
|
||||
const sidebarParagraphs: Paragraph[] = [];
|
||||
if (templateConfig.headerPosition === "sidebar-only") {
|
||||
if (templateConfig.headerPosition === "sidebar-only" && showHeader) {
|
||||
sidebarParagraphs.push(...buildHeader(data, sidebarHeadingColorHex, sidebarTextColorHex));
|
||||
}
|
||||
for (const sectionId of layoutPage.sidebar) {
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const builderSource = readFileSync(fileURLToPath(new URL("./builder.ts", import.meta.url)), "utf8");
|
||||
|
||||
describe("cover letter DOCX layout", () => {
|
||||
it("gates resume headers for cover-letter-only documents", () => {
|
||||
expect(builderSource).toContain("shouldShowResumeHeader(data)");
|
||||
expect(builderSource).toContain('templateConfig.headerPosition === "full-width" && showHeader');
|
||||
expect(builderSource).toContain('templateConfig.headerPosition === "main-only" && showHeader');
|
||||
expect(builderSource).toContain('templateConfig.headerPosition === "sidebar-only" && showHeader');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { ResumeData } from "@reactive-resume/schema/resume/data";
|
||||
|
||||
const isCoverLetterSection = (data: ResumeData, sectionId: string) => {
|
||||
const section = data.customSections.find((customSection) => customSection.id === sectionId);
|
||||
|
||||
return section?.type === "cover-letter" && !section.hidden && section.items.some((item) => !item.hidden);
|
||||
};
|
||||
|
||||
const isCoverLetterOnlyDocument = (data: ResumeData) => {
|
||||
const sectionIds = data.metadata.layout.pages.flatMap((page) => [...page.main, ...page.sidebar]);
|
||||
|
||||
return sectionIds.length > 0 && sectionIds.every((sectionId) => isCoverLetterSection(data, sectionId));
|
||||
};
|
||||
|
||||
export const shouldShowResumeHeader = (data: ResumeData) => !isCoverLetterOnlyDocument(data);
|
||||
@@ -150,6 +150,7 @@ describe("renderCustomSection", () => {
|
||||
const section: CustomSection = {
|
||||
...baseCustom,
|
||||
type: "cover-letter",
|
||||
title: "Cover Letter",
|
||||
items: [
|
||||
{
|
||||
id: "x",
|
||||
@@ -160,8 +161,7 @@ describe("renderCustomSection", () => {
|
||||
],
|
||||
};
|
||||
const paragraphs = renderCustomSection(section, HEX);
|
||||
// 1 heading + at least two paragraphs (recipient + body)
|
||||
expect(paragraphs.length).toBeGreaterThanOrEqual(3);
|
||||
expect(paragraphs).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -506,7 +506,7 @@ export function renderCustomSection(section: CustomSection, colorHex: string): P
|
||||
|
||||
// Cover letter type — render recipient + content
|
||||
if (sectionType === "cover-letter") {
|
||||
const paragraphs: Paragraph[] = [sectionHeading(section.title, colorHex)];
|
||||
const paragraphs: Paragraph[] = [];
|
||||
for (const item of visibleItems) {
|
||||
if ("recipient" in item && item.recipient) {
|
||||
paragraphs.push(...htmlToParagraphs(item.recipient, getHtmlStyle()));
|
||||
|
||||
Reference in New Issue
Block a user