From 34c9f4e485485d9db9b17d9c45a5e9962b148ad9 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Tue, 22 Sep 2020 20:29:56 +0000 Subject: [PATCH] --- ayanova/devdocs/todo.txt | 93 +++++++++++++++++----------- ayanova/src/api/ayanova-version.js | 2 +- ayanova/src/api/gzform.js | 13 +++- ayanova/src/views/ay-report-edit.vue | 60 +++++++++++++++++- 4 files changed, 126 insertions(+), 42 deletions(-) diff --git a/ayanova/devdocs/todo.txt b/ayanova/devdocs/todo.txt index 0f2e285e..7e1feec1 100644 --- a/ayanova/devdocs/todo.txt +++ b/ayanova/devdocs/todo.txt @@ -2,54 +2,65 @@ @@@@@@@@@@@@@@@ ROADMAP STAGE 4 - REPORTING / DASHBOARD / KPI @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -todo: reporting "ZOMBIE" chrome processes on linux - open the shell into the docker container: - docker run -it [container_id] /bin/ash - run the "top" command and then print a report - each run generates 3 chrome processes - Many discussions about workarounds and stuff here: - https://github.com/hardkoded/puppeteer-sharp/issues/1489 - https://github.com/puppeteer/puppeteer/issues/1825 - https://github.com/Yelp/dumb-init -Ok, fixed it, but now it's a little slower and can crash if it hits the limits of the droplet i.e. -Not sure what to do about that, maybe more timeouts in more places? - What are the specs for the droplet? - -todo: figure out how jsreport is launching headless chrome, i.e. which settings and flags etc - https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#puppeteerlaunchoptions - https://jsreport.net/learn/chrome-pdf - https://github.com/jsreport/jsreport-chrome-pdf/blob/master/lib/conversion.js - -todo: look over this: https://github.com/puppeteer/puppeteer/issues/1834 -todo: look at guidance for running puppeteer (js) on alpine docker here: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#running-on-alpine -todo: test with generated huge data locally here in Windows, see what limits get hit and how it handles it -todo: document (or tell Joyce) about the troubleshooting section items here: - https://jsreport.net/learn/chrome-pdf - which may or may not apply in our case - -todo: more timeouts for report rendering, Devops droplet is overwhelmed by 10k records of widgets using the customfields example report - symptom is super high cpu usage (100%) pegged and probably virtual memory usage as well - timeout is kind of a hard core way to work around this issue, maybe instead it should be looking at excessive cpu and memory usage? - The metrics don't catch it because it happens too quickly for the metrics lifecycle - - I want it to be able to handle it gracefully without crashing - -todo: look at metrics snapshot lifecycle, perhaps it should be shorter as it's missing 100% cpu pegging during big rendering on devops - -todo: pdf page numbers control +todo: pdf options UI and passthrough + basically need to be able to select every option and send it through + options: + http://www.puppeteersharp.com/api/PuppeteerSharp.PdfOptions.html + http://www.puppeteersharp.com/api/PuppeteerSharp.Page.html#PuppeteerSharp_Page_PdfAsync_System_String_PuppeteerSharp_PdfOptions_ + https://pptr.dev/#?product=Puppeteer&version=v5.3.0&show=api-pagepdfoptions + page numbers control Test this, it might do what we need as it has a template for pdf footer and page number is part of it http://www.puppeteersharp.com/api/PuppeteerSharp.PdfOptions.html look at jsreport what do they include in their pdf post processing parameters and capabilities need to add pdfkit or whatever it's called at the front. + + + +todo: document (or tell Joyce) about the troubleshooting section items here: + https://jsreport.net/learn/chrome-pdf + which may or may not apply in our case + + +//before getting into timeouts and shit make sure it's running as well as can be in docker +todo: look at guidance for running puppeteer (js) on alpine docker here: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#running-on-alpine + how jsreport is launching headless chrome, i.e. which settings and flags etc + https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#puppeteerlaunchoptions + https://jsreport.net/learn/chrome-pdf + https://github.com/jsreport/jsreport-chrome-pdf/blob/master/lib/conversion.js + (after looking at it, it's still a bit unclear, maybe not relevant as they seem to do a lot differently for that) + + +todo: look over this: https://github.com/puppeteer/puppeteer/issues/1834 + todo: reporting load test test locally with 20k widgets, make it crash then determine what limits to set on it and properly return error when it's exceeded right now it just says something about puppeteer and "crash" + +todo: more timeouts for report rendering, hard kill after 30 seconds tops but adjustable interval maybe? + each process takes time in part, need to see which is taking which time the most and killable + i.e. run a huge report and see which exact step takes which time for each + we have the pre-render timing out maybe need more for each step where it's vulnerable to crashing / timing out + + Devops droplet is overwhelmed by 10k records of widgets using the customfields example report + symptom is super high cpu usage (100%) pegged and probably virtual memory usage as well + timeout is kind of a hard core way to work around this issue, maybe instead it should be looking at excessive cpu and memory usage? + The metrics don't catch it because it happens too quickly for the metrics lifecycle + + I want it to be able to handle it gracefully without crashing + Looks like jsreports has this issue too and they hard kill the process I think if necessary, but they actually re-use the same instance for reporting I think. + If it's not an issue then no need to resolve at the moment + + todo: Need a setting that warns people about printing too much data, i.e. "That's a lot of data, are you sure you want to render that, it will be slow" or something to that effect +todo: look at metrics snapshot lifecycle, perhaps it should be shorter as it's missing 100% cpu pegging during big rendering on devops + + + todo: Take a serious look at .net5 migration, it will almost certainly be better to do it now than down the road after a release it also has many performance enhancements and nifty features like code analysis and warnings which might save me a lot of hassle @@ -61,6 +72,18 @@ todo: look at what's coming on the radar before release in the big libs I'm usin todo: triage this stuff: +todo: Direct report view URL doesn't work if already logged in due to code only being in login form + need to hijack the router before navigation to intercept special urls + https://test.helloayanova.com/widgets/499 + localhost:8080/viewreport?oid=20000&rid=9 + +todo: wiki image helper, if select ok but haven't selected a attachment it errors out, ok should not be available until there is a valid image selected +todo: attach files drag and drop helper should be expanded to include the selection tab, not just the list tab +todo: .webp type not available to wiki image helper when attached + this is because it's not identified as an image when it's a .webp extension + add to image types list for MIME + + todo: DataListFilter UI pretty shitty error on duplicate how to make a new filter? diff --git a/ayanova/src/api/ayanova-version.js b/ayanova/src/api/ayanova-version.js index e2f7483b..8203fae2 100644 --- a/ayanova/src/api/ayanova-version.js +++ b/ayanova/src/api/ayanova-version.js @@ -1,4 +1,4 @@ export default { - version: "8.0.0-alpha.16", + version: "8.0.0-alpha.19", copyright: "© 1999-2020, Ground Zero Tech-Works Inc." }; diff --git a/ayanova/src/api/gzform.js b/ayanova/src/api/gzform.js index 2f9bb728..d662953e 100644 --- a/ayanova/src/api/gzform.js +++ b/ayanova/src/api/gzform.js @@ -686,9 +686,15 @@ export default { /////////////////////////////// // On fieldValueChanged handler // This is required so that server errors can be cleared when input is changed - // - fieldValueChanged(vm, ref) { + // formReference is an optional string name of the form ref property if alternative named form + fieldValueChanged(vm, ref, formReference) { let that = this; + let formControl = null; + if (formReference == undefined) { + formControl = vm.$refs.form; + } else { + formControl = vm.$refs[formReference]; + } //this is currently required to ensure that this method runs after all the broken rule checks have settled Vue.nextTick(function() { //------------- @@ -738,7 +744,8 @@ export default { } //Update the form status - let formValid = vm.$refs.form.validate(); + let formValid = formControl.validate(); + //let formValid = vm.$refs.form.validate();//##FORM REFERENCE // console.log( // "gzform:fieldValueChanged - form validity being set to ", // formValid diff --git a/ayanova/src/views/ay-report-edit.vue b/ayanova/src/views/ay-report-edit.vue index 767677d7..830045ac 100644 --- a/ayanova/src/views/ay-report-edit.vue +++ b/ayanova/src/views/ay-report-edit.vue @@ -22,6 +22,10 @@ {{ $ay.t("ReportEditorProperties") }} + + {{ $ay.t("ReportPdfOptions") }} + + {{ $ay.t("ReportTemplate") }} @@ -114,6 +118,25 @@ + + + + + + + + + + @@ -320,7 +343,20 @@ export default { Handlebars.registerHelper('loud', function (aString) { return aString.toUpperCase() })`, - renderType: 0 + renderType: 0, + headerTemplate: null, + footerTemplate: null, + displayHeaderFooter: false, + paperFormat: 0, + landscape: false, + marginOptionsBottom: null, + marginOptionsLeft: null, + marginOptionsRight: null, + marginOptionsTop: null, + pageRanges: null, + preferCSSPageSize: false, + printBackground: false, + scale: 1 }, formState: { ready: false, @@ -337,6 +373,16 @@ Handlebars.registerHelper('loud', function (aString) { rendering: false }; }, + /*{"data":{"id":10,"concurrency":19494847,"name":"test basic","active":true,"notes":"", + "roles":124927,"objectType":2, + "template":"\n\n\n\t{{#each ayReportData}}\n\t

