Skip to content

feat(pdf): add index section with bookmarks and page numbers to PDF report#1635

Open
AlexanderArce wants to merge 4 commits into
developfrom
f/pdf-pagination
Open

feat(pdf): add index section with bookmarks and page numbers to PDF report#1635
AlexanderArce wants to merge 4 commits into
developfrom
f/pdf-pagination

Conversation

@AlexanderArce
Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI review requested due to automatic review settings May 5, 2026 15:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the voting report PDF with a table-of-contents/index experience, adding localized strings plus PDF bookmarks, links, and visible page numbers in the report output.

Changes:

  • Add new process_pdf.document.bookmarks and process_pdf.document.index locale strings in all supported languages.
  • Update VotingReportPdf.tsx to insert an index page and render bookmark/page-number metadata in the PDF.
  • Expand VotingReportPdf.test.tsx to account for the extra page and new index/page-number structure.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/i18n/locales/it/common.json Adds Italian strings for PDF bookmarks and index text.
src/i18n/locales/es/common.json Adds Spanish strings for PDF bookmarks and index text.
src/i18n/locales/en/common.json Adds English strings for PDF bookmarks and index text.
src/i18n/locales/ca/common.json Adds Catalan strings for PDF bookmarks and index text.
src/components/Process/VotingReportPdf.tsx Implements the new index page, bookmark metadata, internal links, and report page numbers.
src/components/Process/VotingReportPdf.test.tsx Updates unit coverage for the extra PDF page and TOC/page-number rendering.

