fix(print): fix app-wide printing and remove a global print-CSS leak
Root cause of blank/clipped print output across the app: the document root (html/body) is globally locked to one viewport height with overflow hidden, and Angular Material's drawer/tab-body containers each add their own on-screen scroll clip on top of that. main.scss now frees the full chain for print (document root, CDK drawer/sidenav containers, mat-tab-body, and the account-view's mat-tab-nav-bar which was rendering as a stray grey scrollable strip since it isn't covered by the mat-tab-group header rule already hidden). Also fixed both certificate print dialogs (share-certificate-dialog, deposit-certificate-dialog) reusing a `::ng-deep body > :not(.cdk-overlay- container)` rule to hide the shell during their own print: under Angular's style encapsulation this style is emitted fully unscoped into the global stylesheet and is never removed once the component has loaded once in a session, silently blanking every other page's print output for the rest of the session. Dropped `::ng-deep` from that one selector so it goes back to being properly scoped (and therefore inert, matching the other two dialogs that never had this bug) — the app shell is already hidden for every print via the global main.scss rules, so no dialog needs its own global override.
This commit is contained in:
+6
-10
@@ -576,13 +576,11 @@
|
||||
}
|
||||
|
||||
/* ───────── Print — only the page, no toolbar / dialog chrome ─────────
|
||||
This dialog is opened with `maxHeight: '92vh'`, which Angular Material carries onto the
|
||||
overlay pane / .mat-mdc-dialog-container as an inline max-height + overflow:auto clip.
|
||||
`position: absolute` still lives inside that clip and gets cut off — only the on-screen
|
||||
scroll position prints. `position: fixed` escapes it: a fixed element's containing block is
|
||||
the viewport itself, not the clipped ancestor (the classic "fixed child ignores an
|
||||
overflow:hidden parent" behaviour), as long as nothing between here and the viewport sets a
|
||||
transform/filter — the CDK overlay chrome doesn't. */
|
||||
The document-level clip (`html, body { overflow: hidden }`) is lifted globally in main.scss's
|
||||
print block; what remains here is this dialog's own clip — it opens with `maxHeight: '92vh'`,
|
||||
which Angular Material carries onto the overlay pane / .mat-mdc-dialog-container as an inline
|
||||
max-height plus overflow:auto. Freeing those lets the whole certificate flow onto the page in
|
||||
normal static order (a fixed/absolute hack would pin it to the first page instead). */
|
||||
@media print {
|
||||
body > :not(.cdk-overlay-container) {
|
||||
display: none !important;
|
||||
@@ -611,9 +609,7 @@
|
||||
}
|
||||
|
||||
.cpd-root {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
position: static;
|
||||
width: 100% !important;
|
||||
height: auto !important;
|
||||
background: #fff;
|
||||
|
||||
+175
-6
@@ -384,18 +384,59 @@
|
||||
|
||||
/* Print CSS */
|
||||
@media print {
|
||||
/* Hide non-overlay contents during print */
|
||||
::ng-deep html,
|
||||
::ng-deep body {
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
/* Hide non-overlay contents during print. Deliberately NOT `::ng-deep` here: under Angular's
|
||||
emulated encapsulation a bare `body` selector never carries this component's scoping
|
||||
attribute, so a scoped rule can never match the real <body> and is safely inert — whereas
|
||||
`::ng-deep` emits it fully unscoped into the GLOBAL stylesheet for the rest of the session
|
||||
(Angular never removes a component's injected styles when it's destroyed), silently hiding
|
||||
every other page's print output app-wide the moment this dialog is opened once. The app
|
||||
shell (nav, toolbar, sidebar) is already hidden for every print via the global rules in
|
||||
main.scss, so this dialog doesn't need its own global override to get the same effect. */
|
||||
body > :not(.cdk-overlay-container) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* The dialog's own scroll region clips anything past 80vh -- printing only captures what a
|
||||
scrollable/max-height box shows on screen, so both constraints must be lifted. */
|
||||
.dialog-content-container {
|
||||
max-height: none !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
/* CDK's overlay wrapper/backdrop/pane are all position: fixed. Unset them so the full certificate prints statically. */
|
||||
::ng-deep .cdk-overlay-backdrop {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
::ng-deep .cdk-overlay-container,
|
||||
::ng-deep .cdk-global-overlay-wrapper,
|
||||
::ng-deep .cdk-overlay-pane,
|
||||
::ng-deep .mat-mdc-dialog-container,
|
||||
::ng-deep .mdc-dialog__container,
|
||||
::ng-deep .mdc-dialog__surface {
|
||||
position: static !important;
|
||||
display: block !important;
|
||||
max-height: none !important;
|
||||
max-width: none !important;
|
||||
height: auto !important;
|
||||
width: auto !important;
|
||||
overflow: visible !important;
|
||||
transform: none !important;
|
||||
box-shadow: none !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
/* Make certificate fill page */
|
||||
#share-certificate-print {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
position: static !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
height: auto !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
background-color: #fff !important;
|
||||
@@ -411,7 +452,135 @@
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mat-mdc-dialog-container {
|
||||
::ng-deep .mat-mdc-dialog-container {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* Compact every spacing/font value so the whole certificate fits a single printed page */
|
||||
.certificate-container {
|
||||
padding: 6px !important;
|
||||
}
|
||||
|
||||
.certificate-border-inner {
|
||||
padding: 14px !important;
|
||||
}
|
||||
|
||||
.certificate-header {
|
||||
margin-bottom: 10px !important;
|
||||
padding-bottom: 10px !important;
|
||||
|
||||
.bank-name {
|
||||
font-size: 19px !important;
|
||||
margin-bottom: 2px !important;
|
||||
}
|
||||
|
||||
.bank-sub {
|
||||
font-size: 10px !important;
|
||||
margin-bottom: 8px !important;
|
||||
}
|
||||
|
||||
.cert-title {
|
||||
font-size: 19px !important;
|
||||
letter-spacing: 2px !important;
|
||||
margin-bottom: 2px !important;
|
||||
}
|
||||
|
||||
.cert-subtitle {
|
||||
font-size: 9px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.cert-meta-row {
|
||||
margin-bottom: 10px !important;
|
||||
padding-bottom: 8px !important;
|
||||
|
||||
.meta-label {
|
||||
font-size: 9px !important;
|
||||
margin-bottom: 1px !important;
|
||||
}
|
||||
|
||||
.meta-value {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.cert-body-section {
|
||||
margin-bottom: 10px !important;
|
||||
|
||||
.cert-main-text {
|
||||
font-size: 11px !important;
|
||||
line-height: 1.4 !important;
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.issued-to-details {
|
||||
padding: 8px 14px !important;
|
||||
margin: 8px auto !important;
|
||||
|
||||
.client-name-details {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
.client-ids,
|
||||
.client-address {
|
||||
font-size: 10px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.certificate-details-table {
|
||||
margin-bottom: 12px !important;
|
||||
|
||||
td {
|
||||
padding: 5px 10px !important;
|
||||
font-size: 10px !important;
|
||||
}
|
||||
|
||||
.lbl-col-highlight {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
.val-col-highlight {
|
||||
font-size: 13px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.allotment-table {
|
||||
margin-bottom: 12px !important;
|
||||
|
||||
th {
|
||||
padding: 4px 8px !important;
|
||||
font-size: 8px !important;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 4px 8px !important;
|
||||
font-size: 9px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.cert-footer {
|
||||
margin-top: 8px !important;
|
||||
|
||||
.seal-ring {
|
||||
width: 60px !important;
|
||||
height: 60px !important;
|
||||
}
|
||||
|
||||
.seal-text {
|
||||
font-size: 8px !important;
|
||||
}
|
||||
|
||||
.closing-text {
|
||||
font-size: 10px !important;
|
||||
}
|
||||
|
||||
.signature-line {
|
||||
height: 22px !important;
|
||||
}
|
||||
|
||||
.signatory-title {
|
||||
font-size: 10px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+102
-11
@@ -982,6 +982,16 @@ mat-card {
|
||||
.mat-mdc-tab-header,
|
||||
.mat-stepper-vertical-line,
|
||||
.mat-step-header,
|
||||
/* Account-view pages (Shares, Savings, Current, Deposits…) use `<nav mat-tab-nav-bar
|
||||
class="navigation-tabs">` for their General/Passbook/Charges/… tab links — a DIFFERENT
|
||||
Material component from mat-tab-group, so it never carries `.mat-mdc-tab-header` and slipped
|
||||
past the rule above. Its own style (theme/_content.scss) gives it a grey background and
|
||||
`overflow: auto`, which is exactly the grey box with a baked-in scrollbar seen in print/PDF
|
||||
output — printing it is as pointless as printing the tab-group header already excluded above. */
|
||||
.navigation-tabs,
|
||||
[mat-tab-nav-bar],
|
||||
.mat-mdc-tab-nav-bar,
|
||||
.mat-mdc-tab-link-container,
|
||||
/* The real 2-row nav menu (Client Master / Approvals / Cashier … and the row below it) and the
|
||||
live KPI ticker live directly in shell.component.html as .main-header / .kpi-ticker, not
|
||||
inside <mifosx-toolbar> — hiding only the toolbar left this menu printing on every page. */
|
||||
@@ -997,17 +1007,57 @@ mat-card {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
/* The whole app shell scrolls inside CDK's own clipped viewport —
|
||||
.mat-drawer-container { overflow: hidden } and .mat-drawer-content { overflow: auto; height: 100% }
|
||||
— so without freeing these too, print is still capped to one screen's worth of the page
|
||||
regardless of the tab-body fix below. */
|
||||
/* THE root clip: assets/styles/_overflow.scss sets `html, body { overflow: hidden }` and
|
||||
index.html puts `h-full` (height: 100%) on both, so the document itself is locked to exactly
|
||||
one viewport and everything past it is cut away. Every inner container fix below is useless
|
||||
while this stands — it is why printing any page produced a blank sheet with only a sliver of
|
||||
whatever happened to sit at the fold. */
|
||||
html,
|
||||
body {
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
width: 100% !important;
|
||||
background: #fff !important;
|
||||
|
||||
/* Keep backgrounds/colours (certificate rules, table shading) instead of dropping them. */
|
||||
print-color-adjust: exact;
|
||||
}
|
||||
|
||||
/* The shell then scrolls inside CDK's own clipped viewport —
|
||||
#mifosx-shell-container { height: 100vh }, .mat-drawer-content { height: 100%; overflow: auto }
|
||||
— so these have to be freed as well. */
|
||||
#mifosx-shell-container,
|
||||
mat-sidenav-container,
|
||||
mat-drawer-container,
|
||||
mat-sidenav-content,
|
||||
mat-drawer-content,
|
||||
.mat-drawer-container,
|
||||
.mat-drawer-content,
|
||||
mat-sidenav-content.sidenav {
|
||||
position: static !important;
|
||||
.mat-sidenav-content {
|
||||
overflow: visible !important;
|
||||
height: auto !important;
|
||||
max-height: none !important;
|
||||
|
||||
/* Material's own theme paints a background-color on .mat-drawer-container — without
|
||||
overriding it here, that grey shows behind every printed page even though html/body are
|
||||
already forced white above. */
|
||||
background: #fff !important;
|
||||
}
|
||||
|
||||
/* shell.component.scss:247-271 scopes `mifosx-content { overflow-x: hidden; max-width: 100% }`
|
||||
specifically to `.sidenav mifosx-content` so tables/cards shrink to fit whenever the sidebar
|
||||
is open on screen — this rule has nothing to do with the sidebar being hidden for print, and
|
||||
without overriding it too, the routed page content keeps clipping/scrolling horizontally to
|
||||
whatever width was last measured on screen, which is exactly the narrow box with a baked-in
|
||||
scrollbar seen in print/PDF output. */
|
||||
mifosx-content,
|
||||
.sidenav mifosx-content,
|
||||
mat-tab-nav-panel,
|
||||
.mat-mdc-tab-nav-panel {
|
||||
overflow: visible !important;
|
||||
width: auto !important;
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
/* Angular Material clips a tab's content to a JS-measured on-screen height via
|
||||
@@ -1023,11 +1073,6 @@ mat-card {
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
body,
|
||||
html {
|
||||
background: #fff !important;
|
||||
}
|
||||
|
||||
@page {
|
||||
/* stylelint-disable-next-line unit-allowed-list */
|
||||
margin: 1.5cm;
|
||||
@@ -1869,3 +1914,49 @@ mifosx-client-datatable-step * {
|
||||
--mdc-checkbox-selected-pressed-icon-color: #059669;
|
||||
}
|
||||
/* stylelint-enable selector-max-universal */
|
||||
|
||||
/* ==========================================================================
|
||||
Global Print Styles for Material Dialogs & Certificates
|
||||
========================================================================== */
|
||||
@media print {
|
||||
html,
|
||||
body {
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
background: #fff !important;
|
||||
}
|
||||
|
||||
/* Hide main application shell during dialog printing */
|
||||
body > :not(.cdk-overlay-container) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Remove fixed positioning on CDK overlay elements so content flows naturally */
|
||||
.cdk-overlay-backdrop {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.cdk-overlay-container,
|
||||
.cdk-global-overlay-wrapper,
|
||||
.cdk-overlay-pane,
|
||||
.mat-mdc-dialog-container,
|
||||
.mdc-dialog__container,
|
||||
.mdc-dialog__surface {
|
||||
position: static !important;
|
||||
display: block !important;
|
||||
max-height: none !important;
|
||||
max-width: none !important;
|
||||
height: auto !important;
|
||||
width: auto !important;
|
||||
overflow: visible !important;
|
||||
transform: none !important;
|
||||
box-shadow: none !important;
|
||||
background: transparent !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.no-print,
|
||||
.mat-mdc-dialog-actions {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user