{{ Name }}

\n\t
Notes: {{ Notes }}
\n\t{{/each}}\n\n\n","style":".example {\n color: blue;\n}","jsPrerender":"async function ayPrepareData(reportData){ \n //this function (if present) is called with the report data \n //before the report is rendered\n //modify data as required here and return it to change the data before the report renders\n //see the help documentation for details\n return reportData;\n}","jsHelpers":"//Register custom Handlebars helpers here to use in your report script\n//https://handlebarsjs.com/guide/#custom-helpers\nHandlebars.registerHelper('loud', function (aString) {\n return aString.toUpperCase()\n})", + "renderType":0, + "headerTemplate":null,"footerTemplate":null,"displayHeaderFooter":false, + "paperFormat":0,"landscape":false,"marginOptionsBottom":null, + "marginOptionsLeft":null,"marginOptionsRight":null, + "marginOptionsTop":null,"pageRanges":null,"preferCSSPageSize":false, + "printBackground":false,"scale":1}} + */ //WATCHERS watch: { formState: { @@ -403,6 +449,9 @@ Handlebars.registerHelper('loud', function (aString) { case "properties": //no state to save here break; + case "pdfoptions": + //no state to save here + break; case "template": vm.editData.template.state = currentState; break; @@ -427,6 +476,10 @@ Handlebars.registerHelper('loud', function (aString) { vm.view = "properties"; return; break; + case "pdfoptions": + vm.view = "pdfoptions"; + return; + break; case "template": editor.setModel(vm.editData.template.model); editor.restoreViewState(vm.editData.template.state); @@ -487,13 +540,13 @@ Handlebars.registerHelper('loud', function (aString) { form() { return window.$gz.form; }, - fieldValueChanged(ref) { + fieldValueChanged(ref, formReference) { if ( this.formState.ready && !this.formState.loading && !this.formState.readOnly ) { - window.$gz.form.fieldValueChanged(this, ref); + window.$gz.form.fieldValueChanged(this, ref, formReference); } }, async getDataFromApi(recordId) { @@ -919,6 +972,7 @@ async function fetchTranslatedText(vm) { await window.$gz.translation.cacheTranslations([ "ReportDesignReport", "ReportName", + "ReportPdfOptions", "ReportEditorProperties", "ReportEditorData", "ReportEditorMobileWarning",