Replace the HTML preview with a worker-rendered PDF preview
Rendering moves into a module Web Worker behind a latest-wins RenderClient with a watchdog and a handshake-based main-thread fallback. The preview shows the real PDF through pdf.js at 2x with zoom, page indicator, audit issues popover and a focus modal. A4/Letter and margin controls are frozen into each invoice at issue and can be saved as the default (migration M3). react-pdf and pdf.js are lazy-loaded; the main chunk shrinks from 1.8 MB to 0.5 MB. The HTML twin and its styles are removed.
This commit is contained in:
@@ -6,7 +6,7 @@ use tauri::State;
|
||||
pub(crate) const SETTINGS_COLS: &str = "vendor_name, vendor_address, vendor_email, vendor_phone, vendor_pan,
|
||||
vendor_gstin, vendor_state_code, logo_path, signature_path, default_bank_id, default_tax_rate,
|
||||
default_tax_type, payment_terms_days, currency, onboarded, theme, gst_registration, default_hsn_sac, signatory_name,
|
||||
signatory_designation";
|
||||
signatory_designation, render_prefs";
|
||||
|
||||
pub(crate) fn map_settings(row: &Row) -> rusqlite::Result<Settings> {
|
||||
Ok(Settings {
|
||||
@@ -30,6 +30,7 @@ pub(crate) fn map_settings(row: &Row) -> rusqlite::Result<Settings> {
|
||||
default_hsn_sac: row.get(17)?,
|
||||
signatory_name: row.get(18)?,
|
||||
signatory_designation: row.get(19)?,
|
||||
render_prefs: row.get(20)?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -54,7 +55,7 @@ pub fn save_settings(state: State<AppState>, settings: Settings) -> Result<Setti
|
||||
signature_path = ?9, default_bank_id = ?10, default_tax_rate = ?11,
|
||||
default_tax_type = ?12, payment_terms_days = ?13, currency = ?14,
|
||||
onboarded = ?15, theme = ?16, gst_registration = ?17, default_hsn_sac = ?18,
|
||||
signatory_name = ?19, signatory_designation = ?20
|
||||
signatory_name = ?19, signatory_designation = ?20, render_prefs = ?21
|
||||
WHERE id = 1"#,
|
||||
params![
|
||||
settings.vendor_name,
|
||||
@@ -77,6 +78,7 @@ pub fn save_settings(state: State<AppState>, settings: Settings) -> Result<Setti
|
||||
settings.default_hsn_sac,
|
||||
settings.signatory_name,
|
||||
settings.signatory_designation,
|
||||
settings.render_prefs,
|
||||
],
|
||||
)
|
||||
.map_err(|e| e.to_string())?;
|
||||
@@ -230,6 +232,26 @@ mod tests {
|
||||
(setting, flagged)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn settings_carry_render_prefs() {
|
||||
let conn = crate::db::open_in_memory().unwrap();
|
||||
let read = |conn: &Connection| {
|
||||
conn.query_row(
|
||||
&format!("SELECT {} FROM app_settings WHERE id = 1", SETTINGS_COLS),
|
||||
[],
|
||||
map_settings,
|
||||
)
|
||||
.unwrap()
|
||||
};
|
||||
assert_eq!(read(&conn).render_prefs, "");
|
||||
conn.execute("UPDATE app_settings SET render_prefs = ?1 WHERE id = 1", params!["{\"version\":1}"])
|
||||
.unwrap();
|
||||
let settings = read(&conn);
|
||||
assert_eq!(settings.render_prefs, "{\"version\":1}");
|
||||
let json = serde_json::to_value(&settings).unwrap();
|
||||
assert_eq!(json["renderPrefs"], "{\"version\":1}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deleting_the_default_bank_promotes_the_lowest_remaining() {
|
||||
let mut conn = crate::db::open_in_memory().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user