diff --git a/.dockerignore b/.dockerignore index 6a3cec3..34f74b3 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,3 +2,4 @@ **/.git **/.svn node_modules +uploads diff --git a/.wappler/migrations/DB/20241125053059_security.js b/.wappler/migrations/DB/20241125053059_security.js new file mode 100644 index 0000000..bce4edc --- /dev/null +++ b/.wappler/migrations/DB/20241125053059_security.js @@ -0,0 +1,21 @@ + +exports.up = function(knex) { + return knex.schema + .createTable('security', async function (table) { + table.increments('id'); + table.string('user'); + table.string('pass'); + }) + .createTable('permission', async function (table) { + table.increments('id'); + table.string('permission'); + table.string('user'); + }) + +}; + +exports.down = function(knex) { + return knex.schema + .dropTable('permission') + .dropTable('security') +}; diff --git a/.wappler/migrations/ERTDB/20241103201444_catchup.js b/.wappler/migrations/ERTDB/20241103201444_catchup.js deleted file mode 100644 index 6f659c9..0000000 --- a/.wappler/migrations/ERTDB/20241103201444_catchup.js +++ /dev/null @@ -1,13 +0,0 @@ - -exports.up = function (knex) { - return knex.schema - .renameTable('tblSection', 'tSection') - .renameTable('tSection', 'tSectionOld') - -}; - -exports.down = function (knex) { - return knex.schema - .renameTable('tSectionOld', 'tSection') - .renameTable('tSection', 'tblSection') -}; diff --git a/.wappler/project.json b/.wappler/project.json index 99d350e..49c0586 100644 --- a/.wappler/project.json +++ b/.wappler/project.json @@ -39,7 +39,9 @@ "webLoggingMaxFiles": "5", "webLoggingMaxFileSize": "10m", "dockerTimezone": "Etc/UTC", - "databaseConnectionType": "none" + "databaseConnectionType": "none", + "databaseLoggingMaxFiles": "5", + "databaseLoggingMaxFileSize": "10m" } ], "activeTarget": "Development", @@ -48,5 +50,6 @@ { "name": "pdf-lib" } - ] + ], + "userUploadsFolder": "/uploads" } \ No newline at end of file diff --git a/.wappler/targets/Development/databases/DB.json b/.wappler/targets/Development/databases/DB.json index c616012..b307e68 100644 --- a/.wappler/targets/Development/databases/DB.json +++ b/.wappler/targets/Development/databases/DB.json @@ -152,6 +152,68 @@ } } } + }, + "security": { + "columns": { + "id": { + "db": { + "type": "increments", + "primary": true, + "unique": false, + "nullable": false + } + }, + "user": { + "db": { + "type": "string", + "maxLength": 255, + "primary": false, + "unique": false, + "nullable": true + } + }, + "pass": { + "db": { + "type": "string", + "maxLength": 255, + "primary": false, + "unique": false, + "nullable": true + } + } + }, + "db": {} + }, + "permission": { + "columns": { + "id": { + "db": { + "type": "increments", + "primary": true, + "unique": false, + "nullable": false + } + }, + "permission": { + "db": { + "type": "string", + "maxLength": 255, + "primary": false, + "unique": false, + "nullable": true + } + }, + "user": { + "db": { + "type": "string", + "maxLength": 255, + "primary": false, + "unique": false, + "nullable": true + } + } + }, + "db": {} } }, "views": {} diff --git a/.wappler/targets/Development/docker-compose.yml b/.wappler/targets/Development/docker-compose.yml index feac4bb..383863c 100644 --- a/.wappler/targets/Development/docker-compose.yml +++ b/.wappler/targets/Development/docker-compose.yml @@ -8,6 +8,7 @@ services: - '../../../extensions:/opt/node_app/extensions' - '../../../db:/opt/node_app/db' - '../../../certs:/opt/node_app/certs' + - '../../../uploads:/opt/node_app/uploads:rw' ports: - '8100:3000' restart: 'always' @@ -20,3 +21,4 @@ services: options: max-file: '5' max-size: '10m' +volumes: {} diff --git a/app/api/insert.json b/app/api/insert.json index 23d4926..8bb1ab4 100644 --- a/app/api/insert.json +++ b/app/api/insert.json @@ -1,7 +1,7 @@ { "meta": { "options": { - "linkedFile": "/views/index.ejs", + "linkedFile": "/views/index0.ejs", "linkedForm": "serverconnectform1" }, "$_POST": [ @@ -34,98 +34,134 @@ "type": "text", "fieldName": "db_stateIssue", "name": "db_stateIssue" + }, + { + "type": "text", + "fieldName": "db_trainerID", + "name": "db_trainerID" } ] }, "exec": { - "steps": { - "name": "insert", - "module": "dbupdater", - "action": "insert", - "options": { - "connection": "DB", - "sql": { - "type": "insert", - "values": [ + "steps": [ + { + "name": "validate", + "module": "validator", + "action": "validate", + "options": { + "data": [ { - "table": "da", - "column": "db_fullName", - "type": "text", - "value": "{{$_POST.db_fullName}}" - }, - { - "table": "da", - "column": "db_licenseNumber", - "type": "text", - "value": "{{$_POST.db_licenseNumber}}" - }, - { - "table": "da", - "column": "db_stateIssue", - "type": "text", - "value": "{{$_POST.db_stateIssue}}" - }, - { - "table": "da", - "column": "db_employeeID", - "type": "number", - "value": "{{$_POST.db_employeeID}}" - }, - { - "table": "da", - "column": "owner", - "type": "text", - "value": "{{$_POST.owner}}" - } - ], - "table": "da", - "returning": "ID", - "query": "insert into `da` (`db_employeeID`, `db_fullName`, `db_licenseNumber`, `db_stateIssue`, `owner`) values (?, ?, ?, ?, ?) returning `ID`", - "params": [ - { - "name": ":P1", - "type": "expression", - "value": "{{$_POST.db_fullName}}", - "test": "" - }, - { - "name": ":P2", - "type": "expression", + "name": "validate_1", "value": "{{$_POST.db_licenseNumber}}", - "test": "" - }, - { - "name": ":P3", - "type": "expression", - "value": "{{$_POST.db_stateIssue}}", - "test": "" - }, - { - "name": ":P4", - "type": "expression", - "value": "{{$_POST.db_employeeID}}", - "test": "" - }, - { - "name": ":P5", - "type": "expression", - "value": "{{$_POST.owner}}", - "test": "" + "rules": { + "db:notexists": { + "param": { + "connection": "DB", + "table": "da", + "column": "db_licenseNumber" + }, + "message": "Already in database. Delete record then retry." + } + }, + "fieldName": "db_licenseNumber" } ] } }, - "meta": [ - { - "name": "identity", - "type": "text" + { + "name": "insert", + "module": "dbupdater", + "action": "insert", + "options": { + "connection": "DB", + "sql": { + "type": "insert", + "values": [ + { + "table": "da", + "column": "db_fullName", + "type": "text", + "value": "{{$_POST.db_fullName}}", + "recid": 1 + }, + { + "table": "da", + "column": "db_licenseNumber", + "type": "text", + "value": "{{$_POST.db_licenseNumber}}", + "recid": 2 + }, + { + "table": "da", + "column": "db_stateIssue", + "type": "text", + "value": "{{$_POST.db_stateIssue}}", + "recid": 3 + }, + { + "table": "da", + "column": "db_employeeID", + "type": "number", + "value": "{{$_POST.db_employeeID}}", + "recid": 4 + }, + { + "table": "da", + "column": "owner", + "type": "text", + "value": "{{$_POST.owner}}", + "recid": 5 + } + ], + "table": "da", + "returning": "ID", + "query": "insert into `da` (`db_employeeID`, `db_fullName`, `db_licenseNumber`, `db_stateIssue`, `owner`) values (?, ?, ?, ?, ?) returning `ID`", + "params": [ + { + "name": ":P1", + "type": "expression", + "value": "{{$_POST.db_fullName}}", + "test": "" + }, + { + "name": ":P2", + "type": "expression", + "value": "{{$_POST.db_licenseNumber}}", + "test": "" + }, + { + "name": ":P3", + "type": "expression", + "value": "{{$_POST.db_stateIssue}}", + "test": "" + }, + { + "name": ":P4", + "type": "expression", + "value": "{{$_POST.db_employeeID}}", + "test": "" + }, + { + "name": ":P5", + "type": "expression", + "value": "{{$_POST.owner}}", + "test": "" + } + ] + } }, - { - "name": "affected", - "type": "number" - } - ], - "output": true - } + "meta": [ + { + "name": "identity", + "type": "text" + }, + { + "name": "affected", + "type": "number" + } + ], + "output": true + } + ] } } \ No newline at end of file diff --git a/app/api/signatureUpload.json b/app/api/signatureUpload.json new file mode 100644 index 0000000..281790b --- /dev/null +++ b/app/api/signatureUpload.json @@ -0,0 +1,10 @@ +{ + "name": "fileUpload", + "module": "upload", + "action": "upload", + "options": { + "fields": "" + }, + "meta": [], + "outputType": "array" +} \ No newline at end of file diff --git a/app/config/routes.json b/app/config/routes.json index 4ebb053..5e19ddb 100644 --- a/app/config/routes.json +++ b/app/config/routes.json @@ -1,8 +1,8 @@ { "routes": [ { - "path": "/", - "page": "index", + "path": "/index0", + "page": "index0", "routeType": "page", "layout": "main" }, @@ -32,8 +32,18 @@ "layout": "main" }, { - "path": "/start", - "page": "start", + "path": "/Scrollable-sections", + "page": "Scrollable-sections", + "layout": "main" + }, + { + "path": "/", + "page": "index", + "layout": "main" + }, + { + "path": "/da_index1", + "page": "da_index1", "layout": "main" } ] diff --git a/public/ERTSQlite.db b/public/ERTSQlite.db index f0c44c5..9e8cd40 100644 Binary files a/public/ERTSQlite.db and b/public/ERTSQlite.db differ diff --git a/public/PDF/dummyFunctions.js b/public/PDF/dummyFunctions.js index 0b4c781..ae7d77b 100644 --- a/public/PDF/dummyFunctions.js +++ b/public/PDF/dummyFunctions.js @@ -19,4 +19,5 @@ async function toBase64(filePath) { console.log(img) dmx.global.set('imgResult', img) return img -} \ No newline at end of file +} + diff --git a/public/PDF/pdfLibSignature.js b/public/PDF/pdfLibSignature.js index 446ae31..1542100 100644 --- a/public/PDF/pdfLibSignature.js +++ b/public/PDF/pdfLibSignature.js @@ -1,9 +1,20 @@ -// JavaScript Document v1.2 +// JavaScript Document v1.3 -const canvas = document.getElementById('signatureCanvas'); +//let dynamicSignatureElementId = dmx.global.data.signatureElementName // Gets the DYNAMIC ID for the canvas ID +const canvas = document.getElementById('signatureCanvas'); // const canvas = document.getElementById('signatureCanvasIndex'); const ctx = canvas.getContext('2d'); let drawing = false; + + +if (canvas) { + console.log('Canvas element found:'); +} else { + console.log('Canvas element not found'); +} + + + function myTestFunction(variable1, variable2) { console.log(variable1, variable2); // Your logic here @@ -50,7 +61,7 @@ function draw(e) { const { offsetX, offsetY } = getCanvasOffset(); let x = e.clientX - offsetX //canvas.offsetLeft; let y = e.clientY - offsetY //canvas.offsetTop; - //console.log("X:",x," Y:",y) + //console.log("X:", x, " Y:", y) //let x = e.clientX - canvas.offsetLeft; //let y = e.clientY - canvas.offsetTop; diff --git a/public/assets/images/Small-Start-Icon.jpg b/public/assets/images/Small-Start-Icon.jpg new file mode 100644 index 0000000..8ecde06 Binary files /dev/null and b/public/assets/images/Small-Start-Icon.jpg differ diff --git a/public/assets/images/icons/signature.png b/public/assets/images/icons/signature.png new file mode 100644 index 0000000..b7080ab Binary files /dev/null and b/public/assets/images/icons/signature.png differ diff --git a/public/assets/images/start-button-blue.png b/public/assets/images/start-button-blue.png new file mode 100644 index 0000000..68947e0 Binary files /dev/null and b/public/assets/images/start-button-blue.png differ diff --git a/public/assets/images/start-here-image.jpg b/public/assets/images/start-here-image.jpg new file mode 100644 index 0000000..ab20a51 Binary files /dev/null and b/public/assets/images/start-here-image.jpg differ diff --git a/public/dmxAppConnect/config.js b/public/dmxAppConnect/config.js index 3964cb0..dd85b7b 100644 --- a/public/dmxAppConnect/config.js +++ b/public/dmxAppConnect/config.js @@ -36,5 +36,34 @@ dmx.config({ ], "local": {} } + }, + "index": { + "global": [ + { + "type": "text", + "name": "file" + } + ], + "flowRunPageId": { + "meta": [ + { + "name": "setRunPageId", + "type": "text" + } + ], + "local": {} + }, + "flowrunPageId": { + "meta": [ + { + "name": "setRunPageId", + "type": "text" + } + ], + "local": {} + }, + "runPageId": { + "outputType": "text" + } } }); diff --git a/views/.wappler_folder.json b/views/.wappler_folder.json index e46f263..d69940d 100644 --- a/views/.wappler_folder.json +++ b/views/.wappler_folder.json @@ -15,8 +15,20 @@ "layoutPage": "main", "description": "" }, - "start.ejs": { + "Scrollable-sections.ejs": { "layoutPage": "main", "description": "" + }, + "da_index1.ejs": { + "layoutPage": "main", + "description": "" + }, + "index0.ejs": { + "layoutPage": "main", + "description": "" + }, + "index.ejs": { + "layoutPage": "main", + "description": "Starting page" } } \ No newline at end of file diff --git a/views/start.ejs b/views/Scrollable-sections.ejs similarity index 100% rename from views/start.ejs rename to views/Scrollable-sections.ejs diff --git a/views/da_index1.ejs b/views/da_index1.ejs new file mode 100644 index 0000000..4ebfe2a --- /dev/null +++ b/views/da_index1.ejs @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs index df1a878..450e840 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -1,208 +1,13 @@ - -
- -Informational panel
+You must sign for Road Test
+ +ERT Fast Fill - Developed by Jeff Daniels (DNIJE) / Data only locally saved / Powered by Docker and Node.js
- + diff --git a/views/observationPage.ejs b/views/observationPage.ejs index b7fd9f7..3194dd5 100644 --- a/views/observationPage.ejs +++ b/views/observationPage.ejs @@ -138,7 +138,7 @@Who you are grading
-| DELETE | +DA Name | +license number | +state issue | +Trainer # | +Date | +
|---|---|---|---|---|---|
| + + + | ++ | + | + | + | + |