From d7af4414111309623f44d905c05002fc3d93e38b Mon Sep 17 00:00:00 2001 From: Vladimir Simakhin Date: Thu, 21 Mar 2024 11:01:16 +0100 Subject: [PATCH 1/5] custom title page for pdf export, some draft --- .gitignore | 2 +- cmd/web/handlers_export.go | 1 - cmd/web/templates/export-a4.partials.gohtml | 21 +++- cmd/web/templates/export-js.partials.gohtml | 108 +++++++++++++++++--- go.mod | 2 + go.sum | 5 + internal/models/structs.go | 1 + internal/pdfexport/pdfexport.go | 26 +++++ 8 files changed, 145 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index f74ec06..5be2b30 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -logbook.pdf +*.pdf map.png .logbook.json diff --git a/cmd/web/handlers_export.go b/cmd/web/handlers_export.go index ea966fc..13ca181 100644 --- a/cmd/web/handlers_export.go +++ b/cmd/web/handlers_export.go @@ -89,7 +89,6 @@ func (app *application) HandlerExportLogbook(w http.ResponseWriter, r *http.Requ } else { err = errors.New("unknown export format") - } if err != nil { diff --git a/cmd/web/templates/export-a4.partials.gohtml b/cmd/web/templates/export-a4.partials.gohtml index e541ea8..1302888 100644 --- a/cmd/web/templates/export-a4.partials.gohtml +++ b/cmd/web/templates/export-a4.partials.gohtml @@ -375,8 +375,10 @@
-
- +
+ +
+
@@ -389,6 +391,21 @@
+
+
+ +
+
+
+ + + + + +
+
+
+
diff --git a/cmd/web/templates/export-js.partials.gohtml b/cmd/web/templates/export-js.partials.gohtml index 632b9f3..571369e 100644 --- a/cmd/web/templates/export-js.partials.gohtml +++ b/cmd/web/templates/export-js.partials.gohtml @@ -5,7 +5,78 @@ // WebLogbook Export Namespace wlbExport = function () { - function saveExportA4() { + const formatMap = { + "A4": "custom_title_a4", + "A5": "custom_title_a5" + }; + + async function getCustomTitle(format) { + const attachments_url = "{{index .API "LogbookUUIDAttachments"}}"; + + if (!formatMap[format]) {return;} + + const url = attachments_url.replace("{uuid}", formatMap[format]); + const data = await wlbCommon.getJSON(url); + if (data.length > 0) { + return data[0].uuid; + } else { + return "" + } + } + + async function previewCustomTitle(format) { + if (!formatMap[format]) {return;} + + const uuid = await getCustomTitle(format); + if (uuid !== "") { + window.open("{{$api.LogbookAttachmentsDownload}}"+uuid, "_blank"); + } + } + + async function deleteCustomTitle(format) { + // drop current saved file from attachments + const attachments_url = "{{index .API "LogbookUUIDAttachments"}}".replace("{uuid}", formatMap[format]); + const data = await wlbCommon.getJSON(attachments_url); + + if (data.length > 0) { + for (let i = 0; i < data.length; i++) { + const payload = {uuid: data[i].uuid} + const requestOptions = {method: "post", body: JSON.stringify(payload)}; + await fetch("{{index .API "LogbookAttachmentsDelete"}}", requestOptions) + } + } + } + + async function saveCustomTitle(format) { + const custom_title_element = document.getElementById(formatMap[format]); + const file = custom_title_element.files[0]; + + if (file) { + await deleteCustomTitle(format); + + // upload new file as attachment + let payload = new FormData(); + payload.append("document", file); + payload.append("record_id", formatMap[format]); + + const requestOptions = {method: "post", body: payload}; + await fetch("{{index .API "LogbookAttachmentsUpload"}}", requestOptions) + + // update uuid in settings + const attachments_url = "{{index .API "LogbookUUIDAttachments"}}".replace("{uuid}", formatMap[format]); + const data = await wlbCommon.getJSON(attachments_url); + if (data.length > 0) { + return data[0].uuid; + } else { + return "" + } + } else { + const uuid = await getCustomTitle(format); + return uuid; + } + } + + async function saveExportA4() { let time_fields_auto_format = 0; if (document.getElementById("time_field_format_radio2_a4").checked) { time_fields_auto_format = 1; @@ -13,6 +84,8 @@ wlbExport = function () { time_fields_auto_format = 2; } + let custom_title_a4 = await saveCustomTitle("A4"); + let payload = { export_a4: { logbook_rows: parseInt(document.getElementById("logbook_rows_a4").value), @@ -26,6 +99,7 @@ wlbExport = function () { include_signature: document.getElementById("include_signature_a4").checked, is_extended: document.getElementById("is_extended_a4").checked, time_fields_auto_format: time_fields_auto_format, + custom_title: custom_title_a4, columns: { col1: parseFloat(document.getElementById("col1_a4").value), col2: parseFloat(document.getElementById("col2_a4").value), @@ -88,26 +162,24 @@ wlbExport = function () { }; const requestOptions = { - method: 'post', + method: "post", headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json', + "Accept": "application/json", + "Content-Type": "application/json", }, body: JSON.stringify(payload), }; - fetch("{{$api.Export}}/{{$api.ExportFormatA4}}", requestOptions) - .then(response => response.json()) - .then(function(data) { - if (data.ok) { - wlbCommon.showInfoMessage(data.message); - if (typeof data.redirect_url !== 'undefined') { - location.href = data.redirect_url; - } - } else { - wlbCommon.showErrorMessage(data.message); - } - }); + const response = await fetch("{{$api.Export}}/{{$api.ExportFormatA4}}", requestOptions); + const data = await response.json(); + if (data.ok) { + wlbCommon.showInfoMessage(data.message); + if (typeof data.redirect_url !== "undefined") { + location.href = data.redirect_url; + } + } else { + wlbCommon.showErrorMessage(data.message); + } } function saveExportA5() { @@ -317,7 +389,9 @@ wlbExport = function () { saveExportCSV:saveExportCSV, saveExportXLS:saveExportXLS, restoreDefaults:restoreDefaults, - showTab:showTab + showTab:showTab, + previewCustomTitle:previewCustomTitle, + deleteCustomTitle:deleteCustomTitle } }(); diff --git a/go.mod b/go.mod index 3cc8d47..be04968 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,8 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect + github.com/phpdave11/gofpdi v1.0.13 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/richardlehane/mscfb v1.0.4 // indirect diff --git a/go.sum b/go.sum index 87bc7fa..b46fc78 100644 --- a/go.sum +++ b/go.sum @@ -35,7 +35,12 @@ github.com/nathan-osman/go-sunrise v1.1.0 h1:ZqZmtmtzs8Os/DGQYi0YMHpuUqR/iRoJK+w github.com/nathan-osman/go-sunrise v1.1.0/go.mod h1:RcWqhT+5ShCZDev79GuWLayetpJp78RSjSWxiDowmlM= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/phpdave11/gofpdi v1.0.13 h1:o61duiW8M9sMlkVXWlvP92sZJtGKENvW3VExs6dZukQ= +github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= diff --git a/internal/models/structs.go b/internal/models/structs.go index 2ca623a..a6d0b52 100644 --- a/internal/models/structs.go +++ b/internal/models/structs.go @@ -150,6 +150,7 @@ type ExportPDF struct { IncludeSignature bool `json:"include_signature"` IsExtended bool `json:"is_extended"` TimeFieldsAutoFormat byte `json:"time_fields_auto_format"` + CustomTitle string `json:"custom_title"` } type ExportXLS struct { diff --git a/internal/pdfexport/pdfexport.go b/internal/pdfexport/pdfexport.go index 2500e7c..616268c 100644 --- a/internal/pdfexport/pdfexport.go +++ b/internal/pdfexport/pdfexport.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/go-pdf/fpdf" + "github.com/go-pdf/fpdf/contrib/gofpdi" "github.com/vsimakhin/web-logbook/internal/models" ) @@ -440,3 +441,28 @@ func formatTimeField(timeField string) string { return hours + ":" + minutes } + +func customTitle() { + // import first page and determine page sizes + imp := gofpdi.NewImporter() + + imp.ImportPage(pdf, "cv.pdf", 1, "/MediaBox") + pageSizes := imp.GetPageSizes() + nrPages := len(imp.GetPageSizes()) + + a4size := fpdf.SizeType{ + Wd: 210, + Ht: 297, + } + for i := 1; i <= nrPages; i++ { + fmt.Println(pageSizes[i]["/MediaBox"]) + tpl := imp.ImportPage(pdf, "cv.pdf", i, "/MediaBox") + if pageSizes[i]["/MediaBox"]["w"] > pageSizes[i]["/MediaBox"]["h"] { + pdf.AddPageFormat("L", a4size) + imp.UseImportedTemplate(pdf, tpl, 0, -87, 297, 297) + } else { + pdf.AddPageFormat("P", a4size) + imp.UseImportedTemplate(pdf, tpl, 0, 0, 210, 297) + } + } +} From 2a4438b28b567828804dc21ea3cb8e7ec3ffd9f2 Mon Sep 17 00:00:00 2001 From: Vladimir Simakhin Date: Fri, 22 Mar 2024 12:40:23 +0100 Subject: [PATCH 2/5] read file from attachments and add the same functionality for A5 PDF export --- cmd/web/handlers_export.go | 8 ++++ cmd/web/templates/export-a4.partials.gohtml | 3 +- cmd/web/templates/export-a5.partials.gohtml | 26 ++++++++--- cmd/web/templates/export-js.partials.gohtml | 33 +++++++------- internal/models/structs.go | 1 + internal/pdfexport/pdfexport.go | 50 +++++++++++++++------ internal/pdfexport/pdfexport_a4.go | 35 ++++++++------- internal/pdfexport/pdfexport_a5.go | 32 +++++++------ 8 files changed, 122 insertions(+), 66 deletions(-) diff --git a/cmd/web/handlers_export.go b/cmd/web/handlers_export.go index 13ca181..b04193c 100644 --- a/cmd/web/handlers_export.go +++ b/cmd/web/handlers_export.go @@ -58,13 +58,21 @@ func (app *application) HandlerExportLogbook(w http.ResponseWriter, r *http.Requ Signature: settings.SignatureText, SignatureImage: settings.SignatureImage, } + var customTitleUUID string + if format == exportA4 { logbook.Export = settings.ExportA4 + customTitleUUID = settings.ExportA4.CustomTitle } else if format == exportA5 { logbook.Export = settings.ExportA5 + customTitleUUID = settings.ExportA5.CustomTitle } + fmt.Println(customTitleUUID) + att, _ := app.db.GetAttachmentByID(customTitleUUID) + logbook.Export.CustomTitleBlob = att.Document + err = logbook.ExportPDF(format, flightRecords, w) } else if format == exportCSV { diff --git a/cmd/web/templates/export-a4.partials.gohtml b/cmd/web/templates/export-a4.partials.gohtml index 1302888..2774db9 100644 --- a/cmd/web/templates/export-a4.partials.gohtml +++ b/cmd/web/templates/export-a4.partials.gohtml @@ -393,7 +393,7 @@
- +
@@ -405,7 +405,6 @@
- diff --git a/cmd/web/templates/export-a5.partials.gohtml b/cmd/web/templates/export-a5.partials.gohtml index 09bad31..99cee82 100644 --- a/cmd/web/templates/export-a5.partials.gohtml +++ b/cmd/web/templates/export-a5.partials.gohtml @@ -383,20 +383,36 @@
-
- +
+ +
+
- + - + - +
+
+
+ +
+
+
+ + + + + +
+
+
diff --git a/cmd/web/templates/export-js.partials.gohtml b/cmd/web/templates/export-js.partials.gohtml index 571369e..0643ef8 100644 --- a/cmd/web/templates/export-js.partials.gohtml +++ b/cmd/web/templates/export-js.partials.gohtml @@ -182,7 +182,7 @@ wlbExport = function () { } } - function saveExportA5() { + async function saveExportA5() { let time_fields_auto_format = 0; if (document.getElementById("time_field_format_radio2_a5").checked) { time_fields_auto_format = 1; @@ -190,6 +190,8 @@ wlbExport = function () { time_fields_auto_format = 2; } + let custom_title_a5 = await saveCustomTitle("A5"); + let payload = { export_a5: { logbook_rows: parseInt(document.getElementById("logbook_rows_a5").value), @@ -204,6 +206,7 @@ wlbExport = function () { include_signature: document.getElementById("include_signature_a5").checked, is_extended: document.getElementById("is_extended_a5").checked, time_fields_auto_format: time_fields_auto_format, + custom_title: custom_title_a5, columns: { col1: parseFloat(document.getElementById("col1_a5").value), col2: parseFloat(document.getElementById("col2_a5").value), @@ -266,26 +269,24 @@ wlbExport = function () { }; const requestOptions = { - method: 'post', + method: "post", headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json', + "Accept": "application/json", + "Content-Type": "application/json", }, body: JSON.stringify(payload), }; - fetch("{{$api.Export}}/{{$api.ExportFormatA5}}", requestOptions) - .then(response => response.json()) - .then(function(data) { - if (data.ok) { - wlbCommon.showInfoMessage(data.message); - if (typeof data.redirect_url !== 'undefined') { - location.href = data.redirect_url; - } - } else { - wlbCommon.showErrorMessage(data.message); - } - }); + const response = await fetch("{{$api.Export}}/{{$api.ExportFormatA5}}", requestOptions); + const data = await response.json(); + if (data.ok) { + wlbCommon.showInfoMessage(data.message); + if (typeof data.redirect_url !== "undefined") { + location.href = data.redirect_url; + } + } else { + wlbCommon.showErrorMessage(data.message); + } } function saveExportXLS() { diff --git a/internal/models/structs.go b/internal/models/structs.go index a6d0b52..099dbbe 100644 --- a/internal/models/structs.go +++ b/internal/models/structs.go @@ -151,6 +151,7 @@ type ExportPDF struct { IsExtended bool `json:"is_extended"` TimeFieldsAutoFormat byte `json:"time_fields_auto_format"` CustomTitle string `json:"custom_title"` + CustomTitleBlob []byte } type ExportXLS struct { diff --git a/internal/pdfexport/pdfexport.go b/internal/pdfexport/pdfexport.go index 616268c..2c1a47a 100644 --- a/internal/pdfexport/pdfexport.go +++ b/internal/pdfexport/pdfexport.go @@ -56,6 +56,7 @@ var signature string var signatureImg string var isExtended bool var timeFieldsAutoFormat byte +var customTitle []byte //go:embed font/* var content embed.FS @@ -123,6 +124,7 @@ func (l *Logbook) init(format string) { isExtended = l.Export.IsExtended timeFieldsAutoFormat = l.Export.TimeFieldsAutoFormat + customTitle = l.Export.CustomTitleBlob initWidths(l.Export.Columns) initHeaders(l.Export.Headers) @@ -442,27 +444,47 @@ func formatTimeField(timeField string) string { return hours + ":" + minutes } -func customTitle() { - // import first page and determine page sizes +func printCustomTitle(format string) { + // some variables and parameters + sizes := map[string]fpdf.SizeType{ + PDFA4: {Wd: 210, Ht: 297}, + PDFA5: {Wd: 148, Ht: 210}, + } + + type pageParams struct{ x, y, w, h float64 } + params := map[string]map[string]pageParams{ + PDFA4: { + "P": {x: 0, y: 0, w: 210, h: 297}, + "L": {x: 0, y: -87, w: 297, h: 297}, + }, + PDFA5: { + "P": {x: 0, y: 0, w: 148, h: 210}, + "L": {x: 0, y: -62, w: 210, h: 210}, + }, + } + imp := gofpdi.NewImporter() - imp.ImportPage(pdf, "cv.pdf", 1, "/MediaBox") + readSeeker := io.ReadSeeker(bytes.NewReader(customTitle)) + + // import first page and determine page sizes + imp.ImportPageFromStream(pdf, &readSeeker, 1, "/MediaBox") pageSizes := imp.GetPageSizes() nrPages := len(imp.GetPageSizes()) - a4size := fpdf.SizeType{ - Wd: 210, - Ht: 297, - } + // add pages of the attached custom title pdf file for i := 1; i <= nrPages; i++ { - fmt.Println(pageSizes[i]["/MediaBox"]) - tpl := imp.ImportPage(pdf, "cv.pdf", i, "/MediaBox") + tpl := imp.ImportPageFromStream(pdf, &readSeeker, i, "/MediaBox") + + orientation := "P" if pageSizes[i]["/MediaBox"]["w"] > pageSizes[i]["/MediaBox"]["h"] { - pdf.AddPageFormat("L", a4size) - imp.UseImportedTemplate(pdf, tpl, 0, -87, 297, 297) - } else { - pdf.AddPageFormat("P", a4size) - imp.UseImportedTemplate(pdf, tpl, 0, 0, 210, 297) + orientation = "L" } + + pdf.AddPageFormat(orientation, sizes[format]) + imp.UseImportedTemplate(pdf, tpl, + params[format][orientation].x, params[format][orientation].y, + params[format][orientation].w, params[format][orientation].h, + ) } } diff --git a/internal/pdfexport/pdfexport_a4.go b/internal/pdfexport/pdfexport_a4.go index b7d2895..bfa76c0 100644 --- a/internal/pdfexport/pdfexport_a4.go +++ b/internal/pdfexport/pdfexport_a4.go @@ -147,22 +147,27 @@ func printA4LogbookBody(record models.FlightRecord, fill bool) { // titlePageA4 prints title page for A4 func titlePageA4() { - pdf.AddPage() - pdf.SetFont(fontBold, "", 20) - pdf.SetXY(95, 60) - pdf.MultiCell(100, 2, "PILOT LOGBOOK", "", "C", false) - - pdf.SetFont(fontRegular, "", 15) - pdf.SetXY(65, 150) - pdf.MultiCell(160, 2, "HOLDER'S NAME: "+strings.ToUpper(ownerName), "", "C", false) - if licenseNumber != "" { - pdf.SetXY(65, 157) - pdf.MultiCell(160, 2, "LICENSE NUMBER: "+strings.ToUpper(licenseNumber), "", "C", false) - } - if address != "" { - pdf.SetXY(65, 164) - pdf.MultiCell(160, 2, "ADDRESS: "+strings.ToUpper(address), "", "C", false) + if len(customTitle) != 0 { + printCustomTitle(PDFA4) + } else { + pdf.AddPage() + pdf.SetFont(fontBold, "", 20) + pdf.SetXY(95, 60) + pdf.MultiCell(100, 2, "PILOT LOGBOOK", "", "C", false) + + pdf.SetFont(fontRegular, "", 15) + pdf.SetXY(65, 150) + pdf.MultiCell(160, 2, "HOLDER'S NAME: "+strings.ToUpper(ownerName), "", "C", false) + + if licenseNumber != "" { + pdf.SetXY(65, 157) + pdf.MultiCell(160, 2, "LICENSE NUMBER: "+strings.ToUpper(licenseNumber), "", "C", false) + } + if address != "" { + pdf.SetXY(65, 164) + pdf.MultiCell(160, 2, "ADDRESS: "+strings.ToUpper(address), "", "C", false) + } } } diff --git a/internal/pdfexport/pdfexport_a5.go b/internal/pdfexport/pdfexport_a5.go index c4f98c2..15e9c33 100644 --- a/internal/pdfexport/pdfexport_a5.go +++ b/internal/pdfexport/pdfexport_a5.go @@ -235,22 +235,26 @@ func printA5LogbookBodyB(record models.FlightRecord, fill bool) { // titlePageA5 print title page for A5 func titlePageA5() { - pdf.AddPage() - pdf.SetFont(fontBold, "", 20) - pdf.SetXY(55, 60) - pdf.MultiCell(100, 2, "PILOT LOGBOOK", "", "C", false) + if len(customTitle) != 0 { + printCustomTitle(PDFA5) + } else { + pdf.AddPage() + pdf.SetFont(fontBold, "", 20) + pdf.SetXY(55, 60) + pdf.MultiCell(100, 2, "PILOT LOGBOOK", "", "C", false) - pdf.SetFont(fontRegular, "", 15) - pdf.SetXY(25, 100) - pdf.MultiCell(160, 2, "HOLDER'S NAME: "+strings.ToUpper(ownerName), "", "C", false) + pdf.SetFont(fontRegular, "", 15) + pdf.SetXY(25, 100) + pdf.MultiCell(160, 2, "HOLDER'S NAME: "+strings.ToUpper(ownerName), "", "C", false) - if licenseNumber != "" { - pdf.SetXY(25, 107) - pdf.MultiCell(160, 2, "LICENSE NUMBER: "+strings.ToUpper(licenseNumber), "", "C", false) - } - if address != "" { - pdf.SetXY(25, 114) - pdf.MultiCell(160, 2, "ADDRESS: "+strings.ToUpper(address), "", "C", false) + if licenseNumber != "" { + pdf.SetXY(25, 107) + pdf.MultiCell(160, 2, "LICENSE NUMBER: "+strings.ToUpper(licenseNumber), "", "C", false) + } + if address != "" { + pdf.SetXY(25, 114) + pdf.MultiCell(160, 2, "ADDRESS: "+strings.ToUpper(address), "", "C", false) + } } } From 3ec2d29dcbeeb7572bb603ab1382a330f3e21422 Mon Sep 17 00:00:00 2001 From: Vladimir Simakhin Date: Sat, 23 Mar 2024 12:38:34 +0100 Subject: [PATCH 3/5] update UI --- cmd/web/handlers_export.go | 1 - cmd/web/templates/export-a4.partials.gohtml | 41 +++++++++++++----- cmd/web/templates/export-a5.partials.gohtml | 46 +++++++++++++++------ cmd/web/templates/export-js.partials.gohtml | 37 ++++++++++++----- 4 files changed, 90 insertions(+), 35 deletions(-) diff --git a/cmd/web/handlers_export.go b/cmd/web/handlers_export.go index b04193c..6d2f1a3 100644 --- a/cmd/web/handlers_export.go +++ b/cmd/web/handlers_export.go @@ -69,7 +69,6 @@ func (app *application) HandlerExportLogbook(w http.ResponseWriter, r *http.Requ customTitleUUID = settings.ExportA5.CustomTitle } - fmt.Println(customTitleUUID) att, _ := app.db.GetAttachmentByID(customTitleUUID) logbook.Export.CustomTitleBlob = att.Document diff --git a/cmd/web/templates/export-a4.partials.gohtml b/cmd/web/templates/export-a4.partials.gohtml index 2774db9..def2f95 100644 --- a/cmd/web/templates/export-a4.partials.gohtml +++ b/cmd/web/templates/export-a4.partials.gohtml @@ -392,17 +392,11 @@
-
- +
+
-
-
- - - - - -
+
+
@@ -413,4 +407,31 @@ + + + {{end}} \ No newline at end of file diff --git a/cmd/web/templates/export-a5.partials.gohtml b/cmd/web/templates/export-a5.partials.gohtml index 99cee82..c7d4b53 100644 --- a/cmd/web/templates/export-a5.partials.gohtml +++ b/cmd/web/templates/export-a5.partials.gohtml @@ -388,29 +388,23 @@
- + - + - +
-
- +
+
-
-
- - - - - -
+
+
@@ -421,4 +415,30 @@ + + {{end}} \ No newline at end of file diff --git a/cmd/web/templates/export-js.partials.gohtml b/cmd/web/templates/export-js.partials.gohtml index 0643ef8..b911c64 100644 --- a/cmd/web/templates/export-js.partials.gohtml +++ b/cmd/web/templates/export-js.partials.gohtml @@ -24,15 +24,6 @@ wlbExport = function () { } } - async function previewCustomTitle(format) { - if (!formatMap[format]) {return;} - - const uuid = await getCustomTitle(format); - if (uuid !== "") { - window.open("{{$api.LogbookAttachmentsDownload}}"+uuid, "_blank"); - } - } - async function deleteCustomTitle(format) { // drop current saved file from attachments const attachments_url = "{{index .API "LogbookUUIDAttachments"}}".replace("{uuid}", formatMap[format]); @@ -44,6 +35,7 @@ wlbExport = function () { const requestOptions = {method: "post", body: JSON.stringify(payload)}; await fetch("{{index .API "LogbookAttachmentsDelete"}}", requestOptions) } + document.getElementById(`${formatMap[format]}_document`).innerHTML = ""; } } @@ -76,6 +68,29 @@ wlbExport = function () { } } + function showCustomTitleModal(format) { + const modal = new bootstrap.Modal(document.getElementById(`${formatMap[format]}_modal`), {}); + + getCustomTitle(format).then(uuid => { + if (uuid !== "") { + const data = "{{$api.LogbookAttachmentsDownload}}"+uuid; + fetch(data).then(response => response.blob()).then(blob => { + const reader = new FileReader(); + reader.onload = function() { + const text = ` +

Your browser does not support preview of the document

+
`; + + document.getElementById(`${formatMap[format]}_document`).innerHTML = text; + }; + reader.readAsDataURL(blob); + }); + } + }); + + modal.show(); + } + async function saveExportA4() { let time_fields_auto_format = 0; if (document.getElementById("time_field_format_radio2_a4").checked) { @@ -391,8 +406,8 @@ wlbExport = function () { saveExportXLS:saveExportXLS, restoreDefaults:restoreDefaults, showTab:showTab, - previewCustomTitle:previewCustomTitle, - deleteCustomTitle:deleteCustomTitle + deleteCustomTitle:deleteCustomTitle, + showCustomTitleModal:showCustomTitleModal } }(); From b5659ee0f309f8ed7afaf7b456c0fde471d90dcb Mon Sep 17 00:00:00 2001 From: Vladimir Simakhin Date: Sat, 23 Mar 2024 12:48:08 +0100 Subject: [PATCH 4/5] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 547a0d5..fe32d2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [Unreleased] +- New: Add support for a custom title page for PDF A4/A5 exports. - Update: Update openlayers lib from 7.3.0 to 9.0.0. No UI changes. - Update: Update golang from 1.20.3 to 1.21.8. No UI changes. - Fix: Finally fixed the unit tests. No UI changes. From cde335b46974c2f391a1fc1f4090b7101f8d8325 Mon Sep 17 00:00:00 2001 From: Vladimir Simakhin Date: Sat, 23 Mar 2024 12:48:46 +0100 Subject: [PATCH 5/5] update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fc9538b..483e31a 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ You also can easily export all flight records into EASA style pdf format, print ## [Unreleased] +- New: Add support for a custom title page for PDF A4/A5 exports. - Update: Update openlayers lib from 7.3.0 to 9.0.0. No UI changes. - Update: Update golang from 1.20.3 to 1.21.8. No UI changes. - Fix: Finally fixed the unit tests. No UI changes.