Comment on lines +759 to +763
<Page
size='A4'
style={styles.page}
bookmark={t('process_pdf.document.bookmarks.index', { defaultValue: 'Index' })}
>
Comment on lines +690 to +734
const buildReportSections = (t: TFunction): ReportSection[] => [
{
title: t('process_pdf.document.sections.general_information', { defaultValue: '1. General Information' }),
page: 1,
href: '#report-page-3',
},
{
title: t('process_pdf.document.sections.authentication', { defaultValue: '2. Authentication' }),
page: 1,
href: '#report-page-3',
},
{
title: t('process_pdf.document.sections.voting_system', { defaultValue: '3. Voting System' }),
page: 1,
href: '#report-page-3',
},
{
title: t('process_pdf.document.sections.electoral_census', { defaultValue: '4. Electoral Census' }),
page: 1,
href: '#report-page-3',
},
{
title: t('process_pdf.document.sections.turnout_participation', { defaultValue: '5. Turnout and Participation' }),
page: 1,
href: '#report-page-3',
},
{
title: t('process_pdf.document.sections.voting_process', { defaultValue: '6. Voting Process' }),
page: 2,
href: '#report-page-4',
},
{
title: t('process_pdf.document.sections.verification', { defaultValue: '7. Verification' }),
page: 2,
href: '#report-page-4',
},
{
title: t('process_pdf.document.sections.certification_scope', { defaultValue: '8. Certification Scope' }),
page: 2,
href: '#report-page-4',
},
{
title: t('process_pdf.document.sections.issuer', { defaultValue: '9. Issuer' }),
page: 3,
href: '#report-page-5',
Comment on lines +690 to +737
const buildReportSections = (t: TFunction): ReportSection[] => [
{
title: t('process_pdf.document.sections.general_information', { defaultValue: '1. General Information' }),
page: 1,
href: '#report-page-3',
},
{
title: t('process_pdf.document.sections.authentication', { defaultValue: '2. Authentication' }),
page: 1,
href: '#report-page-3',
},
{
title: t('process_pdf.document.sections.voting_system', { defaultValue: '3. Voting System' }),
page: 1,
href: '#report-page-3',
},
{
title: t('process_pdf.document.sections.electoral_census', { defaultValue: '4. Electoral Census' }),
page: 1,
href: '#report-page-3',
},
{
title: t('process_pdf.document.sections.turnout_participation', { defaultValue: '5. Turnout and Participation' }),
page: 1,
href: '#report-page-3',
},
{
title: t('process_pdf.document.sections.voting_process', { defaultValue: '6. Voting Process' }),
page: 2,
href: '#report-page-4',
},
{
title: t('process_pdf.document.sections.verification', { defaultValue: '7. Verification' }),
page: 2,
href: '#report-page-4',
},
{
title: t('process_pdf.document.sections.certification_scope', { defaultValue: '8. Certification Scope' }),
page: 2,
href: '#report-page-4',
},
{
title: t('process_pdf.document.sections.issuer', { defaultValue: '9. Issuer' }),
page: 3,
href: '#report-page-5',
},
]

Copilot AI review requested due to automatic review settings May 12, 2026 08:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.

Comments suppressed due to low confidence (1)

src/components/Process/VotingReportPdf.tsx:749

  • This PR removes the “Encryption method” row from generalInformation. Since the PR is focused on adding an index/bookmarks/page numbers, please confirm this removal is intentional; otherwise, re-add the encryption method field to avoid an unrelated report regression.
    generalInformation: [
      {
        label: t('process_pdf.general.organization', { defaultValue: 'Organization' }),
        value: organizationName || notAvailableLabel,
      },
      { label: t('process_pdf.general.event_name', { defaultValue: 'Event name' }), value: eventReference },
      {
        label: t('process_pdf.general.voting_period_start', { defaultValue: 'Voting period (start)' }),
        value: startDatetime,
      },
      {
        label: t('process_pdf.general.voting_period_end', { defaultValue: 'Voting period (end)' }),
        value: endDatetime,
      },
      {
        label: t('process_pdf.general.results_visibility', { defaultValue: 'Results visibility' }),
        value: resultsVisibility,
      },
      {
        label: t('process_pdf.general.network', { defaultValue: 'Network' }),
        value: blockchainNetwork,
      },
      {
        label: t('process_pdf.general.extended_process_details', { defaultValue: 'Extended process details' }),
        value: verificationExplorerLink,
      },
      {

<Page
size='A4'
style={styles.coverPage}
bookmark={t('process_pdf.document.bookmarks.index', { defaultValue: 'Index' })}
const SectionTitle = ({ children }: { children: string }) => <PdfText style={styles.sectionTitle}>{children}</PdfText>

const ReportSectionBlock = ({ children }: { children: ReactNode }) => (
<View wrap={false} style={styles.section}>
Comment on lines +966 to +1006
page: '1',
},
{
title: t('process_pdf.document.sections.authentication', { defaultValue: '2. Authentication' }),
href: '#report-page-3',
page: '1',
},
{
title: t('process_pdf.document.sections.voting_system', { defaultValue: '3. Voting System' }),
href: '#report-page-3',
page: '1',
},
{
title: t('process_pdf.document.sections.electoral_census', { defaultValue: '4. Electoral Census' }),
href: '#report-page-3',
page: '1',
},
{
title: t('process_pdf.document.sections.turnout_participation', { defaultValue: '5. Turnout and Participation' }),
href: '#report-page-3',
page: '1',
},
{
title: t('process_pdf.document.sections.voting_process', { defaultValue: '6. Voting Process' }),
href: '#report-page-4',
page: '2',
},
{
title: t('process_pdf.document.sections.verification', { defaultValue: '7. Verification' }),
href: '#report-page-4',
page: '2',
},
{
title: t('process_pdf.document.sections.certification_scope', { defaultValue: '8. Certification Scope' }),
href: '#report-page-5',
page: '3',
},
{
title: t('process_pdf.document.sections.issuer', { defaultValue: '9. Issuer' }),
href: '#report-page-5',
page: '3',
Comment thread src/i18n/locales/en/common.json Outdated
Comment on lines +1483 to +1486
"question": "Question: {{question}}",
"results": "Results:"
"results": "Results:",
"share": "Share",
"votes": "Votes"
Comment thread src/i18n/locales/es/common.json Outdated
Comment on lines +1506 to +1509
"question": "Pregunta: {{question}}",
"results": "Resultados:"
"results": "Resultados:",
"share": "Porcentaje",
"votes": "Votos"
Comment thread src/i18n/locales/ca/common.json Outdated
Comment on lines +1506 to +1509
"question": "Pregunta: {{question}}",
"results": "Resultats:"
"results": "Resultats:",
"share": "Percentatge",
"votes": "Vots"
Comment thread src/i18n/locales/it/common.json Outdated
Comment on lines +1506 to +1509
"question": "Domanda: {{question}}",
"results": "Risultati:"
"results": "Risultati:",
"share": "Quota",
"votes": "Voti"
Copilot AI review requested due to automatic review settings May 12, 2026 12:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

<Page
size='A4'
style={styles.coverPage}
bookmark={t('process_pdf.document.bookmarks.index', { defaultValue: 'Index' })}
Comment on lines 1129 to +1134
<Page size='A4' style={styles.page}>
<View style={styles.pageBrand}>
<Image src={vocdoniIcon} style={styles.pageBrandIcon} />
</View>
<RunningHeader />

<ReportSectionBlock>
<SectionTitle>{t('process_pdf.document.index.title', { defaultValue: 'Index' })}</SectionTitle>
<PdfText style={styles.indexIntro}>
const SectionTitle = ({ children }: { children: string }) => <PdfText style={styles.sectionTitle}>{children}</PdfText>

const ReportSectionBlock = ({ children }: { children: ReactNode }) => (
<View wrap={false} style={styles.section}>
Comment on lines +965 to +1006
href: '#report-page-3',
page: '1',
},
{
title: t('process_pdf.document.sections.authentication', { defaultValue: '2. Authentication' }),
href: '#report-page-3',
page: '1',
},
{
title: t('process_pdf.document.sections.voting_system', { defaultValue: '3. Voting System' }),
href: '#report-page-3',
page: '1',
},
{
title: t('process_pdf.document.sections.electoral_census', { defaultValue: '4. Electoral Census' }),
href: '#report-page-3',
page: '1',
},
{
title: t('process_pdf.document.sections.turnout_participation', { defaultValue: '5. Turnout and Participation' }),
href: '#report-page-3',
page: '1',
},
{
title: t('process_pdf.document.sections.voting_process', { defaultValue: '6. Voting Process' }),
href: '#report-page-4',
page: '2',
},
{
title: t('process_pdf.document.sections.verification', { defaultValue: '7. Verification' }),
href: '#report-page-4',
page: '2',
},
{
title: t('process_pdf.document.sections.certification_scope', { defaultValue: '8. Certification Scope' }),
href: '#report-page-5',
page: '3',
},
{
title: t('process_pdf.document.sections.issuer', { defaultValue: '9. Issuer' }),
href: '#report-page-5',
page: '3',
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants