🚸(frontend) print from document options menu

We move the print button from the export select to
the document toolbox, so that it is more accessible
and easier to find.
This commit is contained in:
Anthony LC
2026-08-24 10:52:11 +02:00
parent 675483dce2
commit d28b0d8afc
5 changed files with 24 additions and 28 deletions
+1
View File
@@ -19,6 +19,7 @@ and this project adheres to
- ⚡️(frontend) replace onboarding assets with webm and webp #2569
- 💄(frontend) use the same highlight color for cells and moves #2575
- ⚡️(backend) optimize media_auth endpoint
- 🚸(frontend) print from document options menu #2550
### Fixed
@@ -30,7 +30,7 @@ test.describe('Doc Export', () => {
await expect(page.getByTestId('modal-export-title')).toBeVisible();
await expect(
page.getByText(
'Export your document to print or download in .docx, .odt, .pdf or .html(zip) format.',
'Export your document to download in .docx, .odt, .pdf or .html(zip) format.',
),
).toBeVisible();
await expect(page.getByRole('combobox', { name: 'Format' })).toBeVisible();
@@ -303,12 +303,7 @@ test.describe('Doc Export', () => {
await overrideDocContent({ page, browserName });
await clickInEditorMenu(page, 'Download');
await page.getByRole('combobox', { name: 'Format' }).click();
await page.getByRole('option', { name: 'Print' }).click();
await page.getByRole('button', { name: 'Print' }).click();
await clickInEditorMenu(page, 'Print');
await expect(page.locator('#print-only-content-styles')).toBeAttached();
@@ -1,3 +1,6 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 8V5H8V8H6V3H18V8H16ZM18 12.5C18.2833 12.5 18.5208 12.4042 18.7125 12.2125C18.9042 12.0208 19 11.7833 19 11.5C19 11.2167 18.9042 10.9792 18.7125 10.7875C18.5208 10.5958 18.2833 10.5 18 10.5C17.7167 10.5 17.4792 10.5958 17.2875 10.7875C17.0958 10.9792 17 11.2167 17 11.5C17 11.7833 17.0958 12.0208 17.2875 12.2125C17.4792 12.4042 17.7167 12.5 18 12.5ZM16 19V15H8V19H16ZM18 21H6V17H2V11C2 10.15 2.29167 9.4375 2.875 8.8625C3.45833 8.2875 4.16667 8 5 8H19C19.85 8 20.5625 8.2875 21.1375 8.8625C21.7125 9.4375 22 10.15 22 11V17H18V21ZM20 15V11C20 10.7167 19.9042 10.4792 19.7125 10.2875C19.5208 10.0958 19.2833 10 19 10H5C4.71667 10 4.47917 10.0958 4.2875 10.2875C4.09583 10.4792 4 10.7167 4 11V15H6V13H18V15H20Z" fill="#222631"/>
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M16 8V5H8V8H6V3H18V8H16ZM18 12.5C18.2833 12.5 18.5208 12.4042 18.7125 12.2125C18.9042 12.0208 19 11.7833 19 11.5C19 11.2167 18.9042 10.9792 18.7125 10.7875C18.5208 10.5958 18.2833 10.5 18 10.5C17.7167 10.5 17.4792 10.5958 17.2875 10.7875C17.0958 10.9792 17 11.2167 17 11.5C17 11.7833 17.0958 12.0208 17.2875 12.2125C17.4792 12.4042 17.7167 12.5 18 12.5ZM16 19V15H8V19H16ZM18 21H6V17H2V11C2 10.15 2.29167 9.4375 2.875 8.8625C3.45833 8.2875 4.16667 8 5 8H19C19.85 8 20.5625 8.2875 21.1375 8.8625C21.7125 9.4375 22 10.15 22 11V17H18V21ZM20 15V11C20 10.7167 19.9042 10.4792 19.7125 10.2875C19.5208 10.0958 19.2833 10 19 10H5C4.71667 10 4.47917 10.0958 4.2875 10.2875C4.09583 10.4792 4 10.7167 4 11V15H6V13H18V15H20Z"
fill="currentColor"
/>
</svg>

Before

Width:  |  Height:  |  Size: 842 B

After

Width:  |  Height:  |  Size: 837 B

@@ -40,14 +40,12 @@ import {
generateHtmlDocument,
improveHtmlAccessibility,
} from '../utils_html';
import { printDocumentWithStyles } from '../utils_print';
enum DocDownloadFormat {
HTML = 'html',
PDF = 'pdf',
DOCX = 'docx',
ODT = 'odt',
PRINT = 'print',
}
interface ModalExportProps {
@@ -82,18 +80,12 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
{ label: t('Docx'), value: DocDownloadFormat.DOCX },
{ label: t('ODT'), value: DocDownloadFormat.ODT },
{ label: t('HTML'), value: DocDownloadFormat.HTML },
{ label: t('Print'), value: DocDownloadFormat.PRINT },
];
const formatLabels = Object.fromEntries(
formatOptions.map((opt) => [opt.value, opt.label]),
);
const downloadButtonAriaLabel =
format === DocDownloadFormat.PRINT
? t('Print')
: t('Download {{format}}', { format: formatLabels[format] });
async function onSubmit() {
if (!editor) {
toast(t('The export failed'), VariantType.ERROR);
@@ -102,14 +94,6 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
setIsExporting(true);
// Handle print separately as it doesn't download a file
if (format === DocDownloadFormat.PRINT) {
printDocumentWithStyles();
setIsExporting(false);
onClose();
return;
}
const filename = (doc.title || untitledDocument)
.toLowerCase()
.normalize('NFD')
@@ -250,13 +234,15 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
</Button>
<Button
data-testid="doc-export-download-button"
aria-label={downloadButtonAriaLabel}
aria-label={t('Download {{format}}', {
format: formatLabels[format],
})}
variant="primary"
fullWidth
onClick={() => void onSubmit()}
disabled={isExporting}
>
{format === DocDownloadFormat.PRINT ? t('Print') : t('Download')}
{t('Download')}
</Button>
</>
}
@@ -295,7 +281,7 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
id="modal-export-description"
>
{t(
'Export your document to print or download in .docx, .odt, .pdf or .html(zip) format.',
'Export your document to download in .docx, .odt, .pdf or .html(zip) format.',
)}
</Text>
<Box ref={selectRef}>
@@ -18,12 +18,14 @@ import KeepOffSVG from '@/assets/icons/ui-kit/keep_off.svg';
import LeaveSVG from '@/assets/icons/ui-kit/leave.svg';
import LinkIcon from '@/assets/icons/ui-kit/link.svg';
import MoreSVG from '@/assets/icons/ui-kit/more_horiz.svg';
import PrintIcon from '@/assets/icons/ui-kit/print.svg';
import SharedIcon from '@/assets/icons/ui-kit/shared.svg';
import DeleteIcon from '@/assets/icons/ui-kit/trash.svg';
import { usePresenterStore } from '@/docs/doc-presenter/stores';
import { useAuth } from '@/features/auth';
import { useFocusStore, useResponsiveStore } from '@/stores';
import { printDocumentWithStyles } from '../../doc-export/utils_print';
import {
KEY_DOC,
KEY_LIST_DOC,
@@ -154,6 +156,15 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => {
},
isHidden: !ModalExport,
},
{
label: t('Print', {
description: 'Dropdown menu item to print the document',
}),
icon: <PrintIcon width={18} height={18} aria-hidden="true" />,
callback: () => {
printDocumentWithStyles();
},
},
{ type: 'separator' },
{
label: doc.is_favorite ? t('Unpin') : t('Pin'),