fix: improve native print output for dashboards and record tables (#22272)

## Summary

- Adds print-specific snapshots for dashboards so native browser
print/PDF captures charts and front components instead of the app shell.
- Adds record-table print snapshots for object index pages so printable
tables are generated from visible rows and native print avoids
virtualized blank pages.
- Preserves rendered chart layers by rasterizing canvas/SVG content for
print.

## AI-generated disclosure

This pull request was AI-generated by Hermes Agent on behalf of Vittorio
Alfieri. The changes were reviewed and tested locally before submission.

## Screenshots

### Dashboard print

**Before**

![Dashboard print
before](https://raw.githubusercontent.com/vittolago/twenty/fix/dashboard-native-print/packages/twenty-front/docs/print-screenshots/dashboard-before.png)

**After**

![Dashboard print
after](https://raw.githubusercontent.com/vittolago/twenty/fix/dashboard-native-print/packages/twenty-front/docs/print-screenshots/dashboard-after.png)

### Table records print

**Before**

![Table records print
before](https://raw.githubusercontent.com/vittolago/twenty/fix/dashboard-native-print/packages/twenty-front/docs/print-screenshots/tasks-before.png)

**After**

![Table records print
after](https://raw.githubusercontent.com/vittolago/twenty/fix/dashboard-native-print/packages/twenty-front/docs/print-screenshots/tasks-after.png)

## Test plan

- [x] `yarn nx typecheck twenty-front`
- [x] `yarn nx build twenty-front`
- [x] Generated dashboard PDFs from the preview build and rasterized
pages to PNG for visual verification.
- [x] Generated Tasks/table-record PDFs from the preview build and
verified the final page contains table content instead of blank pages.


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22272?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
vittolago
2026-06-29 15:41:37 -05:00
committed by GitHub
parent 78cbe498f6
commit fb800e7a2d
7 changed files with 175 additions and 9 deletions
@@ -11,6 +11,17 @@ import { RecordTableRecordLimitReloadEffect } from '@/object-record/record-table
import { PageFocusId } from '@/types/PageFocusId';
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
import { styled } from '@linaria/react';
const StyledRecordTablePrintBoundary = styled.div`
display: contents;
@media print {
display: block;
max-height: 100vh;
overflow: hidden;
}
`;
type RecordTableWithWrappersProps = {
objectNameSingular: string;
@@ -60,12 +71,14 @@ export const RecordTableWithWrappers = ({
onRecordIdentifierClick={handleRecordIdentifierClick}
>
<EntityDeleteContext.Provider value={deleteOneRecord}>
<ScrollWrapper
componentInstanceId={`record-table-scroll-${recordTableId}`}
>
<RecordTableRecordLimitReloadEffect />
<RecordTable />
</ScrollWrapper>
<StyledRecordTablePrintBoundary>
<ScrollWrapper
componentInstanceId={`record-table-scroll-${recordTableId}`}
>
<RecordTableRecordLimitReloadEffect />
<RecordTable />
</ScrollWrapper>
</StyledRecordTablePrintBoundary>
</EntityDeleteContext.Provider>
</RecordTableContextProvider>
</RecordTableComponentInstance>