Catchup - Backup

This commit is contained in:
Wappler 2025-01-01 17:29:15 -06:00
parent 2b04df51c0
commit 710c07a10f
9 changed files with 561 additions and 188 deletions

View File

@ -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": {},

View File

@ -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

Binary file not shown.

Binary file not shown.

View File

@ -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": {}
}
}
});

View File

@ -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

404
public/tblSections.json Normal file
View File

@ -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 vehicles 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 vehicles 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"
}
]
}

View File

@ -68,6 +68,10 @@
<script src="/dmxAppConnect/dmxBootstrap5Alert/dmxBootstrap5Alert.js" defer></script>
<script src="/dmxAppConnect/dmxBootstrap5Collapse/dmxBootstrap5Collapse.js" defer></script>
<!--<link rel="stylesheet" href="/dmxAppConnect/dmxDatePicker/daterangepicker.min.css" />-->
<link rel="stylesheet" href="/dmxAppConnect/dmxDatePicker/daterangepicker.min.css" />
<script src="/dmxAppConnect/dmxDatePicker/daterangepicker.min.js" defer></script>
<link rel="stylesheet" href="/dmxAppConnect/dmxDatePicker/dmxDatePicker.css" />
<script src="/dmxAppConnect/dmxDatePicker/dmxDatePicker.js" defer></script>
</head>
<body is="dmx-app" id="main">

View File

