diff --git a/apps/server/src/archive/archive-report.attendance.ts b/apps/server/src/archive/archive-report.attendance.ts
index 18292f2..0e48e1f 100644
--- a/apps/server/src/archive/archive-report.attendance.ts
+++ b/apps/server/src/archive/archive-report.attendance.ts
@@ -1,7 +1,9 @@
import { AttendanceRecord } from '../entities/attendance-record.entity';
-import { esc, pageFrame, pageFooter, pageHeader } from './archive-report.helpers';
+import { esc, sectionFrame, sectionHeader } from './archive-report.helpers';
export function buildAttendance(records: AttendanceRecord[], now: string): string {
+ if (records.length === 0) return '';
+
const present = records.filter((r) => r.status === 'present').length;
const absent = records.filter((r) => r.status === 'absent').length;
const late = records.filter((r) => r.status === 'late').length;
@@ -42,18 +44,11 @@ export function buildAttendance(records: AttendanceRecord[], now: string): strin
const chart = renderAttendanceBar(records);
const matrix = renderAttendanceMatrix(records);
- let extraHtml = '';
- if (records.length === 0) {
- extraHtml = '
暂无出勤记录
';
- }
-
- return pageFrame(`
- ${pageHeader('出勤记录')}
+ return sectionFrame(`
+ ${sectionHeader('出勤记录')}
${metricHtml}
- ${extraHtml}
${chart}
${matrix}
- ${pageFooter()}
`);
}
diff --git a/apps/server/src/archive/archive-report.cover.ts b/apps/server/src/archive/archive-report.cover.ts
index 7ed0618..70f0cb7 100644
--- a/apps/server/src/archive/archive-report.cover.ts
+++ b/apps/server/src/archive/archive-report.cover.ts
@@ -1,7 +1,7 @@
import { Student } from '../entities/student.entity';
import { StudentProfile } from '../entities/student-profile.entity';
import { StudentEnrollment } from '../entities/student-enrollment.entity';
-import { esc, pageFrame, pageFooter, pageHeader } from './archive-report.helpers';
+import { esc, sectionFrame, sectionHeader, coverFooter } from './archive-report.helpers';
import { buildEnrollmentSection } from './archive-report.enrollment';
export function buildCover(
@@ -9,11 +9,22 @@ export function buildCover(
profile: StudentProfile | null,
enrollments: StudentEnrollment[],
now: string,
+ tocNames: string[],
): string {
const types = enrollments.map((e) => e.classType).filter(Boolean).join(' / ') || '-';
- return pageFrame(`
- ${pageHeader('封面')}
+ const tocHtml =
+ tocNames.length > 0
+ ? tocNames
+ .map(
+ (name, i) => `
+ ${String(i + 1).padStart(2, '0')}${esc(name)}
`,
+ )
+ .join('')
+ : '暂无章节
';
+
+ return sectionFrame(`
+ ${sectionHeader('封面')}
学生档案报告
生成日期: ${esc(now)}
@@ -40,16 +51,10 @@ export function buildCover(
-
-
01基础信息与报读记录第 2 页
-
02考试成绩总览第 3 页
-
03出勤记录第 4 页
-
04文化课考试成绩第 5 页
-
05学情记录与录取归档第 6 页
-
+ ${tocHtml}
恭学教育
- ${pageFooter()}
- `);
+ ${coverFooter()}
+ `, true);
}
export function buildBasicInfo(
@@ -80,10 +85,9 @@ export function buildBasicInfo(
const enrollmentSection = buildEnrollmentSection(enrollments);
- return pageFrame(`
- ${pageHeader('基础信息')}
+ return sectionFrame(`
+ ${sectionHeader('基础信息')}
${infoCards}
${enrollmentSection}
- ${pageFooter()}
`);
}
diff --git a/apps/server/src/archive/archive-report.enrollment.ts b/apps/server/src/archive/archive-report.enrollment.ts
index 666e47a..6dada58 100644
--- a/apps/server/src/archive/archive-report.enrollment.ts
+++ b/apps/server/src/archive/archive-report.enrollment.ts
@@ -2,14 +2,10 @@ import { StudentEnrollment } from '../entities/student-enrollment.entity';
import { esc } from './archive-report.helpers';
export function buildEnrollmentSection(enrollments: StudentEnrollment[]): string {
- if (enrollments.length === 0) {
- return `暂无报读记录
`;
- }
+ if (enrollments.length === 0) return '';
const renderEnrollmentTable = (enrs: StudentEnrollment[]): string => {
- if (enrs.length === 0) {
- return `暂无数据
`;
- }
+ if (enrs.length === 0) return '';
let rows = '';
for (const e of enrs) {
@@ -46,35 +42,21 @@ export function buildEnrollmentSection(enrollments: StudentEnrollment[]): string
(!e.courseCategory.includes('文化') && !e.courseCategory.includes('专业')),
);
- if (cultureEnrollments.length > 0 || profEnrollments.length > 0) {
- let html =
- '报读记录
';
+ const cultureTable = renderEnrollmentTable(cultureEnrollments);
+ const profTable = renderEnrollmentTable(profEnrollments);
+ const otherTable = renderEnrollmentTable(otherEnrollments);
+
+ let html = '
报读记录
';
+ if (cultureTable && profTable) {
html += '
';
-
- html += '
';
- html += '
文化课报读
';
- html += renderEnrollmentTable(cultureEnrollments);
+ html += `
文化课报读
${cultureTable}`;
+ html += `
专业课报读
${profTable}`;
html += '
';
-
- html += '
';
- html += '
专业课报读
';
- html += renderEnrollmentTable(profEnrollments);
- html += '';
-
- html += '
';
-
- if (otherEnrollments.length > 0) {
- html +=
- '
其他报读
';
- html += renderEnrollmentTable(otherEnrollments);
- }
-
- html += '
';
- return html;
+ } else {
+ if (cultureTable) html += `
文化课报读
${cultureTable}`;
+ if (profTable) html += `
专业课报读
${profTable}`;
}
-
- return `
-
报读记录
- ${renderEnrollmentTable(enrollments)}
- `;
+ if (otherTable) html += `
其他报读
${otherTable}`;
+ html += '
';
+ return html;
}
diff --git a/apps/server/src/archive/archive-report.exam.ts b/apps/server/src/archive/archive-report.exam.ts
index e3df623..f099c5d 100644
--- a/apps/server/src/archive/archive-report.exam.ts
+++ b/apps/server/src/archive/archive-report.exam.ts
@@ -1,7 +1,9 @@
import { ExamScore } from '../entities/exam-score.entity';
-import { esc, pageFrame, pageFooter, pageHeader } from './archive-report.helpers';
+import { esc, sectionFrame, sectionHeader } from './archive-report.helpers';
export function buildExamOverview(exams: ExamScore[], now: string): string {
+ if (exams.length === 0) return '';
+
const cultureExams = exams.filter(
(e) => e.examType && e.examType.includes('文化'),
);
@@ -64,18 +66,11 @@ export function buildExamOverview(exams: ExamScore[], now: string): string {
const scoreTable = renderScoreTable(cultureExams);
const trendChart = renderScoreTrendChart(cultureExams);
- let extraHtml = '';
- if (cultureExams.length === 0) {
- extraHtml = '暂无文化课考试成绩
';
- }
-
- return pageFrame(`
- ${pageHeader('考试成绩总览')}
+ return sectionFrame(`
+ ${sectionHeader('考试成绩总览')}
${metricHtml}
- ${extraHtml}
${scoreTable}
${trendChart}
- ${pageFooter()}
`);
}
@@ -183,19 +178,7 @@ export function buildExamDetail(exams: ExamScore[], now: string): string {
(e) => e.examType && e.examType.includes('文化'),
);
- if (cultureExams.length === 0) {
- return pageFrame(`
- ${pageHeader('文化课考试成绩')}
-
-
-
${esc(now)} · 系统生成
-
文化课考试成绩
-
-
- 暂无文化课考试成绩
- ${pageFooter()}
- `);
- }
+ if (cultureExams.length === 0) return '';
// Group by subject
const subjectMap = new Map();
@@ -235,8 +218,8 @@ export function buildExamDetail(exams: ExamScore[], now: string): string {
`;
}
- return pageFrame(`
- ${pageHeader('文化课考试成绩')}
+ return sectionFrame(`
+ ${sectionHeader('文化课考试成绩')}
${esc(now)} · 系统生成
@@ -244,6 +227,5 @@ export function buildExamDetail(exams: ExamScore[], now: string): string {
${subjectCards}
- ${pageFooter()}
`);
}
diff --git a/apps/server/src/archive/archive-report.helpers.ts b/apps/server/src/archive/archive-report.helpers.ts
index f2ea33f..a905173 100644
--- a/apps/server/src/archive/archive-report.helpers.ts
+++ b/apps/server/src/archive/archive-report.helpers.ts
@@ -7,14 +7,14 @@ export function esc(value: string): string {
.replace(/'/g, ''');
}
-export function pageFrame(inner: string): string {
- return ``;
+export function sectionFrame(inner: string, cover = false): string {
+ return `${cover ? '
' : ''}${inner}
`;
}
-export function pageHeader(title: string): string {
+export function sectionHeader(title: string): string {
return ``;
}
-export function pageFooter(): string {
+export function coverFooter(): string {
return ``;
}
diff --git a/apps/server/src/archive/archive-report.learning.ts b/apps/server/src/archive/archive-report.learning.ts
index 2039e9d..db9c133 100644
--- a/apps/server/src/archive/archive-report.learning.ts
+++ b/apps/server/src/archive/archive-report.learning.ts
@@ -1,85 +1,61 @@
import { LearningRecord } from '../entities/learning-record.entity';
import { ResultArchive } from '../entities/result-archive.entity';
-import { esc, pageFrame, pageFooter, pageHeader } from './archive-report.helpers';
+import { esc, sectionFrame, sectionHeader } from './archive-report.helpers';
-export function buildLearningAndResult(
- learnings: LearningRecord[],
- result: ResultArchive | null,
- now: string,
-): string {
- let learningHtml = '';
- if (learnings.length === 0) {
- learningHtml = `
-
-
-
${esc(now)} · 系统生成
-
学情记录
-
-
- 暂无学情记录
`;
- } else {
- const latest = learnings.slice(0, 15);
- let rows = '';
- for (const r of latest) {
- rows += `
- | ${esc(r.recordDate || '-')} |
- ${esc(r.recordType || '-')} |
- ${esc((r.content || '-').slice(0, 200))} |
- ${esc(r.followUpMethod || '-')} |
-
`;
- }
+export function buildLearning(learnings: LearningRecord[], now: string): string {
+ if (learnings.length === 0) return '';
- learningHtml = `
-
-
-
${esc(now)} · 系统生成
-
学情记录
-
-
-
-
最近学情记录
-
-
- | 日期 | 类型 |
- 内容 | 跟进方式 |
-
- ${rows}
-
-
`;
+ const latest = learnings.slice(0, 15);
+ let rows = '';
+ for (const r of latest) {
+ rows += `
+ | ${esc(r.recordDate || '-')} |
+ ${esc(r.recordType || '-')} |
+ ${esc((r.content || '-').slice(0, 200))} |
+ ${esc(r.followUpMethod || '-')} |
+
`;
}
- let resultHtml = '';
- if (result) {
- resultHtml = `
-
-
+ return sectionFrame(`
+ ${sectionHeader('学情记录')}
+
+
+
${esc(now)} · 系统生成
+
学情记录
-
-
-
文化课成绩${result.cultureFinalScore != null ? result.cultureFinalScore : '-'}
-
专业课成绩${result.professionalFinalScore != null ? result.professionalFinalScore : '-'}
-
录取状态${esc(result.admissionStatus || '-')}
-
录取院校${esc(result.admittedCollege || '-')}
-
录取专业${esc(result.admittedMajor || '-')}
-
-
-
录取归档信息为最终结果,如有疑问请联系教务处
`;
- } else {
- resultHtml = `
-
-
暂无录取归档信息
`;
- }
-
- return pageFrame(`
- ${pageHeader('学情记录与录取归档')}
- ${learningHtml}
- ${resultHtml}
- ${pageFooter()}
+
+
+
最近学情记录
+
+
+ | 日期 | 类型 |
+ 内容 | 跟进方式 |
+
+ ${rows}
+
+
+ `);
+}
+
+export function buildResult(result: ResultArchive | null, now: string): string {
+ if (!result) return '';
+
+ return sectionFrame(`
+ ${sectionHeader('录取归档')}
+
+
+
+
文化课成绩${result.cultureFinalScore != null ? result.cultureFinalScore : '-'}
+
专业课成绩${result.professionalFinalScore != null ? result.professionalFinalScore : '-'}
+
录取状态${esc(result.admissionStatus || '-')}
+
录取院校${esc(result.admittedCollege || '-')}
+
录取专业${esc(result.admittedMajor || '-')}
+
+
+
录取归档信息为最终结果,如有疑问请联系教务处
`);
}
diff --git a/apps/server/src/archive/archive-report.service.spec.ts b/apps/server/src/archive/archive-report.service.spec.ts
index 457b337..6ec69b6 100644
--- a/apps/server/src/archive/archive-report.service.spec.ts
+++ b/apps/server/src/archive/archive-report.service.spec.ts
@@ -1,26 +1,45 @@
import { ArchiveReportService } from './archive-report.service';
+interface MockData {
+ student?: Record
;
+ profile?: Record | null;
+ enrollments?: Array>;
+ exams?: Array>;
+ learnings?: Array>;
+ result?: Record | null;
+ attendances?: Array>;
+}
+
+function makeService(data: MockData = {}): ArchiveReportService {
+ return new ArchiveReportService(
+ { findOne: jest.fn().mockResolvedValue(data.profile ?? null) } as never,
+ { find: jest.fn().mockResolvedValue(data.enrollments ?? []) } as never,
+ { find: jest.fn().mockResolvedValue(data.exams ?? []) } as never,
+ { find: jest.fn().mockResolvedValue(data.learnings ?? []) } as never,
+ { findOne: jest.fn().mockResolvedValue(data.result ?? null) } as never,
+ { find: jest.fn().mockResolvedValue(data.attendances ?? []) } as never,
+ {
+ findOne: jest.fn().mockResolvedValue(
+ data.student ?? { id: 1, name: '测试学生', studentNo: 'S001' },
+ ),
+ } as never,
+ );
+}
+
describe('ArchiveReportService retired profile fields', () => {
it('does not render the retired campus field in a student report', async () => {
- const service = new ArchiveReportService(
- { findOne: jest.fn().mockResolvedValue({ campusLocation: '旧校区', grade: '高三' }) } as never,
- { find: jest.fn().mockResolvedValue([]) } as never,
- { find: jest.fn().mockResolvedValue([]) } as never,
- { find: jest.fn().mockResolvedValue([]) } as never,
- { findOne: jest.fn().mockResolvedValue(null) } as never,
- { find: jest.fn().mockResolvedValue([]) } as never,
- {
- findOne: jest.fn().mockResolvedValue({
- id: 1,
- name: '测试学生',
- gender: '男',
- phone: '',
- ethnicity: '',
- emergencyContact: '',
- emergencyPhone: '',
- }),
- } as never,
- );
+ const service = makeService({
+ profile: { campusLocation: '旧校区', grade: '高三' },
+ student: {
+ id: 1,
+ name: '测试学生',
+ gender: '男',
+ phone: '',
+ ethnicity: '',
+ emergencyContact: '',
+ emergencyPhone: '',
+ },
+ });
const html = await service.generateReportHtml(1);
@@ -29,3 +48,73 @@ describe('ArchiveReportService retired profile fields', () => {
expect(html).toContain('高三');
});
});
+
+describe('ArchiveReportService empty sections', () => {
+ it('hides empty sections and removes fixed TOC page numbers', async () => {
+ const service = makeService({ profile: { grade: '高三' } });
+ const html = await service.generateReportHtml(1);
+
+ expect(html).toContain('学生档案报告');
+ expect(html).toContain('基础信息');
+ expect(html).not.toContain('考试成绩总览');
+ expect(html).not.toContain('出勤记录');
+ expect(html).not.toContain('文化课考试成绩');
+ expect(html).not.toContain('学情记录');
+ expect(html).not.toContain('录取归档');
+ expect(html).not.toContain('第 2 页');
+ expect(html).not.toContain('暂无');
+ });
+
+ it('renders sections with data and lists only those sections in the TOC', async () => {
+ const service = makeService({
+ profile: { grade: '高三' },
+ enrollments: [{ courseCategory: '文化课', classType: '全日制' }],
+ exams: [
+ {
+ examType: '文化课月考',
+ examName: '一月月考',
+ subject: '数学',
+ score: 88,
+ examDate: '2026-01-10',
+ },
+ ],
+ attendances: [
+ { attendanceDate: '2026-01-12', session: '上午', status: 'present' },
+ ],
+ learnings: [
+ {
+ recordDate: '2026-01-13',
+ recordType: '回访',
+ content: '状态良好',
+ followUpMethod: '电话',
+ },
+ ],
+ result: {
+ cultureFinalScore: 90,
+ professionalFinalScore: 85,
+ admissionStatus: '录取',
+ admittedCollege: '示例大学',
+ admittedMajor: '计算机',
+ },
+ });
+
+ const html = await service.generateReportHtml(1);
+
+ expect(html).toContain('考试成绩总览');
+ expect(html).toContain('出勤记录');
+ expect(html).toContain('文化课考试成绩');
+ expect(html).toContain('学情记录');
+ expect(html).toContain('录取归档');
+ expect(html).toContain('报读记录
');
+ expect(html).not.toContain('第 1 页');
+ expect(html).not.toContain('第 2 页');
+ });
+
+ it('omits the enrollment card when there are no enrollments', async () => {
+ const service = makeService({ profile: { grade: '高三' } });
+ const html = await service.generateReportHtml(1);
+
+ expect(html).not.toContain('报读记录
');
+ expect(html).not.toContain('暂无报读记录');
+ });
+});
diff --git a/apps/server/src/archive/archive-report.service.ts b/apps/server/src/archive/archive-report.service.ts
index 6994219..5542940 100644
--- a/apps/server/src/archive/archive-report.service.ts
+++ b/apps/server/src/archive/archive-report.service.ts
@@ -13,7 +13,7 @@ import { esc } from './archive-report.helpers';
import { buildCover, buildBasicInfo } from './archive-report.cover';
import { buildExamOverview, buildExamDetail } from './archive-report.exam';
import { buildAttendance } from './archive-report.attendance';
-import { buildLearningAndResult } from './archive-report.learning';
+import { buildLearning, buildResult } from './archive-report.learning';
interface ReportData {
student: Student;
@@ -71,17 +71,33 @@ export class ArchiveReportService {
day: 'numeric',
});
+ const sections = [
+ {
+ name: enrollments.length > 0 ? '基础信息与报读记录' : '基础信息',
+ html: buildBasicInfo(student, profile, enrollments, now),
+ },
+ { name: '考试成绩总览', html: buildExamOverview(exams, now) },
+ { name: '出勤记录', html: buildAttendance(attendances, now) },
+ { name: '文化课考试成绩', html: buildExamDetail(exams, now) },
+ { name: '学情记录', html: buildLearning(learnings, now) },
+ { name: '录取归档', html: buildResult(result, now) },
+ ].filter((section) => section.html.length > 0);
+
+ const cover = buildCover(
+ student,
+ profile,
+ enrollments,
+ now,
+ sections.map((section) => section.name),
+ );
+
return `
学生档案报告 - ${esc(name)}
-${buildCover(student, profile, enrollments, now)}
-${buildBasicInfo(student, profile, enrollments, now)}
-${buildExamOverview(exams, now)}
-${buildAttendance(attendances, now)}
-${buildExamDetail(exams, now)}
-${buildLearningAndResult(learnings, result, now)}
+${cover}
+${sections.map((section) => section.html).join('\n')}
`;
}
}
diff --git a/apps/server/src/archive/archive-report.styles.ts b/apps/server/src/archive/archive-report.styles.ts
index fa21ea8..54d2bde 100644
--- a/apps/server/src/archive/archive-report.styles.ts
+++ b/apps/server/src/archive/archive-report.styles.ts
@@ -6,10 +6,14 @@ export const ARCHIVE_REPORT_CSS = `
font-family: "PingFang SC", "Microsoft YaHei", Arial, sans-serif;
-webkit-print-color-adjust: exact; print-color-adjust: exact;
}
- .page {
- position: relative; width: 210mm; height: 297mm;
+ .section {
+ position: relative; width: 210mm; max-width: 100%;
margin: 0 auto 18px; padding: 14mm 15mm 10mm;
- overflow: hidden; background: #fff; page-break-after: always;
+ background: #fff;
+ }
+ .section-cover {
+ height: 297mm; overflow: hidden;
+ page-break-after: always; break-after: page;
}
.frame {
position: absolute; inset: 14mm; border: 1px solid #cfe0f2; pointer-events: none;
@@ -17,6 +21,7 @@ export const ARCHIVE_REPORT_CSS = `
.header {
position: relative; z-index: 1; display: flex; align-items: center;
height: 39px; padding-bottom: 8px; border-bottom: 1px solid #cfe0f2;
+ page-break-after: avoid; break-after: avoid;
}
.logo {
width: 24px; height: 24px; border-radius: 6px;
@@ -33,11 +38,13 @@ export const ARCHIVE_REPORT_CSS = `
font-size: 10px; color: #667085;
}
h1, h2, h3, p { margin: 0; }
+ h1, h2, h3 { page-break-after: avoid; break-after: avoid; }
.section-title { font-size: 24px; line-height: 1.24; font-weight: 800; }
.source { font-size: 12px; color: #667085; padding-bottom: 2px; }
.title-row {
display: flex; align-items: flex-end; justify-content: space-between;
margin: 26px 0 17px;
+ page-break-after: avoid; break-after: avoid;
}
.cover-title { margin-top: 60px; font-size: 34px; line-height: 1.22; font-weight: 800; }
.cover-subtitle { margin-top: 22px; font-size: 16px; color: #667085; }
@@ -60,7 +67,7 @@ export const ARCHIVE_REPORT_CSS = `
.value { font-size: 14px; line-height: 1.5; font-weight: 700; }
.toc { margin-top: 58px; }
.toc-row {
- display: grid; grid-template-columns: 48px 1fr 72px; align-items: center;
+ display: grid; grid-template-columns: 48px 1fr; align-items: center;
height: 47px; border-bottom: 1px solid #cfe0f2;
}
.toc-index { color: #155aa8; font-size: 15px; font-weight: 800; }
@@ -70,9 +77,18 @@ export const ARCHIVE_REPORT_CSS = `
position: absolute; right: 36px; bottom: 82px; color: #eaf1fb;
font-size: 56px; font-weight: 900; writing-mode: vertical-rl;
}
- .grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
- .grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
- .card { border: 1px solid #cfe0f2; padding: 14px; background: #fff; }
+ .grid-2 {
+ display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
+ page-break-inside: avoid; break-inside: avoid;
+ }
+ .grid-4 {
+ display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px;
+ page-break-inside: avoid; break-inside: avoid;
+ }
+ .card {
+ border: 1px solid #cfe0f2; padding: 14px; background: #fff;
+ page-break-inside: avoid; break-inside: avoid;
+ }
.card h3 { font-size: 16px; margin-bottom: 14px; }
.data-table {
width: 100%; border-collapse: collapse; table-layout: fixed;
@@ -86,8 +102,10 @@ export const ARCHIVE_REPORT_CSS = `
}
.data-table td { overflow-wrap: anywhere; word-break: break-word; }
.data-table .nowrap { white-space: nowrap; }
+ .data-table tr { page-break-inside: avoid; break-inside: avoid; }
.metric {
min-height: 88px; border: 1px solid #cfe0f2; padding: 13px 14px;
+ page-break-inside: avoid; break-inside: avoid;
}
.metric .label { margin-bottom: 7px; }
.metric strong {
@@ -107,13 +125,16 @@ export const ARCHIVE_REPORT_CSS = `
.note {
margin-top: 14px; padding: 12px 16px; border-left: 4px solid #155aa8;
background: #eef5ff; color: #173f6f; font-size: 12px; line-height: 1.7;
+ page-break-inside: avoid; break-inside: avoid;
}
- .banner-note {
- margin-top: 12px; padding: 11px 16px; background: #eef5ff;
- color: #173f6f; font-size: 12px; line-height: 1.7;
+ .line-chart {
+ width: 100%; height: 180px; display: block;
+ page-break-inside: avoid; break-inside: avoid;
+ }
+ .bar-chart {
+ width: 100%; height: 150px; display: block;
+ page-break-inside: avoid; break-inside: avoid;
}
- .line-chart { width: 100%; height: 180px; display: block; }
- .bar-chart { width: 100%; height: 150px; display: block; }
.status {
display: inline-flex; align-items: center; justify-content: center;
width: 18px; height: 18px; border-radius: 5px; margin-right: 6px;
@@ -137,6 +158,6 @@ export const ARCHIVE_REPORT_CSS = `
.muted { color: #667085; }
@media print {
body { background: #fff; }
- .page { margin: 0; box-shadow: none; }
+ .section { margin: 0; box-shadow: none; }
}
`;