mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) Improve printing of tables, fix printing of charts, add a browser test.
Summary: - Include column headers on each page for printing tables. - Avoid page-breaks inside rows or cards of a card-list. - Fix printing of charts that did not show up at all before. - Add a browser test, not great, but somewhat functional. Test Plan: New test, plus tested manually. Column headers work on Chrome and Firefox (not Safari). Reviewers: paulfitz Reviewed By: paulfitz Differential Revision: https://phab.getgrist.com/D2636
This commit is contained in:
parent
4d3777578e
commit
5247521cb8
@ -7,6 +7,7 @@ import {fromKoSave} from 'app/client/lib/fromKoSave';
|
|||||||
import {loadPlotly, PlotlyType} from 'app/client/lib/imports';
|
import {loadPlotly, PlotlyType} from 'app/client/lib/imports';
|
||||||
import * as DataTableModel from 'app/client/models/DataTableModel';
|
import * as DataTableModel from 'app/client/models/DataTableModel';
|
||||||
import {ViewFieldRec, ViewSectionRec} from 'app/client/models/DocModel';
|
import {ViewFieldRec, ViewSectionRec} from 'app/client/models/DocModel';
|
||||||
|
import {reportError} from 'app/client/models/errors';
|
||||||
import {KoSaveableObservable, ObjObservable} from 'app/client/models/modelUtil';
|
import {KoSaveableObservable, ObjObservable} from 'app/client/models/modelUtil';
|
||||||
import {SortedRowSet} from 'app/client/models/rowset';
|
import {SortedRowSet} from 'app/client/models/rowset';
|
||||||
import {cssRow} from 'app/client/ui/RightPanel';
|
import {cssRow} from 'app/client/ui/RightPanel';
|
||||||
@ -131,6 +132,10 @@ export class ChartView extends Disposable {
|
|||||||
this.autoDispose(this.sortedRows.getKoArray().subscribe(this._update));
|
this.autoDispose(this.sortedRows.getKoArray().subscribe(this._update));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public prepareToPrint(onOff: boolean) {
|
||||||
|
Plotly.relayout(this._chartDom, {}).catch(reportError);
|
||||||
|
}
|
||||||
|
|
||||||
protected onTableLoaded() {
|
protected onTableLoaded() {
|
||||||
(BaseView.prototype as any).onTableLoaded.call(this);
|
(BaseView.prototype as any).onTableLoaded.call(this);
|
||||||
this._update();
|
this._update();
|
||||||
|
@ -270,3 +270,15 @@
|
|||||||
margin-right: -6px; /* allow labels to overflow into the padding */
|
margin-right: -6px; /* allow labels to overflow into the padding */
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
.detail_theme_record_compact {
|
||||||
|
background-color: var(--grist-color-medium-grey) !important;
|
||||||
|
}
|
||||||
|
.detail_theme_record_compact > .g_record_detail_inner {
|
||||||
|
background-color: white !important;
|
||||||
|
}
|
||||||
|
.detail_theme_field_blocks {
|
||||||
|
background-color: var(--grist-color-medium-grey) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -99,6 +99,33 @@
|
|||||||
.gridview_data_header {
|
.gridview_data_header {
|
||||||
background-color: var(--grist-color-light-grey) !important;
|
background-color: var(--grist-color-light-grey) !important;
|
||||||
}
|
}
|
||||||
|
.print-widget .gridview_header_backdrop_left, .print-widget .gridview_data_corner_overlay {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.print-widget .gridview_data_scroll {
|
||||||
|
display: table;
|
||||||
|
border-collapse: collapse;
|
||||||
|
position: relative !important;
|
||||||
|
height: max-content !important;
|
||||||
|
}
|
||||||
|
.print-widget .gridview_stick-top {
|
||||||
|
/* The next two styles *together* tell Chrome to repeat this header on each page */
|
||||||
|
display: table-header-group;
|
||||||
|
break-inside: avoid;
|
||||||
|
position: static;
|
||||||
|
border-top: 1px solid var(--grist-color-dark-grey);
|
||||||
|
border-left: 1px solid var(--grist-color-dark-grey);
|
||||||
|
}
|
||||||
|
.print-widget .gridview_data_header {
|
||||||
|
padding-left: 4rem !important;
|
||||||
|
}
|
||||||
|
.print-widget .gridview_data_pane .print-all-rows {
|
||||||
|
display: table-row-group;
|
||||||
|
border-left: 1px solid var(--grist-color-dark-grey);
|
||||||
|
}
|
||||||
|
.print-widget .gridview_data_pane .print-row {
|
||||||
|
display: table-row;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========= Overlay styles ========== */
|
/* ========= Overlay styles ========== */
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
.print-widget {
|
.print-widget {
|
||||||
margin: 0px !important;
|
margin: 0px !important;
|
||||||
}
|
}
|
||||||
|
.print-row {
|
||||||
|
break-inside: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
.print-widget .viewsection_title {
|
.print-widget .viewsection_title {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
@ -35,13 +38,6 @@
|
|||||||
position: relative !important;
|
position: relative !important;
|
||||||
height: max-content !important;
|
height: max-content !important;
|
||||||
overflow: visible !important;
|
overflow: visible !important;
|
||||||
border-top: 1px solid var(--grist-color-dark-grey);
|
|
||||||
border-left: 1px solid var(--grist-color-dark-grey);
|
|
||||||
}
|
|
||||||
|
|
||||||
.print-widget .gridview_data_scroll {
|
|
||||||
position: relative !important;
|
|
||||||
height: max-content !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.print-widget .scrolly_outer {
|
.print-widget .scrolly_outer {
|
||||||
@ -51,6 +47,21 @@
|
|||||||
.print-widget .custom_view {
|
.print-widget .custom_view {
|
||||||
height: calc(100vh - 24px);
|
height: calc(100vh - 24px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ui-resizable-handle {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The chart div needs to be measured before its relayout() call, and "@media print" is not in
|
||||||
|
* effect for that measurement, so we temporarily resize the chart for all @media, to a plausible
|
||||||
|
* size for printing.
|
||||||
|
*/
|
||||||
|
.print-widget .chart_container {
|
||||||
|
width: 6.5in !important;
|
||||||
|
height: 6.5in !important;
|
||||||
|
overflow: visible !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media not print {
|
@media not print {
|
||||||
|
@ -67,15 +67,19 @@ export async function printViewSection(layout: any, viewSection: ViewSectionRec)
|
|||||||
const sub2 = dom.onElem(window, 'afterprint', () => {
|
const sub2 = dom.onElem(window, 'afterprint', () => {
|
||||||
sub1.dispose();
|
sub1.dispose();
|
||||||
sub2.dispose();
|
sub2.dispose();
|
||||||
// To debug printing, set window.debugPringint=1 in the console, then print a section, dismiss
|
// To debug printing, set window.debugPrinting=1 in the console, then print a section, dismiss
|
||||||
// the print dialog, switch to "@media print" emulation, and you can explore the styles. You'd
|
// the print dialog, switch to "@media print" emulation, and you can explore the styles. You'd
|
||||||
// need to reload the page to do it again.
|
// need to call window.finishPrinting() or reload the page to do it again.
|
||||||
if (!(window as any).debugPrinting) {
|
if ((window as any).debugPrinting) {
|
||||||
|
(window as any).finishPrinting = () => prepareToPrint(false);
|
||||||
|
} else {
|
||||||
prepareToPrint(false);
|
prepareToPrint(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.print();
|
// Running print on a timeout makes it possible to test printing using selenium, and doesn't
|
||||||
|
// seem to affect normal printing.
|
||||||
|
setTimeout(() => window.print(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -97,7 +101,7 @@ export function renderAllRows(
|
|||||||
rowModel._index(index);
|
rowModel._index(index);
|
||||||
rowModel.assign(rowId);
|
rowModel.assign(rowId);
|
||||||
const elem = renderRow(rowModel);
|
const elem = renderRow(rowModel);
|
||||||
html.push(elem.outerHTML);
|
html.push(`<div class="print-row">${elem.outerHTML}</div>`);
|
||||||
dom.domDispose(elem);
|
dom.domDispose(elem);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user