@ -1,16 +1,5 @@
<!-- Wappler include head-page="layouts/main" fontawesome_5="cdn" bootstrap5="local" is="dmx-app" id="observationPage" appConnect="local" components="{dmxBootstrap5TableGenerator:{},dmxMasonry:{},dmxFormatter:{},dmxBootstrap5Popovers:{},dmxBootstrap5Toasts:{},dmxDataTraversal:{},dmxStateManagement:{},dmxDatastore:{},dmxValidator:{},dmxBootstrap5Offcanvas:{},dmxBootstrap5Modal:{},dmxBootstrap5Navigation:{},dmxBootstrap5Tooltips:{},dmxBootbox5:{},dmxNotifications:{},dmxPouchDB:{},dmxBootstrap5Alert:{},dmxBootstrap5Collapse:{}}" jquery_slim_35="cdn" moment_2="cdn" -->
<script is="dmx-flow" id="minCalc" type="text/dmx-flow">{
runJS: {
name: "CalculateMinutes",
output: true,
outputType: "text",
function: "minutesBetween",
args: [
"{{saveObservationResults.form2.getStartTime.value}}",
"{{saveObservationResults.form2.getEndTime.value}}"
]
}
}</script>
<dmx-datastore id="datastore1"></dmx-datastore>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-timepicker/1.9.1/jquery.timepicker.min.css" integrity="sha512-UimcIlYKETYXXjgBbgq45ZXCLXI+d1O43cZXVTdhtCYYGomJVM2Ahz+L19UEWBIH4f/A/qmlvCaOWiaNMcaw3w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-timepicker/1.9.1/jquery.timepicker.min.js" integrity="sha512-+UV/u4sqwTpgK0d4vvTjan+ofWGwgTX9VkhLPKbRIQSolA4L8JmtJRk2zkh7Pv9ZtBQELMQury9Qf5RSA40N5g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
@ -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}}"]
}
}</script>
<div class="container" id="navContainer">
@ -237,7 +220,6 @@
</div>
</div>
<dmx-toggle id="toggle1" checked="true"></dmx-toggle>
<dmx-datastore id="datastore1"></dmx-datastore>
<div is="dmx-bs5-toasts" id="toasts1"></div>
<dmx-serverconnect id="scQuerySubSections" url="/api/qSubSection" noload="true" dmx-param:subid="1"></dmx-serverconnect>
<dmx-serverconnect id="serverconnect1" url="/api/qSection"></dmx-serverconnect>
@ -327,6 +309,7 @@
</tbody>
</table>
</div>
<div class="container"></div>
<div class="container" dmx-show="toggle1.checked">
<div class="row" dmx-hide="offcanvas1.CKBinput2.checked">
<div class="col-5">
@ -375,7 +358,10 @@
<tbody is="dmx-repeat" dmx-generator="bs5table" id="tableRepeat2" dmx-bind:repeat="scQuerySubSections.data.query">
<tr>
<td>
<select id="selPoints" class="form-select" name="sPoints" dmx-on:changed="datastore1.upsert({numSection: numSection, $id: numSection, description: txtSection},{numSection: numSection, Points: value, description: txtSection})" dmx-bind:id="numSection" dmx-bind:value="selectedValue">
<!--select id="selPoints" class="form-select" name="sPoints" dmx-on:changed="datastore1.upsert({numSection: numSection, $id: numSection, description: txtSection},{numSection: numSection, Points: value, description: txtSection})" dmx-bind:id="numSection" dmx-bind:value="selectedValue"-->
<select id="selPoints" class="form-select" name="sPoints" dmx-bind:id="numSection" dmx-bind:value="selectedValue" dmx-on:changed="datastore1.upsert({numSection: numSection},{numSection: numSection, pointValue: selectedValue, description: txtSection})">
<option value="0">0 points</option>
<option value="1">1 point</option>
<option value="2">2 points</option>
@ -390,50 +376,28 @@
</table>
</div>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th>$id</th>
<th>Db full name</th>
<th>Db license number</th>
<th>Db state name</th>
<th>Db employee</th>
</tr>
</thead>
<tbody is="dmx-repeat" dmx-generator="bs5table" dmx-bind:repeat="datastore1.data" id="tableRepeat5">
<tr>
<td dmx-text="$id"></td>
<td dmx-text="db_fullName"></td>
<td dmx-text="db_licenseNumber"></td>
<td dmx-text="db_stateName"></td>
<td dmx-text="db_employeeID"></td>
</tr>
</tbody>
</table>
</div>
<div class="container" id="DS">
<div class="row">
<header class="text-center">
<h3 id="scoreHeader" dmx-show="!datastore1.data.hasItems()" class="text-bg-danger" dmx-bs-popover="'If you save this file without points the observation will have zero points.'" dmx-bind:popover-title="'Info'" data-bs-trigger="hover focus">No Points recorded&nbsp;</h3>
</header>
</div>
<table class="table table-striped" dmx-show="datastore1.data.hasItems()">
<table class="table table-striped">
<thead>
<tr>
<th>$id</th>
<th>Num section</th>
<th>Points</th>
<th>pointValue</th>
<th>Description&nbsp;
<button id="btn5" class="btn btn-outline-danger w-auto btn-sm lh-base" data-bs-toggle="button" dmx-on:click="run({'bootbox.confirm':{name:'clearPoints',message:'This will clear all points',title:'WATCH OUT',buttons:{confirm:{label:'Yes',className:'btn-danger'},cancel:{label:'Cancel'}},closeButton:false,backdrop:true,then:{steps:{run:{name:'clearDataStore1',outputType:'text',action:`datastore1.clear()`}}}}})" dmx-hide="!datastore1.data.hasItems()">Clear all points</button>
<button id="btn5" class="btn btn-outline-danger w-auto btn-sm lh-base" data-bs-toggle="button" dmx-on:click="run({'bootbox.confirm':{name:'clearPoints',message:'This will clear all points',title:'WATCH OUT',buttons:{confirm:{label:'Yes',className:'btn-danger'},cancel:{label:'Cancel'}},closeButton:false,backdrop:true,then:{steps:{run:{name:'clearDataStore1',outputType:'text',action:`datastore1.clear()`}}}}})">Clear all points</button>
</th>
</tr>
</thead>
<tbody is="dmx-repeat" dmx-generator="bs5table" dmx-bind:repeat="datastore1.data" id="tableRepeat3">
<tbody is="dmx-repeat" dmx-generator="bs5table" dmx-bind:repeat="datastore1.data" id="tableRepeat5">
<tr>
<td dmx-text="$id"></td>
<td dmx-text="numSection"></td>
<td dmx-text="Points"></td>
<td dmx-text="pointValue"></td>
<td dmx-text="description"></td>
</tr>
</tbody>
@ -443,13 +407,7 @@
<script src="https://unpkg.com/pdf-lib/dist/pdf-lib.min.js"></script>
<script src="/js/libProcessScript.js"></script>
<!-- Popperjs -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js" integrity="sha256-BRqBN7dYgABqtY9Hd4ynE+1slnEw+roEPFzQ7TRRfcg=" crossorigin="anonymous"></script>
<!-- Tempus Dominus JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/@eonasdan/tempus-dominus@6.9.4/dist/js/tempus-dominus.min.js" crossorigin="anonymous"></script>
<!-- Tempus Dominus Styles -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@eonasdan/tempus-dominus@6.9.4/dist/css/tempus-dominus.min.css" crossorigin="anonymous">