diff --git a/.wappler/targets/Development/databases/DB.json b/.wappler/targets/Development/databases/DB.json index 0b5295c..ff3a08e 100644 --- a/.wappler/targets/Development/databases/DB.json +++ b/.wappler/targets/Development/databases/DB.json @@ -19,10 +19,39 @@ "db": {} }, "tPoint": { - "db": {} + "db": {}, + "columns": { + "id": { + "db": { + "type": "increments", + "primary": true, + "unique": false, + "nullable": false + } + } + } }, "tSection": { - "db": {} + "db": {}, + "columns": { + "id": { + "db": { + "type": "increments", + "primary": true, + "unique": false, + "nullable": false + } + }, + "fText": { + "db": { + "type": "string", + "maxLength": 255, + "primary": false, + "unique": false, + "nullable": true + } + } + } }, "tblSection": { "db": {}, diff --git a/.wappler/targets/Development/web/Dockerfile b/.wappler/targets/Development/web/Dockerfile index c80c936..d6fcb64 100644 --- a/.wappler/targets/Development/web/Dockerfile +++ b/.wappler/targets/Development/web/Dockerfile @@ -1,5 +1,11 @@ FROM node:lts-alpine +RUN apk --no-cache add fontconfig +COPY ./fonts /usr/shared/fonts +COPY ./fonts /usr/share/fonts/truetype +# refresh system font cache +RUN fc-cache -f -v + ARG NODE_ENV=production ENV NODE_ENV $NODE_ENV diff --git a/public/ERTSQlite.db b/public/ERTSQlite.db index b96fc41..4a7fea2 100644 Binary files a/public/ERTSQlite.db and b/public/ERTSQlite.db differ diff --git a/public/PDF/Template-EDV41-current.pdf b/public/PDF/Template-EDV41-current.pdf new file mode 100644 index 0000000..76655da Binary files /dev/null and b/public/PDF/Template-EDV41-current.pdf differ diff --git a/public/dmxAppConnect/config.js b/public/dmxAppConnect/config.js index 9831047..4632941 100644 --- a/public/dmxAppConnect/config.js +++ b/public/dmxAppConnect/config.js @@ -1,85 +1,37 @@ dmx.config({ "observationPage": { - "tableRepeat4": { - "meta": [ - { - "name": "_id", - "type": "objectId" - }, - { - "name": "db_fullName", - "type": "text" - }, - { - "name": "db_licenseNumber", - "type": "text" - }, - { - "name": "db_employeeID", - "type": "text" - }, - { - "name": "db_signatureData", - "type": "text" - }, - { - "name": "db_trainerSelected", - "type": "text" - }, - { - "name": "db_stateName", - "type": "text" - }, - { - "name": "dummy1", - "type": "text", - "ui": { - "label": "dummy" - } - } - ], - "outputType": "array" - }, - "data_view1": { - "meta": [ - { - "name": "_id", - "type": "objectId" - }, - { - "name": "db_fullName", - "type": "text" - }, - { - "name": "db_licenseNumber", - "type": "text" - }, - { - "name": "db_employeeID", - "type": "text" - }, - { - "name": "db_signatureData", - "type": "text" - }, - { - "name": "db_trainerSelected", - "type": "text" - }, - { - "name": "db_stateName", - "type": "text" - }, - { - "name": "dummy1", - "type": "text", - "ui": { - "label": "dummy" - } - } - ], - "outputType": "array" - }, + "GradingDatastore": [ + { + "type": "text", + "name": "$id" + }, + { + "type": "text", + "name": "numSection" + }, + { + "type": "text", + "name": "pointValue" + }, + { + "type": "text", + "name": "description" + } + ], + "datastore1": [ + { + "type": "text", + "name": "numSection" + }, + { + "type": "text", + "name": "pointValue" + }, + { + "type": "text", + "name": "description" + } + ], "processPDF": { "meta": [ { @@ -88,33 +40,6 @@ dmx.config({ } ], "local": {} - }, - "datastore1": [ - { - "type": "text", - "name": "db_fullName" - }, - { - "type": "text", - "name": "db_licenseNumber" - }, - { - "type": "text", - "name": "db_stateName" - }, - { - "type": "text", - "name": "db_employeeID" - } - ], - "minCalc": { - "meta": [ - { - "name": "CalculateMinutes", - "type": "text" - } - ], - "local": {} } } }); diff --git a/public/js/libProcessScript.js b/public/js/libProcessScript.js index ebb4492..4cb01c4 100644 --- a/public/js/libProcessScript.js +++ b/public/js/libProcessScript.js @@ -21,9 +21,7 @@ const dd = createDebugLogger(true, "dd"); // code function at bottom of the page // Wrapper function to fetch, update, and download PDF async function processAndDownloadPdf(filePath, ...dataSources) { - - dd(`Loaded PDF Template: ${filePath.value}`) - + console.log(filePath) try { const pdfBytes = await fetchPdfBytes(filePath); const updatedPdfBytes = await updatePdfFields(pdfBytes, dataSources); @@ -37,11 +35,8 @@ async function processAndDownloadPdf(filePath, ...dataSources) { } } - - - async function fetchPdfBytes(filePath) { - dd(filePath); + try { const response = await fetch(filePath); @@ -56,43 +51,95 @@ async function fetchPdfBytes(filePath) { // Update form fields in the PDF async function updatePdfFields( pdfBytes, - dataSources, - skipMissingFields = true + dataSources + ) { - console.log("Datasource size:", dataSources.length) + console.log("Datasources Count:", dataSources.length) + console.log(JSON.stringify(dataSources, null, 2)); + try { const pdfDoc = await PDFLib.PDFDocument.load(pdfBytes); const form = pdfDoc.getForm(); - dataSources.forEach((dataSource) => { - console.log("Current Datasource", dataSource) - dataSource.forEach((record) => { + dataSources.forEach((dataSource, dsIndex) => { + console.log(`Processing dataSource[${dsIndex}]:`, dataSource); + + if (!Array.isArray(dataSource)) { + console.warn(`dataSource[${dsIndex}] is not an array. Skipping.`); + return; + } + + dataSource.forEach((record, recIndex) => { + console.log(`Processing record[${recIndex}]:`, record); + + if (!record || typeof record !== 'object') { + console.warn(`record[${recIndex}] is undefined or not an object. Skipping.`); + return; + } + + // Extract numSection and pointValue dynamically or other 'key' components. + const { numSection } = record; + const pointValue = record.pointValue || record.Points; // Fallback to Points if pointValue is missing + + + if (numSection && pointValue) { + console.log(`Updating PDF field: ${numSection} with value: ${pointValue}`); - console.log("Working in: ", record) - Object.entries(record).forEach(([fieldName, fieldValue]) => { - dd(`Field: ${fieldName} Value: ${fieldValue}`) //debugger try { - const formField = form.getTextField(fieldName); + // Use numSection as the dynamic field name + const formField = form.getTextField(numSection); + if (formField) { - // console.info(`Field "${fieldName}" OK`); - dd(`${fieldName} --> ${fieldValue} OK`); - formField.setText(String(fieldValue)); - } else if (!skipMissingFields) { - //dd(`Skipping Field: ${fieldName} NOT FOUND`) - console.warn(`Field "${fieldName}" not found.`); + formField.setText(String(pointValue)); + console.log(`Field "${numSection}" updated with value "${pointValue}".`); + } else { + console.warn(`Field "${numSection}" not found in PDF.`); } } catch (err) { - console.error(`Error updating field "${fieldName}":`); //console.error(`Error updating field "${fieldName}":`, err); + console.error(`Error updating field "${numSection}":`, err); } - }); + } else { + console.warn(`Missing numSection or pointValue in record[${recIndex}].`); + } }); }); + + /** + + dataSources.forEach((dataSource) => { + //console.log("Current Datasource", dataSource) + dataSource.forEach((record) => { + console.log(record) + //console.log("Working in: ", record) + Object.entries(record).forEach(([fieldName, fieldValue]) => { + dd(`Field: ${fieldName} Value: ${fieldValue}`) //debugger + try { + console.log(`----------------> form ${fieldName}`) + const formField = form.getTextField(fieldName); + if (formField) { + // console.info(`Field "${fieldName}" OK`); + dd(`${fieldName} --> ${fieldValue} OK`); + formField.setText(String(fieldValue)); + } else if (!skipMissingFields) { + //dd(`Skipping Field: ${fieldName} NOT FOUND`) + console.warn(`Field "${fieldName}" not found.`); + } + } catch (err) { + console.error(`Error updating field "${fieldName}":`); //console.error(`Error updating field "${fieldName}":`, err); + } + }); + }); + }); + */ + // console.log(JSON.stringify(dataSources, null, 2)); + return await pdfDoc.save(); } catch (err) { console.error("Error updating PDF fields:", err); throw err; } + } // Function to trigger download of the updated PDF diff --git a/public/tblSections.json b/public/tblSections.json new file mode 100644 index 0000000..0902535 --- /dev/null +++ b/public/tblSections.json @@ -0,0 +1,404 @@ +{ + "Sections": [ + { + "isSection": "1", + "numSection": "1", + "txtSection": "1. Locate & Adjust Vehicle Controls (as needed)" + }, + { + "isSection": "0", + "numSection": "1.1", + "txtSection": "Emergency/Parking Brake (applicable to all vehicles except Rivian)" + }, + { + "isSection": "0", + "numSection": "1.2", + "txtSection": "Parking controls/gear shift" + }, + { + "isSection": "0", + "numSection": "1.3", + "txtSection": "Vehicle Height" + }, + { + "isSection": "0", + "numSection": "1.4", + "txtSection": "Mirrors" + }, + { + "isSection": "0", + "numSection": "1.5", + "txtSection": "Lights: hazards, interior, headlights, turn signals, and auxiliary (fog)" + }, + { + "isSection": "0", + "numSection": "1.6", + "txtSection": "Horn" + }, + { + "isSection": "0", + "numSection": "1.7", + "txtSection": "Windshield wipers" + }, + { + "isSection": "0", + "numSection": "1.8", + "txtSection": "Window Defroster" + }, + { + "isSection": "1", + "numSection": "2", + "txtSection": "2. Vehicle Handling and Braking" + }, + { + "isSection": "0", + "numSection": "2.1", + "txtSection": "*Secures seat belt correctly prior to starting vehicle’s drive system*" + }, + { + "isSection": "0", + "numSection": "2.2", + "txtSection": "*Eliminates use of cell phone when vehicle is in motion*" + }, + { + "isSection": "0", + "numSection": "2.3", + "txtSection": "Steers smoothly with minimal adjustments" + }, + { + "isSection": "0", + "numSection": "2.4", + "txtSection": "*Stays centered on lane of travel*" + }, + { + "isSection": "0", + "numSection": "2.5", + "txtSection": "Avoids curbs when turning" + }, + { + "isSection": "0", + "numSection": "2.6", + "txtSection": "Both hands remain on the steering wheel at 9 & 3" + }, + { + "isSection": "0", + "numSection": "2.7", + "txtSection": "Engages turn signals and checks blind spots prior to making turns" + }, + { + "isSection": "0", + "numSection": "2.8", + "txtSection": "Checks mirrors every 5-8 seconds" + }, + { + "isSection": "0", + "numSection": "2.9", + "txtSection": "*Obeys all traffic signs*" + }, + { + "isSection": "1", + "numSection": "3", + "txtSection": "3. Braking, Slowing and Stopping" + }, + { + "isSection": "0", + "numSection": "3.1", + "txtSection": "Checks mirrors every 5-8 seconds" + }, + { + "isSection": "0", + "numSection": "3.2", + "txtSection": "Tests brakes before descending grades" + }, + { + "isSection": "0", + "numSection": "3.3", + "txtSection": "Stops behind crosswalks when stop lines or stop signs are present" + }, + { + "isSection": "0", + "numSection": "3.4", + "txtSection": "Maintains appropriate eye-lead time (looking ahead for hazards)" + }, + { + "isSection": "0", + "numSection": "3.5", + "txtSection": "*Safely controls vehicle by utilizing vehicle’s brake pedals*" + }, + { + "isSection": "0", + "numSection": "3.6", + "txtSection": "Safely utilizes regenerative braking as primary method of operation (EDV Only)" + }, + { + "isSection": "1", + "numSection": "4", + "txtSection": "4. Parking: Reversing into Spot" + }, + { + "isSection": "0", + "numSection": "4.1", + "txtSection": "Smoothly stops and, if needed, completes walk-around of vehicle (using 3 points of contact)" + }, + { + "isSection": "0", + "numSection": "4.2", + "txtSection": "Engages turn signal, hazards, and checks blind spots prior to reverse" + }, + { + "isSection": "0", + "numSection": "4.3", + "txtSection": "Uses horn prior to reverse (and every 3 seconds if no reverse alarm)" + }, + { + "isSection": "0", + "numSection": "4.4", + "txtSection": "Controls speed (3mph) and direction properly when backing" + }, + { + "isSection": "0", + "numSection": "4.5", + "txtSection": "Checks mirrors every 5-8 seconds" + }, + { + "isSection": "0", + "numSection": "4.6", + "txtSection": "Successfully parks within lines of parking spot" + }, + { + "isSection": "0", + "numSection": "4.7", + "txtSection": "Performs proper parking sequence (anytime vehicle is parked)" + }, + { + "isSection": "1", + "numSection": "5", + "txtSection": "5. Parking: Passenger-Side Parallel" + }, + { + "isSection": "0", + "numSection": "5.1", + "txtSection": "Engages turn signal, hazards, and checks blind spots prior to reverse" + }, + { + "isSection": "0", + "numSection": "5.2", + "txtSection": "Uses horn prior to reverse (and every 3 seconds if no reverse alarm)" + }, + { + "isSection": "0", + "numSection": "5.3", + "txtSection": "Controls speed (3mph) and direction properly when backing" + }, + { + "isSection": "0", + "numSection": "5.4", + "txtSection": "Checks mirrors every 5-8 seconds" + }, + { + "isSection": "0", + "numSection": "5.5", + "txtSection": "Appropriately parallel parks in designated area" + }, + { + "isSection": "0", + "numSection": "5.6", + "txtSection": "Performs proper parking sequence (anytime vehicle is parked)" + }, + { + "isSection": "0", + "numSection": "5.7", + "txtSection": "Disengages hazards, engages turn signals, and checks blind spots when exiting parallel parking spot" + }, + { + "isSection": "1", + "numSection": "6", + "txtSection": "6. Steering" + }, + { + "isSection": "0", + "numSection": "6.1", + "txtSection": "*Stays centered in lane of travel*" + }, + { + "isSection": "0", + "numSection": "6.2", + "txtSection": "Steers smoothly with minimal adjustments" + }, + { + "isSection": "0", + "numSection": "6.3", + "txtSection": "Both hands remain on the steering wheel at 9 & 3" + }, + { + "isSection": "1", + "numSection": "7", + "txtSection": "7. Traffic Signs/Signals" + }, + { + "isSection": "0", + "numSection": "7.1", + "txtSection": "*Comes to a complete stop at stop signs and stop lights*" + }, + { + "isSection": "0", + "numSection": "7.2", + "txtSection": "*Obeys all traffic signs*" + }, + { + "isSection": "0", + "numSection": "7.3", + "txtSection": "Uses turn signal when changing lanes" + }, + { + "isSection": "1", + "numSection": "8", + "txtSection": "8. Turning" + }, + { + "isSection": "0", + "numSection": "8.1", + "txtSection": "Avoids curbs when turning" + }, + { + "isSection": "0", + "numSection": "8.2", + "txtSection": "*Begins and ends turns in correct lane*" + }, + { + "isSection": "0", + "numSection": "8.3", + "txtSection": "Engages turn signal in advance and slows for turns" + }, + { + "isSection": "0", + "numSection": "8.4", + "txtSection": "Checks traffic and turns only when clear" + }, + { + "isSection": "0", + "numSection": "8.5", + "txtSection": "Completes turns promptly and smoothly, and does not impede traffic" + }, + { + "isSection": "0", + "numSection": "8.6", + "txtSection": "Checks mirrors and blind spots before completing turns, looking for motorcycles, bicycles\nand pedestrians (MBP), other vehicles, etc…" + }, + { + "isSection": "1", + "numSection": "9", + "txtSection": "9. Intersections" + }, + { + "isSection": "0", + "numSection": "9.1", + "txtSection": "Does not increase speed when light turns yellow" + }, + { + "isSection": "0", + "numSection": "9.2", + "txtSection": "Uses space cushion (one vehicle length) when stopped in intersections" + }, + { + "isSection": "0", + "numSection": "9.3", + "txtSection": "Yields the right-of-way at all times" + }, + { + "isSection": "0", + "numSection": "9.4", + "txtSection": "Identifies and, if needed, gains eye contact with other MPBs" + }, + { + "isSection": "0", + "numSection": "9.5", + "txtSection": "Does not change lanes in intersection" + }, + { + "isSection": "0", + "numSection": "9.6", + "txtSection": "Waits a 1-2-3 count prior to accelerating after being stopped at a lit intersection" + }, + { + "isSection": "0", + "numSection": "9.7", + "txtSection": "Checks left, right, and left again, before entering every intersection" + }, + { + "isSection": "0", + "numSection": "9.8", + "txtSection": "*Eliminate distractions of cell phone use when vehicle is in motion*" + }, + { + "isSection": "1", + "numSection": "10", + "txtSection": "10. Speed" + }, + { + "isSection": "0", + "numSection": "10.1", + "txtSection": "*Adheres to posted speed limit and maintains appropriate speeds*" + }, + { + "isSection": "0", + "numSection": "10.2", + "txtSection": "Reduces speed before turns" + }, + { + "isSection": "0", + "numSection": "10.3", + "txtSection": "Adjusts speed to surrounding conditions (weather, traffic, motorcycles, bicycles, pedestrians, and intersections)" + }, + { + "isSection": "0", + "numSection": "10.4", + "txtSection": "Maintains appropriate following distance based on road/weather conditions, vehicle load, etc." + }, + { + "isSection": "0", + "numSection": "10.5", + "txtSection": "Changes lanes and passes vehicles safely while checking mirrors and using turn signal" + }, + { + "isSection": "0", + "numSection": "10.6", + "txtSection": "Highway on-ramp, gets up to highway speeds gradually and safely (minimum highway speed required\nis 55mph)" + }, + { + "isSection": "0", + "numSection": "10.7", + "txtSection": "On highway exit ramp, slows down to appropriate speed" + }, + { + "isSection": "1", + "numSection": "11", + "txtSection": "11. Proper Parking Sequence (whenever vehicle is parked)" + }, + { + "isSection": "0", + "numSection": "11.1", + "txtSection": "Driver stops vehicle, set parking brake/emergency brake first (applicable to all vehicles except Rivian)" + }, + { + "isSection": "0", + "numSection": "11.2", + "txtSection": "Put vehicle in Park, turn off vehicle, remove keys from ignition (applicable to all vehicles except Rivian)" + }, + { + "isSection": "0", + "numSection": "11.3", + "txtSection": "Take off seat belt, exit using 3 points of contact, and lock vehicle" + }, + { + "isSection": "0", + "numSection": "11.4", + "txtSection": "Total Points Section II" + }, + { + "isSection": "0", + "numSection": "11.5", + "txtSection": "Total Points" + } + ] +} \ No newline at end of file diff --git a/views/layouts/main.ejs b/views/layouts/main.ejs index 4963eda..1015394 100644 --- a/views/layouts/main.ejs +++ b/views/layouts/main.ejs @@ -68,6 +68,10 @@ + + + + diff --git a/views/observationPage.ejs b/views/observationPage.ejs index 43682a9..1472d4d 100644 --- a/views/observationPage.ejs +++ b/views/observationPage.ejs @@ -1,16 +1,5 @@ - + @@ -137,13 +126,7 @@ output: true, outputType: "text", function: "processAndDownloadPdf", - args: [ - "{{ertTemplatePath.value}}", - "{{datastore1.data}}", - "{{data_view1.data}}", - "{{saveObservationResults.form2.getStartTime.value}}", - "{{saveObservationResults.form2.getEndTime.value}}" - ] + args: ["/PDF/Template-EDV41-current.pdf", "{{datastore1.data}}"] } } -
@@ -327,6 +309,7 @@ +
@@ -375,7 +358,10 @@ - + @@ -390,50 +376,28 @@
-
- - - - - - - - - - - - - - - - - - - -
$idDb full nameDb license numberDb state nameDb employee
-

No Points recorded 

- +
- + - + - + @@ -443,13 +407,7 @@ - - - - - -
$id Num sectionPointspointValue Description  - +